BOOL CDeviceView::ListDevicesByConnection() { WCHAR DeviceName[DEVICE_NAME_LEN]; INT ClassImage; BOOL bSuccess; /* Get the details of the root of the device tree */ bSuccess = m_Devices->GetDeviceTreeRoot(DeviceName, DEVICE_NAME_LEN, &ClassImage); if (bSuccess) { /* Add the root of the device tree to the treeview */ m_hTreeRoot = InsertIntoTreeView(NULL, DeviceName, NULL, ClassImage, 0); } /* Walk the device tree and add all the devices */ RecurseChildDevices(m_Devices->GetRootDevice(), m_hTreeRoot); /* Expand the root item */ (VOID)TreeView_Expand(m_hTreeView, m_hTreeRoot, TVE_EXPAND); return TRUE; }
HTREEITEM InitTreeView(HWND hTreeView) { HTREEITEM hRoot; TCHAR ComputerName[MAX_PATH]; DWORD dwSize = MAX_PATH; INT RootImage; (void)TreeView_DeleteAllItems(hTreeView); /* Get the device image list */ ImageListData.cbSize = sizeof(ImageListData); SetupDiGetClassImageList(&ImageListData); (void)TreeView_SetImageList(hTreeView, ImageListData.ImageList, TVSIL_NORMAL); if (!GetComputerName(ComputerName, &dwSize)) { ComputerName[0] = _T('\0'); } /* Get the image index of the computer class */ SetupDiGetClassImageIndex(&ImageListData, &GUID_DEVCLASS_COMPUTER, &RootImage); /* Insert the root item into the tree */ hRoot = InsertIntoTreeView(hTreeView, NULL, ComputerName, NULL, RootImage, 0); return hRoot; }
bool CDeviceView::RecurseChildDevices( _In_ DEVINST ParentDevice, _In_ HTREEITEM hParentTreeItem ) { HTREEITEM hDevItem = NULL; DEVINST Device; bool HasProblem = false; bool bSuccess; // Check if the parent has any child devices if (GetChildDevice(ParentDevice, &Device) == FALSE) return true; // Get the cached device node CDeviceNode *DeviceNode; DeviceNode = dynamic_cast<CDeviceNode *>(GetDeviceNode(Device)); if (DeviceNode == nullptr) { ATLASSERT(FALSE); return false; } // Don't show hidden devices if not requested if ((m_ShowHidden == TRUE) || (!(DeviceNode->IsHidden()))) { // Add this device to the tree under its parent hDevItem = InsertIntoTreeView(hParentTreeItem, DeviceNode); if (hDevItem) { // Check if this child has any children itself if (!RecurseChildDevices(Device, hDevItem)) HasProblem = true; } if (DeviceNode->HasProblem()) { HasProblem = true; } } // Check for siblings for (;;) { // Check if the parent device has anything at the same level bSuccess = GetSiblingDevice(Device, &Device); if (bSuccess == FALSE) break; DeviceNode = dynamic_cast<CDeviceNode *>(GetDeviceNode(Device)); if (DeviceNode == nullptr) { ATLASSERT(FALSE); } // Don't show hidden devices if not requested if ((m_ShowHidden == TRUE) || (!(DeviceNode->IsHidden()))) { if (DeviceNode->HasProblem()) { HasProblem = true; } // Add this device to the tree under its parent hDevItem = InsertIntoTreeView(hParentTreeItem, DeviceNode); if (hDevItem) { // Check if this child has any children itself if (!RecurseChildDevices(Device, hDevItem)) HasProblem = true; } } } (void)TreeView_SortChildren(m_hTreeView, hParentTreeItem, 0); // Expand the class if it has a problem device if (HasProblem == true) { (void)TreeView_Expand(m_hTreeView, hParentTreeItem, TVE_EXPAND); } // If there was a problem, expand the ancestors if (HasProblem) return false; return true; }
bool CDeviceView::ListDevicesByType() { CClassNode *ClassNode; CDeviceNode *DeviceNode; HDEVINFO hDevInfo; HTREEITEM hTreeItem = NULL; GUID ClassGuid; INT ClassIndex; BOOL bClassSuccess, bSuccess; ClassIndex = 0; do { // Loop through all the device classes bClassSuccess = GetNextClass(ClassIndex, &ClassGuid, &hDevInfo); if (bClassSuccess) { bool bClassUnknown = false; bool AddedParent = false; INT DeviceIndex = 0; bool MoreItems = false; // Get the cached class node ClassNode = GetClassNode(&ClassGuid); if (ClassNode == nullptr) { ATLASSERT(FALSE); ClassIndex++; continue; } // Set a flag is this is the (special case) unknown class if (IsEqualGUID(ClassGuid, GUID_DEVCLASS_UNKNOWN)) bClassUnknown = true; // Check if this is a hidden class if (IsEqualGUID(ClassGuid, GUID_DEVCLASS_LEGACYDRIVER) || IsEqualGUID(ClassGuid, GUID_DEVCLASS_VOLUME)) { // Ignore this device if we aren't displaying hidden devices if (m_ShowHidden == FALSE) { ClassIndex++; continue; } } do { // Get a handle to all the devices in this class SP_DEVINFO_DATA DeviceInfoData; ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); bSuccess = SetupDiEnumDeviceInfo(hDevInfo, DeviceIndex, &DeviceInfoData); if (bSuccess == FALSE && GetLastError() == ERROR_NO_MORE_ITEMS) MoreItems = false; if (bSuccess) { MoreItems = true; // The unknown class handle contains all devices on the system, // and we're just looking for the ones with a null GUID if (bClassUnknown) { if (IsEqualGUID(DeviceInfoData.ClassGuid, GUID_NULL) == FALSE) { // This is a known device, we aren't interested in it DeviceIndex++; continue; } } // Get the cached device node DeviceNode = GetDeviceNode(DeviceInfoData.DevInst); if (DeviceNode == nullptr) { ATLASSERT(bClassUnknown == true); DeviceIndex++; continue; } // Check if this is a hidden device if (DeviceNode->IsHidden()) { // Ignore this device if we aren't displaying hidden devices if (m_ShowHidden == FALSE) { DeviceIndex++; continue; } } // We have a device, we need to add the parent if it hasn't yet been added if (AddedParent == false) { // Insert the new class under the root item hTreeItem = InsertIntoTreeView(m_hTreeRoot, ClassNode); AddedParent = true; } // Add the device under the class item node (void)InsertIntoTreeView(hTreeItem, DeviceNode); // Expand the class if it has a problem device if (DeviceNode->HasProblem()) { (void)TreeView_Expand(m_hTreeView, hTreeItem, TVE_EXPAND); } } DeviceIndex++; } while (MoreItems); // If this class has devices, sort them alphabetically if (AddedParent == true) { (void)TreeView_SortChildren(m_hTreeView, hTreeItem, 0); } } ClassIndex++; } while (bClassSuccess); // Sort the classes alphabetically (void)TreeView_SortChildren(m_hTreeView, m_hTreeRoot, 0); // Expand the root item (void)TreeView_Expand(m_hTreeView, m_hTreeRoot, TVE_EXPAND); // Pre-select the root item (VOID)TreeView_SelectItem(m_hTreeView, m_hTreeRoot); return 0; }
bool CDeviceView::AddRootDevice() { m_hTreeRoot = InsertIntoTreeView(NULL, m_RootNode); return (m_hTreeRoot != NULL); }
static HTREEITEM AddDeviceToTree(HWND hTreeView, HTREEITEM hRoot, DEVINST dnDevInst, BOOL bShowHidden) { TCHAR DevName[MAX_DEV_LEN]; TCHAR FriendlyName[MAX_DEV_LEN]; TCHAR ClassGuidString[MAX_GUID_STRING_LEN]; GUID ClassGuid; ULONG ulLength; LPTSTR DeviceID = NULL; INT ClassImage = 24; CONFIGRET cr; ulLength = MAX_GUID_STRING_LEN * sizeof(TCHAR); cr = CM_Get_DevNode_Registry_Property(dnDevInst, CM_DRP_CLASSGUID, NULL, ClassGuidString, &ulLength, 0); if (cr == CR_SUCCESS) { pSetupGuidFromString(ClassGuidString, &ClassGuid); if (bShowHidden == FALSE && (IsEqualGUID(&ClassGuid, &GUID_DEVCLASS_LEGACYDRIVER) || IsEqualGUID(&ClassGuid, &GUID_DEVCLASS_VOLUME))) return NULL; } else { /* It's a device with no driver */ ClassGuid = GUID_DEVCLASS_UNKNOWN; } cr = CM_Get_Device_ID(dnDevInst, DevName, MAX_DEV_LEN, 0); if (cr != CR_SUCCESS) return NULL; ulLength = MAX_DEV_LEN * sizeof(TCHAR); cr = CM_Get_DevNode_Registry_Property(dnDevInst, CM_DRP_FRIENDLYNAME, NULL, FriendlyName, &ulLength, 0); if (cr != CR_SUCCESS) { ulLength = MAX_DEV_LEN * sizeof(TCHAR); cr = CM_Get_DevNode_Registry_Property(dnDevInst, CM_DRP_DEVICEDESC, NULL, FriendlyName, &ulLength, 0); if (cr != CR_SUCCESS) return NULL; } if (!SetupDiGetClassImageIndex(&ImageListData, &ClassGuid, &ClassImage)) { /* FIXME: can we do this? * Set the blank icon: IDI_SETUPAPI_BLANK = 41 * it'll be image 24 in the imagelist */ ClassImage = 24; } if (DevName != NULL) { DeviceID = HeapAlloc(GetProcessHeap(), 0, (lstrlen(DevName) + 1) * sizeof(TCHAR)); if (DeviceID == NULL) { return NULL; } lstrcpy(DeviceID, DevName); } return InsertIntoTreeView(hTreeView, hRoot, FriendlyName, DeviceID, ClassImage, 0); }
static VOID EnumDevices( HWND hTreeView, PDEVCLASS_ENTRY pClassArray, ULONG ulClassCount, BOOL bShowHidden) { HDEVINFO hDevInfo = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA DeviceInfoData; ULONG Status, Problem; DWORD DevIdSize; TCHAR DeviceName[MAX_DEV_LEN]; DWORD DevIndex; LPTSTR InstanceId; PDEVCLASS_ENTRY pClass; UINT OverlayImage; CONFIGRET cr; /* Get device info for all devices of a particular class */ hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES); if (hDevInfo == INVALID_HANDLE_VALUE) return; for (DevIndex = 0; ; DevIndex++) { ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); InstanceId = NULL; DeviceName[0] = _T('\0'); OverlayImage = 0; if (!SetupDiEnumDeviceInfo(hDevInfo, DevIndex, &DeviceInfoData)) break; if (bShowHidden == FALSE && (IsEqualGUID(&DeviceInfoData.ClassGuid, &GUID_DEVCLASS_LEGACYDRIVER) || IsEqualGUID(&DeviceInfoData.ClassGuid, &GUID_DEVCLASS_VOLUME))) continue; pClass = GetClassFromClassGuid(pClassArray, ulClassCount, &DeviceInfoData.ClassGuid); /* get the device ID */ if (!SetupDiGetDeviceInstanceId(hDevInfo, &DeviceInfoData, NULL, 0, &DevIdSize)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { InstanceId = (LPTSTR)HeapAlloc(GetProcessHeap(), 0, DevIdSize * sizeof(TCHAR)); if (InstanceId != NULL) { if (!SetupDiGetDeviceInstanceId(hDevInfo, &DeviceInfoData, InstanceId, DevIdSize, NULL)) { HeapFree(GetProcessHeap(), 0, InstanceId); InstanceId = NULL; } } } } /* Skip the root device */ if (InstanceId != NULL && _tcscmp(InstanceId, _T("HTREE\\ROOT\\0")) == 0) { HeapFree(GetProcessHeap(), 0, InstanceId); InstanceId = NULL; continue; } /* Get the device's friendly name */ if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, 0, (BYTE*)DeviceName, MAX_DEV_LEN, NULL)) { /* If the friendly name fails, try the description instead */ SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, 0, (BYTE*)DeviceName, MAX_DEV_LEN, NULL); } cr = CM_Get_DevNode_Status_Ex(&Status, &Problem, DeviceInfoData.DevInst, 0, NULL); if ((cr == CR_SUCCESS) && (Status & DN_HAS_PROBLEM)) { if (Problem == CM_PROB_DISABLED || Problem == CM_PROB_HARDWARE_DISABLED) OverlayImage = 2; else OverlayImage = 1; } InsertIntoTreeView(hTreeView, pClass->hItem, DeviceName, InstanceId, pClass->ClassImage, OverlayImage); if (OverlayImage != 0) { /* Expand the class if the device has a problem */ (void)TreeView_Expand(hTreeView, pClass->hItem, TVE_EXPAND); } pClass->bUsed = TRUE; } if (hDevInfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(hDevInfo); }
static VOID EnumDeviceClasses( HWND hTreeView, HTREEITEM hRoot, PDEVCLASS_ENTRY pClassArray, ULONG ClassCount) { WCHAR ClassName[MAX_DEV_LEN]; WCHAR ClassDesc[MAX_DEV_LEN]; PDEVCLASS_ENTRY pClass; ULONG ClassIndex; DWORD dwSize; LONG lSize; HKEY hKey; CONFIGRET cr; for (ClassIndex = 0; ClassIndex < ClassCount; ClassIndex++) { pClass = &pClassArray[ClassIndex]; cr = CM_Enumerate_Classes(ClassIndex, &pClass->ClassGuid, 0); if (cr == CR_NO_SUCH_VALUE) return; dwSize = MAX_CLASS_NAME_LEN; if (!SetupDiClassNameFromGuid(&pClass->ClassGuid, ClassName, dwSize, &dwSize)) { ClassName[0] = _T('\0'); } if (!SetupDiGetClassImageIndex(&ImageListData, &pClass->ClassGuid, &pClass->ClassImage)) { /* FIXME: can we do this? * Set the blank icon: IDI_SETUPAPI_BLANK = 41 * it'll be image 24 in the imagelist */ pClass->ClassImage = 24; } hKey = SetupDiOpenClassRegKeyEx(&pClass->ClassGuid, MAXIMUM_ALLOWED, DIOCR_INSTALLER, NULL, 0); if (hKey != INVALID_HANDLE_VALUE) { lSize = MAX_DEV_LEN; if (RegQueryValue(hKey, NULL, ClassDesc, &lSize) != ERROR_SUCCESS) { ClassDesc[0] = _T('\0'); } RegCloseKey(hKey); } pClass->hItem = InsertIntoTreeView(hTreeView, hRoot, (ClassDesc[0] != _T('\0')) ? ClassDesc : ClassName, NULL, pClass->ClassImage, 0); } }
VOID CDeviceView::RecurseChildDevices( _In_ DEVINST ParentDevice, _In_ HTREEITEM hParentTreeItem ) { HTREEITEM hDevItem = NULL; DEVINST Device; WCHAR DeviceName[DEVICE_NAME_LEN]; LPTSTR DeviceId = NULL; INT ClassImage; BOOL IsUnknown = FALSE; BOOL IsHidden = FALSE; ULONG DeviceStatus = 0; ULONG ProblemNumber = 0; UINT OverlayImage = 0; BOOL bSuccess; /* Check if the parent has any child devices */ if (m_Devices->GetChildDevice(ParentDevice, &Device) == FALSE) return; /* Lookup the info about this device */ bSuccess = m_Devices->GetDevice(Device, DeviceName, DEVICE_NAME_LEN, &DeviceId, &ClassImage, &DeviceStatus, &ProblemNumber); if (bSuccess) { /* Check if this is a hidden device */ if ((m_ShowHidden == TRUE) || (!(DeviceStatus & DN_NO_SHOW_IN_DM))) { /* Check if the device has a problem */ if (DeviceStatus & DN_HAS_PROBLEM) { OverlayImage = 1; } /* The disabled overlay takes precidence over the problem overlay */ if (ProblemNumber == CM_PROB_HARDWARE_DISABLED) { OverlayImage = 2; } /* Add this device to the tree under its parent */ hDevItem = InsertIntoTreeView(hParentTreeItem, DeviceName, (LPARAM)DeviceId, ClassImage, 0); if (hDevItem) { /* Check if this child has any children itself */ RecurseChildDevices(Device, hDevItem); } } } for (;;) { /* Check if the parent device has anything at the same level */ bSuccess = m_Devices->GetSiblingDevice(Device, &Device); if (bSuccess == FALSE) break; /* Lookup the info about this device */ bSuccess = m_Devices->GetDevice(Device, DeviceName, DEVICE_NAME_LEN, &DeviceId, &ClassImage, &DeviceStatus, &ProblemNumber); if (bSuccess) { /* Check if this is a hidden device */ if (DeviceStatus & DN_NO_SHOW_IN_DM) { if (m_ShowHidden == FALSE) continue; } /* Check if the device has a problem */ if (DeviceStatus & DN_HAS_PROBLEM) { OverlayImage = 1; } /* The disabled overlay takes precidence over the problem overlay */ if (ProblemNumber == CM_PROB_HARDWARE_DISABLED) { OverlayImage = 2; } /* Add this device to the tree under its parent */ hDevItem = InsertIntoTreeView(hParentTreeItem, DeviceName, (LPARAM)DeviceId, ClassImage, 0); if (hDevItem) { /* Check if this child has any children itself */ RecurseChildDevices(Device, hDevItem); } } } (void)TreeView_SortChildren(m_hTreeView, hParentTreeItem, 0); }
BOOL CDeviceView::ListDevicesByType() { HTREEITEM hDevItem = NULL; GUID ClassGuid; WCHAR ClassName[CLASS_NAME_LEN]; WCHAR ClassDescription[CLASS_DESC_LEN]; INT ClassIndex; INT ClassImage; LPTSTR DeviceId = NULL; BOOL bSuccess; /* Get the details of the root of the device tree */ bSuccess = m_Devices->GetDeviceTreeRoot(ClassName, CLASS_NAME_LEN, &ClassImage); if (bSuccess) { /* Add the root of the device tree to the treeview */ m_hTreeRoot = InsertIntoTreeView(NULL, ClassName, NULL, ClassImage, 0); } /* If something went wrong, bail */ if (m_hTreeRoot == NULL) return FALSE; ClassIndex = 0; do { /* Get the next device class */ bSuccess = m_Devices->EnumClasses(ClassIndex, &ClassGuid, ClassName, CLASS_NAME_LEN, ClassDescription, CLASS_DESC_LEN, &ClassImage); if (bSuccess) { BOOL bDevSuccess, AddedParent; HANDLE Handle = NULL; WCHAR DeviceName[DEVICE_NAME_LEN]; INT DeviceIndex = 0; BOOL MoreItems = FALSE; BOOL DeviceHasProblem = FALSE; ULONG DeviceStatus = 0; ULONG ProblemNumber = 0; ULONG OverlayImage = 0; AddedParent = FALSE; do { /* Enum all the devices that belong to this class */ bDevSuccess = m_Devices->EnumDevicesForClass(&Handle, &ClassGuid, DeviceIndex, &MoreItems, DeviceName, DEVICE_NAME_LEN, &DeviceId, &DeviceStatus, &ProblemNumber); if (bDevSuccess) { /* Check if this is a hidden device */ if (DeviceStatus & DN_NO_SHOW_IN_DM) { if (m_ShowHidden == FALSE) { DeviceIndex++; continue; } } /* Check if the device has a problem */ if (DeviceStatus & DN_HAS_PROBLEM) { DeviceHasProblem = TRUE; OverlayImage = 1; } /* The disabled overlay takes precidence over the problem overlay */ if (ProblemNumber == CM_PROB_HARDWARE_DISABLED) { OverlayImage = 2; } /* We have a device, we're gonna need to add the parent first */ if (AddedParent == FALSE) { /* Insert the new class under the root item */ hDevItem = InsertIntoTreeView(m_hTreeRoot, ClassDescription, NULL, ClassImage, 0); /* Don't add it again */ AddedParent = TRUE; } /* Add the device under the class item */ (VOID)InsertIntoTreeView(hDevItem, DeviceName, (LPARAM)DeviceId, ClassImage, OverlayImage); /* Check if there's a problem with the device */ if (DeviceHasProblem) { /* Expand the class */ (VOID)TreeView_Expand(m_hTreeView, hDevItem, TVE_EXPAND); } } DeviceIndex++; } while (MoreItems); /* Check if this class has any devices */ if (AddedParent == TRUE) { /* Sort the devices alphabetically */ (VOID)TreeView_SortChildren(m_hTreeView, hDevItem, 0); } } ClassIndex++; } while (bSuccess); /* Sort the classes alphabetically */ (VOID)TreeView_SortChildren(m_hTreeView, m_hTreeRoot, 0); /* Expand the root item */ (VOID)TreeView_Expand(m_hTreeView, m_hTreeRoot, TVE_EXPAND); /* Pre-select the root item */ (VOID)TreeView_SelectItem(m_hTreeView, m_hTreeRoot); return 0; }