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