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