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