提交 | 用户 | age
|
4b03ae
|
1 |
#include "stdafx.h"
|
Q |
2 |
#include "DiskFunc.h"
|
|
3 |
|
|
4 |
//打开设备 //sFileName 设备的 文件名 (绝对路径)
|
|
5 |
HANDLE OpenDevice(LPCTSTR sFileName)
|
|
6 |
{
|
|
7 |
HANDLE hDevice; //打开设备
|
|
8 |
hDevice =:: CreateFile(sFileName, //文件名
|
|
9 |
GENERIC_READ|GENERIC_WRITE, //读写方式
|
|
10 |
FILE_SHARE_READ|FILE_SHARE_WRITE,//共享方式
|
|
11 |
NULL, //默认的安全描述符
|
|
12 |
OPEN_EXISTING, //创建方式
|
|
13 |
0, //不需设置文件属性
|
|
14 |
NULL); //不需参照模版文件
|
|
15 |
return hDevice;
|
|
16 |
}
|
|
17 |
char szSerialNumber[2048];
|
|
18 |
char szModelNumber[2048];
|
|
19 |
BOOL __fastcall DoIdentify( HANDLE hPhysicalDriveIOCTL,
|
|
20 |
PSENDCMDINPARAMS pSCIP,
|
|
21 |
PSENDCMDOUTPARAMS pSCOP,
|
|
22 |
BYTE btIDCmd,
|
|
23 |
BYTE btDriveNum,
|
|
24 |
PDWORD pdwBytesReturned)
|
|
25 |
{
|
|
26 |
pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
|
|
27 |
pSCIP->irDriveRegs.bFeaturesReg = 0;
|
|
28 |
pSCIP->irDriveRegs.bSectorCountReg = 1;
|
|
29 |
pSCIP->irDriveRegs.bSectorNumberReg = 1;
|
|
30 |
pSCIP->irDriveRegs.bCylLowReg = 0;
|
|
31 |
pSCIP->irDriveRegs.bCylHighReg = 0;
|
|
32 |
|
|
33 |
pSCIP->irDriveRegs.bDriveHeadReg = (btDriveNum & 1) ? 0xB0 : 0xA0;
|
|
34 |
pSCIP->irDriveRegs.bCommandReg = btIDCmd;
|
|
35 |
pSCIP->bDriveNumber = btDriveNum;
|
|
36 |
pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
|
|
37 |
|
|
38 |
return DeviceIoControl( hPhysicalDriveIOCTL,
|
|
39 |
SMART_RCV_DRIVE_DATA,
|
|
40 |
(LPVOID)pSCIP,
|
|
41 |
sizeof(SENDCMDINPARAMS) - 1,
|
|
42 |
(LPVOID)pSCOP,
|
|
43 |
sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,
|
|
44 |
pdwBytesReturned, NULL);
|
|
45 |
}
|
|
46 |
|
|
47 |
char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex)
|
|
48 |
{
|
|
49 |
static char szResBuf[1024];
|
|
50 |
char ss[256];
|
|
51 |
int nIndex = 0;
|
|
52 |
int nPosition = 0;
|
|
53 |
|
|
54 |
for(nIndex = nFirstIndex; nIndex <= nLastIndex; nIndex++)
|
|
55 |
{
|
|
56 |
ss[nPosition] = (char)(dwDiskData[nIndex] / 256);
|
|
57 |
nPosition++;
|
|
58 |
|
|
59 |
// Get low BYTE for 2nd character
|
|
60 |
ss[nPosition] = (char)(dwDiskData[nIndex] % 256);
|
|
61 |
nPosition++;
|
|
62 |
}
|
|
63 |
|
|
64 |
// End the string
|
|
65 |
ss[nPosition] = '\0';
|
|
66 |
|
|
67 |
int i, index=0;
|
|
68 |
for(i=0; i<nPosition; i++)
|
|
69 |
{
|
|
70 |
if(ss[i]==0 || ss[i]==32) continue;
|
|
71 |
szResBuf[index]=ss[i];
|
|
72 |
index++;
|
|
73 |
}
|
|
74 |
szResBuf[index]=0;
|
|
75 |
|
|
76 |
return szResBuf;
|
|
77 |
}
|
|
78 |
void AdjustString(char * str, int len)
|
|
79 |
{
|
|
80 |
char ch;int i;
|
|
81 |
//两两颠倒
|
|
82 |
for (i =0; i<len; i+=2)
|
|
83 |
{
|
|
84 |
ch=str[i];
|
|
85 |
str[i]=str[i+1];
|
|
86 |
str[i+1]=ch;
|
|
87 |
}
|
|
88 |
str[len-1]=0;
|
|
89 |
//若是右对其,调整为左对其
|
|
90 |
|
|
91 |
}
|
|
92 |
BOOL IDentifyDeviceAsScsi(HANDLE hDevice, int nDrive, PIDINFO pIdInfo)
|
|
93 |
{
|
|
94 |
PSENDCMDINPARAMS pSCIP;
|
|
95 |
PSENDCMDOUTPARAMS pSCOP;
|
|
96 |
PSRB_IO_CONTROL pSRBIO;
|
|
97 |
DWORD dwOutBytes;
|
|
98 |
BOOL bResult;
|
|
99 |
|
|
100 |
pSRBIO = (PSRB_IO_CONTROL)::GlobalAlloc(LMEM_ZEROINIT, sizeof(SRB_IO_CONTROL)+sizeof(SENDCMDOUTPARAMS)+sizeof(IDINFO) -1);
|
|
101 |
pSCIP = (PSENDCMDINPARAMS)((char *)pSRBIO+sizeof(SRB_IO_CONTROL));
|
|
102 |
pSCOP = (PSENDCMDOUTPARAMS)pSCIP;
|
|
103 |
//填充数据
|
|
104 |
pSRBIO->HeaderLength=sizeof(SRB_IO_CONTROL);
|
|
105 |
pSRBIO->Timeout=10000;
|
|
106 |
pSRBIO->Length=sizeof(SENDCMDOUTPARAMS)+sizeof(IDINFO)-1;
|
|
107 |
pSRBIO->ControlCode=IOCTL_SCSI_MINIPORT_IDENTIFY;
|
|
108 |
memcpy_s((char *)pSRBIO->Signature,8,"SCSIDISK",8);
|
|
109 |
//strncpy_s((char *)pSRBIO->Signature,8,"SCSIDISK",8);
|
|
110 |
//指定ATA/ATAPI 命令的寄存器值
|
|
111 |
pSCIP->irDriveRegs.bFeaturesReg = 0;
|
|
112 |
pSCIP->irDriveRegs.bSectorCountReg = 0;
|
|
113 |
pSCIP->irDriveRegs.bSectorNumberReg = 0;
|
|
114 |
pSCIP->irDriveRegs.bCylLowReg = 0;
|
|
115 |
pSCIP->irDriveRegs.bCylHighReg = 0;
|
|
116 |
pSCIP->irDriveRegs.bDriveHeadReg =0;
|
|
117 |
pSCIP->irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
|
|
118 |
pSCIP->bDriveNumber = nDrive;
|
|
119 |
//IDENTIFY DEVICE
|
|
120 |
bResult = ::DeviceIoControl(hDevice, IOCTL_SCSI_MINIPORT,
|
|
121 |
pSRBIO,sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS) -1,
|
|
122 |
pSRBIO,sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDOUTPARAMS) +sizeof(IDINFO)-1,
|
|
123 |
&dwOutBytes,
|
|
124 |
NULL);
|
|
125 |
::memcpy(pIdInfo,pSCOP->bBuffer,sizeof(IDINFO));
|
|
126 |
::GlobalFree(pSRBIO);
|
|
127 |
return bResult;
|
|
128 |
|
|
129 |
}
|
|
130 |
//用SCSI驱动读取IDE硬盘的设备信息,不受权限制约
|
|
131 |
//nDriver 驱动器好( 0 = Primary master, 1=Primary Slave, 2 = Second Master,
|
|
132 |
//pIdInfo 设备信息结构指针;
|
|
133 |
BOOL GetIdeDriveAsScsiInfoInNT(int nDrive, PIDINFO pIdInfo)
|
|
134 |
{
|
|
135 |
HANDLE hDevice;//
|
|
136 |
BOOL bResult; //
|
|
137 |
// char szFileName[20];
|
|
138 |
// ::sprintf(szFileName,"\\\\.\\Scsi%d:",nDrive/2);
|
|
139 |
CString sFileName;
|
|
140 |
sFileName.Format(_T("\\\\.\\Scsi%d:"),nDrive/2);
|
|
141 |
hDevice = OpenDevice(sFileName);
|
|
142 |
if (hDevice == INVALID_HANDLE_VALUE) {return false;}
|
|
143 |
//IDENTIFY DEVICE
|
|
144 |
bResult = IDentifyDeviceAsScsi(hDevice,nDrive%2,pIdInfo);
|
|
145 |
CloseHandle(hDevice);
|
|
146 |
//检查是不是空串;
|
|
147 |
if (pIdInfo->sModelNumber[0] == '\0') {bResult = false;}
|
|
148 |
if (bResult)
|
|
149 |
{
|
|
150 |
//调整字符串
|
|
151 |
::AdjustString(pIdInfo->sSerialNumber,20);
|
|
152 |
::AdjustString(pIdInfo->sModelNumber,40);
|
|
153 |
::AdjustString(pIdInfo->sFirmwareRev,8);
|
|
154 |
}
|
|
155 |
return bResult;
|
|
156 |
|
|
157 |
}
|
|
158 |
int GetHDSerialID(int driver)
|
|
159 |
{
|
|
160 |
// 硬盘物理序列号是硬盘的出厂序列号,它是全球都是唯一的,不会随着系统的安装、硬盘的格式化等操作而改变,跟mac地址一样都具有唯一性。
|
|
161 |
CString s1;
|
|
162 |
// 1,第一步:创建设备对象,得到设备句柄,设备为硬盘。
|
|
163 |
{
|
|
164 |
// int driver=0;
|
|
165 |
CString sFilePath;
|
|
166 |
sFilePath.Format(_T("\\\\.\\PHYSICALDRIVE%d"), driver);
|
|
167 |
HANDLE hFile=::CreateFile(sFilePath,
|
|
168 |
GENERIC_READ , FILE_SHARE_READ ,
|
|
169 |
NULL, OPEN_EXISTING,0, NULL);
|
|
170 |
s1.Format(_T("创建文件 %s 结果 句柄 %X \r\n"),sFilePath,hFile);
|
|
171 |
// mylogger1.LogTxt(s1);
|
|
172 |
if (hFile==INVALID_HANDLE_VALUE) {return -1;}
|
|
173 |
DWORD dwBytesReturned;
|
|
174 |
GETVERSIONINPARAMS gvopVersionParams;
|
|
175 |
int j = DeviceIoControl(hFile, //向设备对象发送SMART_GET_VERSION设备请求,获取硬盘属性
|
|
176 |
SMART_GET_VERSION, NULL, 0,
|
|
177 |
&gvopVersionParams, sizeof(gvopVersionParams),
|
|
178 |
&dwBytesReturned, NULL);
|
|
179 |
s1.Format(_T("获取磁盘属性 0x%X Return %d Bytes %d bIDEDeviceMap %d \r\n"),SMART_GET_VERSION,j,dwBytesReturned,gvopVersionParams.bIDEDeviceMap);
|
|
180 |
// mylogger1.LogTxt(s1);
|
|
181 |
|
|
182 |
// if(gvopVersionParams.bIDEDeviceMap <= 0) return -2;
|
|
183 |
// 2。第二步,发送SMART_RCV_DRIVE_DATA设备请求,获取硬盘详细信息。
|
|
184 |
// IDE or ATAPI IDENTIFY cmd
|
|
185 |
int btIDCmd = 0;
|
|
186 |
SENDCMDINPARAMS InParams;
|
|
187 |
int nDrive =0;
|
|
188 |
btIDCmd = (gvopVersionParams.bIDEDeviceMap >> nDrive & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
|
|
189 |
|
|
190 |
s1.Format(_T("btIDCmd %X \r\n "),btIDCmd);
|
|
191 |
// mylogger1.LogTxt(s1);
|
|
192 |
|
|
193 |
// 输出参数
|
|
194 |
BYTE btIDOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
|
|
195 |
int bResult=DoIdentify(hFile,
|
|
196 |
&InParams,
|
|
197 |
(PSENDCMDOUTPARAMS)btIDOutCmd,
|
|
198 |
(BYTE)btIDCmd,
|
|
199 |
(BYTE)nDrive, &dwBytesReturned);
|
|
200 |
::CloseHandle(hFile);
|
|
201 |
if( bResult== FALSE) return -3;
|
|
202 |
|
|
203 |
DWORD dwDiskData[256];
|
|
204 |
USHORT *pIDSector; // 对应结构IDSECTOR,见头文件
|
|
205 |
|
|
206 |
pIDSector = (USHORT*)((SENDCMDOUTPARAMS*)btIDOutCmd)->bBuffer;
|
|
207 |
for(int i=0; i < 256; i++) dwDiskData[i] = pIDSector[i];
|
|
208 |
|
|
209 |
// 取系列号
|
|
210 |
ZeroMemory(szSerialNumber, sizeof(szSerialNumber));
|
|
211 |
strcpy_s(szSerialNumber, 2048, ConvertToString(dwDiskData, 10, 19));
|
|
212 |
|
|
213 |
// 取模型号
|
|
214 |
ZeroMemory(szModelNumber, sizeof(szModelNumber));
|
|
215 |
strcpy_s(szModelNumber, 2048, ConvertToString(dwDiskData, 27, 46));
|
|
216 |
s1.Format(_T("\r\n Model %S \r\n Serial %S \r\n"),szModelNumber,szSerialNumber);
|
|
217 |
// mylogger1.LogTxt(s1);
|
|
218 |
int len1=strlen(szSerialNumber);
|
|
219 |
short int machinecode[15];
|
|
220 |
int len2=(len1+1)/2;
|
|
221 |
s1.Format(_T("MachineCode: "));
|
|
222 |
for (int i=0;i<len2;i++)
|
|
223 |
{
|
|
224 |
if (i!=0) s1.Append(_T("-"));
|
|
225 |
int j=((szSerialNumber[i*2]-48)+(szSerialNumber[i*2+1]-48)*64)%8192+1234;
|
|
226 |
machinecode[i]=j;
|
|
227 |
s1.AppendFormat(_T("%d"),j);
|
|
228 |
}
|
|
229 |
s1.Append(_T("\r\n"));
|
|
230 |
// mylogger1.LogTxt(s1);
|
|
231 |
s1.Format(_T("Back : "));
|
|
232 |
for (int i=0;i<len2;i++)
|
|
233 |
{
|
|
234 |
int j=machinecode[i];
|
|
235 |
int k,l;
|
|
236 |
k=((j-1234)%64)+48;l=((j-1234)/64)+48;
|
|
237 |
s1.AppendFormat(_T("%c%c"),k,l);
|
|
238 |
}
|
|
239 |
s1.AppendFormat(_T("\r\n"));
|
|
240 |
// mylogger1.LogTxt(s1);
|
|
241 |
return 0;
|
|
242 |
}
|
|
243 |
}
|