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!\r\n")); 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!\r\n",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!\r\n",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] = '\0 '; 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] = '\0 '; 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() 函数获取详细的错误码。