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