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