From 5b7bb95ec1f04aeb9e2bedf95f64bdddae030327 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 11 Jun 2007 22:02:55 +0000 Subject: [PATCH] Massive changes to the driver loading / device creation logic (as a result of collaborative work with Herve): - Really reuse the driver's object, instead of always failing in "IopGetDriverObject()". Fix driver's object creation accordingly in NtLoadDriver() and IopActionInitChildServices(). - Move InvalidateRelations to a later stage, when it really should happen (previously it just delayed the boot process but couldn't load any driver since boot device was inaccessible and reusing drivers loaded by the bootloader was not possible). - Minor bugfixes in various places related to these changes. - Add DPRINTs for easier debugging and failure tracking (silent failure is the worst enemy of a developer). Results: - VMWare video driver regression is gone. - "New device found" wizard appears in the 3rd stage like in "old good times". - Network drivers hang somewhere, so a hack is added to temporarily disable installation of pcnet.sys. svn path=/trunk/; revision=27151 --- reactos/media/inf/netamd.inf | 2 +- reactos/ntoskrnl/io/iomgr/driver.c | 95 ++++++++++++++++++----------- reactos/ntoskrnl/io/iomgr/iomgr.c | 10 +-- reactos/ntoskrnl/io/pnpmgr/pnpmgr.c | 27 ++++++-- 4 files changed, 87 insertions(+), 47 deletions(-) diff --git a/reactos/media/inf/netamd.inf b/reactos/media/inf/netamd.inf index 563b8a5a627..1cd76d849aa 100644 --- a/reactos/media/inf/netamd.inf +++ b/reactos/media/inf/netamd.inf @@ -18,7 +18,7 @@ DefaultDestDir = 12 %AMDMfg% = AMDMfg [AMDMfg] -%PCNET.DeviceDesc% = PCNet_Inst,PCI\VEN_1022&DEV_2000 +;%PCNET.DeviceDesc% = PCNet_Inst,PCI\VEN_1022&DEV_2000 ;----------------------------- PCNET DRIVER ----------------------------- diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index bf3c0444f68..3353bcbc7d7 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -125,7 +125,7 @@ IopGetDriverObject( /* Open driver object */ Status = ObReferenceObjectByName( &DriverName, - OBJ_OPENIF | OBJ_KERNEL_HANDLE, /* Attributes */ + OBJ_OPENIF | OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, /* Attributes */ NULL, /* PassedAccessState */ 0, /* DesiredAccess */ IoDriverObjectType, @@ -134,10 +134,15 @@ IopGetDriverObject( (PVOID*)&Object); if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to reference driver object, status=0x%08x\n", Status); return Status; + } *DriverObject = Object; + DPRINT("Driver Object: %p\n", Object); + return STATUS_SUCCESS; } @@ -498,7 +503,10 @@ IopAttachFilterDriversCallback( &ServiceName, FALSE); if (!NT_SUCCESS(Status)) + { + DPRINT1("IopGetDriverObject() returned status 0x%08x!\n", Status); continue; + } } Status = IopInitializeDevice(DeviceNode, DriverObject); @@ -772,6 +780,7 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry) /* * Initialize the driver */ + DeviceNode->Flags |= DN_DRIVER_LOADED; Status = IopInitializeDriverModule(DeviceNode, LdrEntry, &DeviceNode->ServiceName, FALSE, &DriverObject); @@ -814,6 +823,8 @@ IopInitializeBootDrivers(VOID) NTSTATUS Status; UNICODE_STRING DriverName; + DPRINT("IopInitializeBootDrivers()"); + /* Use IopRootDeviceNode for now */ Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, NULL, &DeviceNode); if (!NT_SUCCESS(Status)) return; @@ -874,6 +885,7 @@ IopInitializeBootDrivers(VOID) /* Make sure we didn't load this driver already */ if (!(LdrEntry->Flags & LDRP_ENTRY_INSERTED)) { + DPRINT("Initializing bootdriver %wZ\n", &LdrEntry->BaseDllName); /* Initialize it */ IopInitializeBuiltinDriver(LdrEntry); } @@ -1233,7 +1245,7 @@ try_again: DriverObject->DriverSize = SizeOfImage; /* Finally, call its init function */ - DPRINT("RegistryKey: %wZ\n", RegistryKey); + DPRINT("RegistryKey: %wZ\n", RegistryPath); DPRINT("Calling driver entrypoint at %p\n", InitializationFunction); Status = (*InitializationFunction)(DriverObject, RegistryPath); if (!NT_SUCCESS(Status)) @@ -1584,42 +1596,55 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName) goto ReleaseCapturedString; } - /* - * Load the driver module - */ - - Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status); - IopFreeDeviceNode(DeviceNode); - goto ReleaseCapturedString; - } - - /* - * Set a service name for the device node - */ - - RtlCreateUnicodeString(&DeviceNode->ServiceName, ServiceName.Buffer); - - /* - * Initialize the driver module - */ - - Status = IopInitializeDriverModule( - DeviceNode, - ModuleObject, - &DeviceNode->ServiceName, - (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ || - Type == 8 /* SERVICE_RECOGNIZER_DRIVER */), - &DriverObject); + /* Get existing DriverObject pointer (in case the driver has + already been loaded and initialized) */ + Status = IopGetDriverObject( + &DriverObject, + &ServiceName, + (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ || + Type == 8 /* SERVICE_RECOGNIZER_DRIVER */)); if (!NT_SUCCESS(Status)) { - DPRINT("IopInitializeDriver() failed (Status %lx)\n", Status); - MmUnloadSystemImage(ModuleObject); - IopFreeDeviceNode(DeviceNode); - goto ReleaseCapturedString; + /* + * Load the driver module + */ + + Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, NULL); + if (!NT_SUCCESS(Status) && Status != STATUS_IMAGE_ALREADY_LOADED) + { + DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status); + IopFreeDeviceNode(DeviceNode); + goto ReleaseCapturedString; + } + + /* + * Set a service name for the device node + */ + + RtlCreateUnicodeString(&DeviceNode->ServiceName, ServiceName.Buffer); + + /* + * Initialize the driver module if it's loaded for the first time + */ + if (Status != STATUS_IMAGE_ALREADY_LOADED) + { + Status = IopInitializeDriverModule( + DeviceNode, + ModuleObject, + &DeviceNode->ServiceName, + (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ || + Type == 8 /* SERVICE_RECOGNIZER_DRIVER */), + &DriverObject); + + if (!NT_SUCCESS(Status)) + { + DPRINT("IopInitializeDriver() failed (Status %lx)\n", Status); + MmUnloadSystemImage(ModuleObject); + IopFreeDeviceNode(DeviceNode); + goto ReleaseCapturedString; + } + } } IopInitializeDevice(DeviceNode, DriverObject); diff --git a/reactos/ntoskrnl/io/iomgr/iomgr.c b/reactos/ntoskrnl/io/iomgr/iomgr.c index 907dc8596b9..390521fc676 100644 --- a/reactos/ntoskrnl/io/iomgr/iomgr.c +++ b/reactos/ntoskrnl/io/iomgr/iomgr.c @@ -497,11 +497,6 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Initialize PnP manager */ PnpInit(); - /* Initialize PnP root relations */ - IoSynchronousInvalidateDeviceRelations(IopRootDeviceNode-> - PhysicalDeviceObject, - BusRelations); - /* Create the group driver list */ IoCreateDriverList(); @@ -511,6 +506,11 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) /* Call back drivers that asked for */ IopReinitializeBootDrivers(); + /* Initialize PnP root relations */ + IoSynchronousInvalidateDeviceRelations(IopRootDeviceNode-> + PhysicalDeviceObject, + BusRelations); + /* Create ARC names for boot devices */ IopCreateArcNames(LoaderBlock); diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 9e79b662c73..8401a901ab1 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -865,6 +865,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, Status = PnpRootCreateDevice(ServiceName, &PhysicalDeviceObject); if (!NT_SUCCESS(Status)) { + DPRINT1("PnpRootCreateDevice() failed with status 0x%08X\n", Status); ExFreePool(Node); return Status; } @@ -2369,29 +2370,44 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode, 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 */ DeviceNode->Flags |= DN_DRIVER_LOADED; Status = IopInitializeDriverModule(DeviceNode, ModuleObject, &DeviceNode->ServiceName, FALSE, &DriverObject); } else { - /* get existing DriverObject pointer */ - Status = IopGetDriverObject( - &DriverObject, - &DeviceNode->ServiceName, - FALSE); + Status = STATUS_SUCCESS; } + } + } + + /* Driver is loaded and initialized at this point */ if (NT_SUCCESS(Status)) { /* 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. */ @@ -2401,7 +2417,6 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode, Status = IopStartDevice(DeviceNode); } } - } else { /*