星期二, 8月 19, 2008

Identify USB/IDE/SD Mass Storage Device (Disk Drivers)

Mass Storage Device會被認成是一個Disk,如果要知道這顆Disk是屬於USB或是SATA/IDE Interface,透過標準C Library或是File Management或是Disk Management都無法得知,這些資訊被隱藏起來了。

我寫了一個C++ Class利用Windows Setup API取得系統內有幾個USB Type的Disk。如要判斷是否為Secure Digital或是IDE可自行另行判斷。

massstorage.h

#pragma once

/**
This is the Mass Storage Device Class Library.

Support Help Function to Mass Storage Class.
*/
class CMassStorage
{
public:
CMassStorage(void);
~CMassStorage(void);
/**
Identify a volumn name is exist or not.
\param volname input volumn name
\return true if exist, 0 do not exist.
*/
int isVolumnNameExist(const CString & volname);
/**
Overloaded help function, to supply more argument
\param volman to be identify
\param drv driver letter if the identified voluman exist.
\return true if exist, 0 do not exist.
*/
int isVolumnNameExist(const CString & volname, CString & drv);
int getUSBMsc(void);
};




massstroage.cpp

#include "StdAfx.h"
#include "MassStorage.h"

#include
#include
#include

CMassStorage::CMassStorage(void)
{
}

CMassStorage::~CMassStorage(void)
{
}


int CMassStorage::isVolumnNameExist(const CString & volname)
{
CString dummyDrv;
return isVolumnNameExist(volname, dummyDrv);
}

int CMassStorage::isVolumnNameExist(const CString & volname, CString & drv)
{
TCHAR disk[MAX_PATH]= _T("C:\\");
TCHAR drvltr; // driver letter
TCHAR buf[MAX_PATH];

// scan the disk from C to Z
for (drvltr = 'C'; drvltr <= 'Z'; drvltr++) {
disk[0] = drvltr;
DWORD dummy;
if (GetVolumeInformation(disk, buf, MAX_PATH, &dummy, &dummy, &dummy, NULL, 0)) {
// the driver exist, check the logical volname.
if (volname.CompareNoCase(buf) == 0) {
drv = disk;
return TRUE;
}
}
}
return FALSE;
}

/**
Return the USB mass storage device number
If there are any errors, the returned USB number is still 0.
This function check the device identify if prefixed by "USBSTOR"
\return number of USB mass storage device.
*/

/**
For other GuidClass, search Microsoft for "System-Supplied Device Setup Classes"
*/
DEFINE_GUID(driverGuidConst, 0x4d36e967, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18);


int CMassStorage::getUSBMsc(void)
{
HDEVINFO hdevinfo;
GUID driverGuid = driverGuidConst;
int nousb = 0;
const static WCHAR USB_MASS[]=_T("USBSTORE");

// Get the device setup class handler, for disk driver.
if (INVALID_HANDLE_VALUE != (hdevinfo = SetupDiGetClassDevs(&driverGuid, NULL, NULL, DIGCF_PRESENT ))) {
// Retrieve every instance of this class.
int index = 0;
SP_DEVINFO_DATA data;
data.cbSize = sizeof(SP_DEVINFO_DATA);

while (SetupDiEnumDeviceInfo(hdevinfo, index, &data)) {
ULONG buflen;
// Get the size of device ID buffer.
if (CR_SUCCESS == CM_Get_Device_ID_Size(&buflen, data.DevInst, 0)) {
// if the device is exist, then buflen > 0.
if (buflen > 0) {
WCHAR * buf = new WCHAR[buflen];
CM_Get_Device_ID(data.DevInst, buf, buflen, 0);
if (0 == wcsncmp(USB_MASS, buf, sizeof(USB_MASS)/sizeof(WCHAR))) {
nousb++;
}
delete buf;
}
}
index++;
}
// must free the handle to device information.
SetupDiDestroyDeviceInfoList(hdevinfo);
}

return nousb;
}


沒有留言: