惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Simon Willison's Weblog
Simon Willison's Weblog
P
Privacy International News Feed
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Troy Hunt's Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
V2EX - 技术
V2EX - 技术
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
O
OpenAI News
Cloudbric
Cloudbric
Google Online Security Blog
Google Online Security Blog
Schneier on Security
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Help Net Security
Help Net Security
Cyberwarzone
Cyberwarzone
G
GRAHAM CLULEY
L
Lohrmann on Cybersecurity
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Spread Privacy
Spread Privacy
NISL@THU
NISL@THU
N
News and Events Feed by Topic
T
Tenable Blog
S
Security @ Cisco Blogs
N
News and Events Feed by Topic
The Hacker News
The Hacker News
C
CXSECURITY Database RSS Feed - CXSecurity.com
宝玉的分享
宝玉的分享
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
美团技术团队
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google DeepMind News
Google DeepMind News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
V
Visual Studio Blog
P
Proofpoint News Feed
Webroot Blog
Webroot Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 三生石上(FineUI控件)
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Jina AI
Jina AI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
Hugging Face - Blog
Hugging Face - Blog
腾讯CDC
L
LangChain Blog
The Register - Security
The Register - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东

博客园 - 凌点

clr20r3 system.InvalidOperationException 程序终止的几种解决方案 能上Q 不能上网 JavaScript中url 传递参数(特殊字符) apache 多站点配置 C#中使用 SendMessage 向非顶端窗体发送组合键 System.Xml.XmlException: 根级别上的数据无效 XP,WIN7双系统启动问题 VM安装XP注意事项 VC 命令行 捕获输出 make 信息重定向 VC 进度条制件CProgressCtrl 用法笔记 VC List Control控件高级使用 List Control 控件技巧总汇 VC中字符串取子串总结 如何禁用Windows屏保和电源管理 unicode cstring to char* - 凌点 将unicode的 Cstring 复制到粘贴板 VC由进程ID获取窗口句柄 嵌入式Linux操作系统学习规划
VC获取硬盘物理序列号
凌点 · 2009-11-07 · via 博客园 - 凌点

本文转自:本文来自CSDN博客:http://blog.csdn.net/ablo_zhou/archive/2006/07/19/942625.aspx  

以下完整内容:

最近才做完了这个获取 IDE 硬盘物理序列号的程序。声明一下,这个程序是我根据 Lynn McGuire 的那个 DiskID32 的源代码做了些自以为是的改动得到的,只能在 NT 平台下获得第一块 IDE 硬盘的物理序列号。同时,这个程序用到了不少未公开的 Windows 的结构和常量......
 
下面就是相应的 C++ 代码,在 XP SP2 + VC 2005 Express 下调试通过。
void GetDiskPhysicalSN(char pchDiskPhysicalSN[14])
{
BYTE IdOutCmd[530];
 HANDLE drive=CreateFile (L"\\\\.\\PhysicalDrive0", GENERIC_READ |
GENERIC_WRITE,
       
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
       
OPEN_EXISTING, 0, NULL);
 if (drive == INVALID_HANDLE_VALUE)
 {
  // 错误处理
  return ;
 }
 GETVERSIONOUTPARAMS VersionParams;
 DWORD cbBytesReturned = 0;
 memset ((void*) &VersionParams, 0, sizeof(VersionParams));
 if (!DeviceIoControl(drive, DFP_GET_VERSION, NULL, 0,
&VersionParams,
       sizeof
(VersionParams), &cbBytesReturned, NULL))
 {
  // 错误处理
  return ;
 }
 if (VersionParams.bIDEDeviceMap<=0)
 {
  // 错误处理
  return ;
 }
 BYTE bIDCmd = 0;
 SENDCMDINPARAMS scip;
 bIDCmd = (VersionParams.bIDEDeviceMap >> 0 & 0x10) ?
IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
 memset (&scip, 0, sizeof(scip));
 memset (IdOutCmd, 0, sizeof(IdOutCmd));
 scip.cBufferSize=IDENTIFY_BUFFER_SIZE;
 scip.irDriveRegs.bFeaturesReg=0;
 scip.irDriveRegs.bSectorCountReg=1;
 scip.irDriveRegs.bSectorNumberReg=1;
 scip.irDriveRegs.bCylLowReg=0;
 scip.irDriveRegs.bCylHighReg=0;
 scip.irDriveRegs.bDriveHeadReg=0xA0 | (((BYTE) drive & 1) << 4);
 scip.irDriveRegs.bCommandReg=bIDCmd;
 scip.bDriveNumber=(BYTE) drive;
 scip.cBufferSize=IDENTIFY_BUFFER_SIZE;
 if (!DeviceIoControl(drive, DFP_RECEIVE_DRIVE_DATA, &scip, sizeof
(SENDCMDINPARAMS) - 1,
       (LPVOID)&IdOutCmd,
sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
       &cbBytesReturned,
NULL))
 {
  // 错误处理
  return ;
 }
 USHORT *pIdSector = (USHORT *)((PSENDCMDOUTPARAMS) IdOutCmd) ->
bBuffer;
 int nIndex=0, nPosition=0;
 for (nIndex=13; nIndex<20; nIndex++)
 {
  pchDiskPhysicalSN[nPosition++]=(unsigned char)(pIdSector
[nIndex]/256);
  pchDiskPhysicalSN[nPosition++]=(unsigned char)(pIdSector
[nIndex]%256);
 }
}
 
需要自定义的常量和结构为:
// IOCTL 指令常数
#define DFP_GET_VERSION   0x00074080
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088
// 用于 IDEREGS 结构 bCommandReg 项的有效值
#define IDE_ATAPI_IDENTIFY  0xA1
#define IDE_ATA_IDENTIFY  0xEC
#define IDENTIFY_BUFFER_SIZE 512

// 结构体定义
// 保存磁盘驱动器的信息
typedef struct _GETVERSIONOUTPARAMS
{
 BYTE bVersion;
 BYTE bRevision;
 BYTE bReserved;
 BYTE bIDEDeviceMap;
 DWORD fCapabilities;
 DWORD dwReserved[4];
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
// IDE 寄存器
typedef struct _IDEREGS
{
 BYTE bFeaturesReg;
 BYTE bSectorCountReg;
 BYTE bSectorNumberReg;
 BYTE bCylLowReg;
 BYTE bCylHighReg;
 BYTE bDriveHeadReg;
 BYTE bCommandReg;
 BYTE bReserved;
} IDEREGS, *PIDEREGS, *LPIDEREGS;
// 发送磁盘指令的输入参数
typedef struct _SENDCMDINPARAMS
{
 DWORD cBufferSize;
 IDEREGS irDriveRegs;
 BYTE bDriveNumber;
 BYTE bReserved[3];
 DWORD dwReserved[4];
 BYTE bBuffer[1];
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
// 磁盘状态
typedef struct _DRIVERSTATUS
{
 BYTE bDriverError;
 BYTE bIDEStatus;
 BYTE bReserved[2];
 DWORD dwReserved[2];
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;
// 发送磁盘指令的输出参数
typedef struct _SENDCMDOUTPARAMS
{
 DWORD cBufferSize;
 DRIVERSTATUS DriverStatus;
 BYTE bBuffer[1];
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
 
同时,还需要提醒的是,这个程序需要用到头文件 Iphlpapi.h,并需要将 Iphlpapi.lib 包含在连接器的库文件参数下。
 
其中很多的细节我还搞得不是特别清楚,该死的微软,那么多的好东西都不公开......