- Rewritten some driver loading functions to get higher control of the driver loading and initialization process (Fixes bug #263).

- Added support for lower level filter drivers.

svn path=/trunk/; revision=8891
This commit is contained in:
Filip Navara 2004-03-27 19:41:32 +00:00
parent bf1b24c1fb
commit 014d8e9588
7 changed files with 1260 additions and 1179 deletions

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: io.h,v 1.40 2004/03/21 18:58:52 navaraf Exp $ /* $Id: io.h,v 1.41 2004/03/27 19:41:31 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -32,6 +32,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/ob.h> #include <internal/ob.h>
#include <internal/module.h>
#ifndef __USE_W32API #ifndef __USE_W32API
@ -62,7 +63,6 @@ typedef struct _DEVICE_NODE
struct _DEVICE_NODE *PrevSibling; struct _DEVICE_NODE *PrevSibling;
struct _DEVICE_NODE *NextSibling; struct _DEVICE_NODE *NextSibling;
struct _DEVICE_NODE *Child; struct _DEVICE_NODE *Child;
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT Pdo; PDEVICE_OBJECT Pdo;
UNICODE_STRING InstancePath; UNICODE_STRING InstancePath;
UNICODE_STRING ServiceName; UNICODE_STRING ServiceName;
@ -266,19 +266,6 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode,
NTSTATUS NTSTATUS
IopFreeDeviceNode(PDEVICE_NODE DeviceNode); IopFreeDeviceNode(PDEVICE_NODE DeviceNode);
NTSTATUS
IopCreateDriverObject(PDRIVER_OBJECT *DriverObject,
PUNICODE_STRING ServiceName,
BOOLEAN FileSystemDriver,
PVOID DriverImageStart,
ULONG DriverImageSize);
NTSTATUS
IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry,
PDEVICE_NODE DeviceNode,
BOOLEAN FileSystemDriver,
PVOID DriverImageStart,
ULONG DriverImageSize,
BOOLEAN BootDriver);
VOID VOID
IoInitCancelHandling(VOID); IoInitCancelHandling(VOID);
VOID VOID
@ -388,37 +375,48 @@ PnpRootCreateDevice(
/* device.c */ /* device.c */
NTSTATUS NTSTATUS FASTCALL
IopAttachFilterDrivers( IopInitializeDevice(
PDEVICE_NODE DeviceNode, PDEVICE_NODE DeviceNode,
BOOLEAN Lower); PDRIVER_OBJECT DriverObject);
NTSTATUS
IopInitializeService(
PDEVICE_NODE DeviceNode,
PUNICODE_STRING ServiceName,
PUNICODE_STRING ImagePath);
/* driver.c */ /* driver.c */
VOID VOID FASTCALL
IopInitializeBootDrivers( IopInitializeBootDrivers(VOID);
VOID);
VOID VOID FASTCALL
IopInitializeSystemDrivers( IopInitializeSystemDrivers(VOID);
VOID);
NTSTATUS NTSTATUS FASTCALL
IopInitializeDeviceNodeService( IopCreateDriverObject(
PDEVICE_NODE DeviceNode, PDRIVER_OBJECT *DriverObject,
PUNICODE_STRING ServiceName, PUNICODE_STRING ServiceName,
BOOLEAN BootDriverOnly); BOOLEAN FileSystemDriver,
PVOID DriverImageStart,
ULONG DriverImageSize);
VOID NTSTATUS FASTCALL
IopLoadServiceModule(
IN PUNICODE_STRING ServiceName,
OUT PMODULE_OBJECT *ModuleObject);
NTSTATUS FASTCALL
IopInitializeDriverModule(
IN PDEVICE_NODE DeviceNode,
IN PMODULE_OBJECT ModuleObject,
IN BOOLEAN FileSystemDriver,
OUT PDRIVER_OBJECT *DriverObject);
NTSTATUS FASTCALL
IopAttachFilterDrivers(
PDEVICE_NODE DeviceNode,
BOOLEAN Lower);
VOID FASTCALL
IopMarkLastReinitializeDriver(VOID); IopMarkLastReinitializeDriver(VOID);
VOID VOID FASTCALL
IopReinitializeDrivers(VOID); IopReinitializeDrivers(VOID);
/* pnpmgr.c */ /* pnpmgr.c */
@ -431,7 +429,6 @@ IopInitializePnpServices(
NTSTATUS NTSTATUS
IopInvalidateDeviceRelations( IopInvalidateDeviceRelations(
IN PDEVICE_NODE DeviceNode, IN PDEVICE_NODE DeviceNode,
IN DEVICE_RELATION_TYPE Type, IN DEVICE_RELATION_TYPE Type);
IN BOOLEAN BootDriver);
#endif #endif

View file

@ -34,11 +34,6 @@ LdrInitModuleManagement (
VOID VOID
); );
NTSTATUS
LdrInitializeBootStartDriver(IN PVOID ModuleLoadBase,
IN PCHAR FileName,
IN ULONG ModuleLength);
NTSTATUS NTSTATUS
LdrpMapSystemDll ( LdrpMapSystemDll (
HANDLE ProcessHandle, HANDLE ProcessHandle,

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* $Id: iomgr.c,v 1.45 2003/12/31 14:20:26 hbirr Exp $ /* $Id: iomgr.c,v 1.46 2004/03/27 19:41:32 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -16,6 +16,7 @@
#include <internal/ob.h> #include <internal/ob.h>
#include <internal/io.h> #include <internal/io.h>
#include <internal/pool.h> #include <internal/pool.h>
#include <internal/module.h>
#include <rosrtl/string.h> #include <rosrtl/string.h>
#define NDEBUG #define NDEBUG
@ -367,6 +368,8 @@ VOID INIT_FUNCTION
IoInit2(VOID) IoInit2(VOID)
{ {
PDEVICE_NODE DeviceNode; PDEVICE_NODE DeviceNode;
PDRIVER_OBJECT DriverObject;
MODULE_OBJECT ModuleObject;
NTSTATUS Status; NTSTATUS Status;
KeInitializeSpinLock (&IoStatisticsLock); KeInitializeSpinLock (&IoStatisticsLock);
@ -383,12 +386,15 @@ IoInit2(VOID)
return; return;
} }
Status = IopInitializeDriver(RawFsDriverEntry, ModuleObject.Base = NULL;
ModuleObject.Length = 0;
ModuleObject.EntryPoint = RawFsDriverEntry;
Status = IopInitializeDriverModule(
DeviceNode, DeviceNode,
&ModuleObject,
TRUE, TRUE,
NULL, &DriverObject);
0,
FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
IopFreeDeviceNode(DeviceNode); IopFreeDeviceNode(DeviceNode);
@ -396,13 +402,20 @@ IoInit2(VOID)
return; return;
} }
Status = IopInitializeDevice(DeviceNode, DriverObject);
if (!NT_SUCCESS(Status))
{
IopFreeDeviceNode(DeviceNode);
CPRINT("IopInitializeDevice() failed with status (%x)\n", Status);
return;
}
/* /*
* Initialize PnP root releations * Initialize PnP root releations
*/ */
IopInvalidateDeviceRelations( IopInvalidateDeviceRelations(
IopRootDeviceNode, IopRootDeviceNode,
BusRelations, BusRelations);
TRUE);
} }
/* /*

View file

@ -1,4 +1,4 @@
/* $Id: pnpmgr.c,v 1.27 2004/03/21 18:58:53 navaraf Exp $ /* $Id: pnpmgr.c,v 1.28 2004/03/27 19:41:32 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -1068,15 +1068,28 @@ IopActionInitChildServices(
!IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) && !IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) &&
!IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED)) !IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED))
{ {
Status = IopInitializeDeviceNodeService( PMODULE_OBJECT ModuleObject;
DeviceNode, PDRIVER_OBJECT DriverObject;
&DeviceNode->ServiceName,
BootDrivers); Status = IopLoadServiceModule(&DeviceNode->ServiceName, &ModuleObject);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
IopAttachFilterDrivers(DeviceNode, FALSE); Status = IopInitializeDriverModule(DeviceNode, ModuleObject, FALSE, &DriverObject);
IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); if (NT_SUCCESS(Status))
} else {
/* Attach lower level filter drivers. */
IopAttachFilterDrivers(DeviceNode, TRUE);
/* Initialize the function driver for the device node */
Status = IopInitializeDevice(DeviceNode, DriverObject);
if (NT_SUCCESS(Status))
{
IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED);
/* Attach upper level filter drivers. */
IopAttachFilterDrivers(DeviceNode, FALSE);
}
}
}
else
{ {
/* /*
* Don't disable when trying to load only boot drivers * Don't disable when trying to load only boot drivers
@ -1138,6 +1151,7 @@ IopActionInitBootServices(
* Parameters * Parameters
* DeviceNode * DeviceNode
* Top device node to start initializing services. * Top device node to start initializing services.
*
* BootDrivers * BootDrivers
* When set to TRUE, only drivers marked as boot start will * When set to TRUE, only drivers marked as boot start will
* be loaded. Otherwise, all drivers will be loaded. * be loaded. Otherwise, all drivers will be loaded.
@ -1177,15 +1191,18 @@ IopInitializePnpServices(
NTSTATUS NTSTATUS
IopInvalidateDeviceRelations( IopInvalidateDeviceRelations(
IN PDEVICE_NODE DeviceNode, IN PDEVICE_NODE DeviceNode,
IN DEVICE_RELATION_TYPE Type, IN DEVICE_RELATION_TYPE Type)
IN BOOLEAN BootDriver)
{ {
DEVICETREE_TRAVERSE_CONTEXT Context; DEVICETREE_TRAVERSE_CONTEXT Context;
PDEVICE_RELATIONS DeviceRelations; PDEVICE_RELATIONS DeviceRelations;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
PDEVICE_NODE ChildDeviceNode; PDEVICE_NODE ChildDeviceNode;
IO_STACK_LOCATION Stack; IO_STACK_LOCATION Stack;
BOOL BootDrivers;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING LinkName;
HANDLE Handle;
NTSTATUS Status; NTSTATUS Status;
ULONG i; ULONG i;
@ -1276,12 +1293,39 @@ IopInvalidateDeviceRelations(
return Status; return Status;
} }
/*
* Get the state of the system boot. If the \\SystemRoot link isn't
* created yet, we will assume that it's possible to load only boot
* drivers.
*/
RtlInitUnicodeString(&LinkName, L"\\SystemRoot");
InitializeObjectAttributes(
&ObjectAttributes,
&LinkName,
0,
NULL,
NULL);
Status = NtOpenFile(
&Handle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
0,
0);
BootDrivers = NT_SUCCESS(Status) ? FALSE : TRUE;
NtClose(Handle);
/* /*
* Initialize services for discovered children. Only boot drivers will * Initialize services for discovered children. Only boot drivers will
* be loaded from boot driver! * be loaded from boot driver!
*/ */
Status = IopInitializePnpServices(DeviceNode, BootDriver); Status = IopInitializePnpServices(DeviceNode, BootDrivers);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("IopInitializePnpServices() failed with status (%x)\n", Status); DPRINT("IopInitializePnpServices() failed with status (%x)\n", Status);
@ -1326,8 +1370,8 @@ PnpInit(VOID)
CPRINT("Insufficient resources\n"); CPRINT("Insufficient resources\n");
KEBUGCHECK(PHASE1_INITIALIZATION_FAILED); KEBUGCHECK(PHASE1_INITIALIZATION_FAILED);
} }
IopRootDeviceNode->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; IopRootDeviceNode->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
IopRootDeviceNode->DriverObject = IopRootDriverObject;
PnpRootDriverEntry(IopRootDriverObject, NULL); PnpRootDriverEntry(IopRootDriverObject, NULL);
IopRootDriverObject->DriverExtension->AddDevice( IopRootDriverObject->DriverExtension->AddDevice(
IopRootDriverObject, IopRootDriverObject,

View file

@ -1,4 +1,4 @@
/* $Id: loader.c,v 1.140 2004/03/07 11:59:10 navaraf Exp $ /* $Id: loader.c,v 1.141 2004/03/27 19:41:32 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -449,107 +449,6 @@ LdrUnloadModule(PMODULE_OBJECT ModuleObject)
} }
NTSTATUS INIT_FUNCTION
LdrInitializeBootStartDriver(PVOID ModuleLoadBase,
PCHAR FileName,
ULONG ModuleLength)
{
PMODULE_OBJECT ModuleObject;
UNICODE_STRING ModuleName;
PDEVICE_NODE DeviceNode;
NTSTATUS Status;
WCHAR Buffer[MAX_PATH];
ULONG Length;
LPWSTR Start;
LPWSTR Ext;
PCHAR FileExt;
CHAR TextBuffer [256];
ULONG x, y, cx, cy;
HalQueryDisplayParameters(&x, &y, &cx, &cy);
RtlFillMemory(TextBuffer, x, ' ');
TextBuffer[x] = '\0';
HalSetDisplayParameters(0, y-1);
HalDisplayString(TextBuffer);
sprintf(TextBuffer, "Initializing %s...\n", FileName);
HalSetDisplayParameters(0, y-1);
HalDisplayString(TextBuffer);
HalSetDisplayParameters(cx, cy);
/* Split the filename into base name and extension */
FileExt = strrchr(FileName, '.');
if (FileExt != NULL)
Length = FileExt - FileName;
else
Length = strlen(FileName);
if ((FileExt != NULL) && (strcmp(FileExt, ".sym") == 0))
{
KDB_SYMBOLFILE_HOOK(ModuleLoadBase, FileName, Length);
return(STATUS_SUCCESS);
}
else if ((FileExt != NULL) && !(strcmp(FileExt, ".sys") == 0))
{
CPRINT("Ignoring non-driver file %s\n", FileName);
return STATUS_SUCCESS;
}
/* Use IopRootDeviceNode for now */
Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode);
if (!NT_SUCCESS(Status))
{
CPRINT("Driver load failed, status (%x)\n", Status);
return(Status);
}
RtlCreateUnicodeStringFromAsciiz(&ModuleName,
FileName);
Status = LdrProcessModule(ModuleLoadBase,
&ModuleName,
&ModuleObject);
RtlFreeUnicodeString(&ModuleName);
if (ModuleObject == NULL)
{
IopFreeDeviceNode(DeviceNode);
CPRINT("Driver load failed, status (%x)\n", Status);
return(STATUS_UNSUCCESSFUL);
}
/* Get the service name from the module name */
Start = wcsrchr(ModuleObject->BaseName.Buffer, L'\\');
if (Start == NULL)
Start = ModuleObject->BaseName.Buffer;
else
Start++;
Ext = wcsrchr(ModuleObject->BaseName.Buffer, L'.');
if (Ext != NULL)
Length = Ext - Start;
else
Length = wcslen(Start);
wcsncpy(Buffer, Start, Length);
Buffer[Length] = 0;
RtlCreateUnicodeString(&DeviceNode->ServiceName, Buffer);
Status = IopInitializeDriver(ModuleObject->EntryPoint,
DeviceNode, FALSE,
ModuleObject->Base,
ModuleObject->Length,
TRUE);
if (!NT_SUCCESS(Status))
{
IopFreeDeviceNode(DeviceNode);
CPRINT("Driver load failed, status (%x)\n", Status);
}
return(Status);
}
NTSTATUS NTSTATUS
LdrProcessModule(PVOID ModuleLoadBase, LdrProcessModule(PVOID ModuleLoadBase,
PUNICODE_STRING ModuleName, PUNICODE_STRING ModuleName,