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

推荐订阅源

S
SegmentFault 最新的问题
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Cisco Talos Blog
Cisco Talos Blog
Spread Privacy
Spread Privacy
Scott Helme
Scott Helme
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Securelist
酷 壳 – CoolShell
酷 壳 – CoolShell
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
博客园 - 叶小钗
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
量子位
Security Latest
Security Latest
P
Proofpoint News Feed
P
Privacy International News Feed
P
Palo Alto Networks Blog
D
DataBreaches.Net
大猫的无限游戏
大猫的无限游戏
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Google Online Security Blog
Google Online Security Blog
Webroot Blog
Webroot Blog
云风的 BLOG
云风的 BLOG
N
Netflix TechBlog - Medium
Vercel News
Vercel News
博客园 - 【当耐特】
C
CERT Recently Published Vulnerability Notes
Hugging Face - Blog
Hugging Face - Blog
月光博客
月光博客
Hacker News - Newest:
Hacker News - Newest: "LLM"
K
Kaspersky official blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Stack Overflow Blog
Stack Overflow Blog
AWS News Blog
AWS News Blog
博客园 - Franky
爱范儿
爱范儿
T
Tor Project blog
The GitHub Blog
The GitHub Blog
宝玉的分享
宝玉的分享
小众软件
小众软件
L
LINUX DO - 最新话题
Application and Cybersecurity Blog
Application and Cybersecurity Blog
W
WeLiveSecurity
SecWiki News
SecWiki News
L
LangChain Blog
I
InfoQ

博客园 - 凌点

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 包含在连接器的库文件参数下。
 
其中很多的细节我还搞得不是特别清楚,该死的微软,那么多的好东西都不公开......