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