|
|
#include "dfstpdi.h"
#include <stdio.h>
#include <winuser.h>
#include <tchar.h>
#include "cfgmgr32.h"
#include "setupapi.h"
#include "dbt.h"
#include "drvfull.h"
#include "dfhlprs.h"
#include "shellapi.h"
#define ARRAYSIZE(a) (sizeof((a))/sizeof((a)[0]))
static GUID g_guidIntfClass = {0x53f5630d, 0xb6bf, 0x11d0, {0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b}};
static HDEVINFO g_hdevinfo = NULL;
_sFLAG_DESCR _SPDID_FD[] = { FLAG_DESCR(SPINT_ACTIVE), FLAG_DESCR(SPINT_DEFAULT), FLAG_DESCR(SPINT_REMOVED), };
_sFLAG_DESCR _regpropFD[] = { FLAG_DESCR_COMMENT(SPDRP_DEVICEDESC, TEXT("DeviceDesc (R/W)")), FLAG_DESCR_COMMENT(SPDRP_HARDWAREID, TEXT("HardwareID (R/W)")), FLAG_DESCR_COMMENT(SPDRP_COMPATIBLEIDS, TEXT("CompatibleIDs (R/W)")), FLAG_DESCR_COMMENT(SPDRP_SERVICE, TEXT("Service (R/W)")), FLAG_DESCR_COMMENT(SPDRP_CLASS, TEXT("Class (R--tied to ClassGUID)")), FLAG_DESCR_COMMENT(SPDRP_CLASSGUID, TEXT("ClassGUID (R/W)")), FLAG_DESCR_COMMENT(SPDRP_DRIVER, TEXT("Driver (R/W)")), FLAG_DESCR_COMMENT(SPDRP_CONFIGFLAGS, TEXT("ConfigFlags (R/W)")), FLAG_DESCR_COMMENT(SPDRP_MFG, TEXT("Mfg (R/W)")), FLAG_DESCR_COMMENT(SPDRP_FRIENDLYNAME, TEXT("FriendlyName (R/W)")), FLAG_DESCR_COMMENT(SPDRP_LOCATION_INFORMATION, TEXT("LocationInformation (R/W)")), FLAG_DESCR_COMMENT(SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, TEXT("PhysicalDeviceObjectName (R)")), FLAG_DESCR_COMMENT(SPDRP_CAPABILITIES, TEXT("Capabilities (R)")), FLAG_DESCR_COMMENT(SPDRP_UI_NUMBER, TEXT("UiNumber (R)")), FLAG_DESCR_COMMENT(SPDRP_UPPERFILTERS, TEXT("UpperFilters (R/W)")), FLAG_DESCR_COMMENT(SPDRP_LOWERFILTERS, TEXT("LowerFilters (R/W)")), FLAG_DESCR_COMMENT(SPDRP_BUSTYPEGUID, TEXT("BusTypeGUID (R)")), FLAG_DESCR_COMMENT(SPDRP_LEGACYBUSTYPE, TEXT("LegacyBusType (R)")), FLAG_DESCR_COMMENT(SPDRP_BUSNUMBER, TEXT("BusNumber (R)")), FLAG_DESCR_COMMENT(SPDRP_ENUMERATOR_NAME, TEXT("Enumerator Name (R)")), FLAG_DESCR_COMMENT(SPDRP_SECURITY, TEXT("Security (R/W, binary form)")), FLAG_DESCR_COMMENT(SPDRP_SECURITY_SDS, TEXT("Security (W, SDS form)")), FLAG_DESCR_COMMENT(SPDRP_DEVTYPE, TEXT("Device Type (R/W)")), FLAG_DESCR_COMMENT(SPDRP_EXCLUSIVE, TEXT("Device is exclusive-access (R/W)")), FLAG_DESCR_COMMENT(SPDRP_CHARACTERISTICS, TEXT("Device Characteristics (R/W)")), FLAG_DESCR_COMMENT(SPDRP_ADDRESS, TEXT("Device Address (R)")), FLAG_DESCR_COMMENT(SPDRP_UI_NUMBER_DESC_FORMAT, TEXT("UiNumberDescFormat (R/W)")), FLAG_DESCR_COMMENT(SPDRP_MAXIMUM_PROPERTY, TEXT("Upper bound on ordinals")), };
HRESULT _PrintDetailed(DWORD dwFlags[], DWORD cchIndent, HDEVINFO hdevinfo, SP_DEVINFO_DATA* pdevinfo, SP_DEVICE_INTERFACE_DATA* pspdid, SP_DEVICE_INTERFACE_DETAIL_DATA* pspdidd) { HRESULT hres = S_OK;
if (_IsFlagSet(MOD_FULLREPORT1, dwFlags)) { _PrintIndent(cchIndent + 2); _tprintf(TEXT("Registry properties (SetupDiGetDeviceRegistryProperty):\n")); _PrintIndent(cchIndent + 2); _tprintf(TEXT("{\n"));
TCHAR szTest[1024]; if (SetupDiGetDeviceRegistryProperty(hdevinfo, pdevinfo, SPDRP_FRIENDLYNAME, NULL, (PBYTE)szTest, ARRAYSIZE(szTest) * sizeof(TCHAR), NULL)) { _PrintIndent(cchIndent + 4); _tprintf(TEXT("%s ("), szTest);
_PrintFlag(SPDRP_FRIENDLYNAME, _regpropFD, ARRAYSIZE(_regpropFD), 0, FALSE, FALSE, TRUE, FALSE); _tprintf(TEXT(")\n")); }
if (SetupDiGetDeviceRegistryProperty(hdevinfo, pdevinfo, SPDRP_DEVICEDESC, NULL, (PBYTE)szTest, ARRAYSIZE(szTest) * sizeof(TCHAR), NULL)) { _PrintIndent(cchIndent + 4); _tprintf(TEXT("%s ("), szTest);
_PrintFlag(SPDRP_DEVICEDESC, _regpropFD, ARRAYSIZE(_regpropFD), 0, FALSE, FALSE, TRUE, FALSE); _tprintf(TEXT(")\n")); } _PrintIndent(cchIndent + 2); _tprintf(TEXT("}\n")); }
if (_IsFlagSet(MOD_FULLREPORT2, dwFlags)) { _PrintCR(); _PrintIndent(cchIndent + 2); _tprintf(TEXT("SP_DEVICE_INTERFACE_DATA\n")); _PrintIndent(cchIndent + 2); _tprintf(TEXT("{\n")); _PrintIndent(cchIndent + 4); _PrintGUID(&(pspdid->InterfaceClassGuid)); _tprintf(TEXT(" (GUID InterfaceClassGuid)\n")); _PrintFlag(pspdid->Flags, _SPDID_FD, ARRAYSIZE(_SPDID_FD), cchIndent + 4, TRUE, TRUE, FALSE, FALSE); _tprintf(TEXT(" (DWORD Flags)\n")); _PrintIndent(cchIndent + 2); _tprintf(TEXT("}\n"));
_PrintIndent(cchIndent + 2); _tprintf(TEXT("SP_DEVINFO_DATA\n")); _PrintIndent(cchIndent + 2); _tprintf(TEXT("{\n")); _PrintIndent(cchIndent + 4); _PrintGUID(&(pdevinfo->ClassGuid)); _tprintf(TEXT(" (GUID ClassGuid)\n")); _PrintIndent(cchIndent + 4); _tprintf(TEXT("%u (DWORD DevInst)\n"), pdevinfo->DevInst); _PrintIndent(cchIndent + 2); _tprintf(TEXT("}\n"));
_PrintIndent(cchIndent + 2); _tprintf(TEXT("SP_DEVICE_INTERFACE_DETAIL_DATA\n")); _PrintIndent(cchIndent + 2); _tprintf(TEXT("{\n"));
DWORD cch = lstrlen(pspdidd->DevicePath);
for (DWORD dw = 0; dw < cch; dw += 80) { TCHAR sz[81];
if (dw && (dw < cch)) { _tprintf(TEXT("...\n")); }
lstrcpyn(sz, pspdidd->DevicePath + dw, ARRAYSIZE(sz));
_PrintIndent(cchIndent + 4); _tprintf(sz); }
_PrintIndent(cchIndent + 4); _tprintf(TEXT(" (TCHAR DevicePath)\n")); _PrintIndent(cchIndent + 2); _tprintf(TEXT("}\n")); }
return hres; }
extern int g_argc; extern wchar_t** g_argv;
// drvfull -pnpcs <deviceID> <Property>
HRESULT _CustomProperty(DWORD dwFlags[], LPWSTR , DWORD cchIndent) { HRESULT hr;
HDEVINFO hdevinfo = SetupDiCreateDeviceInfoList(NULL, NULL);
if (INVALID_HANDLE_VALUE != hdevinfo) { SP_DEVINFO_DATA sdd = {0}; sdd.cbSize = sizeof(sdd);
if ((TEXT('\\') == g_argv[2][0]) && (TEXT('\\') == g_argv[2][1]) && (TEXT('?') == g_argv[2][2]) && (TEXT('\\') == g_argv[2][3])) { SP_DEVICE_INTERFACE_DATA sdid = {0};
sdid.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if (SetupDiOpenDeviceInterface(hdevinfo, (LPCWSTR)g_argv[2], 0, &sdid)) { DWORD cbsdidd = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_DEVICE_ID_LEN * sizeof(WCHAR));
SP_DEVICE_INTERFACE_DETAIL_DATA* psdidd = (SP_DEVICE_INTERFACE_DETAIL_DATA*)LocalAlloc(LPTR, cbsdidd);
if (psdidd) { psdidd->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
// SetupDiGetDeviceInterfaceDetail (below) requires that the
// cbSize member of SP_DEVICE_INTERFACE_DETAIL_DATA be set
// to the size of the fixed part of the structure, and to pass
// the size of the full thing as the 4th param.
if (SetupDiGetDeviceInterfaceDetail(hdevinfo, &sdid, psdidd, cbsdidd, NULL, &sdd)) { hr = S_OK; }
LocalFree((HLOCAL)psdidd); } } } else { if (SetupDiOpenDeviceInfo(hdevinfo, (LPCWSTR)g_argv[2], NULL, 0, &sdd)) { hr = S_OK; }
}
if (SUCCEEDED(hr)) { WCHAR szTestProp[512];
if (SetupDiGetCustomDeviceProperty(hdevinfo, &sdd, (LPCWSTR)g_argv[3], 0, NULL, (PBYTE)szTestProp, ARRAYSIZE(szTestProp), NULL)) { _PrintIndent(cchIndent + 4); _tprintf(TEXT("%s = %s"), (LPCWSTR)g_argv[3], szTestProp); } }
SetupDiDestroyDeviceInfoList(hdevinfo); }
return hr; }
HRESULT _EnumDevices(DWORD dwFlags[], HDEVINFO hdevinfo, SP_DEVINFO_DATA* pdevinfoConstraint, CONST GUID *pguidIntfClass, DWORD cchIndent) { HRESULT hres = E_FAIL; SP_DEVICE_INTERFACE_DATA spdid = {0}; SP_DEVICE_INTERFACE_DETAIL_DATA* pspdidd = NULL; SP_DEVINFO_DATA devinfo = {0}; DWORD cbspdidd = 0;
devinfo.cbSize = sizeof(devinfo); spdid.cbSize = sizeof(spdid);
for (DWORD dw = 0; SetupDiEnumDeviceInterfaces(hdevinfo, pdevinfoConstraint, pguidIntfClass, dw, &spdid); ++dw) { DWORD dwReqSize;
hres = S_OK;
// To retrieve the device interface name (e.g., that you can call
// CreateFile() on...
while (SUCCEEDED(hres) && !SetupDiGetDeviceInterfaceDetail(hdevinfo, &spdid, pspdidd, cbspdidd, &dwReqSize, &devinfo)) { // We failed to get the device interface detail data--was it because
// our buffer was too small? (Hopefully so!)
DWORD dwErr = GetLastError();
if (pspdidd) { free(pspdidd); pspdidd = NULL; }
if (ERROR_INSUFFICIENT_BUFFER == dwErr) { // We failed due to insufficient buffer. Allocate one that's
// sufficiently large and try again.
pspdidd = (SP_DEVICE_INTERFACE_DETAIL_DATA*)malloc(dwReqSize);
if (pspdidd) { cbspdidd = dwReqSize; pspdidd->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); } else { // Failure!
cbspdidd = 0;
_PrintIndent(cchIndent); _tprintf(TEXT("Not enough memory\n"));
hres = E_OUTOFMEMORY; break; } } else { // Failure!
_PrintIndent(cchIndent); _tprintf(TEXT("SetupDiGetDeviceInterfaceDetail failed\n"));
_PrintGetLastError(cchIndent); hres = E_FAIL; break; } }
if (SUCCEEDED(hres)) { if (!pdevinfoConstraint) { BOOL bResult; TCHAR szDeviceName[MAX_PATH]; TCHAR szVolumeName[MAX_PATH * 2];
lstrcpy(szDeviceName, pspdidd->DevicePath); lstrcat(szDeviceName, TEXT("\\"));
bResult = GetVolumeNameForVolumeMountPoint(szDeviceName, szVolumeName, MAX_PATH);
if (bResult) { _PrintCR(); _PrintIndent(cchIndent + 2); _tprintf(TEXT("--------------------------------------------")\ TEXT("--------------------------\n")); _PrintIndent(cchIndent + 2); _tprintf(TEXT("-- Volume name: '%s'\n"), szVolumeName); } }
if (_IsFlagSet(MOD_FULLREPORTFULL, dwFlags)) { hres = _PrintDetailed(dwFlags, cchIndent, hdevinfo, &devinfo, &spdid, pspdidd); }
/* if (!pdevinfoConstraint)
{ GUID guidUSB = {0x36fc9e60, 0xc465, 0x11cf, {0x80, 0x56, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};
hres = _EnumDevices(dwFlags, hdevinfo, &devinfo, &guidUSB, cchIndent + 2); }*/ } }
if (pspdidd) { free(pspdidd); }
return hres; }
HRESULT _InitNotifSetupDI(DWORD dwFlags[], DWORD cchIndent) { HRESULT hres = S_OK;
// Create a device information set that will be the container for our
// device interfaces.
g_hdevinfo = SetupDiCreateDeviceInfoList(NULL, NULL);
if (INVALID_HANDLE_VALUE != g_hdevinfo) { // OK, now we can retrieve the existing list of active device
// interfaces into the device information set we created above.
HDEVINFO hdevinfo = SetupDiGetClassDevsEx(&g_guidIntfClass, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE, g_hdevinfo, NULL, NULL);
if (INVALID_HANDLE_VALUE != hdevinfo) { // If SetupDiGetClassDevsEx succeeds and it was passed in an
// existing device information set to be used, then the HDEVINFO
// it returns is the same as the one it was passed in. Thus, we
// can just use the original DeviceInfoSet handle from here on.
// Now fill in our listbox with the current device interface list.
hres = _EnumDevices(dwFlags, g_hdevinfo, NULL, &g_guidIntfClass, cchIndent);
if (FAILED(hres)) { _PrintGetLastError(cchIndent); } } else { _PrintIndent(cchIndent); _tprintf(TEXT("SetupDiGetClassDevsEx failed\n"));
_PrintGetLastError(cchIndent); hres = E_FAIL; } } else { _PrintIndent(cchIndent); _tprintf(TEXT("SetupDiCreateDeviceInfoList failed\n"));
_PrintGetLastError(cchIndent); hres = E_FAIL; }
return hres; }
HRESULT _CleanupSetupDI() { if (g_hdevinfo) { SetupDiDestroyDeviceInfoList(g_hdevinfo); }
return S_OK; }
HRESULT _HandleNotifSetupDI(DWORD dwFlags[], DWORD cchIndent, WPARAM wParam, LPARAM lParam) { HRESULT hres = E_FAIL; SP_DEVICE_INTERFACE_DATA spdid = {0}; DEV_BROADCAST_DEVICEINTERFACE* pdbdi;
if (DBT_DEVTYP_DEVICEINTERFACE == ((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype) { pdbdi = (DEV_BROADCAST_DEVICEINTERFACE*)lParam;
if (DBT_DEVICEARRIVAL == wParam) { // Open this new device interface into our device information set.
if (!SetupDiOpenDeviceInterface(g_hdevinfo, pdbdi->dbcc_name, 0, NULL)) { _PrintIndent(cchIndent + 2); _tprintf(TEXT("SetupDiOpenDeviceInterface failed\n")); _PrintGetLastError(cchIndent + 2); _PrintCR(); } } else { // First, locate this device interface in our device information set.
spdid.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if (SetupDiOpenDeviceInterface(g_hdevinfo, pdbdi->dbcc_name, DIODI_NO_ADD, &spdid)) { if (!SetupDiDeleteDeviceInterfaceData(g_hdevinfo, &spdid)) { _PrintIndent(cchIndent + 2); _tprintf(TEXT("SetupDiDeletespdid failed\n")); _PrintGetLastError(cchIndent + 2); _PrintCR(); } } else { _PrintIndent(cchIndent + 2); _tprintf(TEXT("SetupDiOpenDeviceInterface failed\n")); _PrintGetLastError(cchIndent + 2); _PrintCR(); } } }
hres = _EnumDevices(dwFlags, g_hdevinfo, NULL, &g_guidIntfClass, cchIndent);
return hres; }
|