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);