Author: hpoussin Date: Sat Jul 7 01:12:44 2007 New Revision: 27435
URL: http://svn.reactos.org/svn/reactos?rev=27435&view=rev Log: Simplify IoSynchronousInvalidateDeviceRelations/IoInvalidateDeviceRelations IoInvalidateDeviceRelations now creates a workitem, which will call IoSynchronousInvalidateDeviceRelations()
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
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 (original) +++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c Sat Jul 7 01:12:44 2007 @@ -37,16 +37,10 @@
typedef struct _INVALIDATE_DEVICE_RELATION_DATA { + PDEVICE_OBJECT DeviceObject; DEVICE_RELATION_TYPE Type; PIO_WORKITEM WorkItem; - PKEVENT Event; - NTSTATUS Status; } INVALIDATE_DEVICE_RELATION_DATA, *PINVALIDATE_DEVICE_RELATION_DATA; - -static VOID NTAPI -IopInvalidateDeviceRelations( - IN PDEVICE_OBJECT DeviceObject, - IN PVOID InvalidateContext);
VOID NTAPI @@ -253,6 +247,22 @@ &Stack); }
+static VOID NTAPI +IopAsynchronousInvalidateDeviceRelations( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID InvalidateContext) +{ + PINVALIDATE_DEVICE_RELATION_DATA Data = InvalidateContext; + + IoSynchronousInvalidateDeviceRelations( + Data->DeviceObject, + Data->Type); + + ObDereferenceObject(Data->WorkItem); + IoFreeWorkItem(Data->WorkItem); + ExFreePool(Data); +} + /* * @implemented */ @@ -275,53 +285,16 @@ return; }
+ ObReferenceObject(DeviceObject); + Data->DeviceObject = DeviceObject; Data->Type = Type; Data->WorkItem = WorkItem; - Data->Event = NULL;
IoQueueWorkItem( WorkItem, - IopInvalidateDeviceRelations, + IopAsynchronousInvalidateDeviceRelations, DelayedWorkQueue, Data); -} - -/* - * @implemented - */ -VOID -NTAPI -IoSynchronousInvalidateDeviceRelations( - IN PDEVICE_OBJECT DeviceObject, - IN DEVICE_RELATION_TYPE Type) -{ - PIO_WORKITEM WorkItem; - PINVALIDATE_DEVICE_RELATION_DATA Data; - KEVENT Event; - - Data = ExAllocatePool(PagedPool, sizeof(INVALIDATE_DEVICE_RELATION_DATA)); - if (!Data) - return; - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) - { - ExFreePool(Data); - return; - } - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - Data->Type = Type; - Data->WorkItem = WorkItem; - Data->Event = &Event; - - IoQueueWorkItem( - WorkItem, - IopInvalidateDeviceRelations, - DelayedWorkQueue, - Data); - - KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); - ExFreePool(Data); }
/* @@ -2186,359 +2159,15 @@ }
/* - * IopActionConfigureChildServices - * - * Retrieve configuration for all (direct) child nodes of a parent node. - * - * Parameters - * DeviceNode - * Pointer to device node. - * Context - * Pointer to parent node to retrieve child node configuration for. - * - * Remarks - * We only return a status code indicating an error (STATUS_UNSUCCESSFUL) - * when we reach a device node which is not a direct child of the device - * node for which we configure child services for. Any errors that occur is - * logged instead so that all child services have a chance of beeing - * configured. + * @implemented */ - -NTSTATUS -IopActionConfigureChildServices(PDEVICE_NODE DeviceNode, - PVOID Context) -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[3]; - PDEVICE_NODE ParentDeviceNode; - PUNICODE_STRING Service; - UNICODE_STRING ClassGUID; - NTSTATUS Status; - - DPRINT("IopActionConfigureChildServices(%p, %p)\n", DeviceNode, Context); - - ParentDeviceNode = (PDEVICE_NODE)Context; - - /* - * We are called for the parent too, but we don't need to do special - * handling for this node - */ - if (DeviceNode == ParentDeviceNode) - { - DPRINT("Success\n"); - return STATUS_SUCCESS; - } - - /* - * Make sure this device node is a direct child of the parent device node - * that is given as an argument - */ - if (DeviceNode->Parent != ParentDeviceNode) - { - /* Stop the traversal immediately and indicate successful operation */ - DPRINT("Stop\n"); - return STATUS_UNSUCCESSFUL; - } - - if (!IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED)) - { - WCHAR RegKeyBuffer[MAX_PATH]; - UNICODE_STRING RegKey; - - RegKey.Length = 0; - RegKey.MaximumLength = sizeof(RegKeyBuffer); - RegKey.Buffer = RegKeyBuffer; - - /* - * Retrieve configuration from Enum key - */ - - Service = &DeviceNode->ServiceName; - - RtlZeroMemory(QueryTable, sizeof(QueryTable)); - RtlInitUnicodeString(Service, NULL); - RtlInitUnicodeString(&ClassGUID, NULL); - - QueryTable[0].Name = L"Service"; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; - QueryTable[0].EntryContext = Service; - - QueryTable[1].Name = L"ClassGUID"; - QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[1].EntryContext = &ClassGUID; - QueryTable[1].DefaultType = REG_SZ; - QueryTable[1].DefaultData = L""; - QueryTable[1].DefaultLength = 0; - - RtlAppendUnicodeToString(&RegKey, L"\Registry\Machine\System\CurrentControlSet\Enum\"); - RtlAppendUnicodeStringToString(&RegKey, &DeviceNode->InstancePath); - - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - RegKey.Buffer, QueryTable, NULL, NULL); - - if (!NT_SUCCESS(Status)) - { - /* FIXME: Log the error */ - DPRINT("Could not retrieve configuration for device %wZ (Status 0x%08x)\n", - &DeviceNode->InstancePath, Status); - IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); - return STATUS_SUCCESS; - } - - if (Service->Buffer == NULL) - { - IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); - - if (ClassGUID.Length != 0) - { - /* Device has a ClassGUID value, but no Service value. - * Suppose it is using the NULL driver, so state the - * device is started */ - DPRINT1("%wZ is using NULL driver\n", &DeviceNode->InstancePath); - IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); - DeviceNode->Flags |= DN_STARTED; - } - return STATUS_SUCCESS; - } - - DPRINT("Got Service %S\n", Service->Buffer); - } - - return STATUS_SUCCESS; -} - -/* - * IopActionInitChildServices - * - * Initialize the service for all (direct) child nodes of a parent node - * - * Parameters - * DeviceNode - * Pointer to device node. - * Context - * Pointer to parent node to initialize child node services for. - * BootDrivers - * Load only driver marked as boot start. - * - * Remarks - * If the driver image for a service is not loaded and initialized - * it is done here too. We only return a status code indicating an - * error (STATUS_UNSUCCESSFUL) when we reach a device node which is - * not a direct child of the device node for which we initialize - * child services for. Any errors that occur is logged instead so - * that all child services have a chance of being initialized. - */ - -NTSTATUS -IopActionInitChildServices(PDEVICE_NODE DeviceNode, - PVOID Context, - BOOLEAN BootDrivers) -{ - PDEVICE_NODE ParentDeviceNode; - NTSTATUS Status; - - DPRINT("IopActionInitChildServices(%p, %p, %d)\n", DeviceNode, Context, - BootDrivers); - - ParentDeviceNode = (PDEVICE_NODE)Context; - - /* - * We are called for the parent too, but we don't need to do special - * handling for this node - */ - if (DeviceNode == ParentDeviceNode) - { - DPRINT("Success\n"); - return STATUS_SUCCESS; - } - - /* - * Make sure this device node is a direct child of the parent device node - * that is given as an argument - */ -#if 0 - if (DeviceNode->Parent != ParentDeviceNode) - { - /* - * Stop the traversal immediately and indicate unsuccessful operation - */ - DPRINT("Stop\n"); - return STATUS_UNSUCCESSFUL; - } -#endif - - if (!IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED) && - !IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) && - !IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED)) - { - PLDR_DATA_TABLE_ENTRY ModuleObject; - PDRIVER_OBJECT DriverObject; - - /* Get existing DriverObject pointer (in case the driver has - already been loaded and initialized) */ - Status = IopGetDriverObject( - &DriverObject, - &DeviceNode->ServiceName, - FALSE); - - if (!NT_SUCCESS(Status)) - { - /* Driver is not initialized, try to load it */ - Status = IopLoadServiceModule(&DeviceNode->ServiceName, &ModuleObject); - - if (NT_SUCCESS(Status) || Status == STATUS_IMAGE_ALREADY_LOADED) - { - /* STATUS_IMAGE_ALREADY_LOADED means this driver - was loaded by the bootloader */ - if (Status != STATUS_IMAGE_ALREADY_LOADED) - { - /* Initialize the driver */ - Status = IopInitializeDriverModule(DeviceNode, ModuleObject, - &DeviceNode->ServiceName, FALSE, &DriverObject); - } - else - { - Status = STATUS_SUCCESS; - } - } - else - { - DPRINT1("IopLoadServiceModule(%wZ) failed with status 0x%08x\n", - &DeviceNode->ServiceName, Status); - } - } - - /* Driver is loaded and initialized at this point */ - if (NT_SUCCESS(Status)) - { - /* We have a driver for this DeviceNode */ - DeviceNode->Flags |= DN_DRIVER_LOADED; - /* Attach lower level filter drivers. */ - IopAttachFilterDrivers(DeviceNode, TRUE); - /* Initialize the function driver for the device node */ - Status = IopInitializeDevice(DeviceNode, DriverObject); - - if (NT_SUCCESS(Status)) - { - /* Attach upper level filter drivers. */ - IopAttachFilterDrivers(DeviceNode, FALSE); - IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); - - Status = IopStartDevice(DeviceNode); - } - else - { - DPRINT1("IopInitializeDevice(%wZ) failed with status 0x%08x\n", - &DeviceNode->InstancePath, Status); - } - } - else - { - /* - * Don't disable when trying to load only boot drivers - */ - if (!BootDrivers) - { - IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); - IopDeviceNodeSetFlag(DeviceNode, DNF_START_FAILED); - /* FIXME: Log the error (possibly in IopInitializeDeviceNodeService) */ - CPRINT("Initialization of service %S failed (Status %x)\n", - DeviceNode->ServiceName.Buffer, Status); - } - } - } - else - { - DPRINT("Device %wZ is disabled or already initialized\n", - &DeviceNode->InstancePath); - } - - return STATUS_SUCCESS; -} - -/* - * IopActionInitAllServices - * - * Initialize the service for all (direct) child nodes of a parent node. This - * function just calls IopActionInitChildServices with BootDrivers = FALSE. - */ - -NTSTATUS -IopActionInitAllServices(PDEVICE_NODE DeviceNode, - PVOID Context) -{ - return IopActionInitChildServices(DeviceNode, Context, FALSE); -} - -/* - * IopActionInitBootServices - * - * Initialize the boot start services for all (direct) child nodes of a - * parent node. This function just calls IopActionInitChildServices with - * BootDrivers = TRUE. - */ -NTSTATUS -IopActionInitBootServices(PDEVICE_NODE DeviceNode, - PVOID Context) -{ - return IopActionInitChildServices(DeviceNode, Context, TRUE); -} - -/* - * IopInitializePnpServices - * - * Initialize services for discovered children - * - * Parameters - * DeviceNode - * Top device node to start initializing services. - * - * BootDrivers - * When set to TRUE, only drivers marked as boot start will - * be loaded. Otherwise, all drivers will be loaded. - * - * Return Value - * Status - */ -NTSTATUS -IopInitializePnpServices(IN PDEVICE_NODE DeviceNode, - IN BOOLEAN BootDrivers) -{ - DEVICETREE_TRAVERSE_CONTEXT Context; - - DPRINT("IopInitializePnpServices(%p, %d)\n", DeviceNode, BootDrivers); - - if (BootDrivers) - { - IopInitDeviceTreeTraverseContext( - &Context, - DeviceNode, - IopActionInitBootServices, - DeviceNode); - } - else - { - IopInitDeviceTreeTraverseContext( - &Context, - DeviceNode, - IopActionInitAllServices, - DeviceNode); - } - - return IopTraverseDeviceTree(&Context); -} - -/* Invalidate device list enumerated by a device node. - * The call can be make synchronous by defining the Event field - * of the INVALIDATE_DEVICE_RELATION_DATA structure - */ -static VOID NTAPI -IopInvalidateDeviceRelations( +VOID +NTAPI +IoSynchronousInvalidateDeviceRelations( IN PDEVICE_OBJECT DeviceObject, - IN PVOID InvalidateContext) /* PINVALIDATE_DEVICE_RELATION_DATA */ -{ - PINVALIDATE_DEVICE_RELATION_DATA Data = InvalidateContext; + IN DEVICE_RELATION_TYPE Type) +{ PDEVICE_NODE DeviceNode = IopGetDeviceNode(DeviceObject); - PKEVENT Event = Data->Event; DEVICETREE_TRAVERSE_CONTEXT Context; PDEVICE_RELATIONS DeviceRelations; IO_STATUS_BLOCK IoStatusBlock; @@ -2555,7 +2184,7 @@
DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
- Stack.Parameters.QueryDeviceRelations.Type = Data->Type; + Stack.Parameters.QueryDeviceRelations.Type = Type;
Status = IopInitiatePnpIrp( DeviceObject, @@ -2565,7 +2194,7 @@ if (!NT_SUCCESS(Status)) { DPRINT("IopInitiatePnpIrp() failed with status 0x%08lx\n", Status); - goto cleanup; + return; }
DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information; @@ -2577,8 +2206,7 @@ { ExFreePool(DeviceRelations); } - Status = STATUS_SUCCESS; - goto cleanup; + return; }
DPRINT("Got %d PDOs\n", DeviceRelations->Count); @@ -2605,8 +2233,7 @@ for (i = 0; i < DeviceRelations->Count; i++) ObDereferenceObject(DeviceRelations->Objects[i]); ExFreePool(DeviceRelations); - Status = STATUS_NO_MEMORY; - goto cleanup; + return; } } ExFreePool(DeviceRelations); @@ -2624,7 +2251,7 @@ if (!NT_SUCCESS(Status)) { DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status); - goto cleanup; + return; }
/* @@ -2640,7 +2267,7 @@ if (!NT_SUCCESS(Status)) { DPRINT("IopTraverseDeviceTree() failed with status 0x%08lx\n", Status); - goto cleanup; + return; }
/* @@ -2677,21 +2304,352 @@ if (!NT_SUCCESS(Status)) { DPRINT("IopInitializePnpServices() failed with status 0x%08lx\n", Status); - goto cleanup; + return; }
DPRINT("IopInvalidateDeviceRelations() finished\n"); - Status = STATUS_SUCCESS; - -cleanup: - IoFreeWorkItem(Data->WorkItem); - if (Event) - { - Data->Status = Status; - KeSetEvent(Event, 0, FALSE); - } - else - ExFreePool(Data); +} + +/* + * IopActionConfigureChildServices + * + * Retrieve configuration for all (direct) child nodes of a parent node. + * + * Parameters + * DeviceNode + * Pointer to device node. + * Context + * Pointer to parent node to retrieve child node configuration for. + * + * Remarks + * We only return a status code indicating an error (STATUS_UNSUCCESSFUL) + * when we reach a device node which is not a direct child of the device + * node for which we configure child services for. Any errors that occur is + * logged instead so that all child services have a chance of beeing + * configured. + */ + +NTSTATUS +IopActionConfigureChildServices(PDEVICE_NODE DeviceNode, + PVOID Context) +{ + RTL_QUERY_REGISTRY_TABLE QueryTable[3]; + PDEVICE_NODE ParentDeviceNode; + PUNICODE_STRING Service; + UNICODE_STRING ClassGUID; + NTSTATUS Status; + + DPRINT("IopActionConfigureChildServices(%p, %p)\n", DeviceNode, Context); + + ParentDeviceNode = (PDEVICE_NODE)Context; + + /* + * We are called for the parent too, but we don't need to do special + * handling for this node + */ + if (DeviceNode == ParentDeviceNode) + { + DPRINT("Success\n"); + return STATUS_SUCCESS; + } + + /* + * Make sure this device node is a direct child of the parent device node + * that is given as an argument + */ + if (DeviceNode->Parent != ParentDeviceNode) + { + /* Stop the traversal immediately and indicate successful operation */ + DPRINT("Stop\n"); + return STATUS_UNSUCCESSFUL; + } + + if (!IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED)) + { + WCHAR RegKeyBuffer[MAX_PATH]; + UNICODE_STRING RegKey; + + RegKey.Length = 0; + RegKey.MaximumLength = sizeof(RegKeyBuffer); + RegKey.Buffer = RegKeyBuffer; + + /* + * Retrieve configuration from Enum key + */ + + Service = &DeviceNode->ServiceName; + + RtlZeroMemory(QueryTable, sizeof(QueryTable)); + RtlInitUnicodeString(Service, NULL); + RtlInitUnicodeString(&ClassGUID, NULL); + + QueryTable[0].Name = L"Service"; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; + QueryTable[0].EntryContext = Service; + + QueryTable[1].Name = L"ClassGUID"; + QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[1].EntryContext = &ClassGUID; + QueryTable[1].DefaultType = REG_SZ; + QueryTable[1].DefaultData = L""; + QueryTable[1].DefaultLength = 0; + + RtlAppendUnicodeToString(&RegKey, L"\Registry\Machine\System\CurrentControlSet\Enum\"); + RtlAppendUnicodeStringToString(&RegKey, &DeviceNode->InstancePath); + + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + RegKey.Buffer, QueryTable, NULL, NULL); + + if (!NT_SUCCESS(Status)) + { + /* FIXME: Log the error */ + DPRINT("Could not retrieve configuration for device %wZ (Status 0x%08x)\n", + &DeviceNode->InstancePath, Status); + IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); + return STATUS_SUCCESS; + } + + if (Service->Buffer == NULL) + { + IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); + + if (ClassGUID.Length != 0) + { + /* Device has a ClassGUID value, but no Service value. + * Suppose it is using the NULL driver, so state the + * device is started */ + DPRINT1("%wZ is using NULL driver\n", &DeviceNode->InstancePath); + IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); + DeviceNode->Flags |= DN_STARTED; + } + return STATUS_SUCCESS; + } + + DPRINT("Got Service %S\n", Service->Buffer); + } + + return STATUS_SUCCESS; +} + +/* + * IopActionInitChildServices + * + * Initialize the service for all (direct) child nodes of a parent node + * + * Parameters + * DeviceNode + * Pointer to device node. + * Context + * Pointer to parent node to initialize child node services for. + * BootDrivers + * Load only driver marked as boot start. + * + * Remarks + * If the driver image for a service is not loaded and initialized + * it is done here too. We only return a status code indicating an + * error (STATUS_UNSUCCESSFUL) when we reach a device node which is + * not a direct child of the device node for which we initialize + * child services for. Any errors that occur is logged instead so + * that all child services have a chance of being initialized. + */ + +NTSTATUS +IopActionInitChildServices(PDEVICE_NODE DeviceNode, + PVOID Context, + BOOLEAN BootDrivers) +{ + PDEVICE_NODE ParentDeviceNode; + NTSTATUS Status; + + DPRINT("IopActionInitChildServices(%p, %p, %d)\n", DeviceNode, Context, + BootDrivers); + + ParentDeviceNode = (PDEVICE_NODE)Context; + + /* + * We are called for the parent too, but we don't need to do special + * handling for this node + */ + if (DeviceNode == ParentDeviceNode) + { + DPRINT("Success\n"); + return STATUS_SUCCESS; + } + + /* + * Make sure this device node is a direct child of the parent device node + * that is given as an argument + */ +#if 0 + if (DeviceNode->Parent != ParentDeviceNode) + { + /* + * Stop the traversal immediately and indicate unsuccessful operation + */ + DPRINT("Stop\n"); + return STATUS_UNSUCCESSFUL; + } +#endif + + if (!IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED) && + !IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) && + !IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED)) + { + PLDR_DATA_TABLE_ENTRY ModuleObject; + PDRIVER_OBJECT DriverObject; + + /* Get existing DriverObject pointer (in case the driver has + already been loaded and initialized) */ + Status = IopGetDriverObject( + &DriverObject, + &DeviceNode->ServiceName, + FALSE); + + if (!NT_SUCCESS(Status)) + { + /* Driver is not initialized, try to load it */ + Status = IopLoadServiceModule(&DeviceNode->ServiceName, &ModuleObject); + + if (NT_SUCCESS(Status) || Status == STATUS_IMAGE_ALREADY_LOADED) + { + /* STATUS_IMAGE_ALREADY_LOADED means this driver + was loaded by the bootloader */ + if (Status != STATUS_IMAGE_ALREADY_LOADED) + { + /* Initialize the driver */ + Status = IopInitializeDriverModule(DeviceNode, ModuleObject, + &DeviceNode->ServiceName, FALSE, &DriverObject); + } + else + { + Status = STATUS_SUCCESS; + } + } + else + { + DPRINT1("IopLoadServiceModule(%wZ) failed with status 0x%08x\n", + &DeviceNode->ServiceName, Status); + } + } + + /* Driver is loaded and initialized at this point */ + if (NT_SUCCESS(Status)) + { + /* We have a driver for this DeviceNode */ + DeviceNode->Flags |= DN_DRIVER_LOADED; + /* Attach lower level filter drivers. */ + IopAttachFilterDrivers(DeviceNode, TRUE); + /* Initialize the function driver for the device node */ + Status = IopInitializeDevice(DeviceNode, DriverObject); + + if (NT_SUCCESS(Status)) + { + /* Attach upper level filter drivers. */ + IopAttachFilterDrivers(DeviceNode, FALSE); + IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); + + Status = IopStartDevice(DeviceNode); + } + else + { + DPRINT1("IopInitializeDevice(%wZ) failed with status 0x%08x\n", + &DeviceNode->InstancePath, Status); + } + } + else + { + /* + * Don't disable when trying to load only boot drivers + */ + if (!BootDrivers) + { + IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); + IopDeviceNodeSetFlag(DeviceNode, DNF_START_FAILED); + /* FIXME: Log the error (possibly in IopInitializeDeviceNodeService) */ + CPRINT("Initialization of service %S failed (Status %x)\n", + DeviceNode->ServiceName.Buffer, Status); + } + } + } + else + { + DPRINT("Device %wZ is disabled or already initialized\n", + &DeviceNode->InstancePath); + } + + return STATUS_SUCCESS; +} + +/* + * IopActionInitAllServices + * + * Initialize the service for all (direct) child nodes of a parent node. This + * function just calls IopActionInitChildServices with BootDrivers = FALSE. + */ + +NTSTATUS +IopActionInitAllServices(PDEVICE_NODE DeviceNode, + PVOID Context) +{ + return IopActionInitChildServices(DeviceNode, Context, FALSE); +} + +/* + * IopActionInitBootServices + * + * Initialize the boot start services for all (direct) child nodes of a + * parent node. This function just calls IopActionInitChildServices with + * BootDrivers = TRUE. + */ +NTSTATUS +IopActionInitBootServices(PDEVICE_NODE DeviceNode, + PVOID Context) +{ + return IopActionInitChildServices(DeviceNode, Context, TRUE); +} + +/* + * IopInitializePnpServices + * + * Initialize services for discovered children + * + * Parameters + * DeviceNode + * Top device node to start initializing services. + * + * BootDrivers + * When set to TRUE, only drivers marked as boot start will + * be loaded. Otherwise, all drivers will be loaded. + * + * Return Value + * Status + */ +NTSTATUS +IopInitializePnpServices(IN PDEVICE_NODE DeviceNode, + IN BOOLEAN BootDrivers) +{ + DEVICETREE_TRAVERSE_CONTEXT Context; + + DPRINT("IopInitializePnpServices(%p, %d)\n", DeviceNode, BootDrivers); + + if (BootDrivers) + { + IopInitDeviceTreeTraverseContext( + &Context, + DeviceNode, + IopActionInitBootServices, + DeviceNode); + } + else + { + IopInitDeviceTreeTraverseContext( + &Context, + DeviceNode, + IopActionInitAllServices, + DeviceNode); + } + + return IopTraverseDeviceTree(&Context); }
static NTSTATUS INIT_FUNCTION