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