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