Author: ekohl Date: Sun Oct 5 08:53:51 2014 New Revision: 64534
URL: http://svn.reactos.org/svn/reactos?rev=64534&view=rev Log: [DEVMGMT] - Reimplement the 'list by device type' function. The old implementation did not list devices as 'unknown devices' if they had no device class GUID or an unknown class GUID. - Use overlay images to indicate problems on a device.
Modified: trunk/reactos/base/applications/mscutils/devmgmt/enumdevices.c trunk/reactos/base/applications/mscutils/devmgmt/precomp.h
Modified: trunk/reactos/base/applications/mscutils/devmgmt/enumdevices.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/mscutils/... ============================================================================== --- trunk/reactos/base/applications/mscutils/devmgmt/enumdevices.c [iso-8859-1] (original) +++ trunk/reactos/base/applications/mscutils/devmgmt/enumdevices.c [iso-8859-1] Sun Oct 5 08:53:51 2014 @@ -15,9 +15,7 @@ #include <devguid.h>
static SP_CLASSIMAGELIST_DATA ImageListData; -static HDEVINFO hDevInfo; - -DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); +
VOID FreeDeviceStrings(HWND hTreeView) @@ -96,7 +94,6 @@ DPF_EXTENDED, FALSE); } - }
@@ -106,7 +103,7 @@ LPTSTR lpLabel, LPTSTR DeviceID, INT DevImage, - LONG DevProb) + UINT OverlayImage) { TV_ITEM tvi; TV_INSERTSTRUCT tvins; @@ -121,15 +118,11 @@ tvi.iImage = DevImage; tvi.iSelectedImage = DevImage;
- if (DevProb != 0) - { + if (OverlayImage != 0) + { + tvi.mask |= TVIF_STATE; tvi.stateMask = TVIS_OVERLAYMASK; - - if (DevProb == CM_PROB_DISABLED) - { - /* FIXME: set the overlay icon */ - } - + tvi.state = INDEXTOOVERLAYMASK(OverlayImage); }
tvins.item = tvi; @@ -139,212 +132,295 @@ }
-static INT -EnumDeviceClasses(INT ClassIndex, - BOOL ShowHidden, - LPTSTR DevClassName, - LPTSTR DevClassDesc, - BOOL *DevPresent, - INT *ClassImage, - BOOL *IsUnknown, - BOOL *IsHidden) -{ +static +ULONG +GetClassCount(VOID) +{ + ULONG ulClassIndex; GUID ClassGuid; - HKEY KeyClass; - TCHAR ClassName[MAX_CLASS_NAME_LEN]; - DWORD RequiredSize = MAX_CLASS_NAME_LEN; - UINT Ret; - - *DevPresent = FALSE; - *DevClassName = _T('\0'); - *IsHidden = FALSE; - - Ret = CM_Enumerate_Classes(ClassIndex, - &ClassGuid, - 0); - if (Ret != CR_SUCCESS) - { - /* all classes enumerated */ - if(Ret == CR_NO_SUCH_VALUE) - { - return -1; - } - - if (Ret == CR_INVALID_DATA) - { - ; /*FIXME: what should we do here? */ - } - - /* handle other errors... */ - } - - /* This case is special because these devices don't show up with normal class enumeration */ - *IsUnknown = IsEqualGUID(&ClassGuid, &GUID_DEVCLASS_UNKNOWN); - - if (ShowHidden == FALSE && - (IsEqualGUID(&ClassGuid, &GUID_DEVCLASS_LEGACYDRIVER) || - IsEqualGUID(&ClassGuid, &GUID_DEVCLASS_VOLUME))) - *IsHidden = TRUE; - - if (SetupDiClassNameFromGuid(&ClassGuid, - ClassName, - RequiredSize, - &RequiredSize)) - { - lstrcpy(DevClassName, ClassName); - } - - 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; - } - - /* Get device info for all devices of a particular class */ - hDevInfo = SetupDiGetClassDevs(*IsUnknown ? NULL : &ClassGuid, - NULL, - NULL, - DIGCF_PRESENT | (*IsUnknown ? DIGCF_ALLCLASSES : 0)); - if (hDevInfo == INVALID_HANDLE_VALUE) - { - return 0; - } - - KeyClass = SetupDiOpenClassRegKeyEx(&ClassGuid, + CONFIGRET cr; + + for (ulClassIndex = 0; ; ulClassIndex++) + { + cr = CM_Enumerate_Classes(ulClassIndex, + &ClassGuid, + 0); + if (cr == CR_NO_SUCH_VALUE) + return ulClassIndex; + } +} + + +static +PDEVCLASS_ENTRY +GetClassFromClassGuid( + PDEVCLASS_ENTRY pClassArray, + ULONG ulClassCount, + GUID *pGuid) +{ + PDEVCLASS_ENTRY pClass, pUnknownClass = NULL; + ULONG i; + + for (i = 0; i < ulClassCount; i++) + { + pClass = &pClassArray[i]; + + if (IsEqualGUID(&pClass->ClassGuid, &GUID_DEVCLASS_UNKNOWN)) + pUnknownClass = pClass; + + if (IsEqualGUID(&pClass->ClassGuid, pGuid)) + return pClass; + } + + return pUnknownClass; +} + + +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 (KeyClass != INVALID_HANDLE_VALUE) - { - - LONG dwSize = MAX_DEV_LEN; - - if (RegQueryValue(KeyClass, - NULL, - DevClassDesc, - &dwSize) != ERROR_SUCCESS) - { - *DevClassDesc = _T('\0'); - } - } - else - { - return 0; - } - - *DevPresent = TRUE; - - RegCloseKey(KeyClass); - - return 0; -} - - -static LONG -EnumDevices(INT index, - LPTSTR DeviceClassName, - LPTSTR DeviceName, - LPTSTR *DeviceID) -{ + 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); + } +} + + +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; - ULONG Status, ProblemNumber; - DWORD DevIdSize; - - *DeviceName = _T('\0'); - *DeviceID = NULL; - - ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); - DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - - if (!SetupDiEnumDeviceInfo(hDevInfo, - index, - &DeviceInfoData)) - { - /* no such device */ - return -1; - } - - if (DeviceClassName == NULL && !IsEqualGUID(&DeviceInfoData.ClassGuid, &GUID_NULL)) - { - /* we're looking for unknown devices and this isn't one */ - return -2; - } - - /* get the device ID */ - if (!SetupDiGetDeviceInstanceId(hDevInfo, - &DeviceInfoData, - NULL, - 0, - &DevIdSize)) - { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - (*DeviceID) = (LPTSTR)HeapAlloc(GetProcessHeap(), - 0, - DevIdSize * sizeof(TCHAR)); - if (*DeviceID) + + + /* 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) { - if (!SetupDiGetDeviceInstanceId(hDevInfo, - &DeviceInfoData, - *DeviceID, - DevIdSize, - NULL)) + InstanceId = (LPTSTR)HeapAlloc(GetProcessHeap(), + 0, + DevIdSize * sizeof(TCHAR)); + if (InstanceId != NULL) { - HeapFree(GetProcessHeap(), - 0, - *DeviceID); - *DeviceID = NULL; + if (!SetupDiGetDeviceInstanceId(hDevInfo, + &DeviceInfoData, + InstanceId, + DevIdSize, + NULL)) + { + HeapFree(GetProcessHeap(), + 0, + InstanceId); + InstanceId = NULL; + } } } } - } - - if (DeviceID != NULL && - _tcscmp(*DeviceID, _T("HTREE\ROOT\0")) == 0) - { - HeapFree(GetProcessHeap(), - 0, - *DeviceID); - *DeviceID = NULL; - return -1; - } - - /* 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, - &ProblemNumber, - DeviceInfoData.DevInst, - 0, - NULL); - if (cr == CR_SUCCESS && (Status & DN_HAS_PROBLEM)) - { - return ProblemNumber; - } - - return 0; + + /* 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 +CleanupDeviceClasses( + HWND hTreeView, + PDEVCLASS_ENTRY pClassArray, + ULONG ulClassCount) +{ + PDEVCLASS_ENTRY pClass; + ULONG i; + + for (i = 0; i < ulClassCount; i++) + { + pClass = &pClassArray[i]; + + if (pClass->bUsed == FALSE) + (void)TreeView_DeleteItem(hTreeView, + pClass->hItem); + else + (void)TreeView_SortChildren(hTreeView, + pClass->hItem, + 0); + } }
@@ -353,105 +429,33 @@ HTREEITEM hRoot, BOOL bShowHidden) { - HTREEITEM hDevItem; - TCHAR DevName[MAX_DEV_LEN]; - TCHAR DevDesc[MAX_DEV_LEN]; - LPTSTR DeviceID = NULL; - BOOL DevExist = FALSE; - INT ClassRet; - INT index = 0; - INT DevImage; - BOOL IsUnknown = FALSE; - BOOL IsHidden = FALSE; - - do - { - ClassRet = EnumDeviceClasses(index, - bShowHidden, - DevName, - DevDesc, - &DevExist, - &DevImage, - &IsUnknown, - &IsHidden); - - if ((ClassRet != -1) && (DevExist) && !IsHidden) - { - TCHAR DeviceName[MAX_DEV_LEN]; - INT DevIndex = 0; - LONG Ret; - - if (DevDesc[0] != _T('\0')) - { - hDevItem = InsertIntoTreeView(hTreeView, - hRoot, - DevDesc, - NULL, - DevImage, - 0); - } - else - { - hDevItem = InsertIntoTreeView(hTreeView, - hRoot, - DevName, - NULL, - DevImage, - 0); - } - - do - { - Ret = EnumDevices(DevIndex, - IsUnknown ? NULL : DevName, - DeviceName, - &DeviceID); - if (Ret >= 0) - { - InsertIntoTreeView(hTreeView, - hDevItem, - DeviceName, - DeviceID, - DevImage, - Ret); - if (Ret != 0) - { - /* Expand the class if the device has a problem */ - (void)TreeView_Expand(hTreeView, - hDevItem, - TVE_EXPAND); - } - } - - DevIndex++; - - } while (Ret != -1); - - /* kill InfoList initialized in EnumDeviceClasses */ - if (hDevInfo) - { - SetupDiDestroyDeviceInfoList(hDevInfo); - hDevInfo = NULL; - } - - /* don't insert classes with no devices */ - if (!TreeView_GetChild(hTreeView, - hDevItem)) - { - (void)TreeView_DeleteItem(hTreeView, - hDevItem); - } - else - { - (void)TreeView_SortChildren(hTreeView, - hDevItem, - 0); - } - } - - index++; - - } while (ClassRet != -1); + PDEVCLASS_ENTRY pClassArray; + ULONG ulClassCount; + + ulClassCount = GetClassCount(); + + pClassArray = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + ulClassCount * sizeof(DEVCLASS_ENTRY)); + if (pClassArray == NULL) + return; + + EnumDeviceClasses(hTreeView, + hRoot, + pClassArray, + ulClassCount); + + EnumDevices(hTreeView, + pClassArray, + ulClassCount, + bShowHidden); + + CleanupDeviceClasses(hTreeView, + pClassArray, + ulClassCount); + + if (pClassArray != NULL) + HeapFree(GetProcessHeap(), 0, pClassArray);
(void)TreeView_Expand(hTreeView, hRoot, @@ -647,25 +651,15 @@ InitTreeView(HWND hTreeView) { HTREEITEM hRoot; - HBITMAP hComp; TCHAR ComputerName[MAX_PATH]; DWORD dwSize = MAX_PATH; INT RootImage;
(void)TreeView_DeleteAllItems(hTreeView);
- /* get the device image List */ + /* Get the device image list */ ImageListData.cbSize = sizeof(ImageListData); SetupDiGetClassImageList(&ImageListData); - - hComp = LoadBitmap(hInstance, - MAKEINTRESOURCE(IDB_ROOT_IMAGE)); - - ImageList_Add(ImageListData.ImageList, - hComp, - NULL); - - DeleteObject(hComp);
(void)TreeView_SetImageList(hTreeView, ImageListData.ImageList, @@ -677,9 +671,12 @@ ComputerName[0] = _T('\0'); }
- RootImage = ImageList_GetImageCount(ImageListData.ImageList) - 1; - - /* insert the root item into the tree */ + /* 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,
Modified: trunk/reactos/base/applications/mscutils/devmgmt/precomp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/mscutils/... ============================================================================== --- trunk/reactos/base/applications/mscutils/devmgmt/precomp.h [iso-8859-1] (original) +++ trunk/reactos/base/applications/mscutils/devmgmt/precomp.h [iso-8859-1] Sun Oct 5 08:53:51 2014 @@ -44,6 +44,15 @@ UINT InMenuLoop : 1;
} MAIN_WND_INFO, *PMAIN_WND_INFO; + + +typedef struct _DEVCLASS_ENTRY +{ + GUID ClassGuid; + INT ClassImage; + BOOL bUsed; + HTREEITEM hItem; +} DEVCLASS_ENTRY, *PDEVCLASS_ENTRY;
INT_PTR CALLBACK AboutDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);