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