|
- #include <WinIOCtl.h>
0 n: F. h+ l% B - #include <stdio.h>
/ s- }7 F6 ]% O. Z" }; y - & | V+ o i! I, H; o( u% C& p
- #pragma inline
- N) E8 P9 j4 j( ?9 ?9 ?8 ? - //---------------------------------------------------------------------------. r5 d) U) \( x
- // IDE NT/2000/XP专用变量
x( B% R6 _7 ~% S" s8 p - #define GETVERSIONOUTPARAMS GETVERSIONINPARAMS
4 ^0 V* y- K9 D# \1 V3 V( k! C - #define DFP_GET_VERSION SMART_GET_VERSION
2 s( i5 b' \- G3 J3 m) W! p/ Q! B2 i - #define DFP_SEND_DRIVE_COMMAND SMART_SEND_DRIVE_COMMAND- h: C" M7 a) M8 }& h! N* q4 h
- #define DFP_RCV_DRIVE_DATA SMART_RCV_DRIVE_DATA
" K# A+ Q1 {7 u6 O' n, W
* Y7 y2 _' l( m1 [) ~: R& a/ b" t- const WORD IDE_ATAPI_IDENTIFY = 0xA1; // 读取ATAPI设备的命令
! B( c) Y. _) }, I; U - const WORD IDE_ATA_IDENTIFY = 0xEC; // 读取ATA设备的命令% }# W( Y1 V- `- ]$ X" B/ o( K1 K' j) U
: n: }3 q: S9 l- const int MAX_IDE_DRIVES = 4;( I# m9 q. n& X1 L4 F
- 7 l9 J8 l/ n3 L3 [! |
- // SCSI专用变量
( i3 _2 T% x9 s2 P: v6 E - const DWORD FILE_DEVICE_SCSI = 0x0000001B;; M/ Q3 ]$ b3 p+ V7 ?
- const DWORD IOCTL_SCSI_MINIPORT_IDENTIFY = ((FILE_DEVICE_SCSI << 16) + 0x0501);! M; V/ X# Q: e
- const DWORD IOCTL_SCSI_MINIPORT = 0x0004D008; // see NTDDSCSI.H for definition( z5 {6 G5 x$ b7 \
- const DWORD SENDIDLENGTH = sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE;
4 c1 i/ B" d; ^& p; e
! X9 n$ J9 r$ v# S) X4 ]- typedef struct _SRB_IO_CONTROL
4 @- Z9 ?8 q4 D+ @( K6 G. F - {
+ ^$ s6 ]; I5 R* f: `8 W8 S - ULONG HeaderLength;$ Y* Y) y, p" t" j1 F+ S3 U* j
- UCHAR Signature[8];; L3 E/ W/ z% Z/ X
- ULONG Timeout;( p0 K9 w3 M4 \. K( S
- ULONG ControlCode;
1 u9 y' ?# B9 @3 ] - ULONG ReturnCode;
+ _2 U- J! T" G; q - ULONG Length;; W0 C0 M- \, L, T F7 C
- }SRB_IO_CONTROL, *PSRB_IO_CONTROL;
3 b8 O% U; Z, x1 q+ q* G' R3 w - # l0 z; E5 T: K
- // 读取的主函数5 P1 q4 _' [. |2 ^& n2 S ~
- void __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList);
5 [1 }: v9 k3 M
, b! a- x- t+ p5 Y, b- // 辅助函数; u) K8 p5 Q; A; Z0 t, f! f
- char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex);( Q+ a, p0 r. n7 R+ D- O
- // NT/2000/XP函数/ l# K2 k6 {. y
- void __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList);
- c" K/ g$ k5 _% r - bool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
9 o. `% V) a9 v2 r& f. c - PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd,' p# T8 L- A1 S, u( ]* G2 S& R" U
- BYTE btDriveNum, PDWORD lpcbBYTEsReturned);
% S& P0 U$ _& f - // Windows 9X函数
3 K- x \4 v7 t8 U" L0 Q - void __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList);6 f+ t9 _" _5 a8 g% Z t' b
- void __fastcall ReadPhysicalDriveOnW9X_Ring0(bool IsFirst, WORD BaseAddress,) S$ t# C q, m i
- BYTE MoS, bool &IsIDEExist, bool &IsDiskExist, WORD *OutData);& W: L: L7 Q$ G9 M4 y0 W+ @6 G: `' X
- 2 P9 Z# o5 J7 E1 x9 c8 X
- // SCSI读取函数(for NT/2000/XP)
3 F* [2 Y% m% e! | - String __fastcall ReadIDEDriveAsScsiDriveOnNT();9 @' ^3 h/ S5 N. t' |; j
- //---------------------------------------------------------------------------( i) c/ ~2 }' r/ \* ?
- // ReadPhysicalDrive
& _) N5 I9 a4 n4 h1 F6 M - void __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList): }5 i* q' Q) Z ?3 e& u/ Y% J1 v
- {1 h! t( Q5 ^7 }8 Q
- switch(Win32Platform)# V6 W9 r& J/ e& @& d
- {
3 p7 Y3 D' V+ ]) K - case VER_PLATFORM_WIN32_WINDOWS:) w0 q6 K" D( N" _
- ReadPhysicalDriveOnW9X(pSerList, pModeList);
9 V1 o' _% B& c! G9 l - break;
- ^: Y0 L l4 O5 Y5 E - case VER_PLATFORM_WIN32_NT:
- V: v' }9 A6 |- i, y' j) }0 @2 h - ReadPhysicalDriveOnNT(pSerList, pModeList);8 B6 I) k( B& ^( @/ S" i
- break;
/ v7 F% H& k3 ]$ y; P) _ - default:, B& u! ^& J# t' ]+ b
- break;
. W9 C4 F3 z9 [* G. ]5 b+ n - }* |! _2 d/ T: @. i4 ~* ]9 `5 A
- } l( C! i1 E) g1 X& o
- //---------------------------------------------------------------------------
% o* P2 z- a h9 O: ? - // ConvertToString
8 l) n% G, m& g r1 ^; Q - char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex)/ B4 c! H6 N, I
- {
I; E3 Z; A, l% V" i - static char szResBuf[1024];& G0 k9 f; U6 w' K! m f
- int nIndex = 0;) J- t; l% M& Z1 Y$ {9 E' J
- int nPosition = 0;
% G( h! @+ y' d9 U/ H$ z5 z - $ }6 a) C& Y) p0 ?
- // Each integer has two characters stored in it backwards
' k3 s! g# C- u - for(nIndex = nFirstIndex; nIndex <= nLastIndex; nIndex++)' q. Q9 ^: [0 n* p, I
- {
2 }2 Y3 d% A0 p - // Get high BYTE for 1st character/ t* s, s8 b3 E' q; a6 Z% g
- szResBuf[nPosition] = (char)(dwDiskData[nIndex] / 256);
4 p! ?, |" r- } {! s. T - nPosition++;
- _+ w# |5 z+ m" e
0 Q0 q) Q* ]7 n- s- // Get low BYTE for 2nd character9 B' i/ n# [( E4 p) L( }
- szResBuf[nPosition] = (char)(dwDiskData[nIndex] % 256);" T' I- \! J& ~1 _1 t" _
- nPosition++;+ g2 ]# \+ r' |" H8 u4 L3 q1 S8 J
- }
' `( a$ A! h8 e - 6 k0 y5 Y+ I. S$ _" \4 a0 R
- // End the string
/ M( c: L$ N- i6 G% Z7 C - szResBuf[nPosition] = '\0';
& j; Q- z' l `* M' s- J2 g( O
6 Y* V9 a5 e& T4 u- // Cut off the trailing blanks
# {3 b1 ]& l1 o) H" R6 `8 Q, E - for(nIndex = nPosition - 1; nIndex > 0 && ' ' == szResBuf[nIndex]; nIndex--)
: B/ V6 P C# K" s% l - szResBuf[nIndex] = '\0';
. d/ i& `0 ^ W: j8 G; E; _ - . ~5 L0 k7 q! z/ B7 a% }% \
- return szResBuf;" c7 _. j3 P2 }7 O
- }
3 U' R0 n, |; Q, e - //---------------------------------------------------------------------------
6 {) F5 `# D) S& o2 Z( g" H% C - // Winndows NT4/2000/XP 代码
( j7 S0 Q, f% f* o4 K9 l - //---------------------------------------------------------------------------
* p! S c4 u8 e" {. C - // ReadPhysicalDriveOnNT5 [: \" [; X1 A# V
- void __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList)
c. i& P& m/ f8 \& G' h6 t - {
1 N. p5 Q# @# Z* U - // 输出参数
+ z' P2 n q0 j% X% d5 \: I% ] - BYTE btIDOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
8 R7 w5 ?" B) [# E
, q, x0 j( r* S- for(int nDrive=0; nDrive < MAX_IDE_DRIVES; nDrive++)
# T* n+ W( S* f- g' Z6 p: k - {' M* `; ^2 ^8 c* L) [& x
- HANDLE hPhysicalDriveIOCTL;' {0 [* z- \1 i4 S7 I
- char szDriveName[32];
7 G6 \2 r7 }6 i7 Z2 a9 P - 7 U r1 ^7 o3 D2 f
- sprintf(szDriveName, "\\\\.\\PhysicalDrive%d", nDrive);
1 ]4 a% ]" y' B5 W1 N5 Y2 S* @7 d - hPhysicalDriveIOCTL = CreateFile(szDriveName,
+ g' I% h D: f) w, X( W - GENERIC_READ | GENERIC_WRITE,
2 s7 u8 I3 y& F& ?$ x4 t - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,+ P: `: S% B$ ~
- OPEN_EXISTING, 0, NULL);* G4 e1 ?, q. N3 L
- : ]) A% y/ M1 q+ h9 l9 ~7 Y3 j) C
- if(hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
$ m- y9 z' b# U; w' V - {
/ C# M# |( Z6 X! [2 h' ^5 P - DWORD dwBytesReturned = 0;
; F2 y* L* n5 P7 j o8 h - GETVERSIONOUTPARAMS gvopVersionParams;# y% d/ @0 p, _8 m M3 U
- 6 E- S& ^9 A# O- e4 U
- // Get the version, etc of PhysicalDrive IOCTL& y8 D! {4 ~3 u- L& t
- ZeroMemory(&gvopVersionParams, sizeof(GETVERSIONOUTPARAMS));
( ^- t, t& }) \6 B
8 W7 {* Y- Q2 ^) H$ p- if(!DeviceIoControl(hPhysicalDriveIOCTL, DFP_GET_VERSION,, p" ]1 X$ R0 E( r) Y5 m
- NULL, 0, &gvopVersionParams, sizeof(gvopVersionParams),. _: ?* @! b0 F/ I
- &dwBytesReturned, NULL))
/ X4 z8 [8 w- N/ y6 t - {' ~) S$ B7 ^2 B) y' l
- continue;
2 b! P2 Q& s, o8 y" }) {; E - }( C. ?; ^$ `* w' I
5 R" w3 E: H* [; P- if(gvopVersionParams.bIDEDeviceMap > 0)' V: x4 b$ W3 r9 t) z
- {
! K6 V3 n) j/ o( V - // IDE or ATAPI IDENTIFY cmd& }& x9 j' p5 o4 r- I" S- o
- BYTE btIDCmd = 0;
6 y! T: N* V- R1 }8 w) {' U# ` - SENDCMDINPARAMS InParams;
" x% B# D& y9 c5 a5 h - // Now, get the ID sector for all IDE devices in the system.
- h2 l7 T. |9 Y. @0 Y0 G - // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command," s- I8 K8 ?0 {" Q
- // otherwise use the IDE_ATA_IDENTIFY command
6 O3 L1 I6 Y4 c5 G) W8 a - // 具体所得结果请参考头文件中的说明3 o$ _4 j4 U0 J
- btIDCmd = (gvopVersionParams.bIDEDeviceMap >> nDrive & 0x10) ?/ j4 l# n5 W8 u7 l; _; }, Z% R
- IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;7 q1 Y4 S0 }4 i" b, j
- ZeroMemory(&InParams, sizeof(SENDCMDINPARAMS));) u9 P2 f: }8 w; d* P3 R
- ZeroMemory(btIDOutCmd, sizeof(btIDOutCmd));5 q% P* V4 u2 l# a% f
- 7 Z8 _ k# o- {
- if(DoIdentify(hPhysicalDriveIOCTL,
- F0 e" C! d+ k0 S - &InParams, (PSENDCMDOUTPARAMS)btIDOutCmd,
! }6 P( o7 p' b; v! C- i# F J - (BYTE)btIDCmd, (BYTE)nDrive, &dwBytesReturned))# t* _1 T+ `2 N' G/ x
- {
7 f4 J* d9 {: r1 h9 ?$ ?5 R4 e - DWORD dwDiskData[256];
& S$ y" h. [3 d" G: | - USHORT *pIDSector; // 对应结构IDSECTOR,见头文件. n5 v, X1 {3 b: L+ `
- char szSerialNumber[21];
4 `1 N3 ^8 {$ | - char szModelNumber[41];
3 t, s" A( c1 @: G6 S - + h9 }% @) e- h+ E. _
- pIDSector = (USHORT*)((SENDCMDOUTPARAMS*)btIDOutCmd)->bBuffer;
! b" x; O$ v0 d6 U# J! Y [ - for(int i=0; i < 256; i++)* S# [: |, C* `' h
- dwDiskData = pIDSector;
- C0 u! C3 S3 @0 e" m - // 取系列号
, p1 k0 B0 j0 _; B; `2 O; S- L4 R) I# h - ZeroMemory(szSerialNumber, sizeof(szSerialNumber));
1 S# v* ~# d5 t5 Y - strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));3 s( O5 D8 b) ~$ ~& }0 I
- 8 n5 R7 |4 S! J- k
- // 取模型号' j' @; {+ p. s) m$ |
- ZeroMemory(szModelNumber, sizeof(szModelNumber));0 r8 L$ P- {( l2 }
- strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));. l* Z1 n& L' Z. N @) k9 w2 c
- 6 u8 g7 E3 @$ D6 ?; l4 b* O( }* u
- pSerList->Add(szSerialNumber);$ F/ {5 |: W) q4 X t: ?% {
- pModeList->Add(szModelNumber);
8 x3 t" @0 U0 B$ a3 q- Q i, d) B - }
% ?+ s0 ]/ S+ w3 a9 o5 u - }
% U; s8 Z% r5 f& F - CloseHandle (hPhysicalDriveIOCTL);
z; S1 u- s5 |3 c - }2 b; @3 f E9 i3 y! `% H3 Y
- }' \4 m3 D$ a9 g0 \0 o5 Y3 [7 q
- }
; T! P% C! F$ R2 x& x R! S9 {, z" j: V - //---------------------------------------------------------------------------: t2 T$ Y, H/ e1 Y: H+ D* A
- // DoIdentify
$ D; n- P3 x3 W V8 K9 C - bool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,: `6 _' o) C) Z7 p- c8 a* B
- PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd, BYTE btDriveNum,
$ P/ _; j1 r- l! ^ - PDWORD pdwBytesReturned)
, N/ y6 B" _9 d - { ?- q" P7 i' S2 @
- // Set up data structures for IDENTIFY command.' f1 j- d( v4 Y% ~$ u. _( V: z& ?* A
- pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
" u/ M- K( m* p1 r$ Q* H2 e0 t - pSCIP->irDriveRegs.bFeaturesReg = 0;2 R4 Y& B2 w; U( o2 p* E d# |" o
- pSCIP->irDriveRegs.bSectorCountReg = 1;
" r: X7 C+ t; ?$ Z6 V8 l/ S% c - pSCIP->irDriveRegs.bSectorNumberReg = 1;8 f$ E; H+ y. S+ {% }' K. Z% F
- pSCIP->irDriveRegs.bCylLowReg = 0;' ~, Q* y$ g u
- pSCIP->irDriveRegs.bCylHighReg = 0;3 Q% T0 o/ q) d1 }0 n0 y
9 R3 v/ T5 b0 C- // Compute the drive number.(主盘和从盘所对应的值是不一样的)
. o7 M5 t2 C }, a: n - pSCIP->irDriveRegs.bDriveHeadReg = (btDriveNum & 1) ? 0xB0 : 0xA0;8 Y% m% D. e+ {+ ~8 X2 _: Q
- # S; I1 ]+ t: E1 s0 ]! ^
- // The command can either be IDE identify or ATAPI identify.! s% E, R8 r# w: U7 ^) z0 X6 S
- pSCIP->irDriveRegs.bCommandReg = btIDCmd;
) h8 o$ X. E3 y - pSCIP->bDriveNumber = btDriveNum;2 @" X) t, Z5 f% {8 F- B/ E% ~
- pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
; D- C& }9 x' v - : ^8 E$ B: m2 ]- L
- return DeviceIoControl(hPhysicalDriveIOCTL, DFP_RCV_DRIVE_DATA,
5 X' Y' M w. L! h9 X1 G% ~ - (LPVOID)pSCIP,/ J+ m& |: Z# L3 B. v) D
- sizeof(SENDCMDINPARAMS) - 1,
" Z8 a% V! | G+ h- f - (LPVOID)pSCOP,
* g: ]2 _/ B$ ^% j% K: h6 x0 X: I - sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
5 X- y+ Q1 I1 Z1 q - pdwBytesReturned, NULL);5 g3 H) M- P& ?6 r) I9 }
- }% L5 r& _4 D! i- F; S
- //---------------------------------------------------------------------------9 V9 U+ a. \+ A9 k8 H9 {
- // Windows 95/98/ME 代码* a* M/ p" _7 m5 c; [
- //---------------------------------------------------------------------------4 a I% O6 p7 _( n; q
- // ReadPhysicalDriveOnW9X3 }' }9 a7 y7 |8 w! X' }
- void __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList)7 `' D) B, x1 }7 x# O1 d- D+ Z
- {
% s/ j0 j* S- s" l3 V6 m% _3 a - WORD wOutData[256];
8 X4 @# f5 s, S; D1 | w - SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);) \9 `6 f& X. r/ q9 m
- : ^4 F7 z* X$ q, \: {
- // 经过测试,发现第一次调用而且Drive >= 2时会在Ring0代码中出现错误,导致蓝屏。+ `/ z6 W' b' G; U3 U: t8 ^2 G. S
- // 经过N(N > 15)次的蓝屏后仍找不到原因:(,不得不在这里增加一段无用代码以
7 w/ @- `) z' z, n! c# @ - // 避免蓝屏的出现。(期待高人能指出原因)1 B( L6 j: z8 R" K- @; \+ D/ D/ p
- for(int nDrive = 0; nDrive < 8; nDrive++)8 h% J* b9 z7 H; o2 _: |
- {
- W" E& O5 H! B5 T# A: a- r' u. r - WORD dwBaseAddress;; ?+ q! U9 O! y" Z/ ^( |
- BYTE btMasterSlave; // Master Or Slave S6 b+ y# h* Y4 ?, q) X2 z+ |* f
- bool bIsIDEExist;* @2 [$ S0 U5 U
- bool IsDiskExist;. G: s5 G g! R6 \ F
- ) m3 v5 |+ j) w3 U9 O4 o# f) B ]
- switch(nDrive / 2)( S5 |& z4 {8 h5 K; C
- {" @8 V, K/ H7 M; |
- case 0: dwBaseAddress = 0x01F0; break;
: k3 G- B7 A7 L; b3 W8 e: }+ {* P - case 1: dwBaseAddress = 0x0170; break;
m6 q& o0 w7 ` - case 2: dwBaseAddress = 0x01E8; break;
1 H' D( b) j# ]5 S - case 3: dwBaseAddress = 0x0168; break;
- R$ G) h4 {* C6 Y, ]7 a6 K- w. K - }5 \- a% s$ v& a/ \8 b! {
- ! B' p7 l6 ]9 N4 T a$ n: a* f
- btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0);
2 x% D( O+ N! J+ @" U4 c
! K# ~4 z1 J& v- // 进入Ring0
% q) n+ Y: {7 q9 Y. i - ReadPhysicalDriveOnW9X_Ring0(true, dwBaseAddress, btMasterSlave,2 m3 x3 |0 ^% f0 A, ]. _) k: P
- bIsIDEExist, IsDiskExist, wOutData);" [1 e- ^6 V- p
- }- a. \! m: j2 L0 e; O S5 n
- " V- V0 @0 {, d8 Y
- // 开始读取
( |/ N; N3 T3 @+ K2 t - for(int nDrive = 0; nDrive < 8; nDrive++), Q; G, c. i3 M- z
- {. J7 h3 T( a8 @
- WORD dwBaseAddress;
6 q0 D2 @9 M* ?" W- } - BYTE btMasterSlave; // Master Or Slave+ ]( r3 t, q" T* U
- bool bIsIDEExist;
" y1 x, H$ m/ n2 w% s; @4 l( t - bool bIsDiskExist;0 S' B6 x$ ]9 P5 c' Q; k7 D% T
- switch(nDrive / 2)
9 R6 X' O ~2 n' _ - {; k8 g7 F9 L! k: Q: F$ t7 \% q
- case 0: dwBaseAddress = 0x01F0; break;
; C6 j/ A0 t) N: `* a - case 1: dwBaseAddress = 0x0170; break;8 W6 S& b3 m3 z% [& l9 [
- case 2: dwBaseAddress = 0x01E8; break;# x2 ~( l9 |9 v9 h; M
- case 3: dwBaseAddress = 0x0168; break;! D3 M% P$ e3 o! f
- }9 x- Q% O5 \2 V4 I3 R9 Y3 {) h7 X
4 j$ E4 |$ S2 [. ?0 O6 ]* u" \2 w5 n- btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0);. s1 x( P. V2 Q. |; s
- 4 w! l" e" r2 g3 ?
- // 进入Ring0
. R# E2 e, w; Z8 M2 g6 y. L - bIsIDEExist = false;
( R( J5 t8 Z3 D; ]* D4 U - bIsDiskExist = false;8 h' ~2 z# I3 O6 j$ j0 |7 t
- ZeroMemory(wOutData, sizeof(wOutData));
/ z6 I4 x: B, h6 D# t* s6 C3 R0 ?
% \8 t: t4 B: T, p' w: O. G2 R, z- ReadPhysicalDriveOnW9X_Ring0(false, dwBaseAddress, btMasterSlave,% p1 H$ R: ]4 |! f: Z
- bIsIDEExist, bIsDiskExist, wOutData);& h1 B Z/ w! h$ P$ Z
7 d/ _- g% M: E+ U- if(bIsIDEExist && bIsDiskExist)% V- J. c) G1 k0 A
- {
x5 e/ n* y+ s4 {( M' a- }7 N8 u - DWORD dwDiskData[256];
3 a+ S9 \5 E. V" q - char szSerialNumber[21];' ~4 [3 s; z4 B U- Y& K7 l+ r' q2 W
- char szModelNumber[41];
+ x0 j( U+ {& e/ z% H" H$ D8 z
' U8 S* {( i- G) b' [; D) d0 i1 m- for(int k=0; k < 256; k++)/ a( k# ^" M1 J+ y* M$ F, M
- dwDiskData[k] = wOutData[k];
! J( Y3 B3 y! A4 {
9 s" H6 \. _# w- // 取系列号
5 c$ x% v. D0 N - ZeroMemory(szSerialNumber, sizeof(szSerialNumber));! H6 h! l0 y0 M# @- a( _: o
- strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));
9 f# J( {" a( l1 M! D - & t1 E& d& m$ Y* M1 j
- // 取模型号6 O7 t7 b W# S/ `+ [; E# r) n
- ZeroMemory(szModelNumber, sizeof(szModelNumber));
8 G7 h/ e8 V/ P+ w8 D, Y7 d& s - strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));. m9 y, S( A# B2 L8 Q
- * w. e% O4 J0 Y' P/ u7 r2 r
- pSerList->Add(szSerialNumber);4 n+ H9 m5 a/ W
- pModeList->Add(szModelNumber);
) k& t) k' F0 h H: v: Y - }
" O( U' x& Q4 s0 l: ~ K - }, x( a* v9 q, w0 `( P1 [9 d
- SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);- i2 g7 Z0 o O, {: B! p
- }
$ I2 R6 P9 u A/ P! G4 t - //---------------------------------------------------------------------------8 d- |) `4 F; e' c
- // ReadPhysicalDriveOnW9X_Ring0()
4 `. d+ v! h+ ^; p - //
1 e' o# M8 {3 X/ d' b8 l) R - // dwBaseAddress = IDE(0,1,2,3) : 1F0h, 170h, 1E8h, 168h
+ |3 b5 k% [+ K8 q - // btMasterSlave = Master(0xA0) Or Slave(0xB0): g# S) L( s! j1 C% u
- //---------------------------------------------------------------------------
0 y7 T/ ?- Z1 B6 i8 O- Q - void __fastcall ReadPhysicalDriveOnW9X_Ring0(bool bIsFirst, WORD dwBaseAddress,
. i& v' V9 ^2 i0 l! F2 @+ O - BYTE btMasterSlave, bool &bIsIDEExist, bool &bIsDiskExist, WORD *pOutData)
& b; P0 T* v0 L0 l - {
7 k! Y1 E8 W, ?4 c: ^ - BYTE btIDTR1[6];% v3 A9 C' ^5 A* T: I1 Z) u
- DWORD dwOldExceptionHook;# V0 c I) r2 }9 z
- const int nHookExceptionNo = 5;
# |9 J" o4 K5 n( \( S
$ y! z# R( ^2 R x: N9 D- BYTE btIsIDEExist = 0;
4 j9 v1 {3 `. T1 O# N - BYTE btIsDiskExist = 0;. x6 @3 _0 ]1 M) d4 f
- WORD wOutDataBuf[256];
0 b/ k$ E6 v u
& \* [/ N$ V8 m, B- BYTE btIsFirst = (BYTE)bIsFirst;* y9 I" t4 B5 U
- 9 s; K, c& P" d4 u5 O: o
- const BYTE btBit00 = 0x01;* n) c! Q+ ~% M- @* d; m
- // const BYTE btBit02 = 0x04;
: v/ B! C+ S o - const BYTE btBit06 = 0x40;
- b& |# A9 [& p' ?% H8 z' ` - const BYTE btBit07 = 0x80;$ o" g# K, }/ `) h; Y6 Q \( ^
- // const BYTE btERR = btBit00;
$ u. f; [% o8 t% b! B% a - const BYTE btBusy = btBit07;
$ V) }, H. z9 J" W8 ^3 W! \ - const BYTE btAtaCmd = 0xEC;7 l% m) `+ P1 K4 r& S
- const BYTE btAtapiCmd = 0xA1;+ }: r, t4 {* ^3 A
- 0 w$ f$ z4 {6 I2 ~
- __asm
% U3 Y, Z0 d: h - {
& e6 m" |4 r& J; n - // 必须先执行这条语句* W( t5 }" U6 q# w- E
- JMP EnterRing0 Z' x0 Q! B: y) q: B( e
2 E$ b' s! ?1 @5 U- // 定义过程" H% X& q' d X6 K: O2 s# o1 G
- // 等待IDE设备直到其不为忙为止
* l- M6 N( l3 u$ \ - WaitWhileBusy proc
; D8 L6 o! { J0 u. _
6 Y- m! v8 v/ X+ V. l; Y; A) y- MOV EBX, 100000
! Q) h( H- T3 E# }+ Y. \# | - MOV DX, dwBaseAddress! @. g& S- @2 Y( o
- ADD DX, 7
5 T( O% u8 y! M, V3 \: ]$ ]
5 }& V+ w- Z5 L- S6 [% f- LoopWhileBusy:( C2 X) V! P6 r/ u6 z
- : h0 ?, r( Y$ U" U/ ^
- DEC EBX- p N- T8 ^7 ]& D# W; t
- CMP EBX, 0
2 u8 d* O1 W% i$ l - JZ Timeout6 T2 _, |4 T/ g, z" R- X$ ^8 u. a
- in AL, DX
$ r7 h% ]6 _$ q: h4 k6 `) o9 E5 o - TEST AL, btBusy. { Z: N0 G/ H" F- M: ~ E
- JNZ LoopWhileBusy+ |5 c; S l! S. g0 |
- JMP DriveReady( y! V- X6 m" S8 [) W
. L* g0 u$ |7 \- // 超时,直接退出
1 h. k( V" ^, [9 `$ E4 `. |8 l. l - Timeout:
, E' E5 o0 Q O6 O - JMP LeaveRing0
! h" l. }2 j. y - DriveReady:
i& m, ^6 z% q$ T' ` - RET* J* Z8 ~7 Z7 M0 ]
- ENDP // End of WaitWhileBusy Procedure! x0 |' m1 s. D+ z! i
" T( n# J6 U' x2 `$ @7 r- // 设置主盘和从盘标志
- Z8 E: C. [5 J I) s: ] - SelectDevice proc
2 v8 I3 ?8 S2 H* s7 R; c- o0 J
% l! x6 `9 b8 h/ F* q) q- MOV DX, dwBaseAddress
! m6 E2 L! w2 Q( R0 i - ADD DX, 6/ I$ M2 B5 u! D0 O* A, v$ m2 X0 q
- MOV AL, btMasterSlave
, H) z2 @. B, N1 F - ' k1 }/ `. u9 g- y- y
- out DX, AL1 f0 s" k7 `; g- \) F2 S& r
- RET9 p" k4 [% K9 X3 d" J) O6 i
- / G; @9 y+ A( q1 e; j
- ENDP // End of SelectDevice Procedure. C& g0 |- A! Y. _
- 3 ]) ]/ h- v6 z5 [
- // 向IDE设备发送存取指令! N8 O2 x2 O, s8 M0 w) H- U
- SendCmd proc" p0 m* U$ B. p& h0 n; [
- 3 k, `& h0 Y$ i; @! R
- MOV DX, dwBaseAddress
7 F+ Q+ Z. ^, C! ?4 v8 {! O" l - ADD DX, 7
% e# g) F8 C. q! A4 ]8 B - MOV AL, BL // BL是主从盘标识,在过程外设置' Q y) m$ g% y8 o2 M
- out DX, AL4 r6 q, b$ ?8 g, r% K& G$ u" F0 [
- RET, r: y- F2 m1 {' A, K5 Y/ T5 N
- ENDP // End of SendCmd Procedure
: [- w& z6 j% P( h( } - 4 U- H6 @) Y( R4 A+ q1 u8 e8 [2 g
- // Ring0代码
, C; w! o9 Q9 c( X - Ring0Proc:( r* y0 z/ ^* [. r3 f
- PUSHAD
- ]& k' J7 H3 E9 G( c - // 查询IDE设备是否存在
; K* X u( x- a$ U5 a; [ - MOV DX, dwBaseAddress
0 e- p1 T' c3 X7 g9 x; Y7 E - ADD DX, 7
1 c9 p6 _& O* K8 c - in AL,DX. V4 M1 L3 u Z& g
/ E3 I6 W% O+ t0 y9 U- // 当AL的值是0xFF或者0x7F时,IDE设备不存在,这时候直接返回
: F# {8 ]8 a9 P! c% S# T% }) X - CMP AL,0xFF
6 I/ v5 l. z, ] - JZ LeaveRing0
. P; t8 x; e4 _. b3 G5 a - CMP AL, 0x7F4 \1 n1 p; a- Q: ~4 Q; B/ Y1 X; V: ]
- JZ LeaveRing0; T( ~2 w) ^+ u* Q: U
- 0 q+ Y' Q7 H) S
- // 设置IDE设备存在标志) i: {- X. {- `5 r$ w3 y+ M
- MOV btIsIDEExist, 19 v/ x& c% K9 h& w
9 o, }7 c* C1 S1 M4 d0 {- // 查询IDE设备上的驱动器是否存在(有IDE插槽在主板上,但是却不一定有硬盘插在上面)
6 M9 V( `# o5 H& h9 o - CALL WaitWhileBusy% K8 t, o4 I. o6 o$ |, ^, X
- CALL SelectDevice
1 N: M o) `" W; k# c
4 ]% {( W% ] N8 t! Y8 b- // 如果是第一次调用,则直接返回,否则执行下行语句时会出现蓝屏
) U: p) U* {6 Z" i) Q8 q4 K( l - CMP btIsFirst, 1
) Q4 z7 r, y: T - JZ LeaveRing0
" w) j+ n; p0 i' J* w6 o
3 J! x1 V% l' q3 _- // 第一次调用时,如果执行这行语句会导致蓝屏,Why???
v6 G0 A* X0 y9 {( b0 j - CALL WaitWhileBusy
" M1 v, R/ E( P2 V2 L& N
7 w3 U5 R. q. `8 c9 |3 P' s- // AL的值等于cBit06时,不存在驱动器,直接返回
* \3 X- l6 _! w3 h( M0 z" R - TEST AL, btBit063 O5 `5 M1 M8 S" X8 P
- JZ LeaveRing0
* S' V/ b, B6 j5 r4 V
5 t- c& r3 Q9 p6 t, {0 |" v( [4 p- // 设置驱动器存在标志
* T8 H0 D# H W, X# @ - MOV btIsDiskExist, 1 p8 w4 f! d2 |8 | w4 e$ E4 {% \
- 0 ` ~$ D6 N5 G
- // 发送存取端口命令8 `6 P! L8 j- \, g) g T( t [( q! I
- // 无法像NT/2000/XP那样可以通过查询VERSION的值得到驱动器的类型,9 M3 n! d5 Y% _5 d4 Q
- // 所以只能一步一步地测试,如果不是ATA设备,再尝试使用ATAPI设备命令
/ ^+ M" T8 E8 l2 z3 J - CALL WaitWhileBusy0 G. V6 c( L& ~" l; q- j6 s
- CALL SelectDevice // 设置主从盘标识3 P! `: J* I6 T; Q9 ~3 ]
- MOV BL, btAtaCmd // 发送读取命令. I8 w0 N' \4 S9 w
- CALL SendCmd
$ _5 I% Y- E! E3 F0 v2 q - CALL WaitWhileBusy! a7 `( F' z" C# p8 i$ h
- . g, o3 l/ k$ V' Q: N
- // 检查是否出错
* f5 |: l" v/ f. N0 j0 F. | - MOV DX, dwBaseAddress7 v$ ?1 F3 w. h
- ADD DX, 76 [' ?5 g$ C2 X# s5 C6 D1 S
" \) O9 A2 j) J; V- in AL, DX8 N0 _& o: W. ^! ]: k
# ]1 u/ I) ?4 O8 Z5 t/ c2 M" L# \- TEST AL, btBit00! u6 E. B8 L. x) N, f+ z0 P
- JZ RetrieveInfo // 没有错误时则读数据$ D, I6 S: G' [ [& y5 A" }" p0 z
- 9 x" T0 B( t, _# a1 D& I8 y6 V
- // 如果出错,则进一步尝试使用ATAPI设备命令
; h# t& H0 J$ o/ [; x! h1 c" } - CALL WaitWhileBusy' I6 z8 g9 A( _4 }/ z- t" g, i: m
- CALL SelectDevice
: ^& h: Z1 o" {5 c4 t) [& d! I - MOV BL, btAtapiCmd
% f9 k3 Y" W# [" b+ a; h9 L7 K - CALL SendCmd
4 f* w1 n- \. K0 u {" c$ s - CALL WaitWhileBusy/ W; T( y" _, B4 B
- 1 e! i: R0 i. \
- // 检查是否还出错
D- s0 c* t. [" G- q - MOV DX, dwBaseAddress
0 R, ?( n! A9 p$ |5 j# I3 \% D4 P - ADD DX, 7: o7 ~) N( x. Q1 C; c- E" L% J
- in AL, DX
* N1 V; `% D1 e5 ~+ \1 M - TEST AL, btBit008 p/ N; @* a5 r! p4 T
- JZ RetrieveInfo // 没有错误时则读数据
$ \0 h* D9 Y3 L! J" t - JMP LeaveRing0 // 如果还是出错,直接返回
; z. ?' N1 {& p M! | - % i7 g9 l4 w( R5 j* p4 _4 ~
- // 读取数据
3 ^" s( r7 D( }- Q- m* l- P9 y; t - RetrieveInfo:9 @2 M2 s! A p& }" a
3 s4 b% R. i8 j* i5 h$ o5 q1 p& u- LEA EDI, wOutDataBuf
0 d, S J- ^9 l; f - MOV ECX, 256" v7 O* O7 Y1 G* H8 T7 I
- MOV DX, dwBaseAddress
; t- ` T* X* T1 ?& R+ l m+ h9 G - CLD* a9 i/ s" {- X& ?
5 r$ b+ y) _" _# [- REP INSW( A) q/ W9 |' y( A$ p
% m$ q' K* B7 \8 o3 I! Q- // 退出Ring0代码
3 `- t, \$ M! } - LeaveRing0:
6 p2 `/ G1 \1 ^ B) T
) [& j* v, W. C5 n- POPAD
) H' s& S" R6 R0 X+ [$ y7 b: i - IRETD
* ?+ M6 m, U" A6 E% L
+ A0 j6 O' } t1 v- // 激活Ring0代码
" C; w5 x8 R: g0 G4 l - EnterRing0:
0 I( L$ |6 E _/ i( i - 1 C* w8 q& g a
- // 修改中断门3 V" ~* [, ]! i
- SIDT FWORD PTR btIDTR17 y$ u/ h6 x+ [
- MOV EAX, DWORD PTR btIDTR1 + 02h2 F% l% s; e% V: @
- ADD EAX, nHookExceptionNo * 08h + 04h
8 |) _) S0 _; {# C+ O0 t; x - CLI
/ P2 n2 y' i8 I* I9 A; g - - N- V( N; p# S: F4 _/ ]1 ^- L9 b
- // 保存原异常处理例程入口
* P& I o# h2 X! H0 L& G - MOV ECX, DWORD PTR [EAX]& L9 F4 L) Z' J5 N) u; J8 C
- MOV CX, WORD PTR [EAX-04h], G+ X1 b+ ]9 J4 V( S( x% V; w
- MOV dwOldExceptionHook, ECX' n7 v" g7 t9 F) b; I# r) J
- 2 G' ]4 c. U; i+ P5 r5 N
- // 指定新入口
2 x, Y2 @; w% T - LEA EBX, Ring0Proc( `8 U7 L; z3 A/ ~; B. R4 q
- MOV WORD PTR [EAX-04h],BX
[! ~! W9 I/ K2 a- J9 G9 _ t - SHR EBX, 10h
7 u& X0 j6 w. r2 _' G0 K - MOV WORD PTR[EAX+02h], BX( Z* K" L3 f: k) N ^, V
- 0 A7 A8 z" v+ e" X5 ]" I
- // 激活Ring0代码
* s: A% L1 h* i7 R' P - INT nHookExceptionNo
4 B% X% c1 Z4 [. D! e+ K& D+ q - / D) M/ j$ P! \, u! {" N
- // 复原入口
4 N* s, j6 p" e1 f7 T - MOV ECX,dwOldExceptionHook( I1 D: N$ A: Y: V" h- A6 A& R: S
- MOV WORD PTR[EAX-04h], CX
! r1 Y2 u" {: v4 Y; j - SHR ECX,10h
0 T" w9 N5 [, G! | - MOV WORD PTR[EAX+02h], CX
7 W, h. {" j* ~+ [2 P3 i0 e2 G* z - STI& Q1 a9 H" d3 h5 ~
- } e& b6 V1 k4 Y' A1 s1 S' z
- if(!bIsFirst)
- M# \1 {; Y" A* j- {6 z - {4 Y2 P0 ?/ S8 @7 t
- bIsIDEExist = (bool)btIsIDEExist;
7 ]7 T7 I% [' @+ U - bIsDiskExist = (bool)btIsDiskExist;
% w/ q4 k4 b: F) v3 P' k: K - CopyMemory(pOutData, wOutDataBuf, sizeof(wOutDataBuf));. C: R: v' c& S1 D% o- V! i) b
- }' A5 h8 q1 t) ]3 X6 i, y6 c6 O8 a& O
- }
; k$ F2 E+ ]4 J3 I* t - //---------------------------------------------------------------------------; {7 J! w" @3 u9 P, s* @
- // 调用方法:
+ W8 A/ ?& i, {! [3 P B' o, O6 ~ - void __fastcall TForm1::Button1Click(TObject *Sender)7 X" {0 e0 X+ s
- {
1 Q* u! _* R/ i: d N3 a - ReadPhysicalDrive(Memo1->Lines, Memo2->Lines);
q, F' Y2 t8 q8 V& t! C - }
复制代码 |
|