这里介绍的是获取硬盘的序列号,不是获取硬盘分区的序列号。核心是通过DeviceIoControl接口获取硬盘的版本与数据信息,很简单。
【1】h头文件
//如果编译有问题,添加#include <afxwin.h>
#if !defined(AFX_HDSERIAL_H__1F6D2512_EBA9_4443_9FEF_DE78D7A28AFB__INCLUDED_)
#define AFX_HDSERIAL_H__1F6D2512_EBA9_4443_9FEF_DE78D7A28AFB__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <iostream>
#include <windows.h>
#define DFP_GET_VERSION 0x00074080
#define DFP_SEND_DRIVE_COMMAND 0x0007c084
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088
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;
typedef struct _IDEREGS
{
BYTE bFeaturesReg; // Used for specifying SMART "commands".
BYTE bSectorCountReg; // IDE sector count register
BYTE bSectorNumberReg; // IDE sector number register
BYTE bCylLowReg; // IDE low order cylinder value
BYTE bCylHighReg; // IDE high order cylinder value
BYTE bDriveHeadReg; // IDE drive/head register
BYTE bCommandReg; // Actual IDE command.
BYTE bReserved; // reserved for future use. Must be zero.
} IDEREGS, *PIDEREGS, *LPIDEREGS;
typedef struct _SENDCMDINPARAMS
{
DWORD cBufferSize; // Buffer size in bytes
IDEREGS irDriveRegs; // Structure with drive register values.
BYTE bDriveNumber; // Physical drive number to send command to (0,1,2,3).
BYTE bReserved[3]; // Reserved for future expansion.
DWORD dwReserved[4]; // For future use.
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
typedef struct _DRIVERSTATUS
{
BYTE bDriverError; // Error code from driver,
// or 0 if no error.
BYTE bIDEStatus; // Contents of IDE Error register.
// Only valid when bDriverError
// is SMART_IDE_ERROR.
BYTE bReserved[2]; // Reserved for future expansion.
DWORD dwReserved[2]; // Reserved for future expansion.
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;
typedef struct _SENDCMDOUTPARAMS
{
DWORD cBufferSize; // Size of bBuffer in bytes
DRIVERSTATUS DriverStatus; // Driver status structure.
BYTE bBuffer[512]; // Buffer of arbitrary length
// in which to store the data read from the drive.
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
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;
//--------------------------------------------------------------
// 硬盘序列号
//--------------------------------------------------------------
BOOL GetHDSerial(char *lpszHD, int len=128);
#endif // !defined(AFX_HDSERIAL_H__1F6D2512_EBA9_4443_9FEF_DE78D7A28AFB__INCLUDED_)
【2】cpp文件
#include "stdafx.h"
#include "HDSerial.h"
void ChangeByteOrder(PCHAR szString, USHORT uscStrSize) {
USHORT i = 0;
CHAR temp= '\0';
for (i = 0; i < uscStrSize; i+=2)
{
temp = szString[i];
szString[i] = szString[i+1];
szString[i+1] = temp;
}
}
//--------------------------------------------------------------
// 硬盘序列号
//--------------------------------------------------------------
BOOL GetHDSerial(char *lpszHD, int len/*=128*/) {
BOOL bRtn = FALSE;
DWORD bytesRtn = 0;
char szhd[80] = {0};
PIDSECTOR phdinfo;
HANDLE hDrive = NULL;
GETVERSIONOUTPARAMS vers;
SENDCMDINPARAMS in;
SENDCMDOUTPARAMS out;
ZeroMemory(&vers, sizeof(vers));
ZeroMemory(&in , sizeof(in));
ZeroMemory(&out , sizeof(out));
//搜索四个物理硬盘,取第一个有数据的物理硬盘
for (int j=0; j<4; j++)
{
sprintf(szhd, "\\\\.\\PhysicalDrive%d", j);
hDrive = CreateFileA(szhd,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
0,
0);
if (NULL == hDrive)
{
continue;
}
if (!DeviceIoControl(hDrive, DFP_GET_VERSION, 0, 0, &vers, sizeof(vers), &bytesRtn,0))
{
goto FOREND;
}
//If IDE identify command not supported, fails
if (!(vers.fCapabilities&1))
{
goto FOREND;
}
//Identify the IDE drives
if (j&1)
{
in.irDriveRegs.bDriveHeadReg = 0xb0;
}
else
{
in.irDriveRegs.bDriveHeadReg = 0xa0;
}
if (vers.fCapabilities&(16>>j))
{
//We don't detect a ATAPI device.
goto FOREND;
}
else
{
in.irDriveRegs.bCommandReg = 0xec;
}
in.bDriveNumber = j;
in.irDriveRegs.bSectorCountReg = 1;
in.irDriveRegs.bSectorNumberReg = 1;
in.cBufferSize = 512;
if (!DeviceIoControl(hDrive, DFP_RECEIVE_DRIVE_DATA, &in, sizeof(in), &out, sizeof(out), &bytesRtn,0))
{
//"DeviceIoControl failed:DFP_RECEIVE_DRIVE_DATA"<<endl;
goto FOREND;
}
phdinfo=(PIDSECTOR)out.bBuffer;
char s[21] = {0};
memcpy(s, phdinfo->sSerialNumber, 20);
s[20] = 0;
ChangeByteOrder(s, 20);
//删除空格字符
int ix = 0;
for (ix=0; ix<20; ix++)
{
if (s[ix] == ' ')
{
continue;
}
break;
}
memcpy(lpszHD, s+ix, 20);
bRtn = TRUE;
break;
FOREND:
CloseHandle(hDrive);
hDrive = NULL;
}
CloseHandle(hDrive);
hDrive = NULL;
return(bRtn);
}
【3】测试
char lpszMac[128] = {0};
GetHDSerial(lpszMac);
今天的文章C++ 获取硬盘序列号分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/15471.html