diff options
| author | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
|---|---|---|
| committer | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
| commit | 97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch) | |
| tree | 46f3701832d70b420eb0fc0eb93261f9da45db3f /usb/usbview/devnode.c | |
| parent | ef1905bf1e8825bb31120dfb27e0daf3154d859a (diff) | |
Initial publish
Diffstat (limited to 'usb/usbview/devnode.c')
| -rw-r--r-- | usb/usbview/devnode.c | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/usb/usbview/devnode.c b/usb/usbview/devnode.c new file mode 100644 index 00000000..6820e3d3 --- /dev/null +++ b/usb/usbview/devnode.c @@ -0,0 +1,336 @@ +/*++ + + Copyright (c) 1998-2011 Microsoft Corporation + + Module Name: + + DEVNODE.C + + --*/ + +/***************************************************************************** + I N C L U D E S + *****************************************************************************/ + +#include "uvcview.h" + +/***************************************************************************** + + DriverNameToDeviceInst() + + Finds the Device instance of the DevNode with the matching DriverName. + Returns FALSE if the matching DevNode is not found and TRUE if found + + *****************************************************************************/ +BOOL +DriverNameToDeviceInst( + _In_reads_bytes_(cbDriverName) PCHAR DriverName, + _In_ size_t cbDriverName, + _Out_ HDEVINFO *pDevInfo, + _Out_writes_bytes_(sizeof(SP_DEVINFO_DATA)) PSP_DEVINFO_DATA pDevInfoData + ) +{ + HDEVINFO deviceInfo = INVALID_HANDLE_VALUE; + BOOL status = TRUE; + ULONG deviceIndex; + SP_DEVINFO_DATA deviceInfoData; + BOOL bResult = FALSE; + PCHAR pDriverName = NULL; + PSTR buf = NULL; + BOOL done = FALSE; + + if (pDevInfo == NULL) + { + return FALSE; + } + + if (pDevInfoData == NULL) + { + return FALSE; + } + + memset(pDevInfoData, 0, sizeof(SP_DEVINFO_DATA)); + + *pDevInfo = INVALID_HANDLE_VALUE; + + // Use local string to guarantee zero termination + pDriverName = (PCHAR) ALLOC((DWORD) cbDriverName + 1); + if (NULL == pDriverName) + { + status = FALSE; + goto Done; + } + StringCbCopyN(pDriverName, cbDriverName + 1, DriverName, cbDriverName); + + // + // We cannot walk the device tree with CM_Get_Sibling etc. unless we assume + // the device tree will stabilize. Any devnode removal (even outside of USB) + // would force us to retry. Instead we use Setup API to snapshot all + // devices. + // + + // Examine all present devices to see if any match the given DriverName + // + deviceInfo = SetupDiGetClassDevs(NULL, + NULL, + NULL, + DIGCF_ALLCLASSES | DIGCF_PRESENT); + + if (deviceInfo == INVALID_HANDLE_VALUE) + { + status = FALSE; + goto Done; + } + + deviceIndex = 0; + deviceInfoData.cbSize = sizeof(deviceInfoData); + + while (done == FALSE) + { + // + // Get devinst of the next device + // + + status = SetupDiEnumDeviceInfo(deviceInfo, + deviceIndex, + &deviceInfoData); + + deviceIndex++; + + if (!status) + { + // + // This could be an error, or indication that all devices have been + // processed. Either way the desired device was not found. + // + + done = TRUE; + break; + } + + // + // Get the DriverName value + // + + bResult = GetDeviceProperty(deviceInfo, + &deviceInfoData, + SPDRP_DRIVER, + &buf); + + // If the DriverName value matches, return the DeviceInstance + // + if (bResult == TRUE && buf != NULL && _stricmp(pDriverName, buf) == 0) + { + done = TRUE; + *pDevInfo = deviceInfo; + CopyMemory(pDevInfoData, &deviceInfoData, sizeof(deviceInfoData)); + FREE(buf); + break; + } + + if(buf != NULL) + { + FREE(buf); + buf = NULL; + } + } + +Done: + + if (bResult == FALSE) + { + if (deviceInfo != INVALID_HANDLE_VALUE) + { + SetupDiDestroyDeviceInfoList(deviceInfo); + } + } + + if (pDriverName != NULL) + { + FREE(pDriverName); + } + + return status; +} + +/***************************************************************************** + + DriverNameToDeviceProperties() + + Returns the Device properties of the DevNode with the matching DriverName. + Returns NULL if the matching DevNode is not found. + + The caller should free the returned structure using FREE() macro + + *****************************************************************************/ +PUSB_DEVICE_PNP_STRINGS +DriverNameToDeviceProperties( + _In_reads_bytes_(cbDriverName) PCHAR DriverName, + _In_ size_t cbDriverName + ) +{ + HDEVINFO deviceInfo = INVALID_HANDLE_VALUE; + SP_DEVINFO_DATA deviceInfoData = {0}; + ULONG len; + BOOL status; + PUSB_DEVICE_PNP_STRINGS DevProps = NULL; + DWORD lastError; + + // Allocate device propeties structure + DevProps = (PUSB_DEVICE_PNP_STRINGS) ALLOC(sizeof(USB_DEVICE_PNP_STRINGS)); + + if(NULL == DevProps) + { + status = FALSE; + goto Done; + } + + // Get device instance + status = DriverNameToDeviceInst(DriverName, cbDriverName, &deviceInfo, &deviceInfoData); + if (status == FALSE) + { + goto Done; + } + + len = 0; + status = SetupDiGetDeviceInstanceId(deviceInfo, + &deviceInfoData, + NULL, + 0, + &len); + lastError = GetLastError(); + + + if (status != FALSE && lastError != ERROR_INSUFFICIENT_BUFFER) + { + status = FALSE; + goto Done; + } + + // + // An extra byte is required for the terminating character + // + + len++; + DevProps->DeviceId = ALLOC(len); + + if (DevProps->DeviceId == NULL) + { + status = FALSE; + goto Done; + } + + status = SetupDiGetDeviceInstanceId(deviceInfo, + &deviceInfoData, + DevProps->DeviceId, + len, + &len); + if (status == FALSE) + { + goto Done; + } + + status = GetDeviceProperty(deviceInfo, + &deviceInfoData, + SPDRP_DEVICEDESC, + &DevProps->DeviceDesc); + + if (status == FALSE) + { + goto Done; + } + + + // + // We don't fail if the following registry query fails as these fields are additional information only + // + + GetDeviceProperty(deviceInfo, + &deviceInfoData, + SPDRP_HARDWAREID, + &DevProps->HwId); + + GetDeviceProperty(deviceInfo, + &deviceInfoData, + SPDRP_SERVICE, + &DevProps->Service); + + GetDeviceProperty(deviceInfo, + &deviceInfoData, + SPDRP_CLASS, + &DevProps->DeviceClass); +Done: + + if (deviceInfo != INVALID_HANDLE_VALUE) + { + SetupDiDestroyDeviceInfoList(deviceInfo); + } + + if (status == FALSE) + { + if (DevProps != NULL) + { + FreeDeviceProperties(&DevProps); + } + } + return DevProps; +} + +/***************************************************************************** + + FreeDeviceProperties() + + Free the device properties structure + + *****************************************************************************/ +VOID FreeDeviceProperties(_In_ PUSB_DEVICE_PNP_STRINGS *ppDevProps) +{ + if(ppDevProps == NULL) + { + return; + } + + if(*ppDevProps == NULL) + { + return; + } + + if ((*ppDevProps)->DeviceId != NULL) + { + FREE((*ppDevProps)->DeviceId); + } + + if ((*ppDevProps)->DeviceDesc != NULL) + { + FREE((*ppDevProps)->DeviceDesc); + } + + // + // The following are not necessary, but left in case + // in the future there is a later failure where these + // pointer fields would be allocated. + // + + if ((*ppDevProps)->HwId != NULL) + { + FREE((*ppDevProps)->HwId); + } + + if ((*ppDevProps)->Service != NULL) + { + FREE((*ppDevProps)->Service); + } + + if ((*ppDevProps)->DeviceClass != NULL) + { + FREE((*ppDevProps)->DeviceClass); + } + + if ((*ppDevProps)->PowerState != NULL) + { + FREE((*ppDevProps)->PowerState); + } + + FREE(*ppDevProps); + *ppDevProps = NULL; +} |
