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