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