-/* $Id: iomgr.c,v 1.10 2000/05/09 16:13:49 ekohl Exp $
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: ntoskrnl/io/iomgr.c
+ * PURPOSE: I/O Manager Initialization and Misc Utility Functions
*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/io/iomgr.c
- * PURPOSE: Initializes the io manager
- * PROGRAMMER: David Welch (welch@mcmail.com)
- * REVISION HISTORY:
- * 29/07/98: Created
+ * PROGRAMMERS: David Welch (welch@mcmail.com)
*/
/* INCLUDES ****************************************************************/
-#include <ddk/ntddk.h>
-#include <internal/ob.h>
-#include <internal/io.h>
-
+#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
-/* GLOBALS *******************************************************************/
-
/* DATA ********************************************************************/
-
POBJECT_TYPE EXPORTED IoDeviceObjectType = NULL;
POBJECT_TYPE EXPORTED IoFileObjectType = NULL;
-ULONG EXPORTED IoReadOperationCount = 0; /* FIXME: unknown type */
-ULONG EXPORTED IoReadTransferCount = 0; /* FIXME: unknown type */
-ULONG EXPORTED IoWriteOperationCount = 0; /* FIXME: unknown type */
-ULONG EXPORTED IoWriteTransferCount = 0; /* FIXME: unknown type */
-ULONG EXPORTED IoStatisticsLock = 0; /* FIXME: unknown type */
+extern POBJECT_TYPE IoControllerObjectType;
+ULONG EXPORTED IoReadOperationCount = 0;
+ULONGLONG EXPORTED IoReadTransferCount = 0;
+ULONG EXPORTED IoWriteOperationCount = 0;
+ULONGLONG EXPORTED IoWriteTransferCount = 0;
+ULONG IoOtherOperationCount = 0;
+ULONGLONG IoOtherTransferCount = 0;
+KSPIN_LOCK EXPORTED IoStatisticsLock = 0;
+
+GENERIC_MAPPING IopFileMapping = {
+ FILE_GENERIC_READ,
+ FILE_GENERIC_WRITE,
+ FILE_GENERIC_EXECUTE,
+ FILE_ALL_ACCESS};
+
+static KSPIN_LOCK CancelSpinLock;
+extern LIST_ENTRY ShutdownListHead;
+extern KSPIN_LOCK ShutdownListLock;
+extern NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside;
+NPAGED_LOOKASIDE_LIST IoLargeIrpLookaside;
+NPAGED_LOOKASIDE_LIST IoSmallIrpLookaside;
+
+/* INIT FUNCTIONS ************************************************************/
+
+VOID
+INIT_FUNCTION
+IoInitCancelHandling(VOID)
+{
+ KeInitializeSpinLock(&CancelSpinLock);
+}
+
+VOID
+INIT_FUNCTION
+IoInitShutdownNotification (VOID)
+{
+ InitializeListHead(&ShutdownListHead);
+ KeInitializeSpinLock(&ShutdownListLock);
+}
+
+VOID
+INIT_FUNCTION
+IopInitLookasideLists(VOID)
+{
+ ULONG LargeIrpSize, SmallIrpSize;
+ ULONG i;
+ PKPRCB Prcb;
+ PNPAGED_LOOKASIDE_LIST CurrentList = NULL;
+
+ /* Calculate the sizes */
+ LargeIrpSize = sizeof(IRP) + (8 * sizeof(IO_STACK_LOCATION));
+ SmallIrpSize = sizeof(IRP) + sizeof(IO_STACK_LOCATION);
+
+ /* Initialize the Lookaside List for Large IRPs */
+ ExInitializeNPagedLookasideList(&IoLargeIrpLookaside,
+ NULL,
+ NULL,
+ 0,
+ LargeIrpSize,
+ IO_LARGEIRP,
+ 0);
+
+ /* Initialize the Lookaside List for Small IRPs */
+ ExInitializeNPagedLookasideList(&IoSmallIrpLookaside,
+ NULL,
+ NULL,
+ 0,
+ SmallIrpSize,
+ IO_SMALLIRP,
+ 0);
+
+ /* Initialize the Lookaside List for I\O Completion */
+ ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside,
+ NULL,
+ NULL,
+ 0,
+ sizeof(IO_COMPLETION_PACKET),
+ IOC_TAG1,
+ 0);
+
+ /* Now allocate the per-processor lists */
+ for (i = 0; i < KeNumberProcessors; i++)
+ {
+ /* Get the PRCB for this CPU */
+ Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb;
+ DPRINT("Setting up lookaside for CPU: %x, PRCB: %p\n", i, Prcb);
+
+ /* Set the Large IRP List */
+ Prcb->PPLookasideList[LookasideLargeIrpList].L = &IoLargeIrpLookaside.L;
+ CurrentList = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(NPAGED_LOOKASIDE_LIST),
+ IO_LARGEIRP_CPU);
+ if (CurrentList)
+ {
+ /* Initialize the Lookaside List for Large IRPs */
+ ExInitializeNPagedLookasideList(CurrentList,
+ NULL,
+ NULL,
+ 0,
+ LargeIrpSize,
+ IO_LARGEIRP_CPU,
+ 0);
+ }
+ else
+ {
+ CurrentList = &IoLargeIrpLookaside;
+ }
+ Prcb->PPLookasideList[LookasideLargeIrpList].P = &CurrentList->L;
+
+ /* Set the Small IRP List */
+ Prcb->PPLookasideList[LookasideSmallIrpList].L = &IoSmallIrpLookaside.L;
+ CurrentList = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(NPAGED_LOOKASIDE_LIST),
+ IO_SMALLIRP_CPU);
+ if (CurrentList)
+ {
+ /* Initialize the Lookaside List for Large IRPs */
+ ExInitializeNPagedLookasideList(CurrentList,
+ NULL,
+ NULL,
+ 0,
+ SmallIrpSize,
+ IO_SMALLIRP_CPU,
+ 0);
+ }
+ else
+ {
+ CurrentList = &IoSmallIrpLookaside;
+ }
+ Prcb->PPLookasideList[LookasideSmallIrpList].P = &CurrentList->L;
+
+ /* Set the I/O Completion List */
+ Prcb->PPLookasideList[LookasideCompletionList].L = &IoCompletionPacketLookaside.L;
+ CurrentList = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(NPAGED_LOOKASIDE_LIST),
+ IO_SMALLIRP_CPU);
+ if (CurrentList)
+ {
+ /* Initialize the Lookaside List for Large IRPs */
+ ExInitializeNPagedLookasideList(CurrentList,
+ NULL,
+ NULL,
+ 0,
+ SmallIrpSize,
+ IOC_CPU,
+ 0);
+ }
+ else
+ {
+ CurrentList = &IoCompletionPacketLookaside;
+ }
+ Prcb->PPLookasideList[LookasideCompletionList].P = &CurrentList->L;
+ }
+
+ DPRINT("Done allocation\n");
+}
+
+VOID
+INIT_FUNCTION
+IoInit (VOID)
+{
+ OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
+ UNICODE_STRING Name;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING DirName;
+ UNICODE_STRING LinkName;
+ HANDLE Handle;
+
+ IopInitDriverImplementation();
+
+ DPRINT1("Creating Device Object Type\n");
+
+ /* Initialize the Driver object type */
+ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
+ RtlInitUnicodeString(&Name, L"Device");
+ ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+ ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DEVICE_OBJECT);
+ ObjectTypeInitializer.PoolType = NonPagedPool;
+ ObjectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS;
+ ObjectTypeInitializer.UseDefaultObject = TRUE;
+ ObjectTypeInitializer.GenericMapping = IopFileMapping;
+ ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &IoDeviceObjectType);
+
+ /* Do the Adapter Type */
+ RtlInitUnicodeString(&Name, L"Adapter");
+ ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &IoAdapterObjectType);
+
+ /* Do the Controller Type */
+ RtlInitUnicodeString(&Name, L"Controller");
+ ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(CONTROLLER_OBJECT);
+ ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &IoControllerObjectType);
+
+ /* Initialize the File object type */
+ RtlInitUnicodeString(&Name, L"File");
+ ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+ ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(FILE_OBJECT);
+ ObjectTypeInitializer.CloseProcedure = IopCloseFile;
+ ObjectTypeInitializer.DeleteProcedure = IopDeleteFile;
+ ObjectTypeInitializer.SecurityProcedure = IopSecurityFile;
+ ObjectTypeInitializer.QueryNameProcedure = IopQueryNameFile;
+ ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &IoFileObjectType);
+
+ /*
+ * Create the '\Driver' object directory
+ */
+ RtlRosInitUnicodeStringFromLiteral(&DirName, L"\\Driver");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DirName,
+ 0,
+ NULL,
+ NULL);
+ ZwCreateDirectoryObject(&Handle,
+ 0,
+ &ObjectAttributes);
+
+ /*
+ * Create the '\FileSystem' object directory
+ */
+ RtlRosInitUnicodeStringFromLiteral(&DirName,
+ L"\\FileSystem");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DirName,
+ 0,
+ NULL,
+ NULL);
+ ZwCreateDirectoryObject(&Handle,
+ 0,
+ &ObjectAttributes);
+
+ /*
+ * Create the '\Device' directory
+ */
+ RtlRosInitUnicodeStringFromLiteral(&DirName,
+ L"\\Device");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DirName,
+ 0,
+ NULL,
+ NULL);
+ ZwCreateDirectoryObject(&Handle,
+ 0,
+ &ObjectAttributes);
+
+ /*
+ * Create the '\??' directory
+ */
+ RtlRosInitUnicodeStringFromLiteral(&DirName,
+ L"\\??");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DirName,
+ 0,
+ NULL,
+ NULL);
+ ZwCreateDirectoryObject(&Handle,
+ 0,
+ &ObjectAttributes);
+
+ /*
+ * Create the '\ArcName' directory
+ */
+ RtlRosInitUnicodeStringFromLiteral(&DirName,
+ L"\\ArcName");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &DirName,
+ 0,
+ NULL,
+ NULL);
+ ZwCreateDirectoryObject(&Handle,
+ 0,
+ &ObjectAttributes);
+
+ /*
+ * Initialize remaining subsubsystem
+ */
+ IoInitCancelHandling();
+ IoInitFileSystemImplementation();
+ IoInitVpbImplementation();
+ IoInitShutdownNotification();
+ IopInitPnpNotificationImplementation();
+ IopInitErrorLog();
+ IopInitTimerImplementation();
+ IopInitIoCompletionImplementation();
+ IopInitLookasideLists();
+
+ /*
+ * Create link from '\DosDevices' to '\??' directory
+ */
+ RtlRosInitUnicodeStringFromLiteral(&LinkName,
+ L"\\DosDevices");
+ RtlRosInitUnicodeStringFromLiteral(&DirName,
+ L"\\??");
+ IoCreateSymbolicLink(&LinkName,
+ &DirName);
+
+ /*
+ * Initialize PnP manager
+ */
+ PnpInit();
+}
+
+VOID
+INIT_FUNCTION
+IoInit2(BOOLEAN BootLog)
+{
+ PDEVICE_NODE DeviceNode;
+ PDRIVER_OBJECT DriverObject;
+ MODULE_OBJECT ModuleObject;
+ NTSTATUS Status;
+
+ IoCreateDriverList();
+
+ KeInitializeSpinLock (&IoStatisticsLock);
+
+ /* Initialize raw filesystem driver */
+
+ /* Use IopRootDeviceNode for now */
+ Status = IopCreateDeviceNode(IopRootDeviceNode,
+ NULL,
+ &DeviceNode);
+ if (!NT_SUCCESS(Status))
+ {
+ CPRINT("IopCreateDeviceNode() failed with status (%x)\n", Status);
+ return;
+ }
-/* FUNCTIONS ****************************************************************/
+ ModuleObject.Base = NULL;
+ ModuleObject.Length = 0;
+ ModuleObject.EntryPoint = RawFsDriverEntry;
-VOID IopCloseFile(PVOID ObjectBody, ULONG HandleCount)
+ Status = IopInitializeDriverModule(
+ DeviceNode,
+ &ModuleObject,
+ &DeviceNode->ServiceName,
+ TRUE,
+ &DriverObject);
+ if (!NT_SUCCESS(Status))
+ {
+ IopFreeDeviceNode(DeviceNode);
+ CPRINT("IopInitializeDriver() failed with status (%x)\n", Status);
+ return;
+ }
+
+ Status = IopInitializeDevice(DeviceNode, DriverObject);
+ if (!NT_SUCCESS(Status))
+ {
+ IopFreeDeviceNode(DeviceNode);
+ CPRINT("IopInitializeDevice() failed with status (%x)\n", Status);
+ return;
+ }
+
+ Status = IopStartDevice(DeviceNode);
+ if (!NT_SUCCESS(Status))
+ {
+ IopFreeDeviceNode(DeviceNode);
+ CPRINT("IopInitializeDevice() failed with status (%x)\n", Status);
+ return;
+ }
+
+ /*
+ * Initialize PnP root releations
+ */
+ IopInvalidateDeviceRelations(
+ IopRootDeviceNode,
+ BusRelations);
+
+ /* Start boot logging */
+ IopInitBootLog(BootLog);
+
+ /* Load boot start drivers */
+ IopInitializeBootDrivers();
+}
+
+VOID
+STDCALL
+INIT_FUNCTION
+IoInit3(VOID)
{
- PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
- PIRP Irp;
- PIO_STACK_LOCATION StackPtr;
- NTSTATUS Status;
-
- DPRINT("IopCloseFile()\n");
-
- if (HandleCount > 0)
- {
- return;
- }
-
- ObReferenceObjectByPointer(FileObject,
- STANDARD_RIGHTS_REQUIRED,
- IoFileObjectType,
- UserMode);
-
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLEANUP,
- FileObject->DeviceObject,
- NULL,
- 0,
- NULL,
- NULL,
- NULL);
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
-
- Status = IoCallDriver(FileObject->DeviceObject, Irp);
+ NTSTATUS Status;
+
+ /* Create ARC names for boot devices */
+ IoCreateArcNames();
+
+ /* Create the SystemRoot symbolic link */
+ DPRINT("CommandLine: %s\n", (PCHAR)KeLoaderBlock.CommandLine);
+ Status = IoCreateSystemRootLink((PCHAR)KeLoaderBlock.CommandLine);
+ if (!NT_SUCCESS(Status)) {
+ CPRINT("IoCreateSystemRootLink FAILED: (0x%x) - ", Status);
+ KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
+ }
+
+ /* Read KDB Data */
+ KdbInit();
+
+ /* I/O is now setup for disk access, so phase 3 */
+ KdInitSystem(3, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+ /* Load services for devices found by PnP manager */
+ IopInitializePnpServices(IopRootDeviceNode, FALSE);
+
+ /* Load system start drivers */
+ IopInitializeSystemDrivers();
+ IoDestroyDriverList();
+
+ /* Stop boot logging */
+ IopStopBootLog();
+
+ /* Assign drive letters */
+ IoAssignDriveLetters((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
+ NULL,
+ NULL,
+ NULL);
}
-VOID IopDeleteFile(PVOID ObjectBody)
+/* FUNCTIONS *****************************************************************/
+
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+IoAcquireCancelSpinLock(PKIRQL Irql)
{
- PFILE_OBJECT FileObject = (PFILE_OBJECT)ObjectBody;
- PIRP Irp;
- PIO_STACK_LOCATION StackPtr;
- NTSTATUS Status;
-
- DPRINT("IopDeleteFile()\n");
-
- ObReferenceObjectByPointer(ObjectBody,
- STANDARD_RIGHTS_REQUIRED,
- IoFileObjectType,
- UserMode);
-
- Irp = IoBuildSynchronousFsdRequest(IRP_MJ_CLOSE,
- FileObject->DeviceObject,
- NULL,
- 0,
- NULL,
- NULL,
- NULL);
- StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->FileObject = FileObject;
-
- Status = IoCallDriver(FileObject->DeviceObject, Irp);
-
- if (FileObject->FileName.Buffer != NULL)
- {
- ExFreePool(FileObject->FileName.Buffer);
- FileObject->FileName.Buffer = 0;
- }
+ KeAcquireSpinLock(&CancelSpinLock,Irql);
}
-VOID IoShutdownIoManager(VOID)
+/*
+ * @implemented
+ */
+PVOID
+STDCALL
+IoGetInitialStack(VOID)
+{
+ return(PsGetCurrentThread()->Tcb.InitialStack);
+}
+
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+IoGetStackLimits(OUT PULONG LowLimit,
+ OUT PULONG HighLimit)
+{
+ *LowLimit = (ULONG)NtCurrentTeb()->Tib.StackLimit;
+ *HighLimit = (ULONG)NtCurrentTeb()->Tib.StackBase;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+STDCALL
+IoIsSystemThread(IN PETHREAD Thread)
{
+ /* Call the Ps Function */
+ return PsIsSystemThread(Thread);
}
+/*
+ * @implemented
+ */
+BOOLEAN STDCALL
+IoIsWdmVersionAvailable(IN UCHAR MajorVersion,
+ IN UCHAR MinorVersion)
+{
+ if (MajorVersion <= 1 && MinorVersion <= 10)
+ return TRUE;
+ return FALSE;
+}
-VOID IoInit (VOID)
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+IoReleaseCancelSpinLock(KIRQL Irql)
{
- OBJECT_ATTRIBUTES attr;
- HANDLE handle;
- UNICODE_STRING UnicodeString;
- ANSI_STRING AnsiString;
-
- /*
- * Register iomgr types: DeviceObjectType
- */
- IoDeviceObjectType = ExAllocatePool (
- NonPagedPool,
- sizeof (OBJECT_TYPE)
- );
-
- IoDeviceObjectType->TotalObjects = 0;
- IoDeviceObjectType->TotalHandles = 0;
- IoDeviceObjectType->MaxObjects = ULONG_MAX;
- IoDeviceObjectType->MaxHandles = ULONG_MAX;
- IoDeviceObjectType->PagedPoolCharge = 0;
- IoDeviceObjectType->NonpagedPoolCharge = sizeof (DEVICE_OBJECT);
- IoDeviceObjectType->Dump = NULL;
- IoDeviceObjectType->Open = NULL;
- IoDeviceObjectType->Close = NULL;
- IoDeviceObjectType->Delete = NULL;
- IoDeviceObjectType->Parse = NULL;
- IoDeviceObjectType->Security = NULL;
- IoDeviceObjectType->QueryName = NULL;
- IoDeviceObjectType->OkayToClose = NULL;
- IoDeviceObjectType->Create = IopCreateDevice;
-
- RtlInitAnsiString (
- & AnsiString,
- "Device"
- );
- RtlAnsiStringToUnicodeString (
- & IoDeviceObjectType->TypeName,
- & AnsiString,
- TRUE
- );
- /*
- * Register iomgr types: FileObjectType
- * (alias DriverObjectType)
- */
- IoFileObjectType = ExAllocatePool (
- NonPagedPool,
- sizeof (OBJECT_TYPE)
- );
-
- IoFileObjectType->TotalObjects = 0;
- IoFileObjectType->TotalHandles = 0;
- IoFileObjectType->MaxObjects = ULONG_MAX;
- IoFileObjectType->MaxHandles = ULONG_MAX;
- IoFileObjectType->PagedPoolCharge = 0;
- IoFileObjectType->NonpagedPoolCharge = sizeof(FILE_OBJECT);
- IoFileObjectType->Dump = NULL;
- IoFileObjectType->Open = NULL;
- IoFileObjectType->Close = IopCloseFile;
- IoFileObjectType->Delete = IopDeleteFile;
- IoFileObjectType->Parse = NULL;
- IoFileObjectType->Security = NULL;
- IoFileObjectType->QueryName = NULL;
- IoFileObjectType->OkayToClose = NULL;
- IoFileObjectType->Create = IopCreateFile;
-
- RtlInitAnsiString (
- & AnsiString,
- "File"
- );
- RtlAnsiStringToUnicodeString (
- & IoFileObjectType->TypeName,
- & AnsiString,
- TRUE
- );
-
- /*
- * Create the device directory
- */
- RtlInitAnsiString (
- & AnsiString,
- "\\Device"
- );
- RtlAnsiStringToUnicodeString (
- & UnicodeString,
- & AnsiString,
- TRUE
- );
- InitializeObjectAttributes (
- & attr,
- & UnicodeString,
- 0,
- NULL,
- NULL
- );
- ZwCreateDirectoryObject (
- & handle,
- 0,
- & attr
- );
- /*
- * Create the \?? directory
- */
- RtlInitAnsiString (
- & AnsiString,
- "\\??"
- );
- RtlAnsiStringToUnicodeString (
- & UnicodeString,
- & AnsiString,
- TRUE
- );
- InitializeObjectAttributes (
- & attr,
- & UnicodeString,
- 0,
- NULL,
- NULL
- );
- ZwCreateDirectoryObject (
- & handle,
- 0,
- & attr
- );
- /*
- * Initialize remaining subsubsystem
- */
- IoInitCancelHandling ();
- IoInitSymbolicLinkImplementation ();
- IoInitFileSystemImplementation ();
+ KeReleaseSpinLock(&CancelSpinLock,Irql);
}
+/*
+ * @implemented
+ */
+PEPROCESS
+STDCALL
+IoThreadToProcess(IN PETHREAD Thread)
+{
+ return(Thread->ThreadsProcess);
+}
/* EOF */