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