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