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