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