如何获取硬盘出厂序号?也就是全球唯一识别码(物理码)

gansininiang 2010-06-12 02:57:38
如何编程实现?
...全文
1094 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
jackyjkchen 2010-06-22
  • 打赏
  • 举报
回复
用wmi吧,可以直接调用命令行
gansininiang 2010-06-22
  • 打赏
  • 举报
回复
感谢gz_qmc
我测试下您的代码。。。
一根烂笔头 2010-06-13
  • 打赏
  • 举报
回复
看不懂
gz_qmc 2010-06-13
  • 打赏
  • 举报
回复
DOS下的C程序很简单
WINDOW下屏蔽了很多中断 端口等操作
所以要先问清楚
这是WINDOW下的代码,自己看吧
int  GetDiskInfo(int driver=0);
char szModelNumber[64];
char szSerialNumber[64];


const WORD IDE_ATAPI_IDENTIFY = 0xA1; // 读取ATAPI设备的命令
const WORD IDE_ATA_IDENTIFY = 0xEC; // 读取ATA设备的命令

#define _WIN32_WINNT 0x0400
#include "winioctl.h"

BOOL __fastcall DoIdentify( HANDLE hPhysicalDriveIOCTL,
PSENDCMDINPARAMS pSCIP,
PSENDCMDOUTPARAMS pSCOP,
BYTE btIDCmd,
BYTE btDriveNum,
PDWORD pdwBytesReturned)
{
pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
pSCIP->irDriveRegs.bFeaturesReg = 0;
pSCIP->irDriveRegs.bSectorCountReg = 1;
pSCIP->irDriveRegs.bSectorNumberReg = 1;
pSCIP->irDriveRegs.bCylLowReg = 0;
pSCIP->irDriveRegs.bCylHighReg = 0;

pSCIP->irDriveRegs.bDriveHeadReg = (btDriveNum & 1) ? 0xB0 : 0xA0;
pSCIP->irDriveRegs.bCommandReg = btIDCmd;
pSCIP->bDriveNumber = btDriveNum;
pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;

return DeviceIoControl( hPhysicalDriveIOCTL,
SMART_RCV_DRIVE_DATA,
(LPVOID)pSCIP,
sizeof(SENDCMDINPARAMS) - 1,
(LPVOID)pSCOP,
sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
pdwBytesReturned, NULL);
}

char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex)
{
static char szResBuf[1024];
char ss[256];
int nIndex = 0;
int nPosition = 0;

for(nIndex = nFirstIndex; nIndex <= nLastIndex; nIndex++)
{
ss[nPosition] = (char)(dwDiskData[nIndex] / 256);
nPosition++;

// Get low BYTE for 2nd character
ss[nPosition] = (char)(dwDiskData[nIndex] % 256);
nPosition++;
}

// End the string
ss[nPosition] = '\0';

int i, index=0;
for(i=0; i<nPosition; i++)
{
if(ss[i]==0 || ss[i]==32) continue;
szResBuf[index]=ss[i];
index++;
}
szResBuf[index]=0;

return szResBuf;
}

int GetDiskInfo(int driver)
{
CString sFilePath;
sFilePath.Format("\\\\.\\PHYSICALDRIVE%d", driver);

HANDLE hFile = INVALID_HANDLE_VALUE;
hFile = ::CreateFile(sFilePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
0, NULL);
if (hFile == INVALID_HANDLE_VALUE) return -1;

DWORD dwBytesReturned;
GETVERSIONINPARAMS gvopVersionParams;
DeviceIoControl(hFile,
SMART_GET_VERSION,
NULL,
0,
&gvopVersionParams,
sizeof(gvopVersionParams),
&dwBytesReturned, NULL);

if(gvopVersionParams.bIDEDeviceMap <= 0) return -2;

// IDE or ATAPI IDENTIFY cmd
int btIDCmd = 0;
SENDCMDINPARAMS InParams;
int nDrive =0;
btIDCmd = (gvopVersionParams.bIDEDeviceMap >> nDrive & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;


// 输出参数
BYTE btIDOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];

if(DoIdentify(hFile,
&InParams,
(PSENDCMDOUTPARAMS)btIDOutCmd,
(BYTE)btIDCmd,
(BYTE)nDrive, &dwBytesReturned) == FALSE) return -3;
::CloseHandle(hFile);

DWORD dwDiskData[256];
USHORT *pIDSector; // 对应结构IDSECTOR,见头文件

pIDSector = (USHORT*)((SENDCMDOUTPARAMS*)btIDOutCmd)->bBuffer;
for(int i=0; i < 256; i++) dwDiskData[i] = pIDSector[i];

// 取系列号
ZeroMemory(szSerialNumber, sizeof(szSerialNumber));
strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19));

// 取模型号
ZeroMemory(szModelNumber, sizeof(szModelNumber));
strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46));

return 0;
}
gansininiang 2010-06-13
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 gz_qmc 的回复:]
DOS版 OR WINDOWS版
[/Quote]
。。。。。。。。。WINDOWS版
AlanBruce 2010-06-12
  • 打赏
  • 举报
回复
http://dl.pconline.com.cn/html_2/1/59/id=3687&pn=0.html
gz_qmc 2010-06-12
  • 打赏
  • 举报
回复
DOS版 OR WINDOWS版

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧