QuakeGod
2022-01-16 326d3e312c74726814c39c9d112faab03c4a167c
提交 | 用户 | 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 }