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/plugplay... ============================================================================== --- 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.c... ============================================================================== --- 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.c... ============================================================================== --- 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; }