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