//h文件中的代码
01.#include "iostream"
02.#include "winioctl.h"
03.
04.#define IDE_ATAPI_IDENTIFY 0xA1 // Returns ID sector for ATAPI.
05.#define IDE_ATA_IDENTIFY 0xEC // Returns ID sector for ATA.
06.#define IOCTL_GET_DRIVE_INFO 0x0007c088
07.#define IOCTL_GET_VERSION 0x00074080
08.
09.typedef struct _GETVERSIONOUTPARAMS
10.{
11. BYTE bVersion; // Binary driver version.
12. BYTE bRevision; // Binary driver revision.
13. BYTE bReserved; // Not used.
14. BYTE bIDEDeviceMap; // Bit map of IDE devices.
15. DWORD fCapabilities; // Bit mask of driver capabilities.
16. DWORD dwReserved[4]; // For future use.
17.} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
/cpp中的代码
01.// Windows NT/2000/XP下读取IDE设备信息
02.bool GetHardwarePhysical_IDE_Info_NT(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP, PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum, PDWORD lpcbBytesReturned)
03.{
04. // 为读取设备信息准备参数
05. pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;
06. pSCIP -> irDriveRegs.bFeaturesReg = 0;
07. pSCIP -> irDriveRegs.bSectorCountReg = 1;
08. pSCIP -> irDriveRegs.bSectorNumberReg = 1;
09. pSCIP -> irDriveRegs.bCylLowReg = 0;
10. pSCIP -> irDriveRegs.bCylHighReg = 0;
11.
12. // 计算驱动器位置
13. pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);
14.
15. // 设置读取命令
16. pSCIP -> irDriveRegs.bCommandReg = bIDCmd;
17. pSCIP -> bDriveNumber = bDriveNum;
18. pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;
19.
20. // 读取驱动器信息
21. return ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_DRIVE_INFO, (LPVOID) pSCIP, sizeof(SENDCMDINPARAMS) - 1, (LPVOID) pSCOP, sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1, lpcbBytesReturned, NULL) ) ? true : false;
22.}
23.// Windows NT/2000/XP下读取IDE硬盘序列号
24.bool GetHDD_SN_forWinNt(DWORD * buffer)
25.{
26. BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
27. bool bFlag = false;
28. int drive = 0;
29. char driveName [256];
30. HANDLE hPhysicalDriveIOCTL = 0;
31.
32. sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);
33. // Windows NT/2000/XP下创建文件需要管理员权限
34. hPhysicalDriveIOCTL = CreateFileA (driveName,
35. GENERIC_READ | GENERIC_WRITE,
36. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
37. OPEN_EXISTING, 0, NULL);
38.
39. if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
40. {
41. GETVERSIONOUTPARAMS VersionParams;
42. DWORD cbBytesReturned = 0;
43.
44. // 得到驱动器的IO控制器版本
45. memset ((void*) &VersionParams, 0, sizeof(VersionParams));
46. if(::DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_VERSION,
47. NULL, 0, &VersionParams,
48. sizeof(VersionParams),
49. &cbBytesReturned, NULL) )
50. {
51. if (VersionParams.bIDEDeviceMap > 0)
52. {
53. BYTE bIDCmd = 0; // IDE或者ATAPI识别命令
54. SENDCMDINPARAMS scip;
55.
56. // 如果驱动器是光驱,采用命令IDE_ATAPI_IDENTIFY, command,
57. // 否则采用命令IDE_ATA_IDENTIFY读取驱动器信息
58. bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10)? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
59.
60. memset (&scip, 0, sizeof(scip));
61. memset (IdOutCmd, 0, sizeof(IdOutCmd));
62. // 获取驱动器信息
63. if (GetHardwarePhysical_IDE_Info_NT(hPhysicalDriveIOCTL,
64. &scip,
65. (PSENDCMDOUTPARAMS)&IdOutCmd,
66. (BYTE) bIDCmd,
67. (BYTE) drive,
68. &cbBytesReturned))
69. {
70. int m = 0;
71. USHORT *pIdSector = (USHORT *)
72. ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;
73.
74. for (m = 0; m < 256; m++)
75. buffer[m] = pIdSector [m];
76. bFlag = false; // 读取硬盘信息成功
77. }
78. }
79. }
80. ::CloseHandle (hPhysicalDriveIOCTL); // 关闭句柄
81. }
82. return bFlag;
83.}
84.// Windows NT/2000/XP系统下,将双字类型(DWORD)的硬盘信息转换为字符类型(char)
85.std::string physical_info_dword_to_char(DWORD diskdata [256], int firstIndex, int lastIndex)
86.{
87. char string [1024];
88. int index = 0;
89. int position = 0;
90.
91. // 按照高字节在前,低字节在后的顺序将双字中的低字存入到字符串string中
92. for (index = firstIndex; index <= lastIndex; index++)
93. {
94. // 存入低字中的高字节
95. string [position] = (char) (diskdata [index] / 256);
96. position++;
97. // 存入低字中的低字节
98. string [position] = (char) (diskdata [index] % 256);
99. position++;
100. }
101. // 添加字符串结束标志
102. string [position] = '\0';
103.
104. // 删除字符串中空格
105. for (index = position - 1; index > 0 && ' ' == string [index]; index--)
106. string [index] = '\0';
107.
108. return string;
109.}
//调用方法
01.DWORD dwBuf[256];
02.char m_buffer[222];
03.
04.GetHDD_SN_forWinNt(dwBuf);
05.strcpy(m_buffer, physical_info_dword_to_char(dwBuf, 10, 19).c_str());
06.::MessageBoxA(m_hWnd, m_buffer, "硬盘序列号", MB_OK);