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