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