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

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

[复制链接]
发表于 2008-1-6 19:59:06 | 显示全部楼层 |阅读模式
代码框架,你所要做的仅是修改WQL语句,具体可看MSDN。以下代码为简介起见,一次返回所有的CPUID或硬盘厂商系列号
3 z* O7 m, b" x9 v( ?5 g. p
  1. - C9 a( d" ]2 V6 u6 @2 c3 D
  2. #include "StdAfx.h"
    * L# Y6 a* y8 H7 s- _8 Q
  3. #include ".\puiddisk.h"! A/ f" U/ ?0 i1 `6 D  R/ E
  4. #define _WIN32_DCOM
      X! V0 {& N+ L) S8 f
  5. #include <iostream>
    0 t8 F) C# x% T! C
  6. using namespace std;
    2 J# z6 k; p5 Q" F/ c
  7. #include <comdef.h>" N$ H. n7 u$ c
  8. #include <Wbemidl.h>* }* u: @# C2 ]5 L# j
  9. * [' O0 q. I# ^/ V+ j& o
  10. # pragma comment(lib, "wbemuuid.lib")
    6 D) X/ B9 `) T8 n/ F
  11. CpuIDDisk::CpuIDDisk(void)1 n5 o8 x: n! ?
  12. {
    7 u/ A" m0 f8 W* p6 c6 \6 n
  13.     GetInfomation();
    ) \% f( |" ]% f( ^& |9 _1 ]2 t0 _) F
  14. }
    % n) n. r+ a( _$ F: Z# w! H
  15. * R. G6 f. j* C' H, ~
  16. CpuIDDisk::~CpuIDDisk(void)6 x) x( \6 y7 n( m* c! Q3 M
  17. {
    8 P+ g+ \3 x1 `7 {( m
  18. }; T0 n( M' U1 a0 d- q! R
  19. int CpuIDDisk::GetInfomation(void)4 Q0 Z: X4 p" S( r
  20. {# ?" P0 b+ _3 d8 K( p& y/ t
  21.     HRESULT hres;
    : p$ ^; f2 m1 V/ o7 f1 C
  22.     //步骤1:不是必须的,COM只须也只能初始化一次, Q" R+ A8 l% L- y6 @2 K
  23.      hres =  CoInitializeEx(0, COINIT_MULTITHREADED );
    ! @& |5 g1 ]1 n) ]
  24.     if (FAILED(hres))
    % w4 k8 E/ q  ]1 u
  25.     {( Y- G; ?7 j/ n! G4 H
  26.         return 1; //初始化COM异常:注意,COM只须也只能初始化一次
    / k& j3 |, E/ k# m, W) z
  27.     }8 \1 O# U* v. m9 L" g( O
  28.     //步骤2:不是必须的,COM只须也只能设置一次
    ' M: x1 E* l7 `6 H
  29.     //Set general COM security levels
    & n9 D4 `4 M0 W+ e
  30.     hres =  CoInitializeSecurity(
    3 ^# Z) C7 R8 Q& m, n
  31.         NULL, 9 {* k$ v# T0 j; f, D+ Q
  32.         -1,                          // COM authentication! o6 v) ^+ `" k* F) \
  33.         NULL,                        // Authentication services
    + E, Q3 R0 t0 ?& h" Z; p* m
  34.         NULL,                        // Reserved
    4 E; P* t7 o# N
  35.         RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication . y' ~8 U3 |& d& Y
  36.         RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  ! A* R% c* d+ ]% F. q
  37.         NULL,                        // Authentication info
      s( U4 e$ M5 N: i9 F1 Z$ {
  38.         EOAC_NONE,                   // Additional capabilities * s  P  o0 I8 D8 h: Q
  39.         NULL                         // Reserved8 |& W. o% C5 Q$ G
  40.         );- {& B) |2 O  f0 z
  41.                      
    6 C9 W( v' O& M
  42.     if (FAILED(hres))
    1 ~$ P- E' G  `* c( m
  43.     {, `! ]: h$ U7 `/ o1 u  @' Q  a4 z; f
  44.         CoUninitialize();
    ; X& w& y' x* `
  45.         return 1;                    // Program has failed.+ ^3 L. y' v" p7 T# o
  46.     }- n6 ]8 Z, p: z
  47.     8 E' K( A% J, y' X; O+ g+ T
  48.     //以上不是必须的,若已有“::COMInit();”,则要跳过
    ( W. _. ]; X: ^
  49.     //步骤3: Obtain the initial locator to WMI ' d: l$ U6 {. G. {, j
  50.     IWbemLocator *pLoc = NULL;! @" ^! v. F4 M
  51.     hres = CoCreateInstance(
    5 s1 l% E, u# P/ U6 y
  52.         CLSID_WbemLocator,             8 ]% h- v, k4 }  A
  53.         0,
    2 t; U, l, q1 ^, j6 C: Y5 n2 u
  54.         CLSCTX_INPROC_SERVER,
    9 V' F) R2 A7 N
  55.         IID_IWbemLocator, (LPVOID *) &pLoc);6 A) C7 K' w' C8 V6 B

  56. 3 K9 r3 L% g4 P/ t: ^+ u! ~
  57.     if (FAILED(hres))
    9 h) f0 Q  ^- H! O& c6 U2 f* s6 f4 E
  58.     {! E+ P) @- H. x& d! D5 ]2 V! s# ~
  59.         CoUninitialize();
    3 ~. K/ h1 H# P0 ]: W
  60.         return 1;//Failed to create IWbemLocator object
    8 B5 q1 U+ Q: |- C7 S5 S
  61.     }
    2 r2 @! t* H0 {' D
  62. ; m/ b5 r1 P7 x( w, Q. v* i
  63.     //步骤4:Connect to WMI through the IWbemLocator::ConnectServer method' ^8 |4 `6 U: F% z" l, ]$ F
  64.     IWbemServices *pSvc = NULL;
    " j" l6 ?! q- c- {  X- r
  65.     hres = pLoc->ConnectServer(" k5 @  @& q3 a! g
  66.          _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace4 M' J- y- }  l  O9 `+ ^
  67.          NULL,                    // User name. NULL = current user
    ) V* p/ p+ ]* I' N2 V! [
  68.          NULL,                    // User password. NULL = current
    ) p% |. \; @, C4 }( B6 ^0 K5 c
  69.          0,                       // Locale. NULL indicates current9 Y/ T  h4 D4 n6 j: E8 }- k, u
  70.          NULL,                    // Security flags." Z3 R7 O& B* \, K
  71.          0,                       // Authority (e.g. Kerberos)3 G' U; d9 y% d9 y8 {- p
  72.          0,                       // Context object 3 R" R$ n6 X( H
  73.          &pSvc                    // pointer to IWbemServices proxy5 T8 ^# q. G# O5 {6 R3 y, X
  74.          );
    % K/ N& I( G5 Y, M
  75.     : f7 ?, `, \1 d! S% E) J, @, {: W
  76.     if (FAILED(hres))
    5 }- n0 S- \; |) `5 n
  77.     {, d8 E; d% L! k  d% o$ m, \
  78.         pLoc->Release();     
    3 ]' p: c# P5 W3 ]: ^
  79.         CoUninitialize();
      P0 B; W9 I! c3 m
  80.         return 1;                // Program has failed.; P4 \; V. u4 Q7 L
  81.     }
    3 |/ k2 l  [" C* a9 f
  82.     // 步骤5: Set security levels on the proxy
    , }$ M$ b! I$ Q! H9 V
  83.     hres = CoSetProxyBlanket($ o2 l) e7 Q- C
  84.        pSvc,                        // Indicates the proxy to set
    4 k1 L2 ^$ h1 f- L
  85.        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx& p1 B' V( H3 Y0 C2 [/ H# }7 O3 h
  86.        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx3 t$ T0 g  |1 g/ n2 T0 ]: C
  87.        NULL,                        // Server principal name
    - n) H2 |8 ?9 V( b+ ^/ s* J8 {
  88.        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx
    ! e% f  U7 t5 D( E3 E* B4 ?$ o
  89.        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx. E2 v# N  k5 d* u+ p5 R0 B: |
  90.        NULL,                        // client identity2 Q' _* F$ i# B6 L0 F4 D- @
  91.        EOAC_NONE                    // proxy capabilities
    5 n3 C% Q! b9 o% D5 a' m
  92.     );, D3 G' ~7 c7 ?5 d+ ?
  93. . l( j% Y' H; A5 S
  94.     if (FAILED(hres))- d7 r, o9 \) C8 {0 k
  95.     {
    & j' q. H4 u% o$ o
  96.         pSvc->Release();" b0 K9 {9 v& Z7 X  w( O# {
  97.         pLoc->Release();     " H4 h9 \' B2 G3 [) d: S$ `* G5 H8 ~+ R; @
  98.         CoUninitialize();+ E( r; l* H5 ^# d2 @. v5 r9 M
  99.         return 1;
    3 Z3 {2 p1 w4 [
  100.     }  u) X% f& W9 v* d

  101. + |) F3 z: b1 x7 {9 K. _+ {
  102.     // 步骤6:Use the IWbemServices pointer to make requests of WMI ----1 a$ v8 p& U9 ]7 h! D
  103.     IEnumWbemClassObject* pEnumerator = NULL;
    & Y) L3 \$ f$ t% Z; S& c: O
  104.     //计算CPUID" s- B' |" A) K
  105.     hres = pSvc->ExecQuery() d! X. @4 v+ D5 k- F
  106.         bstr_t("WQL"), ( C/ g4 z! |8 j( S8 Z- H) Z6 ?) L
  107.         bstr_t("SELECT * FROM Win32_Processor"),//Win32_OperatingSystem& _9 e- }. d: R% F0 p5 g
  108.         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 9 U6 f7 H: p$ q9 Z% F9 A5 m  S
  109.         NULL,
    % ~1 R0 L  O. G+ O, I2 ^
  110.         &pEnumerator);
    # W, R( z7 g2 n8 t/ R1 j$ w# z0 P. c
  111.     6 e* i7 h* ~; `
  112.     if (FAILED(hres))
    + ~! k* F$ E- i: w+ g
  113.     {, R- H# ~3 t4 i% x! i6 N- A
  114.         pSvc->Release();
    ; f6 @3 ]: ^* |5 Y& B1 p7 J* y
  115.         pLoc->Release();5 G# I0 `% }! f0 L; n
  116.         CoUninitialize();
    3 H7 ]! _/ T' I" _) ?) N$ n$ h
  117.         return 1;
    + b8 h- [5 j  H( e& \  y2 v% G
  118.     }
    - F' P( M0 b6 x) \9 |
  119.     // 步骤7:Get the data from the query 6 z" T! q0 \3 r" r, U
  120.     IWbemClassObject *pclsObj;$ l# E7 M$ s: \- z* o3 l; p
  121.     ULONG uReturn = 0;  i) p8 P+ f1 F0 i/ `: W+ Y2 k
  122.     while (pEnumerator)
    7 g. @: F7 O8 G! k9 U5 P# t
  123.     {
    2 B# h  }+ c1 |
  124.         HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
    7 u# q  \% i! O$ J
  125.             &pclsObj, &uReturn);
    " @5 D# ?9 p2 @8 w1 h0 T
  126. * d3 N) B5 S# I, _4 {: O
  127.         if(0 == uReturn)
    ) f' f, v' h& q1 r, A2 q
  128.         {5 p& Q( I* Y: k! O( R
  129.             break;
    + ]' n8 ]& y1 I4 ]# x5 U1 j2 V
  130.         }
      \( v& n# R, l3 \) d
  131.         VARIANT vtProp;
    ( u$ d9 Q9 F2 \, N/ z+ L
  132.         VariantInit(&vtProp);% b5 {% d+ W2 O( N8 }( V
  133.         hr = pclsObj->Get(L"ProcessorId", 0, &vtProp, 0, 0);
    9 ~5 S( Z$ C: }* p4 u+ P
  134.         strProcessID=_com_util::ConvertBSTRToString(vtProp.bstrVal);//strProcessID:类级变量5 ~$ @# S: I& r6 s3 p( K: m' u
  135.     }7 S; c3 C) n8 q9 c2 w, h
  136. 5 T. b" ~: m9 r/ C
  137.     //计算硬盘系列号
    ) b: s/ z9 P4 x( @/ V) r
  138.     hres = pSvc->ExecQuery() c  O) u2 s, m$ _. p. m' Z. N0 H
  139.         bstr_t("WQL"), ' U3 x3 e9 R- k5 P+ X
  140.         bstr_t("SELECT * FROM Win32_DiskDrive"),
    ( T9 q" d4 \2 v  b1 l8 ^
  141.         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, ) G; s% ]* |- U
  142.         NULL,
    + D- Q, h8 B' q+ ~* w
  143.         &pEnumerator);
    & l9 }9 \$ d' T# s

  144. ) P3 w/ t* G6 x3 L  T3 k+ @3 c: ?
  145.     if (FAILED(hres))" y5 V9 L: \- S- X5 y' ~( w
  146.     {! a& D- S( M, `1 C2 p. p; q
  147.         pSvc->Release();
    0 g6 [* Q: T+ l
  148.         pLoc->Release();
    ( C5 M) ~7 m- r# H
  149.         CoUninitialize();
    # N( T1 T6 ~+ L2 F, i' W6 v$ X
  150.         return 1;
    % u& [! r9 f6 c$ \
  151.     }
    0 f$ x$ o3 w7 u" u, r( T3 r5 a; S9 m
  152.     while (pEnumerator)
    8 o2 h9 v  l% @/ V+ l1 ~: b
  153.     {( `) w0 ^/ i+ Q
  154.         HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, : N' \: M+ a& U9 ?
  155.             &pclsObj, &uReturn);/ e& o0 B# H& \
  156. # d2 U$ k. }+ @6 a
  157.         if(0 == uReturn)3 |3 N0 T- \# r; Q
  158.         {. P* l/ L, u% d0 j2 z) ]/ |
  159.             break;
    $ g0 `( G/ |* o
  160.         }
    + f# k9 ^  \  k% D/ a# f& J
  161. 1 R/ r( B0 P% w2 f# ^
  162.         VARIANT vtProp;
    - @4 a2 [' _& n$ ?2 Z. |4 n
  163.         VariantInit(&vtProp);6 p0 \3 Y5 t  Y! d
  164.         hr = pclsObj->Get(L"PNPDeviceID", 0, &vtProp, 0, 0);
    " Q5 W  y0 X3 `6 s- A+ F
  165.     strDisk=_com_util::ConvertBSTRToString(vtProp.bstrVal);
    # |5 X! K( C6 t( t0 O0 K# W- C
  166.     }! M3 T4 H) |# E  x+ |  ?' O
  167. 6 M! ?9 j% a1 C% E& D8 s: K  G! A7 @
  168.     pSvc->Release();
    % i# p0 U- @$ t7 H8 Q
  169.     pLoc->Release();
    " m( I+ D4 F4 P9 b
  170.     pEnumerator->Release();
    , O, D) u1 H% {: c1 H4 }4 @
  171.     pclsObj->Release();# q7 S3 ^: H& |
  172.     CoUninitialize();
    # P( u. B/ m( k; j7 B4 C% u2 _
  173. 7 e7 r6 Z% Z& N$ Z
  174.     return 0;   9 z1 F' F; Q& @: @' F/ W$ O
  175. }
    3 l: J+ Q! P- O4 p6 E! D& C
复制代码
 楼主| 发表于 2010-10-11 19:21:05 | 显示全部楼层
本文代码经ccrun(老妖)在Win2k下试验成功.* f* k# @- [# X1 t1 P

* o2 y! d. y* s: y( E#include <WinIOCtl.h>. i/ g& G* R0 M+ J
#include <stdio.h>4 T2 ~" ?0 x$ X( T  D
, G3 X! {& G' y7 R
#pragma inline
5 {) J4 o- h/ J1 K0 u//---------------------------------------------------------------------------6 P) p+ K: {' X% \/ }% ]
// IDE NT/2000/XP专用变量8 p5 C6 E/ q/ j: r
#define GETVERSIONOUTPARAMS     GETVERSIONINPARAMS
. Q9 d+ A7 Q* f! }/ w! N#define DFP_GET_VERSION         SMART_GET_VERSION
/ d' ]- q' e' \#define DFP_SEND_DRIVE_COMMAND  SMART_SEND_DRIVE_COMMAND. y* O4 A8 b* R4 F3 X
#define DFP_RCV_DRIVE_DATA      SMART_RCV_DRIVE_DATA2 L" g  b2 q" e! K# i
4 r3 O4 ]  j$ X* Y0 R
const WORD IDE_ATAPI_IDENTIFY = 0xA1;   // 读取ATAPI设备的命令$ S9 R5 c/ i+ d$ F9 ]
const WORD IDE_ATA_IDENTIFY   = 0xEC;   // 读取ATA设备的命令; m  p# [# V8 m2 h

3 J% l  M+ R, s" c' V- K3 o0 s3 qconst int MAX_IDE_DRIVES = 4;
  D+ t( M& }8 m5 o, C9 }& n& b1 ]. P+ I- t  y
// SCSI专用变量
4 |  ]5 M8 v  N- w& I9 uconst DWORD FILE_DEVICE_SCSI             = 0x0000001B;! z3 Q+ K* j% q" d
const DWORD IOCTL_SCSI_MINIPORT_IDENTIFY = ((FILE_DEVICE_SCSI << 16) + 0x0501);1 |+ V! H. K6 X  Y7 m
const DWORD IOCTL_SCSI_MINIPORT          = 0x0004D008; // see NTDDSCSI.H for definition
1 f+ ~9 b/ |* g# Gconst DWORD SENDIDLENGTH  = sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE;9 P; X5 X; n8 @$ M) v  L5 m
- |- w7 o" N, @0 u
typedef struct _SRB_IO_CONTROL
# r2 D  w$ D9 |: s' p0 T1 ]{
7 n: C9 }8 O. i4 [* F    ULONG HeaderLength;
0 ?2 r" ?& r' q    UCHAR Signature[8];' {5 d+ K% [1 L- W$ t" m8 H# X- p
    ULONG Timeout;3 ]: i  l& {0 ~: B3 n$ A/ t
    ULONG ControlCode;
- q, q( Q* h6 B. j) q/ I    ULONG ReturnCode;. x, D8 V- A- e; ?7 D
    ULONG Length;' J% F7 P, o. x% z  J, c6 m  ]" c
}SRB_IO_CONTROL, *PSRB_IO_CONTROL;
, \. s9 x' c1 S! s( `- i4 A
9 R+ S% t. \6 u7 j3 ~// 读取的主函数( U! L4 o$ Z; ^% `# Z- X# }
void __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList);( t# k+ A4 A) F6 ]+ f

! `. p  o; `. @2 R( D// 辅助函数& h$ m- r' X: x! V( D3 J( u
char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex);
5 i( l' P' _- q8 M8 |" A5 C8 A// NT/2000/XP函数% g6 t8 l1 O5 `5 d1 b
void __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList);$ Q& m0 e3 d( h5 `/ Q  L
bool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,  s/ g8 m: W- \; {( `6 P# f
        PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd,8 X" J& |  r9 w- n
        BYTE btDriveNum, PDWORD lpcbBYTEsReturned);- W: M7 S- o. m2 W* Y
// Windows 9X函数
, v' W8 O* \% Y' Q4 ]& M8 [" `void __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList);
6 H. X3 y# h4 l, s" D, v) evoid __fastcall ReadPhysicalDriveOnW9X_Ring0(bool IsFirst, WORD BaseAddress,0 J8 T% z' O5 O# A% k, S0 ~
        BYTE MoS, bool &IsIDEExist, bool &IsDiskExist, WORD *OutData);" O8 n# X4 A' E' f
- Q4 K- Z1 z  h) T0 |$ d1 I! z
// SCSI读取函数(for NT/2000/XP)/ \% D, w" |' N- Z2 _6 x
String __fastcall ReadIDEDriveAsScsiDriveOnNT();1 @! u0 h' h) c. \! l
//---------------------------------------------------------------------------/ A/ q" a# K( Z6 v+ F
// ReadPhysicalDrive2 a' M5 J# p9 z; j  S. t4 g: ?' E
void __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList)0 I: N& @; Z8 s- `
{' J- _. B: u+ w" \8 Q
    switch(Win32Platform)9 u0 P0 `4 F8 t9 o: k  g
    {
3 z. V" C  R3 r1 n: U: O6 D: x        case VER_PLATFORM_WIN32_WINDOWS:
6 C4 Y% r7 X( n+ N' d7 L4 i8 m            ReadPhysicalDriveOnW9X(pSerList, pModeList);; x# w9 Y3 P& Y* l9 {% s
            break;6 T' o& W) O# z1 d4 b
        case VER_PLATFORM_WIN32_NT:6 k6 q0 Q; U' d$ p+ a, K
            ReadPhysicalDriveOnNT(pSerList, pModeList);% U: ]2 B: j- R  G8 D
            break;
- q, b* M3 Z  c. G        default:# x7 q3 @& x( T4 G8 n
            break;9 a" g. d) C) [0 X! p/ L
    }' f$ j8 R( w" ?3 F8 U; M
}  E( k( A6 i8 q; v& z
//---------------------------------------------------------------------------
( |" g- X) u7 k// ConvertToString
( w$ r7 }, Q' w6 g% R/ P* dchar *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex)+ m3 Q) O! U6 N- h
{
1 k- W9 m+ H! }0 {& }% l" }( z! A    static char szResBuf[1024];
7 [! R/ H( s+ w$ X( i6 t4 Z: ?. Y    int nIndex = 0;, |. ?' W- W% t" K! {
    int nPosition = 0;
8 y) Q- l1 a8 a/ a$ R. u* W; W' B+ c- p- b+ L
    // Each integer has two characters stored in it backwards0 w8 A8 q7 T8 \1 A
    for(nIndex = nFirstIndex; nIndex <= nLastIndex; nIndex++): V' t& y4 n1 T& }- e
    {
5 ~/ N  y) z! @" S7 K' m  |        // Get high BYTE for 1st character1 |2 Z+ B2 f" R& a  o/ l& g
        szResBuf[nPosition] = (char)(dwDiskData[nIndex] / 256);
& p* L- X  t) K: p$ _& _        nPosition++;
4 T: P. U" g% H& T
! k/ g" O4 q, {        // Get low BYTE for 2nd character$ @0 p/ X! o! ~0 s' M% a. ^5 e
        szResBuf[nPosition] = (char)(dwDiskData[nIndex] % 256);
% [# ], g0 f/ j( s1 y- f        nPosition++;, c1 p  q3 Y1 @: A$ U0 k) v
    }$ S; b/ i  \& L4 P; ^3 V
" C* G8 {; W1 {1 i3 y- h0 A
    // End the string/ c' X3 ~) y1 i. q7 c5 z- ?
    szResBuf[nPosition] = '\0';
4 @: p- W9 q  s& u9 \
/ t0 @; m. B: _/ m+ o# _    // Cut off the trailing blanks# x9 D- r1 h  q/ Y' i
    for(nIndex = nPosition - 1; nIndex > 0 && ' ' == szResBuf[nIndex]; nIndex--). X/ {0 B1 `% h: B/ W" Y
        szResBuf[nIndex] = '\0';
2 }; a& ^& r* k  D- o% j
/ D6 O0 k! V' C7 m( w, Z8 l9 o" B    return szResBuf;/ r0 p! i6 P' A5 ^
}3 W, I' \% L9 o& l
//---------------------------------------------------------------------------0 q9 K) q( R' `' T+ d; x
// Winndows NT4/2000/XP 代码
) |( U# B" ]$ B" m7 s' }! W//---------------------------------------------------------------------------1 E( p* z6 g7 W6 f" V. ?, }
// ReadPhysicalDriveOnNT- c% |( x6 [; y1 r: D
void __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList)8 o( }$ W5 p: m/ L+ H! w
{
: J; A4 Y: x; v) F3 ?; ?' Z    // 输出参数
0 r+ p: z) c- |3 \: p* c' s, v$ I    BYTE btIDOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
9 }+ c3 f6 h1 O* ]6 [
) ?  \7 B3 D% p7 n% ?8 x& c) t    for(int nDrive=0; nDrive < MAX_IDE_DRIVES; nDrive++)
7 _) }$ t5 K6 y    {: _$ J5 n5 V  p
        HANDLE hPhysicalDriveIOCTL;* M  A$ ^9 t) H7 [
        char szDriveName[32];; w$ p. n; A( ?+ y% i
, T2 F! D8 F0 O, R9 S! r* c
        sprintf(szDriveName, "\\\\.\\PhysicalDrive%d", nDrive);$ p2 s7 ^& v- S" M/ l. I
        hPhysicalDriveIOCTL = CreateFile(szDriveName,
7 A8 U7 \/ A# {3 f( Y                        GENERIC_READ | GENERIC_WRITE,
* @8 g; \- X* ^: \: A  b9 E% j                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,6 ]3 T7 }4 j2 @' M
                        OPEN_EXISTING, 0, NULL);& ?9 ~( a9 L2 P" {; {
( Q1 i' j/ V) l" B
        if(hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
/ ]' Y* i; W4 u) ~6 o+ c. z% P8 |% Q        {( ~- ], ^( N# q+ v, H9 V5 I
            DWORD dwBytesReturned = 0;
" j) @& Z- t. [* z            GETVERSIONOUTPARAMS gvopVersionParams;
8 h: J  U/ Z: i9 E" w3 m' n1 G% D5 N/ i% }" `" z/ O! P; {, o+ T* t
            // Get the version, etc of PhysicalDrive IOCTL8 {5 k( D$ O5 V& u# W4 e, q
            ZeroMemory(&gvopVersionParams, sizeof(GETVERSIONOUTPARAMS));/ v7 {2 h6 Y6 Z; L& z  B

0 }- g0 ?3 q- L$ k  n5 m            if(!DeviceIoControl(hPhysicalDriveIOCTL, DFP_GET_VERSION," C5 I, A) J1 ?- M: n$ `
                    NULL, 0, &gvopVersionParams, sizeof(gvopVersionParams),  R& G1 a( C# r" T# t. r0 I7 x2 y
                    &dwBytesReturned, NULL))
, }3 P! u& W& f4 r2 [$ Q+ b- E            {8 I+ P; i8 D8 c# [
                continue;
5 \# u+ s( P6 o; [7 V; R            }3 I# S$ E' _. n, n0 |/ Y2 W$ m/ j
, Q7 e5 w, o8 R4 t/ O& L$ m. J; F
            if(gvopVersionParams.bIDEDeviceMap > 0)
' p* F2 h% w: b$ @' A( u9 q            {! H' l4 C) J5 G, V4 h
                // IDE or ATAPI IDENTIFY cmd/ l4 Q" ^: u" F# n5 j- x3 z* k
                BYTE btIDCmd = 0;1 m& }! ^  G6 o! I; c4 |
                SENDCMDINPARAMS InParams;; _1 r) Z7 @% h- f. I! J! t% A) d3 v
                // Now, get the ID sector for all IDE devices in the system." @* _  ^8 u4 |/ h
                // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,8 z9 H& D; {8 \! G) j
                // otherwise use the IDE_ATA_IDENTIFY command
2 Q# H6 y* T7 N; E: O* l7 b                // 具体所得结果请参考头文件中的说明
4 {' x; x: d1 B( Q/ i                btIDCmd = (gvopVersionParams.bIDEDeviceMap >> nDrive & 0x10) ?
, j! j: d  W* w: T. n                        IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
4 v+ E# \" V0 |# Q$ T                ZeroMemory(&InParams, sizeof(SENDCMDINPARAMS));: p6 _2 A9 ?0 [9 V
                ZeroMemory(btIDOutCmd, sizeof(btIDOutCmd));$ S% H3 C- {7 o8 J

3 T# m/ N5 R; Z                if(DoIdentify(hPhysicalDriveIOCTL,
9 j9 m0 y& E* R# I& x                     &InParams, (PSENDCMDOUTPARAMS)btIDOutCmd,8 W) o/ n  b$ j9 Z& s+ x/ y
                     (BYTE)btIDCmd, (BYTE)nDrive, &dwBytesReturned)): u' H$ G  ~1 A4 i8 ?8 l6 P
                {
# d$ c3 j, c; j& t' P                    DWORD dwDiskData[256];! @, [3 M9 C" m, e1 O, Q( ?5 }9 P
                    USHORT *pIDSector; // 对应结构IDSECTOR,见头文件
" i8 ?+ J1 B. h/ Y+ q1 ?                    char szSerialNumber[21];
. N+ C& x. d6 t3 Q# p" O% S                    char szModelNumber[41];
% @' ?+ d8 @: J
- @) u; _  C, c. o- q                    pIDSector = (USHORT*)((SENDCMDOUTPARAMS*)btIDOutCmd)->bBuffer;
2 Q( ~' T& _2 l' q3 R* r! j2 E0 ^                    for(int i=0; i < 256; i++)- D% [3 z) t' }) G; s
                        dwDiskData[i] = pIDSector[i];
  ~2 ~1 A' u3 A& Y  J) K                    // 取系列号
5 g& {6 W1 e3 G* c, f% r7 d                    ZeroMemory(szSerialNumber, sizeof(szSerialNumber));7 a; ]5 b7 V  O2 P; F) a
                    strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));$ x: D2 q# \" o
9 j4 D. m+ A- D- d# R5 r
                    // 取模型号0 R5 a$ Z; J* K% \* ?8 f  r
                    ZeroMemory(szModelNumber, sizeof(szModelNumber));
# p* P& r  h4 O8 U0 ]7 \) x7 V# D                    strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));! Z4 ?5 X+ n! \  a; h( C7 h0 l0 }& F
+ c+ i/ F8 y* b
                    pSerList->Add(szSerialNumber);2 @2 {- @9 }( T1 q/ y. W9 }# X/ B
                    pModeList->Add(szModelNumber);( B2 h) l; {/ U. Y- F9 K! g$ i
                }4 T/ ]2 W& U4 \+ Z1 j- h8 r
            }
8 `5 ~8 B+ U- A( T$ |9 l            CloseHandle (hPhysicalDriveIOCTL);. {# Z/ R2 m0 w& S5 R# ]/ ~! `7 `! T8 F
        }
3 }" C5 Q3 Y) S2 _& A( C    }2 W" o$ O9 ]' o/ I. \
}
, q& D; f9 Y$ C//---------------------------------------------------------------------------
+ F0 l: |7 E4 r: ?// DoIdentify& M1 x* {. h) i, x$ f
bool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
- e/ p' H/ {+ P% \$ Y, U, K              PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd, BYTE btDriveNum,
/ h% l- F: ~2 _" H$ C              PDWORD pdwBytesReturned)
; }: K$ c# ?4 v{1 C1 j3 Y5 S5 o& s& V# m
    // Set up data structures for IDENTIFY command.
6 K$ @8 l& F7 c$ H3 ]* x. _8 i: p    pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;% F4 C! N% k( W( b7 e" v8 t. ]
    pSCIP->irDriveRegs.bFeaturesReg = 0;
) b7 j6 L9 e+ o* P" a' u    pSCIP->irDriveRegs.bSectorCountReg  = 1;/ C* e# c- f4 l# w. l& E* Q5 I
    pSCIP->irDriveRegs.bSectorNumberReg = 1;
' _3 P! V: }7 r2 t: I4 K    pSCIP->irDriveRegs.bCylLowReg  = 0;3 i* _. f9 n* Y: X0 V
    pSCIP->irDriveRegs.bCylHighReg = 0;' J% h4 x9 A+ ^4 c2 s( C# D

, _/ Z& {1 q2 p9 X$ \% u    // Compute the drive number.(主盘和从盘所对应的值是不一样的)
9 O" x. t: r( Z# {  Z. j' v" F    pSCIP->irDriveRegs.bDriveHeadReg = (btDriveNum & 1) ? 0xB0 : 0xA0;6 A( u6 M) f2 {/ r% @

% T3 c' u! e: Y" W: I    // The command can either be IDE identify or ATAPI identify.
' H3 F4 M. j0 k& E6 J    pSCIP->irDriveRegs.bCommandReg = btIDCmd;4 a3 C8 V2 E5 R/ T8 c
    pSCIP->bDriveNumber = btDriveNum;
1 o' B& w" b3 ^6 D    pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;# j  d" t/ J/ x+ v& u, F

7 \' e; n1 |0 N( s    return DeviceIoControl(hPhysicalDriveIOCTL, DFP_RCV_DRIVE_DATA," O2 S4 w! b. |3 j
           (LPVOID)pSCIP,2 K: `! l! k( q, @, E. I6 ^
           sizeof(SENDCMDINPARAMS) - 1,  X% u3 J1 k) z( k, h+ g' f$ K
           (LPVOID)pSCOP,/ m) i6 `, a2 Q5 a7 w' T* ~7 i
           sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,! P8 ~, h$ `( B9 q
           pdwBytesReturned, NULL);" J# [9 O7 x! B  i+ j
}
6 p8 t$ Y* [8 @) L+ l/ V/ C//---------------------------------------------------------------------------4 d( X; t/ P1 w" `+ K
// Windows 95/98/ME 代码
; a; q+ r- c; [( {//---------------------------------------------------------------------------
) H6 z2 V7 _4 S% Q1 p6 C// ReadPhysicalDriveOnW9X% ?9 x. z" U3 j2 T2 d+ j
void __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList)1 `* Q8 r1 e8 ]( U8 I) `) h
{* ~: C4 n' e7 m* K2 x: O5 D9 F  _$ v
    WORD wOutData[256];
3 ?, W0 F" R) W! r' v    SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
6 r" z* S  R# L+ T# z* Y9 h- ]% [8 \" S
    // 经过测试,发现第一次调用而且Drive >= 2时会在Ring0代码中出现错误,导致蓝屏。
9 ]. g1 U2 x( ]    // 经过N(N > 15)次的蓝屏后仍找不到原因:(,不得不在这里增加一段无用代码以/ {) _5 C$ D: S: v7 }9 m
    // 避免蓝屏的出现。(期待高人能指出原因)
4 B# e/ b+ l, b    for(int nDrive = 0; nDrive < 8; nDrive++)8 G8 c) `* @; n2 T, y8 m
    {/ a# p* u. W, `' y% X1 K5 g
        WORD dwBaseAddress;1 t8 U/ o8 R& L; x( n" \
        BYTE btMasterSlave;         // Master Or Slave
6 l: a" Q6 Y' o" h0 C        bool bIsIDEExist;
# T: r' F  C: {5 I2 m  v$ W; ?        bool IsDiskExist;
( i2 p. I" Q2 k. y/ N& z8 V) }- o1 m' r+ F
        switch(nDrive / 2)
% B9 i- m1 X/ }+ f. u6 x0 k        {# _. w" ?9 v  u  ^! ^: T; v
            case 0: dwBaseAddress = 0x01F0; break;
" D2 D! }9 m- O- O( j* C& f$ K            case 1: dwBaseAddress = 0x0170; break;. W( B9 h2 m: y  }5 ]! G0 a1 B
            case 2: dwBaseAddress = 0x01E8; break;
1 f/ e7 q  v6 x( b5 |: j: @            case 3: dwBaseAddress = 0x0168; break;
8 |8 F  S* [( F, S3 P6 u5 R        }% P) ^/ V# w+ Y
  C: y4 d' S/ H$ v* F. \
        btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0);
+ R7 L# V: G- j0 D! t6 e- J% c* \
4 e* ?% {! B* C6 @. P: c. z' ~        // 进入Ring0/ x4 f% r' i; o* l2 W
        ReadPhysicalDriveOnW9X_Ring0(true, dwBaseAddress, btMasterSlave,! Z0 {$ B* z' y0 A: ^" g
                bIsIDEExist, IsDiskExist, wOutData);
/ w+ x' I8 `1 y0 K    }
- x) A/ ~. L% x
7 B5 w" ~9 I4 k) [9 m$ l( l    // 开始读取, u3 `( B# t: P) O" x4 {
    for(int nDrive = 0; nDrive < 8; nDrive++)
8 ]  }: f4 M/ V, [  L- c    {4 \: x9 y$ Z& O' ?* I' W
        WORD dwBaseAddress;. o' W+ k$ K$ E. ^% H
        BYTE btMasterSlave;         // Master Or Slave
  V7 s9 v0 ]1 c; ], v+ x* {( Y        bool bIsIDEExist;
6 V7 C' t/ \( D8 Z  H# g$ o( o        bool bIsDiskExist;
% b  D- q" I; [& u1 I3 p        switch(nDrive / 2)" G8 E4 Z/ j% ~0 c* [4 i# ^
        {1 C4 r) Y6 v8 Z8 r- `
            case 0: dwBaseAddress = 0x01F0; break;+ g1 n) ^( _( h! O/ B
            case 1: dwBaseAddress = 0x0170; break;
  ~) s1 `$ T* ~1 S1 t) p  y5 O% r* P            case 2: dwBaseAddress = 0x01E8; break;
: l4 r7 P# [* }  V# I            case 3: dwBaseAddress = 0x0168; break;
; M) Q1 m+ }, W& _        }
& E2 S5 v# v0 w' j" s7 s
% {- C8 t5 T! }        btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0);
% k/ o; z4 E) C$ `* T- X' r& i8 Q  V% s
        // 进入Ring04 \% c5 u& `* D% \6 `2 u/ p6 }
        bIsIDEExist  = false;; F# ^* H6 D; G3 g' T& |* O8 }7 o
        bIsDiskExist = false;$ r2 O: n/ m" B" p( {6 W
        ZeroMemory(wOutData, sizeof(wOutData));2 l. b, k% \5 x9 ]' x/ ]. u- K" [

4 @: a& z; @- s0 E        ReadPhysicalDriveOnW9X_Ring0(false, dwBaseAddress, btMasterSlave,+ O& H; w; [9 g
                bIsIDEExist, bIsDiskExist, wOutData);
) Z. F) w8 C1 [. K$ T+ D2 q  C* ^" Y- n
        if(bIsIDEExist && bIsDiskExist)- s" q; t7 C: s
        {
& o, G. w( T: F  X* H& i) u" x5 l# K; @            DWORD dwDiskData[256];4 U, i8 @0 D$ I: @+ _* q
            char  szSerialNumber[21];
1 Q6 l1 T; \4 N. v& M            char  szModelNumber[41];8 m$ H; N) F- M- o$ k( y
4 P$ v( s! ~/ w1 v1 `  @# y
            for(int k=0; k < 256; k++)1 K, C  j6 }" c6 Q
                dwDiskData[k] = wOutData[k];; n" D& ~* N7 V+ t
5 j& s" n7 b5 Q# ~
            // 取系列号  V' w) D, B8 x6 Z
            ZeroMemory(szSerialNumber, sizeof(szSerialNumber));
8 G0 `8 E; J4 @) t7 C            strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));
0 m& W3 w" [, C+ e% c" a+ z/ Z3 n
+ t* |/ W+ v+ R            // 取模型号+ _- D# W, {, u% R( Y- q; D/ C0 I" M
            ZeroMemory(szModelNumber, sizeof(szModelNumber));; Q. G9 A. _# d: x$ }& c
            strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));
% W9 G: I  ^% n& _  S  k1 |
& Y: g& b# F# C. ]) ~2 u            pSerList->Add(szSerialNumber);+ k8 F  o: Y/ T
            pModeList->Add(szModelNumber);4 g8 ~( H2 k  o3 |2 P) G, P4 G
        }* e& `. M! x: V- d
    }
1 T$ o" k$ X$ y' t5 t0 I    SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);; i7 X% B1 p& u1 n- N5 U
}3 [2 s1 K) M8 C9 i. N8 |9 L
//---------------------------------------------------------------------------; Q, X9 E8 V% f
// 为防止不负责任的转载者,在此注明原出处信息,请见谅。
) M% o1 b/ M% Q! X// 资料收集整理:ccrun(老妖),欢迎光临C++Builder研究: http://www.ccrun.com
5 A: o" t. h; O//---------------------------------------------------------------------------
4 {: F2 s. E' A" r" i* o# V1 t1 M// ReadPhysicalDriveOnW9X_Ring0()
, u7 Z  N5 |% a2 F: \//2 Y8 A1 B& Z) P" O8 W+ ~& H* f
// dwBaseAddress = IDE(0,1,2,3) : 1F0h, 170h, 1E8h, 168h
' G: W0 x' C# D/ L// btMasterSlave = Master(0xA0) Or Slave(0xB0)4 R8 y* b' q9 b( T3 |- ^
//---------------------------------------------------------------------------0 u  {2 B. a) w* k
void __fastcall ReadPhysicalDriveOnW9X_Ring0(bool bIsFirst, WORD dwBaseAddress,9 n- u; W  J0 j) C4 y0 D
        BYTE btMasterSlave, bool &bIsIDEExist, bool &bIsDiskExist, WORD *pOutData)
: L- r* O' I' l{- C: k5 I4 W6 s7 r
    BYTE  btIDTR1[6];
: R: U) {0 ^0 G+ Z1 P    DWORD dwOldExceptionHook;. j" v. v3 ^/ K, n
    const int nHookExceptionNo = 5;! V, S0 K% i% @7 N* O% `

7 V' w' p$ x, m% N/ i) ~    BYTE  btIsIDEExist = 0;
: f) U' F5 T  _8 D7 s    BYTE  btIsDiskExist = 0;
( w6 T$ }$ G$ M* A6 H7 X$ ^    WORD  wOutDataBuf[256];
- j0 K/ g# j% G$ e* X
3 ]+ n# w4 X! G1 w9 L    BYTE  btIsFirst = (BYTE)bIsFirst;
9 Y0 D4 o5 A5 f4 Z/ P" @6 i4 [; a  N8 J2 b0 _
    const BYTE btBit00 = 0x01;/ D- |- w1 V! |, F
    // const BYTE btBit02 = 0x04;, o9 t+ l1 N: [6 A8 v& A
    const BYTE btBit06 = 0x40;
/ N' r6 R: p& S! n, _) p    const BYTE btBit07 = 0x80;
5 E" J; U, Y: L6 i% ^    // const BYTE btERR  = btBit00;
7 Q" o* ^' J8 K) Y$ H    const BYTE btBusy = btBit07;
+ k4 B5 ?- W0 [# y7 W    const BYTE btAtaCmd   = 0xEC;; g  r" _4 c, X5 b
    const BYTE btAtapiCmd = 0xA1;
8 I4 I) a9 S3 O% c" i& _
# L- ?# s, H* I9 I$ ^/ t- R$ w    __asm
$ M+ I' y9 `$ S    {3 B3 `; q& w8 G
        // 必须先执行这条语句5 `% @  O! P- h: }4 q9 G( ~
        JMP EnterRing0, K" K4 U3 K, T

% R* c1 G- [! X. y9 y8 J" n* G& T        // 定义过程
4 ^4 N% C4 X% D) Z        // 等待IDE设备直到其不为忙为止
6 j1 f7 A! r$ j* E( s        WaitWhileBusy proc0 t0 Z; t, Z/ V  g) u/ ]- n5 Y7 p
& r! F3 h6 ~- E. d, A2 Q
        MOV  EBX, 100000
2 ?3 A- ?  i( y& G5 }$ Q+ U- Q: B        MOV  DX, dwBaseAddress
: O+ l4 }( y1 W6 `. K        ADD  DX, 7
' h# _3 `4 P' R  q! F0 L- ]9 C/ Q: C, U; s
        LoopWhileBusy:) ^/ J& X: S" I2 x# y& E. h- N
: p8 Z! j5 G6 p* ]5 p# [, [# M
        DEC  EBX; Z+ e& G" j+ }. \
        CMP  EBX, 0' u  @6 A# y" H. g- C
        JZ   Timeout: R/ m4 `% H  E8 {7 @
        in   AL, DX; s6 L4 N- a/ x: j
        TEST AL, btBusy8 X' j% H9 [9 x
        JNZ  LoopWhileBusy
3 j% K2 f* j! X9 C        JMP  DriveReady
8 p9 C% N# K) m- t
8 c) |  Y, c0 m        // 超时,直接退出
1 m& C3 R- `" U        Timeout:
! |) c/ ]. P9 ?' }        JMP  LeaveRing0/ F- i- F  ^+ k' E+ C. m# R
        DriveReady:1 M4 j% }( b- b) S5 V2 p$ z3 s
        RET8 m) {8 y; J# F% b  M+ y0 }! Z7 A
        ENDP   // End of WaitWhileBusy Procedure
! d+ a* i1 {4 }) z/ a3 i
' l4 H1 C2 M+ R6 j* v        // 设置主盘和从盘标志
8 K0 B. g6 u" [: e6 V        SelectDevice proc
9 x$ U  L+ K0 |& q" P# N- H, Y) h( ]+ j3 l
        MOV  DX, dwBaseAddress
5 T- X  u1 N2 o5 s. F. x9 R        ADD  DX, 6
5 j. C/ a. ~& }1 h8 A4 V        MOV  AL, btMasterSlave; h1 Z& ^& ]. g  v. d0 j# Z# n8 J
8 B5 I4 e: u8 K; \
        out  DX, AL
6 m& {+ D" D4 w        RET; K1 q4 j' |3 v, |0 T$ i9 C9 t
% ?$ m7 `: m# F9 Q
        ENDP  // End of SelectDevice Procedure0 R8 s7 N. d5 @, h% v
2 o% W( n* c$ g
        // 向IDE设备发送存取指令
- u. R& a/ j" d/ _        SendCmd proc3 Z: D/ C2 z4 ]+ u+ u8 |

% i% A6 @, W/ l2 [" _        MOV DX, dwBaseAddress9 B) ]- |" Q1 x7 W* s( x+ X
        ADD DX, 7
) o. _1 E: @2 i4 i5 c6 Y( m: f+ Y        MOV AL, BL // BL是主从盘标识,在过程外设置, r3 K* L6 c. ?. h/ s
        out DX, AL3 e1 A) ?5 {( F' H7 r4 |
        RET8 ?; S" k: s" O% T: @
        ENDP  // End of SendCmd Procedure
7 J- x# U) i5 @, h8 Y2 x; y2 u9 C! P6 ]+ S
        // Ring0代码6 e' d4 h) Q. e* w) W/ U
        Ring0Proc:
7 k! U9 ?+ J( I& H8 e( ?        PUSHAD
" e, ]4 i4 C- n! o3 ]7 e        // 查询IDE设备是否存在
4 v/ `( ~/ l! t( Z        MOV DX, dwBaseAddress
$ S- i( g3 v! ^" k5 N& M7 I& \        ADD DX, 75 s+ F* H8 \, b0 f
        in  AL,DX2 _& y) x2 H8 a3 P6 C& u* }" A! w
( T  A$ Y/ M, t5 b# w/ l3 C
        // 当AL的值是0xFF或者0x7F时,IDE设备不存在,这时候直接返回+ ^5 t) b2 ]5 w" u$ t( n
        CMP AL,0xFF
$ r- H" y; j2 P& V        JZ  LeaveRing0
# s' v- J1 `5 Q9 p        CMP AL, 0x7F6 B( w  S# S( N4 T
        JZ  LeaveRing0# a. V" ~( s- z. t2 n) p
! S6 w3 I$ _" K. k
        // 设置IDE设备存在标志
) ]9 Q1 U8 B' L& J7 A% F        MOV btIsIDEExist, 1  @: ]' S, ~, g/ u7 H

, U4 c# w/ p3 i' Z" k6 _' A        // 查询IDE设备上的驱动器是否存在(有IDE插槽在主板上,但是却不一定有硬盘插在上面)
- ^6 G" C; |- ^8 G2 F! K        CALL WaitWhileBusy
( f; g' ?( A5 s5 U" n        CALL SelectDevice7 G7 k! }$ A) u! C1 R" p( I2 h

1 S- M9 n; H9 x3 {, D9 J% g, j        // 如果是第一次调用,则直接返回,否则执行下行语句时会出现蓝屏
  U' ?' G+ |9 J4 q. w( M0 F        CMP  btIsFirst, 1' E( [+ Y, c4 S0 n9 r
        JZ   LeaveRing0
# }: x$ R, o0 C% P2 y. ~
0 M- D& b* t7 \) G+ y% G' z8 L8 U        // 第一次调用时,如果执行这行语句会导致蓝屏,Why???
" ^& L+ T/ S  v" z; M% [        CALL WaitWhileBusy
& U/ r0 ]% D  `9 l0 R* C9 e2 C0 L1 h7 S9 j
        // AL的值等于cBit06时,不存在驱动器,直接返回
( N. j( U4 x3 a. v* ?% L        TEST AL, btBit06/ J; o- ^& ^! \' l& b( o- q+ N! |
        JZ   LeaveRing0
4 n2 {5 D- W& `1 U  s) C& v  h
0 }) U, A# y) a4 e! \3 x$ f        // 设置驱动器存在标志
6 Y6 |/ R' G' _5 b8 K        MOV  btIsDiskExist, 19 {* N2 r* ]4 d
2 v7 n+ U, a" t
        // 发送存取端口命令  l. k( l0 ~# C( y: q7 Q$ W
        // 无法像NT/2000/XP那样可以通过查询VERSION的值得到驱动器的类型,
& S* O( f8 R  L$ v- ^7 t! W        // 所以只能一步一步地测试,如果不是ATA设备,再尝试使用ATAPI设备命令
" p$ v7 x3 u5 ?: l! m        CALL WaitWhileBusy
( L, H7 v3 ]8 Z: b* E        CALL SelectDevice    // 设置主从盘标识6 Q( v8 ?  r% D+ ^
        MOV  BL, btAtaCmd      // 发送读取命令# C, l" A/ D1 ~+ ]
        CALL SendCmd$ t3 A% W! P, Z) _" F
        CALL WaitWhileBusy1 I5 Q2 U+ X  m

5 h" ]" ^( a6 l9 i, L        // 检查是否出错
* Y" M3 D* Y5 a        MOV  DX, dwBaseAddress
  Y! Y0 y: ^7 C* q        ADD  DX, 7
  ^7 C+ p# ~* p/ w: D6 w3 Z# @: _$ \' P" H$ a; X% C
        in   AL, DX
; d3 B6 Y4 J; z& W# L1 Y( n* V/ @3 j- x) l  D4 h5 S
        TEST AL, btBit00
8 j7 f0 ?1 L, z# h4 X4 _$ g        JZ   RetrieveInfo   // 没有错误时则读数据- l- P; O& m( P6 S1 s" h: \( z7 q

; _$ k5 T- x" P/ N+ {) O+ U        // 如果出错,则进一步尝试使用ATAPI设备命令
/ Z5 B3 B6 ^; n" ~& i        CALL WaitWhileBusy( ]. J3 W: p6 H/ M/ `$ K8 w
        CALL SelectDevice; u6 a; S# I* P; V0 B- W$ `6 A
        MOV  BL, btAtapiCmd+ G7 D: {0 _& }
        CALL SendCmd( N' N  [0 R3 B
        CALL WaitWhileBusy: ^; {, U# z3 L- t5 B$ H
5 f- S4 p3 o! @2 s
        // 检查是否还出错* v/ s5 g' L6 n, o; n7 P- X5 a& j
        MOV  DX, dwBaseAddress: s1 H8 `) t: h4 [# ~" J/ e- E
        ADD  DX, 72 Q+ ~  p) v  X- C8 h7 C
        in   AL, DX
5 Y) s- z% c: b' f4 l        TEST AL, btBit00
% ]2 O) b' E! Q. J* K4 y3 ]        JZ   RetrieveInfo   // 没有错误时则读数据
" s; z* w$ d+ @        JMP  LeaveRing0     // 如果还是出错,直接返回
% B* l' @! J, U1 l4 W* s
$ D* e% p- H; Q" W2 t, i* L        // 读取数据
+ K5 G" q  l9 C2 P5 f+ `        RetrieveInfo:
7 o8 c: @& e% G0 b9 e, E9 {2 t- Q: V  w8 N! E
        LEA  EDI, wOutDataBuf
+ ]  _. @, [: ]0 ~5 [        MOV  ECX, 256
9 n; d: }+ p+ I4 N3 s* ^1 Y. A$ Q        MOV  DX, dwBaseAddress
9 l- X" I7 n( I" w8 D0 R        CLD
- T$ v3 r; u! A+ `& D: C% |( x1 e' o8 q$ H. f5 N# D: X  `' m
        REP  INSW
4 L( e$ E3 P" k* E; k% Y# n6 j1 a/ k3 e3 P# n6 N
        // 退出Ring0代码
5 v8 i. k- c, S' P5 L        LeaveRing0:9 k  K7 N/ a: y# [: {9 D* m
6 @# C* @5 x) p# ]
        POPAD
% o, |! f* R, y. D6 Z+ i        IRETD9 @3 B8 g7 J9 C+ P8 K8 U& I

8 F0 _6 I' P9 Y$ m9 Q        // 激活Ring0代码( j& x* f5 q8 [
        EnterRing0:
2 N5 b' \; j' @0 @5 x* R6 k, ]- [$ }5 G. g: k* B
        // 修改中断门
+ o+ K8 u% l  D/ N$ p0 G; p        SIDT FWORD PTR btIDTR1) c8 h6 _3 ]+ R4 i
        MOV EAX, DWORD PTR btIDTR1 + 02h
1 E, J# ?3 v9 Q  s        ADD EAX, nHookExceptionNo * 08h + 04h
: X  ^) O! g0 ^, t        CLI
8 t- |, X8 d. c4 V4 U4 ?$ }$ b: P5 {4 H2 o/ @
        // 保存原异常处理例程入口
3 F0 }2 b9 Z$ X/ M9 u$ m+ ]+ J/ @        MOV ECX, DWORD PTR [EAX]) e. o9 J+ h8 s3 m5 w% A  S
        MOV CX, WORD PTR [EAX-04h]
; ?7 o  g: i1 i4 A        MOV dwOldExceptionHook, ECX
, H& I3 T6 d5 a0 z; g) S9 z" e1 R# h4 y2 G
        // 指定新入口0 I# C$ c+ d7 n" F
        LEA EBX, Ring0Proc
, W& y/ r& w' i) k4 V. j& o/ x# s        MOV WORD PTR [EAX-04h],BX3 K4 A  K: [( r
        SHR EBX, 10h( \6 q* n) C: E* x7 F
        MOV WORD PTR[EAX+02h], BX0 ~* @7 s( N0 m  x" h7 t- {

$ @. e7 B6 R' P& Y$ k2 ~        // 激活Ring0代码. U- N: k; {9 _
        INT nHookExceptionNo
6 \; {( E# K# r, Z7 T& u% q1 x" y' E, h; n; f7 ~/ P: X5 z6 T. n1 N' `
        // 复原入口  Y. p( {" _8 U  ]5 x
        MOV ECX,dwOldExceptionHook
' ]* ?2 L( u* ~6 \4 B5 a        MOV WORD PTR[EAX-04h], CX" ~; Y1 z$ V  }% B) ?6 p+ k
        SHR ECX,10h; X7 @9 g$ g9 ~; Z
        MOV WORD PTR[EAX+02h], CX
  V" \4 T; Q7 |; k5 n        STI/ p- r7 a5 ^# v! z& W
    }
2 `% L. j. Y( _( N* [/ U) [& }1 v    if(!bIsFirst), K! A" ^3 V, e# y: Z9 }
    {
9 |' Z7 g; H5 X% W' q- i  z. v        bIsIDEExist  = (bool)btIsIDEExist;
" D% m3 m) X3 n) w" u9 P  ?6 b        bIsDiskExist = (bool)btIsDiskExist;
6 X2 Y) _# R0 F& L1 u        CopyMemory(pOutData, wOutDataBuf, sizeof(wOutDataBuf));7 W4 v! G. P- Z0 u9 p0 s
    }
0 r0 U7 d/ }% y& T}
% ^* L9 j# b# N9 c0 }0 x  |) O) |//---------------------------------------------------------------------------
" Y' c4 `, ~& T4 I  U$ C0 O// 调用方法:
6 ?* }7 A) f& C8 f. o, Qvoid __fastcall TForm1::Button1Click(TObject *Sender)
9 D1 ]4 `+ v5 i  P0 j{3 [4 e/ V" g0 i% \6 m3 n( `% H# k6 f
    ReadPhysicalDrive(Memo1->Lines, Memo2->Lines);
4 u! k6 g5 r- x$ g. t}
( U0 w7 f. n5 }3 _+ B
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-9 06:31 , Processed in 0.037031 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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