找回密码
 注册
搜索
查看: 6743|回复: 1

C++获取CPU和硬盘系列号的源代码

[复制链接]
发表于 2008-1-6 19:59:06 | 显示全部楼层 |阅读模式
代码框架,你所要做的仅是修改WQL语句,具体可看MSDN。以下代码为简介起见,一次返回所有的CPUID或硬盘厂商系列号& w; l3 i8 s) m* f
  1. $ u1 I$ K4 H1 h7 h% W" q" G& t
  2. #include "StdAfx.h"8 |3 V% z! f- T3 k! x& Y! @; t
  3. #include ".\puiddisk.h"1 B( T" k5 `  v7 z7 {3 M
  4. #define _WIN32_DCOM
    . m8 h; n: v% d
  5. #include <iostream>
    2 q0 j  V5 a. e- }
  6. using namespace std;
    $ Q6 }6 C) ?4 F4 H7 b
  7. #include <comdef.h>& b$ R% @" O7 x
  8. #include <Wbemidl.h>9 D8 i# o0 B1 @' ^& t9 O% K
  9. - L5 o' j- T, E) u, @
  10. # pragma comment(lib, "wbemuuid.lib")4 o$ _6 N: f# O! f
  11. CpuIDDisk::CpuIDDisk(void)6 F% g+ V# k3 E. h# Q) T, t/ U
  12. {. r( H% U2 d) Q4 h; h$ w! ?- j3 W
  13.     GetInfomation();
    " r0 B0 [+ }* P6 x+ q6 _  x2 a) F
  14. }
    ) x9 s  C4 Z, N: z

  15. " y# ~9 U1 e; R
  16. CpuIDDisk::~CpuIDDisk(void)
    & V6 n. D8 `! m8 Q) E0 p% h% K
  17. {, S6 M# [2 d+ u' A& |
  18. }1 Z$ s+ S" F, C, m" E6 q( c) |
  19. int CpuIDDisk::GetInfomation(void)
    " J. J) k! ]3 G! x
  20. {
    ; l% s7 B6 t& v" n" j
  21.     HRESULT hres;
    . I5 N- N, x8 s; c$ @! X; r9 j6 w1 b
  22.     //步骤1:不是必须的,COM只须也只能初始化一次
    / t! d1 q: L" W
  23.      hres =  CoInitializeEx(0, COINIT_MULTITHREADED );
    * ^( }( v, ]* I1 ]: P
  24.     if (FAILED(hres))
    5 i+ Q; V# ^  X. x8 K7 s  J" l, ?* ?
  25.     {2 Y6 b% |  ]' Q
  26.         return 1; //初始化COM异常:注意,COM只须也只能初始化一次( \8 N, j: J' u% z- v9 a0 d9 l
  27.     }& u: u# n% l, r% N# F1 d! J! m
  28.     //步骤2:不是必须的,COM只须也只能设置一次
    9 B1 B7 ^1 x9 S6 n' p: k2 k6 ?
  29.     //Set general COM security levels
    / _. M& Q: w8 I$ P2 H; I
  30.     hres =  CoInitializeSecurity(% H2 b* w" _2 I5 {
  31.         NULL,
    ! k; \# _4 H. p- A# F1 c
  32.         -1,                          // COM authentication4 r# Y4 w) U( j8 X8 s5 ^
  33.         NULL,                        // Authentication services
    5 `! \8 y; a' A
  34.         NULL,                        // Reserved! C, Z$ r* L, p6 r- t
  35.         RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication
    ; t% E6 I* D$ E9 ]2 Y
  36.         RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
    - K  n* _. A% \4 A
  37.         NULL,                        // Authentication info4 R7 l) v0 t) }7 y* C. j7 L' A; B% l
  38.         EOAC_NONE,                   // Additional capabilities " u1 j; B2 N4 e0 ^- S4 E
  39.         NULL                         // Reserved
      b9 J2 N; l3 y* W
  40.         );5 Q! j4 {- {+ T
  41.                      
    % V' C4 h( d* D; g2 Y" ?
  42.     if (FAILED(hres))
      T# g- @+ W$ X. f( l! ]) X+ Z2 Q
  43.     {
    0 r/ I2 h; S7 G+ _7 h# q+ w6 z4 T
  44.         CoUninitialize();& i9 O. q2 z1 n' C8 h
  45.         return 1;                    // Program has failed.
    : Q+ Q; ^/ Z* L% k
  46.     }
    2 H- f- d! _5 k) t- Y; R5 I
  47.     . p% T& a. y- ]' y6 V/ J% g
  48.     //以上不是必须的,若已有“::COMInit();”,则要跳过
    # c) p* C9 s) ~3 ]  t7 p
  49.     //步骤3: Obtain the initial locator to WMI ; _$ |$ C8 h0 B
  50.     IWbemLocator *pLoc = NULL;4 U8 U! D6 H1 \/ f1 f+ S
  51.     hres = CoCreateInstance(3 Q  z& d" L6 I
  52.         CLSID_WbemLocator,             , l" \/ e" [" a' g6 q: k
  53.         0, 2 ]+ L) b* ~) M) w+ E
  54.         CLSCTX_INPROC_SERVER, 1 t+ z; M/ V! Y  ^5 j
  55.         IID_IWbemLocator, (LPVOID *) &pLoc);
    / B( J; O6 j( E+ p: v2 Q
  56. % B" Q% N0 O' C$ Q5 f: G
  57.     if (FAILED(hres))
    3 c8 Y+ E* Q. g. B# p. k& L
  58.     {2 Q* q4 x7 R0 X
  59.         CoUninitialize();& m+ g, @" b/ F) p/ o; F8 _
  60.         return 1;//Failed to create IWbemLocator object
    $ a0 a/ \6 r. g8 S; O/ j
  61.     }! J9 y: Y+ \9 m. G

  62. ( z9 v  T2 F$ W  ^1 x/ e
  63.     //步骤4:Connect to WMI through the IWbemLocator::ConnectServer method# x; y( a  Q2 E2 A# y6 `* e  z/ E
  64.     IWbemServices *pSvc = NULL;& B( v7 V7 s1 D
  65.     hres = pLoc->ConnectServer(
    ) O% t# h! D9 i, w
  66.          _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace6 l) A- l. u2 {& O* }0 ?
  67.          NULL,                    // User name. NULL = current user% g/ s7 ^3 }  F) {
  68.          NULL,                    // User password. NULL = current
    : Y4 I0 b, L: S: [$ V# j+ B9 @/ a
  69.          0,                       // Locale. NULL indicates current% D! z$ o4 Y/ F8 r, s
  70.          NULL,                    // Security flags.  D3 Z8 V* h" E$ B1 _4 n
  71.          0,                       // Authority (e.g. Kerberos)- @+ W: n; l9 J& w$ p  Z, h
  72.          0,                       // Context object 1 H7 i9 r4 D& z
  73.          &pSvc                    // pointer to IWbemServices proxy
    : {2 V" `4 y/ h5 I0 `: u
  74.          );
    9 X. e) ~$ i* X# G+ c
  75.     5 o/ p# t% m7 _$ L3 W
  76.     if (FAILED(hres))
    ' Z/ J2 \" a, l! N+ O4 q
  77.     {
    . z& _/ H) @; e( V
  78.         pLoc->Release();     1 V' c! Q' H; [: K; A
  79.         CoUninitialize();" Q7 W" u+ {0 _" j0 ?
  80.         return 1;                // Program has failed.3 n: N7 N* C  w' K& X8 [
  81.     }
    6 N4 u4 M! ~$ g2 ?: C
  82.     // 步骤5: Set security levels on the proxy
    ( a5 U% S5 O( B. p+ b3 W6 R
  83.     hres = CoSetProxyBlanket(6 r4 ~- p' _; R% u5 E' L. a1 u
  84.        pSvc,                        // Indicates the proxy to set+ T6 A6 x' W0 R6 [+ ]
  85.        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx, ~8 E' \8 R! j+ E: p/ z+ H
  86.        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
    3 H1 `% F$ |  k1 t$ e
  87.        NULL,                        // Server principal name
    ' I# [% i. {, U  j" S% N$ b
  88.        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx
    6 C( e  Z: j& v' x* U; s
  89.        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx# f* l8 M1 q4 Q! e! u8 k
  90.        NULL,                        // client identity4 l; W# q! Z$ p. l4 m4 Q- N3 x
  91.        EOAC_NONE                    // proxy capabilities
    $ S5 m2 S# |9 Q; s9 ^0 W
  92.     );
    . R5 o' C( ?% d& ^3 B

  93. ; _8 l0 V4 X, z8 x
  94.     if (FAILED(hres))5 ?( g5 H  R& O+ i' D% z
  95.     {1 ~8 L9 s- J2 G$ C& ^4 v# _
  96.         pSvc->Release();
    / _) Z9 q) `' c0 K! ?/ N6 u
  97.         pLoc->Release();     ' P( z/ b3 S& D7 g2 z7 g
  98.         CoUninitialize();/ f5 z+ |$ A- `* @1 h; P6 ^
  99.         return 1; : v% H9 F7 C; A. Q& Y% i
  100.     }
    ; X( P% f: d! a% k- t
  101. & K; j0 a# g/ X* m' W: [
  102.     // 步骤6:Use the IWbemServices pointer to make requests of WMI ----
    " Y- U* D+ W" T
  103.     IEnumWbemClassObject* pEnumerator = NULL;! {9 n/ s( U) L0 T0 n% {
  104.     //计算CPUID
    + ?& N( |# q4 A: m: k& |7 s& m8 Z
  105.     hres = pSvc->ExecQuery(4 l$ y5 X! }. X0 P5 q$ t
  106.         bstr_t("WQL"),
    , G/ F2 c$ C$ f
  107.         bstr_t("SELECT * FROM Win32_Processor"),//Win32_OperatingSystem! E/ ]$ z* K' x5 E+ `/ a( l' v
  108.         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, & [- i; g, K! L4 k
  109.         NULL,: j* i  }- J. L7 O$ I- H" ^% u
  110.         &pEnumerator);
    8 N% p; b8 F& }8 ?2 i
  111.    
    3 g) @) P( O0 N2 B& v
  112.     if (FAILED(hres))
    $ B/ S) K- x# Y! m4 k" `# T1 }
  113.     {
    ( U& t+ F( n1 W  D8 E$ V3 e
  114.         pSvc->Release();
    # M: W% k$ T+ S( {7 |4 E* A
  115.         pLoc->Release();# S' p) q7 k. d" W
  116.         CoUninitialize();, q, r( F; }/ M. A9 ]& r( i
  117.         return 1;& p& s8 d7 E! x' w
  118.     }0 q' W6 b( R9 C* P( d
  119.     // 步骤7:Get the data from the query
    ' r9 i5 ?/ i* Z' E: S) `5 G8 f( I8 z% n
  120.     IWbemClassObject *pclsObj;# G6 }$ \9 r& G8 d
  121.     ULONG uReturn = 0;0 R5 H+ r; f& X0 Y6 C
  122.     while (pEnumerator)
    , m5 v+ f0 {1 Q
  123.     {
    & O" A, K* Z+ l" @" @
  124.         HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 5 B& p4 ^/ T5 C8 ~) w% l! A
  125.             &pclsObj, &uReturn);7 V5 o2 J! b9 q4 E" ?
  126. $ ]5 J* ^! x& n$ @
  127.         if(0 == uReturn)
    0 f- x2 G6 r5 I( j* d" A
  128.         {
    ) i/ ~1 K' @% z- s& z
  129.             break;
    , B) ?% g, ]9 S. j& r: _
  130.         }
    4 S( Z8 D+ a% z2 ^
  131.         VARIANT vtProp;) a$ a4 \9 M& Y( K4 O
  132.         VariantInit(&vtProp);; n0 R8 _& |+ i8 J3 k# p# D* w- D
  133.         hr = pclsObj->Get(L"ProcessorId", 0, &vtProp, 0, 0);
    : f- H7 ~/ b" T
  134.         strProcessID=_com_util::ConvertBSTRToString(vtProp.bstrVal);//strProcessID:类级变量
      c0 Z+ u# S) i/ {4 L
  135.     }9 |3 M4 |6 x# s$ y# r
  136. 4 D4 F& z8 L) {! I: B
  137.     //计算硬盘系列号
    ; w7 g- {; `/ @, t
  138.     hres = pSvc->ExecQuery(7 Z/ y" ]$ D! s4 @* C( U  j
  139.         bstr_t("WQL"),
    & l9 |) s; ?5 g" m
  140.         bstr_t("SELECT * FROM Win32_DiskDrive"),4 N: g( {  Q# m- @( v' A' J$ }
  141.         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, & u% B7 N! c; o6 |6 h0 S
  142.         NULL,* j) W6 G: w! H2 O7 |
  143.         &pEnumerator);7 x0 ]# r  O+ U1 F
  144. - d) a  I5 h$ E  E, m2 R7 u2 T
  145.     if (FAILED(hres))
    $ |8 ^* R4 R4 G2 K
  146.     {, v9 h# i3 n$ Y4 Z' L
  147.         pSvc->Release();: @2 K+ b! v2 M# X5 @4 m. {; b
  148.         pLoc->Release();. y. e: p) }3 R
  149.         CoUninitialize();7 U+ T1 d2 C- x9 A, O4 s6 s/ a# B
  150.         return 1; 2 J3 C7 Y7 }  F4 B8 L" l4 g, t% ~
  151.     }
    - V4 r" v' E4 d* A
  152.     while (pEnumerator). X& D/ A/ [, u" E
  153.     {1 _- O, L! U; g
  154.         HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, - i: }. T, k- _: g7 Y
  155.             &pclsObj, &uReturn);( E% s( {1 v9 U& e9 V) C9 t" p

  156. $ |4 [4 C% t  k  e1 ]0 ]* l) m
  157.         if(0 == uReturn)
    ( M0 p2 q' S# Y/ b$ E
  158.         {
    * K! ~( f* T0 z+ a3 z* b# \
  159.             break;2 i! M* u5 I2 d' W( i
  160.         }
    , @; w" H1 O) n# |/ ^' C
  161. 8 [  f: X% @( g7 P! K- V! [2 r1 M
  162.         VARIANT vtProp;
    2 v' z/ T( E" Y
  163.         VariantInit(&vtProp);1 F3 B6 _% \3 m+ H' r" E! l5 I! v
  164.         hr = pclsObj->Get(L"PNPDeviceID", 0, &vtProp, 0, 0);
    ; q1 Y0 x+ w& n: [" l. D2 H$ P+ ]1 J
  165.     strDisk=_com_util::ConvertBSTRToString(vtProp.bstrVal);0 v, S1 F: j- H: F
  166.     }
    5 R0 W4 n, z) ^; B. h' f
  167. 4 ?1 ]8 _2 ]+ h" u3 M
  168.     pSvc->Release();# x2 R" k: B0 i8 k. I
  169.     pLoc->Release();
      t" Q  p9 @* h  J# A
  170.     pEnumerator->Release();3 X$ }( ~5 L* U$ s! {
  171.     pclsObj->Release();
    " h* B6 H$ n. W7 e, ], f
  172.     CoUninitialize();) M, _4 g  g( n' G0 O. x8 c

  173. + d  k7 N6 N( N& {7 ]
  174.     return 0;   : z* _5 j( O" p: |, n4 J2 ~2 Z/ y
  175. }
    : D! l& h3 t' i. E% X& J5 ^
复制代码
 楼主| 发表于 2010-10-11 19:21:05 | 显示全部楼层
本文代码经ccrun(老妖)在Win2k下试验成功.
3 `2 S+ s3 m3 v
+ F, j3 c9 U/ O" g+ v: q( R#include <WinIOCtl.h>4 O$ e0 h+ w: s6 S$ l
#include <stdio.h>
, ?" w3 O  f) E! T2 h/ a
5 s' a# t" S1 d! O9 e8 I+ J9 R& `#pragma inline7 K: i& ^- l4 T; b# m0 V
//---------------------------------------------------------------------------
5 M% O; C8 |; G; G( I5 f' d// IDE NT/2000/XP专用变量
! u  j2 ?* i- w* K8 c# o#define GETVERSIONOUTPARAMS     GETVERSIONINPARAMS
9 g; s3 d6 Y# d# T+ P#define DFP_GET_VERSION         SMART_GET_VERSION
" v2 U3 ^2 m2 r; V0 p#define DFP_SEND_DRIVE_COMMAND  SMART_SEND_DRIVE_COMMAND# p/ q: a5 m0 w) `" [: X: m
#define DFP_RCV_DRIVE_DATA      SMART_RCV_DRIVE_DATA8 I3 U9 u% r8 z, f- I

  X* t9 v) w$ W- y+ tconst WORD IDE_ATAPI_IDENTIFY = 0xA1;   // 读取ATAPI设备的命令( {: T  k4 }% K# z9 S, u
const WORD IDE_ATA_IDENTIFY   = 0xEC;   // 读取ATA设备的命令; ?* b$ G8 w2 }0 J

* t2 {8 M) b9 a, q; _const int MAX_IDE_DRIVES = 4;
" b3 n3 }- @1 N; T# R4 u: I  q) M9 O: O
// SCSI专用变量
7 J6 c* H9 L9 `% H8 m  ^% o. @0 Jconst DWORD FILE_DEVICE_SCSI             = 0x0000001B;
9 b, G/ E' t, l9 m- S# rconst DWORD IOCTL_SCSI_MINIPORT_IDENTIFY = ((FILE_DEVICE_SCSI << 16) + 0x0501);: d3 D! j& `/ e' s2 Q, n, ~
const DWORD IOCTL_SCSI_MINIPORT          = 0x0004D008; // see NTDDSCSI.H for definition
2 P. @/ D" E  Q9 }const DWORD SENDIDLENGTH  = sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE;# n  `$ }3 B- O" C/ D/ M

6 N& n5 t7 N5 s8 Q4 `* itypedef struct _SRB_IO_CONTROL! \# O/ b+ I+ [$ v
{
2 }# L% W3 }! I% z2 z% r    ULONG HeaderLength;
6 E3 h% a. D9 Z9 U6 q2 `    UCHAR Signature[8];
- T* k$ P7 w% `( `; k    ULONG Timeout;
6 Z/ D* \! p5 T$ C( g8 \9 `    ULONG ControlCode;1 C) g3 x# L2 X  F! A
    ULONG ReturnCode;( s( C5 D1 L* b* N( O: y; _* \( s
    ULONG Length;
+ a1 ~7 O1 o+ ~5 e4 l}SRB_IO_CONTROL, *PSRB_IO_CONTROL;
; H/ F  ]  r$ S& Y/ ~( ~" d& B$ R  c' A
// 读取的主函数
0 L" V# D, @# }2 D: b% h. g  Bvoid __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList);
# i8 @/ |6 b7 m  X4 g
, ?- d/ o5 l1 i4 \& F! t3 a+ D) D// 辅助函数1 q$ ]( z6 @8 R6 D1 _
char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex);: K- s2 y! i' v" }! k2 Z
// NT/2000/XP函数
8 X, k5 D$ r% }# [- Yvoid __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList);
- s/ I/ W6 T6 ebool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,& X; N6 F+ a& f4 y  H4 s$ e
        PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd,
9 I3 y4 t$ i1 X) j        BYTE btDriveNum, PDWORD lpcbBYTEsReturned);
; s9 |6 W+ s$ D# B" Q// Windows 9X函数* [+ |, `- h/ F! \
void __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList);
: Y: H0 T9 h: Q& O1 G4 ovoid __fastcall ReadPhysicalDriveOnW9X_Ring0(bool IsFirst, WORD BaseAddress,
$ m& R4 f$ R; {: W$ o8 M        BYTE MoS, bool &IsIDEExist, bool &IsDiskExist, WORD *OutData);
- q# h& b8 I7 A
/ k+ \7 e' G9 E$ |// SCSI读取函数(for NT/2000/XP)
$ r6 t& n. R) GString __fastcall ReadIDEDriveAsScsiDriveOnNT();
6 ]+ y( h4 k4 @( @4 N7 l3 U; ]' j1 I: s//---------------------------------------------------------------------------
! X' U) N2 V6 }& g( R8 ?// ReadPhysicalDrive) d' C& S6 K' x7 m/ L# m% `
void __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList)
" b/ z4 e3 {2 u5 p: [& }; L4 R{- I% G) J7 Y& z  c
    switch(Win32Platform)
5 r# s& \/ I% b5 O7 b% N    {
9 Z1 V! b( d4 I8 J* h) T5 b        case VER_PLATFORM_WIN32_WINDOWS:
1 r5 c: i' Y/ `  R            ReadPhysicalDriveOnW9X(pSerList, pModeList);7 g, L4 u9 R/ |8 G0 ]2 u; K
            break;8 H) [% a! D( `! l. [7 T- B2 Z
        case VER_PLATFORM_WIN32_NT:$ E' x' R8 E- j
            ReadPhysicalDriveOnNT(pSerList, pModeList);
+ \9 @% M+ n, P; e! }- C$ ^            break;5 x# T/ H2 k. Z. ?/ \4 h5 Y
        default:
1 J2 E( ?$ ]( u7 x( q7 i& u, R' T/ H            break;' j" U+ X0 E) j8 ?7 V+ N7 [
    }9 o) r8 a) c7 q
}
- Z1 h1 i' [- k0 P/ ?7 Z. C& T$ E8 a//---------------------------------------------------------------------------& ?+ g7 B0 }6 u) D- E; Z4 f
// ConvertToString. t( V9 B: o) D& F
char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex)
$ \+ Y  [: S2 y& Y3 Y1 g# w9 [{3 X- ?5 ]. m7 s7 R% C
    static char szResBuf[1024];
3 R! x8 o5 E+ ^: S- ~9 p3 {4 V# Z    int nIndex = 0;" k: t! ^3 o& j2 w% w1 Z) K
    int nPosition = 0;
' B  S7 i- E0 T! h
* \& o; n+ j6 B# T    // Each integer has two characters stored in it backwards
+ I9 P! y: g$ l& ^' I/ b    for(nIndex = nFirstIndex; nIndex <= nLastIndex; nIndex++)4 m4 l/ X6 d' f: h; u3 @3 G
    {: a; t- R2 O( L: t
        // Get high BYTE for 1st character3 S& D6 `6 C% r- L2 A
        szResBuf[nPosition] = (char)(dwDiskData[nIndex] / 256);0 \- R* H( C+ H8 n
        nPosition++;7 i* ]& _0 u) r- {
( g  E3 N6 K1 U
        // Get low BYTE for 2nd character
- R* P( A* v9 M        szResBuf[nPosition] = (char)(dwDiskData[nIndex] % 256);
' J5 \2 J' u# R' W        nPosition++;% W  \6 A' J' {2 c
    }
2 U/ P$ c& Q$ q1 L$ Q( B$ I2 R0 v# c2 W
  Y! E9 g. u9 Y) K& g    // End the string+ E' o1 E& r- ?# B* P/ `
    szResBuf[nPosition] = '\0';# @! S9 i+ e" F, J# a  f+ Y* j

& Y7 q1 C# ]. P3 J2 n    // Cut off the trailing blanks! T' g% ]9 Z  D' s( C
    for(nIndex = nPosition - 1; nIndex > 0 && ' ' == szResBuf[nIndex]; nIndex--)
# U+ ]8 g0 i, S% J6 x        szResBuf[nIndex] = '\0';
6 ?4 N) T! s9 D5 [2 O. Y
. ]! E! n. a# S- S    return szResBuf;# z3 }. G2 S5 d7 J: k
}, ^: f$ h) t2 A5 c! _
//---------------------------------------------------------------------------
) U, B, s  X4 T+ U6 P7 N4 C// Winndows NT4/2000/XP 代码
; A; G# H; S' E* ^& W2 e//---------------------------------------------------------------------------
: ]/ V4 y& w* ]0 v1 }1 N" A: C# h// ReadPhysicalDriveOnNT  t/ v) }4 \" k8 N/ g  `1 r( v+ i3 Y
void __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList)
8 u  S. ~9 k2 x0 }- h# S{# b7 n  j. }" ^* l: }6 ?
    // 输出参数5 g9 r3 }' e5 x% A# Q) s
    BYTE btIDOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];; y0 G: @: n/ t$ @, [' e
. i. a" h0 a* o
    for(int nDrive=0; nDrive < MAX_IDE_DRIVES; nDrive++)# Y4 n+ n3 Q: T7 |; ^: r
    {
2 @8 n! B9 X' N5 H' q: H9 ?* l/ t        HANDLE hPhysicalDriveIOCTL;8 W) Z# M( }+ r: |9 |0 L
        char szDriveName[32];9 L/ {* M. C9 k

& A% ?( ?; ]* c8 \        sprintf(szDriveName, "\\\\.\\PhysicalDrive%d", nDrive);" b& G7 n& W+ p" i1 l
        hPhysicalDriveIOCTL = CreateFile(szDriveName,# Z3 N( p% a1 t1 H) z
                        GENERIC_READ | GENERIC_WRITE,
8 r. h# e# ^6 s) `                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL," L$ s! K3 d0 W! H
                        OPEN_EXISTING, 0, NULL);- \3 K2 b0 b/ [& q: y
4 z! s+ \! `: p/ p" y
        if(hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)/ r+ q+ m* a2 t$ [8 E: N  @
        {
  T  J+ ~( o! s            DWORD dwBytesReturned = 0;, A/ n/ c, r: e
            GETVERSIONOUTPARAMS gvopVersionParams;% E0 X7 i& i! _8 D; f
; c1 L& i, ?  d$ C) H
            // Get the version, etc of PhysicalDrive IOCTL
; g8 K! A5 b2 k            ZeroMemory(&gvopVersionParams, sizeof(GETVERSIONOUTPARAMS));6 q: Z" F% {! Y$ E' l

/ g$ K: D6 ~! m7 }) V            if(!DeviceIoControl(hPhysicalDriveIOCTL, DFP_GET_VERSION,0 @0 }% x1 l2 q$ `- R
                    NULL, 0, &gvopVersionParams, sizeof(gvopVersionParams),
: f) O3 `0 j8 M* g% @                    &dwBytesReturned, NULL))5 _1 h9 p, M9 X
            {
. Z! ]$ `7 A) [4 J                continue;/ ~: v: d4 h* W* d& o
            }
  }. X+ p% ]. a+ c: t. h  W
- {( P- T3 A1 n3 E/ B6 [' o" v4 X. c+ V            if(gvopVersionParams.bIDEDeviceMap > 0)
0 ~# ?+ |: r: B5 [9 b            {0 V: N6 F# O5 R) y' v- j
                // IDE or ATAPI IDENTIFY cmd
* d. C( N, M% F6 w) P                BYTE btIDCmd = 0;
% T2 a* }. C4 [                SENDCMDINPARAMS InParams;( p; @& y, t- y( ^
                // Now, get the ID sector for all IDE devices in the system.. c, Y2 l& ^! R9 a: Y" X# t
                // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,9 b6 q0 s5 C; X6 c( j+ a( J* R
                // otherwise use the IDE_ATA_IDENTIFY command
4 k+ F7 [* l6 N. k( E, _/ s9 ^                // 具体所得结果请参考头文件中的说明( p2 ]0 ?1 u% s% m# T! w! G
                btIDCmd = (gvopVersionParams.bIDEDeviceMap >> nDrive & 0x10) ?
, T' ^. Q1 ?$ S                        IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
' A( Q' t2 e0 T0 T( M$ Z                ZeroMemory(&InParams, sizeof(SENDCMDINPARAMS));
# ^+ b: }' J" g. Y; N6 `. c                ZeroMemory(btIDOutCmd, sizeof(btIDOutCmd));6 p6 I# ]! j% `# j

# G! c2 k# p4 L. y- ?6 `                if(DoIdentify(hPhysicalDriveIOCTL,
2 K: H6 s1 M0 [                     &InParams, (PSENDCMDOUTPARAMS)btIDOutCmd,& Y9 @# Z  B- n3 j; K, A
                     (BYTE)btIDCmd, (BYTE)nDrive, &dwBytesReturned))( S3 b% y/ E4 S4 d1 i) |
                {- |* X% I7 v, X- y. T9 w( ^
                    DWORD dwDiskData[256];
. c2 H  V" y5 H& R5 O                    USHORT *pIDSector; // 对应结构IDSECTOR,见头文件$ W1 o* o, o& X, T. I
                    char szSerialNumber[21];
0 k! P) J  x4 g                    char szModelNumber[41];
+ ~) u5 C6 l. ]6 Q. d3 n! v. `" U, |) T6 ]" m7 K. Q" B
                    pIDSector = (USHORT*)((SENDCMDOUTPARAMS*)btIDOutCmd)->bBuffer;( Y, k- J4 u3 F* O4 x
                    for(int i=0; i < 256; i++)5 I+ g& q9 a! A' w6 b
                        dwDiskData[i] = pIDSector[i];
: P  {7 A0 r' ~) F- ~+ ]                    // 取系列号
( O3 x# H, }7 C# Z; R9 X/ W                    ZeroMemory(szSerialNumber, sizeof(szSerialNumber));
" E0 _* S6 G  m3 C( V0 A/ R6 \                    strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));
6 }) o9 b2 |/ T  E( I: p, o8 }( Q: @3 h6 N0 I. |
                    // 取模型号" ?' E3 A+ O9 n% N* P1 \
                    ZeroMemory(szModelNumber, sizeof(szModelNumber));
1 i# y# ]! S, ]1 x  k1 w# Z                    strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));
1 `5 J4 B' m' s4 B, |: A" ~% m9 R" w5 m$ t) K9 c0 M1 `+ w
                    pSerList->Add(szSerialNumber);
. v+ [+ H  F! ?8 N5 X$ C+ |                    pModeList->Add(szModelNumber);
4 U! R+ @; Z$ }5 @                }
; n; i9 H* E9 U1 `9 b! Y            }, }% C; C' S5 E0 Q& ]
            CloseHandle (hPhysicalDriveIOCTL);6 _) f( z* K+ l" `! T, |2 s
        }" P9 X$ N: e4 Q( z
    }; B0 b! z2 ]9 \
}
8 n8 x: L# C# \//---------------------------------------------------------------------------
2 R/ B  E8 s& L; _// DoIdentify
& O1 s# s3 I4 F) x( dbool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,+ m5 |+ Q5 P7 l5 d, z
              PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd, BYTE btDriveNum,9 B( b# |* V6 h" f" i8 e# S7 r3 q
              PDWORD pdwBytesReturned)
* u# q+ D6 ^0 k. Q' s! \5 C8 q{, T- u! X# u3 Q; d
    // Set up data structures for IDENTIFY command.
) S2 Q4 X0 B. D( c& y9 B% u    pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;+ m8 ?! h4 {% s. ]# ~
    pSCIP->irDriveRegs.bFeaturesReg = 0;0 \& p/ M! n" Q
    pSCIP->irDriveRegs.bSectorCountReg  = 1;
$ D4 Z# r" e3 T- ?3 |& c6 H) A" y    pSCIP->irDriveRegs.bSectorNumberReg = 1;# z; Z) C0 k( j
    pSCIP->irDriveRegs.bCylLowReg  = 0;
5 [: Q! D8 M; b( |% |    pSCIP->irDriveRegs.bCylHighReg = 0;- ~$ O0 m4 I- }

! B1 n' {4 {: ^, Q6 P5 W    // Compute the drive number.(主盘和从盘所对应的值是不一样的)
" J, N' i  D" s$ g) E: ]    pSCIP->irDriveRegs.bDriveHeadReg = (btDriveNum & 1) ? 0xB0 : 0xA0;
+ u# Z5 V$ P9 |+ u; ^. }0 o" q; r' W
    // The command can either be IDE identify or ATAPI identify.6 o  ?: u+ ]1 t5 ?$ l7 i2 [
    pSCIP->irDriveRegs.bCommandReg = btIDCmd;
% S( }1 D8 W+ T( ?0 ?    pSCIP->bDriveNumber = btDriveNum;
6 p+ e7 V$ x- N- L, Y    pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
; D. R0 g/ K* d1 H6 H' r3 S1 a, ?, G: F3 U9 U9 k4 Y+ m% ^* y4 H
    return DeviceIoControl(hPhysicalDriveIOCTL, DFP_RCV_DRIVE_DATA,
5 y' X9 H' o; S           (LPVOID)pSCIP,
" O, P2 w6 ~& g) O* f           sizeof(SENDCMDINPARAMS) - 1,. T4 D" A- b/ k( Y. c
           (LPVOID)pSCOP,& I# ~2 H3 U  C% }
           sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
! }3 n7 _& k( |9 Y0 `, `& g0 B           pdwBytesReturned, NULL);
' M& x: l$ S' L% w) ?}
9 q3 n, ^! n6 z0 G/ D9 j//---------------------------------------------------------------------------
2 c3 I8 d  r) @// Windows 95/98/ME 代码$ a6 g9 a& y: d' Y
//---------------------------------------------------------------------------" N1 P( ~/ u  J' y" O
// ReadPhysicalDriveOnW9X
" {: ?" _  S( H6 C- d7 W8 x! Zvoid __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList)
$ P# ?( ^/ P# W7 D, i{
: F! b! U4 Q8 Q% j: l+ Z- X+ C% B8 h    WORD wOutData[256];
( f; Z( S- x1 M6 [* X  R    SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
; T* B, I3 M7 u7 p0 n! J& q' {0 S3 p* Q* e! g
    // 经过测试,发现第一次调用而且Drive >= 2时会在Ring0代码中出现错误,导致蓝屏。# I$ C* j5 }* Z% f1 n9 r6 j% y
    // 经过N(N > 15)次的蓝屏后仍找不到原因:(,不得不在这里增加一段无用代码以1 u  m" [7 ^2 f! Q4 S& D$ r
    // 避免蓝屏的出现。(期待高人能指出原因)/ i5 @& m7 L! w- s, \% ^1 V
    for(int nDrive = 0; nDrive < 8; nDrive++)
+ O) Y5 ~( x& R( t. n& a    {7 z6 `' H7 n0 }+ P) V7 b, {. ]  u9 C' b
        WORD dwBaseAddress;0 f0 b" p: Q7 H5 `
        BYTE btMasterSlave;         // Master Or Slave
4 @, V/ ^; X1 ~1 Z' K" ]        bool bIsIDEExist;
' P% b- Y. d4 d7 B/ d" g# x        bool IsDiskExist;8 ^- P3 ^2 H( Q; C" _4 ^
9 [4 s( [2 i0 U+ ?7 }0 @
        switch(nDrive / 2)
6 i% Y, o4 i: T+ n        {
  _- Y/ M- C5 f! z  \* H* H! O, `  ?7 m            case 0: dwBaseAddress = 0x01F0; break;) C2 P; o( s& b# D$ I+ H# Z1 @& j0 E
            case 1: dwBaseAddress = 0x0170; break;
8 w/ \( u: z' l& i            case 2: dwBaseAddress = 0x01E8; break;
; e; H/ A/ I+ ^; Y" v8 ^            case 3: dwBaseAddress = 0x0168; break;. R1 S  B/ f$ h* H3 y; m; _
        }
7 S4 ?- r5 K9 d$ }% {4 S  J% ], Z- B: a9 |
        btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0);
6 ]9 B: p2 L% q7 n$ q, m4 b9 |2 M
        // 进入Ring0
4 }! A# L9 @3 Q% Q        ReadPhysicalDriveOnW9X_Ring0(true, dwBaseAddress, btMasterSlave,  k; v5 {% _8 W; x0 ]2 \& y
                bIsIDEExist, IsDiskExist, wOutData);
, `( ~! e, a+ R6 h  d    }
2 Q9 k; d  b# V. ?
* M. O9 t& D( k7 G/ u7 A' K5 m    // 开始读取
) g; P% {; Z- X% {0 E$ U  v* Q    for(int nDrive = 0; nDrive < 8; nDrive++)
/ y$ I$ U) E; p. i0 ], S    {
0 J0 W9 _$ X3 v3 O        WORD dwBaseAddress;
' w- R% R" B" t5 w, w; k        BYTE btMasterSlave;         // Master Or Slave; S1 D9 l3 B& g0 Q, Q
        bool bIsIDEExist;
% c* r  N4 r& ?! K. B# \' |        bool bIsDiskExist;' m. K& c6 `0 B, K4 ^9 y7 X6 O
        switch(nDrive / 2)
' Z5 [" z& O% g5 K6 k7 b        {
7 W1 Q* L' `" Z( I8 h            case 0: dwBaseAddress = 0x01F0; break;
8 t' W1 @0 z% l, n1 H' Q            case 1: dwBaseAddress = 0x0170; break;# v4 T  s9 p% @+ ?  l
            case 2: dwBaseAddress = 0x01E8; break;
1 E3 f8 \! y6 K0 Z, ?" u! s            case 3: dwBaseAddress = 0x0168; break;* y* ~9 _; o6 ], h* n
        }4 S' u/ O8 `- N8 ?

: I& j; \8 H2 N8 ^' f: d        btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0);
  J! |  [8 g0 t% s4 S6 u1 @
! }; L2 v8 |; w        // 进入Ring0
% L- {. f& q( u1 G        bIsIDEExist  = false;9 t8 N0 P: W' c0 O# u
        bIsDiskExist = false;7 O% v$ g5 Z- c  k$ ?7 X
        ZeroMemory(wOutData, sizeof(wOutData));0 ?2 n6 X8 l3 [$ u. v
* c1 b# ?, ]$ F6 y
        ReadPhysicalDriveOnW9X_Ring0(false, dwBaseAddress, btMasterSlave,1 V4 u3 b7 h" I) O/ y4 P7 l2 Q
                bIsIDEExist, bIsDiskExist, wOutData);  I* a4 ^4 M6 s. J

/ K+ O3 d! l0 @! u) _: H5 X* j! K        if(bIsIDEExist && bIsDiskExist)  e  u% v- W6 C( B
        {
3 Y5 a* [" @1 F1 ~5 ?            DWORD dwDiskData[256];
1 F: X/ W# q0 p5 I' t3 S            char  szSerialNumber[21];
+ F( M# l' {; s8 t( g/ ^            char  szModelNumber[41];
5 `2 @1 q$ a3 G: s$ @' A4 [+ G" Q! g: n: I5 U+ R: `2 n3 Q( ]$ ?( j
            for(int k=0; k < 256; k++)
8 @3 p: c& ^. b" a: m                dwDiskData[k] = wOutData[k];
" o! c8 g% e2 J5 r% l6 m
0 e5 v4 P# W8 U, M! q2 r8 j) F            // 取系列号& b0 Q2 q" E& x: E5 C$ \
            ZeroMemory(szSerialNumber, sizeof(szSerialNumber));
( j3 X4 u) i. R            strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));0 O; U& C* s4 p9 v
* i; c* U8 Z1 y) K) _3 }; K. P
            // 取模型号
$ C+ b  d+ p8 f            ZeroMemory(szModelNumber, sizeof(szModelNumber));5 {2 b+ F3 S0 q1 G! ]2 s) }
            strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));2 s' _& j- Q" J% S' a

3 r4 _2 q: B, O3 e5 |9 u            pSerList->Add(szSerialNumber);
# L6 G: I; H  f6 M            pModeList->Add(szModelNumber);
* w8 V4 v5 Z; k0 n6 ]* a. w        }
. {0 i% ~% G( C1 G    }- X5 ]8 N9 R; w  t" Q2 w
    SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
6 ]( G) D! m4 b/ ^. w}
) |- w! z+ ?- A$ {' M( z//---------------------------------------------------------------------------
) e6 c% @' p. y3 I' y/ B1 m5 p// 为防止不负责任的转载者,在此注明原出处信息,请见谅。
3 C! U6 N6 ]% _! f// 资料收集整理:ccrun(老妖),欢迎光临C++Builder研究: http://www.ccrun.com
/ m3 o3 A, f& k//---------------------------------------------------------------------------! W; X( {2 U6 [9 W9 |6 m( M  ]
// ReadPhysicalDriveOnW9X_Ring0()
- N8 S  e) y0 J  v- s  F& ]$ T) M6 s( e//+ x. l6 A* q& s/ k5 Z4 b
// dwBaseAddress = IDE(0,1,2,3) : 1F0h, 170h, 1E8h, 168h" `) m4 a7 U9 s( \
// btMasterSlave = Master(0xA0) Or Slave(0xB0)) z: _! a( G! ^* ]
//---------------------------------------------------------------------------6 B$ C; f% N* e! }
void __fastcall ReadPhysicalDriveOnW9X_Ring0(bool bIsFirst, WORD dwBaseAddress,
: }8 ^2 P. I  T+ P        BYTE btMasterSlave, bool &bIsIDEExist, bool &bIsDiskExist, WORD *pOutData)
1 Y  t7 ], Y" `7 ~* `{3 |' o% M1 F# g, X- N; G) C
    BYTE  btIDTR1[6];8 ~. z  L. Q, d+ Q- a1 k0 R) S0 N
    DWORD dwOldExceptionHook;
& a$ C+ v' d0 v& N4 k7 b    const int nHookExceptionNo = 5;
& t, P% P1 {) j
6 \+ y. D. U+ L2 d/ c9 @/ O    BYTE  btIsIDEExist = 0;$ p4 b7 w' @5 f- o& q: y
    BYTE  btIsDiskExist = 0;
' E( E% s: b0 Q; M; _, W    WORD  wOutDataBuf[256];0 a2 I+ R. G  B  ]1 M0 e, @
3 k  w9 W4 I2 Y( a) O
    BYTE  btIsFirst = (BYTE)bIsFirst;
0 d" G% B: A& z" Y" H% {8 H& ~4 ?9 M  k
    const BYTE btBit00 = 0x01;$ D- k/ |7 m1 t5 [3 z$ z& {3 Q5 e
    // const BYTE btBit02 = 0x04;, c3 L) A0 r; d0 r
    const BYTE btBit06 = 0x40;1 G5 _7 p9 w$ |! X
    const BYTE btBit07 = 0x80;2 W) b3 w. C% w
    // const BYTE btERR  = btBit00;
' V$ m& j, a5 S9 p: `    const BYTE btBusy = btBit07;
, K; S* }, ?# ]" D0 Q8 }0 m# B    const BYTE btAtaCmd   = 0xEC;
! S& G$ J5 t1 M  Q    const BYTE btAtapiCmd = 0xA1;
: s. n% J0 F2 p' P" ^
4 f: i! g/ s; p( Q% I' E4 \    __asm
  U. W: o; T5 F" o2 [% M) E    {" D# Y1 q. r, r4 ^/ d. |
        // 必须先执行这条语句
  n, Q7 }! a. R+ d2 m        JMP EnterRing0
& P7 u+ V: P' i6 X/ y& X- _5 \0 q3 `" I4 l
        // 定义过程
" n( O1 D7 K3 y/ B2 @        // 等待IDE设备直到其不为忙为止" E* P  E" n) i  A, i2 |; q" E! K
        WaitWhileBusy proc
" Y8 I2 Y" Z/ k: [$ g- b& I- v1 K9 \8 n+ j! n
        MOV  EBX, 100000
! u- k$ c+ p6 H+ j' H) s        MOV  DX, dwBaseAddress8 w9 q0 \) U! C4 k; @! P; D9 j& R
        ADD  DX, 7
9 g& w4 M+ \2 c7 X  s" |* Z- y% c0 \7 q; j5 a
        LoopWhileBusy:+ h; }% q% R, V$ J5 [+ Z- T

( f4 d6 p. ]" {6 a0 g5 Y        DEC  EBX% ^- w# _9 K, J3 `" z0 I* B4 f
        CMP  EBX, 02 x4 y3 ?) S% p7 ~. {
        JZ   Timeout
: _, W1 w/ l) q1 @! X1 M5 l1 ]        in   AL, DX
7 B2 ?: z% O) b7 a' [        TEST AL, btBusy
" E( L) v+ E8 \: ]        JNZ  LoopWhileBusy3 g; O( B. K6 W
        JMP  DriveReady% B2 K4 Z7 O) M* N

- V+ r; B. l" o# G$ x2 y        // 超时,直接退出- N; A* s" x9 E, [
        Timeout:8 }  B  g; [3 a6 T2 g: x
        JMP  LeaveRing0
& f6 W1 A+ D. |7 r& |        DriveReady:' E2 R$ @1 y9 \( {( w7 r9 s
        RET
0 v2 W) E$ v5 ~6 b) z2 N% G        ENDP   // End of WaitWhileBusy Procedure% O- h/ C7 Z$ V: c7 C

! J1 F% j1 e8 E# n% i& _  a) B6 m        // 设置主盘和从盘标志: Y" \% {7 h- T) ^
        SelectDevice proc
* y" D! o% }8 r! [1 m+ X* E( X- H% L" q
        MOV  DX, dwBaseAddress2 z' L& \* r; @% g% N! Z
        ADD  DX, 6& \5 ?2 D* d3 e7 l8 k
        MOV  AL, btMasterSlave: ^  m  v" ~- R" V
/ {, [; v" u1 U3 `8 K; t
        out  DX, AL
! R. d" i8 o! }5 I) X        RET/ }: o* S. y) H' z% a% ]6 c" @

* @+ U5 ^, O6 V% E+ d; u$ |        ENDP  // End of SelectDevice Procedure
9 [7 T4 v# M- s: S
9 o( H$ Y$ w# h& B1 Y* C2 t        // 向IDE设备发送存取指令
7 X+ W& G7 B% C* `        SendCmd proc
# o" I6 i9 f1 j. W$ D/ j
$ E: g$ R4 z$ y; J% w5 B, Y        MOV DX, dwBaseAddress# w" b6 z7 a5 y# [$ t! h4 u, Q
        ADD DX, 7
! E- M& o; F1 a) H9 c: R% K* F        MOV AL, BL // BL是主从盘标识,在过程外设置+ E3 h9 Y+ A0 T
        out DX, AL/ V& [9 ^, [+ v6 x& Q" g
        RET
& h& ^: k% \  Z; y% V+ P        ENDP  // End of SendCmd Procedure
# o: ?7 @* E7 m- W& i( z/ k# T) |, |9 G2 R+ N5 @
        // Ring0代码6 t# i- @% V. U% C( i5 e
        Ring0Proc:
+ Y8 T7 J: i1 [% L, S, p        PUSHAD
/ T/ C# F/ V% K        // 查询IDE设备是否存在
$ ^, D: G7 a) A5 r        MOV DX, dwBaseAddress
7 a1 \7 H( [9 N% w# g* o  o+ a        ADD DX, 7* A# C( m9 v( U- E3 H# D" Y! m
        in  AL,DX
% S6 }4 m9 ^! V  [0 O- p* M6 ]$ B# i5 i& F4 X) H
        // 当AL的值是0xFF或者0x7F时,IDE设备不存在,这时候直接返回
9 I# p0 J( _6 \* z# Y        CMP AL,0xFF
2 g' i% U4 A5 F( ~        JZ  LeaveRing0" T2 G1 p; a9 y6 P/ u
        CMP AL, 0x7F
/ T2 V2 D, V# ~( ]- V$ I$ b        JZ  LeaveRing04 b$ x; p6 D9 n% [! v& t7 ?9 t& C

: w  r) E0 ^/ O& r* F  I        // 设置IDE设备存在标志1 |5 A  u+ Q; Q8 R8 t; a5 R  j) l! v
        MOV btIsIDEExist, 1% \# q2 d, c' ]/ m" P) N( f
, S4 O1 G. m3 |6 W- q  L
        // 查询IDE设备上的驱动器是否存在(有IDE插槽在主板上,但是却不一定有硬盘插在上面)) Q4 M, K7 q" }9 ^  n6 E
        CALL WaitWhileBusy
1 x, v; K, q& N9 m        CALL SelectDevice; U' j$ |( d. j
5 }( n3 K% U! q3 u; [4 g* |5 J
        // 如果是第一次调用,则直接返回,否则执行下行语句时会出现蓝屏
5 k8 t0 R5 W: x' B        CMP  btIsFirst, 1+ J. R; ~. _5 h/ k+ V
        JZ   LeaveRing02 V9 W; @$ Q2 Y7 I/ f

* q  h: P4 K/ l        // 第一次调用时,如果执行这行语句会导致蓝屏,Why???
' y+ W. ^6 l3 }2 O        CALL WaitWhileBusy7 }2 H$ h& S2 a! i% R8 p

8 f' f0 D  Q' N" l7 X  Y+ R        // AL的值等于cBit06时,不存在驱动器,直接返回
. o& t: _& K( V9 C        TEST AL, btBit06
) y1 \5 ~  T6 n2 K, @9 ?        JZ   LeaveRing0- U" S. L" P) e  B: ~

$ U8 I& F6 _4 M+ L+ [; w        // 设置驱动器存在标志; p, ~7 I8 D' R% u
        MOV  btIsDiskExist, 1: Z( d3 C; a+ |6 P6 q. m- J8 [1 A: v
( d0 Z! h- V) x( s! }
        // 发送存取端口命令
+ L$ p: z% N0 R' K% Q4 ~0 {( E6 u        // 无法像NT/2000/XP那样可以通过查询VERSION的值得到驱动器的类型," ]* p% o% _/ r' y- K5 T
        // 所以只能一步一步地测试,如果不是ATA设备,再尝试使用ATAPI设备命令: S; ?1 \6 u1 U& p8 P; d$ G
        CALL WaitWhileBusy& D. ~) h5 i+ M
        CALL SelectDevice    // 设置主从盘标识
$ h& N7 P0 q: E        MOV  BL, btAtaCmd      // 发送读取命令8 R$ F! o$ \0 g
        CALL SendCmd
+ r( [/ @/ X2 U        CALL WaitWhileBusy
" e, |8 d; E) q  G! G3 e, N
* u2 u6 n& O7 Q2 E3 f        // 检查是否出错1 c+ e4 `6 P( m: i: K. D
        MOV  DX, dwBaseAddress% |  K6 d* c' i, o3 b3 _8 v
        ADD  DX, 7
9 @5 K/ a: ^) o$ n& o  w
" i0 ^4 n/ A5 }% z* H" ~        in   AL, DX
% h$ K; Y" F( P  v1 _+ \
0 @4 U* T& p: x4 n/ C* S        TEST AL, btBit00
) ?) L! W, @( L% D        JZ   RetrieveInfo   // 没有错误时则读数据
. {/ f  m1 D9 y$ [9 @( I1 P3 N9 \1 D2 W" F
        // 如果出错,则进一步尝试使用ATAPI设备命令
  x  ~) D7 N# ]        CALL WaitWhileBusy
" {4 g. A+ J4 |' E5 ^7 N/ Z        CALL SelectDevice
$ ]% B. O# f6 p$ y        MOV  BL, btAtapiCmd
' @9 Y/ B4 x' v; u7 Y* [- S. R        CALL SendCmd
. Q" b4 ]% |; L$ t& \8 |5 D$ n7 T        CALL WaitWhileBusy
1 r5 N5 n6 k; n4 w9 E) |& s+ u0 l1 v3 A5 [- y5 V
        // 检查是否还出错- O$ F2 |) Y" R. O8 Z3 c" F+ n
        MOV  DX, dwBaseAddress
3 f6 y8 W- n, L' w! c9 A        ADD  DX, 78 ^. A3 M5 g; T. ?
        in   AL, DX3 o/ H  b. U0 D: w) Q- D; n
        TEST AL, btBit00, P$ b/ G$ V6 m9 {( @
        JZ   RetrieveInfo   // 没有错误时则读数据" f# v+ b/ g! W& M$ b9 r! A# _
        JMP  LeaveRing0     // 如果还是出错,直接返回" ?7 B3 m& e9 {: c/ Q4 ]; w
9 G' A9 h6 z6 F* x$ U* n
        // 读取数据
; a! x0 a) B: k1 |, E        RetrieveInfo:
- W5 I5 B  i! m% v+ Q( l) b
! H/ t3 I- w- ]$ ~        LEA  EDI, wOutDataBuf: D: Y7 J  y( Q5 \
        MOV  ECX, 256
5 ^: x+ B2 j5 Y, I        MOV  DX, dwBaseAddress# y9 _6 b7 p+ c4 x2 O
        CLD( j; p/ Y( n" F( N) t3 B
, g" E6 Z2 W% l& P
        REP  INSW% n+ t+ S6 o4 M. c. }1 a
, g# F8 D: A% i' _! Y1 _
        // 退出Ring0代码( p) }# I% d' _# u- E- J3 p+ S
        LeaveRing0:6 e* A/ B* W! h* g/ ?2 S! M4 [
& O$ t( M2 q) \' u, ^
        POPAD. r* h, e7 B; Y3 B. S8 i: |6 Z. o
        IRETD0 J! h; c: P0 _

1 C! o# @& S3 \, ]" G6 Z        // 激活Ring0代码3 S. e  E" [' ?( {5 `0 K& M  `& y
        EnterRing0:
' B5 b0 {5 ]3 w8 U& Y
$ f6 q3 \9 R0 @: R        // 修改中断门
: ~/ I1 @* Y& J; k1 {$ h6 L        SIDT FWORD PTR btIDTR1* D2 I9 O8 x  ?$ G$ M, d( N  S, x8 w
        MOV EAX, DWORD PTR btIDTR1 + 02h
9 |  C- L( u2 ]$ w  M' q" i        ADD EAX, nHookExceptionNo * 08h + 04h
2 v( Y8 a8 r: t        CLI
7 M* t! W8 ^& M8 K  y+ M
; ^. U, J" N( _/ n* R; G6 {        // 保存原异常处理例程入口; a/ b3 R# I  g5 Z( F, K6 F+ M  i9 z
        MOV ECX, DWORD PTR [EAX]$ `: u' @5 @8 l  u+ D
        MOV CX, WORD PTR [EAX-04h]$ m6 Y2 c3 J; F' N. e' D$ i
        MOV dwOldExceptionHook, ECX
4 ~  a* O7 F7 P- }4 p% y% {
& ^' }% E  t5 |        // 指定新入口2 R- [* L" K- K7 Q9 b% s
        LEA EBX, Ring0Proc' \. e* }/ g4 I0 o1 C* a
        MOV WORD PTR [EAX-04h],BX* v( x# p! D7 a1 E
        SHR EBX, 10h" _* Y! m0 e# x, |) P% y8 x
        MOV WORD PTR[EAX+02h], BX
4 a" \+ Y* B# T3 Y& P9 y4 b0 [" E0 V6 `
        // 激活Ring0代码% H1 ^' F  e. k, Q' N. p4 I
        INT nHookExceptionNo! Y/ n4 Y8 i3 j5 L  @1 P/ W

5 G% E7 k. W2 \5 R' F2 {3 `0 _        // 复原入口- B3 ?; N; R8 h- r
        MOV ECX,dwOldExceptionHook' l4 g( E* o+ s" J, t
        MOV WORD PTR[EAX-04h], CX
0 M. M. ~# T( N; M1 R' T/ V        SHR ECX,10h
8 [4 R9 [$ i9 c- A" U        MOV WORD PTR[EAX+02h], CX
0 D% Z$ P5 t) `, y        STI
, K# j! C3 @6 D1 Q    }, Y. V) T1 o, Z$ ~- F7 F* a5 y3 d
    if(!bIsFirst)
! }+ ^1 @- O/ |  x, i    {
) `7 m6 O! P! V& i/ d) a; v        bIsIDEExist  = (bool)btIsIDEExist;; y' l# h' V# D" @' J+ j# c9 S) r
        bIsDiskExist = (bool)btIsDiskExist;
$ x7 e4 T( T) i! @: G% h& l4 s        CopyMemory(pOutData, wOutDataBuf, sizeof(wOutDataBuf));9 ?/ [  x8 }5 Z* a- C5 W
    }
- g5 V- ?& [- ]0 R}
: ~2 S  O1 ]4 f3 h4 Y6 J/ W//---------------------------------------------------------------------------
2 i5 m+ Y9 a' T& q; F. B// 调用方法:% {/ a5 D/ x0 B3 z/ F8 s) r: b
void __fastcall TForm1::Button1Click(TObject *Sender)
1 E/ [* ]  C. A{
+ s( U* z5 P8 q7 Y    ReadPhysicalDrive(Memo1->Lines, Memo2->Lines);+ Q! @+ |8 p2 C2 F4 L
}6 O6 ?% O& o0 M" ~" U0 i
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2025-11-14 21:51 , Processed in 0.019444 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表