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