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