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

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

[复制链接]
发表于 2008-1-6 19:59:06 | 显示全部楼层 |阅读模式
代码框架,你所要做的仅是修改WQL语句,具体可看MSDN。以下代码为简介起见,一次返回所有的CPUID或硬盘厂商系列号
& f+ P# p) r8 P) l" `

  1. 8 S* \0 U5 Y1 A$ g, ~" S7 L* |! f
  2. #include "StdAfx.h"- F4 l" |$ I' ~+ |6 m$ i; {0 Y- Y
  3. #include ".\puiddisk.h"
    & A$ x. c( m" {. s
  4. #define _WIN32_DCOM. |5 x* B. `" V2 s5 [& o9 M
  5. #include <iostream>
    . o! P+ N1 A( v
  6. using namespace std;7 _8 u" s6 s4 C+ ?. r3 h3 h7 u
  7. #include <comdef.h>
    ; c- ~% ]. B$ Q7 |
  8. #include <Wbemidl.h>( v9 z8 q8 E6 \8 b0 R! v& f' F; y
  9. # {4 }& r! V, y! _# W! D$ `  S
  10. # pragma comment(lib, "wbemuuid.lib")
    6 F5 s1 @* Z& ]8 K! i1 }
  11. CpuIDDisk::CpuIDDisk(void)
    ' \: a& _' C! B" Y4 ?; X1 n
  12. {
    + |/ B' k% g' C8 V
  13.     GetInfomation();
    4 }( M# W3 H) O* ^- S! C: |* V7 A
  14. }
    % B+ R0 O7 F# P5 g: J2 T
  15. * e% T( b7 {/ c2 `3 _
  16. CpuIDDisk::~CpuIDDisk(void)+ x7 _" x! R& o0 I3 M5 ~
  17. {
    8 w' v: o* u2 t  C: @! C7 i9 {
  18. }' l# F6 ?& |1 D6 A
  19. int CpuIDDisk::GetInfomation(void)
    1 o8 c* e( K+ W( w# o6 m7 g
  20. {8 B5 c. m; y) ~- {5 I' J4 l2 ?
  21.     HRESULT hres;# N* H# _- Z( E' g, h
  22.     //步骤1:不是必须的,COM只须也只能初始化一次
    / G$ d6 y' N& H! k- c2 Y
  23.      hres =  CoInitializeEx(0, COINIT_MULTITHREADED );: J" y1 h6 X/ k3 V) }
  24.     if (FAILED(hres))
    3 y3 b9 w9 \7 u9 X' p9 v4 H
  25.     {
    $ u' S& q9 L  ?$ y  R" T( `
  26.         return 1; //初始化COM异常:注意,COM只须也只能初始化一次9 \7 T, g4 H9 a
  27.     }  C8 f0 ]$ y' B1 }. S. c7 c- b
  28.     //步骤2:不是必须的,COM只须也只能设置一次
    $ a3 W, ?5 g) X& J6 D4 V5 c: o
  29.     //Set general COM security levels- v! `$ j& O% U& \: {
  30.     hres =  CoInitializeSecurity(9 y/ ]- t1 A5 M+ S
  31.         NULL, 3 F4 w2 S$ X% S' E3 z
  32.         -1,                          // COM authentication
    & d" J" x# o8 V+ y
  33.         NULL,                        // Authentication services
      W, w* U$ i6 ^+ i( |( y& h
  34.         NULL,                        // Reserved
    # K! i) ~' b0 E! g. f2 f/ Z) O
  35.         RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication , E* _+ r& x. o# j% {4 A
  36.         RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  + Y6 z- E2 d% x: l2 z$ v9 R/ x1 q, M
  37.         NULL,                        // Authentication info* m! C1 O+ Y- a; b- ~9 h7 }/ O
  38.         EOAC_NONE,                   // Additional capabilities
    1 E" B% r" K! Q
  39.         NULL                         // Reserved
    9 t7 v- q; z0 ]+ e/ {! E
  40.         );
    2 o: }7 T+ Y6 d5 V
  41.                      
    . l. g$ X, z4 v7 a9 g( I7 r9 h
  42.     if (FAILED(hres))
    & D' p% l6 l6 [7 k- O6 s5 n
  43.     {
      M' M: s" V( b: g. T
  44.         CoUninitialize();( F  j* o! _+ y/ K; @
  45.         return 1;                    // Program has failed.
    5 I+ w3 ]5 b+ T3 C6 H$ l/ K
  46.     }. d" W6 X# D" M) S! F
  47.    
    7 s4 H5 S' w3 E- L5 D7 R. n
  48.     //以上不是必须的,若已有“::COMInit();”,则要跳过  p) ?. o9 c8 }% T
  49.     //步骤3: Obtain the initial locator to WMI / E, _4 x3 K8 D; f
  50.     IWbemLocator *pLoc = NULL;; w- }/ U, ?0 ?+ ?+ b
  51.     hres = CoCreateInstance(
    ( f- x$ ~8 E: x* Q3 q- C
  52.         CLSID_WbemLocator,             7 p# v5 I, |, T/ b) m1 v. l
  53.         0, 0 N+ U: i' `' G2 i, I% x( m
  54.         CLSCTX_INPROC_SERVER, " A3 C7 x4 L" E+ u6 E9 D
  55.         IID_IWbemLocator, (LPVOID *) &pLoc);
    ' F* l7 I( K9 `
  56. ' A  Q, J( I; T4 l! a
  57.     if (FAILED(hres))
    ) v# p7 j& q* D& j: {( o4 Y
  58.     {3 p2 c) k+ I5 N# j- W! v
  59.         CoUninitialize();
    ( C/ Z7 |6 v, [3 l, y3 Q' }$ |) p- j
  60.         return 1;//Failed to create IWbemLocator object2 M0 f- j8 k* J$ E- U7 k6 {
  61.     }. t4 G% v' T9 n& I
  62. 5 P/ }( U% K. w$ t" m8 F
  63.     //步骤4:Connect to WMI through the IWbemLocator::ConnectServer method1 k) K# Q1 x- y3 _' i
  64.     IWbemServices *pSvc = NULL;
    8 U$ u8 i( G3 K/ m
  65.     hres = pLoc->ConnectServer(
    0 I. O4 d" e5 Q8 t$ J/ F- X
  66.          _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace" c2 B2 h4 T% D! f1 r
  67.          NULL,                    // User name. NULL = current user
    ; c, [3 q( g( h7 q; w- K& k  |
  68.          NULL,                    // User password. NULL = current
    ) O: W5 x( c. _- p! O4 p2 }: c
  69.          0,                       // Locale. NULL indicates current
    ! _$ p9 N3 N- M4 g, z6 u/ T+ b, T
  70.          NULL,                    // Security flags.6 o9 ?% [4 c8 A9 a2 j) V6 M- M
  71.          0,                       // Authority (e.g. Kerberos)
    9 \4 d7 @/ J9 Y, F# F8 V
  72.          0,                       // Context object
    ) r. F* v: U/ q' D8 _( j9 R% b9 [
  73.          &pSvc                    // pointer to IWbemServices proxy. X% }) J0 P& x, S$ p! @
  74.          );
    - e2 v0 i5 b; }- X
  75.     8 _/ P, h0 _% f0 B# B: c
  76.     if (FAILED(hres))
    - g1 Q( H% Q8 F1 }" w: Y0 e" K
  77.     {8 d' k+ a) e8 e/ ~0 h8 t
  78.         pLoc->Release();     & H0 p' p( N% e$ I/ \, `  ]
  79.         CoUninitialize();$ B- C1 V/ [  b: v' a
  80.         return 1;                // Program has failed.: b: X# s* t  [+ P& c8 Z' W6 q
  81.     }+ e3 T" [% O& p
  82.     // 步骤5: Set security levels on the proxy7 @* |9 ?( c2 E9 Z( e
  83.     hres = CoSetProxyBlanket(
    : L( D' |1 D- x6 m. Y
  84.        pSvc,                        // Indicates the proxy to set
    0 n" _/ B# ^8 H& ?
  85.        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
    5 V- o6 j0 v8 h2 a3 b7 }
  86.        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
    - p7 j+ E7 G4 I5 n( M% W
  87.        NULL,                        // Server principal name 4 [! r- r  p# M: b$ v$ U9 P
  88.        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 8 f: h9 v5 U8 K% z2 t" m8 Z7 p
  89.        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx% ^$ m+ `: y) \3 ^
  90.        NULL,                        // client identity$ `6 E! g! \( x1 n# O' V( ?
  91.        EOAC_NONE                    // proxy capabilities
    : J! L$ B( L. F$ q* o% v: o0 Q1 I) y) c
  92.     );# `3 O3 v9 H/ @% a

  93. ! `) T, B) N+ l  w$ _" H& |
  94.     if (FAILED(hres))3 q7 Y4 _5 G5 k, j) I7 [
  95.     {( A5 [) c7 y9 x6 _  c9 ]# I
  96.         pSvc->Release();+ \$ V3 J4 s3 _
  97.         pLoc->Release();     , o: w/ [# t4 l/ o% P$ O
  98.         CoUninitialize();% G) Q1 Y; H; R: R% \- ~1 k6 q
  99.         return 1;
    " S% y/ M; F5 ~" d! W
  100.     }
    3 B, b' B0 ]9 l2 n
  101. ' s$ ?/ Z2 K! @5 d
  102.     // 步骤6:Use the IWbemServices pointer to make requests of WMI ----
    1 L# L# a, U; W1 I; c* n
  103.     IEnumWbemClassObject* pEnumerator = NULL;
    & U' a! i- B. \9 V9 L" Q
  104.     //计算CPUID
    % h7 X4 P8 k! Y2 j. I6 l% }$ l
  105.     hres = pSvc->ExecQuery(* N& P- _# G" k, I7 L
  106.         bstr_t("WQL"),
    2 x; Y" V, e- D. |4 ?, T
  107.         bstr_t("SELECT * FROM Win32_Processor"),//Win32_OperatingSystem7 J7 M+ S# P& Y
  108.         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    ; `9 D2 @9 t6 {, m! M& Z4 j/ r
  109.         NULL,
    ( s% K/ w8 U7 o
  110.         &pEnumerator);. o* ^! ]7 n( n* t$ c; s
  111.     % T8 i& E  {2 z, @) z: D
  112.     if (FAILED(hres))
    $ Z; Z% e  P1 _. E! Z) _0 \
  113.     {
    + e) \' O& t1 {% f/ x2 j  X8 L, U5 L
  114.         pSvc->Release();
    ) X; f, F2 _; K- U* |
  115.         pLoc->Release();  |, m( A$ k' i
  116.         CoUninitialize();$ h7 P# L+ h5 s: J
  117.         return 1;5 b9 u1 d5 B8 l; F. h, K
  118.     }
    # X* \8 R7 y/ s( s7 M
  119.     // 步骤7:Get the data from the query
    1 m) C2 d6 d. ^% u. o5 D! n+ ]; A
  120.     IWbemClassObject *pclsObj;/ O1 s+ m6 c% \
  121.     ULONG uReturn = 0;
    4 ]0 x! h' V! ~+ L; Z5 T3 T' L) U
  122.     while (pEnumerator)
    ) z( M! c8 M/ l# K* x) a
  123.     {
    6 T: z/ m# y" K, x
  124.         HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, " p! i% U! G0 j: L0 B
  125.             &pclsObj, &uReturn);6 C: K& Y$ ^& g
  126. 2 F* u0 H, K/ a, s5 m
  127.         if(0 == uReturn): W* L% ~, v  d6 u% Z+ Z5 B; P
  128.         {
    ; j/ n+ I( M1 `4 G% U' T
  129.             break;
    & }6 U' W# G: c+ s% M8 ?
  130.         }
    3 V  n9 T7 ]* B) ?8 u: L5 G9 u' O
  131.         VARIANT vtProp;
    9 V$ x( M4 A0 n5 h% M
  132.         VariantInit(&vtProp);% {- [; M; \! `$ u8 ~
  133.         hr = pclsObj->Get(L"ProcessorId", 0, &vtProp, 0, 0);9 j1 S4 e( M4 `/ L; m) G' U
  134.         strProcessID=_com_util::ConvertBSTRToString(vtProp.bstrVal);//strProcessID:类级变量) W; v" w& O* A# W0 f4 D
  135.     }
    % \- N7 d3 E4 U) X4 T

  136. 3 w8 C/ t$ o: ]
  137.     //计算硬盘系列号
    % m% V! o5 w" b" I
  138.     hres = pSvc->ExecQuery(. x0 z, A$ p) c* e7 e/ w) s# {3 H
  139.         bstr_t("WQL"),
    / P0 D0 L$ r+ Q! i8 `+ r$ k
  140.         bstr_t("SELECT * FROM Win32_DiskDrive"),
    . e  `0 l, x( i2 E3 @0 S  u
  141.         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    2 u5 Z! @/ Y6 [  I$ R/ o
  142.         NULL,
    + ~$ w, l9 Q* e1 @( m; N! N  N8 H/ o
  143.         &pEnumerator);! f8 G" u2 J4 {4 C% V, H3 N$ U+ n3 U9 Q

  144.   ]1 S: F3 J5 [9 E. r
  145.     if (FAILED(hres))7 j; ?' C$ |2 s& V" @; p& u0 s- L
  146.     {! L" A: |3 w. S" V, R& |
  147.         pSvc->Release();5 C# }, M  s* [! |1 L
  148.         pLoc->Release();
    4 C; w5 l# l5 Z3 V7 t/ W4 u+ p
  149.         CoUninitialize();: n( X" c# Z. x) I
  150.         return 1; ( U7 _# |+ m, c1 K7 s8 w7 n0 I, g
  151.     }. e4 D2 w# y* p- f9 v" C: i: T
  152.     while (pEnumerator)
    " k; R' e1 m$ v/ N- A$ w
  153.     {! q6 m6 S: l; G* S$ x# n& i9 B
  154.         HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
    , s) p9 J8 ^3 S& E9 F0 N+ F& w
  155.             &pclsObj, &uReturn);6 x6 w2 B! {5 J6 F
  156. 3 X5 x; V0 w( [% s+ e6 N# d4 a9 @
  157.         if(0 == uReturn)  i4 j3 r6 ~; g& t
  158.         {
    3 U' x/ x$ ~2 @. c1 |2 a% h
  159.             break;
    7 Q, A0 I- ~3 j! k$ x' ^4 r8 k
  160.         }2 d+ f+ K4 [& D4 c9 P

  161. 2 \% o3 R" m7 w% \
  162.         VARIANT vtProp;
    & t! P4 k/ c6 V8 D  K
  163.         VariantInit(&vtProp);
    - l. |) R9 C  ~! t' Q" T
  164.         hr = pclsObj->Get(L"PNPDeviceID", 0, &vtProp, 0, 0);7 C5 {" {! Q$ R& Z; j4 b& j
  165.     strDisk=_com_util::ConvertBSTRToString(vtProp.bstrVal);( P: c4 A% z0 \6 o3 D* s, F
  166.     }
      a, ]) |  r" B0 t# u, x
  167. 1 z' s, h2 @- y4 ]/ y8 C5 e
  168.     pSvc->Release();; q& T& v' G" O+ U
  169.     pLoc->Release();
    2 f; X% a( l& U6 B4 A
  170.     pEnumerator->Release();$ W, |" s) k4 B& P" \, n: f9 o. ]
  171.     pclsObj->Release();
    / v- {1 [' O/ y. C  M) U
  172.     CoUninitialize();: C" a! J! ~8 ?; ~6 @

  173. , |8 H- F* I0 X: Z
  174.     return 0;   
    % e+ u( {3 T$ ~' w) [
  175. }( H1 ^. {0 F$ ^% h% z& t0 h5 @
复制代码
 楼主| 发表于 2010-10-11 19:21:05 | 显示全部楼层
本文代码经ccrun(老妖)在Win2k下试验成功./ S+ F/ U% a7 x/ C, h
0 S0 u2 o0 m) s( [8 i
#include <WinIOCtl.h>
) l( v% A% a5 F; h#include <stdio.h>
. P9 n6 e( J( j) y, k9 U0 v* X/ `7 B1 x" y
#pragma inline
. }7 v6 E2 b3 A) j/ h2 n; L% ]5 Z//---------------------------------------------------------------------------
. l% I; `: z1 \// IDE NT/2000/XP专用变量
8 G% a) x+ N7 x3 m8 P9 W% L#define GETVERSIONOUTPARAMS     GETVERSIONINPARAMS' `: u$ |+ m$ I& h
#define DFP_GET_VERSION         SMART_GET_VERSION) U1 j- V; d% u1 c9 G9 ?8 s
#define DFP_SEND_DRIVE_COMMAND  SMART_SEND_DRIVE_COMMAND
0 g" A5 @5 t# K: F" G; Q& Q# o#define DFP_RCV_DRIVE_DATA      SMART_RCV_DRIVE_DATA6 Q7 |# F" T2 E) O* T# a3 }. _' ^

0 `( ~. K  T% `, D) e, Z: tconst WORD IDE_ATAPI_IDENTIFY = 0xA1;   // 读取ATAPI设备的命令
: M2 F( G* a0 w3 E; {3 L. Vconst WORD IDE_ATA_IDENTIFY   = 0xEC;   // 读取ATA设备的命令
8 Y1 w: H$ j, ?# N$ A% E- G+ I4 t) `3 d, c9 I9 E- }0 ?
const int MAX_IDE_DRIVES = 4;6 O$ A& y: s  m' U; C2 l. v' T

$ P+ f- `: n  z) ^6 s" ]// SCSI专用变量1 E7 b) W$ Z$ D
const DWORD FILE_DEVICE_SCSI             = 0x0000001B;
2 J0 t5 j  C5 ~: f' Q" k! [. wconst DWORD IOCTL_SCSI_MINIPORT_IDENTIFY = ((FILE_DEVICE_SCSI << 16) + 0x0501);
% U4 Z/ J$ R- a5 J2 rconst DWORD IOCTL_SCSI_MINIPORT          = 0x0004D008; // see NTDDSCSI.H for definition
1 I5 h& o2 T" f; P* K7 f& ]const DWORD SENDIDLENGTH  = sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE;
* }- `$ g0 O9 ]3 ]4 }+ H/ y/ U) [! `
+ V& I8 w- L. L% f4 `" r  C8 Q2 Atypedef struct _SRB_IO_CONTROL
. t3 S7 n: {! q# E' O{
8 U$ i  r, ]( |0 i0 Z    ULONG HeaderLength;
% g8 D8 L* l4 Q. M, r    UCHAR Signature[8];3 |7 F! c! }( f7 C  @6 x' m) d
    ULONG Timeout;
2 ]) B4 n( p0 d+ B' U* t+ Y* N- E    ULONG ControlCode;' m7 }4 V% I2 @
    ULONG ReturnCode;
. C* j9 ?4 P0 S5 D    ULONG Length;& A+ T' C) A+ F, V! V# y
}SRB_IO_CONTROL, *PSRB_IO_CONTROL;9 b+ }( y" f2 f, d- y2 T& {
+ m! p( R  r; A( d' o
// 读取的主函数. O* P7 R" l' b5 D& }$ O* P
void __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList);
9 X. |' @) U6 }7 S6 |& w4 x' k
6 K3 z+ j- f4 [// 辅助函数
; |' V% ?1 R, Tchar *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex);
  R" M7 \' V! V8 Z# c: Q5 ~// NT/2000/XP函数
# m: O$ [, ~# R+ d* Fvoid __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList);; g8 C/ J; ?* C; Q; j
bool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
) r8 U9 ~; o* g2 @# R6 f! y4 j        PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd,
& m1 r" D1 A( N. K) D# a- T        BYTE btDriveNum, PDWORD lpcbBYTEsReturned);
2 ]# u/ X0 x/ e- V6 W' H+ B// Windows 9X函数- X5 _: m; I) s1 Y) i
void __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList);
2 V( m5 S* l9 qvoid __fastcall ReadPhysicalDriveOnW9X_Ring0(bool IsFirst, WORD BaseAddress,! |$ u1 d9 _6 V. P: E3 X
        BYTE MoS, bool &IsIDEExist, bool &IsDiskExist, WORD *OutData);
6 y# P- u/ ]8 Y8 x1 J' N- ?
  D- x1 S0 `+ q: q+ }% q// SCSI读取函数(for NT/2000/XP)
  l/ A1 [$ ~4 \, ?, w6 d1 OString __fastcall ReadIDEDriveAsScsiDriveOnNT();  [. l" F5 E* o0 h6 f8 F
//---------------------------------------------------------------------------, f# |/ B+ `  l4 P* ]9 u2 z7 W: ~, Z' R
// ReadPhysicalDrive8 Z1 ]& h4 S/ R
void __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList)
8 g; _: m: h4 d8 j' t4 E{8 t8 V+ V: R/ h! b" A" Q$ M
    switch(Win32Platform)
4 p% F/ }! a9 R! M' D+ [1 A    {
/ s1 e4 B0 G7 _. ?  \1 K' b        case VER_PLATFORM_WIN32_WINDOWS:* i* [3 x& V7 v$ Q% c$ i2 ^4 F
            ReadPhysicalDriveOnW9X(pSerList, pModeList);% }  h  q& W2 q# h5 k! L
            break;
2 [% @5 W- f" e) o, D. t0 S% W! N        case VER_PLATFORM_WIN32_NT:
9 y$ T. c4 x5 p            ReadPhysicalDriveOnNT(pSerList, pModeList);
6 [7 g: `: Y+ B4 t            break;& h+ }% i: L9 ?# B& t& t+ }
        default:! `* K+ m5 k$ o+ L6 P6 Z8 A* D; F
            break;
1 u+ q% w* o$ k4 i    }
7 z9 h: A+ f: p% b+ b0 q# I7 m}
0 o7 U" ]1 I- S9 W//---------------------------------------------------------------------------0 A. H; t# L( d( \  H  n
// ConvertToString
/ l3 e( K: s# K, ?7 Fchar *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex)
% q2 M( q- X' @, c8 ?/ q{: n4 F* Z7 O" y% m: G7 O' V
    static char szResBuf[1024];- X6 F; B* C3 I: @
    int nIndex = 0;& @3 t% e3 a7 w8 F' V
    int nPosition = 0;
! ^0 u$ {  R3 J' Y1 v" |2 X) U4 Y& ^6 f  B1 v5 k
    // Each integer has two characters stored in it backwards9 M  w: u( x: }3 M9 ]0 M
    for(nIndex = nFirstIndex; nIndex <= nLastIndex; nIndex++)
  z1 g( u1 g4 [" t+ |+ C& {    {
, r2 R& J6 C8 d2 Z; N$ }        // Get high BYTE for 1st character3 p# K9 t, B# R6 z
        szResBuf[nPosition] = (char)(dwDiskData[nIndex] / 256);
% f6 x+ o( A7 E, N        nPosition++;
. E' T8 h7 P% ?* {) P3 Q. N
; P/ a& t6 U1 a4 S& y# A) g( L, y3 |6 S        // Get low BYTE for 2nd character" Y! U2 N; r6 U" {8 f
        szResBuf[nPosition] = (char)(dwDiskData[nIndex] % 256);
5 `$ k+ y3 k; v        nPosition++;" U8 k8 |& V* J$ I, d1 V+ M
    }
9 P# Y- [" @0 @" ]2 m, f# u
2 |* `, J: d; u4 u0 d    // End the string7 P$ f5 v9 G0 a: Y7 ?4 j/ h, F/ x
    szResBuf[nPosition] = '\0';
4 ~% i# x3 h7 ?7 d
5 a$ ~. ~, M0 a/ W6 H6 P$ m    // Cut off the trailing blanks% x5 G# ~3 l$ b. A5 e& N
    for(nIndex = nPosition - 1; nIndex > 0 && ' ' == szResBuf[nIndex]; nIndex--)
- k1 L/ O2 Y9 b; d' N' [        szResBuf[nIndex] = '\0';
/ D2 p5 g, r) ?" }3 Q% a" B
/ |: Z) q+ P+ m: ]+ S0 o  \    return szResBuf;
+ y1 H) j- w2 Q+ q% P, L: R1 a}% z- C9 `( K  a$ D. Q
//---------------------------------------------------------------------------( s" d+ G& O* i5 Z  E
// Winndows NT4/2000/XP 代码$ ~4 h2 ~; ?0 C7 x9 G
//---------------------------------------------------------------------------! W5 M1 X; n" q3 Q/ t, G/ h9 M
// ReadPhysicalDriveOnNT8 f- [+ S1 u* i7 k7 b
void __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList)
( s# p( }4 I4 ?0 [9 h! z2 @6 `- P{( c; _$ ]# M8 d; I: A
    // 输出参数* ?9 U7 A2 \$ W1 U) Z; P
    BYTE btIDOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
% L+ \$ h" `; z/ c/ l- n; w) d
, x, X( D# w0 q1 r( ]% h* I    for(int nDrive=0; nDrive < MAX_IDE_DRIVES; nDrive++)
! O/ \& g) O& z' w0 {# F4 P    {! b" C4 i! W5 r) `
        HANDLE hPhysicalDriveIOCTL;! q+ _3 Q# X2 L1 r; `
        char szDriveName[32];
/ V) g# X2 N1 o/ w! r/ @1 A: _5 U6 ^8 s) q9 B+ O7 z
        sprintf(szDriveName, "\\\\.\\PhysicalDrive%d", nDrive);( j* v1 L* s5 A+ M: x) q- n
        hPhysicalDriveIOCTL = CreateFile(szDriveName,
4 W+ ]0 q- M2 Q" D) L3 T% `# J8 y; m                        GENERIC_READ | GENERIC_WRITE,
8 U( J: X/ V% D2 V) P                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,: l/ |: s1 ~7 ?/ E+ X; y  r  ?
                        OPEN_EXISTING, 0, NULL);% r8 W0 m9 E6 t# f! n1 T
5 _  ?8 }' e* Z3 P& h
        if(hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE). W0 V$ x" e, \+ I! q* W( _
        {5 i; T* i6 ^7 _8 t3 r" Z6 f, M
            DWORD dwBytesReturned = 0;
) W% P8 [; R( n1 Y0 S+ L$ T/ s$ e5 Q            GETVERSIONOUTPARAMS gvopVersionParams;2 i' b+ c" K/ y, w
2 ?& E4 Y" H% d' u9 {1 n0 U- `
            // Get the version, etc of PhysicalDrive IOCTL$ w1 L$ d; Y7 ]* ~3 W
            ZeroMemory(&gvopVersionParams, sizeof(GETVERSIONOUTPARAMS));% U7 v( x0 P& Z: ?  d
  x1 k& c; ~- ?. B0 N2 O+ o4 l0 A
            if(!DeviceIoControl(hPhysicalDriveIOCTL, DFP_GET_VERSION,
( H! \/ X! u% L- @5 z% V/ ~                    NULL, 0, &gvopVersionParams, sizeof(gvopVersionParams),
( T, W% z% n/ A3 J0 w9 H                    &dwBytesReturned, NULL))
7 U+ f; ?1 d6 Y! L+ c: r            {
; P9 |& [# P5 v# n                continue;
6 d8 Y7 ]: Z0 H. S0 I% n* d            }: A6 d6 `9 R: _. ]' T( w/ ?0 a( K

7 B! M$ T3 I" g" [* t( `. N" z            if(gvopVersionParams.bIDEDeviceMap > 0)
8 K4 n5 Z& l9 V7 y' l! @            {% w. r% a& ^( F3 k/ L
                // IDE or ATAPI IDENTIFY cmd
, [  B; q  _- ]                BYTE btIDCmd = 0;3 R$ L5 s7 D- Z; r1 z  D3 A
                SENDCMDINPARAMS InParams;
5 K/ o, [4 v7 F7 y                // Now, get the ID sector for all IDE devices in the system.
5 Z) |4 b1 ~" I- h                // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,5 d0 ^/ Y/ c) W' f
                // otherwise use the IDE_ATA_IDENTIFY command. h$ K+ t9 a% l' d+ {' M
                // 具体所得结果请参考头文件中的说明" G7 ?- U) y6 Q' H  W' N
                btIDCmd = (gvopVersionParams.bIDEDeviceMap >> nDrive & 0x10) ?
" x+ X  h! v( v( V4 I7 i' ~6 Y. g4 L                        IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;  T$ e7 O1 N6 A  n, e- F( L
                ZeroMemory(&InParams, sizeof(SENDCMDINPARAMS));' c, T+ g, G& ^; S. j4 `
                ZeroMemory(btIDOutCmd, sizeof(btIDOutCmd));
: y/ ?: v+ M+ C0 ]% N7 n
' h. e2 x, s1 ~$ h                if(DoIdentify(hPhysicalDriveIOCTL,
, O1 P  {0 N7 ]                     &InParams, (PSENDCMDOUTPARAMS)btIDOutCmd,
- j7 R  x" |2 k& S( {7 v( O                     (BYTE)btIDCmd, (BYTE)nDrive, &dwBytesReturned)); j( Q/ m7 B* i
                {6 y( J8 f7 x# w8 t1 Y7 p8 t/ X
                    DWORD dwDiskData[256];
4 y* ?* }# \' v% k+ e$ C! {                    USHORT *pIDSector; // 对应结构IDSECTOR,见头文件
; ]; ?2 r$ s- w9 M- @; R5 C& k5 O                    char szSerialNumber[21];
5 x$ L1 x; e# E- H" D/ X; a                    char szModelNumber[41];! e$ l2 x  z& D) z

" V1 H) v; b& w+ y" d                    pIDSector = (USHORT*)((SENDCMDOUTPARAMS*)btIDOutCmd)->bBuffer;$ [3 F3 J1 f# G5 t6 k6 ]
                    for(int i=0; i < 256; i++)
" ?4 d9 D, d$ F9 r2 z1 `' N( X                        dwDiskData[i] = pIDSector[i];# {. h5 z8 N$ D( j2 A
                    // 取系列号- x7 G. P: u6 k) a
                    ZeroMemory(szSerialNumber, sizeof(szSerialNumber));  _* P$ X/ N4 U* E1 U  a
                    strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));
  p' D/ H# \/ V0 w4 L& c; h1 `
& ?: {" G6 j: {                    // 取模型号
% _% u0 a! v2 ?  S" T3 E7 ^1 @3 q                    ZeroMemory(szModelNumber, sizeof(szModelNumber));/ a4 X7 y: g, k0 b
                    strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));
' K) d: A4 B* x, @) b. q/ ]
9 f: |+ r% ~: A                    pSerList->Add(szSerialNumber);
6 G3 L6 G" E( Q/ [9 r                    pModeList->Add(szModelNumber);( }6 @- b# F" @- ^2 I
                }  h# q# F7 ?9 W! m& ]  l
            }7 V& J+ _5 ^% G; r
            CloseHandle (hPhysicalDriveIOCTL);9 D; A& {/ ^. w
        }  |& `- q" l2 j
    }
* P# g: N4 {& }}
, q" p' j+ `! o7 t//---------------------------------------------------------------------------
* k- W0 U0 p  J  y& ^/ ]  Y7 O) q// DoIdentify
- o9 a/ ?# {/ i( Sbool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
$ M$ D8 X' Q) F6 X' ^8 d3 R# g              PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd, BYTE btDriveNum,
9 o! T" k' M5 T( d- j              PDWORD pdwBytesReturned)6 c( a+ |) }) j) I6 C+ W
{' p- e5 d2 O; M
    // Set up data structures for IDENTIFY command.! d  w, b( x$ O6 G/ R" P$ T5 j( {
    pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;6 T! H: x, M9 w6 @' j4 |
    pSCIP->irDriveRegs.bFeaturesReg = 0;
" u, H& _2 S% X/ t% K; J% k: U7 N    pSCIP->irDriveRegs.bSectorCountReg  = 1;# M' H- D5 O2 R1 c  X
    pSCIP->irDriveRegs.bSectorNumberReg = 1;, Z2 W& M0 u8 Q; x% S
    pSCIP->irDriveRegs.bCylLowReg  = 0;4 j$ J( G! g* N- A# r( H' t
    pSCIP->irDriveRegs.bCylHighReg = 0;: `* z4 I% ~6 U1 d

6 g9 P7 e% Y. l7 f" v    // Compute the drive number.(主盘和从盘所对应的值是不一样的); |1 r: b9 z+ m' L
    pSCIP->irDriveRegs.bDriveHeadReg = (btDriveNum & 1) ? 0xB0 : 0xA0;% D% j5 E5 A' S3 i$ I

/ x3 Z( n% O1 R    // The command can either be IDE identify or ATAPI identify.
* y, ^3 l& a7 b    pSCIP->irDriveRegs.bCommandReg = btIDCmd;
/ m, y) x4 C! w+ y0 H    pSCIP->bDriveNumber = btDriveNum;
4 i8 {( i4 I" e' R: V9 N    pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
2 i  ]% ?$ g' \4 F- G/ y" L: P/ K; Z
    return DeviceIoControl(hPhysicalDriveIOCTL, DFP_RCV_DRIVE_DATA,, ~: T" V) j# V. \7 L" P
           (LPVOID)pSCIP,& ~& f5 n4 V. J+ _( Q7 x7 V4 ~
           sizeof(SENDCMDINPARAMS) - 1,
2 Z( j( t3 K; e1 h           (LPVOID)pSCOP,
% K* U4 u5 D5 D* b' X/ B# e           sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
1 z$ R1 T" z  F& `, B           pdwBytesReturned, NULL);3 I" ?- e- `& {0 b* T" W
}3 A2 v9 ^( `% P# N
//---------------------------------------------------------------------------
( ]5 f$ V) h3 I; ~// Windows 95/98/ME 代码
& `/ p' @) \# U+ a9 ?. b//---------------------------------------------------------------------------5 T6 l5 ~8 u% o
// ReadPhysicalDriveOnW9X
* h; z' y9 O( O% p1 Avoid __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList)8 e; L2 V" F+ Y3 i' J) N* ~
{( X" x# S  C5 g9 {( T) t$ y, r
    WORD wOutData[256];
& C8 v4 \8 }! ^) w2 B: S    SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);! c9 E. y2 }# F( j' O  T4 x) a! O
9 }% x2 D. T% @* a
    // 经过测试,发现第一次调用而且Drive >= 2时会在Ring0代码中出现错误,导致蓝屏。
6 w) g) `$ O  [! O    // 经过N(N > 15)次的蓝屏后仍找不到原因:(,不得不在这里增加一段无用代码以
) G4 W/ W5 i1 K3 @+ r    // 避免蓝屏的出现。(期待高人能指出原因)
" o+ s# c' [, Y8 M8 c( k' e    for(int nDrive = 0; nDrive < 8; nDrive++)
% @! ]( d" j6 S" t    {/ }5 v" W* t" M8 O1 W7 G9 z9 F8 n
        WORD dwBaseAddress;2 i1 _/ a9 A! M8 K
        BYTE btMasterSlave;         // Master Or Slave) X4 \, w/ L/ B+ L0 n. f
        bool bIsIDEExist;
! P/ F. s! |+ L        bool IsDiskExist;! m" C8 T- ^7 d$ ?

5 w1 M+ C$ x; \" g8 O        switch(nDrive / 2)! U; o/ A, Y' c* @4 |' x
        {
( t6 ?) `- }0 l1 U1 N; \! K            case 0: dwBaseAddress = 0x01F0; break;
# p1 V% Z0 o7 N8 K% a6 c2 Z; o            case 1: dwBaseAddress = 0x0170; break;
7 V5 J6 ~) q0 `3 I% d) Y8 j            case 2: dwBaseAddress = 0x01E8; break;" U& c: q0 _" H7 v9 b. B
            case 3: dwBaseAddress = 0x0168; break;, l2 o5 v% a2 X' C
        }
4 z$ b5 [* ]. b  R! [# R- Z6 C6 E- d- F! d
        btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0);4 `* f5 q- D% H: }1 c) ]2 d
2 F2 y7 |( }3 d6 D$ ?( Y" \
        // 进入Ring0
% l# d8 y$ b9 u9 P( O! N  g        ReadPhysicalDriveOnW9X_Ring0(true, dwBaseAddress, btMasterSlave,
) ?1 z2 F# s8 k; [% z& p                bIsIDEExist, IsDiskExist, wOutData);
4 Z$ I$ h% {; M    }
3 K/ X. G# R+ |+ b9 E
3 O$ L* b7 n' \2 n" b0 L    // 开始读取
3 Q7 K/ o) B) r4 N0 b    for(int nDrive = 0; nDrive < 8; nDrive++)
& l7 `& m4 p3 x& ^$ V. H    {" W. j* a$ I0 e! ?  Y
        WORD dwBaseAddress;
5 R6 f: [% w) T: K- [0 ^9 R# c        BYTE btMasterSlave;         // Master Or Slave+ g0 I4 ?' M2 }- j" R4 ]5 [
        bool bIsIDEExist;! N4 E. x3 ]8 G+ g- E3 ?2 a, N, L
        bool bIsDiskExist;
- t/ m) z! V+ y* ~$ D& f1 _6 w  f# H        switch(nDrive / 2)8 W6 [4 H+ b1 P$ F
        {
2 y" d6 v' Q' L* a  C; Y( W9 }            case 0: dwBaseAddress = 0x01F0; break;
* ?3 v6 e( V7 V# w% g& a3 ~7 F            case 1: dwBaseAddress = 0x0170; break;
+ P8 G7 q- ?, K9 q: ^* l% h8 G            case 2: dwBaseAddress = 0x01E8; break;
. `( s4 r$ \# h6 a            case 3: dwBaseAddress = 0x0168; break;
' L/ I* Q9 B, n        }
8 I' U- `( {( m% T9 U% y) P+ Y: o- O) z6 ?! ^, w
        btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0);% }2 E& W# K# U: c& H
+ a+ K+ Z& t) X' e, ~; \1 l
        // 进入Ring0
7 [, _# T9 |+ U' y        bIsIDEExist  = false;
) S5 @4 x0 t' Q, |2 ]8 R/ f! f        bIsDiskExist = false;0 I9 |; ?& [2 H# k2 X
        ZeroMemory(wOutData, sizeof(wOutData));; ~+ h7 E5 n. K  Z" @1 Z
) U0 R; i1 a6 t1 ~8 l8 Q1 Q! Y, t
        ReadPhysicalDriveOnW9X_Ring0(false, dwBaseAddress, btMasterSlave,) P+ }# \  y. M$ M
                bIsIDEExist, bIsDiskExist, wOutData);
0 G8 G7 @) d% I
. t. t0 C! x, f        if(bIsIDEExist && bIsDiskExist)* n) I; Z! D$ K
        {* O8 `- b, P$ k# n& A$ S2 @
            DWORD dwDiskData[256];  J5 ?" q0 ^; J' r2 H
            char  szSerialNumber[21];
2 `2 v7 @* o! p4 A* e$ A4 ^            char  szModelNumber[41];! F0 L; B5 u$ }3 S) F9 ?

- I; ]8 A' i/ Y( E2 x4 z' V3 r& h            for(int k=0; k < 256; k++)
  A' ]2 u# q5 W* Z& O6 m                dwDiskData[k] = wOutData[k];
  V# q& L$ T; h) o
+ F! |/ u  U' u* C  Q            // 取系列号
' h  {; O; v5 \. l+ s  k            ZeroMemory(szSerialNumber, sizeof(szSerialNumber));9 _& T# B5 l% l# F; i
            strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));! M1 u& y: p# C9 ?

& X. d8 b  l- c& N            // 取模型号) x# D& T: l5 y# i8 M
            ZeroMemory(szModelNumber, sizeof(szModelNumber));+ V2 r# c& Q& l# }# p- k7 d# Q
            strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));, \/ M! \% p" V' U7 U( Q
7 g$ [) l8 w# H1 n' E) i" P
            pSerList->Add(szSerialNumber);9 _+ M( a. W) u$ B6 r- d" M3 E% X
            pModeList->Add(szModelNumber);
7 V* W6 W1 Q8 g        }
8 }: [6 i; Y0 b    }. K3 k, H: z9 j0 s
    SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
3 N2 b$ E3 J3 V}
4 c# l+ a4 N4 Q. X$ P( H9 H2 n//---------------------------------------------------------------------------" n  W% y3 s: j4 h4 I
// 为防止不负责任的转载者,在此注明原出处信息,请见谅。
4 p; r# q$ u$ }; p# @& \; r// 资料收集整理:ccrun(老妖),欢迎光临C++Builder研究: http://www.ccrun.com! J) C' P4 x9 E4 A) X  u  {, W
//---------------------------------------------------------------------------
5 s* B# \" F/ j) B) Q// ReadPhysicalDriveOnW9X_Ring0()
$ D+ |( `0 \9 [; N* F$ S( r; F% [//
3 b; d# d  C/ W5 G8 k8 }// dwBaseAddress = IDE(0,1,2,3) : 1F0h, 170h, 1E8h, 168h
* i- @, |( N/ L// btMasterSlave = Master(0xA0) Or Slave(0xB0)
  f2 J+ D) L. n, |$ t9 W//---------------------------------------------------------------------------# v3 ]8 [1 j4 G5 G$ F& ^
void __fastcall ReadPhysicalDriveOnW9X_Ring0(bool bIsFirst, WORD dwBaseAddress,
4 N7 g  e( r" t. P2 }1 N        BYTE btMasterSlave, bool &bIsIDEExist, bool &bIsDiskExist, WORD *pOutData)) y8 q% D( m& k. i: }3 `! K
{; b6 S+ M7 ~; E. E3 Z
    BYTE  btIDTR1[6];
2 Z7 H4 X6 D2 D) W+ x- P7 k) A/ N7 J9 l    DWORD dwOldExceptionHook;) |9 A( ~, n" @- I
    const int nHookExceptionNo = 5;
/ E* O0 O' Y- O# B5 A1 U  ?) G& ?# Q+ I. C0 J) G+ x6 y
    BYTE  btIsIDEExist = 0;* Z5 {! [# H+ `# L& j/ X( q) Y
    BYTE  btIsDiskExist = 0;
' E1 ]: X7 P% f) ]8 }    WORD  wOutDataBuf[256];
, T% y7 ^, q! M' t8 k$ P4 W% I% X
) V: G& o( [  V. K    BYTE  btIsFirst = (BYTE)bIsFirst;% D5 u/ G" t, U% f2 L3 z0 y# _, G9 V" @

5 z% {2 ^0 X) w/ g8 Z, O, S    const BYTE btBit00 = 0x01;2 D$ U; r8 r+ e# I
    // const BYTE btBit02 = 0x04;; A+ p. _; k) `' x1 W1 _( x7 b% L8 O/ H
    const BYTE btBit06 = 0x40;& P. i! y, \& [+ e5 x
    const BYTE btBit07 = 0x80;. T. c+ H' L- u( A5 `! @
    // const BYTE btERR  = btBit00;( o0 |% B+ ~4 x! q+ ]% _! N
    const BYTE btBusy = btBit07;( B5 K* {0 B  R; _3 |$ f* {
    const BYTE btAtaCmd   = 0xEC;8 H% B1 c; ], J* g9 ^. A
    const BYTE btAtapiCmd = 0xA1;
# N5 {2 P9 p7 Q' }8 E$ W% v; Z
. M/ O( U6 B& c. p/ B$ y    __asm( N+ `$ F1 Y! K* S# A
    {2 l8 A$ N+ J1 M$ N+ D. X" c4 m/ V
        // 必须先执行这条语句6 [  F& p7 f, v4 r5 O
        JMP EnterRing0$ w% I0 c2 S* X! K) L5 \

  L# u+ w* @: n6 V/ R5 W- \        // 定义过程2 M% G) C" y8 j
        // 等待IDE设备直到其不为忙为止1 C9 X+ r" w" x9 ^9 F( l
        WaitWhileBusy proc
+ O# G, n( n) p$ T- \% J5 ?# c3 }4 E! Z( \
        MOV  EBX, 100000; P- E- U* R) |! p$ B
        MOV  DX, dwBaseAddress
8 z! k+ k: d" L  ~        ADD  DX, 7+ D, s/ {( V! D& O

2 S- J- g( x$ I! g: B6 S        LoopWhileBusy:1 o7 y% ^& J& F+ s) X

! F4 G. V$ K8 G* w$ {0 d        DEC  EBX
0 ]" J. }2 N" S3 d2 q        CMP  EBX, 0* g- t8 x' ~2 b. |& y- p- ~2 S% @
        JZ   Timeout
" k. I, i% L# r9 a        in   AL, DX2 y$ T. H0 T7 W
        TEST AL, btBusy
' F$ m9 ~( ], j, `        JNZ  LoopWhileBusy# `# R  O+ l  l8 l; L7 w
        JMP  DriveReady
* K, R. B" U5 [) }0 ]
+ X) O1 o1 o& }/ H  |( d        // 超时,直接退出# @  y/ Y* n& S7 u; u- Y+ I
        Timeout:
7 F; ?' Y% t5 h  |# S+ c        JMP  LeaveRing0
4 I/ M; f' j. L/ X# g! I+ U9 e# N        DriveReady:
9 P) k1 i, O9 ?        RET$ X$ Q) A. J* ^3 r& Z
        ENDP   // End of WaitWhileBusy Procedure  |* X! R( D8 D

# [+ B. b) U3 J3 ~$ n" p        // 设置主盘和从盘标志' c( k1 \' _4 a- j) x
        SelectDevice proc
6 V; h. v5 e) z
7 k7 X3 J  g3 }        MOV  DX, dwBaseAddress, Z" ~, A( \5 V: E& {
        ADD  DX, 6
( v- M- C7 p7 r2 C        MOV  AL, btMasterSlave4 p. }/ i5 u% }8 T3 x

5 U  E! K$ x8 H- g# v' C5 N        out  DX, AL5 v+ T6 ?) t5 G) H$ Y# d
        RET
$ U$ _" T# j; P+ ~  y, z& a) I1 V) r
        ENDP  // End of SelectDevice Procedure
+ y$ Q8 z9 S" E& g8 G' D1 e, W4 o; |: n7 H2 ]7 }5 g: c
        // 向IDE设备发送存取指令9 G' \- b; T2 i9 |
        SendCmd proc
+ D/ u6 `+ A3 s* x; D) `+ m1 \% v9 `. b3 ?5 A5 p9 ~* b9 D% G0 a
        MOV DX, dwBaseAddress
0 x0 G( T% R3 x6 F! m5 O8 u, d# z2 ?        ADD DX, 74 Y+ `, W1 _% V/ g/ |' M; l/ }
        MOV AL, BL // BL是主从盘标识,在过程外设置
' R7 A2 }% _: t9 K( Y* q# F) f        out DX, AL2 n9 x9 o3 X' B  h9 R
        RET0 A- U$ j- G, A: o/ g: W$ q# y
        ENDP  // End of SendCmd Procedure3 {: H5 B, u/ P
# a9 y/ i% v' t$ }* A/ {" n" j6 y
        // Ring0代码9 S2 \7 x/ y) n- e1 P* J2 P
        Ring0Proc:8 k8 U" j" n9 @4 B# ]; S7 x
        PUSHAD# j9 @7 @2 v& S
        // 查询IDE设备是否存在
/ l6 o8 E6 z. h, r/ K        MOV DX, dwBaseAddress3 X6 c! N# X8 Z5 k% V  h/ Z/ J" R
        ADD DX, 7
, U! _6 A$ P, ~# G& N' u5 n        in  AL,DX+ y( O3 P  w9 w2 Z% @# i" S
' @3 e# u# F2 D# o; N
        // 当AL的值是0xFF或者0x7F时,IDE设备不存在,这时候直接返回
6 T" Y, }$ E; Z; {% `        CMP AL,0xFF+ t0 [3 {5 r& L/ C8 {
        JZ  LeaveRing0, V- p5 _+ v1 C6 a; P# \* B
        CMP AL, 0x7F" ^- b0 n0 G# Z1 p; j: K/ E: v0 `3 t
        JZ  LeaveRing0/ u% y2 ]% k3 |' U

3 P0 F9 M. p0 z        // 设置IDE设备存在标志$ P" `! P: U/ w
        MOV btIsIDEExist, 1; b) v0 I9 _2 j2 r5 O  b

5 i  l- b# P3 f7 V2 k( L6 N; I! w        // 查询IDE设备上的驱动器是否存在(有IDE插槽在主板上,但是却不一定有硬盘插在上面)
6 F* q; k* p+ Z) E% a' H; W9 f  M        CALL WaitWhileBusy
0 {! i/ O/ S! J3 _9 B, X+ a! F8 a        CALL SelectDevice
$ T) k, _5 t) g1 w2 U- @: m8 m" k$ |. Z1 L1 V
        // 如果是第一次调用,则直接返回,否则执行下行语句时会出现蓝屏
% X  o0 e( i; I- K( P) K7 P( u0 N( a1 Y        CMP  btIsFirst, 1  i9 x- L" h$ I- }" L$ f
        JZ   LeaveRing0
$ ?3 S! I) C' o" h& E0 c3 P  l5 R
        // 第一次调用时,如果执行这行语句会导致蓝屏,Why???3 r. j' R. i/ _$ M/ \
        CALL WaitWhileBusy/ m7 l9 g# @( K& L

' @" E2 h" Q% P# _/ m4 ]( q        // AL的值等于cBit06时,不存在驱动器,直接返回1 V9 b) P. J# [( E" T0 j1 Q
        TEST AL, btBit06( ?" d6 d9 P: i0 {
        JZ   LeaveRing0
, T; L% t+ q: t& ~
% k; @% p+ U+ h/ \2 K! x0 b8 v        // 设置驱动器存在标志
5 a! {9 `% J" e        MOV  btIsDiskExist, 1/ T' I  R* Y$ W0 _! p8 U- }
) m8 c3 B" O! w) X3 |. |# D" I$ b
        // 发送存取端口命令/ T8 O. B% \5 ]8 V
        // 无法像NT/2000/XP那样可以通过查询VERSION的值得到驱动器的类型,
* T' r+ h$ |& t. J0 P/ A/ a        // 所以只能一步一步地测试,如果不是ATA设备,再尝试使用ATAPI设备命令
+ r- u: n# ?% l8 G. K! p, R' E        CALL WaitWhileBusy: }+ N" c4 Q% J
        CALL SelectDevice    // 设置主从盘标识
( d3 o+ ~5 N+ @+ m        MOV  BL, btAtaCmd      // 发送读取命令
, u7 V: i8 s/ h8 P% z2 @* W        CALL SendCmd1 `; [' H6 h4 H
        CALL WaitWhileBusy8 @) ~( Z- b5 h* ?: v
" g, l- Z0 s) w2 K
        // 检查是否出错
6 P* c4 N1 B/ b, {( G# \3 r        MOV  DX, dwBaseAddress3 t+ u0 _2 H' R8 c, h2 g' E1 h
        ADD  DX, 7
8 t3 _0 J2 \9 }
3 P/ V* m, c% |: x/ v* y        in   AL, DX
; {5 M5 C7 j+ l9 K( z, S* k5 h! y/ b
        TEST AL, btBit00
2 X% y- |$ Q1 S' X        JZ   RetrieveInfo   // 没有错误时则读数据/ p, F- h% F3 K0 Y

8 g- y3 i/ O( R) u% q0 I; }        // 如果出错,则进一步尝试使用ATAPI设备命令# o7 ~; m% x& r2 o
        CALL WaitWhileBusy) m! X, F$ ]; u  O$ |4 }
        CALL SelectDevice
* l/ O( o4 B, b        MOV  BL, btAtapiCmd
/ T4 [+ M( x( B) g' Q! I/ s        CALL SendCmd7 c" K( W3 N/ e5 O
        CALL WaitWhileBusy, a2 Z" O. Z4 y
6 w2 s& Z& F, Q
        // 检查是否还出错  q# r+ I$ o2 t# h1 ~+ _0 v5 |
        MOV  DX, dwBaseAddress9 d. C9 ^) |9 g8 O
        ADD  DX, 7
4 J8 i5 I( M: g& ]        in   AL, DX
' c7 C# Z' z" S% x        TEST AL, btBit00
5 x- y8 M) i+ e4 d        JZ   RetrieveInfo   // 没有错误时则读数据% }1 k1 u0 w! G$ `1 W3 m6 O3 N' ^
        JMP  LeaveRing0     // 如果还是出错,直接返回
( m7 O5 g. ?9 S0 ?" w1 A+ G$ a) n. z6 y1 i$ l; m4 n
        // 读取数据
8 f! H/ x, t: O" S9 P9 l/ y& Y        RetrieveInfo:8 b, a" B& _+ U) M" _
( a! [2 j7 E: z8 [
        LEA  EDI, wOutDataBuf1 S2 t3 c; ]: V$ l" K
        MOV  ECX, 256
5 N" o, w- D' p6 |" g" _        MOV  DX, dwBaseAddress8 P8 N0 p' X2 C1 |4 e
        CLD
# `# b% d) H0 G& t+ c! a: \# {  t" S) {2 p
        REP  INSW. O4 r' t* G" g3 W4 D

: s" ~0 U9 U+ @        // 退出Ring0代码4 o, @0 W! Q( ~1 i5 H$ }6 I
        LeaveRing0:/ A3 Q+ h6 d$ ?' W3 R" i2 t, r

- n3 Z% P9 q4 @' Y        POPAD- F4 J+ ^2 n1 [$ z: ~& j/ N
        IRETD, ~/ ^. q3 h5 ?  |) M
* O' K) k0 L9 ]9 B! b
        // 激活Ring0代码% Y- i$ b4 O# M" r% F* |" R
        EnterRing0:9 U6 m5 W! \1 M* H. t

4 n$ [" O5 P3 I8 u9 i& ?* ^! v4 s        // 修改中断门% `# Q; N, q" a" ]5 V$ K
        SIDT FWORD PTR btIDTR17 ?& W; Q* I5 J. \) E
        MOV EAX, DWORD PTR btIDTR1 + 02h
0 K& v$ s# X/ o& D        ADD EAX, nHookExceptionNo * 08h + 04h
- K) D8 c. a; l# k" f, }        CLI
. W# ~& H3 X( k" l2 ?
- {  c2 Z- ^/ t( y2 c! Q" A        // 保存原异常处理例程入口$ Q, Q; x# t* @3 g) n
        MOV ECX, DWORD PTR [EAX]% K7 f% @, ]" g2 X! a
        MOV CX, WORD PTR [EAX-04h]
& K  M1 c0 z4 j5 K$ r        MOV dwOldExceptionHook, ECX" [) R0 [* M/ j* Y8 ?/ ^
6 d1 Z& S8 r+ h8 h
        // 指定新入口
- O  P; P0 U% G; d1 i+ K# M        LEA EBX, Ring0Proc+ p9 e; [. c' M; M, r
        MOV WORD PTR [EAX-04h],BX
! N) E$ _9 Y3 B1 `3 C$ [        SHR EBX, 10h7 m) v* n1 w2 x: n) r9 s/ p
        MOV WORD PTR[EAX+02h], BX
) V" t" i- D; ~: G8 P
, J9 m; m! }  p( ^6 O  ]; v6 }) N% G        // 激活Ring0代码
: T5 \, s# v) q7 q* J* I' j, ^        INT nHookExceptionNo
( u, M& P8 H5 k4 g% p
4 L" {5 R+ f  D; q4 A, s' l0 g6 R        // 复原入口7 ?# P" h+ o" l. Y8 H+ G! H
        MOV ECX,dwOldExceptionHook; K) T0 e+ S% z9 N1 i5 Y1 P# ^+ ?
        MOV WORD PTR[EAX-04h], CX
" ?) ~) N0 {' t! p        SHR ECX,10h" m; n6 l( f# n# Q* ]6 Z
        MOV WORD PTR[EAX+02h], CX
; E1 t- Z/ ?; ]  ~0 `        STI
4 h9 E) ?+ v9 [# A) G, ]7 X    }
1 M: H$ l$ D7 z* F* Y" ?    if(!bIsFirst)
; O% [9 h( Y/ a3 u4 U* x    {
8 E. j* n6 s# Q" x( x5 {9 E2 z9 F        bIsIDEExist  = (bool)btIsIDEExist;% }6 \9 [4 z) i+ Q5 G3 [( g
        bIsDiskExist = (bool)btIsDiskExist;" V, p) @9 d/ _
        CopyMemory(pOutData, wOutDataBuf, sizeof(wOutDataBuf));
% @8 i/ y* t6 A8 U1 `    }; a5 S) s( f0 o0 J/ G" q  _
}
1 i; ^6 F% `& K" n0 Z" m1 p//---------------------------------------------------------------------------
2 r$ I) |. E# J7 _5 r4 Y9 I// 调用方法:
. @1 k! h8 F' R4 uvoid __fastcall TForm1::Button1Click(TObject *Sender)4 R3 i3 u5 y# P* p5 y& `- U* i+ D
{
" U( C8 n( s7 r    ReadPhysicalDrive(Memo1->Lines, Memo2->Lines);: b* b7 U3 a2 F( [
}
7 U5 r; e$ }7 {/ X
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-6-18 08:42 , Processed in 0.021260 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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