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