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