diff --git a/GetHDDSerial2.cpp b/GetHDDSerial2.cpp
new file mode 100644
index 0000000..8406ea8
Binary files /dev/null and b/GetHDDSerial2.cpp differ
diff --git a/GetHDDSerial2.vcxproj b/GetHDDSerial2.vcxproj
new file mode 100644
index 0000000..50c0e68
--- /dev/null
+++ b/GetHDDSerial2.vcxproj
@@ -0,0 +1,168 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 15.0
+ {F3BD4B09-C664-4EE0-B29B-9B2E8E8320C1}
+ Win32Proj
+ GetHDDSerial2
+ 10.0.16299.0
+
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+ Application
+ true
+ v141
+ Unicode
+
+
+ Application
+ false
+ v141
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+ Use
+ Level3
+ Disabled
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Use
+ Level3
+ Disabled
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS
+ true
+ MultiThreaded
+
+
+ Console
+ true
+
+
+
+
+ Use
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Use
+ Level3
+ MaxSpeed
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS
+ true
+ MultiThreaded
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
\ No newline at end of file
diff --git a/GetHDDSerial2.vcxproj.filters b/GetHDDSerial2.vcxproj.filters
new file mode 100644
index 0000000..f3a74cb
--- /dev/null
+++ b/GetHDDSerial2.vcxproj.filters
@@ -0,0 +1,36 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/GetHDDSerial2.vcxproj.user b/GetHDDSerial2.vcxproj.user
new file mode 100644
index 0000000..6e2aec7
--- /dev/null
+++ b/GetHDDSerial2.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/HardDriveSerialNumber.h b/HardDriveSerialNumber.h
new file mode 100644
index 0000000..b97ca52
--- /dev/null
+++ b/HardDriveSerialNumber.h
@@ -0,0 +1,266 @@
+#pragma once
+#ifndef _HDD_SERIAL_INFO_H_
+#define _HDD_SERIAL_INFO_H_
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#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 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;
+
+#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 &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_
\ No newline at end of file
diff --git a/stdafx.cpp b/stdafx.cpp
index a6e9ef9..c723c7e 100644
Binary files a/stdafx.cpp and b/stdafx.cpp differ
diff --git a/stdafx.h b/stdafx.h
index b102f11..94d4ed8 100644
Binary files a/stdafx.h and b/stdafx.h differ