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