hd获取硬盘序列号_[原创]两种获取硬盘序列号的方法.

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];

BYTE    bReserved2[512];

} IDSECTOR, * PIDSECTOR;

//这里我把SENDCMDOUTPARAMS跟IDSECTOR直接合并来了,这样的操作方便传入输参

typedef struct _HARDDISKINFO

{

//SENDCMDOUTPARAMS

DWORD                   cBufferSize;            // Size of bBuffer in bytes

DRIVERSTATUS            DriverStatus;           // Driver status structure.

IDSECTOR    info;

}HARDDISKINFO ,*PHARDDISKINFO;

string get_HardDiskSerialNumber_1(int harddiskindex)//硬盘序列号索引,第一个硬盘=0,第二个硬盘=1

{

char objName[50] = {0};

wsprintfA(objName, "\\\\.\\PhysicalDrive%d", harddiskindex);

HANDLE hDevice = ::CreateFileA(objName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);

if (hDevice == INVALID_HANDLE_VALUE)return "-1";

SENDCMDINPARAMS scip;//输入

ZeroMemory(&scip, sizeof(SENDCMDINPARAMS));

scip.cBufferSize = IDENTIFY_BUFFER_SIZE;

scip.irDriveRegs.bSectorCountReg = 1;

scip.irDriveRegs.bSectorNumberReg = 1;

scip.irDriveRegs.bDriveHeadReg = 0xA0;

scip.irDriveRegs.bCommandReg = 0xEC;

HARDDISKINFO hdinfo = {0};//输出,把SENDCMDOUTPARAMS ,IDSECTOR直接合并成一个结构了

DWORD dwBytesReturned = 0;

if (!DeviceIoControl(hDevice, SMART_RCV_DRIVE_DATA, &scip, sizeof(SENDCMDINPARAMS),&hdinfo, sizeof(HARDDISKINFO), &dwBytesReturned, NULL))

{

::CloseHandle(hDevice);

return "-2";

}

ConvertSerialString(hdinfo.info.sSerialNumber, sizeof(hdinfo.info.sSerialNumber));//转换格式

::CloseHandle(hDevice);

return string(hdinfo.info.sSerialNumber);

}

方法二, 0x2D1400

网上找到不资料,根据硬盘分区工具DiskGenius.exe逆出来的,其中的结构体我也不懂是啥,随便构造了一个

代码如下:

typedef struct _HARDDISKINFO2

{

ULONG  of_name1;//名称1偏移

ULONG  unknown1[3];//未知数据

ULONG  of_name2;//名称2偏移

ULONG  of_FirmwareRev;  //  固件版本偏移

ULONG  of_SerialNumber; // 序列号偏移

ULONG  unknown2;//未知数据

char   outdata[520];//硬盘数据

PCHAR  get_FirmwareRev()

{

if (of_FirmwareRev 

{

return (PCHAR)this + of_FirmwareRev;

}

return "";

}

PCHAR  get_name1()

{

if (((PCHAR)this)[of_name1] == 0)

return (PCHAR)this + of_name1+8;

else

return (PCHAR)this + of_name1;

return NULL;

}

PCHAR  get_name2()

{

if (of_name2 

{

return (PCHAR)this + of_name2;

}

return "";

}

PCHAR  get_SerialNumber()

{

if (of_SerialNumber 

{

return (PCHAR)this + of_SerialNumber;

}

return "";

}

}HARDDISKINFO2, * PHARDDISKINFO2;

string get_HardDiskSerialNumber_2(int harddiskindex)

{

char objName[50] = { 0 };

wsprintfA(objName, "\\\\.\\PhysicalDrive%d", harddiskindex);

HANDLE hDevice = ::CreateFileA(objName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);

if (hDevice == INVALID_HANDLE_VALUE)return "-1";

char inputdata[] = { 0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x80,  0x03,  0x00,  0x00 };//不知道这个是什么结构,格式就这样

HARDDISKINFO2 hdinfo = {0};

DWORD dwBytesReturned = 0;

if (!DeviceIoControl(hDevice, 0x2D1400, inputdata, sizeof(inputdata), &hdinfo, sizeof(HARDDISKINFO2), &dwBytesReturned , NULL))

{

::CloseHandle(hDevice);

return "-2";

}

::CloseHandle(hDevice);

return string(hdinfo.get_SerialNumber());

}

方法一获取的硬盘数据多一些,但是硬盘型号名称获取有时候不太对,而且序列号,名字这些字符要转换,转换方式我这么写:

VOID DiskSerialConvert(PCHAR DiskSerial, PCHAR newDiskSerial)

{

int len = strlen(DiskSerial);

int i = 0;

if (len > 20)

{

len = 20;

}

if (len % 2 == 1)

{

len = len + 1;

}

for (i = 0; i 

{

if (i % 2 == 0)

{

newDiskSerial[i] = DiskSerial[i + 1];

}

else

{

newDiskSerial[i] = DiskSerial[i - 1];

}

}

}

void ConvertSerialString(PCHAR str,int len)

{

char* strTemp = new char[len];

DiskSerialConvert(str, strTemp);

RtlCopyMemory(str, strTemp, len);

delete[] strTemp;

}

如果只是要序列号跟名称,还是方法二好用一点,名称获取完整.

调用过程已经运行结果:

还有什么奇葩读取硬盘ID的方法,发出来学习呗!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值