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