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