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

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

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

  1. 2 D# s8 x2 J/ i( ~
  2. #include "StdAfx.h"# l# x& \! N) t" `1 `$ @2 d
  3. #include ".\puiddisk.h"
    & F( ^. A' W1 v& [9 h) a
  4. #define _WIN32_DCOM
    / N2 |9 o# f. z6 c8 |! e9 S
  5. #include <iostream>+ D$ ?5 x" X5 x4 D
  6. using namespace std;# A% B* h$ G% R
  7. #include <comdef.h>- J# ~7 E4 _" Y- Q
  8. #include <Wbemidl.h>
    6 o* J7 ]' v. K( i

  9. , [' h- r$ e+ a% p1 K, U. c: m
  10. # pragma comment(lib, "wbemuuid.lib")
    % E9 o/ |. S; e
  11. CpuIDDisk::CpuIDDisk(void)
    8 H- t" z, K, {3 |
  12. {
    : E) k+ ~( R% o9 S
  13.     GetInfomation();% b9 ]! Q+ h2 W% q! |
  14. }
    : V1 `2 f; {" A1 u& l; d5 x. h
  15. & X& a! H% F6 N# ?/ `
  16. CpuIDDisk::~CpuIDDisk(void)& b; P) e  H1 B, @7 U( M+ v
  17. {
    " F7 f% X  `! W$ R
  18. }
    3 R# [+ F$ _- q& H2 @
  19. int CpuIDDisk::GetInfomation(void)
    0 C4 B' k. d# a! ]) I
  20. {* m4 o- N4 W- W5 L9 J) d- L* q5 L3 t
  21.     HRESULT hres;
    5 o3 Z( `: A( p/ n, G# W
  22.     //步骤1:不是必须的,COM只须也只能初始化一次) o, z1 Y; O4 q0 S8 N+ v
  23.      hres =  CoInitializeEx(0, COINIT_MULTITHREADED );/ {  b  A5 {8 j& q$ O
  24.     if (FAILED(hres))& A5 [0 e# X! o1 I
  25.     {; I& T) x1 V, C
  26.         return 1; //初始化COM异常:注意,COM只须也只能初始化一次
    - U% Y. t8 S  {0 X$ @
  27.     }
    " e5 _* s, t+ \
  28.     //步骤2:不是必须的,COM只须也只能设置一次, x% L9 \* C" [4 Y* b8 I$ p8 A
  29.     //Set general COM security levels
    1 _7 X, [0 |+ U- P# i7 o" @
  30.     hres =  CoInitializeSecurity(
    0 r8 R4 o, q' c& W" C. {
  31.         NULL,
    , d1 z6 [- r$ s' j2 a( }: t. ?
  32.         -1,                          // COM authentication7 ~$ }3 c- K7 ?' s
  33.         NULL,                        // Authentication services0 w& d% C5 \5 ~4 ]
  34.         NULL,                        // Reserved
    # B2 @  S2 V2 [0 \" E& l8 z1 |9 }8 |* q
  35.         RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication
    + f( d& _9 w% G. u6 @
  36.         RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
    4 r6 P# U6 j; z# F  T0 S8 V, }
  37.         NULL,                        // Authentication info) O( B( |# ^8 E2 V5 f. [
  38.         EOAC_NONE,                   // Additional capabilities 1 W! p9 ]' t/ K/ ?  ~# ^
  39.         NULL                         // Reserved7 {6 k, s" u6 J* j6 k# O6 g3 [
  40.         );
    + [" n, D  V8 O6 u4 T2 |
  41.                      
    6 I; [3 m* ^  g5 ?- ]* B/ R
  42.     if (FAILED(hres))
    . f/ s, ^7 G9 j1 I+ M
  43.     {
      K9 j- R" X4 Z+ G& {* B5 U
  44.         CoUninitialize();' V7 [5 m' U; y% L8 X
  45.         return 1;                    // Program has failed.
    3 p1 t, x; d6 }+ j+ Z8 |6 l  N, e" b
  46.     }
    ( s" s! G! x2 ?0 y5 X. d& f
  47.    
    # N* X& ]. T. a8 M8 o' o, r  i% a$ u
  48.     //以上不是必须的,若已有“::COMInit();”,则要跳过7 P/ S( p2 m( M  V3 I" q
  49.     //步骤3: Obtain the initial locator to WMI
    6 R! c# N: q6 a' t
  50.     IWbemLocator *pLoc = NULL;
    , a9 o4 O. j6 r, a# S9 J9 M6 U5 u5 F
  51.     hres = CoCreateInstance(4 t5 S# ^0 g+ S) |, [; d2 L
  52.         CLSID_WbemLocator,             : l, m5 }6 \  B, w  F
  53.         0,
    1 G3 q. q, }8 @! e# [3 I
  54.         CLSCTX_INPROC_SERVER,
    4 M& r' x0 d  F3 L% f
  55.         IID_IWbemLocator, (LPVOID *) &pLoc);  z* V$ @9 s! S: q1 h0 _9 J2 p, Y
  56. 1 L) U0 n$ d/ P  |8 k/ X7 s: _
  57.     if (FAILED(hres))1 o9 x( d' z0 @" m, l2 h
  58.     {
    ' {3 j+ F) s+ z. z' t3 U
  59.         CoUninitialize();2 m& `) T: B/ v/ m5 ]) V( d
  60.         return 1;//Failed to create IWbemLocator object, {2 x, t9 p" @5 `
  61.     }
    ( g: B# y5 X; f+ |$ H+ J
  62. ' `0 \2 y/ H  k* G0 Z; R
  63.     //步骤4:Connect to WMI through the IWbemLocator::ConnectServer method
    $ j6 I8 l% U! X! l- N
  64.     IWbemServices *pSvc = NULL;7 M% Z0 {) o' I' T. _' l
  65.     hres = pLoc->ConnectServer(3 n- _" H4 X/ v+ k
  66.          _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace7 P3 z  a' D7 o( L8 p
  67.          NULL,                    // User name. NULL = current user
    : b' ~: u2 i$ U! m
  68.          NULL,                    // User password. NULL = current
    6 J5 W; R2 s5 s1 {& p, L
  69.          0,                       // Locale. NULL indicates current% q3 H% X2 ~! L( e2 O+ q0 m
  70.          NULL,                    // Security flags.
    ( S+ Q- ?: J. ]5 _# a, C0 G
  71.          0,                       // Authority (e.g. Kerberos)) G- [9 @9 W( A& L+ s4 S7 _8 R
  72.          0,                       // Context object
    4 d6 `' O, u+ u5 I; f
  73.          &pSvc                    // pointer to IWbemServices proxy$ E( P3 |" B+ o% E- o3 `3 O( O
  74.          );
    * b+ v6 }; F* j: v  l: L! j1 a
  75.     5 u# n3 ?( S; m+ M- B
  76.     if (FAILED(hres))
    4 V' D0 y, V1 K6 g
  77.     {
    ! Z9 U3 J8 F, e6 }! w
  78.         pLoc->Release();     
    ! F; q* K9 ]! d' W1 a% R
  79.         CoUninitialize();) ~* R4 }8 q& C7 u
  80.         return 1;                // Program has failed.) O, Z+ A4 p) q- l$ K0 o* d7 r
  81.     }
    6 W! ^  t% g0 C  z0 S( D1 q* q' h4 d
  82.     // 步骤5: Set security levels on the proxy0 F" c+ }, S( B  t
  83.     hres = CoSetProxyBlanket(% J2 I6 e5 }  e/ q& {: I
  84.        pSvc,                        // Indicates the proxy to set& i2 n$ i& }# y: S. K- w' t
  85.        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx+ r# f) S7 o5 P& Z0 n% |
  86.        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
    , z0 T4 n8 B5 l- Q. K
  87.        NULL,                        // Server principal name , Y3 [  e5 m# Z1 d, K; M) {
  88.        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx % \: O% e! O6 I5 z0 z! W: V
  89.        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
    # J# _2 @0 X2 Z5 v6 v
  90.        NULL,                        // client identity8 t* m; h( A2 m# M# [6 b
  91.        EOAC_NONE                    // proxy capabilities
    ! ^) g; C# z/ ^! x5 P. }6 O
  92.     );+ W0 t4 C  J3 x: x5 h5 J
  93. 0 G, E4 D4 y9 m9 A/ z" h
  94.     if (FAILED(hres))
    . n, t1 l9 E  I$ [4 K
  95.     {
    7 x, ]  |7 T6 d( v
  96.         pSvc->Release();
    * _: q. r7 K1 ?$ C' C
  97.         pLoc->Release();     
    1 J2 m7 c$ p* f) Q) a0 t/ Y( V* U0 y
  98.         CoUninitialize();
    4 B( b, b6 t8 @8 [
  99.         return 1;
    2 G7 k+ F7 N3 `- I7 X# v. @% ^; V
  100.     }
    # t, e% v% ^$ z

  101. $ L- H4 \) z; W1 z
  102.     // 步骤6:Use the IWbemServices pointer to make requests of WMI ----
    . Z' N& H8 d; v" C
  103.     IEnumWbemClassObject* pEnumerator = NULL;
    , H9 T& n2 Q! N: @- a2 e% l6 a
  104.     //计算CPUID) W4 m0 k1 i5 r4 a0 j3 s3 \
  105.     hres = pSvc->ExecQuery(
    4 ?% D$ H* E1 Y3 a
  106.         bstr_t("WQL"), ) o0 B+ Y9 g/ \& Q0 H! c1 S, k
  107.         bstr_t("SELECT * FROM Win32_Processor"),//Win32_OperatingSystem' Y/ {% m$ _% _$ c! ~; H# A$ u; J
  108.         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    ; f8 k" x  p+ z; t* [9 G
  109.         NULL,
    + _+ @3 A& O! {! _7 L; r0 T
  110.         &pEnumerator);
    , Z& ]+ L  `+ v0 G3 B0 p' a" R6 i
  111.    
    + a, g# K8 @% n
  112.     if (FAILED(hres))4 o6 r, I' _$ A# }# {
  113.     {# z* a4 F$ o$ N8 G9 ?. ^+ |$ W0 p0 w9 L
  114.         pSvc->Release();: `# |4 M# f- D" k
  115.         pLoc->Release();# B: V, T$ g. o2 V" X! _* @. [
  116.         CoUninitialize();5 C- h8 \# U1 j
  117.         return 1;
      ^7 X- a4 r; _0 C
  118.     }0 B# y' }: y& v7 K4 P7 a9 }: {
  119.     // 步骤7:Get the data from the query 8 D) k5 D" z; T/ s* I! Q+ p+ F3 T0 m
  120.     IWbemClassObject *pclsObj;
    ! U7 |2 K  _- ^+ Y! q$ H0 [
  121.     ULONG uReturn = 0;
    % O! a0 U3 O. x8 i! V2 P
  122.     while (pEnumerator)
    - i0 v) H2 x4 p4 r6 Y
  123.     {
    8 H- C( n) m8 O( Z/ U; O) X, Q" E
  124.         HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, % U1 N$ ]$ {. @3 m; n
  125.             &pclsObj, &uReturn);
    3 q) J, ]6 a* g7 x/ T7 ?
  126. ' y5 {& V8 d+ V
  127.         if(0 == uReturn)
    , i2 W" w) A& t7 X  k4 A3 X; `
  128.         {
    ) K0 `! j: E4 k4 L# T# u& R- F
  129.             break;
    & g1 M" C/ M' _0 F* w- S
  130.         }/ F( ?8 O) k( I, o8 ~0 H
  131.         VARIANT vtProp;
    2 u0 W2 h2 N9 ^) V, J2 Q
  132.         VariantInit(&vtProp);
    3 }" p+ D! x. T( `2 z4 L( m. w
  133.         hr = pclsObj->Get(L"ProcessorId", 0, &vtProp, 0, 0);7 l9 e  C; `. g
  134.         strProcessID=_com_util::ConvertBSTRToString(vtProp.bstrVal);//strProcessID:类级变量0 M1 i# y5 k! v
  135.     }8 i" I& [$ W- n& v0 f- c
  136. ) u& B4 @. m- A& w* w9 ]
  137.     //计算硬盘系列号
    # w$ P0 m; h) t' {9 v' q! D& @
  138.     hres = pSvc->ExecQuery(5 U2 w6 `6 Z/ z9 ^
  139.         bstr_t("WQL"), : K* [1 ]/ k, s; Q& x/ m
  140.         bstr_t("SELECT * FROM Win32_DiskDrive"),
    # ?+ s9 B8 u/ V
  141.         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
      p! \8 u) \; R( ^2 B, a
  142.         NULL,
    6 x# K9 o# t4 H
  143.         &pEnumerator);
    4 H" u# s3 l' a9 }
  144. / c: j: {8 X+ o1 U
  145.     if (FAILED(hres))
    : j0 C' C8 `9 e9 [
  146.     {
    ( @% B& A/ Q: _5 V* [9 p
  147.         pSvc->Release();
    . {' Y' p+ I* F% K) R
  148.         pLoc->Release();
    + B# ~' h6 o. m7 x
  149.         CoUninitialize();7 I+ ]& @  R: N3 i
  150.         return 1;
    1 ^1 n, k9 Y" Q1 B/ _
  151.     }
    / S, j! R( x, s3 P. U
  152.     while (pEnumerator)
    3 i) K) Z5 d; d7 e5 [
  153.     {; P  v' F' ]# Y' {. F9 a' {% t: `
  154.         HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, % M3 l+ E, {" z- E9 I
  155.             &pclsObj, &uReturn);
    ( o: f. X1 d! x3 e8 o* O

  156. 5 x& F- l  M6 @2 ^, @2 X! x
  157.         if(0 == uReturn)
    6 U5 W( T/ G2 c+ o- B
  158.         {
    5 o5 B6 x& r3 L' [6 I
  159.             break;
    $ Y* P% v# b6 I( L) _
  160.         }
    : k* l3 w, P: L. a& b
  161. 4 p& \8 A2 {) p# c# x
  162.         VARIANT vtProp;# W8 t" g$ e7 w# A4 W1 E; T0 q2 L
  163.         VariantInit(&vtProp);, X/ F2 p" |& e7 s  t$ G
  164.         hr = pclsObj->Get(L"PNPDeviceID", 0, &vtProp, 0, 0);) w* `: s. b: i( L$ [
  165.     strDisk=_com_util::ConvertBSTRToString(vtProp.bstrVal);+ B. }1 E5 B4 v. `
  166.     }
    6 i( J2 c( N% U- M! |4 p, _
  167. 0 ^0 b- u! C% ^9 i! o% {
  168.     pSvc->Release();* e  F- f% f' T3 e
  169.     pLoc->Release();
    # l' n8 v- A) o* y4 ?: R, X
  170.     pEnumerator->Release();. V1 x; b1 ?; J7 U# b# K" ^( Q' \
  171.     pclsObj->Release();+ t# z+ ]& C1 ^) ^6 ?  r
  172.     CoUninitialize();7 t& z+ e- G' ?

  173. / N4 I- J: a! J8 ?/ |
  174.     return 0;   ; R6 S4 g- b; b0 _9 _. p
  175. }
    6 A( D/ F: }6 f9 q
复制代码
 楼主| 发表于 2010-10-11 19:21:05 | 显示全部楼层
本文代码经ccrun(老妖)在Win2k下试验成功.! v( k; u. b5 M' E6 i

6 b; }$ C% G" y% |# {$ D#include <WinIOCtl.h>6 [; Z4 c! d, d) G5 e
#include <stdio.h>! f! B# Z: T& d$ l4 f" r, V
/ O; h2 @- I5 k+ L
#pragma inline/ y1 S+ t& x- h5 M: M# _! L
//---------------------------------------------------------------------------( @' u4 D% d, k
// IDE NT/2000/XP专用变量
, k! c5 [; _0 s7 I5 e8 Y$ w#define GETVERSIONOUTPARAMS     GETVERSIONINPARAMS
$ M4 f! `& P2 M- l. }* a7 {( s#define DFP_GET_VERSION         SMART_GET_VERSION% Q" v5 n" B: z  |# B, Z
#define DFP_SEND_DRIVE_COMMAND  SMART_SEND_DRIVE_COMMAND
& `1 V+ h. y) ~) R3 M% s2 c- w* B#define DFP_RCV_DRIVE_DATA      SMART_RCV_DRIVE_DATA
7 k. M* F% `+ R) P9 B% e
1 g( Z1 Z$ U' Hconst WORD IDE_ATAPI_IDENTIFY = 0xA1;   // 读取ATAPI设备的命令* \! E* U+ a0 B
const WORD IDE_ATA_IDENTIFY   = 0xEC;   // 读取ATA设备的命令( T  X  f7 l2 a! R2 R
; u- _% o$ N+ f$ I
const int MAX_IDE_DRIVES = 4;
$ @) R/ d2 q1 C) Q  A. C& _) @, S- Q1 S" |! l# l2 J/ O
// SCSI专用变量
) x* [/ m# H* S# Z& h1 kconst DWORD FILE_DEVICE_SCSI             = 0x0000001B;/ A* E( x& @4 X. V: ?) ~3 J
const DWORD IOCTL_SCSI_MINIPORT_IDENTIFY = ((FILE_DEVICE_SCSI << 16) + 0x0501);' u* G0 h% W% e, S0 x1 Y& L
const DWORD IOCTL_SCSI_MINIPORT          = 0x0004D008; // see NTDDSCSI.H for definition  S/ ?% x  ?( i7 m; Q( w9 T9 [
const DWORD SENDIDLENGTH  = sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE;
* a) c0 m% {; F$ k/ E3 [- R& k& R% k; W( S8 y5 ?: M. ~
typedef struct _SRB_IO_CONTROL
/ D9 d2 a' S& h{
  Y; q8 D: w2 a) X* D' B" G    ULONG HeaderLength;
* @0 L0 C' m+ n0 p/ m    UCHAR Signature[8];& e! p8 Q' F( h/ a6 M
    ULONG Timeout;7 x- D7 X3 {. Y
    ULONG ControlCode;9 v8 O6 p' P; V. c
    ULONG ReturnCode;
" c) x0 h- K' j    ULONG Length;
$ e6 Q* P- i+ ?( _- t# C) p9 b  u2 J}SRB_IO_CONTROL, *PSRB_IO_CONTROL;5 U# ?- L* ?% S, w% v7 E
# F6 w9 i  ?) I
// 读取的主函数  I( w$ A; M' n3 ~2 p) r
void __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList);; k$ j* P: Q  L0 l+ q: y
8 w9 W" g/ c9 I) T1 I* X+ N
// 辅助函数
0 t/ X' B6 G8 z2 N6 [1 fchar *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex);8 C/ N8 R$ X6 w3 H; Y5 q8 d5 `
// NT/2000/XP函数
/ B/ K$ Y! g5 d7 t9 f; avoid __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList);+ c7 Q% V9 J* B9 p- Y
bool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,9 T& ^$ m3 n- g% k! b+ E
        PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd,- F; S- T7 K! K/ c* P; ?/ u: q$ e
        BYTE btDriveNum, PDWORD lpcbBYTEsReturned);
" W% a) q/ V( `: T: Z9 c// Windows 9X函数
: y! O8 s* k! i, L/ c# |void __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList);0 f, K) k& P4 Y8 Z; e) Y" P
void __fastcall ReadPhysicalDriveOnW9X_Ring0(bool IsFirst, WORD BaseAddress,
$ ?- `( M' J( \0 B        BYTE MoS, bool &IsIDEExist, bool &IsDiskExist, WORD *OutData);
5 e$ x# M+ F5 i1 h5 K; x
7 R0 k3 h1 ?. Q# r+ ]// SCSI读取函数(for NT/2000/XP): ]' R; C+ D5 m( b
String __fastcall ReadIDEDriveAsScsiDriveOnNT();; E% ~; h, Y% M9 L$ E, X: K
//---------------------------------------------------------------------------
$ Z( A0 t- s  `* j, s3 m+ O- D// ReadPhysicalDrive
- \9 Q2 Z( ~0 O6 K$ o$ Ovoid __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList)" g+ P5 |& d4 W" p. |7 [
{6 i2 L  d4 B& H" s& z
    switch(Win32Platform)% r; f6 K) |; [& l. \! J  n
    {" P9 i* h  m9 w1 t: A
        case VER_PLATFORM_WIN32_WINDOWS:
5 a- u$ J6 v- [3 p            ReadPhysicalDriveOnW9X(pSerList, pModeList);. q0 h, \* d5 I( ]
            break;5 K6 E  u9 q. H$ @" p, Q. }
        case VER_PLATFORM_WIN32_NT:
5 k6 l1 L. ^+ T+ }9 [, Z            ReadPhysicalDriveOnNT(pSerList, pModeList);
( G$ Y6 g0 d8 m/ f* ]  n" k            break;2 W9 ]+ p6 f1 h; ^9 e4 f* S3 F
        default:4 D8 Q0 p! l! c
            break;
1 d! S  w' N; B! V    }
- \  v6 H: y* u( Z$ y4 f}
/ @$ ]  a: s5 C9 A, a3 j" L' y//---------------------------------------------------------------------------* _! h9 g+ f0 q8 x4 V% ]
// ConvertToString* s  Z2 ?# ^/ H
char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex)' P; n3 j0 v, o
{
2 Y( ?; P) }0 t/ G    static char szResBuf[1024];
9 O% |7 P" D& F/ @9 [    int nIndex = 0;/ D" {4 C/ _! |% H) Q; u  v4 u( h6 _
    int nPosition = 0;
, C  E: {% g( U; [& }( F; t$ N; U$ q% @) q$ N% R6 O4 z( N
    // Each integer has two characters stored in it backwards; s- e' P! `$ A! m5 y3 O. W
    for(nIndex = nFirstIndex; nIndex <= nLastIndex; nIndex++)7 _% t9 F2 k7 N+ Y
    {
3 p( l; ?# q2 Z6 C        // Get high BYTE for 1st character5 W' p& p7 x4 O2 O( t& [- Q
        szResBuf[nPosition] = (char)(dwDiskData[nIndex] / 256);
: W+ V) U7 Y7 x# C' C- p        nPosition++;: L$ w/ C. z! a' U& Q

  p- m* x( ?! o        // Get low BYTE for 2nd character+ j/ M* x0 Q$ n2 l
        szResBuf[nPosition] = (char)(dwDiskData[nIndex] % 256);
6 ~. K3 m8 d- M, t4 @1 G; [: A# A$ `, T        nPosition++;: B  Z7 a7 I% J) U: Y
    }* @0 ^7 f! {* h9 b/ t9 d

& J4 u5 G2 N( q( H: \& U; m' F( z" L: J    // End the string
" {9 G) W- Z2 q0 D, ~$ B    szResBuf[nPosition] = '\0';( C; t5 N# v3 h( b( |" b& i. K$ T

4 ^9 x& O' j4 w, h2 z    // Cut off the trailing blanks
/ F% s" @6 a  }0 d3 B9 L    for(nIndex = nPosition - 1; nIndex > 0 && ' ' == szResBuf[nIndex]; nIndex--)+ }6 W; v1 j0 Q2 `. s. ~
        szResBuf[nIndex] = '\0';( C5 ]* X, i, q+ u! Y8 k

# K# B0 X% n: h) k7 e% _    return szResBuf;8 N3 s4 a3 d! a$ g
}
& J2 L0 N( J4 q, m5 c2 I% u//---------------------------------------------------------------------------# q) N- I; H0 N: b( h2 a
// Winndows NT4/2000/XP 代码4 u% a/ |' l( A. h" U! D
//---------------------------------------------------------------------------
" K  i0 F. t0 i% c7 T8 N7 d1 D( K// ReadPhysicalDriveOnNT! j$ z5 t4 _) d/ k$ f! T* }$ I
void __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList)/ v3 y4 l6 E( O1 [, h6 ?
{- N# o4 U6 p1 ~& W8 \
    // 输出参数
0 Z5 _  [- C$ ?, S( M: M    BYTE btIDOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];4 b5 o: R+ f( D0 P! _

8 {7 m6 S# F' N; P3 ~' o  ^    for(int nDrive=0; nDrive < MAX_IDE_DRIVES; nDrive++)  R1 F9 l6 b; e+ M2 h- q
    {
  k7 K1 K# R* Z7 n" y* C        HANDLE hPhysicalDriveIOCTL;
+ z/ v, C5 o" `9 j        char szDriveName[32];3 r3 c* K% x; W. C
& O! x7 m8 `& D
        sprintf(szDriveName, "\\\\.\\PhysicalDrive%d", nDrive);
5 h( |; x& J* X. ?        hPhysicalDriveIOCTL = CreateFile(szDriveName,
+ z0 W/ _3 o, x  s6 B: ^                        GENERIC_READ | GENERIC_WRITE,
" E+ `" ^$ ]2 N2 s% U( K' t                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
" b8 `% ~( Y5 R: ]& w                        OPEN_EXISTING, 0, NULL);
: x6 |- w8 x5 }4 [, t1 o/ x+ b8 ]
5 ?: {% I  }; ^& }. {: N+ b# A1 t& Z        if(hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE). E) p4 s- K* k0 R( |
        {9 \% i: z# y) Q: F# ~7 H7 D/ c
            DWORD dwBytesReturned = 0;
' N; w& e! ^( I            GETVERSIONOUTPARAMS gvopVersionParams;
/ V( l, L+ Z; h! f% S6 K' j; |- ?. D$ H+ p
            // Get the version, etc of PhysicalDrive IOCTL# ^, j3 y6 C- b% i0 ~) F
            ZeroMemory(&gvopVersionParams, sizeof(GETVERSIONOUTPARAMS));5 N1 j! }  z9 s4 X6 v& `9 X# ~
% c0 U$ A, J# _* S1 |- o3 d) ?$ a
            if(!DeviceIoControl(hPhysicalDriveIOCTL, DFP_GET_VERSION,
  {' ?, x' f# A5 Q                    NULL, 0, &gvopVersionParams, sizeof(gvopVersionParams),3 s: C: N) K$ d7 e- \+ y) n
                    &dwBytesReturned, NULL))
, s! M0 a7 n% H3 h            {9 g2 g  a" H4 H+ |+ N
                continue;2 a( X7 {  _: x. e
            }
# Q4 F2 {/ l; q$ I  x
! t" ^' T; N7 b; N! d            if(gvopVersionParams.bIDEDeviceMap > 0)
* T/ W+ L  }5 P: N8 B9 d            {
+ G1 u; I, l0 [* y0 Q0 C                // IDE or ATAPI IDENTIFY cmd
) M1 m+ N! y" v                BYTE btIDCmd = 0;5 g# B4 D- v4 j: w& p5 u
                SENDCMDINPARAMS InParams;* K* r2 p1 ?+ B1 B* ^( E
                // Now, get the ID sector for all IDE devices in the system.  y7 F5 j/ ~- I
                // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,
+ X3 z* N% R, Q0 x4 N3 p                // otherwise use the IDE_ATA_IDENTIFY command) d0 z2 q# z3 z9 H7 I$ u8 S8 n
                // 具体所得结果请参考头文件中的说明0 F8 E' Z) h) [' f, g6 E
                btIDCmd = (gvopVersionParams.bIDEDeviceMap >> nDrive & 0x10) ?
. l& y7 Y5 R9 A                        IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;0 _6 \$ b, }* y. T
                ZeroMemory(&InParams, sizeof(SENDCMDINPARAMS));
9 q! F5 ?. f7 ^  j! r% ^2 x3 e+ ^                ZeroMemory(btIDOutCmd, sizeof(btIDOutCmd));& _/ s( \2 u+ Z

4 [/ X+ M0 \% ~* A9 Z2 }8 o                if(DoIdentify(hPhysicalDriveIOCTL,
. a; y0 c+ u3 K" C                     &InParams, (PSENDCMDOUTPARAMS)btIDOutCmd,
. d8 ?* T/ e: N+ l+ l                     (BYTE)btIDCmd, (BYTE)nDrive, &dwBytesReturned))
# f! s: i5 O/ R; x& u                {$ ~) i9 D# t& [6 m; [8 w
                    DWORD dwDiskData[256];
6 w$ Q5 n( i' }* S                    USHORT *pIDSector; // 对应结构IDSECTOR,见头文件
6 K7 o& ^7 g0 \                    char szSerialNumber[21];
1 x  v$ h* @- R4 B9 u/ Q( J7 H6 e                    char szModelNumber[41];
# m* ]: S1 o5 o2 K; z0 E
8 t. b+ U, G8 Y. l                    pIDSector = (USHORT*)((SENDCMDOUTPARAMS*)btIDOutCmd)->bBuffer;8 P' V5 u0 b- ]8 a$ e: K
                    for(int i=0; i < 256; i++)3 I3 C- p1 J( T& N* v5 U; B2 N. v& h' s
                        dwDiskData[i] = pIDSector[i];
* X! W5 e9 H& R                    // 取系列号
' k$ k# z% ~6 P( q2 z# O2 k                    ZeroMemory(szSerialNumber, sizeof(szSerialNumber));
) H' h, k' r' [  q# W, W/ Z( v                    strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));
1 r$ U% G9 V! r" I7 ^; s1 L) Z7 X$ V6 e8 ~
                    // 取模型号4 O& L/ x- v! _# k9 F8 w. a4 F
                    ZeroMemory(szModelNumber, sizeof(szModelNumber));
/ t. F. [  Q0 L, ]                    strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));5 ^3 f- P6 n6 H' I! W5 |3 m' [
* a7 M+ S2 L% {$ o+ k' c4 \
                    pSerList->Add(szSerialNumber);& k0 _( A. \2 W% j4 W
                    pModeList->Add(szModelNumber);; C" }7 q: J5 _/ a
                }8 k( H% x0 `( A$ t
            }
7 }3 z5 I. U6 u. D" e2 c            CloseHandle (hPhysicalDriveIOCTL);
! c; P+ g! S, W, u4 P6 v        }
0 I, ]- Z/ V5 `% f$ e    }  d/ M1 j7 M- _
}
: r6 Y3 K# B- \2 E& q//---------------------------------------------------------------------------5 ]" ?+ W7 f4 y6 K! {' f
// DoIdentify3 }# s& P* C* H, U+ g& g1 A  {
bool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
- [" v7 g2 m4 d' b# L$ @* a              PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd, BYTE btDriveNum,
3 s. U3 ~' K1 V1 ]- T              PDWORD pdwBytesReturned)  V, V* n  O1 F6 ]
{9 Z/ Y- @% i4 Q3 U
    // Set up data structures for IDENTIFY command.
" X/ o" A+ y; D* W' w0 K* X    pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
1 W7 F2 c  Q! A    pSCIP->irDriveRegs.bFeaturesReg = 0;
! L( N$ ^0 H1 P, `" S, U# [$ T7 O3 s    pSCIP->irDriveRegs.bSectorCountReg  = 1;
% ~" N. R8 B9 f! v7 G    pSCIP->irDriveRegs.bSectorNumberReg = 1;5 s- D9 Q" E  Q' Z+ W
    pSCIP->irDriveRegs.bCylLowReg  = 0;" B6 D2 W! k% }  j9 P( A5 C
    pSCIP->irDriveRegs.bCylHighReg = 0;
( `) ]* s* g: E. [$ z8 K/ ^6 N2 D! ]
; _& b; G! K3 }/ Z2 K* n    // Compute the drive number.(主盘和从盘所对应的值是不一样的)) q4 h) M( F) Q9 N; [4 h
    pSCIP->irDriveRegs.bDriveHeadReg = (btDriveNum & 1) ? 0xB0 : 0xA0;
7 h$ \" O0 Z% ~7 y8 _9 `
% E4 S: `6 `9 S# |# M* }    // The command can either be IDE identify or ATAPI identify." Z. L. R, P- T
    pSCIP->irDriveRegs.bCommandReg = btIDCmd;3 u% i! j$ ~- ~7 q
    pSCIP->bDriveNumber = btDriveNum;2 l6 M3 C/ n! V4 X
    pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
0 X' d% r0 X0 D' ?+ o+ v, L) `! }3 s5 U0 a  w. o8 N: V7 h6 f# Y
    return DeviceIoControl(hPhysicalDriveIOCTL, DFP_RCV_DRIVE_DATA,4 ^3 s6 j3 {  i' f# P. g8 a
           (LPVOID)pSCIP,
& V# t$ v, g! V1 q7 ^           sizeof(SENDCMDINPARAMS) - 1,
& Z$ W% D  z! n& d8 E8 v3 Z7 h           (LPVOID)pSCOP,9 X- n! n! [3 `7 n1 m
           sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,% {8 u( Y  Q9 r8 B/ n2 k" O7 U
           pdwBytesReturned, NULL);4 V8 B6 ], e5 q
}! y3 {6 s" p: V) X
//---------------------------------------------------------------------------
# F( u1 L. g/ X; u7 V( n) y// Windows 95/98/ME 代码  W+ G/ R. h- I( ~4 K3 S0 G; b9 ]
//---------------------------------------------------------------------------
  f: e8 ~$ R, S9 j6 H  [+ Q) |. N/ W// ReadPhysicalDriveOnW9X
+ |0 i" ~3 k  ~/ |; E6 Q7 U# qvoid __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList)' x) a' J: F3 X8 C9 A
{
$ D! G: u: |2 p* j9 Z1 J    WORD wOutData[256];( i4 u/ l$ f' I: I; [
    SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);7 ?$ I# k9 L8 N8 R  L5 B

: Z8 E  N% ]) t- q+ j% m7 d$ Z    // 经过测试,发现第一次调用而且Drive >= 2时会在Ring0代码中出现错误,导致蓝屏。! F9 @# Q- ]1 x  ^$ H; X& |7 P# \
    // 经过N(N > 15)次的蓝屏后仍找不到原因:(,不得不在这里增加一段无用代码以6 G) S% ^2 h8 `5 V$ U
    // 避免蓝屏的出现。(期待高人能指出原因)" b/ m& X$ z& _4 ~4 W4 R
    for(int nDrive = 0; nDrive < 8; nDrive++)$ O5 `7 T: H6 D$ _- w
    {. S! U. @5 }% K/ a% S
        WORD dwBaseAddress;
. ~& r5 c( C( |: l) {        BYTE btMasterSlave;         // Master Or Slave: U- \- }6 I/ c
        bool bIsIDEExist;
8 o1 R3 Y2 y& c6 ~) t7 D! Y        bool IsDiskExist;
) Z3 f. E) C% @, O7 W9 T5 k! R' {. l, k6 _1 v# d3 S
        switch(nDrive / 2), D# V. J7 }0 @
        {
4 v/ }" X" I2 S; D. V            case 0: dwBaseAddress = 0x01F0; break;
% c$ x$ e3 A/ ~! n            case 1: dwBaseAddress = 0x0170; break;  w' s& L* Y( v. ~6 y6 E
            case 2: dwBaseAddress = 0x01E8; break;8 t5 w- {0 C+ i" _% ]
            case 3: dwBaseAddress = 0x0168; break;
& a5 v% d3 U. u; T$ v$ G* i        }
; t2 ~$ Q$ u; A+ J1 t( _; F# g
7 L9 D6 V0 f# Y+ \        btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0);8 u6 t3 a% [, R8 u/ i- W) m; N

$ w& P; e9 J5 [" C/ _/ o        // 进入Ring09 P) {8 r8 V! e' T) l& o9 U
        ReadPhysicalDriveOnW9X_Ring0(true, dwBaseAddress, btMasterSlave,
: e  d& X: s6 b: K7 `/ E                bIsIDEExist, IsDiskExist, wOutData);! N, W! T8 C5 K( r5 g6 p
    }
  Z. K6 K; N, b$ I5 v
8 P& z% ?8 M6 j    // 开始读取
# [8 d5 R+ H8 ?2 _% [  ]- a) k, I    for(int nDrive = 0; nDrive < 8; nDrive++)/ X5 G" M$ h8 [0 n: Y0 }
    {% {- _2 w# N2 d. [- m2 y* M
        WORD dwBaseAddress;
# E3 X* L* Q; u  q        BYTE btMasterSlave;         // Master Or Slave
! K, T) J  x* u        bool bIsIDEExist;+ F% d9 O8 n# N- K5 s! Z3 }
        bool bIsDiskExist;
9 @; {# a% R% k4 J7 U! Q        switch(nDrive / 2)1 i' a; U" J8 r+ o4 t" I2 S
        {
0 P( Q/ @( C  n! Y) D7 m3 i            case 0: dwBaseAddress = 0x01F0; break;8 ^- _1 L: @: V
            case 1: dwBaseAddress = 0x0170; break;
/ B9 Z' o* ]( H4 p            case 2: dwBaseAddress = 0x01E8; break;% ]. L. X% u# D/ L8 Y" R
            case 3: dwBaseAddress = 0x0168; break;0 d" S3 ~1 r3 D+ P4 Y5 z* G- a: z, A
        }
: R2 s, w' o* D- j' Z0 }8 D1 B' e4 ]/ o
        btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0);
6 L5 R9 w5 _2 C7 U! A
  S+ r, I- t, L: g0 V- t        // 进入Ring09 q/ p: c2 }4 M8 A
        bIsIDEExist  = false;  D, |* k! t0 R: b: D4 A
        bIsDiskExist = false;
6 T# n" P$ a# G6 v        ZeroMemory(wOutData, sizeof(wOutData));' c* c4 h! R  `- x
& n  Z+ u  N9 t2 Q& ]! \" b
        ReadPhysicalDriveOnW9X_Ring0(false, dwBaseAddress, btMasterSlave,8 G$ K' M" O( S0 M& y
                bIsIDEExist, bIsDiskExist, wOutData);
; b" [$ |) J1 [) B# t
5 l. j) ]7 ^) L4 P5 ?        if(bIsIDEExist && bIsDiskExist); B9 ?* X( O2 P7 Y/ W- V
        {" p# c& B1 n8 [) y( I/ _+ B! A
            DWORD dwDiskData[256];" \) x* a* b6 _! b0 C- l% `: c
            char  szSerialNumber[21];
/ v- f" [1 @( \. P            char  szModelNumber[41];6 x7 h/ j+ }  ^0 `) r
+ |0 o$ r/ r. j" k, H
            for(int k=0; k < 256; k++)
. _2 b* X+ }: Z1 p" N                dwDiskData[k] = wOutData[k];/ i; z+ t4 Q8 e8 M  H3 c: n0 C
1 i; n! |( j! X7 R# v
            // 取系列号
/ b% q. A& ^, ]% O. [            ZeroMemory(szSerialNumber, sizeof(szSerialNumber));9 C+ G3 Q4 ]/ e6 Z9 r! x
            strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));0 U1 H% q' b+ Z: U; t9 ]4 i
  r7 k8 p1 V& A+ M
            // 取模型号/ U3 }- ~. x  \( |  |
            ZeroMemory(szModelNumber, sizeof(szModelNumber));
$ W; j- }8 \' x& @, t# H/ i+ q            strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));
* n4 u, i/ k2 i' ~: L& q+ U5 [# c) G
9 k0 ], w. ?% g! A) @; L) ~            pSerList->Add(szSerialNumber);
4 V9 \9 M$ ]0 j) w' r+ ~% |            pModeList->Add(szModelNumber);
' @" K5 ]$ f9 C% W        }
  z- S# {0 C" K* L0 T% m5 d    }7 \0 _7 p$ X9 d3 e
    SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
9 g8 U/ u0 D1 q- V}
4 N+ L$ H3 b, r: U//---------------------------------------------------------------------------
) T& l2 o3 }! G2 J% X& h// 为防止不负责任的转载者,在此注明原出处信息,请见谅。
! [: c1 o! O3 P( k. s* p0 n' ^// 资料收集整理:ccrun(老妖),欢迎光临C++Builder研究: http://www.ccrun.com
) J) z) X5 w( C) C. g% b//---------------------------------------------------------------------------
8 |( K1 ]' A* f2 ?3 \. p// ReadPhysicalDriveOnW9X_Ring0()3 x" j! ]3 ?" ~0 |- [3 o/ O# G/ h
//, J* e+ R$ H* K( P! z% h& M& K
// dwBaseAddress = IDE(0,1,2,3) : 1F0h, 170h, 1E8h, 168h
% H" L% [( Y; N9 v// btMasterSlave = Master(0xA0) Or Slave(0xB0)
# X5 q! p% G# K0 h) }//---------------------------------------------------------------------------6 I9 d+ h, o) X4 j4 y% e& z
void __fastcall ReadPhysicalDriveOnW9X_Ring0(bool bIsFirst, WORD dwBaseAddress,5 Y" o2 {7 n. B. p
        BYTE btMasterSlave, bool &bIsIDEExist, bool &bIsDiskExist, WORD *pOutData)
# M5 V* \4 y* b! Z; f{1 V- \  ?" \! G* C' x3 F2 r( _1 B
    BYTE  btIDTR1[6];
. n/ w, i1 ]& f0 X0 r    DWORD dwOldExceptionHook;  r8 O& [! g7 M6 `5 C: M
    const int nHookExceptionNo = 5;: K3 m- C0 L; [5 T4 R6 }

/ N$ s) k! a, [2 w    BYTE  btIsIDEExist = 0;
1 j* z' C9 [3 {5 }* y* N    BYTE  btIsDiskExist = 0;
3 r: h; T' o2 |- R- d    WORD  wOutDataBuf[256];3 ^. k" Y" ^- d

8 b! W! m- F' i1 i9 X: O9 k8 Z; R    BYTE  btIsFirst = (BYTE)bIsFirst;
5 B" u; l' B, i' O# C
3 U$ P9 p5 ?; O7 q2 d    const BYTE btBit00 = 0x01;
$ b+ d; |1 M& o7 q, R    // const BYTE btBit02 = 0x04;
$ \1 c1 ?4 N! R" M    const BYTE btBit06 = 0x40;/ k! l% X7 x- n# O& k% j; z2 S
    const BYTE btBit07 = 0x80;
& @/ V% v% h! |" Y    // const BYTE btERR  = btBit00;
& K% m8 O4 Q5 l  K/ X    const BYTE btBusy = btBit07;' [  t9 R- s7 O. w- @1 S- o# O( t
    const BYTE btAtaCmd   = 0xEC;% G9 I* k1 E" [' l5 _9 V2 q7 O: W
    const BYTE btAtapiCmd = 0xA1;
6 v$ Y) i( F: c! ~5 |0 _. t# `* G+ R
    __asm
( G1 d/ @) A" P) g/ }    {: ?% R1 T8 d2 Z8 K
        // 必须先执行这条语句# @; H; ]% _* a  ~. r4 }" Z2 k
        JMP EnterRing0
1 X' L9 U! v4 Y; Z" C4 d. K9 f/ I
        // 定义过程2 o4 C2 ]0 `" a" I; e
        // 等待IDE设备直到其不为忙为止
1 G* k& \7 K" u  b& ~& Q        WaitWhileBusy proc
# f2 A. c" y3 v  @/ B7 Q( A. e+ P& I: c+ e4 R) y
        MOV  EBX, 100000
) h' F2 n6 h& ~, A6 `        MOV  DX, dwBaseAddress) f1 z: F3 [- I: U8 ~1 ~
        ADD  DX, 7+ B0 A5 A1 r$ C) U( R9 W% `
4 S/ b3 R8 r% Y3 d* p
        LoopWhileBusy:% F  E2 r# {" c# w, j
. A( X7 R9 t/ I7 L+ t, j. N
        DEC  EBX
2 g1 u: i+ M, {        CMP  EBX, 0/ s: P/ f. H3 w$ U! M# S6 |
        JZ   Timeout
1 }6 ?9 w8 ]' h9 k        in   AL, DX
8 ^- X& m. U1 i+ L0 ?' }        TEST AL, btBusy: P% [' C) T7 o5 q, \, {- X% Y
        JNZ  LoopWhileBusy
8 f. n+ \. f* U  {7 E        JMP  DriveReady  X( `" ?# z; v' `, B" P8 ]$ E$ F

/ U6 k) J( z8 [  S; \7 \        // 超时,直接退出
% O1 \! X9 d, q  [% i/ X* h' e2 A1 t        Timeout:6 p7 E6 x- i- L0 j( d
        JMP  LeaveRing0
" R; s0 d( l7 Y4 D7 M5 K8 H        DriveReady:
2 _, g% Z( q- F0 {6 e5 `+ n        RET4 R5 t  j8 y' D4 S, L
        ENDP   // End of WaitWhileBusy Procedure( S) P3 g. F$ Y

5 g# Z! Q, x4 V# S        // 设置主盘和从盘标志
* E- Y' v1 M  q3 {' g        SelectDevice proc: X& ?' F7 v" Y% y( d

. K* A+ f- {  l" u8 k8 l' r8 ~        MOV  DX, dwBaseAddress
9 Q, A* ?$ G9 b8 B" `) K        ADD  DX, 6; i0 G* ]+ @1 w- X$ Q, [
        MOV  AL, btMasterSlave
' A8 X% K" n/ w8 e) m6 Q3 p8 t" r# j1 \/ }. r
        out  DX, AL
) I. `+ {2 o' l4 v: C        RET% n5 ?1 ~/ k* u& g1 O! E2 S

0 H+ D4 }' H& q& R. }$ A* t2 R' F        ENDP  // End of SelectDevice Procedure
/ s0 |, r( j2 J  A' b+ N: ?
$ @* g( H, u7 P% r        // 向IDE设备发送存取指令6 Y3 u2 b2 f* R/ B1 N8 F
        SendCmd proc7 S+ A4 r) Y8 {( q' P* ?7 ?- M0 l
3 M) b5 g7 A6 J/ O3 v
        MOV DX, dwBaseAddress
0 a0 H  H2 o" u9 b6 J        ADD DX, 7$ [' o5 v( ~9 Q" W, v
        MOV AL, BL // BL是主从盘标识,在过程外设置; L5 m% }! P: |) B. L( j0 q
        out DX, AL5 X( K3 c# z' k3 }  q' n
        RET
& D/ X3 G: g! f$ x( |        ENDP  // End of SendCmd Procedure, z: U" U: U8 ^7 c: @3 V' v
6 C5 i1 u+ O. \) T/ R9 m
        // Ring0代码. d( s8 P' w* y2 A2 ~- J
        Ring0Proc:- ]' B2 O  f# X8 N9 g7 V  U4 E; z
        PUSHAD
1 p1 C4 d/ _( Z8 _& P        // 查询IDE设备是否存在
, x6 [; o( t. b2 R- h        MOV DX, dwBaseAddress2 H1 F8 Z. t. P* L
        ADD DX, 7
: ~$ R3 g3 X: _/ |0 I        in  AL,DX
. b" J- [, y  z, f' r. ?: p
+ e5 M& c' T$ t2 a        // 当AL的值是0xFF或者0x7F时,IDE设备不存在,这时候直接返回4 D% v& C; N0 m2 s. S1 W
        CMP AL,0xFF2 m! k6 r: y5 _2 A5 j$ m( b* U( l3 ~
        JZ  LeaveRing0
- M, u( c& ?; G% `        CMP AL, 0x7F/ c  O) `/ c1 z- L
        JZ  LeaveRing0; o  w( p) M; D3 L; a
! O' a9 E$ g: g) Z% j$ A
        // 设置IDE设备存在标志/ _0 ?8 k! H& ?& `
        MOV btIsIDEExist, 1
; t! F! w8 C- E5 ?% H# I& `- V5 l  h' J9 }' w  A$ D8 a
        // 查询IDE设备上的驱动器是否存在(有IDE插槽在主板上,但是却不一定有硬盘插在上面)' f7 M/ a/ q/ ?# g
        CALL WaitWhileBusy6 a& U7 V( \$ Y" d) }
        CALL SelectDevice
) V! N5 J2 Y0 x) |5 r. j) v  J- ~5 @$ \( u' p
        // 如果是第一次调用,则直接返回,否则执行下行语句时会出现蓝屏
( p1 I0 X5 A$ x- Y- `        CMP  btIsFirst, 1  g/ |/ n5 O* b/ H; h5 {" e
        JZ   LeaveRing0+ l2 K/ `# d# I- N
- T! S' r5 {: d! f' q9 b5 d
        // 第一次调用时,如果执行这行语句会导致蓝屏,Why???# k. i3 ?  y  L  R$ j
        CALL WaitWhileBusy
0 @# q( g/ ^) q8 u
8 ?; Y% x  y9 ^( e4 l0 h6 i        // AL的值等于cBit06时,不存在驱动器,直接返回( Y: V* h' Z  h  Y- h5 M& D& G
        TEST AL, btBit060 x9 {0 I( d3 ?+ B
        JZ   LeaveRing0* k, V  y, b+ H2 I. R# b& G

5 |8 O6 c6 k. V+ J, m3 G) m        // 设置驱动器存在标志" }' Y: f0 F1 p: ?! F
        MOV  btIsDiskExist, 1
" P* }6 R3 N: W+ G3 v6 s6 G1 o* Z) O0 T4 z/ F* V
        // 发送存取端口命令
& r3 h. G4 ?& H* u        // 无法像NT/2000/XP那样可以通过查询VERSION的值得到驱动器的类型,! D- T! E: a  {* r3 |/ G& |+ \
        // 所以只能一步一步地测试,如果不是ATA设备,再尝试使用ATAPI设备命令
* p7 P5 A* W) f" w        CALL WaitWhileBusy; v2 h8 g+ B7 O, _1 k
        CALL SelectDevice    // 设置主从盘标识% m( ~5 b& [0 N
        MOV  BL, btAtaCmd      // 发送读取命令2 M! A3 x* I4 m" h4 s
        CALL SendCmd
) j! C( k5 [7 [2 w        CALL WaitWhileBusy* U1 P: R1 b- k$ r! i+ U0 N
! g$ M/ H- L4 k0 b( w# m% Y
        // 检查是否出错
+ I4 F9 x! i* }4 \        MOV  DX, dwBaseAddress$ P& d" S. x/ R$ N6 j
        ADD  DX, 7# G* O" c4 T* g& q/ v" ^$ a

9 t$ J5 J; R" O* m        in   AL, DX
' U; {7 f- ^5 _6 ]' {8 H6 ~; j5 y
3 p8 \  W: H0 b! A  G4 q9 j3 E        TEST AL, btBit00* o5 A; [: @  u6 i, c: H9 i; k) x
        JZ   RetrieveInfo   // 没有错误时则读数据
  P- r2 u( O6 U
- X" `6 Y) H' P' G0 N        // 如果出错,则进一步尝试使用ATAPI设备命令
) z8 a- o, y- @        CALL WaitWhileBusy" b6 T: x" O3 y* h6 ~* }7 H1 H9 ~
        CALL SelectDevice
3 u. ^0 M; r+ t+ f1 M3 {        MOV  BL, btAtapiCmd
- g5 l/ J; O& d) i" v% v- _        CALL SendCmd: Y; A( e5 |  Z: [" h; f* q" B4 i
        CALL WaitWhileBusy# ]' _& {& n" h  U" k5 Q$ |6 ^, j' L4 v
' p6 [. _6 t3 \$ Q+ |& Y5 v+ J
        // 检查是否还出错
) G6 D. E& R* s' ~* q* a9 T; {        MOV  DX, dwBaseAddress# S' A' A3 h& l, z! g- h. |
        ADD  DX, 7& Z9 `7 d( V8 y( [/ I5 V5 F" z
        in   AL, DX
( O( s- o$ Z: Z0 V0 d( a        TEST AL, btBit00
6 v& a1 r9 Y' X  R( m$ S3 d8 U        JZ   RetrieveInfo   // 没有错误时则读数据+ I/ g1 @. [% k' T& ~# ]# S
        JMP  LeaveRing0     // 如果还是出错,直接返回
' S$ i9 `- o( I* Z% X
/ N3 p" V9 E7 S: A' u( z0 P        // 读取数据3 o5 f1 K* j: ~" T6 M2 ^
        RetrieveInfo:
& }" [3 X2 X0 U( n7 \0 S* E! E
9 u# s$ E- s% |( C        LEA  EDI, wOutDataBuf
/ ?& W- Z$ e- ]( V% X$ y1 P        MOV  ECX, 256+ V: J1 {3 N0 T5 V! J3 O6 f
        MOV  DX, dwBaseAddress
8 i$ u# ]- J8 ~' h' g        CLD
5 @1 \0 i8 }. N
' j+ T3 ]9 i0 s        REP  INSW
- _% u4 K3 A2 s
- ?1 i' `+ A7 X9 {        // 退出Ring0代码
, U9 `5 ~3 q6 a6 X6 E+ a$ `        LeaveRing0:
; |  {; l* F  ]8 l
$ ~. M  G6 w5 p9 Q        POPAD
7 |( r; a. M( I. p% ^9 _( \        IRETD
$ H4 i' i! O5 c- C! Y- a5 r* p8 J5 h1 w2 j3 s9 k# }: N
        // 激活Ring0代码  I% [" ]& g$ q
        EnterRing0:
! G6 F9 i3 `( N* C" `" X3 g% h( z& K0 u4 d7 e
        // 修改中断门
9 V5 r3 V- D- G! j        SIDT FWORD PTR btIDTR1) Q5 N  N1 P# m5 A+ ]0 A  ]
        MOV EAX, DWORD PTR btIDTR1 + 02h  O7 T2 L: d' t4 e% b( x
        ADD EAX, nHookExceptionNo * 08h + 04h9 N. O+ z# G; n$ K. O. B
        CLI
: W" t! J) e. R* ^
- f; j( S) w& Y: w& i        // 保存原异常处理例程入口
- y6 G6 d2 R9 p9 `4 h7 {! B        MOV ECX, DWORD PTR [EAX]# _* ^" Z7 z8 N# m9 @/ }) u2 L0 V6 ]
        MOV CX, WORD PTR [EAX-04h]4 P4 l& H# _5 w) V' `
        MOV dwOldExceptionHook, ECX9 g% u4 a' d& N

. _! f2 Y5 ^/ q5 ~7 S* R  O" m# ]        // 指定新入口
; q4 T; e( p; B* T) _        LEA EBX, Ring0Proc
" D4 P0 o$ o0 |6 H( A        MOV WORD PTR [EAX-04h],BX
% o) c, Z2 Z' Y4 C. c2 ]        SHR EBX, 10h* N5 H0 W; Q% d( t3 z* {$ @
        MOV WORD PTR[EAX+02h], BX/ P. ]6 v2 [  l% s. k+ r' l0 M
* u) b! P# y) I$ k! K. s6 v8 [) x
        // 激活Ring0代码
8 R4 T# ?# x7 U- Y# ?  V/ z' p        INT nHookExceptionNo
9 |( e2 y( g! H2 s2 E
4 P9 c9 k. o) o/ {0 R/ y- z        // 复原入口' m/ E1 Z+ p* K1 b
        MOV ECX,dwOldExceptionHook7 w. q  i3 c/ J4 S
        MOV WORD PTR[EAX-04h], CX- Z! A% j' C) n# W" ?/ q
        SHR ECX,10h7 U, T1 d; s/ ?$ c4 X* M
        MOV WORD PTR[EAX+02h], CX# B# D4 C! b2 b* Z1 [
        STI
2 s, ^& d# t/ I# X( z3 P5 D    }3 d/ u4 ~$ U8 q( a
    if(!bIsFirst)
5 [5 v( m) P1 a" I' }. s2 f' P9 I3 z    {0 _+ T; h# Q' E) V
        bIsIDEExist  = (bool)btIsIDEExist;/ E7 G" S8 Z2 @. h- k
        bIsDiskExist = (bool)btIsDiskExist;/ c) ^) {. Q: N* ?& ^
        CopyMemory(pOutData, wOutDataBuf, sizeof(wOutDataBuf));: G3 t1 L& F) o; e
    }
( A% a3 [! M8 S}
5 Y3 N9 m* v. [: q//---------------------------------------------------------------------------( {+ S& \  K1 T' m. Z
// 调用方法:
) i3 p* w0 h5 F( v( h5 ?1 r  lvoid __fastcall TForm1::Button1Click(TObject *Sender)
/ N% V; d4 ~( @7 j; a4 @! `1 B{. d% z3 T5 v  i) `+ q- f2 j4 w
    ReadPhysicalDrive(Memo1->Lines, Memo2->Lines);
# r1 Q& H  f+ x* ^}) ~) f$ r1 \9 L+ v; y& z
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-1-27 17:45 , Processed in 0.019802 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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