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