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

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

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

  1. 6 U0 N" X2 S' s3 j: N$ D8 q4 J
  2. #include "StdAfx.h": i" r/ I" C+ |0 `% }" D$ C) j! p
  3. #include ".\puiddisk.h"
    ( z' A7 C' A; z0 a( Y& q
  4. #define _WIN32_DCOM7 `5 p+ j+ v3 s4 \4 `' h2 k
  5. #include <iostream>
    # ~- A$ k! X' f
  6. using namespace std;: y# h# ?% L1 d0 Q* ]) d
  7. #include <comdef.h>
    * M5 A8 x7 z- {; L% G  U4 C
  8. #include <Wbemidl.h>9 {0 C$ }2 `% J$ m3 g

  9. ' q" Y0 x6 l) ?; {' n6 g8 h
  10. # pragma comment(lib, "wbemuuid.lib")# w; i# R6 d8 e. ^
  11. CpuIDDisk::CpuIDDisk(void)/ `# W# Q# C2 m7 f' u% C: H
  12. {
    5 R4 C& C1 O! c2 i& ^. `/ U* D, L6 X
  13.     GetInfomation();
    , [$ h" Q" |8 y+ A9 O
  14. }  W9 W; [' i" C5 W' H6 ?; Z3 L
  15. 0 k, z$ ^" ?& Q# s7 j
  16. CpuIDDisk::~CpuIDDisk(void)8 b: _% v3 p6 l+ ]6 p9 ]
  17. {# e3 G3 D( \' Q. z/ \
  18. }8 W: Q. t0 Q! ~" }/ o
  19. int CpuIDDisk::GetInfomation(void)
    " ]# y: _$ h* E( M9 Y
  20. {
    ; p8 t) ~9 [' }0 a
  21.     HRESULT hres;
    / Z' r5 R4 B( r2 v6 O
  22.     //步骤1:不是必须的,COM只须也只能初始化一次6 h  ^# u; d+ n5 m- B
  23.      hres =  CoInitializeEx(0, COINIT_MULTITHREADED );" g2 O, z. p& f& }4 ~6 u4 i
  24.     if (FAILED(hres))! y, \2 d; ~% t4 V" M& U
  25.     {% T( u* Q$ `7 E6 s- w1 D, I) |
  26.         return 1; //初始化COM异常:注意,COM只须也只能初始化一次
    6 S% k8 Y5 j6 {. M' C$ p
  27.     }; f: s2 j" @$ I( \+ J
  28.     //步骤2:不是必须的,COM只须也只能设置一次  B, J2 m( _% c# S% Q* D
  29.     //Set general COM security levels
    & u8 n& S+ E4 e" b
  30.     hres =  CoInitializeSecurity(
    3 G7 E2 k4 f" H" l4 L) A5 q$ k
  31.         NULL, . s0 l) I( `% v$ r
  32.         -1,                          // COM authentication
    * L1 {+ d0 s6 q! O  b
  33.         NULL,                        // Authentication services
    + L. l& t3 {1 r1 R7 R5 E
  34.         NULL,                        // Reserved
    ) U* i; B/ \$ B6 p. z! a2 L; g
  35.         RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication
    ' M$ u' t# d7 v- V
  36.         RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  / i7 [8 j$ b* q4 D! \3 O/ J
  37.         NULL,                        // Authentication info; {- i; i' j7 ?/ @+ Q
  38.         EOAC_NONE,                   // Additional capabilities
    $ N* e* s8 ?$ E
  39.         NULL                         // Reserved
    4 m  f( y! h0 D- {
  40.         );
    2 l* c: x8 ^, E, h5 @
  41.                      
    " |- L0 \$ a( M) K/ n3 P
  42.     if (FAILED(hres))
    # \8 ^7 I6 I) R# [6 U5 Y
  43.     {$ g/ M, x, Q% d/ \
  44.         CoUninitialize();* N2 n+ n  L4 o1 Y' ~1 ?
  45.         return 1;                    // Program has failed." S* R' T& `3 Z9 U  R$ [
  46.     }2 k( I0 F, r# K9 b' `
  47.    
    / \7 _9 s: g5 Z: h0 \9 R3 Y
  48.     //以上不是必须的,若已有“::COMInit();”,则要跳过
    0 \8 {" g6 D( d9 \5 F& q
  49.     //步骤3: Obtain the initial locator to WMI - `/ h5 v! r+ q/ O+ C
  50.     IWbemLocator *pLoc = NULL;+ \# V: ?, q2 f* o$ K- t/ i" Y
  51.     hres = CoCreateInstance(
    5 {, T3 @4 v0 l% g9 c/ l1 t6 |1 ^( |
  52.         CLSID_WbemLocator,            
    ; q* F9 c4 W6 z
  53.         0, 4 ?4 }9 P6 O( W5 Y) _. O
  54.         CLSCTX_INPROC_SERVER,
    8 [5 `  o( J4 [4 ]3 W8 e/ O
  55.         IID_IWbemLocator, (LPVOID *) &pLoc);& r7 B4 n/ N) ]* \/ s0 x. [

  56. # D) Q0 x" L! ~4 Z# X  ]  ^
  57.     if (FAILED(hres))4 X8 Y# H/ {1 m. Q2 S( k
  58.     {& r" W+ H4 G' B. y3 q
  59.         CoUninitialize();
    9 s5 K+ i9 P: w9 x; G( R
  60.         return 1;//Failed to create IWbemLocator object
    2 H1 l* |5 L; Q' |4 X- m
  61.     }- n& S  D+ p& r

  62. + e; M$ P1 \2 _6 ?
  63.     //步骤4:Connect to WMI through the IWbemLocator::ConnectServer method
      z0 q! \2 G; Z- E
  64.     IWbemServices *pSvc = NULL;
    8 V/ K2 q' i: b( q& s& [3 q
  65.     hres = pLoc->ConnectServer(
    4 V3 T5 X/ m0 ]5 `$ V1 }, _4 l
  66.          _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace4 y2 \$ |) C  C
  67.          NULL,                    // User name. NULL = current user
    ) k1 C0 k# E% Q' O
  68.          NULL,                    // User password. NULL = current
    ! B3 w3 S8 @3 L$ H
  69.          0,                       // Locale. NULL indicates current- R' C3 m* R4 S' I5 R
  70.          NULL,                    // Security flags.
    / ?. f' e7 R/ f5 K
  71.          0,                       // Authority (e.g. Kerberos)
    5 A. q% V- g. Q5 W3 L
  72.          0,                       // Context object + q& ?! C6 g% p$ e
  73.          &pSvc                    // pointer to IWbemServices proxy
    " e( W+ }! e7 I$ V1 M1 `) M. M
  74.          );' F9 t$ z* }% [( l% f( M
  75.     6 x# W( E7 ~* X" E& K
  76.     if (FAILED(hres))- `% |# v) Z) f
  77.     {0 z4 p0 |' n! U
  78.         pLoc->Release();     
    ' y& ?3 Z/ c: k  A5 T& _* p
  79.         CoUninitialize();
    $ u& V( _# |) b; o8 ?* g
  80.         return 1;                // Program has failed.4 u- ]+ V% H. Q2 F. f$ u1 N$ ~
  81.     }
    ! Q7 m! }' F4 U5 F, ~$ ?  k$ K
  82.     // 步骤5: Set security levels on the proxy
    ( m/ C% M3 h* i' ~
  83.     hres = CoSetProxyBlanket(
    - @9 d4 G, B0 u; m
  84.        pSvc,                        // Indicates the proxy to set
    3 _$ U8 [2 z( d8 C- J( ^5 c# z
  85.        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
    7 G7 Q* K  Q* b, Z0 P5 o
  86.        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
    6 _2 @. }+ g3 `  Q# u
  87.        NULL,                        // Server principal name ' ^- k  Q: g2 C. \
  88.        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 9 Q- I0 s8 \6 I5 p4 L5 I9 }
  89.        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
    + M; ?3 m" L0 E! V
  90.        NULL,                        // client identity* R- V" z( K, U$ k
  91.        EOAC_NONE                    // proxy capabilities 8 K) K2 b+ K* B; O' k* ?; z" S, p+ h
  92.     );# {, @: F( C3 o: e7 _

  93. 9 \( g; S7 H3 ?4 b% G
  94.     if (FAILED(hres))
    ) k* X. F( P$ p4 y8 T
  95.     {0 h$ y0 B8 }0 n5 c/ E
  96.         pSvc->Release();
    + n) G" B2 S5 L7 ^* I  S9 o
  97.         pLoc->Release();     
    4 f7 C' ^4 W0 }
  98.         CoUninitialize();
    ' g7 [4 T+ {- l5 n4 V9 O3 r, A, w
  99.         return 1;
    0 u4 Y/ d( f0 T# l6 [6 z5 d
  100.     }
    + ]1 y$ [+ X/ b2 z
  101. 5 I1 Z0 U3 G; k8 F: S7 y4 Q
  102.     // 步骤6:Use the IWbemServices pointer to make requests of WMI ----5 ?7 g7 N* d/ l* Y# L; t0 }
  103.     IEnumWbemClassObject* pEnumerator = NULL;- i; \! ?) L1 e8 V/ v1 }
  104.     //计算CPUID/ q/ i- a9 g2 c" c& l
  105.     hres = pSvc->ExecQuery(
    4 h2 M7 N$ q: E
  106.         bstr_t("WQL"), * u) ]( d4 t$ W; E/ X9 S, ?1 C
  107.         bstr_t("SELECT * FROM Win32_Processor"),//Win32_OperatingSystem
    , o( M8 B; \6 g4 c8 }! g6 @  u8 Q; t4 N
  108.         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    # Q0 X' w6 k9 ^1 C) u
  109.         NULL,
    8 G, Y2 F5 z: U% W4 i' u
  110.         &pEnumerator);
    + I( @% W" m4 o$ U" A% \' E
  111.    
    ; C5 H  [1 a: [9 }2 |" V$ Q
  112.     if (FAILED(hres))# w9 Q+ K" F! B: `9 `6 q- b, m: T6 E
  113.     {
    + i9 E/ c* J6 ~
  114.         pSvc->Release();/ @% {2 R0 C' N, ]' G
  115.         pLoc->Release();
    # H, ?7 Z3 q7 ^- e+ i' Y  c) F
  116.         CoUninitialize();$ T  n0 R  V& O7 {) v1 `
  117.         return 1;
    4 p3 T. V- N8 k8 z: [
  118.     }
    . ^% Q7 J- k2 G* a% ~5 Y- r
  119.     // 步骤7:Get the data from the query
    1 p% }$ @4 d( v; G% t3 S, ^
  120.     IWbemClassObject *pclsObj;
    $ u: V- `4 H: s+ l: t
  121.     ULONG uReturn = 0;
    3 S* d, w4 N, i; _# }1 i" j# |7 k
  122.     while (pEnumerator)
    % Y' i! O# P8 L( m# _
  123.     {, o2 o/ w; u6 U; O
  124.         HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
    3 P/ S8 `" R1 c/ B
  125.             &pclsObj, &uReturn);, ~' g: z5 K! q, {
  126. , ?, Q5 c: K+ X+ B0 L& p
  127.         if(0 == uReturn)
    ) b  f: P% ^5 s# M+ s. O( _% Z
  128.         {: o$ `" B! `' U% Y
  129.             break;" f: U) z9 q' Y% _7 n& [$ Q/ _
  130.         }
    ) @1 f  W( o9 d
  131.         VARIANT vtProp;- H* ^* M* T- F; y9 a
  132.         VariantInit(&vtProp);) R! M/ K# n( N0 U! v/ W
  133.         hr = pclsObj->Get(L"ProcessorId", 0, &vtProp, 0, 0);1 W9 V7 k1 c  C& B! i5 Y% X* u
  134.         strProcessID=_com_util::ConvertBSTRToString(vtProp.bstrVal);//strProcessID:类级变量
    1 W  X+ w* Q, K7 P4 p/ I# {- a/ q, |
  135.     }
    0 s# A! B4 k! ^

  136. 0 I* j5 m: E! Y, u- s( P
  137.     //计算硬盘系列号' u+ b! h# j* g4 f9 j$ v$ _
  138.     hres = pSvc->ExecQuery(. ?+ ]. ^$ _' E4 e
  139.         bstr_t("WQL"), $ q7 {7 h. R7 a$ o% N
  140.         bstr_t("SELECT * FROM Win32_DiskDrive"),
    $ k+ G8 l) n1 {) n4 }. @% Y$ K
  141.         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    0 w1 C& q0 d. _- t  R
  142.         NULL,- r" o$ V1 S3 u5 R6 k
  143.         &pEnumerator);( R; N& Q7 N1 ~/ n8 J$ W
  144. 7 `& j  t+ k5 f- I* j' q( K
  145.     if (FAILED(hres))
    5 s/ l; d; y0 i) C; [5 }- g
  146.     {
    * q9 W4 E. M# E7 H" P$ M
  147.         pSvc->Release();
    % L2 ^- I0 o  I
  148.         pLoc->Release();% w0 Y1 e/ `: y$ [' S: V8 [" T
  149.         CoUninitialize();
    & j" p6 I$ h, H/ K1 C$ V
  150.         return 1;
    3 r/ u/ E3 c+ O) r; u
  151.     }
    $ q/ A4 E& _7 A2 z3 J
  152.     while (pEnumerator)
    : b# @8 f3 j4 N* N% q1 @6 L
  153.     {5 q; R: l  K5 S; `" H0 \
  154.         HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
    : X1 A( K  N5 @: e: B1 k# `1 V
  155.             &pclsObj, &uReturn);
    7 X& ~  \  k1 j0 ~* o" b' @+ b

  156. ' f6 u# N6 J' ?
  157.         if(0 == uReturn)
    0 d5 v: E, O2 _& ^4 d3 C: L+ H/ a
  158.         {" g) f1 C7 f/ H. t3 J3 n$ A
  159.             break;
    1 C/ A; E/ h, q0 d) @3 M
  160.         }
    # Z9 J3 U/ L1 G& y0 S

  161.   O3 t7 \& w' U, n( Z, T, T! {6 w
  162.         VARIANT vtProp;6 j1 A& D4 V) f6 ^* n8 u2 n
  163.         VariantInit(&vtProp);
    / s% }7 S8 }+ x) i- a! G7 T& D+ A
  164.         hr = pclsObj->Get(L"PNPDeviceID", 0, &vtProp, 0, 0);
    ' H% J, `' ~# L. x
  165.     strDisk=_com_util::ConvertBSTRToString(vtProp.bstrVal);
    3 I* f: J7 h( i, V7 @) O
  166.     }
    5 G* T& T  l2 Z" k* l  Y: v! @
  167. 9 ~1 S1 F" k( P7 f, K
  168.     pSvc->Release();8 d4 q! h7 o1 {  {
  169.     pLoc->Release();; I& e4 ~7 Y! ~
  170.     pEnumerator->Release();
    * K( A! R7 a, d/ m& m
  171.     pclsObj->Release();, U% h/ S' F  W; s" c! f; n
  172.     CoUninitialize();
    & i% a4 f" l* e6 M

  173.   ?& A* c: @' V' |1 }1 l2 b( _
  174.     return 0;     C2 m- l& f6 G- E
  175. }
    . d8 G% h) y1 K  {1 x0 R9 ~
复制代码
 楼主| 发表于 2010-10-11 19:21:05 | 显示全部楼层
本文代码经ccrun(老妖)在Win2k下试验成功.
3 _. O4 D" K( N+ x  R: H8 K6 k3 l+ u1 [1 l* E
#include <WinIOCtl.h>( B5 o2 s* R- |0 h+ j( X/ c
#include <stdio.h>, I' j6 e" w% z
4 @9 H* _; s4 H! d, ]' g
#pragma inline
  F1 d* h9 k" E# F' f  o//---------------------------------------------------------------------------
: r" n# F! r! _2 Y; O// IDE NT/2000/XP专用变量
# H8 t$ {, H$ z#define GETVERSIONOUTPARAMS     GETVERSIONINPARAMS
: Y8 z" I1 E2 J: ~/ S#define DFP_GET_VERSION         SMART_GET_VERSION+ Z  U5 z) k/ ?9 ?: T7 Z$ e. p
#define DFP_SEND_DRIVE_COMMAND  SMART_SEND_DRIVE_COMMAND
5 z. P5 L. |' |( @- z#define DFP_RCV_DRIVE_DATA      SMART_RCV_DRIVE_DATA2 }; {! @' Q4 U. |$ L5 O. v

: E' N; `. D; K7 m+ a2 e. Xconst WORD IDE_ATAPI_IDENTIFY = 0xA1;   // 读取ATAPI设备的命令8 Z4 @  H+ F2 l% D+ Z8 K7 L! ?9 {
const WORD IDE_ATA_IDENTIFY   = 0xEC;   // 读取ATA设备的命令' w- w9 g2 \9 @% p

. U5 z. r# Z, u; kconst int MAX_IDE_DRIVES = 4;
5 d( G5 J5 ~: V. y- n% |2 ?% m0 X& T0 c3 u) R4 b: {& j/ t
// SCSI专用变量; C$ Z6 `/ j' F8 t( h
const DWORD FILE_DEVICE_SCSI             = 0x0000001B;
1 g2 E. Y- z3 S2 x- tconst DWORD IOCTL_SCSI_MINIPORT_IDENTIFY = ((FILE_DEVICE_SCSI << 16) + 0x0501);
; Y$ @  h. f# F8 b* N- ^const DWORD IOCTL_SCSI_MINIPORT          = 0x0004D008; // see NTDDSCSI.H for definition6 s# P* ]4 E  D
const DWORD SENDIDLENGTH  = sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE;
! F8 F( c! _% q  W8 y# `) D/ Q2 h1 d) {7 e  t
typedef struct _SRB_IO_CONTROL, ?) h5 O- ~  j2 A% T' P
{9 B5 j- K8 F- T# i
    ULONG HeaderLength;; V+ g1 }% ?, i( O5 L" ^
    UCHAR Signature[8];
4 P3 `' M, O5 m. v; x% [$ A5 c6 i+ \    ULONG Timeout;( q; L, g9 A' V' |1 g5 F
    ULONG ControlCode;5 ~8 Z3 y2 Y/ |; c* @7 h0 s3 |1 V8 y
    ULONG ReturnCode;8 i! d/ d/ D' z9 ^# Z  @1 f
    ULONG Length;
  Y% w8 h% x* ^$ f' P' ?) p}SRB_IO_CONTROL, *PSRB_IO_CONTROL;8 k% e  @2 g: y. @& e$ n
5 q/ M5 ]$ \) p, v6 M
// 读取的主函数
* n2 R' `1 L& ?8 Ivoid __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList);3 ^3 l* U" C0 k- x
5 F3 q0 ^7 w2 x
// 辅助函数/ Y7 k5 Z; [; ]+ K
char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex);  G1 g# r5 s$ K: b! a9 O
// NT/2000/XP函数6 x  U  H' r. P, z# Y9 O
void __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList);
* s) f1 R; u. m$ qbool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
% S. S4 @; y* U        PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd,( `3 L# S" p5 Z. V$ Z" Q- ~
        BYTE btDriveNum, PDWORD lpcbBYTEsReturned);
4 }2 x: W8 u& w1 ~3 `' x# Z// Windows 9X函数
# y, L: G$ h4 N8 Svoid __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList);
1 b1 q" V# {4 V; D7 O) Gvoid __fastcall ReadPhysicalDriveOnW9X_Ring0(bool IsFirst, WORD BaseAddress,
; X! o8 ]$ s( ]9 T/ a, `        BYTE MoS, bool &IsIDEExist, bool &IsDiskExist, WORD *OutData);5 g5 W! }' F, D/ K$ `4 c
; S2 y& L, L  \. `
// SCSI读取函数(for NT/2000/XP)
5 q4 u& g% _1 ]% Q  [, R4 I, HString __fastcall ReadIDEDriveAsScsiDriveOnNT();5 ^/ H4 v' [  l( u2 ]/ U6 s
//---------------------------------------------------------------------------, Y% T5 t$ U8 I4 ^( N
// ReadPhysicalDrive4 [( ?/ N9 t! b
void __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList)
8 T# M- G7 t6 t* w( G{
6 e; T! }& V4 ^$ ]" s    switch(Win32Platform)
0 o9 _2 k: S+ t9 c    {% m- `  l3 r! P- ]- K8 G
        case VER_PLATFORM_WIN32_WINDOWS:
! O5 [& V' @3 x( ~0 n( i/ x0 K            ReadPhysicalDriveOnW9X(pSerList, pModeList);# Y5 J$ t6 l% C$ a6 Q7 p6 @# k( r
            break;- a( }0 l+ G+ r. }' D
        case VER_PLATFORM_WIN32_NT:
- H; ]" m- d5 M8 u6 T, o            ReadPhysicalDriveOnNT(pSerList, pModeList);- ^/ x" n0 I. k
            break;
4 t. M5 s/ k+ Q* C( V0 B        default:
) J) n$ V/ l( ?9 U* F% r2 y            break;- D0 u" Y0 l/ c$ y
    }1 A  i  p. T- `! g0 U7 d
}9 h" a1 V3 i, H1 I1 y8 B
//---------------------------------------------------------------------------3 a5 e9 Z! H, J% V- l1 n
// ConvertToString/ |; q" I; k! _: O2 O6 _9 D* b1 ^
char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex)
  h: u* C* P" ^3 B. a. ^9 i{
+ b0 o8 G! P' W2 W+ w. t    static char szResBuf[1024];
+ n* K+ X, W& T    int nIndex = 0;9 K) ^/ b9 S' O
    int nPosition = 0;  t6 I  V% b4 m9 z/ Q4 B
; w5 m$ S4 }2 p5 E  u
    // Each integer has two characters stored in it backwards
% R& r( o+ v4 m2 t    for(nIndex = nFirstIndex; nIndex <= nLastIndex; nIndex++)
/ s5 G9 Q! G2 a/ k) [( Y    {, j1 }; }6 P" B9 l+ c$ e
        // Get high BYTE for 1st character$ P* `9 w! y4 b! x  r8 u
        szResBuf[nPosition] = (char)(dwDiskData[nIndex] / 256);
( \' q& s) {! R8 Q! W: p4 ^        nPosition++;6 j! Y6 ~9 a0 F' h
2 `% ^: v' C9 T3 R/ k& @
        // Get low BYTE for 2nd character) k  D1 t5 d2 m5 e- `/ W
        szResBuf[nPosition] = (char)(dwDiskData[nIndex] % 256);, n5 b% ^; |$ E  ~- ]) H4 m
        nPosition++;
, p1 @: L7 P: Z; R    }8 _( _- Z2 u. A5 K; a0 @

, I! h" T( H9 U% F    // End the string
7 j- V* c8 n, s    szResBuf[nPosition] = '\0';# d7 @: x8 s; [9 G3 b

/ d9 h, `; J+ f0 Q( h. _    // Cut off the trailing blanks
: l2 y2 j" X0 m, x0 o4 Z$ Q" r    for(nIndex = nPosition - 1; nIndex > 0 && ' ' == szResBuf[nIndex]; nIndex--)4 E" C4 j$ c8 o$ I1 D& {
        szResBuf[nIndex] = '\0';
. n1 F: X* _, E/ m+ j
) m% T4 `* r; r7 u# c! [; Y, T; A    return szResBuf;" {! T5 b+ K# Q
}) m8 w3 F, f4 u  ?2 g" h/ V
//---------------------------------------------------------------------------% M; P4 C7 j1 Q( x3 R6 M. Q1 p# o
// Winndows NT4/2000/XP 代码
4 V" t5 c' {/ o4 K& v; _- z//---------------------------------------------------------------------------7 I- a/ ^9 [6 H: M; [
// ReadPhysicalDriveOnNT
/ Q1 y0 J, q, L% Wvoid __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList)" e. I; B6 ?# U6 M0 @! C
{
! y  X$ g* ^# C. V& ]    // 输出参数
, J6 B/ x# |- u+ ?8 c( w    BYTE btIDOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];, C7 i! C2 L  k% q- \

4 \! `8 U' f& z! C    for(int nDrive=0; nDrive < MAX_IDE_DRIVES; nDrive++)# Z3 X/ V% H8 L! u3 u$ n* y
    {. s4 |* g; [7 ]& b* V4 {7 ^3 W
        HANDLE hPhysicalDriveIOCTL;
2 a/ A# X; h# F1 N) D: k        char szDriveName[32];. B: C$ {% I& O. V* d2 K0 l

. t: ~- y+ n( }! H, c2 ~        sprintf(szDriveName, "\\\\.\\PhysicalDrive%d", nDrive);5 b  k6 Z8 ^) W- c6 t$ U3 Q
        hPhysicalDriveIOCTL = CreateFile(szDriveName,
7 Q, R! R5 ~/ G1 W                        GENERIC_READ | GENERIC_WRITE,! o: n; @) [0 f$ n, I- ~
                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,% M5 B  H( h+ w
                        OPEN_EXISTING, 0, NULL);
- D" k3 I* ~% w' M  n
9 x$ g6 x0 N. W6 Y        if(hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE); k! n9 ^( N9 A. h3 A
        {
, w7 f/ J) [9 G; M/ Z% l            DWORD dwBytesReturned = 0;* {, Y0 |$ g$ P7 T. U# h
            GETVERSIONOUTPARAMS gvopVersionParams;- r6 M  L" u2 R
" V/ Z( v* d% a5 W* z# L/ n
            // Get the version, etc of PhysicalDrive IOCTL: `, y( Q6 p8 X6 o
            ZeroMemory(&gvopVersionParams, sizeof(GETVERSIONOUTPARAMS));) h! S5 A1 r" c/ C. \0 \6 J

6 B& R4 _4 f  W1 |# J1 d            if(!DeviceIoControl(hPhysicalDriveIOCTL, DFP_GET_VERSION,
" [; X, K$ l; z" K                    NULL, 0, &gvopVersionParams, sizeof(gvopVersionParams),
, a: c8 q! j% [6 n                    &dwBytesReturned, NULL))# Z0 \* M) p- v2 L! W  s
            {
4 v' z1 ]0 b$ W) j" C                continue;. W8 _( U% K# g3 |
            }
7 G' E0 [9 w1 y0 m2 `9 K  |1 j# {, c# }: D1 K
            if(gvopVersionParams.bIDEDeviceMap > 0)
4 ]' q/ x( E* e) i3 U            {8 a& s9 x2 R7 \! h- k; U
                // IDE or ATAPI IDENTIFY cmd# J( l' Q- p* b
                BYTE btIDCmd = 0;- X% N% A9 |) I: C* W( N
                SENDCMDINPARAMS InParams;& U$ M  v8 w8 l1 g
                // Now, get the ID sector for all IDE devices in the system.% p& d1 b. Y" s$ ^- X' _6 F
                // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,
" j+ `9 k3 g  e* {; i3 m, Y! a: H                // otherwise use the IDE_ATA_IDENTIFY command& M; R8 j9 g7 ^) I: b2 i" L' U; y; D
                // 具体所得结果请参考头文件中的说明
- X8 X! ~- H& }3 e                btIDCmd = (gvopVersionParams.bIDEDeviceMap >> nDrive & 0x10) ?6 T* J# U. d' v# Z7 B5 h* C. F
                        IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;9 x# {+ Q7 ?9 h/ ^
                ZeroMemory(&InParams, sizeof(SENDCMDINPARAMS));/ q, L, J1 z" B# ^- p& W" g6 x6 g
                ZeroMemory(btIDOutCmd, sizeof(btIDOutCmd));
5 `; g4 s$ e5 P  T
5 M. g* ~+ z0 e0 R7 i9 j                if(DoIdentify(hPhysicalDriveIOCTL,
0 t; A5 N2 c1 S                     &InParams, (PSENDCMDOUTPARAMS)btIDOutCmd,. b6 V+ |/ \7 E4 i. J4 w$ I
                     (BYTE)btIDCmd, (BYTE)nDrive, &dwBytesReturned))
& F  G3 @0 f: y) E                {. u9 h7 a$ B8 i% J
                    DWORD dwDiskData[256];
9 C3 P' x! e: y- c6 T, w$ N3 _                    USHORT *pIDSector; // 对应结构IDSECTOR,见头文件
9 p0 w. [; _: t! Q, [                    char szSerialNumber[21];0 Y6 q; {: V: |2 ~: w. ^
                    char szModelNumber[41];
) c2 }, c2 a, D/ |8 U( a- ]% r. q+ `7 ^3 Z% p: {( L6 W
                    pIDSector = (USHORT*)((SENDCMDOUTPARAMS*)btIDOutCmd)->bBuffer;
- a3 @, G# I. s! q                    for(int i=0; i < 256; i++)  F" F' F( e% u1 v2 D1 N1 I; e- }
                        dwDiskData[i] = pIDSector[i];5 S9 n8 A# R+ i2 k
                    // 取系列号8 G. v" K' Y* X; O5 i! i- Q' a
                    ZeroMemory(szSerialNumber, sizeof(szSerialNumber));) l: I3 Z; O& S+ t$ n5 [" [* {" l
                    strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));! F4 a' W' G8 T2 ?0 ^0 K$ k
7 X/ {* y4 l1 \: B3 A* r
                    // 取模型号
' t+ d' U! p5 z9 v7 M) X8 i                    ZeroMemory(szModelNumber, sizeof(szModelNumber));6 e: B, t0 O6 r: Y8 O
                    strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));  e, z2 j: T- F
; I6 @( o0 ?4 o: L3 o8 N
                    pSerList->Add(szSerialNumber);9 J( w, Q' V$ \
                    pModeList->Add(szModelNumber);
( C' O6 s: M0 x* {                }+ S; N. m% ]& }% r( t
            }
# m8 T4 Q  [+ b+ M- g) O            CloseHandle (hPhysicalDriveIOCTL);4 U* U: G8 n( i; Q( q: _
        }% d( d6 o$ c7 S! z
    }
, x& X' }  W8 v}, _- s0 J2 N5 O6 \( l
//---------------------------------------------------------------------------' b% Y/ M! t  F
// DoIdentify
8 Q* w6 V+ k1 Z% x& ^$ w7 gbool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,. Y" O: N; M' a! F( {& }* N
              PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd, BYTE btDriveNum,1 l" I2 j" X; F, a$ {+ W) h
              PDWORD pdwBytesReturned)7 ~8 g& M+ R, O0 d4 x
{
& B8 a6 d/ T' }: d9 O$ @" d; p8 g    // Set up data structures for IDENTIFY command.
( o- `# G5 |4 ?+ p    pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;3 D, i' O6 z# h- S+ e
    pSCIP->irDriveRegs.bFeaturesReg = 0;
% |$ F5 E$ {7 ~* \! n  a/ O    pSCIP->irDriveRegs.bSectorCountReg  = 1;9 R; I* p! P( d- u7 ^: ~4 ~
    pSCIP->irDriveRegs.bSectorNumberReg = 1;" m" {! w8 t0 Y2 U0 \
    pSCIP->irDriveRegs.bCylLowReg  = 0;3 f2 g& H' m: ?: d1 Z! ^" V
    pSCIP->irDriveRegs.bCylHighReg = 0;: {% ]/ k! _9 |0 h
3 k* x  y( X' V# E
    // Compute the drive number.(主盘和从盘所对应的值是不一样的)1 p1 N4 r9 @2 I
    pSCIP->irDriveRegs.bDriveHeadReg = (btDriveNum & 1) ? 0xB0 : 0xA0;
  ]# n. P$ u8 l8 W% V9 y: P* a0 f: x; t# N% K$ o: U3 f
    // The command can either be IDE identify or ATAPI identify.* S9 s# v: x" Q) ?8 s* w+ _6 `
    pSCIP->irDriveRegs.bCommandReg = btIDCmd;
: P! m" Q: s$ ~; R$ }    pSCIP->bDriveNumber = btDriveNum;- S( n: i! M5 z& m; n, e! _7 f% t
    pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
8 [' X/ `. O) K5 a" r
& E) M/ Y# k5 t( e) l% S    return DeviceIoControl(hPhysicalDriveIOCTL, DFP_RCV_DRIVE_DATA,9 r! M$ f8 ?/ _7 v; V
           (LPVOID)pSCIP,' G8 G; v) Q4 U* t: U$ `
           sizeof(SENDCMDINPARAMS) - 1,, g" q. `2 k! _- f) I* W) T- v
           (LPVOID)pSCOP,, `' j5 L" ]! q* g' @5 o; e
           sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
1 ~4 c. J- V: p7 V2 T- x4 L# |0 t           pdwBytesReturned, NULL);
% X- u* U$ d: i}) I& q- c. w% B3 _! `. q1 C
//---------------------------------------------------------------------------# _! d+ _! X6 N
// Windows 95/98/ME 代码
/ d: X' R1 D+ [8 s4 g$ A* [//---------------------------------------------------------------------------
0 w" C# m+ t8 o0 M// ReadPhysicalDriveOnW9X" f9 I6 `( V8 M+ p4 i0 A
void __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList)" y/ s' v+ \' X: s. P1 Q9 U9 q+ |
{
5 w% t  U% |" F  }: j    WORD wOutData[256];
) T. k- H( O7 D( f    SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);: O! a2 D# A* Y! f) K! z8 x. ]
4 R$ P& p- `3 E! O8 p6 ^
    // 经过测试,发现第一次调用而且Drive >= 2时会在Ring0代码中出现错误,导致蓝屏。
) F! Z! K  b9 I! B$ e% u    // 经过N(N > 15)次的蓝屏后仍找不到原因:(,不得不在这里增加一段无用代码以0 b6 L2 u1 n6 L1 W0 G4 W
    // 避免蓝屏的出现。(期待高人能指出原因)
4 ~! X3 o; g1 D5 R* e1 i    for(int nDrive = 0; nDrive < 8; nDrive++)
+ Q& R% j- K% X) A# {7 i4 ?    {3 U! k% b8 A1 v1 H( i2 H$ c
        WORD dwBaseAddress;" k. V5 a: @9 B, b4 |% @: p
        BYTE btMasterSlave;         // Master Or Slave
2 c( k  `: z0 w. t2 r) U; y# ?# [        bool bIsIDEExist;; O7 g6 A# |2 K! }- Y% i
        bool IsDiskExist;
  b5 W5 O5 ~9 s3 q
7 {4 t$ S% e$ Z, y  {        switch(nDrive / 2)/ \( @( d$ @/ L. U6 @7 U' L( F
        {
/ U: @1 A8 N1 j/ m+ n2 K            case 0: dwBaseAddress = 0x01F0; break;
3 G9 o3 y8 Q9 M$ e            case 1: dwBaseAddress = 0x0170; break;  S8 o6 r4 h( ^/ z% O5 y3 E
            case 2: dwBaseAddress = 0x01E8; break;
; f, G$ J( t# ^* \' f# {            case 3: dwBaseAddress = 0x0168; break;. S$ h; k; W5 U9 s2 t# G3 u3 m
        }
/ J5 c" K% x  d& [, H7 U5 Q& m* n  Z  G, R( R6 F4 k1 K. G
        btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0);
2 |! j3 g6 ^( X4 N6 \* f. w8 N: q
        // 进入Ring0
% ^7 i$ {, {0 y. o. }9 A) q' n        ReadPhysicalDriveOnW9X_Ring0(true, dwBaseAddress, btMasterSlave,
8 f6 f: i, ~3 q) F7 ^                bIsIDEExist, IsDiskExist, wOutData);, ^1 |# U4 N) J3 J: ?' C
    }) E& L0 h( R& o, O

+ Z# V* G* l% u/ S8 \9 h    // 开始读取
- f/ G$ R9 R! i! _) D* q    for(int nDrive = 0; nDrive < 8; nDrive++)
" _2 A# K5 G0 z/ Y. w9 m    {( t5 A) {4 N. [9 A* B
        WORD dwBaseAddress;
3 ?  c) Q" P* R& A4 o' @0 F9 ~        BYTE btMasterSlave;         // Master Or Slave, _/ a& \# e$ ?5 z( v
        bool bIsIDEExist;
, w$ N8 j; v! T# a        bool bIsDiskExist;
4 H& o0 T6 g9 ~* D+ o: x7 `        switch(nDrive / 2)
! }/ K! ?7 \" ]$ P% p4 D        {
" B2 _" Y' g. t            case 0: dwBaseAddress = 0x01F0; break;
) C* g4 y5 w5 d9 a) `9 d+ n            case 1: dwBaseAddress = 0x0170; break;
$ s+ k  Z+ W. H$ D. {8 H2 }' K            case 2: dwBaseAddress = 0x01E8; break;
3 _, @. f3 U( P            case 3: dwBaseAddress = 0x0168; break;
3 L; F+ H+ j) b. W( d' Z# j6 L        }
) Y- M5 L, `7 [% {
9 i% g4 I$ s0 S; E        btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0);' e, E4 o. A1 U/ P# T

1 q7 f4 I  n* J+ _0 h- l% {        // 进入Ring00 S7 ?: Q' D! P) x7 ?
        bIsIDEExist  = false;
7 a9 j: F! \" @8 H- z        bIsDiskExist = false;
$ S" d( j7 G4 ]5 K! G5 d# |: s1 n        ZeroMemory(wOutData, sizeof(wOutData));  v1 {0 G( N" b8 O: j

- S3 v# r6 i/ T: M) z; l3 r% A0 ]        ReadPhysicalDriveOnW9X_Ring0(false, dwBaseAddress, btMasterSlave,. J% i* \5 w/ n: j8 k% p
                bIsIDEExist, bIsDiskExist, wOutData);' g2 Q: s; ?% }1 T" ?3 K

  ]- K4 Q0 k8 o; x        if(bIsIDEExist && bIsDiskExist)
3 g# \' h2 v. y( k  h- J$ u        {4 Z8 {, t9 O3 ~) C1 p  O8 W6 K
            DWORD dwDiskData[256];! h0 W( A1 ?- Q
            char  szSerialNumber[21];
! Z* T6 C+ {8 l: t5 N7 j- Y6 j6 B            char  szModelNumber[41];
* K0 l( F( R  P4 V1 M- l6 d8 C# c: E+ h+ h0 c0 Q1 T+ H! M; A
            for(int k=0; k < 256; k++)( G7 _* d/ e; g% [0 B2 y8 F
                dwDiskData[k] = wOutData[k];- [+ H7 z- L8 ~
$ E3 w5 s4 A0 \. Q
            // 取系列号0 t2 e# w( `7 X5 _4 _" G2 P
            ZeroMemory(szSerialNumber, sizeof(szSerialNumber));
( ^5 a, d$ R$ S5 C  v( k7 j% Z            strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));
; C: l/ I/ ?5 P# Y; w/ K
: a  b) _! M% O            // 取模型号
- v0 z0 C8 F/ u! R0 }5 D1 O            ZeroMemory(szModelNumber, sizeof(szModelNumber));
5 m' A- I( d. C2 T. J/ W            strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));
/ F  X' _1 j/ o' S1 H3 w3 m& m2 e0 ^% U5 l# j
            pSerList->Add(szSerialNumber);
2 n  S2 }7 A" ~2 `3 I0 f9 Y            pModeList->Add(szModelNumber);" i9 @2 z; P7 R# r
        }. z+ l9 M- _/ ~8 ?' x
    }
4 X1 ]. B, j2 H9 A    SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
  E! g" I! ^# _6 i  L  D. X}. p: |) }; U; {3 R$ g2 Z3 k8 t
//---------------------------------------------------------------------------- j8 x6 j1 O! j- [0 l
// 为防止不负责任的转载者,在此注明原出处信息,请见谅。
4 _: U: w" M1 h! O" R: |: ?) ^// 资料收集整理:ccrun(老妖),欢迎光临C++Builder研究: http://www.ccrun.com
: n2 h( O% y& V, @& b//---------------------------------------------------------------------------
2 ]/ i3 T$ f7 Y// ReadPhysicalDriveOnW9X_Ring0()2 a; r, m; W7 [
//
* E) W5 P2 [" o: ^: g4 d// dwBaseAddress = IDE(0,1,2,3) : 1F0h, 170h, 1E8h, 168h
( _( `6 |1 \' B  Q7 m% u// btMasterSlave = Master(0xA0) Or Slave(0xB0)+ n1 z  E9 q  A* P3 q1 Y2 S
//---------------------------------------------------------------------------+ S6 t7 b, h6 l
void __fastcall ReadPhysicalDriveOnW9X_Ring0(bool bIsFirst, WORD dwBaseAddress,
# G% Y, i0 _$ g2 x0 v        BYTE btMasterSlave, bool &bIsIDEExist, bool &bIsDiskExist, WORD *pOutData)! _8 \9 u0 E: c% b2 J0 [
{
1 p" k: S3 }! a! u0 u, c    BYTE  btIDTR1[6];2 f% z5 u' E- b1 J
    DWORD dwOldExceptionHook;
. p! O+ [7 U+ `+ E/ _% {  ]    const int nHookExceptionNo = 5;' i) N% T9 B9 J/ A

0 q, X4 A- t! U1 n9 w% X    BYTE  btIsIDEExist = 0;
& z, D9 B/ R/ _: ]8 y: \; \+ e5 y    BYTE  btIsDiskExist = 0;
& C. R6 o/ ]; w+ g3 v3 k5 y0 M# G: N    WORD  wOutDataBuf[256];7 l# `9 q4 ~* j. G
5 E4 u. y) W- q( c& g6 c
    BYTE  btIsFirst = (BYTE)bIsFirst;
, e2 Z+ @9 U3 O; [3 c* Y1 {; G# I
    const BYTE btBit00 = 0x01;; ], h# E/ i3 A4 P" E
    // const BYTE btBit02 = 0x04;+ T! {; j, B$ x" A0 a! s, g
    const BYTE btBit06 = 0x40;
" ^( [: D0 a# F$ a3 c9 |' X    const BYTE btBit07 = 0x80;9 a7 ?- z; Q( C) J# `* |
    // const BYTE btERR  = btBit00;
7 K1 `  b# ^1 `  U7 b$ ]7 f* Z; }    const BYTE btBusy = btBit07;* m+ E- d& s9 ^
    const BYTE btAtaCmd   = 0xEC;, _3 f* q$ m* j8 K, N
    const BYTE btAtapiCmd = 0xA1;0 J2 J+ @- V3 |$ v3 ]7 k5 x

. P6 j& [0 G6 q( t4 }9 d6 \. K    __asm0 b) L: G& U& Q& u$ F! g: T
    {8 s) v1 o+ w2 f& O# C6 R
        // 必须先执行这条语句+ {2 V; @7 f3 g; v
        JMP EnterRing0
- E5 K) X* t  T( g: X" p# g/ |$ x# M& \) C- N( u) C$ V1 q
        // 定义过程
4 o' F) d0 i! |+ y        // 等待IDE设备直到其不为忙为止
+ r7 z8 M% L0 H, E9 ~        WaitWhileBusy proc$ E( c/ r0 r0 G4 g  \

- v6 n/ l! D7 {  t4 Z" Z- `% t, M& M        MOV  EBX, 100000  K; a5 j. t& g5 p* V% o' {
        MOV  DX, dwBaseAddress" ?# Z5 C2 v& X5 V
        ADD  DX, 74 |7 I1 d) \( M/ [
. b4 J0 f" ^  l# o
        LoopWhileBusy:
' l3 f8 _* y3 K  n* ^# K9 m0 Q2 V
' F  Z5 S: A( _( \        DEC  EBX% H6 f$ `. S7 _8 v8 g8 R, r
        CMP  EBX, 06 \7 _8 o+ i* q; B7 L% B7 ^
        JZ   Timeout
( H9 J0 g# Z" [& g" c        in   AL, DX. z# a& m. P" h/ S
        TEST AL, btBusy
& I4 q, B3 \4 t# ~        JNZ  LoopWhileBusy1 F) C& [0 D$ H& p
        JMP  DriveReady
+ j% K4 p3 F& D; V$ W, z$ l0 l, ?5 u
        // 超时,直接退出6 z! R7 u- E( _
        Timeout:- J8 Y- I% ~* {5 e
        JMP  LeaveRing0
6 D5 \9 U* m; U& v' p% i        DriveReady:* c6 s+ b3 X2 D3 }: v
        RET
! u# y. A7 O# P. {1 ~2 Y        ENDP   // End of WaitWhileBusy Procedure" A9 M% _4 D" b* ]1 B, f$ r2 g' m

9 d9 Z7 N7 T) h3 a) x! N  u7 I2 c0 c        // 设置主盘和从盘标志# D) }4 A% a- c% W/ U2 x
        SelectDevice proc
9 D9 Q5 i7 O  A  k! z) w' L( \6 z
4 l1 R* P# p+ V        MOV  DX, dwBaseAddress
% I6 Y$ M( W* c7 s/ ]        ADD  DX, 6' u6 }) ~7 W4 L; U2 r
        MOV  AL, btMasterSlave
9 d( X- M, N' c) O" r8 R! ^
( S1 i5 G1 }, t6 N% x9 U% q        out  DX, AL
6 F6 ^% K( D) A  C3 m! g2 D        RET8 ?* b, E# m  t, X4 x4 ?" X
; \+ t  x( G) B' \, q( _) u( \! _
        ENDP  // End of SelectDevice Procedure; k4 w- s& n, w/ g. _; g$ q
) ]! c7 V1 O% Z" m" T: [
        // 向IDE设备发送存取指令
  L+ g# \  W/ @; E% ?# A        SendCmd proc+ ^3 h, X0 I0 M4 Y

7 |, u) ]& I7 }$ i+ [) P        MOV DX, dwBaseAddress
, i8 M% }2 V6 X1 u" E        ADD DX, 7
7 R# A( _) n, w7 R, k        MOV AL, BL // BL是主从盘标识,在过程外设置
- W& ~: J2 R5 s9 [) w* l7 g4 ^$ X        out DX, AL& @0 i3 u3 V2 ~2 I; b+ C0 R
        RET3 _( F# t& R3 p0 v, t
        ENDP  // End of SendCmd Procedure  t4 E& H. r* k7 A& X- c

% [4 P: L7 b' n2 v4 |& b+ i        // Ring0代码
' R" f! q3 }( x: h8 l& j        Ring0Proc:5 T7 i9 i* {% X# Q/ {3 `
        PUSHAD  p7 B/ l* O0 t  W$ Y, O' @
        // 查询IDE设备是否存在
7 y; P" v4 I: A: R/ o        MOV DX, dwBaseAddress& T; q/ \. b) L6 `# s
        ADD DX, 7, g( I+ h2 d2 W. }4 b+ i" {) n
        in  AL,DX
& S7 t% @' J; k& S' ^( @# @5 N( z) P# ^  j- L" v1 m
        // 当AL的值是0xFF或者0x7F时,IDE设备不存在,这时候直接返回
! U* [; O! }2 E        CMP AL,0xFF
& C8 T* {7 O/ x        JZ  LeaveRing0
, y1 S/ B- j+ M3 R        CMP AL, 0x7F
& C1 D+ d' n4 ?        JZ  LeaveRing0
! H' \# n6 ^+ |0 p. k# g; E
+ [( ]. ]. _% f7 v  L, o: v: T" D        // 设置IDE设备存在标志
5 q" @4 J! A* f& V  u        MOV btIsIDEExist, 1
9 q( ^: j) f* Q, q/ A% F7 h3 O, X
        // 查询IDE设备上的驱动器是否存在(有IDE插槽在主板上,但是却不一定有硬盘插在上面)! h8 n- `' A! V$ D- o; Q
        CALL WaitWhileBusy- w/ g0 C& [  S% L8 V) x; @
        CALL SelectDevice
7 k0 ]6 m! I& a
  y& z, X' \: e; {1 K1 c* V  @. P8 r6 v        // 如果是第一次调用,则直接返回,否则执行下行语句时会出现蓝屏- e4 @) p0 h* H6 ~" G) G6 c/ j
        CMP  btIsFirst, 1! n+ c2 c& `$ P+ H0 |
        JZ   LeaveRing0
+ y7 ~) |. n6 v+ g) U5 u+ m
, z; s" ~* B: p7 `; M! V- R        // 第一次调用时,如果执行这行语句会导致蓝屏,Why???
$ i$ \+ D2 Y+ s! W  g% m% v$ \        CALL WaitWhileBusy
# m8 g' m/ x( S8 T6 {) u9 b- [/ l$ Y0 }) E
        // AL的值等于cBit06时,不存在驱动器,直接返回8 r& a0 x1 M; T7 E$ T* q
        TEST AL, btBit06! Y( n. b0 m* c
        JZ   LeaveRing0" R- \) q% C4 K& X! f

. J. C# k: i  A3 R/ C        // 设置驱动器存在标志
+ o1 V+ {% y! i3 e3 p) E* H5 o        MOV  btIsDiskExist, 1, C% ?% z& [0 e0 x6 M$ ~6 |( u0 m

, c- \; ]; k; @: Y# w        // 发送存取端口命令
, g# z0 E: O- [" g4 z, Q2 y        // 无法像NT/2000/XP那样可以通过查询VERSION的值得到驱动器的类型,' b. r3 E# ?- }) c) w5 e  j
        // 所以只能一步一步地测试,如果不是ATA设备,再尝试使用ATAPI设备命令# H( @; J2 f# I1 ~9 W7 |- R
        CALL WaitWhileBusy
, P9 h3 A% D, y$ A4 m        CALL SelectDevice    // 设置主从盘标识+ n2 a3 G: {6 U+ y3 c
        MOV  BL, btAtaCmd      // 发送读取命令
" u1 l% M' l$ I2 B) U        CALL SendCmd+ [% j8 ]: E: ^9 Z/ t
        CALL WaitWhileBusy
& `0 b% \# X0 @* @  s9 E! T2 ^) U  s8 U2 }$ ?
        // 检查是否出错* m6 t5 B. C1 p! T' r% M1 c
        MOV  DX, dwBaseAddress
& L% O1 [( W( Z7 j% x- ?: `; ]0 x        ADD  DX, 7, p" _- G: {3 Z0 ?; ^& X2 D' `% I

0 X+ j$ t2 G5 V/ K. `: |$ n0 x6 |6 n        in   AL, DX
% I) h- I3 a: Z  R+ h  L0 b
, J8 C0 c0 t7 i2 ]- p. [* [6 v, W1 \        TEST AL, btBit00' G2 I/ {, H4 k/ z% k1 [
        JZ   RetrieveInfo   // 没有错误时则读数据7 ?9 C) y9 @! c) \" @
8 v2 k# r' M) B: N
        // 如果出错,则进一步尝试使用ATAPI设备命令
3 q7 a, E  Q& N( O) F        CALL WaitWhileBusy4 S3 `) b4 F% M7 q! M
        CALL SelectDevice
: H6 _, d: u& P        MOV  BL, btAtapiCmd
. i# S# y0 h* n& ]/ I, D        CALL SendCmd$ e' Q9 Y( R7 q: O, @0 h
        CALL WaitWhileBusy+ M0 d# x$ T% k0 q4 `3 s/ `
. j3 v% \6 d# F; [( F; l
        // 检查是否还出错
+ g( }3 G& c0 k/ i) f, i' Z        MOV  DX, dwBaseAddress- F2 H3 t) u" E6 [
        ADD  DX, 7
$ ^5 Z; P+ g1 M) @+ T% r        in   AL, DX
0 e: F. d* |( e2 ?        TEST AL, btBit00
+ w: T- @! p7 z# j9 C* i+ g. w5 o2 d        JZ   RetrieveInfo   // 没有错误时则读数据
, E; v7 E4 u0 i" A0 J) }  O        JMP  LeaveRing0     // 如果还是出错,直接返回" a3 N5 \8 h. K, ]" U

5 Q- [% P' ]  o( M2 L' ~3 F/ H4 u        // 读取数据
* D- m- e' m9 _7 A% }) O        RetrieveInfo:
% T& \4 \- ]: U0 H- n, g8 p! g5 n, M/ U5 w
        LEA  EDI, wOutDataBuf: I1 N; w$ k$ ~; ]+ V& x4 \! h
        MOV  ECX, 256( ]% x, Y9 B9 a
        MOV  DX, dwBaseAddress5 A7 M3 F9 b% L; n* u& K
        CLD) R) q/ J1 x& o( V. `7 W) G
7 }9 I* {0 n8 T6 u% p8 O
        REP  INSW
$ H" @1 O/ `4 O4 ^- S
% X5 h& @3 ^/ i; K        // 退出Ring0代码
5 x/ [5 A' o4 A! k+ P4 @5 k6 A        LeaveRing0:3 ]* q. b% R5 D. ]

$ _' ?2 q, }3 ~; Y. S' x2 X5 J' p6 ]# W        POPAD5 K$ C5 E; I& c
        IRETD
0 J& @5 C. ]; Q& Z9 X" h3 O- n7 |" g7 Q
        // 激活Ring0代码% U* H! U0 p, ?, `* F4 p
        EnterRing0:
6 d& F/ f  l4 k" Q& E' U+ q; l4 A! X: }2 R/ R
        // 修改中断门
% ~* c+ X* W: |* Z3 z        SIDT FWORD PTR btIDTR11 M% r1 o7 r- U# S. r
        MOV EAX, DWORD PTR btIDTR1 + 02h( v. H4 [3 A! `5 e( ^1 w; D
        ADD EAX, nHookExceptionNo * 08h + 04h1 Y3 w. q8 }& A. i% s# \
        CLI
9 g5 ?8 y% S+ I# N9 x% \# o/ P, D! F
        // 保存原异常处理例程入口: i0 k* m+ Y* ~7 J, ^% j6 B
        MOV ECX, DWORD PTR [EAX]
5 x! _6 e. ?& Z/ t! @        MOV CX, WORD PTR [EAX-04h]8 Y+ Z& k. q7 V. Q3 S
        MOV dwOldExceptionHook, ECX
# K9 B8 Y& p. V# Y8 k7 {7 L* I& ^- i1 l9 q6 S% g$ g# S
        // 指定新入口# u, Z. ?" d- e: O: _  p8 _7 W
        LEA EBX, Ring0Proc
' [" I2 |6 |4 ^9 X        MOV WORD PTR [EAX-04h],BX+ G; C% g! r: a! v# V
        SHR EBX, 10h
- W+ z1 b) N9 A- d        MOV WORD PTR[EAX+02h], BX2 W& p) n- H$ r4 B  K

0 [: v3 Y& @# Y& x, n        // 激活Ring0代码
% y! Q: {( h* }        INT nHookExceptionNo* q# K9 A4 c/ T2 b7 ^( F

% Z1 t5 f/ c7 l$ \3 L        // 复原入口# U+ n- \4 f2 L
        MOV ECX,dwOldExceptionHook
/ q8 m, t) o" s( O        MOV WORD PTR[EAX-04h], CX
% O$ F# t1 F+ Q' p/ L9 r        SHR ECX,10h
2 J2 ?, [& _$ r- J1 S7 m+ \8 a        MOV WORD PTR[EAX+02h], CX
+ H9 q: t$ o0 R" E) v* @% N        STI' A- V  x! s- k6 X
    }
& i, S- @, [1 e. D7 y    if(!bIsFirst)9 W' V) T% u1 G, T3 \
    {
9 c/ C* \$ t5 M& m& F        bIsIDEExist  = (bool)btIsIDEExist;
1 @" W# V4 v( \0 r        bIsDiskExist = (bool)btIsDiskExist;
7 e! r! |2 l+ D( M& W6 C& q- g        CopyMemory(pOutData, wOutDataBuf, sizeof(wOutDataBuf));; ^7 @7 f, m: F5 a
    }
0 y# Q; F0 Q! [( r( a/ P- W}; I$ X( i1 C! b" x
//---------------------------------------------------------------------------$ g. p( t" a. z+ b# t* ~
// 调用方法:) l( A3 ]1 ~9 E2 k
void __fastcall TForm1::Button1Click(TObject *Sender)4 w1 t, f- O, R7 f7 D. J, t! \
{
  |. E. e- ]& t2 H    ReadPhysicalDrive(Memo1->Lines, Memo2->Lines);
5 \0 _$ ]+ R8 Y2 E% P( _$ q}
6 ^) C3 F1 N; ]" b7 }5 L' w; K
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-4 23:31 , Processed in 0.016434 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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