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