说明:经过上百台计算机测试,IDE和SATA硬盘可以获取序列号;SCSI硬盘没有测试环境,无法测试成功与否。请有条件的朋友帮忙测试下,给个消息,谢谢。

虚拟机上测试不了,不用测试了。IDE测试出来全部是0000等数字。

网络流传的版本不少,下下来测试修改了下。

#include   <windows.h>
#include   <iostream.h>
#include   <stdio.h>

#pragma argsused

#define   DFP_GET_VERSION   0x00074080
#define   DFP_SEND_DRIVE_COMMAND   0x0007c084
#define   DFP_RECEIVE_DRIVE_DATA   0x0007c088

#define  SENDIDLENGTH  sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE
#define  IDENTIFY_BUFFER_SIZE  512
#define  FILE_DEVICE_SCSI              0x0000001b
#define  IOCTL_SCSI_MINIPORT_IDENTIFY  ((FILE_DEVICE_SCSI << 16) + 0x0501)
#define  IOCTL_SCSI_MINIPORT 0x0004D008  //  see NTDDSCSI.H for definition
#define  IDE_ATAPI_IDENTIFY  0xA1  //  Returns ID sector for ATAPI.
#define  IDE_ATA_IDENTIFY    0xEC  //  Returns ID sector for ATA.
#define  IOCTL_GET_DRIVE_INFO   0x0007c088
#define  IOCTL_GET_VERSION          0x00074080

#pragma   pack(1)
typedef   struct   _GETVERSIONOUTPARAMS   {
    BYTE   bVersion;        //Binary   driver   version.
    BYTE   bRevision;       //Binary   driver   revision.
    BYTE   bReserved;       //Not   used.
    BYTE   bIDEDeviceMap;   //Bit   map   of   IDE   devices.
    DWORD   fCapabilities; //Bit   mask   of   driver   capabilities.
    DWORD   dwReserved[4]; //For   future   use.
}   GETVERSIONOUTPARAMS,   *PGETVERSIONOUTPARAMS,   *LPGETVERSIONOUTPARAMS;

typedef   struct   _IDEREGS   {
    BYTE   bFeaturesReg;     //Used for   specifying   SMART   "commands".
    BYTE   bSectorCountReg;   //IDE   sector   count   register
    BYTE   bSectorNumberReg;   //IDE   sector   number   register
    BYTE   bCylLowReg;       //   IDE   low   order   cylinder   value    
    BYTE   bCylHighReg;     //   IDE   high   order   cylinder   value    
    BYTE   bDriveHeadReg;     //   IDE   drive/head   register    
    BYTE   bCommandReg;     //   Actual   IDE   command.    
    BYTE   bReserved;       //   reserved   for   future   use.     Must   be   zero.    
}   IDEREGS,   *PIDEREGS,   *LPIDEREGS;

typedef   struct   _SENDCMDINPARAMS   {    
    DWORD   cBufferSize;     //   Buffer   size   in   bytes    
    IDEREGS   irDriveRegs;     //   Structure   with   drive   register   values.    
    BYTE   bDriveNumber;     //   Physical   drive   number   to   send    
 //   command   to   (0,1,2,3).    
    BYTE   bReserved[3];     //   Reserved   for   future   expansion.    
    DWORD   dwReserved[4];     //   For   future   use.    
    //BYTE     bBuffer[1];       //   Input   buffer.    
}   SENDCMDINPARAMS,   *PSENDCMDINPARAMS,   *LPSENDCMDINPARAMS;

typedef   struct   _DRIVERSTATUS   {    
    BYTE   bDriverError;     //   Error   code   from   driver,    
 //   or   0   if   no   error.    
    BYTE   bIDEStatus;       //   Contents   of   IDE   Error   register.    
 //   Only   valid   when   bDriverError    
 //   is   SMART_IDE_ERROR.    
    BYTE   bReserved[2];     //   Reserved   for   future   expansion.    
    DWORD   dwReserved[2];     //   Reserved   for   future   expansion.    
}   DRIVERSTATUS,   *PDRIVERSTATUS,   *LPDRIVERSTATUS;

typedef   struct   _SENDCMDOUTPARAMS   {    
    DWORD         cBufferSize;     //   Size   of   bBuffer   in   bytes    
    DRIVERSTATUS   DriverStatus;     //   Driver   status   structure.    
    BYTE       bBuffer[512];       //   Buffer   of   arbitrary   length    
 //   in   which   to   store   the   data   read   from   the   drive.    
}   SENDCMDOUTPARAMS,   *PSENDCMDOUTPARAMS,   *LPSENDCMDOUTPARAMS;

typedef   struct   _IDSECTOR   {    
    USHORT   wGenConfig;    
    USHORT   wNumCyls;    
    USHORT   wReserved;    
    USHORT   wNumHeads;    
    USHORT   wBytesPerTrack;    
    USHORT   wBytesPerSector;    
    USHORT   wSectorsPerTrack;    
    USHORT   wVendorUnique[3];    
    CHAR   sSerialNumber[20];    
    USHORT   wBufferType;    
    USHORT   wBufferSize;    
    USHORT   wECCSize;    
    CHAR   sFirmwareRev[8];    
    CHAR   sModelNumber[40];    
    USHORT   wMoreVendorUnique;    
    USHORT   wDoubleWordIO;    
    USHORT   wCapabilities;    
    USHORT   wReserved1;    
    USHORT   wPIOTiming;    
    USHORT   wDMATiming;    
    USHORT   wBS;    
    USHORT   wNumCurrentCyls;    
    USHORT   wNumCurrentHeads;    
    USHORT   wNumCurrentSectorsPerTrack;    
    ULONG   ulCurrentSectorCapacity;    
    USHORT   wMultSectorStuff;    
    ULONG   ulTotalAddressableSectors;    
    USHORT   wSingleWordDMA;    
    USHORT   wMultiWordDMA;    
    BYTE   bReserved[128];    
}   IDSECTOR,   *PIDSECTOR;
typedef struct _SRB_IO_CONTROL
{
 ULONG HeaderLength;
 UCHAR Signature[8];
 ULONG Timeout;
 ULONG ControlCode;
 ULONG ReturnCode;
 ULONG Length;
} SRB_IO_CONTROL, *PSRB_IO_CONTROL;
/*+++    
Global   vars    
---*/    
GETVERSIONOUTPARAMS   vers;    
SENDCMDINPARAMS   in;    
SENDCMDOUTPARAMS   out;    
HANDLE   h;    
DWORD   i;
BYTE   j;
char HardDiskNO[200];

VOID   ChangeByteOrder(PCHAR   szString,   USHORT   uscStrSize)
{
 USHORT   i;
 CHAR   temp;   
 
 for   (i   =   0;   i   <   uscStrSize;   i+=2)
 {
  temp   =   szString[i];
  szString[i]   =   szString[i+1];
  szString[i+1]   =   temp;
 }
}

PCHAR DeleteHeadSpace(PCHAR TheString) //删除获取序列号开头的空格,便于其他调用
{
 int j=0;
 for(int i=0;i<strlen(TheString);i++)
 {
  if(!isspace(TheString[i])) break;
  j++;
 }
 
 return &TheString[j];
}

void   HD_IDE_9X()
{    
 ZeroMemory(&vers,sizeof(vers));
 
 h=CreateFile("\\\\.\\Smartvsd",0,0,0,CREATE_NEW,0,0);
 if   (!h)
 {
  exit(0);
 }
 
 if   (!DeviceIoControl(h,DFP_GET_VERSION,0,0,&vers,sizeof(vers),&i,0))
 {
  CloseHandle(h);
  return;
 }
 
 if   (!(vers.fCapabilities&1))
 {    
  CloseHandle(h);    
  return;    
 }
 
 for   (j=0;j<4;j++)
 {
  PIDSECTOR   phdinfo;
  char   s[41];
       
  ZeroMemory(&in,sizeof(in));    
  ZeroMemory(&out,sizeof(out));    
  if   (j&1)
  {    
   in.irDriveRegs.bDriveHeadReg=0xb0;    
  }
  else
  {
   in.irDriveRegs.bDriveHeadReg=0xa0;    
  }    
  if   (vers.fCapabilities&(16>>j))
  {    
   continue;
  }
  else
  {    
   in.irDriveRegs.bCommandReg=0xec;    
  }    
  in.bDriveNumber=j;    
  in.irDriveRegs.bSectorCountReg=1;    
  in.irDriveRegs.bSectorNumberReg=1;
  in.cBufferSize=512;    
  if   (!DeviceIoControl(h,DFP_RECEIVE_DRIVE_DATA,&in,sizeof(in),&out,sizeof(out),&i,0))
  {    
   CloseHandle(h);    
   return;    
  }
  phdinfo=(PIDSECTOR)out.bBuffer;    
  
  memcpy(s,phdinfo->sSerialNumber,sizeof(phdinfo->sSerialNumber));
  s[sizeof(phdinfo->sSerialNumber)]=0;
  ChangeByteOrder(s,sizeof(phdinfo->sSerialNumber)); 
  cout<<"\tSN:"<<DeleteHeadSpace(s)<<endl;
  
  strcpy(HardDiskNO, DeleteHeadSpace(s)); 
 }    
 
 CloseHandle(h);
}

bool HD_IDE_NT()
{
 cout<<"**********************************************************"<<endl;
 cout<<"IDE测试"<<endl;
 bool IDEFlag=false;
 char hd[80];
 PIDSECTOR   phdinfo;
 char s[61];
 
 ZeroMemory(&vers,sizeof(vers)); 
 
 
 for (j = 0; j < 4; j++)
 {
  sprintf(hd,"\\\\.\\PhysicalDrive%d",j);
  h = CreateFile(hd,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
  //  Windows NT/2000/XP下创建文件需要管理员权限
  if (!h) continue;
  if (!DeviceIoControl(h,DFP_GET_VERSION,0,0,&vers,sizeof(vers),&i,0))
   // 得到驱动器的IO控制器版本
  {
   CloseHandle(h);
   continue;
  }
  
  if (!(vers.fCapabilities&1)){
   CloseHandle(h);
   return false;
  }
  
  
  ZeroMemory(&in,sizeof(in));
  ZeroMemory(&out,sizeof(out));
  
  if (j&1){
   in.irDriveRegs.bDriveHeadReg=0xb0;
  }
  else
  {
   in.irDriveRegs.bDriveHeadReg=0xa0;
  }
  if (vers.fCapabilities&(16>>j))    continue;
  else
  {
   in.irDriveRegs.bCommandReg=0xec;
  }
  in.bDriveNumber=j;
  in.irDriveRegs.bSectorCountReg=1;
  in.irDriveRegs.bSectorNumberReg=1;
  in.cBufferSize=512;
  
  if (!DeviceIoControl(h,DFP_RECEIVE_DRIVE_DATA,&in,sizeof(in),&out,sizeof(out),&i,0))
  {
   CloseHandle(h);
   return IDEFlag;
  }
  
  phdinfo=(PIDSECTOR)out.bBuffer;
  
  memcpy(s,phdinfo->sModelNumber,sizeof(phdinfo->sModelNumber));    
  s[sizeof(phdinfo->sModelNumber)]=0;
  ChangeByteOrder(s,sizeof(phdinfo->sModelNumber));
  cout<<endl<<"硬盘名称:"<<s<<endl; 
  
  memcpy(s,phdinfo->sSerialNumber,sizeof(phdinfo->sSerialNumber));
  s[sizeof(phdinfo->sSerialNumber)]=0;
  ChangeByteOrder(s,sizeof(phdinfo->sSerialNumber)); 
  cout<<"硬盘序列号:"<<DeleteHeadSpace(s)<<endl;
  
  strcpy(HardDiskNO, DeleteHeadSpace(s)); 
  IDEFlag=true;
  CloseHandle(h);
 }
 
 return  IDEFlag; 
}

bool HD_SCSI_NT()
{
 cout<<"**********************************************************"<<endl;
 cout<<"SCSI测试"<<endl;
 bool SCSIFlag=false;
 
 for (int controller=0;controller<16;controller++)
 {
  HANDLE hScsiDriveIOCTL = 0;
  char  driveName [256];
  char s[256];
  
  sprintf (driveName, "\\\\.\\Scsi%d:", controller);
  
  //  Windows NT/2000/XP下任何权限都可以进行
  hScsiDriveIOCTL = CreateFile (driveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, 0, NULL);
  
  if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)
  {
   int drive = 0;
   DWORD dummy;
   
   for (drive = 0; drive < 2; drive++)
   {
    char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];
    SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;
    SENDCMDINPARAMS *pin =(SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));          
    
    memset (buffer, 0, sizeof (buffer));
    p -> HeaderLength = sizeof (SRB_IO_CONTROL);
    p -> Timeout = 10000;
    p -> Length = SENDIDLENGTH;
    p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
    strncpy ((char *) p -> Signature, "SCSIDISK", 8); 
    pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
    pin -> bDriveNumber = drive;
    // 得到SCSI硬盘信息
    
    if (DeviceIoControl (hScsiDriveIOCTL,
     IOCTL_SCSI_MINIPORT, 
     buffer,
     sizeof (SRB_IO_CONTROL) + sizeof (SENDCMDINPARAMS) - 1,
     buffer,
     sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,
     &dummy, NULL))
    {
     SENDCMDOUTPARAMS *pOut =(SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
     IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);
     
     if(pId->sModelNumber[0])
     { 
      memcpy(s,pId->sModelNumber,sizeof(pId->sModelNumber));    
      s[sizeof(pId->sModelNumber)]=0;
      ChangeByteOrder(s,sizeof(pId->sModelNumber));
      cout<<endl<<"硬盘名称:"<<s<<endl; 
      
      ChangeByteOrder(s,sizeof( pId->sSerialNumber)); 
      cout<<"\tSN:"<<DeleteHeadSpace( pId->sSerialNumber)<<endl;
      strcpy(HardDiskNO, DeleteHeadSpace(s)); 
      SCSIFlag=true;  // 读取成功  
     }     
    }
   }
   CloseHandle (hScsiDriveIOCTL);  // 关闭句柄
  } 
 } 
 return SCSIFlag;  
}

extern "C" {
    char * _export _stdcall GetHardDiskNO();
}

char * _stdcall GetHardDiskNO()
{
    OSVERSIONINFO   VersionInfo;
 
    ZeroMemory(&VersionInfo,sizeof(VersionInfo));
    VersionInfo.dwOSVersionInfoSize=sizeof(VersionInfo);
    GetVersionEx(&VersionInfo);
 
    memset(HardDiskNO, 0, 200);
 
    switch (VersionInfo.dwPlatformId)
    {
 case VER_PLATFORM_WIN32s:
  break;
 case VER_PLATFORM_WIN32_WINDOWS:
  HD_IDE_9X();
  break;
 case VER_PLATFORM_WIN32_NT: //这里没有做处理,便于测试
  HD_IDE_NT();
  HD_SCSI_NT();
  
  break;
    }
 
    return HardDiskNO;
}

调用方法:

GetHardDiskNO();

获取硬盘序列号(VC)相关推荐

  1. 用C#获取硬盘序列号,CPU序列号,网卡MAC地址

    这个问题首先得考虑的就是你的硬盘是不是SCSI硬盘 如果是,那么根本不存在"物理序列号",只可能取得卷标的序列号 如果是卷标序列号,要注意的是每次格式化硬盘的时候这个序列号都会变 ...

  2. VC6获取硬盘序列号、型号、修订版本号

    因为要做个读取硬盘参数信息的控件,所以在网上找了不少代码,但是自己作为一个初学者在使用别人代码时,总会发现有各种各样的问题: 1. 需要的头文件未写明 2. 有些定义未给出 3. 代码的开发环境未明, ...

  3. 使用java获取硬盘序列号

    使用java获取硬盘序列号 使用java获取硬盘的序列号呢,涉及了跨平台的问题,不同的操作系统的查看命令不一样,可以使用oshi获取. oshi(Native Operating System and ...

  4. MFC 获取硬盘序列号、IP地址、MAC地址

    1)获取本地硬盘序列号 调出cmd 输入wmic diskdrive get serialnumber 或 wmic diskdrive get Name, Manufacturer, Model, ...

  5. VC 之获取硬盘序列号

    硬盘物理序列号是硬盘的出厂序列号,它是全球都是唯一的,不会随着系统的安装.硬盘的格式化等操作而改变,跟mac地址一样都具有唯一性. 1,第一步:创建设备对象,得到设备句柄,设备为硬盘. { CStri ...

  6. 转另一个获取硬盘序列号的方法

    原谅转自:http://blog.sina.com.cn/s/blog_57dff12f0100d5so.html #define  DFP_GET_VERSION                   ...

  7. java获取硬盘序列号_Win7 64+Python3.7获取计算机硬盘信息初探

    一.需求 由于最近负责电脑资产清查的工作,有100多台分散的电脑需要获得用户名.MAC地址.硬盘序列号.硬盘品牌 一般方法: (1)查看系统用户名 (2) 获取MAC地址 windos命令行使用ipc ...

  8. 获取硬盘序列号的真正方法!!

    最近要获取磁盘的序列号,在网上找了很久发现大部分都是通过diskpart来查询 这种查询方法只是查询的磁盘的id 真正查询磁盘序列号应该使用下面方法:wmic diskdrive get serial ...

  9. .NET获取硬盘序列号的几个方法

    最近作软件注册,收集了很多.NET相关的获取硬盘物理序列号的方法,主要分为使用WMI方式和API方式.但这些方法均可能有问题. 1,使用WMI方式,有的机器根本取不到硬盘序列号,有的方式在Vista下 ...

  10. 获取硬盘序列号、CPU序列号

    public class SerialUtils {private static Properties props = System.getProperties();private static St ...

最新文章

  1. struts2相对路径解释
  2. 八数码问题II-bfs和map标记
  3. 自动驾驶公司 | 纵目科技完成D轮1.9亿美元融资
  4. java 网页正文抽取算法_GitHub - hfut-dmic/ContentExtractor: 自动抽取网页正文的算法,用JAVA实现...
  5. Web开发HTTP中URI和URL的情感纠葛
  6. 在java语言中下列语句正确的是_java考试习题及答案
  7. 三级联动下拉列表的开发过程与范例
  8. WPS插件开发流程(1)
  9. MFC-利用内存映射文件来读写文件
  10. Openvino 模型文件部署推理
  11. 物联网NB-IoT之电信物联网开放平台对接流程浅析
  12. array python lambda_Python 06 lambda函数
  13. 实战技法 - 短线操盘 (3)
  14. nacos-server1.4.1linux和windows版本下载
  15. 关于Mysql出现1045错误的方法
  16. Win10C盘满了怎么清理?如何清理电脑C盘?
  17. 文件重命名的快捷键是什么F2
  18. DVWA学习之XSS(跨站脚本攻击)(超级详细)
  19. 汇编语言小设计——抢答器
  20. 新华书店也网售 要与当当、卓越“三足鼎立”?

热门文章

  1. 有必要考国二mysql_国二证有用吗
  2. 以mysql为例的数据字典_建立数据字典
  3. 公司用的非标普通自动化用单片机还是plc_合格电气自动化工程师必备十大技能...
  4. 树莓派学习2-连接蓝牙音箱进行语音播放
  5. Linux面试题总结(一)
  6. 关于keeplive
  7. 哪些思维方式是你刻意训练过的?
  8. 计算机应用程序错误怎么办 6,WinXP电脑应用程序错误怎么办?
  9. 智慧环卫系统建设方案(智能垃圾分类收运管理)
  10. JDBC 常用的类和接口--一学就会(欢迎转载)