You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
258 lines
8.0 KiB
C++
258 lines
8.0 KiB
C++
#ifndef _HDD_SERIAL_INFO_H_
|
|
#define _HDD_SERIAL_INFO_H_
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <tchar.h>
|
|
#include <vector>
|
|
#include <windows.h>
|
|
#include <winioctl.h>
|
|
|
|
#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<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_
|