硬盘爱好者 发表于 2012-4-20 08:50:17

C++获取硬盘序列号

#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

//#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; //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;   //   Reserved   for   future   expansion.   
    DWORD   dwReserved;   //   For   future   use.   
    //BYTE   bBuffer;       //   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;   //   Reserved   for   future   expansion.   
    DWORD   dwReserved;   //   Reserved   for   future   expansion.   
}   DRIVERSTATUS,   *PDRIVERSTATUS,   *LPDRIVERSTATUS;   
   
typedef   struct   _SENDCMDOUTPARAMS   {   
    DWORD         cBufferSize;   //   Size   of   bBuffer   in   bytes   
    DRIVERSTATUS   DriverStatus;   //   Driver   status   structure.   
    BYTE       bBuffer;       //   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;   
    CHAR   sSerialNumber;   
    USHORT   wBufferType;   
    USHORT   wBufferSize;   
    USHORT   wECCSize;   
    CHAR   sFirmwareRev;   
    CHAR   sModelNumber;   
    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;   
}   IDSECTOR,   *PIDSECTOR;
   
/*+++   
Global   vars   
---*/   
GETVERSIONOUTPARAMS   vers;   
SENDCMDINPARAMS   in;   
SENDCMDOUTPARAMS   out;   
HANDLE   h;   
DWORD   i;
BYTE   j;
char HardDiskNO;

VOID   ChangeByteOrder(PCHAR   szString,   USHORT   uscStrSize)
{
USHORT   i;
CHAR   temp;   

for   (i   =   0;   i   <   uscStrSize;   i+=2)
{
    temp   =   szString;
    szString   =   szString;
    szString   =   temp;
}
}
   
void   DetectIDE(BYTE bIDEDeviceMap){
if   (bIDEDeviceMap&1){
    if   (bIDEDeviceMap&16){
      //cout<<"ATAPI   device   is   attached   to   primary   controller,   drive   0."<<endl;
    }else{
      //cout<<"IDE   device   is   attached   to   primary   controller,   drive   0."<<endl;
    }
}   
if   (bIDEDeviceMap&2){   
    if   (bIDEDeviceMap&32){   
      //cout<<"ATAPI   device   is   attached   to   primary   controller,   drive   1."<<endl;
    }else{
      //cout<<"IDE   device   is   attached   to   primary   controller,   drive   1."<<endl;
    }   
}   
if   (bIDEDeviceMap&4){   
    if   (bIDEDeviceMap&64){
      //cout<<"ATAPI   device   is   attached   to   secondary   controller,   drive   0."<<endl;
    }else{   
      //cout<<"IDE   device   is   attached   to   secondary   controller,   drive   0."<<endl;
    }   
}   
if   (bIDEDeviceMap&8){
    if   (bIDEDeviceMap&128){   
      //cout<<"ATAPI   device   is   attached   to   secondary   controller,   drive   1."<<endl;
    }else{   
      //cout<<"IDE   device   is   attached   to   secondary   controller,   drive   1."<<endl;
    }
}   
}   
   
void   hdid9x(){   
ZeroMemory(&vers,sizeof(vers));
//We   start   in   95/98/Me
h=CreateFile("\\\\.\\Smartvsd",0,0,0,CREATE_NEW,0,0);
if   (!h){
    //cout<<"open   smartvsd.vxd   failed"<<endl;
    exit(0);
}

if   (!DeviceIoControl(h,DFP_GET_VERSION,0,0,&vers,sizeof(vers),&i,0)){
    //cout<<"DeviceIoControl   failed:DFP_GET_VERSION"<<endl;
    CloseHandle(h);
    return;
}
//If   IDE   identify   command   not   supported,   fails   
if   (!(vers.fCapabilities&1)){   
    //cout<<"Error:   IDE   identify   command   not   supported.";
    CloseHandle(h);   
    return;   
}
//Display   IDE   drive   number   detected
DetectIDE(vers.bIDEDeviceMap);
//Identify   the   IDE   drives
for   (j=0;j<4;j++){
    PIDSECTOR   phdinfo;
    char   s;
      
    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)){   
      //We   don't   detect   a   ATAPI   device.   
      //cout<<"Drive   "<<(int)(j+1)<<"   is   a   ATAPI   device,   we   don't   detect   it"<<endl;
      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)){   
      //cout<<"DeviceIoControl   failed:DFP_RECEIVE_DRIVE_DATA"<<endl;
      CloseHandle(h);   
      return;   
    }
    phdinfo=(PIDSECTOR)out.bBuffer;   
    memcpy(s,phdinfo->sModelNumber,40);   
    s=0;   
    ChangeByteOrder(s,40);   
    //cout<<endl<<"Module   Number:"<<s<<endl;
    memcpy(s,phdinfo->sFirmwareRev,8);
    s=0;   
    ChangeByteOrder(s,8);   
    //cout<<"\tFirmware   rev:"<<s<<endl;
    memcpy(s,phdinfo->sSerialNumber,20);   
    s=0;   
    ChangeByteOrder(s,20);
    strcpy(HardDiskNO, s);
    //cout<<"\tSerial   Number:"<<s<<endl;
    //cout<<"\tCapacity:"<<phdinfo->ulTotalAddressableSectors/2/1024<<"M"<<endl<<endl;
}   
   
//Close   handle   before   quit
CloseHandle(h);
}

void hdidnt(){
char hd;
PIDSECTOR   phdinfo;
char s;

ZeroMemory(&vers,sizeof(vers));
//We   start   in   NT/Win2000
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);
    if (!h) continue;
    if (!DeviceIoControl(h,DFP_GET_VERSION,0,0,&vers,sizeof(vers),&i,0))
    {
      CloseHandle(h);
      continue;
    }
    //If   IDE   identify   command   not   supported,   fails
    if (!(vers.fCapabilities&1)){
      CloseHandle(h);
      return;
    }

    //Identify   the   IDE   drives
    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)) {
      //We   don't   detect   a   ATAPI   device.
      //cout<<"Drive "<<(int)(j+1)<<" is a ATAPI device, we don't detect it"<<endl;
      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)){
      //cout<<"DeviceIoControl   failed:DFP_RECEIVE_DRIVE_DATA"<<endl;
      CloseHandle(h);
      return;
    }
    phdinfo=(PIDSECTOR)out.bBuffer;
    memcpy(s,phdinfo->sModelNumber,40);   
    s=0;
    ChangeByteOrder(s,40);
    //cout<<endl<<"Module   Number:"<<s<<endl;
    memcpy(s,phdinfo->sFirmwareRev,8);   
    s=0;
    ChangeByteOrder(s,8);

    //cout<<"\tFirmware   rev:"<<s<<endl;
    memcpy(&s,phdinfo->sSerialNumber,20);
    s=0;
    ChangeByteOrder(&s,20);
    //cout<<"\tSerial   Number:"<<s<<endl;
    sprintf(s, "硬盘 %d 的序列号是:%s", j + 1, &s);
    strcpy(&HardDiskNO, s);
    //cout<<"\tCapacity:"<<phdinfo->ulTotalAddressableSectors/2/1024<<"M"<<endl<<endl;
    CloseHandle(h);
}
}

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:
          hdid9x();
          break;
      case VER_PLATFORM_WIN32_NT:
          hdidnt();
          break;
    }

    return HardDiskNO;
}

ikkyphoenix 发表于 2013-7-9 17:48:11

支持一下!多谢分享!

onflypuma 发表于 2013-11-27 18:13:39

支持LZ,谢谢分享!
页: [1]
查看完整版本: C++获取硬盘序列号