C++ 获得硬盘序列号

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. /**************************************/
  5. // web:itbaby.jss.cn
  6. // 作者:javasuki(itbaby)
  7. // 日期:2003/03/04
  8. /**************************************/
  9. //用于WinNT/Win2000,对Win9X无效
  10. //通过MS的S.M.A.R.T.接口,直接从RING3调用
  11. //API DeviceIoControl()来获取硬盘信息
  12. typedef struct _SRB_IO_CONTROL {
  13.     ULONG HeaderLength;
  14.     char Signature[8];
  15.     ULONG Timeout;
  16.     ULONG ControlCode;
  17.     ULONG ReturnCode;
  18.     ULONG Length;
  19. } SRB_IO_CONTROL;
  20. typedef struct _DRIVERSTATUS {
  21.     BYTE bDriverError; // Error code from driver,or 0 if no error.
  22.     BYTE bIDEStatus; // Contents of IDE Error register.
  23.     // Only valid when bDriverError
  24.     // is SMART_IDE_ERROR.
  25.     BYTE bReserved[2]; // Reserved for future expansion.
  26.     DWORD dwReserved[2]; // Reserved for future expansion.
  27. } DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;
  28. typedef struct _IDEREGS {
  29.     BYTE bFeaturesReg;
  30.     BYTE bSectorCountReg;
  31.     BYTE bSectorNumberReg;
  32.     BYTE bCylLowReg;
  33.     BYTE bCylHighReg;
  34.     BYTE bDriveHeadReg;
  35.     BYTE bCommandReg;
  36.     BYTE bReserved;
  37. } IDEREGS;
  38. typedef struct _SENDCMDINPARAMS {
  39.     DWORD cBufferSize;
  40.     IDEREGS irDriveRegs;
  41.     BYTE bDriveNumber;
  42.     BYTE bReserved[3];
  43.     DWORD dwReserved[4];
  44.     BYTE bBuffer[1];
  45. } SENDCMDINPARAMS;
  46. typedef struct _SENDCMDOUTPARAMS {
  47.     DWORD cBufferSize;
  48.     DRIVERSTATUS DriverStatus;
  49.     BYTE bBuffer[1];
  50. } SENDCMDOUTPARAMS;
  51. typedef struct _IDSECTOR {
  52.     USHORT wGenConfig;
  53.     USHORT wNumCyls;
  54.     USHORT wReserved;
  55.     USHORT wNumHeads;
  56.     USHORT wBytesPerTrack;
  57.     USHORT wBytesPerSector;
  58.     USHORT wSectorsPerTrack;
  59.     USHORT wVendorUnique[3];
  60.     CHAR sSerialNumber[20];
  61.     USHORT wBufferType;
  62.     USHORT wBufferSize;
  63.     USHORT wECCSize;
  64.     CHAR sFirmwareRev[8];
  65.     CHAR sModelNumber[40];
  66.     USHORT wMoreVendorUnique;
  67.     USHORT wDoubleWordIO;
  68.     USHORT wCapabilities;
  69.     USHORT wReserved1;
  70.     USHORT wPIOTiming;
  71.     USHORT wDMATiming;
  72.     USHORT wBS;
  73.     USHORT wNumCurrentCyls;
  74.     USHORT wNumCurrentHeads;
  75.     USHORT wNumCurrentSectorsPerTrack;
  76.     ULONG ulCurrentSectorCapacity;
  77.     USHORT wMultSectorStuff;
  78.     ULONG ulTotalAddressableSectors;
  79.     USHORT wSingleWordDMA;
  80.     USHORT wMultiWordDMA;
  81.     BYTE bReserved[128];
  82. } IDSECTOR;
  83. #define IDE_ATAPI_IDENTIFY 0xA1
  84. #define IDE_ATA_IDENTIFY 0xEC
  85. #define IDENTIFY_BUFFER_SIZE 512
  86. #define DFP_RECEIVE_DRIVE_DATA 0x0007c088
  87. #define IOCTL_SCSI_MINIPORT 0x0004d008
  88. #define IOCTL_SCSI_MINIPORT_IDENTIFY 0x001b0501
  89. #define DATA_SIZE (sizeof(SENDCMDINPARAMS)-1+IDENTIFY_BUFFER_SIZE)
  90. #define BUFFER_SIZE (sizeof(SRB_IO_CONTROL)+DATA_SIZE)
  91. #define W9X_BUFFER_SIZE (IDENTIFY_BUFFER_SIZE+16)
  92. #define SENDIDLENGTH (sizeof(SENDCMDOUTPARAMS)+IDENTIFY_BUFFER_SIZE)
  93. #define PRINTING_TO_CONSOLE_ALLOWED
  94. static char HardDriveSerialNumber [1024];
  95. //-----------------------------------------------------------------
  96. char *ConvertToString (DWORD diskdata [256], int firstIndex, int lastIndex)
  97. {
  98.     static char string [1024];
  99.     int index = 0;
  100.     int position = 0;
  101.     for (index = firstIndex; index <= lastIndex; index++){
  102.         string [position] = (char) (diskdata [index] / 256);
  103.         position++;
  104.         string [position] = (char) (diskdata [index] % 256);
  105.         position++;
  106.     }
  107.     string [position] = '/0';
  108.     for (index = position - 1; index > 0 && ' ' == string [index]; index--)
  109.         string [index] = '/0';
  110.     return string;
  111. }
  112. //-----------------------------------------------------------------
  113. void PrintIdeInfo (int drive, DWORD diskdata [256])
  114. {
  115.     strcpy (HardDriveSerialNumber, ConvertToString (diskdata, 10, 19));
  116. #ifdef PRINTING_TO_CONSOLE_ALLOWED
  117.     switch (drive / 2) {
  118.     case 0: //printf ("/nPrimary Controller - ");
  119.         break;
  120.     case 1: //printf ("/nSecondary Controller - ");
  121.         break;
  122.     case 2: //printf ("/nTertiary Controller - ");
  123.         break;
  124.     case 3: //printf ("/nQuaternary Controller - ");
  125.         break;
  126.     }
  127.     switch (drive % 2)    {
  128.     case 0: //printf ("Master drive/n/n");
  129.         break;
  130.     case 1: //printf ("Slave drive/n/n");
  131.         break;
  132.     }
  133.     //输出硬盘信息
  134.     printf ("Drive Model Number: %s/n", ConvertToString (diskdata, 27, 46));
  135.     printf ("Drive Serial Number: %s/n", ConvertToString (diskdata, 10, 19));
  136.     printf ("Drive Controller Revision Number__: %s/n", ConvertToString (diskdata, 23, 26));
  137.     printf ("Controller Buffer Size on Drive___: %u bytes/n", diskdata [21] * 512);
  138.     printf ("Drive Type________________________: ");
  139.     if (diskdata [0] & 0x0080)
  140.         printf ("Removable/n");
  141.     else if (diskdata [0] & 0x0040)
  142.         printf ("Fixed/n");
  143.     else printf ("Unknown/n");
  144.     printf ("Physical Geometry: "
  145.         "%u Cylinders %u Heads %u Sectors per track/n",
  146.         diskdata [1], diskdata [3], diskdata [6]);
  147. #else // PRINTING_TO_CONSOLE_ALLOWED
  148. #endif // PRINTING_TO_CONSOLE_ALLOWED
  149. }
  150. //-----------------------------------------------------------------
  151. int ReadIdeDriveAsScsiDriveInNT (void)
  152. {
  153.     int done = FALSE;
  154.     int controller = 0;
  155.     for (controller = 0; controller < 2; controller++)    {
  156.         HANDLE hScsiDriveIOCTL = 0;
  157.         char driveName [256];
  158.         sprintf (driveName, ".//Scsi%d:", controller);
  159.         hScsiDriveIOCTL = CreateFile (driveName,
  160.             GENERIC_READ | GENERIC_WRITE,
  161.             FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  162.             OPEN_EXISTING, 0, NULL);
  163.         // if (hScsiDriveIOCTL == INVALID_HANDLE_VALUE)
  164.         // printf ("Unable to open SCSI controller %d, error code: 0x%lX/n",
  165.         // controller, GetLastError ());
  166.         if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE){
  167.             int drive = 0;
  168.             for (drive = 0; drive < 2; drive++)    {
  169.                 char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];
  170.                 SRB_IO_CONTROL *p = (SRB_IO_CONTROL *)buffer;
  171.                 SENDCMDINPARAMS *pin =(SENDCMDINPARAMS *)(buffer + sizeof (SRB_IO_CONTROL));
  172.                 DWORD dummy;
  173.                 memset (buffer, 0, sizeof (buffer));
  174.                 p -> HeaderLength = sizeof (SRB_IO_CONTROL);
  175.                 p -> Timeout = 10000;
  176.                 p -> Length = SENDIDLENGTH;
  177.                 p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
  178.                 strncpy ((char *) p -> Signature, "SCSIDISK", 8);
  179.                 pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
  180.                 pin -> bDriveNumber = drive;
  181.                 if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,
  182.                     buffer,
  183.                     sizeof (SRB_IO_CONTROL) +
  184.                     sizeof (SENDCMDINPARAMS) - 1,
  185.                     buffer,
  186.                     sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,
  187.                     &dummy, NULL))    {
  188.                         SENDCMDOUTPARAMS *pOut =(SENDCMDOUTPARAMS *)(buffer + sizeof (SRB_IO_CONTROL));
  189.                         IDSECTOR *pId = (IDSECTOR *)(pOut -> bBuffer);
  190.                         if (pId -> sModelNumber [0])    {
  191.                             DWORD diskdata [256];
  192.                             int ijk = 0;
  193.                             USHORT *pIdSector = (USHORT *) pId;
  194.                             for (ijk = 0; ijk < 256; ijk++)
  195.                                 diskdata [ijk] = pIdSector [ijk];
  196.                             PrintIdeInfo (controller * 2 + drive, diskdata);
  197.                             done = TRUE;
  198.                         }
  199.                 }
  200.             }
  201.             CloseHandle (hScsiDriveIOCTL);
  202.         }
  203.     }
  204.     return done;
  205. }
  206. //-----------------------------------------------------------------
  207. long getHardDriveComputerID ()
  208. {
  209.     int done = FALSE;
  210.     __int64 id = 0;
  211.     strcpy (HardDriveSerialNumber, "");
  212.     if ( ! done) done = ReadIdeDriveAsScsiDriveInNT ();
  213.     if (done)    {
  214.         char *p = HardDriveSerialNumber;
  215.         if ( ! strncmp (HardDriveSerialNumber, "WD-W", 4)) p += 5;
  216.         for ( ; p && *p; p++)    {
  217.             if ('-' == *p) continue;
  218.             id *= 10;
  219.             switch (*p)    {
  220.             case '0': id += 0; break;
  221.             case '1': id += 1; break;
  222.             case '2': id += 2; break;
  223.             case '3': id += 3; break;
  224.             case '4': id += 4; break;
  225.             case '5': id += 5; break;
  226.             case '6': id += 6; break;
  227.             case '7': id += 7; break;
  228.             case '8': id += 8; break;
  229.             case '9': id += 9; break;
  230.             case 'a'case 'A': id += 10; break;
  231.             case 'b'case 'B': id += 11; break;
  232.             case 'c'case 'C': id += 12; break;
  233.             case 'd'case 'D': id += 13; break;
  234.             case 'e'case 'E': id += 14; break;
  235.             case 'f'case 'F': id += 15; break;
  236.             case 'g'case 'G': id += 16; break;
  237.             case 'h'case 'H': id += 17; break;
  238.             case 'i'case 'I': id += 18; break;
  239.             case 'j'case 'J': id += 19; break;
  240.             case 'k'case 'K': id += 20; break;
  241.             case 'l'case 'L': id += 21; break;
  242.             case 'm'case 'M': id += 22; break;
  243.             case 'n'case 'N': id += 23; break;
  244.             case 'o'case 'O': id += 24; break;
  245.             case 'p'case 'P': id += 25; break;
  246.             case 'q'case 'Q': id += 26; break;
  247.             case 'r'case 'R': id += 27; break;
  248.             case 's'case 'S': id += 28; break;
  249.             case 't'case 'T': id += 29; break;
  250.             case 'u'case 'U': id += 30; break;
  251.             case 'v'case 'V': id += 31; break;
  252.             case 'w'case 'W': id += 32; break;
  253.             case 'x'case 'X': id += 33; break;
  254.             case 'y'case 'Y': id += 34; break;
  255.             case 'z'case 'Z': id += 35; break;
  256.             }
  257.         }
  258.     }
  259.     if (id > 268435455) id %= 268435456;
  260. #ifdef PRINTING_TO_CONSOLE_ALLOWED
  261.     //printf ("/nComputer ID_______________________: %d/n", id);
  262. #endif
  263.     return (long) id;
  264. }
  265. //-----------------------------------------------------------------
  266. int main (int argc, char * argv [])
  267. {
  268.     OSVERSIONINFO ver;
  269.     ver.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
  270.     GetVersionEx(&ver);
  271.     if(VER_PLATFORM_WIN32_NT==ver.dwPlatformId)
  272.         getHardDriveComputerID ();
  273.     else
  274.         printf("不能在Win9X下运行!!!/n");
  275.     return 0;
  276. }
  277. //-----------------------------------------------------------------
 
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值