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