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