获取硬盘序列号(VC)

 说明:经过上百台计算机测试,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();

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值