#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 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_