Author: fireball
Date: Tue Jun 12 02:02:55 2007
New Revision: 27151
URL:
http://svn.reactos.org/svn/reactos?rev=27151&view=rev
Log:
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.
Modified:
trunk/reactos/media/inf/netamd.inf
trunk/reactos/ntoskrnl/io/iomgr/driver.c
trunk/reactos/ntoskrnl/io/iomgr/iomgr.c
trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c
Modified: trunk/reactos/media/inf/netamd.inf
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/media/inf/netamd.inf?rev=2…
==============================================================================
--- trunk/reactos/media/inf/netamd.inf (original)
+++ trunk/reactos/media/inf/netamd.inf Tue Jun 12 02:02:55 2007
@@ -18,7 +18,7 @@
%AMDMfg% = AMDMfg
[AMDMfg]
-%PCNET.DeviceDesc% = PCNet_Inst,PCI\VEN_1022&DEV_2000
+;%PCNET.DeviceDesc% = PCNet_Inst,PCI\VEN_1022&DEV_2000
;----------------------------- PCNET DRIVER -----------------------------
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 (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/driver.c Tue Jun 12 02:02:55 2007
@@ -125,7 +125,7 @@
/* 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,9 +134,14 @@
(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 @@
&ServiceName,
FALSE);
if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("IopGetDriverObject() returned status 0x%08x!\n", Status);
continue;
+ }
}
Status = IopInitializeDevice(DeviceNode, DriverObject);
@@ -772,6 +780,7 @@
/*
* Initialize the driver
*/
+ DeviceNode->Flags |= DN_DRIVER_LOADED;
Status = IopInitializeDriverModule(DeviceNode, LdrEntry,
&DeviceNode->ServiceName, FALSE, &DriverObject);
@@ -813,6 +822,8 @@
LDR_DATA_TABLE_ENTRY ModuleObject;
NTSTATUS Status;
UNICODE_STRING DriverName;
+
+ DPRINT("IopInitializeBootDrivers()");
/* Use IopRootDeviceNode for now */
Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, NULL, &DeviceNode);
@@ -874,6 +885,7 @@
/* 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 @@
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 @@
goto ReleaseCapturedString;
}
- /*
- * Load the driver module
- */
-
- Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject,
NULL);
+ /* 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("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);
-
- 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);
Modified: trunk/reactos/ntoskrnl/io/iomgr/iomgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/iomgr.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/iomgr.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/iomgr.c Tue Jun 12 02:02:55 2007
@@ -497,19 +497,19 @@
/* Initialize PnP manager */
PnpInit();
+ /* Create the group driver list */
+ IoCreateDriverList();
+
+ /* Load boot start drivers */
+ IopInitializeBootDrivers();
+
+ /* Call back drivers that asked for */
+ IopReinitializeBootDrivers();
+
/* Initialize PnP root relations */
IoSynchronousInvalidateDeviceRelations(IopRootDeviceNode->
PhysicalDeviceObject,
BusRelations);
-
- /* Create the group driver list */
- IoCreateDriverList();
-
- /* Load boot start drivers */
- IopInitializeBootDrivers();
-
- /* Call back drivers that asked for */
- IopReinitializeBootDrivers();
/* Create ARC names for boot devices */
IopCreateArcNames(LoaderBlock);
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 (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c Tue Jun 12 02:02:55 2007
@@ -865,6 +865,7 @@
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 @@
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 @@
Status = IopStartDevice(DeviceNode);
}
}
- }
else
{
/*