Download CHardDisk.h from here
Download CHardDisk.cpp from hereExplore My Other Channel for More Cool and Valuable Insights
👉 Youtube Learn Tech Tips👉 Tiktok
👉 Facebook:Create one class name CDiskInfo, post my code to your project
Source code:
CDiskInfo.h// huuvi168@gmail.com (Zidane)
#pragma once
#include <winioctl.h>
#define DI_SET_ERROR(pError, err_code) {if (pError) *pError = err_code;}
#define COM_GETDI_SUCCESS 0
#define COM_CREATE_INSTANCE_FAILED -1
#define COM_CONNECT_SERVER_FAILED -2
#define COM_SET_PROXY_PLANET_FAILED -3
#define COM_EXE_QUERY_BOOTPARTITION_FAILED -4
#define COM_ENUMERATOR_NEXT_WIN32DP_FAILED -5
#define COM_GET_DEVICEID_DP_FAILED -6
#define COM_EXE_QUERY_JOIN_DP_DD_FAILED -7
#define COM_ENUMERATOR_NEXT_WIN32DD_FAILED -8
#define COM_GET_DEVICEID_DD_FAILED -9
#define INVALID_INFO_PC _T("000000000000000000000000000000000000000000000000")
class DiskInfo
{
public:
DiskInfo(void);
~DiskInfo(void);
static void GetHDSerialList(CStringArray &csOutList);
static CString ConvertToHex(CString csString);
static int GetIndexOfOSHardDisk();
static bool GetOSHDSerial(CString& csOsHDSerial);
static CString GetOSHDSerialByCom(int *pErr = 0);
private:
static char * flipAndCodeBytes (const char * str, int pos, int flip, char * buf);
static wchar_t *ConvertToString (DWORD diskdata [MAX_PATH], int firstIndex,
int lastIndex, wchar_t* buf);
static int ReadPhysicalDriveInNTUsingSmart (CStringArray &csSerialList);
static int ReadPhysicalDriveInNTWithZeroRights (CStringArray &csSerialList);
static int ReadIdeDriveAsScsiDriveInNT (CStringArray &csSerialList);
static int ReadPhysicalDriveInNTWithAdminRights (CStringArray &csSerialList);
static BOOL DoIDENTIFY( HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum, PDWORD lpcbBytesReturned );
static void MergeList( CStringArray &csOutList, CStringArray const &csAddList);
};
CDiskInfo.cpp
// huuvi168@gmail.com (zidane)
#include "StdAfx.h"
#include "DiskInfo.h"
#include <windows.h>
#include <winioctl.h>
#include <cstdio>
#include <comdef.h>
#include <Wbemidl.h>
#ifdef USING_VMPROTECT
#include "VMProtectSDK.h"
#endif
#pragma comment(lib, "wbemuuid.lib")
typedef struct _MEDIA_SERAL_NUMBER_DATA {
ULONG SerialNumberLength;
ULONG Result;
ULONG Reserved[2];
UCHAR SerialNumberData[1];
} MEDIA_SERIAL_NUMBER_DATA, *PMEDIA_SERIAL_NUMBER_DATA;
typedef struct _IDENTIFY_DATA {
USHORT GeneralConfiguration; // 00 00
USHORT NumberOfCylinders; // 02 1
USHORT Reserved1; // 04 2
USHORT NumberOfHeads; // 06 3
USHORT UnformattedBytesPerTrack; // 08 4
USHORT UnformattedBytesPerSector; // 0A 5
USHORT SectorsPerTrack; // 0C 6
USHORT VendorUnique1[3]; // 0E 7-9
USHORT SerialNumber[10]; // 14 10-19
USHORT BufferType; // 28 20
USHORT BufferSectorSize; // 2A 21
USHORT NumberOfEccBytes; // 2C 22
USHORT FirmwareRevision[4]; // 2E 23-26
USHORT ModelNumber[20]; // 36 27-46
UCHAR MaximumBlockTransfer; // 5E 47
UCHAR VendorUnique2; // 5F
USHORT DoubleWordIo; // 60 48
USHORT Capabilities; // 62 49
USHORT Reserved2; // 64 50
UCHAR VendorUnique3; // 66 51
UCHAR PioCycleTimingMode; // 67
UCHAR VendorUnique4; // 68 52
UCHAR DmaCycleTimingMode; // 69
USHORT TranslationFieldsValid:1; // 6A 53
USHORT Reserved3:15;
USHORT NumberOfCurrentCylinders; // 6C 54
USHORT NumberOfCurrentHeads; // 6E 55
USHORT CurrentSectorsPerTrack; // 70 56
ULONG CurrentSectorCapacity; // 72 57-58
USHORT CurrentMultiSectorSetting; // 59
ULONG UserAddressableSectors; // 60-61
USHORT SingleWordDMASupport : 8; // 62
USHORT SingleWordDMAActive : 8;
USHORT MultiWordDMASupport : 8; // 63
USHORT MultiWordDMAActive : 8;
USHORT AdvancedPIOModes : 8; // 64
USHORT Reserved4 : 8;
USHORT MinimumMWXferCycleTime; // 65
USHORT RecommendedMWXferCycleTime; // 66
USHORT MinimumPIOCycleTime; // 67
USHORT MinimumPIOCycleTimeIORDY; // 68
USHORT Reserved5[2]; // 69-70
USHORT ReleaseTimeOverlapped; // 71
USHORT ReleaseTimeServiceCommand; // 72
USHORT MajorRevision; // 73
USHORT MinorRevision; // 74
USHORT Reserved6[50]; // 75-126
USHORT SpecialFunctionsEnabled; // 127
USHORT Reserved7[128]; // 128-255
} IDENTIFY_DATA, *PIDENTIFY_DATA;
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;
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;
#define SENDIDLENGTH sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE
#define FILE_DEVICE_SCSI 0x0000001b
#define IOCTL_SCSI_MINIPORT_IDENTIFY ((FILE_DEVICE_SCSI << 16) + 0x0501)
// Valid values for the bCommandReg member of IDEREGS.
// Returns ID sector for ATAPI.
#define IDE_ATAPI_IDENTIFY 0xA1
// Returns ID sector for ATA.
#define IDE_ATA_IDENTIFY 0xEC
// see NTDDSCSI.H for definition
#define IOCTL_SCSI_MINIPORT 0x0004D008
#define MAX_IDE_DRIVES 16
#define DFP_GET_VERSION 0x00074080
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088
DiskInfo::DiskInfo(void)
{
}
DiskInfo::~DiskInfo(void)
{
}
int DiskInfo::ReadPhysicalDriveInNTWithZeroRights( CStringArray &csSerialList )
{
#ifdef USING_VMPROTECT
// VMProtectBegin("ProtectRPDInNTZR");
#endif
int done = 0;
csSerialList.RemoveAll();
char buffer [10000];
wchar_t driveName [256] = {0};
for (int drive = 0; drive < MAX_IDE_DRIVES; drive++)
{
HANDLE hPhysicalDriveIOCTL = 0;
// Try to get a handle to PhysicalDrive IOCTL, report failure
// and exit if can't.
swprintf (driveName, _T("\\\\.\\PhysicalDrive%d"), drive);
// swprintf ( driveName, 100, _T("\\\\.\\PhysicalDrive%d"),
16, drive );
// Windows NT, Windows 2000, Windows XP - admin rights not required
hPhysicalDriveIOCTL = CreateFile (driveName, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE)
continue;
STORAGE_PROPERTY_QUERY query;
DWORD cbBytesReturned = 0;
memset ((void *) & query, 0, sizeof (query));
query.PropertyId = StorageDeviceProperty;
query.QueryType = PropertyStandardQuery;
memset (buffer, 0, sizeof (buffer));
if ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
& query,
sizeof (query),
& buffer,
sizeof (buffer),
& cbBytesReturned, NULL) )
{
STORAGE_DEVICE_DESCRIPTOR * descrip =
(STORAGE_DEVICE_DESCRIPTOR *) & buffer;
CString csSerialNumber;
char szSerialNumber [512] = {0};
wchar_t wcSerialNumber [512] = {0};
flipAndCodeBytes (buffer, descrip -> SerialNumberOffset,
1, szSerialNumber );
mbstowcs_s(NULL, wcSerialNumber, sizeof(wcSerialNumber) /
sizeof(wcSerialNumber[0]), szSerialNumber,
strlen(szSerialNumber));
csSerialNumber = wcSerialNumber;
csSerialNumber.Trim();
done = true;
if (!csSerialNumber.IsEmpty() &&
csSerialNumber.CompareNoCase(INVALID_INFO_PC))
{
// Get the disk drive geometry.
memset (buffer, 0, sizeof(buffer));
if ( DeviceIoControl (hPhysicalDriveIOCTL,
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
NULL,
0,
&buffer,
sizeof(buffer),
&cbBytesReturned,
NULL))
{
DISK_GEOMETRY_EX* geom = (DISK_GEOMETRY_EX*) &buffer;
if (geom->Geometry.MediaType == FixedMedia)
{
csSerialList.Add(csSerialNumber);
}
}
}
}
CloseHandle (hPhysicalDriveIOCTL);
}
return done;
#ifdef USING_VMPROTECT
// VMProtectEnd();
#endif
}
int DiskInfo::ReadPhysicalDriveInNTUsingSmart( CStringArray &csSerialList )
{
#ifdef USING_VMPROTECT
// VMProtectBegin("ProtectRPDInNTUS");
#endif
csSerialList.RemoveAll();
int done = FALSE;
int drive = 0;
wchar_t driveName [256];
for (drive = 0; drive < MAX_IDE_DRIVES; drive++)
{
HANDLE hPhysicalDriveIOCTL = 0;
// Try to get a handle to PhysicalDrive IOCTL, report failure
// and exit if can't.
wsprintf (driveName, _T("\\\\.\\PhysicalDrive%d"), drive);
// Windows NT, Windows 2000, Windows Server 2003, Vista
hPhysicalDriveIOCTL = CreateFile (driveName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
{
GETVERSIONINPARAMS GetVersionParams;
DWORD cbBytesReturned = 0;
// Get the version, etc of PhysicalDrive IOCTL
memset ((void*) & GetVersionParams, 0, sizeof(GetVersionParams));
if ( DeviceIoControl (hPhysicalDriveIOCTL, SMART_GET_VERSION,
NULL,
0,
&GetVersionParams, sizeof (GETVERSIONINPARAMS),
&cbBytesReturned, NULL) )
{
// Print the SMART version
// PrintVersion (& GetVersionParams);
// Allocate the command buffer
ULONG CommandSize = sizeof(SENDCMDINPARAMS) + IDENTIFY_BUFFER_SIZE;
PSENDCMDINPARAMS Command = (PSENDCMDINPARAMS) malloc (CommandSize);
// Retrieve the IDENTIFY data
// Prepare the command
Command -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
DWORD BytesReturned = 0;
if ( DeviceIoControl (hPhysicalDriveIOCTL,
SMART_RCV_DRIVE_DATA, Command, sizeof(SENDCMDINPARAMS),
Command, CommandSize,
&BytesReturned, NULL) )
{
// Print the IDENTIFY data
DWORD diskdata [256];
USHORT *pIdSector = (USHORT *)
(PIDENTIFY_DATA) ((PSENDCMDOUTPARAMS) Command) -> bBuffer;
for (int ijk = 0; ijk < 256; ijk++)
diskdata [ijk] = pIdSector [ijk];
if (diskdata [0] & 0x0040)
{
wchar_t szTemp[256] = {0};
CString csTemp;
ConvertToString(diskdata, 10, 19, szTemp);
csTemp = szTemp;
csTemp.Trim();
if (!csTemp.IsEmpty() && csTemp.CompareNoCase(INVALID_INFO_PC) != 0)
{
csSerialList.Add(csTemp);
done = TRUE;
}
}
}
// Done
CloseHandle (hPhysicalDriveIOCTL);
free (Command);
}
}
}
return done;
#ifdef USING_VMPROTECT
// VMProtectEnd();
#endif
}
int DiskInfo::ReadIdeDriveAsScsiDriveInNT( CStringArray &csSerialList )
{
#ifdef USING_VMPROTECT
// VMProtectBegin("ProtectRIDASCSIDInNT");
#endif
csSerialList.RemoveAll();
int done = FALSE;
wchar_t driveName [256] = {0};
HANDLE hScsiDriveIOCTL = 0;
for (int controller = 0; controller < 16; controller++)
{
// Try to get a handle to PhysicalDrive IOCTL, report failure
// and exit if can't.
wsprintf (driveName, _T("\\\\.\\Scsi%d:"), controller);
// Windows NT, Windows 2000, any rights should do
hScsiDriveIOCTL = CreateFile (driveName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if (hScsiDriveIOCTL == INVALID_HANDLE_VALUE)
continue;
for (int 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));
DWORD dummy;
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;
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])
{
DWORD diskdata [256];
int ijk = 0;
USHORT *pIdSector = (USHORT *) pId;
for (ijk = 0; ijk < 256; ijk++)
diskdata [ijk] = pIdSector [ijk];
//PrintIdeInfo (controller * 2 + drive, diskdata);
if (diskdata [0] & 0x0040)
{
wchar_t szTemp[256] = {0};
CString csTemp;
ConvertToString(diskdata, 10, 19, szTemp);
csTemp = szTemp;
csTemp.Trim();
if (!csTemp.IsEmpty() && csTemp.CompareNoCase(INVALID_INFO_PC) != 0)
{
csSerialList.Add(csTemp);
done = TRUE;
}
}
}
}
}
CloseHandle (hScsiDriveIOCTL);
}
return done;
#ifdef USING_VMPROTECT
// VMProtectEnd();
#endif
}
int DiskInfo::ReadPhysicalDriveInNTWithAdminRights( CStringArray &csSerialList )
{
#ifdef USING_VMPROTECT
// VMProtectBegin("ProtectRPDInNTWAR");
#endif
csSerialList.RemoveAll();
wchar_t driveName [256] = {0};
GETVERSIONOUTPARAMS VersionParams;
int done = FALSE;
BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
for (int drive = 0; drive < MAX_IDE_DRIVES; drive++)
{
HANDLE hPhysicalDriveIOCTL = 0;
// Try to get a handle to PhysicalDrive IOCTL, report failure
// and exit if can't.
wsprintf (driveName, _T("\\\\.\\PhysicalDrive%d"), drive);
// Windows NT, Windows 2000, must have admin rights
hPhysicalDriveIOCTL = CreateFile (driveName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE , NULL,
OPEN_EXISTING, 0, NULL);
if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE)
continue;
DWORD cbBytesReturned = 0;
// Get the version, etc of PhysicalDrive IOCTL
memset ((void*) &VersionParams, 0, sizeof(VersionParams));
if (DeviceIoControl (hPhysicalDriveIOCTL, DFP_GET_VERSION,
NULL,
0,
&VersionParams,
sizeof(VersionParams),
&cbBytesReturned, NULL))
{
if (VersionParams.bIDEDeviceMap > 0)
{
BYTE bIDCmd = 0; // IDE or ATAPI IDENTIFY cmd
SENDCMDINPARAMS 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 command
bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10)
? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
memset (&scip, 0, sizeof(scip));
memset (IdOutCmd, 0, sizeof(IdOutCmd));
if ( DoIDENTIFY (hPhysicalDriveIOCTL,
&scip,
(PSENDCMDOUTPARAMS)&IdOutCmd,
(BYTE) bIDCmd,
(BYTE) drive,
&cbBytesReturned))
{
DWORD diskdata [256] = {0};
int ijk = 0;
USHORT *pIdSector = (USHORT *)
((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;
for (ijk = 0; ijk < 256; ijk++)
diskdata [ijk] = pIdSector [ijk];
if (diskdata [0] & 0x0040)
{
wchar_t szTemp[256] = {0};
CString csTemp;
ConvertToString(diskdata, 10, 19, szTemp);
csTemp = szTemp;
csTemp.Trim();
if (!csTemp.IsEmpty() && csTemp.CompareNoCase(INVALID_INFO_PC) != 0)
{
csSerialList.Add(csTemp);
done = TRUE;
}
}
}
}
}
CloseHandle (hPhysicalDriveIOCTL);
}
return done;
#ifdef USING_VMPROTECT
// VMProtectEnd();
#endif
}
BOOL DiskInfo::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 drive 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 DiskInfo::GetIndexOfOSHardDisk()
{
int nDiskOS = 0;
HANDLE m_hOSPartition = 0;
wchar_t szSysDir[MAX_PATH] = {0};
GetSystemDirectory(szSysDir, MAX_PATH);
CString csPartitionOS;
csPartitionOS.Format(_T("\\\\.\\%s"), CString(szSysDir).Left(2));
m_hOSPartition = CreateFile (csPartitionOS, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if (m_hOSPartition != INVALID_HANDLE_VALUE)
{
//char buffer [10000];
VOLUME_DISK_EXTENTS buffer;
DWORD cbBytesReturned = 0;
if ( DeviceIoControl (m_hOSPartition, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
NULL,
0,
&buffer,
sizeof (buffer),
& cbBytesReturned, NULL) )
{
nDiskOS = buffer.Extents->DiskNumber;
}
}
CloseHandle(m_hOSPartition);
return nDiskOS;
}
bool DiskInfo::GetOSHDSerial(CString& csOsHDSerial)
{
#ifdef USING_VMPROTECT
// VMProtectBegin("GetOSHDSerial");
#endif
int err = 0;
//Get HD Serial by Com
csOsHDSerial = GetOSHDSerialByCom(&err);
if (!csOsHDSerial.IsEmpty())
return true;
wchar_t szErr[256] = {0};
wsprintf(szErr, L"Get MCByCom failed %d", err);
//CHelper::WriteLog(szErr);
CStringArray csSerialList;
GetHDSerialList(csSerialList);
if (csSerialList.GetCount() <= 0)
return false;
int nOsDiskIndex = GetIndexOfOSHardDisk();
if (nOsDiskIndex < 0 || nOsDiskIndex >= csSerialList.GetCount())
return false;
csOsHDSerial = csSerialList.GetAt(nOsDiskIndex);
csSerialList.RemoveAll();
return true;
#ifdef USING_VMPROTECT
// VMProtectEnd();
#endif
}
wchar_t *DiskInfo::ConvertToString( DWORD diskdata [MAX_PATH],
int firstIndex, int lastIndex, wchar_t* buf )
{
int index = 0;
int position = 0;
// each integer has two characters stored in it backwards
for (index = firstIndex; index <= lastIndex; index++)
{
// get high byte for 1st character
buf [position++] = (wchar_t) (diskdata [index] / 256);
// get low byte for 2nd character
buf [position++] = (wchar_t) (diskdata [index] % 256);
}
// end the string
buf[position] = '\0';
// cut off the trailing blanks
for (index = position - 1; index > 0 && isspace(buf [index]); index--)
buf [index] = '\0';
return buf;
}
char* DiskInfo::flipAndCodeBytes (const char * str, int pos, int flip, char * buf)
{
int i;
int j = 0;
int k = 0;
buf [0] = '\0';
if (pos <= 0)
return buf;
if ( ! j)
{
char p = 0;
// First try to gather all characters representing hex digits only.
j = 1;
k = 0;
buf[k] = 0;
for (i = pos; j && str[i] != '\0'; ++i)
{
char c = tolower(str[i]);
if (isspace(c))
c = '0';
++p;
buf[k] <<= 4;
if (c >= '0' && c <= '9')
buf[k] |= (unsigned char) (c - '0');
else if (c >= 'a' && c <= 'f')
buf[k] |= (unsigned char) (c - 'a' + 10);
else
{
j = 0;
break;
}
if (p == 2)
{
if (buf[k] != '\0' && ! isprint(buf[k]))
{
j = 0;
break;
}
++k;
p = 0;
buf[k] = 0;
}
}
}
if ( ! j)
{
// There are non-digit characters, gather them as is.
j = 1;
k = 0;
for (i = pos; j && str[i] != '\0'; ++i)
{
char c = str[i];
if ( ! isprint(c))
{
j = 0;
break;
}
buf[k++] = c;
}
}
if ( ! j)
{
// The characters are not there or are not printable.
k = 0;
}
buf[k] = '\0';
if (flip)
// Flip adjacent characters
for (j = 0; j < k; j += 2)
{
char t = buf[j];
buf[j] = buf[j + 1];
buf[j + 1] = t;
}
// Trim any beginning and end space
i = j = -1;
for (k = 0; buf[k] != '\0'; ++k)
{
if (! isspace(buf[k]))
{
if (i < 0)
i = k;
j = k;
}
}
if ((i >= 0) && (j >= 0))
{
for (k = i; (k <= j) && (buf[k] != '\0'); ++k)
buf[k - i] = buf[k];
buf[k - i] = '\0';
}
return buf;
}
void DiskInfo::MergeList( CStringArray &csOutList,
CStringArray const &csAddList)
{
CString csTmp;
bool bExist;
for (int i = 0; i < csAddList.GetCount(); i++)
{
csTmp = csAddList.GetAt(i);
bExist = false;
for (int j = 0; j < csOutList.GetCount(); j++)
{
if (csOutList.GetAt(j).CompareNoCase(csTmp) == 0)
{
bExist = true;
break;
}
}
if (!bExist)
csOutList.Add(csTmp);
}
}
void DiskInfo::GetHDSerialList(CStringArray &csHDSerialList)
{
CStringArray csTmpList;
csHDSerialList.RemoveAll();
ReadPhysicalDriveInNTWithAdminRights(csTmpList);
MergeList(csHDSerialList, csTmpList);
ReadPhysicalDriveInNTUsingSmart(csTmpList);
MergeList(csHDSerialList, csTmpList);
ReadPhysicalDriveInNTWithZeroRights(csTmpList);
MergeList(csHDSerialList, csTmpList);
ReadIdeDriveAsScsiDriveInNT(csTmpList);
MergeList(csHDSerialList, csTmpList);
}
CString DiskInfo::ConvertToHex(CString csString)
{
CString csOutHex;
for(register int i = 0; i < csString.GetLength(); i++)
{
csOutHex.AppendFormat(_T("%02x"), csString[i]);
}
return csOutHex;
}
CString DiskInfo::GetOSHDSerialByCom(int *pError)
{
#ifdef USING_VMPROTECT
// VMProtectBegin("GetOSHDSerialByCom");
#endif
HRESULT hr = CoInitialize(NULL);
HRESULT hres;
CString strRetId = _T("");
DI_SET_ERROR(pError, COM_GETDI_SUCCESS);
IWbemLocator *pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hres))
{
DI_SET_ERROR(pError, COM_CREATE_INSTANCE_FAILED);
CoUninitialize();
return strRetId; // Program has failed.
}
// Step 4: -----------------------------------------------------
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServices *pSvc = NULL;
// Connect to the root\cimv2 namespace with
// the current user and obtain pointer pSvc
// to make IWbemServices calls.
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
NULL, // Security flags.
0, // Authority (e.g. Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);
if (FAILED(hres))
{
DI_SET_ERROR(pError, COM_CONNECT_SERVER_FAILED);
pLoc->Release();
CoUninitialize();
return strRetId;
// Program has failed.
}
// Step 5: --------------------------------------------------
// Set security levels on the proxy -------------------------
hres = CoSetProxyBlanket(
pSvc, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
if (FAILED(hres))
{
DI_SET_ERROR(pError, COM_SET_PROXY_PLANET_FAILED);
pSvc->Release();
pLoc->Release();
CoUninitialize();
return strRetId;
// Program has failed.
}
IEnumWbemClassObject* pEnumerator = NULL;
IEnumWbemClassObject* pEnumerator1 = NULL;
IEnumWbemClassObject* pEnumerator2 = NULL;
IWbemClassObject *pclsObj = NULL;
IWbemClassObject *pclsObj1 = NULL;
IWbemClassObject *pclsObj2 = NULL;
ULONG uReturn = 0;
wchar_t wmihddsn[256] = {0};
hres = pSvc->ExecQuery(
bstr_t(_T("WQL")),
bstr_t(_T("SELECT * FROM Win32_DiskPartition WHERE BootPartition=True")),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
if (!SUCCEEDED(hres) || !pEnumerator)
{
DI_SET_ERROR(pError, COM_EXE_QUERY_BOOTPARTITION_FAILED);
if (pEnumerator)
pEnumerator->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
return strRetId;
}
// get the first Win32_DiskPartition
hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (!SUCCEEDED(hr) || 0 == uReturn)
{
DI_SET_ERROR(pError, COM_ENUMERATOR_NEXT_WIN32DP_FAILED);
if (pclsObj)
pclsObj->Release();
pEnumerator->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
return strRetId;
}
VARIANT vtProp;
wchar_t tmp[1024];
wchar_t query[1024];
tmp[0] = '\0';
query[0] = '\0';
// Get the value of the partition's DeviceID property
hr = pclsObj->Get(_T("DeviceID"), 0, &vtProp, 0, 0);
if (!SUCCEEDED(hr))
{
DI_SET_ERROR(pError, COM_GET_DEVICEID_DP_FAILED);
pclsObj->Release();
pEnumerator->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
return strRetId;
}
if(vtProp.vt == VT_BSTR)
{
wcscpy(tmp, vtProp.bstrVal);
}
VariantClear(&vtProp);
// "join" Win32_DiskPartition to Win32_DiskDrive
wsprintf(query, _T("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='%s'}
WHERE ResultClass=Win32_DiskDrive"), tmp);
hres = pSvc->ExecQuery(
bstr_t(_T("WQL")),
bstr_t(query),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator1);
if(!SUCCEEDED(hres) || !pEnumerator1)
{
DI_SET_ERROR(pError, COM_EXE_QUERY_JOIN_DP_DD_FAILED);
if (pEnumerator1)
pEnumerator1->Release();
pclsObj->Release();
pEnumerator->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
return strRetId;
}
// get the first Win32_DiskDrive
hr = pEnumerator1->Next(WBEM_INFINITE, 1, &pclsObj1, &uReturn);
if(!SUCCEEDED(hr) || 0 == uReturn)
{
DI_SET_ERROR(pError, COM_ENUMERATOR_NEXT_WIN32DD_FAILED);
if (pclsObj1)
pclsObj1->Release();
pEnumerator1->Release();
pclsObj->Release();
pEnumerator->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
return strRetId;
}
// Get the value of the disk-drive's DeviceID
hr = pclsObj1->Get(_T("DeviceID"), 0, &vtProp, 0, 0);
if(!SUCCEEDED(hr))
{
DI_SET_ERROR(pError, COM_GET_DEVICEID_DD_FAILED);
pclsObj1->Release();
pEnumerator1->Release();
pclsObj->Release();
pEnumerator->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
return strRetId;
}
if(vtProp.vt == VT_BSTR)
{
wcscpy(tmp, vtProp.bstrVal);
}
VariantClear(&vtProp);
// "join" Win32_DiskDrive to Win32_PhysicalMedia
wsprintf(query, _T("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='%s'}
WHERE ResultClass=Win32_PhysicalMedia"), tmp);
hres = pSvc->ExecQuery(
bstr_t(_T("WQL")),
bstr_t(query),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator2);
hr = WBEM_S_NO_ERROR;
while (hr == WBEM_S_NO_ERROR && pEnumerator2)
{
// get the first Win32_PhysicalMedia
pclsObj2 = NULL;
hr = pEnumerator2->Next(WBEM_INFINITE, 1, &pclsObj2, &uReturn);
if(!SUCCEEDED(hr) || 0 == uReturn || !pclsObj2)
{
if(pclsObj2)
pclsObj2->Release();
continue;
}
// get the PhysicalMedia's SerialNumber
hr = pclsObj2->Get(_T("SerialNumber"), 0, &vtProp, 0, 0);
if(!SUCCEEDED(hr))
{
pclsObj2->Release();
continue;
}
if(vtProp.vt == VT_BSTR && vtProp.bstrVal)
{
wcscpy(wmihddsn, vtProp.bstrVal);
strRetId = wmihddsn;
}
VariantClear(&vtProp);
pclsObj2->Release();
if (strRetId.GetLength() > 0)
{
strRetId.Trim();
if (!strRetId.IsEmpty() && strRetId.CompareNoCase(INVALID_INFO_PC) != 0)
break;
else
strRetId.Empty();
}
}
if(pEnumerator2)
pEnumerator2->Release();
pclsObj1->Release();
pEnumerator1->Release();
pclsObj->Release();
pEnumerator->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
return strRetId; // Program successfully completed.
#ifdef USING_VMPROTECT
// VMProtectEnd();
#endif
}
How to use
CString csOSHDSerial;
DiskInfo::GetOSHDSerial(csOSHDSerial);
AfxMessageBox(csOSHDSerial);
Download CHardDisk.h from here
Download CHardDisk.cpp from here
If you have any feedback on How to get Hard Disk serial key using C++. please leave your comment, we can discuss about it
Thank you for reading this post. I hope you found it helpful and easy to follow. If you have any feedback or questions about
How to "get Hard Disk serial key using C++"
,
please share them in the comments below. I would love to hear from you and discuss this topic further
✋✋✋✋
Webzone Tech Tips
- I am Zidane, See you next time soon ✋✋✋✋