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