硬盘序列号,英文名:Hard Disk Serial Number,该号是硬盘厂家为区别产品而设置的,是唯一的。网上搜索一下,发现获取硬盘序列号的代码遍地都是,但很多是错误的。典型代表就是使用GetVolumeInformation函数获取序列号。这种方法获取的是卷的序列号,即Volume Serial Number。硬盘格式化后,这种序列号将发生变化。本文仅举例一种方法,目前并没有统一的硬盘序列号接口,像disgenius、HD Tune Pro这些软件可以准确获取到硬盘序列号,是因为其背后有大量的工程,按接口、按厂家、甚至固态有的还需要单独讨论。如果仅用命令行,有些硬盘序列号顺序是反的,有些硬盘序列号是乱码的,有的甚至重装系统就变了,有的完全错误和硬盘标签压根就不一样。

1、cmd命令行获取;

windows命令行获取命令:wmic diskdrive get serialnumber

2、c++函数底层获取

三个文件:HardDriveSerialNumer.h    HardDriveSerialNumer.cpp    main.cpp

//HardDriveSerialNumer.h

#ifndef _HDD_SERIAL_INFO_H_
#define _HDD_SERIAL_INFO_H_#include <tchar.h>
#include <string.h>
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <vector>#pragma pack(1)#define  IDENTIFY_BUFFER_SIZE  512//  IOCTL commands
#define  DFP_GET_VERSION          0x00074080
#define  DFP_SEND_DRIVE_COMMAND   0x0007c084
#define  DFP_RECEIVE_DRIVE_DATA   0x0007c088#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 SMART_GET_VERSION               CTL_CODE(IOCTL_DISK_BASE, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS)
#define SMART_SEND_DRIVE_COMMAND        CTL_CODE(IOCTL_DISK_BASE, 0x0021, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define SMART_RCV_DRIVE_DATA            CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)//  GETVERSIONOUTPARAMS contains the data returned from the
//  Get Driver Version function.
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;//  Bits returned in the fCapabilities member of GETVERSIONOUTPARAMS
#define  CAP_IDE_ID_FUNCTION             1  // ATA ID command supported
#define  CAP_IDE_ATAPI_ID                2  // ATAPI ID command supported
#define  CAP_IDE_EXECUTE_SMART_FUNCTION  4  // SMART commannds supported//  Valid values for the bCommandReg member of IDEREGS.
#define  IDE_ATAPI_IDENTIFY  0xA1  //  Returns ID sector for ATAPI.
#define  IDE_ATA_IDENTIFY    0xEC  //  Returns ID sector for ATA.// The following struct defines the interesting part of the IDENTIFY
// buffer:
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;//  Max number of drives assuming primary/secondary, master/slave topology
//  Modified to read only the master serial
#define  MAX_IDE_DRIVES  1//
// IDENTIFY data (from ATAPI driver source)
//#pragma pack(1)typedef struct _IDENTIFY_DATA {USHORT GeneralConfiguration;            // 00 00USHORT NumberOfCylinders;               // 02  1USHORT Reserved1;                       // 04  2USHORT NumberOfHeads;                   // 06  3USHORT UnformattedBytesPerTrack;        // 08  4USHORT UnformattedBytesPerSector;       // 0A  5USHORT SectorsPerTrack;                 // 0C  6USHORT VendorUnique1[3];                // 0E  7-9USHORT SerialNumber[10];                // 14  10-19USHORT BufferType;                      // 28  20USHORT BufferSectorSize;                // 2A  21USHORT NumberOfEccBytes;                // 2C  22USHORT FirmwareRevision[4];             // 2E  23-26USHORT ModelNumber[20];                 // 36  27-46UCHAR  MaximumBlockTransfer;            // 5E  47UCHAR  VendorUnique2;                   // 5FUSHORT DoubleWordIo;                    // 60  48USHORT Capabilities;                    // 62  49USHORT Reserved2;                       // 64  50UCHAR  VendorUnique3;                   // 66  51UCHAR  PioCycleTimingMode;              // 67UCHAR  VendorUnique4;                   // 68  52UCHAR  DmaCycleTimingMode;              // 69USHORT TranslationFieldsValid:1;        // 6A  53USHORT Reserved3:15;USHORT NumberOfCurrentCylinders;        // 6C  54USHORT NumberOfCurrentHeads;            // 6E  55USHORT CurrentSectorsPerTrack;          // 70  56ULONG  CurrentSectorCapacity;           // 72  57-58USHORT CurrentMultiSectorSetting;       //     59ULONG  UserAddressableSectors;          //     60-61USHORT SingleWordDMASupport : 8;        //     62USHORT SingleWordDMAActive : 8;USHORT MultiWordDMASupport : 8;         //     63USHORT MultiWordDMAActive : 8;USHORT AdvancedPIOModes : 8;            //     64USHORT Reserved4 : 8;USHORT MinimumMWXferCycleTime;          //     65USHORT RecommendedMWXferCycleTime;      //     66USHORT MinimumPIOCycleTime;             //     67USHORT MinimumPIOCycleTimeIORDY;        //     68USHORT Reserved5[2];                    //     69-70USHORT ReleaseTimeOverlapped;           //     71USHORT ReleaseTimeServiceCommand;       //     72USHORT MajorRevision;                   //     73USHORT MinorRevision;                   //     74USHORT Reserved6[50];                   //     75-126USHORT SpecialFunctionsEnabled;         //     127USHORT Reserved7[128];                  //     128-255
} IDENTIFY_DATA, *PIDENTIFY_DATA;#pragma pack()//  Required to ensure correct PhysicalDrive IOCTL structure setup
#pragma pack(4)//
// IOCTL_STORAGE_QUERY_PROPERTY
//
// Input Buffer:
//      a STORAGE_PROPERTY_QUERY structure which describes what type of query
//      is being done, what property is being queried for, and any additional
//      parameters which a particular property query requires.
//
//  Output Buffer:
//      Contains a buffer to place the results of the query into.  Since all
//      property descriptors can be cast into a STORAGE_DESCRIPTOR_HEADER,
//      the IOCTL can be called once with a small buffer then again using
//      a buffer as large as the header reports is necessary.
////
// Types of queries
////
// define some initial property id's
////
// Query structure - additional parameters for specific queries can follow
// the header
//#define IOCTL_STORAGE_QUERY_PROPERTY   CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)//
// Device property descriptor - this is really just a rehash of the inquiry
// data retrieved from a scsi device
//
// This may only be retrieved from a target device.  Sending this to the bus
// will result in an error
//#pragma pack(4)// (* Output Bbuffer for the VxD (rt_IdeDinfo record) *)
typedef struct _rt_IdeDInfo_
{BYTE IDEExists[4];BYTE DiskExists[8];WORD DisksRawInfo[8*256];
} rt_IdeDInfo, *pt_IdeDInfo;// (* IdeDinfo "data fields" *)
typedef struct _rt_DiskInfo_
{BOOL DiskExists;BOOL ATAdevice;BOOL RemovableDevice;WORD TotLogCyl;WORD TotLogHeads;WORD TotLogSPT;char SerialNumber[20];char FirmwareRevision[8];char ModelNumber[40];WORD CurLogCyl;WORD CurLogHeads;WORD CurLogSPT;
} rt_DiskInfo;#define  SENDIDLENGTH  sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_DISK_BASE, 0x0028, METHOD_BUFFERED, FILE_ANY_ACCESS)class MasterHardDiskSerial
{
public:MasterHardDiskSerial();~MasterHardDiskSerial();//int GetSerialNo(std::vector<char> &serialNumber);int GetSerialNo(char *SerialNumber);int GetErrorMessage(TCHAR* _ptszErrorMessage= NULL);
private:char* ConvertToString ( DWORD dwDiskdata [256], int iFirstIndex, int iLastIndex, char* pcBuf = NULL );BOOL DoIDENTIFY (HANDLE, PSENDCMDINPARAMS, PSENDCMDOUTPARAMS, BYTE, BYTE, PDWORD);int ReadPhysicalDriveInNTWithAdminRights (void);int    ReadPhysicalDriveInNTUsingSmart (void);int  ReadPhysicalDriveInNTWithZeroRights (void);int  ReadIdeDriveAsScsiDriveInNT (void);char* flipAndCodeBytes ( int iPos, int iFlip,const char * pcStr = NULL, char * pcBuf= NULL);void PrintIdeInfo (int iDrive, DWORD dwDiskdata [256]);long getHardDriveComputerID();
private:char m_cszHardDriveSerialNumber [1024];char m_cszHardDriveModelNumber [1024];char m_cszErrorMessage[256];BYTE byIdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
};#endif // _HDD_SERIAL_INFO_H_

//HardDriveSerialNumer.cpp

//#include "pch.h" //vs控制台项目自动生成
#include "HardDriveSerialNumer.h"
#include <iostream>int MasterHardDiskSerial::ReadPhysicalDriveInNTWithAdminRights (void)
{int iDone = FALSE;int iDrive = 0;for (iDrive = 0; iDrive < MAX_IDE_DRIVES; iDrive++){HANDLE hPhysicalDriveIOCTL = 0;//  Try to get a handle to PhysicalDrive IOCTL, report failure//  and exit if can't.char cszDriveName [256];sprintf_s(cszDriveName, 256, "\\\\.\\PhysicalDrive%d", iDrive);//  Windows NT, Windows 2000, must have admin rightshPhysicalDriveIOCTL = CreateFileA (cszDriveName,GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE , NULL,OPEN_EXISTING, 0, NULL);if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE){SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));sprintf_s(m_cszErrorMessage,256,"%d ReadPhysicalDriveInNTWithAdminRights ERROR ,CreateFileA(%s) returned INVALID_HANDLE_VALUE",__LINE__, cszDriveName);}else{GETVERSIONOUTPARAMS VersionParams;DWORD               dwBytesReturned = 0;// Get the version, etc of PhysicalDrive IOCTLmemset ((void*) &VersionParams, 0, sizeof(VersionParams));if ( ! DeviceIoControl (hPhysicalDriveIOCTL, DFP_GET_VERSION,NULL, 0,&VersionParams,sizeof(VersionParams),&dwBytesReturned, NULL) ){         DWORD dwErr = GetLastError ();SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));sprintf_s(m_cszErrorMessage,256,"%d ReadPhysicalDriveInNTWithAdminRights ERROR DeviceIoControl() %d, DFP_GET_VERSION) returned 0, error is %d\n",__LINE__, (int) hPhysicalDriveIOCTL, (int) dwErr);}// If there is a IDE device at number "iI" issue commands// to the deviceif (VersionParams.bIDEDeviceMap <= 0){SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));sprintf_s(m_cszErrorMessage,256,"%d ReadPhysicalDriveInNTWithAdminRights ERROR No device found at iPosition %d (%d)",__LINE__, (int) iDrive, (int) VersionParams.bIDEDeviceMap);}else{BYTE             bIDCmd = 0;   // IDE or ATAPI IDENTIFY cmdSENDCMDINPARAMS  scip;//SENDCMDOUTPARAMS OutCmd;// Now, get the ID sector for all IDE devices in the system.// If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,// otherwise use the IDE_ATA_IDENTIFY commandbIDCmd = (VersionParams.bIDEDeviceMap >> iDrive & 0x10) ? \IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;memset (&scip, 0, sizeof(scip));memset (byIdOutCmd, 0, sizeof(byIdOutCmd));if ( DoIDENTIFY (hPhysicalDriveIOCTL, &scip, (PSENDCMDOUTPARAMS)&byIdOutCmd, (BYTE) bIDCmd,(BYTE) iDrive,&dwBytesReturned)){DWORD dwDiskData [256];int iIjk = 0;USHORT *punIdSector = (USHORT *)((PSENDCMDOUTPARAMS) byIdOutCmd) -> bBuffer;for (iIjk = 0; iIjk < 256; iIjk++)dwDiskData [iIjk] = punIdSector [iIjk];PrintIdeInfo (iDrive, dwDiskData);iDone = TRUE;}}CloseHandle (hPhysicalDriveIOCTL);}}return iDone;
}int MasterHardDiskSerial::ReadPhysicalDriveInNTUsingSmart (void)
{int iDone = FALSE;int iDrive = 0;for (iDrive = 0; iDrive < MAX_IDE_DRIVES; iDrive++){HANDLE hPhysicalDriveIOCTL = 0;//  Try to get a handle to PhysicalDrive IOCTL, report failure//  and exit if can't.char cszDriveName [256];sprintf_s(cszDriveName,256, "\\\\.\\PhysicalDrive%d", iDrive);//  Windows NT, Windows 2000, Windows Server 2003, VistahPhysicalDriveIOCTL = CreateFileA (cszDriveName,GENERIC_READ | GENERIC_WRITE, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);// if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE)//    printf ("Unable to open physical iDrive %d, error code: 0x%lX\n",//            iDrive, GetLastError ());if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE){SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));sprintf_s(m_cszErrorMessage,256,"%d ReadPhysicalDriveInNTUsingSmart ERROR, CreateFileA(%s) returned INVALID_HANDLE_VALUE Error Code %d",__LINE__, cszDriveName, GetLastError ());}else{GETVERSIONINPARAMS GetVersionParams;DWORD dwBytesReturned = 0;// Get the version, etc of PhysicalDrive IOCTLmemset ((void*) & GetVersionParams, 0, sizeof(GetVersionParams));if ( ! DeviceIoControl (hPhysicalDriveIOCTL, SMART_GET_VERSION,NULL, 0,&GetVersionParams, sizeof (GETVERSIONINPARAMS),&dwBytesReturned, NULL) ){         DWORD dwErr = GetLastError ();SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));sprintf_s(m_cszErrorMessage,256,"\n%d ReadPhysicalDriveInNTUsingSmart ERROR DeviceIoControl(%d, SMART_GET_VERSION) returned 0, error is %d",__LINE__, (int) hPhysicalDriveIOCTL, (int) dwErr);}else{// Print the SMART version// PrintVersion (& GetVersionParams);// Allocate the command cszBufferULONG CommandSize = sizeof(SENDCMDINPARAMS) + IDENTIFY_BUFFER_SIZE;PSENDCMDINPARAMS Command = (PSENDCMDINPARAMS) malloc (CommandSize);// Retrieve the IDENTIFY data// Prepare the command
#define ID_CMD          0xEC            // Returns ID sector for ATACommand -> irDriveRegs.bCommandReg = ID_CMD;DWORD BytesReturned = 0;if ( ! DeviceIoControl (hPhysicalDriveIOCTL, SMART_RCV_DRIVE_DATA, Command, sizeof(SENDCMDINPARAMS),Command, CommandSize,&BytesReturned, NULL) ){SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));sprintf_s(m_cszErrorMessage,256,"SMART_RCV_DRIVE_DATA IOCTL");// Print the error//PrintError ("SMART_RCV_DRIVE_DATA IOCTL", GetLastError());} else{// Print the IDENTIFY dataDWORD dwDiskData [256];USHORT *punIdSector = (USHORT *)(PIDENTIFY_DATA) ((PSENDCMDOUTPARAMS) Command) -> bBuffer;for (int iIjk = 0; iIjk < 256; iIjk++)dwDiskData [iIjk] = punIdSector [iIjk];PrintIdeInfo (iDrive, dwDiskData);iDone = TRUE;}// DoneCloseHandle (hPhysicalDriveIOCTL);free (Command);}}}return iDone;
}char * MasterHardDiskSerial::flipAndCodeBytes ( int iPos, int iFlip, const char * pcszStr, char * pcszBuf)
{int iI;int iJ = 0;int iK = 0;pcszBuf [0] = '\0';if (iPos <= 0)return pcszBuf;if ( ! iJ){char cP = 0;// First try to gather all characters representing hex digits only.iJ = 1;iK = 0;pcszBuf[iK] = 0;for (iI = iPos; iJ && !(pcszStr[iI] == '\0'); ++iI){char cC = tolower(pcszStr[iI]);if (isspace(cC))cC = '0';++cP;pcszBuf[iK] <<= 4;if (cC >= '0' && cC <= '9')pcszBuf[iK] |= (char) (cC - '0');else if (cC >= 'a' && cC <= 'f')pcszBuf[iK] |= (char) (cC - 'a' + 10);else{iJ = 0;break;}if (cP == 2){if ((pcszBuf[iK] != '\0') && ! isprint(pcszBuf[iK])){iJ = 0;break;}++iK;cP = 0;pcszBuf[iK] = 0;}}}if ( ! iJ){// There are non-digit characters, gather them as is.iJ = 1;iK = 0;for (iI = iPos; iJ && (pcszStr[iI] != '\0'); ++iI){char cC = pcszStr[iI];if ( ! isprint(cC)){iJ = 0;break;}pcszBuf[iK++] = cC;}}if ( ! iJ){// The characters are not there or are not printable.iK = 0;}pcszBuf[iK] = '\0';if (iFlip)// Flip adjacent charactersfor (iJ = 0; iJ < iK; iJ += 2){char t = pcszBuf[iJ];pcszBuf[iJ] = pcszBuf[iJ + 1];pcszBuf[iJ + 1] = t;}// Trim any beginning and end spaceiI = iJ = -1;for (iK = 0; (pcszBuf[iK] != '\0'); ++iK){if (! isspace(pcszBuf[iK])){if (iI < 0)iI = iK;iJ = iK;}}if ((iI >= 0) && (iJ >= 0)){for (iK = iI; (iK <= iJ) && (pcszBuf[iK] != '\0'); ++iK)pcszBuf[iK - iI] = pcszBuf[iK];pcszBuf[iK - iI] = '\0';}return pcszBuf;
}int MasterHardDiskSerial::ReadPhysicalDriveInNTWithZeroRights (void)
{int iDone = FALSE;int iDrive = 0;for (iDrive = 0; iDrive < MAX_IDE_DRIVES; iDrive++){HANDLE hPhysicalDriveIOCTL = 0;//  Try to get a handle to PhysicalDrive IOCTL, report failure//  and exit if can't.char cszDriveName [256];sprintf_s(cszDriveName,256,"\\\\.\\PhysicalDrive%d", iDrive);//  Windows NT, Windows 2000, Windows XP - admin rights not requiredhPhysicalDriveIOCTL = CreateFileA (cszDriveName, 0,FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, 0, NULL);if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE){SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));sprintf_s(m_cszErrorMessage,256,"%d ReadPhysicalDriveInNTWithZeroRights ERROR CreateFileA(%s) returned INVALID_HANDLE_VALUE",__LINE__, cszDriveName);}else{STORAGE_PROPERTY_QUERY query;DWORD dwBytesReturned = 0;char cszBuffer [10000];memset ((void *) & query, 0, sizeof (query));query.PropertyId = StorageDeviceProperty;query.QueryType = PropertyStandardQuery;memset (cszBuffer, 0, sizeof (cszBuffer));if ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,& query,sizeof (query),& cszBuffer,sizeof (cszBuffer),& dwBytesReturned, NULL) ){         STORAGE_DEVICE_DESCRIPTOR * descrip = (STORAGE_DEVICE_DESCRIPTOR *) & cszBuffer;char cszSerialNumber [1000];char cszModelNumber [1000];char cszVendorId [1000];char cszProductRevision [1000];flipAndCodeBytes ( descrip -> VendorIdOffset,0,cszBuffer, cszVendorId );flipAndCodeBytes ( descrip -> ProductIdOffset,0,cszBuffer, cszModelNumber );flipAndCodeBytes ( descrip -> ProductRevisionOffset,0,cszBuffer, cszProductRevision );flipAndCodeBytes ( descrip -> SerialNumberOffset,0,cszBuffer, cszSerialNumber );if (0 == m_cszHardDriveSerialNumber [0] &&//  serial number must be alphanumeric//  (but there can be leading spaces on IBM drives)(iswalnum (cszSerialNumber [0]) || iswalnum (cszSerialNumber [19]))){strcpy_s(m_cszHardDriveSerialNumber, 1024, cszSerialNumber);strcpy_s(m_cszHardDriveModelNumber,      1024, cszModelNumber);iDone = TRUE;}// Get the disk iDrive geometry.memset (cszBuffer, 0, sizeof(cszBuffer));if ( ! DeviceIoControl (hPhysicalDriveIOCTL,IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,NULL,0,&cszBuffer,sizeof(cszBuffer),&dwBytesReturned,NULL)){SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));sprintf_s(m_cszErrorMessage,"%s ReadPhysicalDriveInNTWithZeroRights ERROR DeviceIoControl(), IOCTL_DISK_GET_DRIVE_GEOMETRY_EX) returned 0", cszDriveName);}else{         DISK_GEOMETRY_EX* geom = (DISK_GEOMETRY_EX*) &cszBuffer;int iFixed = (geom->Geometry.MediaType == FixedMedia);__int64 i64Size = geom->DiskSize.QuadPart;}}else{DWORD dwErr = GetLastError ();SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));sprintf_s (m_cszErrorMessage,"DeviceIOControl IOCTL_STORAGE_QUERY_PROPERTY error = %d\n", dwErr);}CloseHandle (hPhysicalDriveIOCTL);}}return iDone;
}BOOL MasterHardDiskSerial::DoIDENTIFY (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,PDWORD lpcbBytesReturned)
{// Set up data structures for IDENTIFY command.pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;pSCIP -> irDriveRegs.bFeaturesReg = 0;pSCIP -> irDriveRegs.bSectorCountReg = 1;//pSCIP -> irDriveRegs.bSectorNumberReg = 1;pSCIP -> irDriveRegs.bCylLowReg = 0;pSCIP -> irDriveRegs.bCylHighReg = 0;// Compute the iDrive number.pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);// The command can either be IDE identify or ATAPI identify.pSCIP -> irDriveRegs.bCommandReg = bIDCmd;pSCIP -> bDriveNumber = bDriveNum;pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;return ( DeviceIoControl (hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA,(LPVOID) pSCIP,sizeof(SENDCMDINPARAMS) - 1,(LPVOID) pSCOP,sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,lpcbBytesReturned, NULL) );
}int MasterHardDiskSerial::ReadIdeDriveAsScsiDriveInNT (void)
{int iDone = FALSE;int iController = 0;for (iController = 0; iController < 2; iController++){HANDLE hScsiDriveIOCTL = 0;char   cszDriveName [256];//  Try to get a handle to PhysicalDrive IOCTL, report failure//  and exit if can't.sprintf_s (cszDriveName, "\\\\.\\Scsi%d:", iController);//  Windows NT, Windows 2000, any rights should dohScsiDriveIOCTL = CreateFileA (cszDriveName,GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, 0, NULL);if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE){int iDrive = 0;for (iDrive = 0; iDrive < 2; iDrive++){char cszBuffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];SRB_IO_CONTROL *cP = (SRB_IO_CONTROL *) cszBuffer;SENDCMDINPARAMS *pin =(SENDCMDINPARAMS *) (cszBuffer + sizeof (SRB_IO_CONTROL));DWORD dwDummy;memset (cszBuffer, 0, sizeof (cszBuffer));cP -> HeaderLength = sizeof (SRB_IO_CONTROL);cP -> Timeout = 10000;cP -> Length = SENDIDLENGTH;cP -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;strncpy ((char *) cP -> Signature, "SCSIDISK", 8);pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;pin -> bDriveNumber = iDrive;if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT, cszBuffer,sizeof (SRB_IO_CONTROL) +sizeof (SENDCMDINPARAMS) - 1,cszBuffer,sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,&dwDummy, NULL)){SENDCMDOUTPARAMS *pOut =(SENDCMDOUTPARAMS *) (cszBuffer + sizeof (SRB_IO_CONTROL));IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);if (pId -> sModelNumber [0]){DWORD dwDiskData [256];int iIjk = 0;USHORT *punIdSector = (USHORT *) pId;for (iIjk = 0; iIjk < 256; iIjk++)dwDiskData [iIjk] = punIdSector [iIjk];PrintIdeInfo (iController * 2 + iDrive, dwDiskData);iDone = TRUE;}}}CloseHandle (hScsiDriveIOCTL);}}return iDone;
}void MasterHardDiskSerial::PrintIdeInfo (int iDrive, DWORD dwDiskData [256])
{char cszSerialNumber [1024];char cszModelNumber [1024];char cszRevisionNumber [1024];char bufferSize [32];__int64 i64Sectors = 0;__int64 i64Byte = 0;//  copy the hard iDrive serial number to the cszBufferConvertToString (dwDiskData, 10, 19, cszSerialNumber);ConvertToString (dwDiskData, 27, 46, cszModelNumber);ConvertToString (dwDiskData, 23, 26, cszRevisionNumber);sprintf_s(bufferSize,32, "%u", dwDiskData [21] * 512);if (0 == m_cszHardDriveSerialNumber [0] &&//  serial number must be alphanumeric//  (but there can be leading spaces on IBM drives)(isalnum (cszSerialNumber [0]) || isalnum (cszSerialNumber [19]))){strcpy_s(m_cszHardDriveSerialNumber,1024, cszSerialNumber);strcpy_s(m_cszHardDriveModelNumber,1024, cszModelNumber);}}long MasterHardDiskSerial::getHardDriveComputerID ()
{int iDone = FALSE;// char string [1024];__int64 i64Id = 0;OSVERSIONINFO version;strcpy_s(m_cszHardDriveSerialNumber,1024, "");memset (&version, 0, sizeof (version));version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);GetVersionEx (&version);if (version.dwPlatformId == VER_PLATFORM_WIN32_NT){//  this works under WinNT4 or Win2K if you have admin rightsiDone = ReadPhysicalDriveInNTWithAdminRights ();//  this should work in WinNT or Win2K if previous did not work//  this is kind of a backdoor via the SCSI mini port driver into//     the IDE drivesif ( ! iDone) iDone = ReadIdeDriveAsScsiDriveInNT ();//  this works under WinNT4 or Win2K or WinXP if you have any rightsif ( ! iDone)iDone = ReadPhysicalDriveInNTWithZeroRights ();//  this works under WinNT4 or Win2K or WinXP or Windows Server 2003 or Vista if you have any rightsif ( ! iDone)iDone = ReadPhysicalDriveInNTUsingSmart ();}if (m_cszHardDriveSerialNumber [0] > 0){char *cP = m_cszHardDriveSerialNumber;//  ignore first 5 characters from western digital hard drives if//  the first four characters are WD-Wif ( ! strncmp (m_cszHardDriveSerialNumber, "WD-W", 4)) cP += 5;for ( ; cP && *cP; cP++){if ('-' == *cP) continue;i64Id *= 10;switch (*cP){case '0': i64Id += 0; break;case '1': i64Id += 1; break;case '2': i64Id += 2; break;case '3': i64Id += 3; break;case '4': i64Id += 4; break;case '5': i64Id += 5; break;case '6': i64Id += 6; break;case '7': i64Id += 7; break;case '8': i64Id += 8; break;case '9': i64Id += 9; break;case 'a': case 'A': i64Id += 10; break;case 'b': case 'B': i64Id += 11; break;case 'c': case 'C': i64Id += 12; break;case 'd': case 'D': i64Id += 13; break;case 'e': case 'E': i64Id += 14; break;case 'f': case 'F': i64Id += 15; break;case 'g': case 'G': i64Id += 16; break;case 'h': case 'H': i64Id += 17; break;case 'i': case 'I': i64Id += 18; break;case 'j': case 'J': i64Id += 19; break;case 'k': case 'K': i64Id += 20; break;case 'l': case 'L': i64Id += 21; break;case 'm': case 'M': i64Id += 22; break;case 'n': case 'N': i64Id += 23; break;case 'o': case 'O': i64Id += 24; break;case 'p': case 'P': i64Id += 25; break;case 'q': case 'Q': i64Id += 26; break;case 'r': case 'R': i64Id += 27; break;case 's': case 'S': i64Id += 28; break;case 't': case 'T': i64Id += 29; break;case 'u': case 'U': i64Id += 30; break;case 'v': case 'V': i64Id += 31; break;case 'w': case 'W': i64Id += 32; break;case 'x': case 'X': i64Id += 33; break;case 'y': case 'Y': i64Id += 34; break;case 'z': case 'Z': i64Id += 35; break;}                            }}i64Id %= 100000000;if (strstr (m_cszHardDriveModelNumber, "IBM-"))i64Id += 300000000;else if (strstr (m_cszHardDriveModelNumber, "MAXTOR") ||strstr (m_cszHardDriveModelNumber, "Maxtor"))i64Id += 400000000;else if (strstr (m_cszHardDriveModelNumber, "WDC "))i64Id += 500000000;elsei64Id += 600000000;return (long) i64Id;
}//int MasterHardDiskSerial::GetSerialNo(std::vector<char> &serialNumber)
int MasterHardDiskSerial::GetSerialNo(char *SerialNumber)
{getHardDriveComputerID();size_t numberLength = strlen(m_cszHardDriveSerialNumber);if (numberLength == 0)return -1;//serialNumber.resize(numberLength);//std::cout << "size " << serialNumber.size() << std::endl;//memcpy(&serialNumber.front(), m_cszHardDriveSerialNumber, serialNumber.size()); //m_cszHardDriveSerialNumber;memcpy(SerialNumber, m_cszHardDriveSerialNumber, numberLength);return 0;
}char *MasterHardDiskSerial::ConvertToString (DWORD dwDiskData [256],int iFirstIndex,int iLastIndex,char* pcszBuf)
{int iIndex = 0;int iPosition = 0;//  each integer has two characters stored in it backwards// Removes the spaces from the serial nofor ( iIndex = iFirstIndex; iIndex <= iLastIndex ; iIndex++ ){//  get high byte for 1st character  char ctemp = (char) (dwDiskData [iIndex] / 256);char cszmyspace[] = " ";if ( !(ctemp == *cszmyspace)){pcszBuf [iPosition++] = ctemp ;}//  get low byte for 2nd characterchar ctemp1 = (char) (dwDiskData [iIndex] % 256);if ( !(ctemp1 == *cszmyspace)){pcszBuf [iPosition++] = ctemp1 ;}}//  end the string pcszBuf[iPosition] = '\0';//  cut off the trailing blanksfor (iIndex = iPosition - 1; iIndex > 0 && isspace(pcszBuf [iIndex]); iIndex--)pcszBuf [iIndex] = '\0';return pcszBuf;
}int MasterHardDiskSerial::GetErrorMessage(TCHAR* tszErrorMessage)
{if (strlen(m_cszErrorMessage)!=0){mbstowcs((wchar_t *)tszErrorMessage,m_cszErrorMessage,sizeof(m_cszErrorMessage));return 0;}else return -1;
}MasterHardDiskSerial::MasterHardDiskSerial()
{SecureZeroMemory(m_cszErrorMessage,sizeof(m_cszErrorMessage));SecureZeroMemory(m_cszHardDriveModelNumber,sizeof(m_cszHardDriveModelNumber));SecureZeroMemory(m_cszHardDriveSerialNumber,sizeof(m_cszHardDriveSerialNumber));
}MasterHardDiskSerial::~MasterHardDiskSerial()
{
}

//main.cpp

#include "pch.h"//vs控制台项目自动加入的头文件
#include "HardDriveSerialNumer.h"
#include <iostream>
#include <string.h>
int main()
{int out = 0,i=10;MasterHardDiskSerial a;char SerialNumber[1024] = {""};std::cout << "i" << i-- << std::endl;memset(&SerialNumber,0,sizeof(SerialNumber));out = a.GetSerialNo(SerialNumber);std::cout << "SN " << SerialNumber << std::endl;
}

以上在vs控制台项目可以直接编译通过得到结果,如果报错

解决方案,项目 =》属性 =》c/c++  =》预处理器=》点击预处理器定义,编辑,加入_CRT_SECURE_NO_WARNINGS,即可。

项目 >> 属性 >> C / C++ >> 常规 >> sdl检查,选择“否”

c++ 获取硬盘序列号serialnumber相关推荐

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

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

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

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

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

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

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

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

  5. iOS9获取手机序列号serialNumber(UDID)

    iOS9获取手机序列号serialNumber(UDID) http://www.jianshu.com/p/b48524a4aff2 作者  LeonLei  关注 2016.10.26 11:44 ...

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

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

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

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

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

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

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

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

  10. 驱动下如何获取硬盘序列号

    最近公司有个项目,需要在驱动模式及用户模式下,获取硬盘的序列号,在网上找了半天,大多是用户模式的代码,而且许多已经过时,于是参照了一下,改写成内核模式下的代码,本人是驱动的菜鸟,希望此代码能对那些和我 ...

最新文章

  1. Daydream VR
  2. 【笔记】虚拟机用Xshell登陆报错“ssh服务器拒绝了密码”解决方法
  3. linux根文件系统配置,嵌入式Linux的Cramfs根文件系统配置的解决方案
  4. Fast R-CNN论文详解 - CSDN博客
  5. postscript怎么打开_怎么把在学习中用的Adobe PDF文件转换成Microsoft office Word
  6. 数据库SQL语言类型(DQL.DML.DDL.DCL)
  7. 6818 开发板 配置 ubuntu 桌面环境 与 ROS
  8. spark学习-Spark算子Transformations和Action使用大全(Action章)
  9. Docker和容器简介
  10. 智慧校园建设方案!高校统一数据中心解决方案
  11. tomcat6升级到tomcat7配置的修改
  12. 增长率用计算机怎么算,操作方法:Excel使用公式来计算增长率教程
  13. C++ 字符串的截取
  14. StackExchange.Redis Timeout performing 超时问题
  15. qt几种常见的打包安装程序工具
  16. PLSQL入门与精通(第72章:LOGOFF触发器)
  17. 小萌库- 新海诚那些唯美感人的动漫
  18. PPT怎么插入图案填充效果
  19. 同轴线传输网络摄像机信号2KM
  20. 洛谷P1331 海战 题解

热门文章

  1. 如何批量将 psd 转换为 png、jpeg、bmp、svg、webp 格式
  2. springboot+vue3+微信小程序活动报名系统源码
  3. VS编译运行时提示:应用程序并行配置不正确,无法启动程序
  4. pom文件project爆红
  5. H5基础阶段二(表格、表单)
  6. PS-elevenday-仿制图章工具组
  7. 安卓手机5个好用的思维导图软件
  8. 输入服务器名或许可证文件,vCenter 6.0 部署文档
  9. Windows 10 20H2 微软MSDN官方正式版英文ISO镜像下载
  10. 开箱:阿里技术人在读什么书?