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