mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 00:45:24 +00:00
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
This commit is contained in:
parent
8bb5ea4208
commit
5b7bb95ec1
4 changed files with 87 additions and 47 deletions
|
@ -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 -----------------------------
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue