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