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