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