Author: cgutman
Date: Sun Mar 25 23:28:23 2012
New Revision: 56231
URL:
http://svn.reactos.org/svn/reactos?rev=56231&view=rev
Log:
[NTOSKRNL]
- Implement proper use of alternate resource requirement lists
- Implement the case to set DN_NO_SHOW_IN_DM
- Implement reporting more problem codes: CM_PROB_NEED_RESTART,
CM_PROB_FAILED_DRIVER_ENTRY, CM_PROB_FAILED_DRIVER_ENTRY, CM_PROB_DRIVER_FAILED_LOAD,
CM_PROB_WILL_BE_REMOVED, CM_PROB_HELD_FOR_EJECT, CM_PROB_TRANSLATION_FAILED, and
CM_PROB_NORMAL_CONFLICT
Modified:
trunk/reactos/ntoskrnl/io/iomgr/driver.c
trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnpres.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/driver.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/driver.c…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/driver.c [iso-8859-1] Sun Mar 25 23:28:23 2012
@@ -402,8 +402,8 @@
if (ServiceStart >= 4)
{
- /* FIXME: Check if it is the right status code */
- Status = STATUS_PLUGPLAY_NO_DEVICE;
+ /* We can't load this */
+ Status = STATUS_DRIVER_UNABLE_TO_LOAD;
}
else
{
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/plugpla…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/plugplay.c [iso-8859-1] Sun Mar 25 23:28:23 2012
@@ -441,6 +441,9 @@
if (DeviceNode->Flags & DNF_LEGACY_DRIVER)
Output |= DN_LEGACY_DRIVER;
+ if (DeviceNode->UserFlags & DNUF_DONT_SHOW_IN_UI)
+ Output |= DN_NO_SHOW_IN_DM;
+
/* FIXME: Implement the rest */
Output |= DN_NT_ENUMERATOR | DN_NT_DRIVER;
@@ -611,6 +614,7 @@
{
/* A driver has already been loaded for this device */
DPRINT1("A reboot is required for the current driver for '%wZ'
to be replaced\n", &DeviceNode->InstancePath);
+ DeviceNode->Problem = CM_PROB_NEED_RESTART;
}
}
else
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c [iso-8859-1] Sun Mar 25 23:28:23 2012
@@ -2624,11 +2624,18 @@
/* Initialize the driver */
Status = IopInitializeDriverModule(DeviceNode, ModuleObject,
&DeviceNode->ServiceName, FALSE, &DriverObject);
+ if (!NT_SUCCESS(Status)) DeviceNode->Problem =
CM_PROB_FAILED_DRIVER_ENTRY;
+ }
+ else if (Status == STATUS_DRIVER_UNABLE_TO_LOAD)
+ {
+ DPRINT1("Service '%wZ' is disabled\n",
&DeviceNode->ServiceName);
+ DeviceNode->Problem = CM_PROB_DISABLED_SERVICE;
}
else
{
DPRINT("IopLoadServiceModule(%wZ) failed with status 0x%08x\n",
&DeviceNode->ServiceName, Status);
+ if (!BootDrivers) DeviceNode->Problem = CM_PROB_DRIVER_FAILED_LOAD;
}
}
@@ -2649,12 +2656,6 @@
if (!BootDrivers)
{
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);
}
}
}
@@ -4504,7 +4505,7 @@
}
Stack.Parameters.QueryDeviceRelations.Type = RemovalRelations;
-
+
Status = IopInitiatePnpIrp(DeviceObject,
&IoStatusBlock,
IRP_MN_QUERY_DEVICE_RELATIONS,
@@ -4518,7 +4519,7 @@
{
DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
}
-
+
if (DeviceRelations)
{
Status = IopQueryRemoveDeviceRelations(DeviceRelations, Force);
@@ -4535,6 +4536,7 @@
}
DeviceNode->Flags |= DNF_WILL_BE_REMOVED;
+ DeviceNode->Problem = CM_PROB_WILL_BE_REMOVED;
if (DeviceRelations)
IopSendRemoveDeviceRelations(DeviceRelations);
IopSendRemoveChildDevices(DeviceNode);
@@ -4625,7 +4627,8 @@
if (DeviceRelations)
IopSendRemoveDeviceRelations(DeviceRelations);
IopSendRemoveChildDevices(DeviceNode);
-
+
+ DeviceNode->Problem = CM_PROB_HELD_FOR_EJECT;
if (Capabilities.EjectSupported)
{
if (IopSendEject(PhysicalDeviceObject) != STATUS_SUCCESS)
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpres.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnpres.…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnpres.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpres.c [iso-8859-1] Sun Mar 25 23:28:23 2012
@@ -202,12 +202,48 @@
IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList,
OUT PCM_RESOURCE_LIST *ResourceList)
{
- ULONG i;
+ ULONG i, OldCount;
+ BOOLEAN AlternateRequired = FALSE;
+
+ /* Save the initial resource count when we got here so we can restore if an alternate
fails */
+ if (*ResourceList != NULL)
+ OldCount = (*ResourceList)->List[0].PartialResourceList.Count;
+ else
+ OldCount = 0;
+
for (i = 0; i < RequirementsList->AlternativeLists; i++)
{
ULONG ii;
PIO_RESOURCE_LIST ResList = &RequirementsList->List[i];
- BOOLEAN AlternateRequired = FALSE;
+
+ /* We need to get back to where we were before processing the last alternative
list */
+ if (OldCount == 0 && *ResourceList != NULL)
+ {
+ /* Just free it and kill the pointer */
+ ExFreePool(*ResourceList);
+ *ResourceList = NULL;
+ }
+ else if (OldCount != 0)
+ {
+ PCM_RESOURCE_LIST NewList;
+
+ /* Let's resize it */
+ (*ResourceList)->List[0].PartialResourceList.Count = OldCount;
+
+ /* Allocate the new smaller list */
+ NewList = ExAllocatePool(PagedPool,
PnpDetermineResourceListSize(*ResourceList));
+ if (!NewList)
+ return STATUS_NO_MEMORY;
+
+ /* Copy the old stuff back */
+ RtlCopyMemory(NewList, *ResourceList,
PnpDetermineResourceListSize(*ResourceList));
+
+ /* Free the old one */
+ ExFreePool(*ResourceList);
+
+ /* Store the pointer to the new one */
+ *ResourceList = NewList;
+ }
for (ii = 0; ii < ResList->Count; ii++)
{
@@ -226,14 +262,10 @@
/* Check if we couldn't satsify a requirement or its alternates */
if (AlternateRequired && !(IoDesc->Option &
IO_RESOURCE_ALTERNATIVE))
{
- DPRINT1("Unable to satisfy preferred resource or
alternates\n");
-
- if (*ResourceList)
- {
- ExFreePool(*ResourceList);
- *ResourceList = NULL;
- }
- return STATUS_CONFLICTING_ADDRESSES;
+ DPRINT1("Unable to satisfy preferred resource or alternates in list
%d\n", i);
+
+ /* Break out of this loop and try the next list */
+ break;
}
for (iii = 0; PartialList && iii < PartialList->Count
&& !Matched; iii++)
@@ -411,12 +443,9 @@
/* Check if it's missing and required */
if (!FoundResource && IoDesc->Option == 0)
{
- if (*ResourceList)
- {
- ExFreePool(*ResourceList);
- *ResourceList = NULL;
- }
- return STATUS_CONFLICTING_ADDRESSES;
+ /* Break out of this loop and try the next list */
+ DPRINT1("Unable to satisfy required resource in list %d\n",
i);
+ break;
}
else if (!FoundResource)
{
@@ -476,10 +505,32 @@
*ResourceList = NewList;
}
}
+
+ /* Check if we need an alternate with no resources left */
+ if (AlternateRequired)
+ {
+ DPRINT1("Unable to satisfy preferred resource or alternates in list
%d\n", i);
+
+ /* Try the next alternate list */
+ continue;
+ }
+
+ /* We're done because we satisfied one of the alternate lists */
+ return STATUS_SUCCESS;
}
- /* Done */
- return STATUS_SUCCESS;
+ /* We ran out of alternates */
+ DPRINT1("Out of alternate lists!\n");
+
+ /* Free the list */
+ if (*ResourceList)
+ {
+ ExFreePool(*ResourceList);
+ *ResourceList = NULL;
+ }
+
+ /* Fail */
+ return STATUS_CONFLICTING_ADDRESSES;
}
static
@@ -717,28 +768,28 @@
OBJECT_ATTRIBUTES ObjectAttributes;
RtlInitUnicodeString(&KeyName,
- L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
+ L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
- 0,
- NULL);
+ &KeyName,
+ OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+ 0,
+ NULL);
Status = ZwCreateKey(&ResourceMapKey,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- REG_OPTION_VOLATILE,
- &Disposition);
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ &Disposition);
if (!NT_SUCCESS(Status))
return Status;
RtlInitUnicodeString(&KeyName, Level1Key);
InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
- ResourceMapKey,
- NULL);
+ &KeyName,
+ OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+ ResourceMapKey,
+ NULL);
Status = ZwCreateKey(&PnpMgrLevel1,
KEY_ALL_ACCESS,
&ObjectAttributes,
@@ -752,10 +803,10 @@
RtlInitUnicodeString(&KeyName, Level2Key);
InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
- PnpMgrLevel1,
- NULL);
+ &KeyName,
+ OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
+ PnpMgrLevel1,
+ NULL);
Status = ZwCreateKey(&PnpMgrLevel2,
KEY_ALL_ACCESS,
&ObjectAttributes,
@@ -1069,6 +1120,7 @@
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to fixup a resource list from supplied resources for
%wZ\n", &DeviceNode->InstancePath);
+ DeviceNode->Problem = CM_PROB_NORMAL_CONFLICT;
goto ByeBye;
}
@@ -1079,6 +1131,7 @@
Status = IopTranslateDeviceResources(DeviceNode);
if (!NT_SUCCESS(Status))
{
+ DeviceNode->Problem = CM_PROB_TRANSLATION_FAILED;
DPRINT1("Failed to translate resources for %wZ\n",
&DeviceNode->InstancePath);
goto ByeBye;
}