zoukankan      html  css  js  c++  java
  • VC获取硬盘物理序列号

    本文转自:本文来自CSDN博客:http://blog.csdn.net/ablo_zhou/archive/2006/07/19/942625.aspx  

    以下完整内容:

    最近才做完了这个获取 IDE 硬盘物理序列号的程序。声明一下,这个程序是我根据 Lynn McGuire 的那个 DiskID32 的源代码做了些自以为是的改动得到的,只能在 NT 平台下获得第一块 IDE 硬盘的物理序列号。同时,这个程序用到了不少未公开的 Windows 的结构和常量......
     
    下面就是相应的 C++ 代码,在 XP SP2 + VC 2005 Express 下调试通过。
    void GetDiskPhysicalSN(char pchDiskPhysicalSN[14])
    {
    BYTE IdOutCmd[530];
     HANDLE drive=CreateFile (L"\\\\.\\PhysicalDrive0", GENERIC_READ |
    GENERIC_WRITE,
           
    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
           
    OPEN_EXISTING, 0, NULL);
     if (drive == INVALID_HANDLE_VALUE)
     {
      // 错误处理
      return ;
     }
     GETVERSIONOUTPARAMS VersionParams;
     DWORD cbBytesReturned = 0;
     memset ((void*) &VersionParams, 0, sizeof(VersionParams));
     if (!DeviceIoControl(drive, DFP_GET_VERSION, NULL, 0,
    &VersionParams,
           sizeof
    (VersionParams), &cbBytesReturned, NULL))
     {
      // 错误处理
      return ;
     }
     if (VersionParams.bIDEDeviceMap<=0)
     {
      // 错误处理
      return ;
     }
     BYTE bIDCmd = 0;
     SENDCMDINPARAMS scip;
     bIDCmd = (VersionParams.bIDEDeviceMap >> 0 & 0x10) ?
    IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
     memset (&scip, 0, sizeof(scip));
     memset (IdOutCmd, 0, sizeof(IdOutCmd));
     scip.cBufferSize=IDENTIFY_BUFFER_SIZE;
     scip.irDriveRegs.bFeaturesReg=0;
     scip.irDriveRegs.bSectorCountReg=1;
     scip.irDriveRegs.bSectorNumberReg=1;
     scip.irDriveRegs.bCylLowReg=0;
     scip.irDriveRegs.bCylHighReg=0;
     scip.irDriveRegs.bDriveHeadReg=0xA0 | (((BYTE) drive & 1) << 4);
     scip.irDriveRegs.bCommandReg=bIDCmd;
     scip.bDriveNumber=(BYTE) drive;
     scip.cBufferSize=IDENTIFY_BUFFER_SIZE;
     if (!DeviceIoControl(drive, DFP_RECEIVE_DRIVE_DATA, &scip, sizeof
    (SENDCMDINPARAMS) - 1,
           (LPVOID)&IdOutCmd,
    sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
           &cbBytesReturned,
    NULL))
     {
      // 错误处理
      return ;
     }
     USHORT *pIdSector = (USHORT *)((PSENDCMDOUTPARAMS) IdOutCmd) ->
    bBuffer;
     int nIndex=0, nPosition=0;
     for (nIndex=13; nIndex<20; nIndex++)
     {
      pchDiskPhysicalSN[nPosition++]=(unsigned char)(pIdSector
    [nIndex]/256);
      pchDiskPhysicalSN[nPosition++]=(unsigned char)(pIdSector
    [nIndex]%256);
     }
    }
     
    需要自定义的常量和结构为:
    // IOCTL 指令常数
    #define DFP_GET_VERSION   0x00074080
    #define DFP_RECEIVE_DRIVE_DATA 0x0007c088
    // 用于 IDEREGS 结构 bCommandReg 项的有效值
    #define IDE_ATAPI_IDENTIFY  0xA1
    #define IDE_ATA_IDENTIFY  0xEC
    #define IDENTIFY_BUFFER_SIZE 512

    // 结构体定义
    // 保存磁盘驱动器的信息
    typedef struct _GETVERSIONOUTPARAMS
    {
     BYTE bVersion;
     BYTE bRevision;
     BYTE bReserved;
     BYTE bIDEDeviceMap;
     DWORD fCapabilities;
     DWORD dwReserved[4];
    } GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
    // IDE 寄存器
    typedef struct _IDEREGS
    {
     BYTE bFeaturesReg;
     BYTE bSectorCountReg;
     BYTE bSectorNumberReg;
     BYTE bCylLowReg;
     BYTE bCylHighReg;
     BYTE bDriveHeadReg;
     BYTE bCommandReg;
     BYTE bReserved;
    } IDEREGS, *PIDEREGS, *LPIDEREGS;
    // 发送磁盘指令的输入参数
    typedef struct _SENDCMDINPARAMS
    {
     DWORD cBufferSize;
     IDEREGS irDriveRegs;
     BYTE bDriveNumber;
     BYTE bReserved[3];
     DWORD dwReserved[4];
     BYTE bBuffer[1];
    } SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
    // 磁盘状态
    typedef struct _DRIVERSTATUS
    {
     BYTE bDriverError;
     BYTE bIDEStatus;
     BYTE bReserved[2];
     DWORD dwReserved[2];
    } DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;
    // 发送磁盘指令的输出参数
    typedef struct _SENDCMDOUTPARAMS
    {
     DWORD cBufferSize;
     DRIVERSTATUS DriverStatus;
     BYTE bBuffer[1];
    } SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
     
    同时,还需要提醒的是,这个程序需要用到头文件 Iphlpapi.h,并需要将 Iphlpapi.lib 包含在连接器的库文件参数下。
     
    其中很多的细节我还搞得不是特别清楚,该死的微软,那么多的好东西都不公开......


     

  • 相关阅读:
    547. Friend Circles
    399. Evaluate Division
    684. Redundant Connection
    327. Count of Range Sum
    LeetCode 130 被围绕的区域
    LeetCode 696 计数二进制子串
    LeetCode 116 填充每个节点的下一个右侧节点
    LeetCode 101 对称二叉树
    LeetCode 111 二叉树最小深度
    LeetCode 59 螺旋矩阵II
  • 原文地址:https://www.cnblogs.com/ganmk/p/1597902.html
Copyright © 2011-2022 走看看