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