-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/driver.c
#include <internal/debug.h>
/* ke/main.c */
-extern LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock;
+extern LOADER_PARAMETER_BLOCK KeLoaderBlock;
extern ULONG KeTickCount;
-
-NTSTATUS
-LdrProcessModule(PVOID ModuleLoadBase,
- PUNICODE_STRING ModuleName,
- PMODULE_OBJECT *ModuleObject);
+extern BOOLEAN SetupMode;
+extern BOOLEAN NoGuiBoot;
typedef struct _SERVICE_GROUP
{
static LIST_ENTRY ServiceListHead = {NULL, NULL};
static UNICODE_STRING IopHardwareDatabaseKey =
- ROS_STRING_INITIALIZER(L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM");
+ RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM");
-POBJECT_TYPE EXPORTED IoDriverObjectType = NULL;
-
-#define TAG_DRIVER TAG('D', 'R', 'V', 'R')
-#define TAG_DRIVER_EXTENSION TAG('D', 'R', 'V', 'E')
+POBJECT_TYPE IoDriverObjectType = NULL;
/* DECLARATIONS ***************************************************************/
VOID STDCALL
IopDeleteDriver(PVOID ObjectBody);
+NTSTATUS
+LdrProcessModule(PVOID ModuleLoadBase,
+ PUNICODE_STRING ModuleName,
+ PLDR_DATA_TABLE_ENTRY *ModuleObject);
+
+VOID
+FASTCALL
+INIT_FUNCTION
+IopDisplayLoadingMessage(PVOID ServiceName,
+ BOOLEAN Unicode);
+
+static VOID INIT_FUNCTION
+MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length);
+
+NTSTATUS FASTCALL INIT_FUNCTION
+IopInitializeBuiltinDriver(
+ PDEVICE_NODE ModuleDeviceNode,
+ PVOID ModuleLoadBase,
+ PCHAR FileName,
+ ULONG ModuleLength);
+
+static INIT_FUNCTION NTSTATUS
+IopLoadDriver(PSERVICE Service);
+
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, IopInitDriverImplementation)
+#pragma alloc_text(INIT, IopDisplayLoadingMessage)
+#pragma alloc_text(INIT, IoCreateDriverList)
+#pragma alloc_text(INIT, IoDestroyDriverList)
+#pragma alloc_text(INIT, MiFreeBootDriverMemory)
+#pragma alloc_text(INIT, IopInitializeBuiltinDriver)
+#pragma alloc_text(INIT, IopLoadDriver)
+#endif
+
+
/* PRIVATE FUNCTIONS **********************************************************/
VOID
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
UNICODE_STRING Name;
- DPRINT1("Creating Registry Object Type\n");
+ DPRINT("Creating Registry Object Type\n");
/* Initialize the Driver object type */
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
KIRQL OldIrql;
PPRIVATE_DRIVER_EXTENSIONS DriverExtension, NextDriverExtension;
- DPRINT("IopDeleteDriver(ObjectBody %x)\n", ObjectBody);
+ DPRINT("IopDeleteDriver(ObjectBody 0x%p)\n", ObjectBody);
ExFreePool(Object->DriverExtension);
ExFreePool(Object->DriverName.Buffer);
KfLowerIrql(OldIrql);
}
+NTSTATUS FASTCALL
+IopGetDriverObject(
+ PDRIVER_OBJECT *DriverObject,
+ PUNICODE_STRING ServiceName,
+ BOOLEAN FileSystem)
+{
+ PDRIVER_OBJECT Object;
+ WCHAR NameBuffer[MAX_PATH];
+ UNICODE_STRING DriverName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ NTSTATUS Status;
+
+ DPRINT("IopOpenDriverObject(%p '%wZ' %x)\n",
+ DriverObject, ServiceName, FileSystem);
+
+ *DriverObject = NULL;
+
+ /* Create ModuleName string */
+ if (ServiceName == NULL || ServiceName->Buffer == NULL)
+ /* We don't know which DriverObject we have to open */
+ return STATUS_INVALID_PARAMETER_2;
+
+ DriverName.Buffer = NameBuffer;
+ DriverName.Length = 0;
+ DriverName.MaximumLength = sizeof(NameBuffer);
+
+ if (FileSystem == TRUE)
+ RtlAppendUnicodeToString(&DriverName, FILESYSTEM_ROOT_NAME);
+ else
+ RtlAppendUnicodeToString(&DriverName, DRIVER_ROOT_NAME);
+ RtlAppendUnicodeStringToString(&DriverName, ServiceName);
+
+ DPRINT("Driver name: '%wZ'\n", &DriverName);
+
+ /* Initialize ObjectAttributes for driver object */
+ InitializeObjectAttributes(
+ &ObjectAttributes,
+ &DriverName,
+ OBJ_OPENIF | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ /* Open driver object */
+ Status = ObReferenceObjectByName(
+ &DriverName,
+ 0, /* Attributes */
+ NULL, /* PassedAccessState */
+ 0, /* DesiredAccess */
+ IoDriverObjectType,
+ KernelMode,
+ NULL, /* ParseContext */
+ (PVOID*)&Object);
+
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ *DriverObject = Object;
+
+ return STATUS_SUCCESS;
+}
+
NTSTATUS FASTCALL
IopCreateDriverObject(
PDRIVER_OBJECT *DriverObject,
RtlInitUnicodeString(&DriverName, NameBuffer);
DPRINT("Driver name: '%wZ'\n", &DriverName);
- Buffer = (PWSTR)ExAllocatePool(NonPagedPool, DriverName.Length);
+ Buffer = (PWSTR)ExAllocatePool(PagedPool, DriverName.Length + sizeof(WCHAR));
/* If we don't success, it is not a problem. Our driver
* object will not have associated driver name... */
}
return Status;
}
- if (Status == STATUS_OBJECT_EXISTS)
+ Status = ObInsertObject(Object,
+ NULL,
+ FILE_ALL_ACCESS,
+ 0,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
{
- /* The driver object already exists, so it is already
- * initialized. Don't initialize it once more. */
- *DriverObject = Object;
- return STATUS_SUCCESS;
- }
+ return Status;
+ }
- /* Create driver extension */
+ /* Create driver extension */
Object->DriverExtension = (PDRIVER_EXTENSION)
ExAllocatePoolWithTag(
NonPagedPool,
if (!Object->DriverName.Buffer)
{
Object->DriverName.Buffer = Buffer;
- Object->DriverName.Length = Object->DriverName.MaximumLength = DriverName.Length;
+ Object->DriverName.Length = DriverName.Length;
+ Object->DriverName.MaximumLength = DriverName.Length + sizeof(WCHAR);
RtlCopyMemory(Object->DriverName.Buffer, DriverName.Buffer, DriverName.Length);
+ Object->DriverName.Buffer[Object->DriverName.Length / sizeof(WCHAR)] = L'\0';
}
else
ExFreePool(Buffer);
* Display 'Loading XXX...' message.
*/
-VOID FASTCALL
-IopDisplayLoadingMessage(PWCHAR ServiceName)
+VOID
+FASTCALL
+INIT_FUNCTION
+IopDisplayLoadingMessage(PVOID ServiceName,
+ BOOLEAN Unicode)
{
- CHAR TextBuffer[256];
- sprintf(TextBuffer, "Loading %S...\n", ServiceName);
- HalDisplayString(TextBuffer);
+ CHAR TextBuffer[256];
+ if (SetupMode || !NoGuiBoot) return;
+ if (Unicode)
+ {
+ sprintf(TextBuffer, "Loading %S...\n", (PWCHAR)ServiceName);
+ }
+ else
+ {
+ sprintf(TextBuffer, "Loading %s...\n", (PCHAR)ServiceName);
+ }
+ HalDisplayString(TextBuffer);
}
/*
NTSTATUS FASTCALL
IopLoadServiceModule(
IN PUNICODE_STRING ServiceName,
- OUT PMODULE_OBJECT *ModuleObject)
+ OUT PLDR_DATA_TABLE_ENTRY *ModuleObject)
{
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
ULONG ServiceStart;
UNICODE_STRING ServiceImagePath;
NTSTATUS Status;
- DPRINT("IopLoadServiceModule(%wZ, %x)\n", ServiceName, ModuleObject);
+ DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
/*
* Get information about the service.
DPRINT("RtlQueryRegistryValues() failed (Status %x)\n", Status);
return Status;
}
-
- IopDisplayLoadingMessage(ServiceName->Buffer);
+
+ //IopDisplayLoadingMessage(ServiceName->Buffer, TRUE);
/*
* Normalize the image path for all later processing.
break;
}
}
+ if (!NT_SUCCESS(Status))
+ /* Try to load it. It may just have been installed by PnP manager */
+ Status = LdrLoadModule(&ServiceImagePath, ModuleObject);
}
/*
NTSTATUS FASTCALL
IopInitializeDriverModule(
IN PDEVICE_NODE DeviceNode,
- IN PMODULE_OBJECT ModuleObject,
+ IN PLDR_DATA_TABLE_ENTRY ModuleObject,
IN PUNICODE_STRING ServiceName,
IN BOOLEAN FileSystemDriver,
OUT PDRIVER_OBJECT *DriverObject)
ServiceName,
0,
FileSystemDriver,
- ModuleObject->Base,
- ModuleObject->Length);
+ ModuleObject->DllBase,
+ ModuleObject->SizeOfImage);
if (!NT_SUCCESS(Status))
{
PDEVICE_NODE DeviceNode = Context;
UNICODE_STRING ServiceName;
PWCHAR Filters;
- PMODULE_OBJECT ModuleObject;
+ PLDR_DATA_TABLE_ENTRY ModuleObject;
PDRIVER_OBJECT DriverObject;
NTSTATUS Status;
else
{
/* get existing DriverObject pointer */
- Status = IopCreateDriverObject(
+ Status = IopGetDriverObject(
&DriverObject,
&ServiceName,
- OBJ_OPENIF,
- FALSE,
- ModuleObject->Base,
- ModuleObject->Length);
+ FALSE);
if (!NT_SUCCESS(Status))
continue;
}
{
PSERVICE_GROUP Group;
- DPRINT("IopGetGroupOrderList(%S, %x, %x, %x, %x, %x)\n",
+ DPRINT("IopGetGroupOrderList(%S, %x, 0x%p, %x, 0x%p, 0x%p)\n",
ValueName, ValueType, ValueData, ValueLength, Context, EntryContext);
if (ValueType == REG_BINARY &&
RtlZeroMemory(Group, sizeof(SERVICE_GROUP));
- if (!RtlpCreateUnicodeString(&Group->GroupName, (PWSTR)ValueData, NonPagedPool))
+ if (!RtlCreateUnicodeString(&Group->GroupName, (PWSTR)ValueData))
{
ExFreePool(Group);
return(STATUS_INSUFFICIENT_RESOURCES);
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
PKEY_BASIC_INFORMATION KeyInfo = NULL;
OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING ServicesKeyName;
+ UNICODE_STRING ServicesKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services");
UNICODE_STRING SubKeyName;
HANDLE KeyHandle;
NTSTATUS Status;
return(Status);
/* Enumerate services and create the service list */
- RtlRosInitUnicodeStringFromLiteral(&ServicesKeyName,
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Services");
-
InitializeObjectAttributes(&ObjectAttributes,
&ServicesKeyName,
OBJ_CASE_INSENSITIVE,
NTSTATUS INIT_FUNCTION
IoDestroyDriverList(VOID)
{
- PLIST_ENTRY GroupEntry;
- PLIST_ENTRY ServiceEntry;
- PSERVICE_GROUP CurrentGroup;
- PSERVICE CurrentService;
+ PSERVICE_GROUP CurrentGroup, tmp1;
+ PSERVICE CurrentService, tmp2;
DPRINT("IoDestroyDriverList() called\n");
/* Destroy group list */
- GroupEntry = GroupListHead.Flink;
- while (GroupEntry != &GroupListHead)
+ LIST_FOR_EACH_SAFE(CurrentGroup, tmp1, &GroupListHead, SERVICE_GROUP, GroupListEntry)
{
- CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
-
ExFreePool(CurrentGroup->GroupName.Buffer);
- RemoveEntryList(GroupEntry);
+ RemoveEntryList(&CurrentGroup->GroupListEntry);
if (CurrentGroup->TagArray)
{
ExFreePool(CurrentGroup->TagArray);
}
ExFreePool(CurrentGroup);
-
- GroupEntry = GroupListHead.Flink;
}
/* Destroy service list */
- ServiceEntry = ServiceListHead.Flink;
- while (ServiceEntry != &ServiceListHead)
+ LIST_FOR_EACH_SAFE(CurrentService, tmp2, &ServiceListHead, SERVICE, ServiceListEntry)
{
- CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
-
ExFreePool(CurrentService->ServiceName.Buffer);
ExFreePool(CurrentService->RegistryPath.Buffer);
ExFreePool(CurrentService->ServiceGroup.Buffer);
ExFreePool(CurrentService->ImagePath.Buffer);
- RemoveEntryList(ServiceEntry);
+ RemoveEntryList(&CurrentService->ServiceListEntry);
ExFreePool(CurrentService);
-
- ServiceEntry = ServiceListHead.Flink;
}
DPRINT("IoDestroyDriverList() done\n");
return(STATUS_SUCCESS);
}
-VOID STATIC INIT_FUNCTION
+static VOID INIT_FUNCTION
MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length)
{
ULONG i;
PCHAR FileName,
ULONG ModuleLength)
{
- PMODULE_OBJECT ModuleObject;
+ PLDR_DATA_TABLE_ENTRY ModuleObject;
PDEVICE_NODE DeviceNode;
PDRIVER_OBJECT DriverObject;
NTSTATUS Status;
- CHAR TextBuffer[256];
PCHAR FileNameWithoutPath;
LPWSTR FileExtension;
FileName, ModuleLoadBase, ModuleLength);
/*
- * Display 'Initializing XXX...' message
+ * Display 'Loading XXX...' message
*/
-
- sprintf(TextBuffer, "Initializing %s...\n", FileName);
- HalDisplayString(TextBuffer);
+ IopDisplayLoadingMessage(FileName, FALSE);
/*
* Determine the right device object
Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode);
if (!NT_SUCCESS(Status))
{
- CPRINT("Driver load failed, status (%x)\n", Status);
+ CPRINT("Driver '%s' load failed, status (%x)\n", FileName, Status);
return(Status);
}
} else
{
if (ModuleDeviceNode == NULL)
IopFreeDeviceNode(DeviceNode);
- CPRINT("Driver load failed, status (%x)\n", Status);
+ CPRINT("Driver '%s' load failed, status (%x)\n", FileName, Status);
return Status;
}
{
if (ModuleDeviceNode == NULL)
IopFreeDeviceNode(DeviceNode);
- CPRINT("Driver load failed, status (%x)\n", Status);
+ CPRINT("Driver '%s' load failed, status (%x)\n", FileName, Status);
return Status;
}
if (BootDriverCount == 0)
{
DbgPrint("No boot drivers available.\n");
- KEBUGCHECK(0);
+ KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
}
}
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
- IopDisplayLoadingMessage(Service->ServiceName.Buffer);
+ IopDisplayLoadingMessage(Service->ServiceName.Buffer, TRUE);
Status = ZwLoadDriver(&Service->RegistryPath);
IopBootLog(&Service->ImagePath, NT_SUCCESS(Status) ? TRUE : FALSE);
if (!NT_SUCCESS(Status))
VOID FASTCALL
IopInitializeSystemDrivers(VOID)
{
- PLIST_ENTRY GroupEntry;
- PLIST_ENTRY ServiceEntry;
PSERVICE_GROUP CurrentGroup;
PSERVICE CurrentService;
NTSTATUS Status;
DPRINT("IopInitializeSystemDrivers()\n");
- GroupEntry = GroupListHead.Flink;
- while (GroupEntry != &GroupListHead)
+ LIST_FOR_EACH(CurrentGroup, &GroupListHead, SERVICE_GROUP, GroupListEntry)
{
- CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry);
-
DPRINT("Group: %wZ\n", &CurrentGroup->GroupName);
/* Load all drivers with a valid tag */
for (i = 0; i < CurrentGroup->TagCount; i++)
{
- ServiceEntry = ServiceListHead.Flink;
- while (ServiceEntry != &ServiceListHead)
+ LIST_FOR_EACH(CurrentService, &ServiceListHead, SERVICE, ServiceListEntry)
{
- CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
-
if ((RtlCompareUnicodeString(&CurrentGroup->GroupName,
&CurrentService->ServiceGroup, TRUE) == 0) &&
(CurrentService->Start == 1 /*SERVICE_SYSTEM_START*/) &&
DPRINT(" Path: %wZ\n", &CurrentService->RegistryPath);
Status = IopLoadDriver(CurrentService);
}
- ServiceEntry = ServiceEntry->Flink;
}
}
/* Load all drivers without a tag or with an invalid tag */
- ServiceEntry = ServiceListHead.Flink;
- while (ServiceEntry != &ServiceListHead)
+ LIST_FOR_EACH(CurrentService, &ServiceListHead, SERVICE, ServiceListEntry)
{
- CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry);
if ((RtlCompareUnicodeString(&CurrentGroup->GroupName,
&CurrentService->ServiceGroup, TRUE) == 0) &&
(CurrentService->Start == 1 /*SERVICE_SYSTEM_START*/))
Status = IopLoadDriver(CurrentService);
}
}
- ServiceEntry = ServiceEntry->Flink;
}
- GroupEntry = GroupEntry->Flink;
}
DPRINT("IopInitializeSystemDrivers() done\n");
UNICODE_STRING ServiceName;
UNICODE_STRING ObjectName;
PDRIVER_OBJECT DriverObject;
- PMODULE_OBJECT ModuleObject;
+ PLDR_DATA_TABLE_ENTRY ModuleObject;
NTSTATUS Status;
LPWSTR Start;
DPRINT("IopUnloadDriver('%wZ', %d)\n", DriverServiceName, UnloadPnpDrivers);
+ PAGED_CODE();
+
/*
* Get the service name from the registry key name
*/
ObjectName.Length = (wcslen(Start) + 8) * sizeof(WCHAR);
ObjectName.MaximumLength = ObjectName.Length + sizeof(WCHAR);
- ObjectName.Buffer = ExAllocatePool(NonPagedPool, ObjectName.MaximumLength);
+ ObjectName.Buffer = ExAllocatePool(PagedPool, ObjectName.MaximumLength);
wcscpy(ObjectName.Buffer, L"\\Driver\\");
memcpy(ObjectName.Buffer + 8, Start, (ObjectName.Length - 8) * sizeof(WCHAR));
ObjectName.Buffer[ObjectName.Length/sizeof(WCHAR)] = 0;
KeAcquireSpinLock(&DriverReinitListLock,
&Irql);
- if (DriverReinitTailEntry == NULL)
- {
- KeReleaseSpinLock(&DriverReinitListLock,
- Irql);
- return;
- }
+ Entry = DriverReinitTailEntry;
KeReleaseSpinLock(&DriverReinitListLock,
Irql);
+ if (Entry == NULL)
+ {
+ return;
+ }
+
for (;;)
{
Entry = ExInterlockedRemoveHeadList(&DriverReinitListHead,
RTL_QUERY_REGISTRY_TABLE QueryTable[3];
UNICODE_STRING ImagePath;
UNICODE_STRING ServiceName;
- UNICODE_STRING CapturedDriverServiceName;
+ UNICODE_STRING CapturedDriverServiceName = {0};
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
ULONG Type;
PDEVICE_NODE DeviceNode;
- PMODULE_OBJECT ModuleObject;
+ PLDR_DATA_TABLE_ENTRY ModuleObject;
PDRIVER_OBJECT DriverObject;
WCHAR *cur;
}
#endif
- Status = RtlCaptureUnicodeString(&CapturedDriverServiceName,
- PreviousMode,
- PagedPool,
- FALSE,
- DriverServiceName);
+ Status = ProbeAndCaptureUnicodeString(&CapturedDriverServiceName,
+ PreviousMode,
+ DriverServiceName);
if (!NT_SUCCESS(Status))
{
return Status;
* Set a service name for the device node
*/
- RtlpCreateUnicodeString(&DeviceNode->ServiceName, ServiceName.Buffer, NonPagedPool);
+ RtlCreateUnicodeString(&DeviceNode->ServiceName, ServiceName.Buffer);
/*
* Initialize the driver module
Status = IopStartDevice(DeviceNode);
ReleaseCapturedString:
- RtlReleaseCapturedUnicodeString(&CapturedDriverServiceName,
- PreviousMode,
- FALSE);
+ ReleaseCapturedUnicodeString(&CapturedDriverServiceName,
+ PreviousMode);
return Status;
}