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