Created
April 26, 2012 13:19
-
-
Save gabonator/2499496 to your computer and use it in GitHub Desktop.
USB enumerating tools
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "usb.h" | |
#ifndef DISABLE_USB | |
#pragma comment(lib, "setupapi.lib") | |
#include "SetupAPI.h" | |
#include "cfgmgr32.h" | |
#pragma pack(4) | |
DEFINE_GUID(GUID_DEVINTERFACE_VOLUME, | |
00110 0x53f5630dL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b); | |
bool RemovableScanDisks(CArray <stDriveVolume, stDriveVolume> &arrDrives) | |
{ | |
WCHAR caDrive[4] = _T("A:\\"); | |
WCHAR volume[1024]; | |
DWORD dwDriveMask; | |
// Get all drives in the system. | |
dwDriveMask = GetLogicalDrives(); | |
if(dwDriveMask == 0) | |
return false; | |
// Loop for all drives (MAX_DRIVES = 26) | |
for(; dwDriveMask; dwDriveMask >>= 1, caDrive[0]++) | |
{ | |
// if a drive is present, | |
if(dwDriveMask & 1) | |
{ | |
// If a drive is removable | |
if(GetDriveType(caDrive) == DRIVE_REMOVABLE) | |
//Get its volume info and store it in the global variable. | |
if(GetVolumeNameForVolumeMountPoint(caDrive, volume, 1024)) | |
arrDrives.Add( stDriveVolume( caDrive[0], volume )); | |
} | |
} | |
return true; | |
} | |
bool RemovableFillInfo( CArray <stDriveVolume, stDriveVolume> &arrDrives ) | |
{ | |
HDEVINFO hDevInfo; | |
GUID guid; | |
BYTE buffer[1024]; | |
DWORD dwRequiredSize ; | |
WCHAR buf[1024]; | |
DEVINST devInstParent; | |
DWORD dwIndex; | |
WCHAR volume[1024]; | |
int nLength; | |
SP_DEVICE_INTERFACE_DATA devInterfaceData; | |
SP_DEVINFO_DATA devInfoData; | |
PSP_DEVICE_INTERFACE_DETAIL_DATA pDevDetail; | |
// GUID_DEVINTERFACE_VOLUME is interface Guid for Volume class devices. | |
guid = GUID_DEVINTERFACE_VOLUME; | |
// Get device Information handle for Volume interface | |
hDevInfo = SetupDiGetClassDevs(&guid, NULL, NULL, | |
/*DIGCF_ALLCLASSES | */ | |
DIGCF_DEVICEINTERFACE | | |
DIGCF_PRESENT); | |
if(hDevInfo == INVALID_HANDLE_VALUE) | |
return false; | |
SP_DEVINFO_DATA* pspDevInfoData = | |
(SP_DEVINFO_DATA*)HeapAlloc(GetProcessHeap(), 0, sizeof(SP_DEVINFO_DATA)); | |
pspDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA); | |
/* | |
for(int i=0; SetupDiEnumDeviceInfo(hDevInfo,i,pspDevInfoData); i++) | |
{ | |
char buf[1024]; | |
DWORD nSize; | |
if ( SetupDiGetDeviceInstanceIdA(hDevInfo, pspDevInfoData, buf, sizeof(buf), &nSize) ) | |
{ | |
DWORD DataT; | |
if ( SetupDiGetDeviceRegistryPropertyA(hDevInfo, pspDevInfoData, | |
SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, sizeof(buf), &nSize) ) | |
{ | |
int f = 9; | |
OutputDebugStringA( "friendlyname: " ); | |
OutputDebugStringA( buf ); | |
OutputDebugStringA( "\n" ); | |
} | |
if ( SetupDiGetDeviceRegistryPropertyA(hDevInfo, pspDevInfoData, | |
SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize) ) | |
{ | |
OutputDebugStringA( "devicedesc: " ); | |
OutputDebugStringA( buf ); | |
OutputDebugStringA( "\n" ); | |
} | |
} | |
} | |
*/ | |
// Loop until device interfaces are found. | |
for(dwIndex = 0; ; dwIndex ++) | |
{ | |
ZeroMemory(&devInterfaceData, sizeof(devInterfaceData)); | |
devInterfaceData.cbSize = sizeof(devInterfaceData); | |
// Get device Interface data. | |
if(!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &guid, dwIndex, &devInterfaceData)) | |
break; | |
ZeroMemory(&devInfoData, sizeof(devInfoData)); | |
devInfoData.cbSize = sizeof(devInfoData); | |
pDevDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)buffer; | |
pDevDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); | |
// Get device interface detail data to get | |
// Device Instance from SP_DEVINFO_DATA and | |
// Device Path from SP_DEVICE_INTERFACE_DETAIL_DATA | |
SetupDiGetDeviceInterfaceDetail(hDevInfo, | |
&devInterfaceData, | |
pDevDetail, // SP_DEVICE_INTERFACE_DETAIL_DATA | |
1024, | |
&dwRequiredSize, | |
&devInfoData); // SP_DEVINFO_DATA | |
/* | |
char buf[1024]; | |
DWORD nSize; | |
if ( SetupDiGetDeviceInstanceIdA(hDevInfo, &devInfoData, buf, sizeof(buf), &nSize) ) | |
{ | |
OutputDebugStringA( buf ); | |
OutputDebugStringA( " " ); | |
DWORD DataT; | |
if ( SetupDiGetDeviceRegistryPropertyA(hDevInfo, &devInfoData, | |
SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, sizeof(buf), &nSize) ) | |
{ | |
OutputDebugStringA( buf ); | |
OutputDebugStringA( " " ); | |
} else if ( SetupDiGetDeviceRegistryPropertyA(hDevInfo, &devInfoData, | |
SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize) ) | |
{ | |
OutputDebugStringA( buf ); | |
OutputDebugStringA( " " ); | |
} | |
OutputDebugStringA( "\n" ); | |
} | |
*/ | |
// Get the device instance of parent. This points to USBSTOR. | |
CM_Get_Parent(&devInstParent,devInfoData.DevInst, 0); | |
// Get the device instance of grand parent. This points to USB root. | |
CM_Get_Parent(&devInstParent,devInstParent, 0); | |
// Get the device ID of the USB root. | |
CM_Get_Device_ID(devInstParent, buf, 1024, 0); | |
// If USB root device matches with the input device ID, it is the target | |
// device. | |
if( buf != NULL /*&& wcscmp(lpDevID,buf) == 0*/ ) | |
{ | |
// Append \ to the DevicePath of SP_DEVICE_INTERFACE_DETAIL_DATA | |
nLength = (int)wcslen(pDevDetail->DevicePath); | |
pDevDetail->DevicePath[nLength] = '\\'; | |
pDevDetail->DevicePath[nLength+1] = 0; | |
// Get Volume mount point for the device path. | |
if(GetVolumeNameForVolumeMountPoint(pDevDetail->DevicePath, volume, 1024)) | |
{ | |
// Compare volume mount point with the one stored earlier. | |
// If both match, return the corresponding drive letter. | |
for(int nLoopIndex=0; nLoopIndex < arrDrives.GetSize(); nLoopIndex++) | |
if ( arrDrives[nLoopIndex].strFriendlyProduct.IsEmpty() ) | |
if(wcscmp(arrDrives[nLoopIndex].strVolume, volume)==0) | |
{ | |
CString strBuffer( buf ); | |
int nVid = strBuffer.Find(_T("VID_")); | |
int nPid = strBuffer.Find(_T("PID_")); | |
if ( nVid == -1 || nPid == -1 ) | |
continue; | |
int nVidE = strBuffer.Find(_T("&"), nVid); | |
int nPidE = strBuffer.Find(_T("\\"), nPid); | |
if ( nVidE == -1 || nPidE == -1 ) | |
{ | |
continue; | |
} | |
arrDrives[nLoopIndex].strFriendlyProduct = strBuffer.Mid(nVid+4, nVidE-nVid-4); | |
arrDrives[nLoopIndex].strFriendlyVendor = strBuffer.Mid(nPid+4, nPidE-nPid-4); | |
arrDrives[nLoopIndex].strDevicePath = CString(pDevDetail->DevicePath); | |
} | |
} | |
} | |
} | |
SetupDiDestroyDeviceInfoList(hDevInfo); | |
return true; | |
} | |
static const GUID guidDISK = | |
{ | |
0x53f56307, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } | |
}; | |
#include "fscommands.h" | |
// http://www.codeproject.com/KB/system/RemoveDriveByLetter.aspx | |
CString GetDevicePathByDeviceNumber(long DeviceNumber, UINT DriveType, char* szDosDeviceName) | |
{ | |
bool IsFloppy = (strstr(szDosDeviceName, "\\Floppy") != NULL); // is there a better way? | |
GUID* guid; | |
switch (DriveType) { | |
case DRIVE_REMOVABLE: | |
if ( IsFloppy ) { | |
guid = (GUID*)&GUID_DEVINTERFACE_FLOPPY; | |
} else { | |
guid = (GUID*)&GUID_DEVINTERFACE_DISK; | |
} | |
break; | |
case DRIVE_FIXED: | |
guid = (GUID*)&GUID_DEVINTERFACE_DISK; | |
break; | |
case DRIVE_CDROM: | |
guid = (GUID*)&GUID_DEVINTERFACE_CDROM; | |
break; | |
default: | |
return _T(""); | |
} | |
// Get device interface info set handle | |
// for all devices attached to system | |
HDEVINFO hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL, | |
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); | |
if (hDevInfo == INVALID_HANDLE_VALUE) { | |
return _T(""); | |
} | |
// Retrieve a context structure for a device interface | |
// of a device information set. | |
DWORD dwIndex = 0; | |
BOOL bRet = FALSE; | |
BYTE Buf[1024]; | |
PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd = | |
(PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf; | |
SP_DEVICE_INTERFACE_DATA spdid; | |
SP_DEVINFO_DATA spdd; | |
DWORD dwSize; | |
spdid.cbSize = sizeof(spdid); | |
while ( true ) { | |
bRet = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, | |
guid, dwIndex, &spdid); | |
if (!bRet) { | |
break; | |
} | |
dwSize = 0; | |
SetupDiGetDeviceInterfaceDetail(hDevInfo, | |
&spdid, NULL, 0, &dwSize, NULL); | |
if ( dwSize!=0 && dwSize<=sizeof(Buf) ) { | |
pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes! | |
ZeroMemory((PVOID)&spdd, sizeof(spdd)); | |
spdd.cbSize = sizeof(spdd); | |
long res = | |
SetupDiGetDeviceInterfaceDetail(hDevInfo, & | |
spdid, pspdidd, | |
dwSize, &dwSize, | |
&spdd); | |
if ( res ) { | |
HANDLE hDrive = CreateFile(pspdidd->DevicePath,0, | |
FILE_SHARE_READ | FILE_SHARE_WRITE, | |
NULL, OPEN_EXISTING, NULL, NULL); | |
if ( hDrive != INVALID_HANDLE_VALUE ) { | |
STORAGE_DEVICE_NUMBER sdn; | |
DWORD dwBytesReturned = 0; | |
res = DeviceIoControl(hDrive, | |
IOCTL_STORAGE_GET_DEVICE_NUMBER, | |
NULL, 0, &sdn, sizeof(sdn), | |
&dwBytesReturned, NULL); | |
if ( res ) { | |
if ( DeviceNumber == (long)sdn.DeviceNumber ) { | |
CloseHandle(hDrive); | |
SetupDiDestroyDeviceInfoList(hDevInfo); | |
return CString(pspdidd->DevicePath); | |
} | |
} | |
CloseHandle(hDrive); | |
} | |
} | |
} | |
dwIndex++; | |
} | |
SetupDiDestroyDeviceInfoList(hDevInfo); | |
return _T(""); | |
} | |
bool RemovableFriendlyName( stDriveVolume &volDrive ) | |
{ | |
// "\\\\.\\X:" | |
// "\\\\\?\\Volume{3dd04400-bdaa-11da-af8e-806d6172696f}" | |
CString strDevice; | |
strDevice.Format(_T("\\\\.\\%c:"), toupper(volDrive.chDrive)); | |
//strDevice = volDrive.strVolume.Left( volDrive.strVolume.GetLength()-1 ); | |
HANDLE hDevice = CreateFile(strDevice, | |
GENERIC_READ | GENERIC_WRITE, | |
FILE_SHARE_READ | FILE_SHARE_WRITE, | |
NULL, OPEN_EXISTING, NULL, NULL); | |
if ( hDevice == NULL || hDevice == INVALID_HANDLE_VALUE ) | |
return false; | |
DWORD dwOutBytes = 0; | |
STORAGE_PROPERTY_QUERY Query; | |
Query.PropertyId = StorageDeviceProperty; | |
Query.QueryType = PropertyStandardQuery; | |
char Buf[1024] = {0}; | |
PSTORAGE_DEVICE_DESCRIPTOR pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)Buf; | |
pDevDesc->Size = sizeof(Buf); | |
BOOL res = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &Query, | |
sizeof(STORAGE_PROPERTY_QUERY), pDevDesc, pDevDesc->Size, &dwOutBytes, (LPOVERLAPPED)NULL); | |
if (!res) | |
{ | |
CloseHandle(hDevice); | |
return false; | |
} | |
if (pDevDesc->VendorIdOffset != 0) | |
volDrive.strFriendlyVendor = CString( (PCHAR)((PBYTE)pDevDesc + pDevDesc->VendorIdOffset) ); | |
if (pDevDesc->ProductIdOffset != 0) | |
volDrive.strFriendlyProduct = CString( (PCHAR)((PBYTE)pDevDesc + pDevDesc->ProductIdOffset) ); | |
STORAGE_DEVICE_NUMBER deviceNumber; | |
res = DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, | |
NULL, 0, &deviceNumber, sizeof(deviceNumber), &dwOutBytes, (LPOVERLAPPED)NULL); | |
CloseHandle(hDevice); | |
if (!res) | |
return false; | |
char szDosDeviceName[MAX_PATH]; | |
char szDevicePath[] = "X:\\"; | |
szDevicePath[0] = toupper(volDrive.chDrive); | |
UINT DriveType = GetDriveTypeA(szDevicePath); | |
szDevicePath[2] = 0; | |
res = QueryDosDeviceA(szDevicePath, szDosDeviceName, MAX_PATH); | |
volDrive.strDevicePath = CString(szDosDeviceName); | |
volDrive.strDevice = GetDevicePathByDeviceNumber(deviceNumber.DeviceNumber, DriveType, szDosDeviceName); | |
//wprintf(_T("dev number = %d, drive type = %d, dos driver = %S\nDEVICE=%s\n"), deviceNumber.DeviceNumber, DriveType, szDosDeviceName, strDevPath); | |
return true; | |
} | |
bool RemovableEnumerate(CArray <stDriveVolume, stDriveVolume> &arrDrives) | |
{ | |
// TCHAR strLabel[MAX_PATH] = {0}; | |
// TCHAR strDrive[4] = {'?', ':', '\\'}; | |
// DWORD dwSerial; | |
if ( !RemovableScanDisks( arrDrives ) ) | |
return false; | |
for (int i=0; i<arrDrives.GetSize(); i++) | |
// { | |
RemovableFriendlyName( arrDrives[i] ); | |
// strDrive[0] = tolower(arrDrives[i].chDrive); | |
// if ( GetVolumeInformation(strDrive, strLabel, sizeof(strLabel), &dwSerial, NULL, NULL, NULL, 0) ) | |
// arrDrives[i].strLabel = CString( strLabel ); | |
// } | |
// only XP compatible, catches problematic devices without VID/PID | |
RemovableFillInfo( arrDrives ); | |
return true; | |
for (int i=0; i<arrDrives.GetSize(); i++) | |
{ | |
CString strDebug; | |
strDebug.Format(_T("drive=%c:\nvolume=%s\ndevice=%s\nvendor=%s\nproduct=%s\ndevpath=%s\nlabel=%s"), | |
arrDrives[i].chDrive, | |
arrDrives[i].strVolume, | |
arrDrives[i].strDevice, | |
arrDrives[i].strFriendlyVendor, | |
arrDrives[i].strFriendlyProduct, | |
arrDrives[i].strDevicePath, | |
arrDrives[i].strLabel); | |
MessageBox( NULL, strDebug, _T("debug info"), 0 ); | |
} | |
return true; | |
} | |
#else | |
bool RemovableEnumerate(CArray <stDriveVolume, stDriveVolume> &arrDrives) | |
{ | |
return false; | |
} | |
//} | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//#define DISABLE_USB | |
#include "_mfc.h" | |
struct stDriveVolume | |
{ | |
stDriveVolume() | |
{ | |
} | |
stDriveVolume( WCHAR _chDrive, CString _strVolume ) | |
{ | |
chDrive = _chDrive; | |
strVolume = _strVolume; | |
} | |
const stDriveVolume& operator=(const stDriveVolume& child) | |
{ | |
chDrive = child.chDrive; | |
strVolume = child.strVolume; | |
strDevice = child.strDevice; | |
strDevicePath = child.strDevicePath; | |
strFriendlyVendor = child.strFriendlyVendor; | |
strFriendlyProduct = child.strFriendlyProduct; | |
strLabel = child.strLabel; | |
return *this; | |
} | |
WCHAR chDrive; | |
CString strVolume; | |
CString strDevice; | |
CString strFriendlyVendor; | |
CString strFriendlyProduct; | |
CString strDevicePath; | |
CString strLabel; | |
}; | |
bool RemovableEnumerate(CArray <stDriveVolume, stDriveVolume> &arrDrives); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment