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