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