獲取SD卡序列號和廠商ID

honwsn發表於2010-04-30

wince 儲存裝置有兩個名稱,
一個裝置名稱CreateFile開啟裝置獲取控制程式碼的時候要用的,如DSK1:
一個是儲存名稱,如Mircosoft Flash Disk
見如下資料結構:

typedef struct {
DWORD cbSize;
TCHAR szDeviceName[DEVICENAMESIZE];
TCHAR szStoreName[STORENAMESIZE];
DWORD dwDeviceClass;
DWORD dwDeviceType;
STORAGEDEVICEINFO sdi;
DWORD dwDeviceFlags;
SECTORNUM snNumSectors;
DWORD dwBytesPerSector;
SECTORNUM snFreeSectors;
SECTORNUM snBiggestPartCreatable;
FILETIME ftCreated;
FILETIME ftLastModified;
DWORD dwAttributes;
DWORD dwPartitionCount;
DWORD dwMountCount;
} STOREINFO, *PSTOREINFO;

[@more@]

下面是我找的獲取SD序號號和廠商ID一份示例程式碼:
SD卡的廠商ID和序列號都是ASCII字串.

摘自http://geekswithblogs.net/BruceEitman/Default.aspx

#include "windows.h"
#include "Diskio.h"

void RETAILMSG_ASCII(char *Str, DWORD NumChars)
{
DWORD Index;

for( Index = 0; *Str != '' && Index < NumChars; Index++ )
{
RETAILMSG( 1, (TEXT("%c"), *Str++));
}
}

BOOL DisplayDiskID( TCHAR *Disk )
{
STORAGE_IDENTIFICATION *StoreID = NULL;
STORAGE_IDENTIFICATION GetSizeStoreID;
DWORD dwSize;
HANDLE hVol;
TCHAR VolumeName[MAX_PATH];
char *ManfID;
char *SerialNumber;
BOOL RetVal = FALSE;
DWORD GLE;

//_stprintf(VolumeName, _T(":"), Disk);
_stprintf(VolumeName, _T(""), Disk);//這兩種方式狀況都可以,輸入應該是裝置名稱,如DSK1: DSK2:

hVol = CreateFile( Disk, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

if( hVol != INVALID_HANDLE_VALUE )
{
if(DeviceIoControl(hVol, IOCTL_DISK_GET_STORAGEID, (LPVOID)NULL, 0, &GetSizeStoreID, sizeof(STORAGE_IDENTIFICATION), &dwSize, NULL) == FALSE)
{
GLE = GetLastError();
if( GLE == ERROR_INSUFFICIENT_BUFFER )
{
//若是空間不足,引起的呼叫失敗,說明還是有廠商ID和序列號資訊的.
//GetSizeStoreID.dwSize 說明了STORAGE_IDENTIFICATION結構本身的大小加上了
//廠商ID和序列號所需的儲存空間.

StoreID = (STORAGE_IDENTIFICATION *)malloc( GetSizeStoreID.dwSize );
if(DeviceIoControl(hVol, IOCTL_DISK_GET_STORAGEID, (LPVOID)NULL, 0, StoreID, GetSizeStoreID.dwSize, &dwSize, NULL) != FALSE)
{
if( !(StoreID->dwFlags & MANUFACTUREID_INVALID) )
{
ManfID = (char *)((DWORD)StoreID + StoreID->dwManufactureIDOffset);
RETAILMSG( 1, (TEXT("DisplayDiskID: Manufacture ID ")));
//下面的輸出函式考慮到輸出字元的長度
//The serial number and module number are NULL terminated ASCII strings.

RETAILMSG_ASCII( ManfID, StoreID->dwSerialNumOffset - StoreID->dwManufactureIDOffset);
RETAILMSG( 1, (TEXT("rn")));
}
if( !(StoreID->dwFlags & SERIALNUM_INVALID) )
{
SerialNumber = (char *)((DWORD)StoreID + StoreID->dwSerialNumOffset);
RETAILMSG( 1, (TEXT("DisplayDiskID: Serial Number ")));
RETAILMSG_ASCII( SerialNumber, GetSizeStoreID.dwSize - StoreID->dwSerialNumOffset );
RETAILMSG( 1, (TEXT("rn")));
}
RetVal = TRUE;
}
else
RETAILMSG( 1, (TEXT("DisplayDiskID: DeviceIoControl failed (%d)rn"), GLE));

free(StoreID);
}
else
RETAILMSG( 1, (TEXT("No Disk Identifcation available for %srn"), VolumeName ));
}
else//這種狀況下,DeviceIoControl返回成功 說明這張卡沒有序列號和廠商ID資訊
RETAILMSG( 1, (TEXT("DisplayDiskID: DeviceIoControl succeeded (and shouldn't have)rn")));

CloseHandle (hVol);
}
else
RETAILMSG( 1, (TEXT("DisplayDiskID: Failed to open volume (%s)rn"), VolumeName ));

return RetVal;
}

下面是作者的原話,說明在獲取卡的序列號時的注意事項,體現的嚴謹態度

"Note that the manufature ID and serial number are ASCII strings, so I included a little function to output those on the debug serial port. I also found that some of the memory card drivers don't handle the strings very well, so I had to limit the strings by length rather than by looking for the null character.

Further testing showed that both : and : work when calling CreateFile();"

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23410886/viewspace-1033323/,如需轉載,請註明出處,否則將追究法律責任。

相關文章