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