CE6.0 下获得 SD 卡序列号的方法

经常在坛子里看到讨论软件加密的帖子,纯软件加密与读取硬件序列号加密是经常讨论到的。

两种方法各有优缺点。

在通过读取硬件序列号的方法来加密的方法,受硬件的限制。

一般来说,CPU和T-Flash可能存在序列号。今天研究了一下 Windows CE 6.0 下的读取 SD 卡(T-Flash)的方法,以下将自己的实现过程列出来,供有需要的朋友一起学习。

函数的声明,在.H文件文件中:

1 #define SD_PART_NAME    L"DSK2:"
2 #define VALID_SD_SERIAL_1    L"A7DFB784"
3 BOOL GetStorageID(TCHAR *ptcCardName,TCHAR *ptcManufactureID,TCHAR *ptcSerialNum);

源代码如下函数所示:

 1 BOOL GetStorageID(TCHAR *ptcCardName,TCHAR *ptcManufactureID,TCHAR *ptcSerialNum)  
 2 {  
 3     DWORD dwSize = 0;  
 4     DWORD dwReqSize = 0;  
 5     STORAGE_IDENTIFICATION StoreInfo;  
 6     STORAGE_IDENTIFICATION StoreInfo2;  
 7     HANDLE hVolume = NULL;  
 8     BOOL bRet = FALSE;  
 9   
10     BYTE *pucSerialNo = NULL;  
11     BYTE *pucManuID = NULL;  
12     int i = 0;  
13   
14     ZeroMemory(&StoreInfo,sizeof(STORAGE_IDENTIFICATION));  
15   
16     hVolume = CreateFile(ptcCardName,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);    
17     if(NULL == hVolume || INVALID_HANDLE_VALUE == hVolume)    
18     {  
19         // MessageBox(L"Open Partation failed!");  
20         RETAILMSG(1,(L"Open Partation failed!
"));  
21         return FALSE;  
22     }  
23     bRet = DeviceIoControl(hVolume,IOCTL_DISK_GET_STORAGEID,  
24         NULL,0,(LPVOID)&StoreInfo,/*sizeof(STORAGE_IDENTIFICATION)*/3000,&dwSize,NULL);  
25     if(!bRet)  
26     {  
27         DWORD dwErr = GetLastError();  
28         // TCHAR tcError[64];  
29   
30         // wsprintf(tcError,L"Device IO 1 failed: %d!",dwErr);  
31   
32         // MessageBox(tcError);  
33         RETAILMSG(1,(L"Device IO 1 failed: %d!
",dwErr));  
34         CloseHandle(hVolume);  
35         return FALSE;  
36     }  
37     dwReqSize = StoreInfo.dwSize;  
38   
39     ASSERT(dwReqSize > 0);  
40   
41     dwSize = 0;  
42     StoreInfo2.dwSize = dwReqSize;  
43     bRet = DeviceIoControl(hVolume,IOCTL_DISK_GET_STORAGEID,  
44         NULL,0,(LPVOID)&StoreInfo,dwReqSize,&dwSize,NULL);     
45   
46     if(FALSE == bRet)  
47     {  
48         DWORD dwErr = GetLastError();  
49         // TCHAR tcError[64];  
50   
51         // wsprintf(tcError,L"Device IO 2 failed: %d!",dwErr);  
52   
53         // MessageBox(tcError);  
54         RETAILMSG(1,(L"Device IO 2 failed: %d!
",dwErr));  
55         CloseHandle(hVolume);  
56   
57         return FALSE;  
58     }  
59   
60     pucSerialNo = (((BYTE *)&StoreInfo) + StoreInfo.dwSerialNumOffset);  
61     pucManuID = (((BYTE *)&StoreInfo) + StoreInfo.dwManufactureIDOffset);  
62     while(pucSerialNo[i] != 0 && i < 200 && i < (int)(dwSize - StoreInfo.dwSerialNumOffset))  
63     {  
64         ptcSerialNum[i] = pucSerialNo[i];  
65         i++;  
66     }  
67     pucSerialNo[i] = ' ';  
68   
69     i = 0;  
70     while(pucManuID[i] != 0 && i < 200 && i < (int)(StoreInfo.dwSerialNumOffset - StoreInfo.dwManufactureIDOffset))  
71     {  
72         ptcManufactureID[i] = pucManuID[i];  
73         i++;  
74     }  
75     pucManuID[i] = ' ';  
76   
77     CloseHandle(hVolume);  
78   
79     return TRUE;   
80 }  

调用示例如下:

 1 TCHAR tcSDSerial[256];  
 2  TCHAR tcSDManu[256];  
 3   
 4  ZeroMemory(tcSDSerial,sizeof(TCHAR) * 256);  
 5 ZeroMemory(tcSDManu,sizeof(TCHAR) * 256);  
 6   
 7 if(0 == GetStorageID(SD_PART_NAME,tcSDManu,tcSDSerial))  
 8 {  
 9     MessageBox(tcSDSerial);  
10     if(0 == wcsncmp(VALID_SD_SERIAL_1,tcSDSerial,wcslen(VALID_SD_SERIAL_1)))  
11     {  
12     }  
13     else  
14     {  
15     }  
16 }  
17   
18 实现过程中,遇到以下错误:  
19 (1) 当将调用代码修改为: if(GetStorageID(L"DSK1:",csManufactureID,csSerialID)) 时(DSK1 是存在的)产生如下错误:  
20 Error 50: 不支持请求。   
21 (2) 当将实现代码中的 DeviceIoControl()函数 修改为如下时:  
22 bRet = DeviceIoControl(hVolume,IOCTL_DISK_GET_STORAGEID,  
23     NULL,0,(LPVOID)&StoreInfo,sizeof(STORAGE_IDENTIFICATION),&dwSize,NULL);  
24       
25  产生如下错误:Error 122: 传递给系统调用的数据区域太小。所以,建议各位程序在编码时,尽量对函数的返回值进行判断。在出错的状态,一定要调用 GetLastError() 函数获取详细的错误码。  
原文地址:https://www.cnblogs.com/91program/p/5207319.html