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

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

两种方法各有优缺点。


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

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


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


#define SD_PART_NAME    L"DSK2:"
#define VALID_SD_SERIAL_1    L"A7DFB784"

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/LoongEmbedded/p/5298400.html