-/* $Id: driver.c,v 1.39 2004/03/27 19:41:32 navaraf Exp $
+/* $Id: driver.c,v 1.51 2004/09/07 11:48:16 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* INCLUDES *******************************************************************/
-#include <limits.h>
-#include <ddk/ntddk.h>
-#include <internal/io.h>
-#include <internal/po.h>
-#include <internal/ldr.h>
-#include <internal/id.h>
-#include <internal/pool.h>
-#include <internal/se.h>
-#include <internal/mm.h>
-#include <internal/ke.h>
-#include <internal/kd.h>
-#include <rosrtl/string.h>
-
-#include <roscfg.h>
-
+#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
#define TAG_DRIVER TAG('D', 'R', 'V', 'R')
#define TAG_DRIVER_EXTENSION TAG('D', 'R', 'V', 'E')
-#define DRIVER_REGISTRY_KEY_BASENAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
-
-/* PRIVATE FUNCTIONS **********************************************************/
+/* DECLARATIONS ***************************************************************/
NTSTATUS STDCALL
IopCreateDriver(
PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
- POBJECT_ATTRIBUTES ObjectAttributes)
-{
- DPRINT("LdrCreateModule(ObjectBody %x, Parent %x, RemainingPath %S)\n",
- ObjectBody, Parent, RemainingPath);
-
- if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL)
- return STATUS_UNSUCCESSFUL;
+ POBJECT_ATTRIBUTES ObjectAttributes);
- return STATUS_SUCCESS;
-}
+VOID STDCALL
+IopDeleteDriver(PVOID ObjectBody);
+/* PRIVATE FUNCTIONS **********************************************************/
VOID INIT_FUNCTION
IopInitDriverImplementation(VOID)
IoDriverObjectType->Dump = NULL;
IoDriverObjectType->Open = NULL;
IoDriverObjectType->Close = NULL;
- IoDriverObjectType->Delete = NULL;
+ IoDriverObjectType->Delete = IopDeleteDriver;
IoDriverObjectType->Parse = NULL;
IoDriverObjectType->Security = NULL;
IoDriverObjectType->QueryName = NULL;
}
NTSTATUS STDCALL
-IopDefaultDispatchFunction(
+IopInvalidDeviceRequest(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
- Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_NOT_IMPLEMENTED;
+ return STATUS_INVALID_DEVICE_REQUEST;
+}
+
+NTSTATUS STDCALL
+IopCreateDriver(
+ PVOID ObjectBody,
+ PVOID Parent,
+ PWSTR RemainingPath,
+ POBJECT_ATTRIBUTES ObjectAttributes)
+{
+ PDRIVER_OBJECT Object = ObjectBody;
+ ULONG i;
+
+ DPRINT("IopCreateDriver(ObjectBody %x, Parent %x, RemainingPath %S)\n",
+ ObjectBody, Parent, RemainingPath);
+
+ if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL)
+ return STATUS_UNSUCCESSFUL;
+
+ /* Create driver extension */
+ Object->DriverExtension = (PDRIVER_EXTENSION)
+ ExAllocatePoolWithTag(
+ NonPagedPool,
+ sizeof(DRIVER_EXTENSION),
+ TAG_DRIVER_EXTENSION);
+
+ if (Object->DriverExtension == NULL)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION));
+
+ Object->Type = InternalDriverType;
+
+ for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
+ Object->MajorFunction[i] = IopInvalidDeviceRequest;
+
+ return STATUS_SUCCESS;
+}
+
+VOID STDCALL
+IopDeleteDriver(PVOID ObjectBody)
+{
+ PDRIVER_OBJECT Object = ObjectBody;
+ KIRQL OldIrql;
+ PPRIVATE_DRIVER_EXTENSIONS DriverExtension, NextDriverExtension;
+
+ DPRINT("IopDeleteDriver(ObjectBody %x)\n", ObjectBody);
+
+ ExFreePool(Object->DriverExtension);
+
+ OldIrql = KeRaiseIrqlToDpcLevel();
+
+ for (DriverExtension = Object->DriverSection;
+ DriverExtension != NULL;
+ DriverExtension = NextDriverExtension)
+ {
+ NextDriverExtension = DriverExtension->Link;
+ ExFreePool(DriverExtension);
+ }
+
+ KfLowerIrql(OldIrql);
}
NTSTATUS FASTCALL
ULONG DriverImageSize)
{
PDRIVER_OBJECT Object;
- ULONG i;
WCHAR NameBuffer[MAX_PATH];
UNICODE_STRING DriverName;
OBJECT_ATTRIBUTES ObjectAttributes;
return Status;
}
- /* Create driver extension */
- Object->DriverExtension = (PDRIVER_EXTENSION)
- ExAllocatePoolWithTag(
- NonPagedPool,
- sizeof(DRIVER_EXTENSION),
- TAG_DRIVER_EXTENSION);
-
- if (Object->DriverExtension == NULL)
- {
- ExFreePool(Object);
- return STATUS_NO_MEMORY;
- }
-
- RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION));
-
- Object->Type = InternalDriverType;
Object->DriverStart = DriverImageStart;
Object->DriverSize = DriverImageSize;
- for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
- Object->MajorFunction[i] = IopDefaultDispatchFunction;
-
*DriverObject = Object;
return STATUS_SUCCESS;
UNICODE_STRING ServiceImagePath;
NTSTATUS Status;
+ DPRINT("IopLoadServiceModule(%wZ, %x)\n", ServiceName, ModuleObject);
+
/*
* Get information about the service.
*/
if (*ModuleObject == NULL)
{
+ Status = STATUS_UNSUCCESSFUL;
+
/*
* Special case for boot modules that were loaded by boot loader.
*/
PLOADER_MODULE KeLoaderModules =
(PLOADER_MODULE)KeLoaderBlock.ModsAddr;
- Status = STATUS_UNSUCCESSFUL;
-
/*
* FIXME:
* Improve this searching algorithm by using the image name
for (i = 1; i < KeLoaderBlock.ModsCount; i++)
{
ModuleName = (PCHAR)KeLoaderModules[i].String;
- if (!strcmp(ModuleName, SearchName))
+ if (!_stricmp(ModuleName, SearchName))
{
+ DPRINT("Initializing boot module\n");
+
/* Tell, that the module is already loaded */
KeLoaderModules[i].Reserved = 1;
UNICODE_STRING RegistryKey;
PDRIVER_INITIALIZE DriverEntry = ModuleObject->EntryPoint;
NTSTATUS Status;
+ WCHAR ServicesKeyName[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\";
Status = IopCreateDriverObject(
DriverObject,
if (DeviceNode->ServiceName.Buffer)
{
RegistryKey.Length = DeviceNode->ServiceName.Length +
- sizeof(DRIVER_REGISTRY_KEY_BASENAME);
+ sizeof(ServicesKeyName);
RegistryKey.MaximumLength = RegistryKey.Length + sizeof(UNICODE_NULL);
RegistryKey.Buffer = ExAllocatePool(PagedPool, RegistryKey.MaximumLength);
- wcscpy(RegistryKey.Buffer, DRIVER_REGISTRY_KEY_BASENAME);
+ wcscpy(RegistryKey.Buffer, ServicesKeyName);
wcscat(RegistryKey.Buffer, DeviceNode->ServiceName.Buffer);
}
else
Status = DriverEntry(*DriverObject, &RegistryKey);
if (!NT_SUCCESS(Status))
{
- ExFreePool((*DriverObject)->DriverExtension);
- ObMakeTemporaryObject(DriverObject);
- ObDereferenceObject(DriverObject);
+ ObMakeTemporaryObject(*DriverObject);
+ ObDereferenceObject(*DriverObject);
return Status;
}
PMODULE_OBJECT ModuleObject;
PDRIVER_OBJECT DriverObject;
NTSTATUS Status;
-
for (Filters = ValueData;
((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
return STATUS_SUCCESS;
}
-
-
-
-
-
-
-
static NTSTATUS STDCALL
IopCreateGroupListEntry(PWSTR ValueName,
ULONG ValueType,
VOID STATIC
MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length)
{
- ULONG i;
+ ULONG i;
- for (i = 0; i < PAGE_ROUND_UP(Length)/PAGE_SIZE; i++)
- {
- MmDeleteVirtualMapping(NULL, (char*)StartAddress + i * PAGE_SIZE, TRUE, NULL, NULL);
- }
+ for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++)
+ {
+ MmDeleteVirtualMapping(NULL, (char*)StartAddress + i * PAGE_SIZE, TRUE, NULL, NULL);
+ }
}
/*
/*
* Display 'Initializing XXX...' message
*/
+
sprintf(TextBuffer, "Initializing %s...\n", FileName);
HalDisplayString(TextBuffer);
/*
* Determine the right device object
*/
+
if (ModuleDeviceNode == NULL)
{
/* Use IopRootDeviceNode for now */
/*
* Generate filename without path (not needed by freeldr)
*/
+
FileNameWithoutPath = strrchr(FileName, '\\');
if (FileNameWithoutPath == NULL)
{
/*
* Load the module
*/
+
RtlCreateUnicodeStringFromAsciiz(&DeviceNode->ServiceName,
FileNameWithoutPath);
Status = LdrProcessModule(ModuleLoadBase, &DeviceNode->ServiceName,
/*
* Strip the file extension from ServiceName
*/
+
FileExtension = wcsrchr(DeviceNode->ServiceName.Buffer, '.');
if (FileExtension != NULL)
{
- DeviceNode->ServiceName.Length -= wcslen(DeviceNode->ServiceName.Buffer);
+ DeviceNode->ServiceName.Length -= wcslen(FileExtension) * sizeof(WCHAR);
FileExtension[0] = 0;
}
/*
* Initialize the driver
*/
+
Status = IopInitializeDriverModule(DeviceNode, ModuleObject, FALSE,
&DriverObject);
/*
* Pass symbol files to kernel debugger
*/
+
if (!_stricmp(Extension, ".sym"))
{
KDB_SYMBOLFILE_HOOK((PVOID)ModuleStart, ModuleName, ModuleSize);
/*
* Load builtin driver
*/
+
if (!_stricmp(Extension, ".sys"))
{
if (!ModuleLoaded)
/*
* Free memory for all boot files, except ntoskrnl.exe and hal.dll
*/
+
#ifdef KDBG
/*
* Do not free the memory from symbol files, if the kernel debugger
return STATUS_SUCCESS;
}
-/* FUNCTIONS ******************************************************************/
+VOID FASTCALL
+IopMarkLastReinitializeDriver(VOID)
+{
+ KIRQL Irql;
+
+ KeAcquireSpinLock(&DriverReinitListLock,
+ &Irql);
+
+ if (IsListEmpty(&DriverReinitListHead))
+ {
+ DriverReinitTailEntry = NULL;
+ }
+ else
+ {
+ DriverReinitTailEntry = DriverReinitListHead.Blink;
+ }
+
+ KeReleaseSpinLock(&DriverReinitListLock,
+ Irql);
+}
+
+
+VOID FASTCALL
+IopReinitializeDrivers(VOID)
+{
+ PDRIVER_REINIT_ITEM ReinitItem;
+ PLIST_ENTRY Entry;
+ KIRQL Irql;
+
+ KeAcquireSpinLock(&DriverReinitListLock,
+ &Irql);
+
+ if (DriverReinitTailEntry == NULL)
+ {
+ KeReleaseSpinLock(&DriverReinitListLock,
+ Irql);
+ return;
+ }
+
+ KeReleaseSpinLock(&DriverReinitListLock,
+ Irql);
+
+ for (;;)
+ {
+ Entry = ExInterlockedRemoveHeadList(&DriverReinitListHead,
+ &DriverReinitListLock);
+ if (Entry == NULL)
+ return;
+
+ ReinitItem = (PDRIVER_REINIT_ITEM)CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
+
+ /* Increment reinitialization counter */
+ ReinitItem->DriverObject->DriverExtension->Count++;
+
+ ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
+ ReinitItem->Context,
+ ReinitItem->DriverObject->DriverExtension->Count);
+
+ ExFreePool(Entry);
+
+ if (Entry == DriverReinitTailEntry)
+ return;
+ }
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+IoCreateDriver (
+ IN PUNICODE_STRING DriverName, OPTIONAL
+ IN PDRIVER_INITIALIZE InitializationFunction
+ )
+{
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+STDCALL
+IoDeleteDriver (
+ IN PDRIVER_OBJECT DriverObject
+ )
+{
+ UNIMPLEMENTED;
+}
+
/*
* NtLoadDriver
*
* Return Value
* Status
+ *
+ * Status
+ * implemented
*/
NTSTATUS STDCALL
* Check security privileges
*/
+/* FIXME: Uncomment when privileges will be correctly implemented. */
#if 0
if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, KeGetPreviousMode()))
+ {
+ DPRINT("Privilege not held\n");
return STATUS_PRIVILEGE_NOT_HELD;
+ }
#endif
RtlInitUnicodeString(&ImagePath, NULL);
/*
* See, if the driver module isn't already loaded
*/
+
ModuleObject = LdrGetModuleObject(&ImagePath);
if (ModuleObject != NULL)
{
+ DPRINT("Image already loaded\n");
return STATUS_IMAGE_ALREADY_LOADED;
}
Status = IopInitializeDriverModule(
DeviceNode,
ModuleObject,
- (Type == 2 /*SERVICE_FILE_SYSTEM_DRIVER*/ ||
- Type == 8 /*SERVICE_RECOGNIZER_DRIVER*/),
+ (Type == 2 /* SERVICE_FILE_SYSTEM_DRIVER */ ||
+ Type == 8 /* SERVICE_RECOGNIZER_DRIVER */),
&DriverObject);
if (!NT_SUCCESS(Status))
{
- DPRINT1("IopInitializeDriver() failed (Status %lx)\n", Status);
+ DPRINT("IopInitializeDriver() failed (Status %lx)\n", Status);
LdrUnloadModule(ModuleObject);
IopFreeDeviceNode(DeviceNode);
return Status;
*
* Return Value
* Status
+ *
+ * Status
+ * implemented
*/
NTSTATUS STDCALL
return IopUnloadDriver(DriverServiceName, FALSE);
}
-
/*
- * @implemented
+ * IoRegisterDriverReinitialization
+ *
+ * Status
+ * @implemented
*/
-VOID STDCALL
-IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject,
- PDRIVER_REINITIALIZE ReinitRoutine,
- PVOID Context)
-{
- PDRIVER_REINIT_ITEM ReinitItem;
-
- ReinitItem = ExAllocatePool(NonPagedPool,
- sizeof(DRIVER_REINIT_ITEM));
- if (ReinitItem == NULL)
- return;
-
- ReinitItem->DriverObject = DriverObject;
- ReinitItem->ReinitRoutine = ReinitRoutine;
- ReinitItem->Context = Context;
- ExInterlockedInsertTailList(&DriverReinitListHead,
- &ReinitItem->ItemEntry,
- &DriverReinitListLock);
-}
-
-
-VOID FASTCALL
-IopMarkLastReinitializeDriver(VOID)
-{
- KIRQL Irql;
-
- KeAcquireSpinLock(&DriverReinitListLock,
- &Irql);
-
- if (IsListEmpty(&DriverReinitListHead))
- {
- DriverReinitTailEntry = NULL;
- }
- else
- {
- DriverReinitTailEntry = DriverReinitListHead.Blink;
- }
-
- KeReleaseSpinLock(&DriverReinitListLock,
- Irql);
-}
-
-
-VOID FASTCALL
-IopReinitializeDrivers(VOID)
+VOID STDCALL
+IoRegisterDriverReinitialization(
+ PDRIVER_OBJECT DriverObject,
+ PDRIVER_REINITIALIZE ReinitRoutine,
+ PVOID Context)
{
- PDRIVER_REINIT_ITEM ReinitItem;
- PLIST_ENTRY Entry;
- KIRQL Irql;
-
- KeAcquireSpinLock(&DriverReinitListLock,
- &Irql);
-
- if (DriverReinitTailEntry == NULL)
- {
- KeReleaseSpinLock(&DriverReinitListLock,
- Irql);
- return;
- }
+ PDRIVER_REINIT_ITEM ReinitItem;
- KeReleaseSpinLock(&DriverReinitListLock,
- Irql);
-
- for (;;)
- {
- Entry = ExInterlockedRemoveHeadList(&DriverReinitListHead,
- &DriverReinitListLock);
- if (Entry == NULL)
+ ReinitItem = ExAllocatePool(NonPagedPool, sizeof(DRIVER_REINIT_ITEM));
+ if (ReinitItem == NULL)
return;
- ReinitItem = (PDRIVER_REINIT_ITEM)CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
-
- /* Increment reinitialization counter */
- ReinitItem->DriverObject->DriverExtension->Count++;
+ ReinitItem->DriverObject = DriverObject;
+ ReinitItem->ReinitRoutine = ReinitRoutine;
+ ReinitItem->Context = Context;
- ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
- ReinitItem->Context,
- ReinitItem->DriverObject->DriverExtension->Count);
-
- ExFreePool(Entry);
-
- if (Entry == DriverReinitTailEntry)
- return;
- }
+ ExInterlockedInsertTailList(
+ &DriverReinitListHead,
+ &ReinitItem->ItemEntry,
+ &DriverReinitListLock);
}
-typedef struct _PRIVATE_DRIVER_EXTENSIONS {
- struct _PRIVATE_DRIVER_EXTENSIONS *Link;
- PVOID ClientIdentificationAddress;
- CHAR Extension[1];
-} PRIVATE_DRIVER_EXTENSIONS, *PPRIVATE_DRIVER_EXTENSIONS;
+/*
+ * IoAllocateDriverObjectExtension
+ *
+ * Status
+ * @implemented
+ */
NTSTATUS STDCALL
IoAllocateDriverObjectExtension(
return STATUS_SUCCESS;
}
+/*
+ * IoGetDriverObjectExtension
+ *
+ * Status
+ * @implemented
+ */
+
PVOID STDCALL
IoGetDriverObjectExtension(
PDRIVER_OBJECT DriverObject,