mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-30 19:26:05 +00:00
- Major improvements to the device manager experience (finally making it useful for users to gather information from)
- Device manager now reports problem codes, shows unknown devices, and displays non-PnP drivers like Windows - Inspired by Eric's recent work [DEVMGMT] - Finally (!!!) add support for showing devices with no drivers installed yet - Expand the class tree if one of the devices has a problem [INF] - Add legcydrv.inf for installing the LegacyDriver class [NTOSKRNL] - Fix null termination issues and enable the legacy driver registry code - Add a service description in legacy device entries - Return valid flags for a device status query - Store problem codes for several common device node failure states svn path=/trunk/; revision=56199
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
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)
|
||||
@@ -138,7 +139,8 @@ EnumDeviceClasses(INT ClassIndex,
|
||||
LPTSTR DevClassName,
|
||||
LPTSTR DevClassDesc,
|
||||
BOOL *DevPresent,
|
||||
INT *ClassImage)
|
||||
INT *ClassImage,
|
||||
BOOL *IsUnknown)
|
||||
{
|
||||
GUID ClassGuid;
|
||||
HKEY KeyClass;
|
||||
@@ -157,7 +159,6 @@ EnumDeviceClasses(INT ClassIndex,
|
||||
/* all classes enumerated */
|
||||
if(Ret == CR_NO_SUCH_VALUE)
|
||||
{
|
||||
hDevInfo = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -169,6 +170,9 @@ EnumDeviceClasses(INT ClassIndex,
|
||||
/* 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 (SetupDiClassNameFromGuid(&ClassGuid,
|
||||
ClassName,
|
||||
RequiredSize,
|
||||
@@ -188,13 +192,12 @@ EnumDeviceClasses(INT ClassIndex,
|
||||
}
|
||||
|
||||
/* Get device info for all devices of a particular class */
|
||||
hDevInfo = SetupDiGetClassDevs(&ClassGuid,
|
||||
hDevInfo = SetupDiGetClassDevs(*IsUnknown ? NULL : &ClassGuid,
|
||||
NULL,
|
||||
NULL,
|
||||
DIGCF_PRESENT);
|
||||
DIGCF_PRESENT | (*IsUnknown ? DIGCF_ALLCLASSES : 0));
|
||||
if (hDevInfo == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
hDevInfo = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -218,7 +221,7 @@ EnumDeviceClasses(INT ClassIndex,
|
||||
}
|
||||
else
|
||||
{
|
||||
return -3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*DevPresent = TRUE;
|
||||
@@ -254,6 +257,12 @@ EnumDevices(INT index,
|
||||
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,
|
||||
@@ -328,6 +337,7 @@ ListDevicesByType(HWND hTreeView,
|
||||
INT ClassRet;
|
||||
INT index = 0;
|
||||
INT DevImage;
|
||||
BOOL IsUnknown = FALSE;
|
||||
|
||||
do
|
||||
{
|
||||
@@ -335,7 +345,8 @@ ListDevicesByType(HWND hTreeView,
|
||||
DevName,
|
||||
DevDesc,
|
||||
&DevExist,
|
||||
&DevImage);
|
||||
&DevImage,
|
||||
&IsUnknown);
|
||||
|
||||
if ((ClassRet != -1) && (DevExist))
|
||||
{
|
||||
@@ -365,7 +376,7 @@ ListDevicesByType(HWND hTreeView,
|
||||
do
|
||||
{
|
||||
Ret = EnumDevices(DevIndex,
|
||||
DevName,
|
||||
IsUnknown ? NULL : DevName,
|
||||
DeviceName,
|
||||
&DeviceID);
|
||||
if (Ret >= 0)
|
||||
@@ -376,6 +387,13 @@ ListDevicesByType(HWND hTreeView,
|
||||
DeviceID,
|
||||
DevImage,
|
||||
Ret);
|
||||
if (Ret != 0)
|
||||
{
|
||||
/* Expand the class if the device has a problem */
|
||||
(void)TreeView_Expand(hTreeView,
|
||||
hDevItem,
|
||||
TVE_EXPAND);
|
||||
}
|
||||
}
|
||||
|
||||
DevIndex++;
|
||||
@@ -472,16 +490,21 @@ AddDeviceToTree(HWND hTreeView,
|
||||
if (cr == CR_SUCCESS)
|
||||
{
|
||||
pSetupGuidFromString(ClassGuidString, &ClassGuid);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's a device with no driver */
|
||||
ClassGuid = GUID_DEVCLASS_UNKNOWN;
|
||||
}
|
||||
|
||||
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 (!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)
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
#include <cfgmgr32.h>
|
||||
#include <commctrl.h>
|
||||
#include <dll/devmgr/devmgr.h>
|
||||
#include <initguid.h>
|
||||
#include <cguid.h>
|
||||
#include <devguid.h>
|
||||
#include "resource.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
@@ -17,6 +17,7 @@ list(APPEND INF_FILES
|
||||
ks.inf
|
||||
kscaptur.inf
|
||||
layout.inf
|
||||
legcydrv.inf
|
||||
machine.inf
|
||||
monitor.inf
|
||||
msmouse.inf
|
||||
|
||||
Binary file not shown.
@@ -13,7 +13,8 @@ hal.inf
|
||||
hdc.inf
|
||||
input.inf
|
||||
keyboard.inf
|
||||
machine.inf
|
||||
legcydrv.inf
|
||||
machine.inf
|
||||
monitor.inf
|
||||
msmouse.inf
|
||||
NET_NIC.inf
|
||||
|
||||
@@ -24,7 +24,8 @@ hal.inf
|
||||
hdc.inf
|
||||
input.inf
|
||||
keyboard.inf
|
||||
machine.inf
|
||||
legcydrv.inf
|
||||
machine.inf
|
||||
monitor.inf
|
||||
msmouse.inf
|
||||
NET_NIC.inf
|
||||
|
||||
@@ -406,6 +406,47 @@ IopGetRelatedDevice(PPLUGPLAY_CONTROL_RELATED_DEVICE_DATA RelatedDeviceData)
|
||||
return Status;
|
||||
}
|
||||
|
||||
static ULONG
|
||||
IopGetDeviceNodeStatus(PDEVICE_NODE DeviceNode)
|
||||
{
|
||||
ULONG Output = 0;
|
||||
|
||||
if (DeviceNode->Parent == IopRootDeviceNode)
|
||||
Output |= DN_ROOT_ENUMERATED;
|
||||
|
||||
if (DeviceNode->Flags & DNF_ADDED)
|
||||
Output |= DN_DRIVER_LOADED;
|
||||
|
||||
/* FIXME: DN_ENUM_LOADED */
|
||||
|
||||
if (DeviceNode->Flags & DNF_STARTED)
|
||||
Output |= DN_STARTED;
|
||||
|
||||
/* FIXME: Manual */
|
||||
|
||||
if (!(DeviceNode->Flags & DNF_PROCESSED))
|
||||
Output |= DN_NEED_TO_ENUM;
|
||||
|
||||
/* DN_NOT_FIRST_TIME is 9x only */
|
||||
|
||||
/* FIXME: DN_HARDWARE_ENUM */
|
||||
|
||||
/* DN_LIAR and DN_HAS_MARK are 9x only */
|
||||
|
||||
if (DeviceNode->Problem != 0)
|
||||
Output |= DN_HAS_PROBLEM;
|
||||
|
||||
/* FIXME: DN_FILTERED */
|
||||
|
||||
if (DeviceNode->Flags & DNF_LEGACY_DRIVER)
|
||||
Output |= DN_LEGACY_DRIVER;
|
||||
|
||||
/* FIXME: Implement the rest */
|
||||
|
||||
Output |= DN_NT_ENUMERATOR | DN_NT_DRIVER;
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
IopDeviceStatus(PPLUGPLAY_CONTROL_STATUS_DATA StatusData)
|
||||
@@ -453,14 +494,12 @@ IopDeviceStatus(PPLUGPLAY_CONTROL_STATUS_DATA StatusData)
|
||||
{
|
||||
case PNP_GET_DEVICE_STATUS:
|
||||
DPRINT("Get status data\n");
|
||||
DeviceStatus = DeviceNode->Flags;
|
||||
DeviceStatus = IopGetDeviceNodeStatus(DeviceNode);
|
||||
DeviceProblem = DeviceNode->Problem;
|
||||
break;
|
||||
|
||||
case PNP_SET_DEVICE_STATUS:
|
||||
DPRINT("Set status data\n");
|
||||
DeviceNode->Flags = DeviceStatus;
|
||||
DeviceNode->Problem = DeviceProblem;
|
||||
DPRINT1("Set status data is NOT SUPPORTED\n");
|
||||
break;
|
||||
|
||||
case PNP_CLEAR_DEVICE_STATUS:
|
||||
@@ -576,6 +615,7 @@ IopResetDevice(PPLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData)
|
||||
{
|
||||
/* FIXME: What if the device really is disabled? */
|
||||
DeviceNode->Flags &= ~DNF_DISABLED;
|
||||
DeviceNode->Problem = 0;
|
||||
|
||||
/* Load service data from the registry */
|
||||
Status = IopActionConfigureChildServices(DeviceNode, DeviceNode->Parent);
|
||||
|
||||
@@ -460,6 +460,7 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode,
|
||||
&DeviceNode->InstancePath,
|
||||
Status);
|
||||
IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED);
|
||||
DeviceNode->Problem = CM_PROB_FAILED_ADD;
|
||||
return Status;
|
||||
}
|
||||
|
||||
@@ -663,6 +664,7 @@ IopStartDevice2(IN PDEVICE_OBJECT DeviceObject)
|
||||
|
||||
/* Set the appropriate flag */
|
||||
DeviceNode->Flags |= DNF_START_FAILED;
|
||||
DeviceNode->Problem = CM_PROB_FAILED_START;
|
||||
|
||||
DPRINT1("Warning: PnP Start failed (%wZ) [Status: 0x%x]\n", &DeviceNode->InstancePath, Status);
|
||||
return;
|
||||
@@ -1008,9 +1010,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
|
||||
UNICODE_STRING KeyName, ClassName;
|
||||
PUNICODE_STRING ServiceName1;
|
||||
ULONG LegacyValue;
|
||||
#if 0
|
||||
UNICODE_STRING ClassGUID;
|
||||
#endif
|
||||
HANDLE InstanceHandle;
|
||||
|
||||
DPRINT("ParentNode 0x%p PhysicalDeviceObject 0x%p ServiceName %wZ\n",
|
||||
@@ -1091,17 +1091,21 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
|
||||
{
|
||||
RtlInitUnicodeString(&KeyName, L"Class");
|
||||
|
||||
RtlInitUnicodeString(&ClassName, L"LegacyDriver");
|
||||
Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassName.Buffer, ClassName.Length);
|
||||
#if 0
|
||||
RtlInitUnicodeString(&ClassName, L"LegacyDriver\0");
|
||||
Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassName.Buffer, ClassName.Length + sizeof(UNICODE_NULL));
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
RtlInitUnicodeString(&KeyName, L"ClassGUID");
|
||||
|
||||
RtlInitUnicodeString(&ClassGUID, L"{8ECC055D-047F-11D1-A537-0000F8753ED1}");
|
||||
Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassGUID.Buffer, ClassGUID.Length);
|
||||
RtlInitUnicodeString(&ClassGUID, L"{8ECC055D-047F-11D1-A537-0000F8753ED1}\0");
|
||||
Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ClassGUID.Buffer, ClassGUID.Length + sizeof(UNICODE_NULL));
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
RtlInitUnicodeString(&KeyName, L"DeviceDesc");
|
||||
|
||||
Status = ZwSetValueKey(InstanceHandle, &KeyName, 0, REG_SZ, ServiceName1->Buffer, ServiceName1->Length + sizeof(UNICODE_NULL));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2490,6 +2494,7 @@ IopActionConfigureChildServices(PDEVICE_NODE DeviceNode,
|
||||
}
|
||||
else
|
||||
{
|
||||
DeviceNode->Problem = CM_PROB_FAILED_INSTALL;
|
||||
IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED);
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
@@ -2621,6 +2626,8 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode,
|
||||
{
|
||||
IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED);
|
||||
IopDeviceNodeSetFlag(DeviceNode, DNF_START_FAILED);
|
||||
DeviceNode->Problem = CM_PROB_FAILED_START;
|
||||
|
||||
/* FIXME: Log the error (possibly in IopInitializeDeviceNodeService) */
|
||||
DPRINT1("Initialization of service %S failed (Status %x)\n",
|
||||
DeviceNode->ServiceName.Buffer, Status);
|
||||
|
||||
Reference in New Issue
Block a user