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