-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSource.cpp
More file actions
109 lines (93 loc) · 2.53 KB
/
Source.cpp
File metadata and controls
109 lines (93 loc) · 2.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <windows.h>
#include <winioctl.h>
#include <iostream>
//
BOOL GetPhyDriveSerial(LPTSTR pModelNo, LPTSTR pSerialNo);
void ToLittleEndian(PUSHORT pWords, int nFirstIndex, int nLastIndex, LPTSTR pBuf);
void TrimStart(LPTSTR pBuf);
//
// get hard disk serial number
// Model Number: 40 ASCII Chars
// SerialNumber: 20 ASCII Chars
//
BOOL GetPhyDriveSerial(LPTSTR pModelNo, LPTSTR pSerialNo)
{
//-1是因为 SENDCMDOUTPARAMS 的结尾是 BYTE bBuffer[1];
BYTE IdentifyResult[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
DWORD dwBytesReturned;
GETVERSIONINPARAMS get_version;
SENDCMDINPARAMS send_cmd = { 0 };
HANDLE hFile = CreateFile(L"\\\\.\\PHYSICALDRIVE0", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return FALSE;
//get version
DeviceIoControl(hFile, SMART_GET_VERSION, NULL, 0,
&get_version, sizeof(get_version), &dwBytesReturned, NULL);
//identify device
send_cmd.irDriveRegs.bCommandReg = (get_version.bIDEDeviceMap & 0x10) ? ATAPI_ID_CMD : ID_CMD;
DeviceIoControl(hFile, SMART_RCV_DRIVE_DATA, &send_cmd, sizeof(SENDCMDINPARAMS) - 1,
IdentifyResult, sizeof(IdentifyResult), &dwBytesReturned, NULL);
CloseHandle(hFile);
//adjust the byte order
PUSHORT pWords = (USHORT*)(((SENDCMDOUTPARAMS*)IdentifyResult)->bBuffer);
ToLittleEndian(pWords, 27, 46, pModelNo);
ToLittleEndian(pWords, 10, 19, pSerialNo);
return TRUE;
}
//把WORD数组调整字节序为little-endian,并滤除字符串结尾的空格。
void ToLittleEndian(PUSHORT pWords, int nFirstIndex, int nLastIndex, LPTSTR pBuf)
{
int index;
LPTSTR pDest = pBuf;
for (index = nFirstIndex; index <= nLastIndex; ++index)
{
pDest[0] = pWords[index] >> 8;
pDest[1] = pWords[index] & 0xFF;
pDest += 2;
}
*pDest = 0;
//trim space at the endof string; 0x20: _T(' ')
--pDest;
while (*pDest == 0x20)
{
*pDest = 0;
--pDest;
}
}
//滤除字符串起始位置的空格
void TrimStart(LPTSTR pBuf)
{
if (*pBuf != 0x20)
return;
LPTSTR pDest = pBuf;
LPTSTR pSrc = pBuf + 1;
while (*pSrc == 0x20)
++pSrc;
while (*pSrc)
{
*pDest = *pSrc;
++pDest;
++pSrc;
}
*pDest = 0;
}
int main(int argc, char* argv[])
{
TCHAR szModelNo[48], szSerialNo[24];
if (GetPhyDriveSerial(szModelNo, szSerialNo))
{
std::cout << "Model No: " << szModelNo << std::endl;
TrimStart(szSerialNo);
std::cout << "Serial No: " << szSerialNo << std::endl;
}
else
{
std::cout << "Failed." << std::endl;
}
getchar();
return 0;
}