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