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