-/* $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;
extern BOOLEAN SetupMode;
-
-NTSTATUS
-LdrProcessModule(PVOID ModuleLoadBase,
- PUNICODE_STRING ModuleName,
- PMODULE_OBJECT *ModuleObject);
+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;
+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);
/* 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)
- wcscpy(NameBuffer, FILESYSTEM_ROOT_NAME);
+ RtlAppendUnicodeToString(&DriverName, FILESYSTEM_ROOT_NAME);
else
- wcscpy(NameBuffer, DRIVER_ROOT_NAME);
- wcscat(NameBuffer, ServiceName->Buffer);
+ RtlAppendUnicodeToString(&DriverName, DRIVER_ROOT_NAME);
+ RtlAppendUnicodeStringToString(&DriverName, ServiceName);
- RtlInitUnicodeString(&DriverName, NameBuffer);
DPRINT("Driver name: '%wZ'\n", &DriverName);
/* Initialize ObjectAttributes for driver object */
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... */
}
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);
IopDisplayLoadingMessage(PVOID ServiceName,
BOOLEAN Unicode)
{
- if (SetupMode) return;
CHAR TextBuffer[256];
+ if (SetupMode || !NoGuiBoot) return;
if (Unicode)
{
sprintf(TextBuffer, "Loading %S...\n", (PWCHAR)ServiceName);
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.
return Status;
}
- IopDisplayLoadingMessage(ServiceName->Buffer, TRUE);
+ //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;
{
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;
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);
}
}
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;
}