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