Windows Mobile 下显示 Flash Card 容量和序列号的代码[转载]
版权所有为 王军杰
原文地址
http://blog.youkuaiyun.com/wang_junjie/archive/2007/11/04/1865569.aspx
- #include <projects.h>
- #include <winioctl.h>
- // Include library Note_Prj.lib
- #pragma comment (lib, "Note_Prj.lib")
- //------------------------------------------------------------------------------
- //
- // Static data members
- //
- //------------------------------------------------------------------------------
- TCHAR CFlashCard::m_CardPath[CFlashCard::MAX_CARD_PATH];
- const UINT CFlashCard::MINIMUM_CARD_SIZE = 63 * (1024 * 1024);
- //------------------------------------------------------------------------------
- //
- // Used to see if a flash card is inserted into a socket. Return true
- if card
- // is found, false otherwise. Also, if found, sets card's path
- //
- //------------------------------------------------------------------------------
- BOOL CFlashCard::isCardAvailable()
- {
- BOOL res = TRUE;
- HANDLE hFlashCard = NULL;
- WIN32_FIND_DATA find;
- BOOL loop = TRUE;
- UINT flashCardCount = 0;
- ULARGE_INTEGER freeBytesAvailableToCaller;
- ULARGE_INTEGER totalNumberOfBytes;
- ULARGE_INTEGER totalNumberOfFreeBytes;
- // Look for the SD card.
- memset(&find, 0, sizeof(WIN32_FIND_DATA));
- hFlashCard = ::FindFirstFlashCard(&find);
- if(INVALID_HANDLE_VALUE != hFlashCard)
- {
- // We must enumerate the flash cards, since the dumb
- // iPAQ file store is defined as a flash card
- while(loop)
- {
- // Only look at the flash card if it is a directory and temporary
- if(((find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
- FILE_ATTRIBUTE_DIRECTORY) &&
- ((find.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) ==
- FILE_ATTRIBUTE_TEMPORARY))
- {
- // NOTE: Even though we specify temporary, the local storage will
- also be
- // found, such as "iPaq File Store" for ipaqs and "Built-in Storage" for
- // Dells. So, instead of filtering on a name, we will filter on a
- // volumn size. The storage must be at least MIN_FLASH_CARD_SIZE
- for us
- // to consider it to be a storage card
- res = ::GetDiskFreeSpaceEx(find.cFileName, &freeBytesAvailableToCaller,
- &totalNumberOfBytes,
- &totalNumberOfFreeBytes);
- // Only count the card if it is the correct size
- if((res == TRUE) && (totalNumberOfBytes.QuadPart >= MINIMUM_CARD_SIZE))
- {
- // Save the name of the flash card
- _tcsncpy(m_CardPath, find.cFileName, MAX_CARD_PATH);
- flashCardCount++;
- }
- }
- // Next flash card
- loop = ::FindNextFlashCard(hFlashCard, &find);
- }
- ::FindClose (hFlashCard);
- // If no flash cards were found in the enumeration, then leave
- if(flashCardCount == 0)
- {
- res = FALSE;
- }
- }
- else
- {
- // No flash cards found
- _stprintf(m_CardPath, _T("ERR: %d"), ::GetLastError());
- res = FALSE;
- }
- return res;
- }
- //------------------------------------------------------------------------------
- //
- // Get the flash card serial number and save in passed in buffer.
- //
- //------------------------------------------------------------------------------
- BOOL CFlashCard::getSerialNumber(TCHAR* buf, UINT bufLength)
- {
- // These values are only defined in Platform Builder, so we have to
- // redefine them here
- #define IOCTL_DISK_BASE FILE_DEVICE_DISK
- #define IOCTL_DISK_GET_STORAGEID CTL_CODE(IOCTL_DISK_BASE, 0x709, /
- METHOD_BUFFERED, FILE_ANY_ACCESS)
- #define MANUFACTUREID_INVALID 0x01
- #define SERIALNUM_INVALID 0x02
- // This structure is only defined in Platform Builder, so we have to
- // redefine it here
- typedef struct _STORAGE_IDENTIFICATION
- {
- DWORD dwSize;
- DWORD dwFlags;
- DWORD dwManufactureIDOffest;
- DWORD dwSerialNumOffset;
- } STORAGE_IDENTIFICATION, *PSTORAGE_IDENTIFICATION;
- const UINT BBUF_LENGTH = 256;
- const UINT STR_LENGTH = 256;
- const UINT SERIAL_NUMBER_LENGTH = 8;
- BOOL res = TRUE;
- byte bbuf[BBUF_LENGTH];
- TCHAR str[STR_LENGTH];
- STORAGE_IDENTIFICATION* si;
- HANDLE hCard = NULL;
- ULONG dwNumReturned = 0;
- ULONG err = 0;
- // Make sure a card is inserted and found before attempting to read
- // the serial number
- if(isCardAvailable() == TRUE)
- {
- // Clear the buffer
- memset(bbuf, 0, BBUF_LENGTH);
- // Clear the buffer
- memset(buf, 0, bufLength * sizeof(TCHAR));
- // Set a STORAGE_IDENTIFICATION pointer to the buffer (overlaying the
- structure)
- si = (STORAGE_IDENTIFICATION*)bbuf;
- // Create the volume name of the flash card
- _stprintf(str, _T("//%s//Vol:"), m_CardPath);
- // Get a handle to the flash card (drive) volume
- hCard = ::CreateFile(str, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
- // Set the size element of the STORAGE_IDENTIFICATION structure
- si->dwSize = BBUF_LENGTH;
- // Fill the STORAGE_IDENTIFICATION structure with the flash card info
- if(::DeviceIoControl(hCard, IOCTL_DISK_GET_STORAGEID, (LPVOID)NULL, 0,
- si, BBUF_LENGTH, &dwNumReturned, NULL) == FALSE)
- {
- err = ::GetLastError();
- res = FALSE;
- }
- // Close the handle
- ::CloseHandle (hCard);
- // See if the serial number is valid. If not, return false, otherwise
- get
- // the serial number
- if((si->dwFlags & SERIALNUM_INVALID) != SERIALNUM_INVALID)
- {
- // Get a char pointer to the serial number in the byte array
- CHAR* sn = (CHAR*)((UINT)si + si->dwSerialNumOffset);
- // Covert the CHAR serial number to a TCHAR string
- mbstowcs(buf, sn, SERIAL_NUMBER_LENGTH);
- buf[SERIAL_NUMBER_LENGTH] = 0;
- }
- else
- {
- // Serial number is not available
- _tcscpy(buf, _T("! NONE !"));
- res = FALSE;
- }
- }
- else
- {
- // No card
- _tcscpy(buf, _T("NO CARD"));
- res = FALSE;
- }
- return res;