#include <Iphlpapi.h>
#pragma comment(lib,"Iphlpapi")
//#pragma warning( disable : 4996 )
#define DFP_GET_VERSION 0x00074080
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088
#define IDE_ATAPI_IDENTIFY 0xA1
#define IDE_ATA_IDENTIFY 0xEC
#define IDENTIFY_BUFFER_SIZE 512
typedef struct _GETVERSIONOUTPARAMS
{
BYTE bVersion;
BYTE bRevision;
BYTE bReserved;
BYTE bIDEDeviceMap;
DWORD fCapabilities;
DWORD dwReserved[4];
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
typedef struct _IDEREGS
{
BYTE bFeaturesReg;
BYTE bSectorCountReg;
BYTE bSectorNumberReg;
BYTE bCylLowReg;
BYTE bCylHighReg;
BYTE bDriveHeadReg;
BYTE bCommandReg;
BYTE bReserved;
} IDEREGS, *PIDEREGS, *LPIDEREGS;
typedef struct _SENDCMDINPARAMS
{
DWORD cBufferSize;
IDEREGS irDriveRegs;
BYTE bDriveNumber;
BYTE bReserved[3];
DWORD dwReserved[4];
BYTE bBuffer[1];
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
typedef struct _DRIVERSTATUS
{
BYTE bDriverError;
BYTE bIDEStatus;
BYTE bReserved[2];
DWORD dwReserved[2];
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;
typedef struct _SENDCMDOUTPARAMS
{
DWORD cBufferSize;
DRIVERSTATUS DriverStatus;
BYTE bBuffer[1];
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
std::string GetDiskPhysicalSerialNumber()
{
std::string sResult = _T("");
BYTE IdOutCmd[530];
HANDLE drive = CreateFile(_T("\\\\.\\PhysicalDrive0"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
if ( drive == INVALID_HANDLE_VALUE )
return sResult;
GETVERSIONOUTPARAMS VersionParams;
DWORD cbBytesReturned = 0;
memset( ( void* ) &VersionParams, 0, sizeof( VersionParams ) );
if ( ! DeviceIoControl( drive, DFP_GET_VERSION, NULL, 0, &VersionParams, sizeof( VersionParams ), &cbBytesReturned, NULL ) )
return sResult;
if (VersionParams.bIDEDeviceMap<=0)
return sResult;
BYTE bIDCmd = 0;
SENDCMDINPARAMS scip;
bIDCmd = ( VersionParams.bIDEDeviceMap >> 0 & 0x10 ) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
memset( &scip, 0, sizeof( scip) );
memset( IdOutCmd, 0, sizeof( IdOutCmd ) );
scip.cBufferSize = IDENTIFY_BUFFER_SIZE;
scip.irDriveRegs.bFeaturesReg = 0;
scip.irDriveRegs.bSectorCountReg = 1;
scip.irDriveRegs.bSectorNumberReg = 1;
scip.irDriveRegs.bCylLowReg = 0;
scip.irDriveRegs.bCylHighReg = 0;
scip.irDriveRegs.bDriveHeadReg= 0xA0 | ( ( ( BYTE ) drive & 1 ) << 4 );
scip.irDriveRegs.bCommandReg = bIDCmd;
scip.bDriveNumber = ( BYTE ) drive;
scip.cBufferSize = IDENTIFY_BUFFER_SIZE;
if ( ! DeviceIoControl( drive, DFP_RECEIVE_DRIVE_DATA, &scip, sizeof( SENDCMDINPARAMS)- 1, ( LPVOID )&IdOutCmd, sizeof( SENDCMDOUTPARAMS ) + IDENTIFY_BUFFER_SIZE - 1, &cbBytesReturned, NULL ) )
return sResult;
USHORT *pIdSector = ( USHORT * )( ( PSENDCMDOUTPARAMS )IdOutCmd )->bBuffer;
int nPosition = 0;
char pchDiskPhysicalSN[15] = { 0 };
for( int nIndex = 13; nIndex < 20; nIndex++ )
{
pchDiskPhysicalSN[ nPosition++ ]=( unsigned char )( pIdSector[ nIndex ] / 256 );
pchDiskPhysicalSN[ nPosition++ ]=( unsigned char )( pIdSector[ nIndex ] % 256 );
}
sResult = std::string(pchDiskPhysicalSN);
sResult.erase(0,sResult.find_first_not_of(" "));
sResult.erase(sResult.find_last_not_of(" ") + 1);
return sResult;
}