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