reactos/ntoskrnl/io/iomgr/iomgr.c

664 lines
22 KiB
C
Raw Normal View History

IO Manager Cleanup continues: - Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile, IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an example). - Cleaned up some IRP code and fixed a couple of bugs, mainly: - Write I/O Type in IRP - Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code) - Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect behaviour. Code should never depend on a buffer being zeroed! - Remove a lot of duplicated code and helper/alternate functions that weren't really useful. - Free MDL and IRP on some failures where we didn't - Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the old revision and copy/pasting the new code directly above it. The functions which we touched are: - IoAllocateIrp - IoBuild[A]SyncronousFsdRequest - IoBuildDeviceIoControlRequest - IoInitializeIrp - IoPageRead, IoSynchronousPageWrite svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
/*
* COPYRIGHT: See COPYING in the top level directory
IO Manager Cleanup continues: - Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile, IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an example). - Cleaned up some IRP code and fixed a couple of bugs, mainly: - Write I/O Type in IRP - Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code) - Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect behaviour. Code should never depend on a buffer being zeroed! - Remove a lot of duplicated code and helper/alternate functions that weren't really useful. - Free MDL and IRP on some failures where we didn't - Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the old revision and copy/pasting the new code directly above it. The functions which we touched are: - IoAllocateIrp - IoBuild[A]SyncronousFsdRequest - IoBuildDeviceIoControlRequest - IoInitializeIrp - IoPageRead, IoSynchronousPageWrite svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
* PROJECT: ReactOS Kernel
* FILE: ntoskrnl/io/iomgr/iomgr.c
IO Manager Cleanup continues: - Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile, IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an example). - Cleaned up some IRP code and fixed a couple of bugs, mainly: - Write I/O Type in IRP - Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code) - Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect behaviour. Code should never depend on a buffer being zeroed! - Remove a lot of duplicated code and helper/alternate functions that weren't really useful. - Free MDL and IRP on some failures where we didn't - Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the old revision and copy/pasting the new code directly above it. The functions which we touched are: - IoAllocateIrp - IoBuild[A]SyncronousFsdRequest - IoBuildDeviceIoControlRequest - IoInitializeIrp - IoPageRead, IoSynchronousPageWrite svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
* PURPOSE: I/O Manager Initialization and Misc Utility Functions
*
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
/* INCLUDES ****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
ULONG IopTraceLevel = 0;
BOOLEAN PnpSystemInit = FALSE;
VOID
NTAPI
IopTimerDispatch(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2
);
BOOLEAN
NTAPI
WmiInitialize(
VOID);
/* DATA ********************************************************************/
POBJECT_TYPE IoDeviceObjectType = NULL;
POBJECT_TYPE IoFileObjectType = NULL;
extern POBJECT_TYPE IoControllerObjectType;
BOOLEAN IoCountOperations = TRUE;
ULONG IoReadOperationCount = 0;
LARGE_INTEGER IoReadTransferCount = {{0, 0}};
ULONG IoWriteOperationCount = 0;
LARGE_INTEGER IoWriteTransferCount = {{0, 0}};
ULONG IoOtherOperationCount = 0;
LARGE_INTEGER IoOtherTransferCount = {{0, 0}};
KSPIN_LOCK IoStatisticsLock = 0;
ULONG IopNumTriageDumpDataBlocks;
PVOID IopTriageDumpDataBlocks[64];
IO Manager Cleanup continues: - Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile, IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an example). - Cleaned up some IRP code and fixed a couple of bugs, mainly: - Write I/O Type in IRP - Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code) - Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect behaviour. Code should never depend on a buffer being zeroed! - Remove a lot of duplicated code and helper/alternate functions that weren't really useful. - Free MDL and IRP on some failures where we didn't - Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the old revision and copy/pasting the new code directly above it. The functions which we touched are: - IoAllocateIrp - IoBuild[A]SyncronousFsdRequest - IoBuildDeviceIoControlRequest - IoInitializeIrp - IoPageRead, IoSynchronousPageWrite svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
GENERIC_MAPPING IopFileMapping = {
FILE_GENERIC_READ,
FILE_GENERIC_WRITE,
FILE_GENERIC_EXECUTE,
FILE_ALL_ACCESS};
IO Manager Cleanup continues: - Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile, IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an example). - Cleaned up some IRP code and fixed a couple of bugs, mainly: - Write I/O Type in IRP - Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code) - Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect behaviour. Code should never depend on a buffer being zeroed! - Remove a lot of duplicated code and helper/alternate functions that weren't really useful. - Free MDL and IRP on some failures where we didn't - Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the old revision and copy/pasting the new code directly above it. The functions which we touched are: - IoAllocateIrp - IoBuild[A]SyncronousFsdRequest - IoBuildDeviceIoControlRequest - IoInitializeIrp - IoPageRead, IoSynchronousPageWrite svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
extern LIST_ENTRY ShutdownListHead;
extern LIST_ENTRY LastChanceShutdownListHead;
IO Manager Cleanup continues: - Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile, IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an example). - Cleaned up some IRP code and fixed a couple of bugs, mainly: - Write I/O Type in IRP - Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code) - Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect behaviour. Code should never depend on a buffer being zeroed! - Remove a lot of duplicated code and helper/alternate functions that weren't really useful. - Free MDL and IRP on some failures where we didn't - Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the old revision and copy/pasting the new code directly above it. The functions which we touched are: - IoAllocateIrp - IoBuild[A]SyncronousFsdRequest - IoBuildDeviceIoControlRequest - IoInitializeIrp - IoPageRead, IoSynchronousPageWrite svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
extern KSPIN_LOCK ShutdownListLock;
extern POBJECT_TYPE IoAdapterObjectType;
[NTOSKRNL] - renamed Io volumes global to match Windows names (in case of debug) - renamed IopDereferenceVpb() to IopDereferenceVpbAndFree(), IopReferenceVpbForVerify() to IopReferenceVerifyVpb(), IopInitializeVpbForMount() to IopMountInitializeVpb(), IopLoadFileSystem() to IopLoadFileSystemDriver() - implemented IopDecrementDeviceObjectHandleCount(), IopInterlockedIncrementUlong(), IopInterlockedDecrementUlong(), IopNotifyAlreadyRegisteredFileSystems() and IoEnumerateRegisteredFiltersList() - halfplemented IopDecrementDeviceObjectRef() - implemented check for already registrered notification in IoRegisterFsRegistrationChange() - implemented sending notifications for already registered drivers to registrant in IoRegisterFsRegistrationChange() - implemented VPB freeing in IopDereferenceVpbAndFree() - acquire Io volumes lists once and forever for system shutdown, instead of keeping acquiring and releasing - reference device object in IopShutdownBaseFileSystems() before sending it the shutdown IRP. To ensure to keep it valid till the end - added a FS driver registration operations counter - use this counter to handle failed mounts - fixed: release locks before calling driver for mounting and reacquire them after - fixed check for boot partition failure (and associated bugcheck): check we are in boot phase 0 or 1 - simplified lock process by using only one lock (ie removed mutex). Also use only critical region where needed - fixed: ensure that locks are properly released when quitting a function - fixed wrong return in IopCreateVpb() - minor fixes around svn path=/trunk/; revision=52065
2011-06-02 17:43:44 +00:00
extern ERESOURCE IopDatabaseResource;
ERESOURCE IopSecurityResource;
extern ERESOURCE IopDriverLoadResource;
[NTOSKRNL] - renamed Io volumes global to match Windows names (in case of debug) - renamed IopDereferenceVpb() to IopDereferenceVpbAndFree(), IopReferenceVpbForVerify() to IopReferenceVerifyVpb(), IopInitializeVpbForMount() to IopMountInitializeVpb(), IopLoadFileSystem() to IopLoadFileSystemDriver() - implemented IopDecrementDeviceObjectHandleCount(), IopInterlockedIncrementUlong(), IopInterlockedDecrementUlong(), IopNotifyAlreadyRegisteredFileSystems() and IoEnumerateRegisteredFiltersList() - halfplemented IopDecrementDeviceObjectRef() - implemented check for already registrered notification in IoRegisterFsRegistrationChange() - implemented sending notifications for already registered drivers to registrant in IoRegisterFsRegistrationChange() - implemented VPB freeing in IopDereferenceVpbAndFree() - acquire Io volumes lists once and forever for system shutdown, instead of keeping acquiring and releasing - reference device object in IopShutdownBaseFileSystems() before sending it the shutdown IRP. To ensure to keep it valid till the end - added a FS driver registration operations counter - use this counter to handle failed mounts - fixed: release locks before calling driver for mounting and reacquire them after - fixed check for boot partition failure (and associated bugcheck): check we are in boot phase 0 or 1 - simplified lock process by using only one lock (ie removed mutex). Also use only critical region where needed - fixed: ensure that locks are properly released when quitting a function - fixed wrong return in IopCreateVpb() - minor fixes around svn path=/trunk/; revision=52065
2011-06-02 17:43:44 +00:00
extern LIST_ENTRY IopDiskFileSystemQueueHead;
extern LIST_ENTRY IopCdRomFileSystemQueueHead;
extern LIST_ENTRY IopTapeFileSystemQueueHead;
extern LIST_ENTRY IopNetworkFileSystemQueueHead;
extern LIST_ENTRY DriverBootReinitListHead;
extern LIST_ENTRY DriverReinitListHead;
[NTOSKRNL] - renamed Io volumes global to match Windows names (in case of debug) - renamed IopDereferenceVpb() to IopDereferenceVpbAndFree(), IopReferenceVpbForVerify() to IopReferenceVerifyVpb(), IopInitializeVpbForMount() to IopMountInitializeVpb(), IopLoadFileSystem() to IopLoadFileSystemDriver() - implemented IopDecrementDeviceObjectHandleCount(), IopInterlockedIncrementUlong(), IopInterlockedDecrementUlong(), IopNotifyAlreadyRegisteredFileSystems() and IoEnumerateRegisteredFiltersList() - halfplemented IopDecrementDeviceObjectRef() - implemented check for already registrered notification in IoRegisterFsRegistrationChange() - implemented sending notifications for already registered drivers to registrant in IoRegisterFsRegistrationChange() - implemented VPB freeing in IopDereferenceVpbAndFree() - acquire Io volumes lists once and forever for system shutdown, instead of keeping acquiring and releasing - reference device object in IopShutdownBaseFileSystems() before sending it the shutdown IRP. To ensure to keep it valid till the end - added a FS driver registration operations counter - use this counter to handle failed mounts - fixed: release locks before calling driver for mounting and reacquire them after - fixed check for boot partition failure (and associated bugcheck): check we are in boot phase 0 or 1 - simplified lock process by using only one lock (ie removed mutex). Also use only critical region where needed - fixed: ensure that locks are properly released when quitting a function - fixed wrong return in IopCreateVpb() - minor fixes around svn path=/trunk/; revision=52065
2011-06-02 17:43:44 +00:00
extern LIST_ENTRY IopFsNotifyChangeQueueHead;
extern LIST_ENTRY IopErrorLogListHead;
extern LIST_ENTRY IopTimerQueueHead;
extern KDPC IopTimerDpc;
extern KTIMER IopTimer;
extern KSPIN_LOCK IoStatisticsLock;
extern KSPIN_LOCK DriverReinitListLock;
extern KSPIN_LOCK DriverBootReinitListLock;
extern KSPIN_LOCK IopLogListLock;
extern KSPIN_LOCK IopTimerLock;
extern PDEVICE_OBJECT IopErrorLogObject;
extern BOOLEAN PnPBootDriversInitialized;
GENERAL_LOOKASIDE IoLargeIrpLookaside;
GENERAL_LOOKASIDE IoSmallIrpLookaside;
GENERAL_LOOKASIDE IopMdlLookasideList;
extern GENERAL_LOOKASIDE IoCompletionPacketLookaside;
PLOADER_PARAMETER_BLOCK IopLoaderBlock;
IO Manager Cleanup continues: - Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile, IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an example). - Cleaned up some IRP code and fixed a couple of bugs, mainly: - Write I/O Type in IRP - Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code) - Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect behaviour. Code should never depend on a buffer being zeroed! - Remove a lot of duplicated code and helper/alternate functions that weren't really useful. - Free MDL and IRP on some failures where we didn't - Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the old revision and copy/pasting the new code directly above it. The functions which we touched are: - IoAllocateIrp - IoBuild[A]SyncronousFsdRequest - IoBuildDeviceIoControlRequest - IoInitializeIrp - IoPageRead, IoSynchronousPageWrite svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
/* INIT FUNCTIONS ************************************************************/
CODE_SEG("INIT")
VOID
NTAPI
IopInitLookasideLists(VOID)
{
ULONG LargeIrpSize, SmallIrpSize, MdlSize;
LONG i;
PKPRCB Prcb;
PGENERAL_LOOKASIDE CurrentList = NULL;
/* Calculate the sizes */
LargeIrpSize = sizeof(IRP) + (8 * sizeof(IO_STACK_LOCATION));
SmallIrpSize = sizeof(IRP) + sizeof(IO_STACK_LOCATION);
MdlSize = sizeof(MDL) + (23 * sizeof(PFN_NUMBER));
/* Initialize the Lookaside List for I\O Completion */
ExInitializeSystemLookasideList(&IoCompletionPacketLookaside,
NonPagedPool,
sizeof(IOP_MINI_COMPLETION_PACKET),
IOC_TAG1,
32,
&ExSystemLookasideListHead);
/* Initialize the Lookaside List for Large IRPs */
ExInitializeSystemLookasideList(&IoLargeIrpLookaside,
NonPagedPool,
LargeIrpSize,
IO_LARGEIRP,
64,
&ExSystemLookasideListHead);
/* Initialize the Lookaside List for Small IRPs */
ExInitializeSystemLookasideList(&IoSmallIrpLookaside,
NonPagedPool,
SmallIrpSize,
IO_SMALLIRP,
32,
&ExSystemLookasideListHead);
/* Initialize the Lookaside List for MDLs */
ExInitializeSystemLookasideList(&IopMdlLookasideList,
NonPagedPool,
MdlSize,
TAG_MDL,
128,
&ExSystemLookasideListHead);
/* Allocate the global lookaside list buffer */
CurrentList = ExAllocatePoolWithTag(NonPagedPool,
4 * KeNumberProcessors *
sizeof(GENERAL_LOOKASIDE),
TAG_IO);
/* Loop all processors */
for (i = 0; i < KeNumberProcessors; i++)
{
/* Get the PRCB for this CPU */
Prcb = KiProcessorBlock[i];
DPRINT("Setting up lookaside for CPU: %x, PRCB: %p\n", i, Prcb);
/* Write IRP credit limit */
Prcb->LookasideIrpFloat = 512 / KeNumberProcessors;
/* Set the I/O Completion List */
Prcb->PPLookasideList[LookasideCompletionList].L = &IoCompletionPacketLookaside;
if (CurrentList)
{
/* Initialize the Lookaside List for mini-packets */
ExInitializeSystemLookasideList(CurrentList,
NonPagedPool,
sizeof(IOP_MINI_COMPLETION_PACKET),
IO_SMALLIRP_CPU,
32,
&ExSystemLookasideListHead);
Prcb->PPLookasideList[LookasideCompletionList].P = CurrentList;
CurrentList++;
}
else
{
Prcb->PPLookasideList[LookasideCompletionList].P = &IoCompletionPacketLookaside;
}
/* Set the Large IRP List */
Prcb->PPLookasideList[LookasideLargeIrpList].L = &IoLargeIrpLookaside;
if (CurrentList)
{
/* Initialize the Lookaside List for Large IRPs */
ExInitializeSystemLookasideList(CurrentList,
NonPagedPool,
LargeIrpSize,
IO_LARGEIRP_CPU,
64,
&ExSystemLookasideListHead);
Prcb->PPLookasideList[LookasideLargeIrpList].P = CurrentList;
CurrentList++;
}
else
{
Prcb->PPLookasideList[LookasideLargeIrpList].P = &IoLargeIrpLookaside;
}
/* Set the Small IRP List */
Prcb->PPLookasideList[LookasideSmallIrpList].L = &IoSmallIrpLookaside;
if (CurrentList)
{
/* Initialize the Lookaside List for Small IRPs */
ExInitializeSystemLookasideList(CurrentList,
NonPagedPool,
SmallIrpSize,
IO_SMALLIRP_CPU,
32,
&ExSystemLookasideListHead);
Prcb->PPLookasideList[LookasideSmallIrpList].P = CurrentList;
CurrentList++;
}
else
{
Prcb->PPLookasideList[LookasideSmallIrpList].P = &IoSmallIrpLookaside;
}
/* Set the MDL Completion List */
Prcb->PPLookasideList[LookasideMdlList].L = &IopMdlLookasideList;
if (CurrentList)
{
/* Initialize the Lookaside List for MDLs */
ExInitializeSystemLookasideList(CurrentList,
NonPagedPool,
SmallIrpSize,
TAG_MDL,
128,
&ExSystemLookasideListHead);
Prcb->PPLookasideList[LookasideMdlList].P = CurrentList;
CurrentList++;
}
else
{
Prcb->PPLookasideList[LookasideMdlList].P = &IopMdlLookasideList;
}
}
}
CODE_SEG("INIT")
BOOLEAN
NTAPI
IopCreateObjectTypes(VOID)
{
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
UNICODE_STRING Name;
/* Initialize default settings */
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
ObjectTypeInitializer.PoolType = NonPagedPool;
ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
ObjectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS;
ObjectTypeInitializer.UseDefaultObject = TRUE;
ObjectTypeInitializer.GenericMapping = IopFileMapping;
/* Do the Adapter Type */
RtlInitUnicodeString(&Name, L"Adapter");
if (!NT_SUCCESS(ObCreateObjectType(&Name,
&ObjectTypeInitializer,
NULL,
&IoAdapterObjectType))) return FALSE;
/* Do the Controller Type */
RtlInitUnicodeString(&Name, L"Controller");
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(CONTROLLER_OBJECT);
if (!NT_SUCCESS(ObCreateObjectType(&Name,
&ObjectTypeInitializer,
NULL,
&IoControllerObjectType))) return FALSE;
/* Do the Device Type */
RtlInitUnicodeString(&Name, L"Device");
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DEVICE_OBJECT);
ObjectTypeInitializer.DeleteProcedure = IopDeleteDevice;
ObjectTypeInitializer.ParseProcedure = IopParseDevice;
ObjectTypeInitializer.SecurityProcedure = IopGetSetSecurityObject;
ObjectTypeInitializer.CaseInsensitive = TRUE;
if (!NT_SUCCESS(ObCreateObjectType(&Name,
&ObjectTypeInitializer,
NULL,
&IoDeviceObjectType))) return FALSE;
/* Initialize the Driver object type */
RtlInitUnicodeString(&Name, L"Driver");
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DRIVER_OBJECT);
ObjectTypeInitializer.DeleteProcedure = IopDeleteDriver;
ObjectTypeInitializer.ParseProcedure = NULL;
ObjectTypeInitializer.SecurityProcedure = NULL;
if (!NT_SUCCESS(ObCreateObjectType(&Name,
&ObjectTypeInitializer,
NULL,
&IoDriverObjectType))) return FALSE;
/* Initialize the I/O Completion object type */
RtlInitUnicodeString(&Name, L"IoCompletion");
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KQUEUE);
ObjectTypeInitializer.ValidAccessMask = IO_COMPLETION_ALL_ACCESS;
ObjectTypeInitializer.InvalidAttributes |= OBJ_PERMANENT;
ObjectTypeInitializer.GenericMapping = IopCompletionMapping;
ObjectTypeInitializer.DeleteProcedure = IopDeleteIoCompletion;
if (!NT_SUCCESS(ObCreateObjectType(&Name,
&ObjectTypeInitializer,
NULL,
&IoCompletionType))) return FALSE;
/* Initialize the File object type */
RtlInitUnicodeString(&Name, L"File");
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(FILE_OBJECT);
ObjectTypeInitializer.InvalidAttributes |= OBJ_EXCLUSIVE;
ObjectTypeInitializer.MaintainHandleCount = TRUE;
ObjectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS;
ObjectTypeInitializer.GenericMapping = IopFileMapping;
ObjectTypeInitializer.CloseProcedure = IopCloseFile;
ObjectTypeInitializer.DeleteProcedure = IopDeleteFile;
ObjectTypeInitializer.SecurityProcedure = IopGetSetSecurityObject;
ObjectTypeInitializer.QueryNameProcedure = IopQueryName;
ObjectTypeInitializer.ParseProcedure = IopParseFile;
ObjectTypeInitializer.UseDefaultObject = FALSE;
if (!NT_SUCCESS(ObCreateObjectType(&Name,
&ObjectTypeInitializer,
NULL,
&IoFileObjectType))) return FALSE;
/* Success */
return TRUE;
}
CODE_SEG("INIT")
BOOLEAN
NTAPI
IopCreateRootDirectories(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DirName;
HANDLE Handle;
NTSTATUS Status;
/* Create the '\Driver' object directory */
RtlInitUnicodeString(&DirName, L"\\Driver");
InitializeObjectAttributes(&ObjectAttributes,
&DirName,
OBJ_PERMANENT,
NULL,
NULL);
Status = NtCreateDirectoryObject(&Handle,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create \\Driver directory: 0x%lx\n", Status);
return FALSE;
}
NtClose(Handle);
/* Create the '\FileSystem' object directory */
RtlInitUnicodeString(&DirName, L"\\FileSystem");
InitializeObjectAttributes(&ObjectAttributes,
&DirName,
OBJ_PERMANENT,
NULL,
NULL);
Status = NtCreateDirectoryObject(&Handle,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create \\FileSystem directory: 0x%lx\n", Status);
return FALSE;
}
NtClose(Handle);
/* Create the '\FileSystem' object directory */
RtlInitUnicodeString(&DirName, L"\\FileSystem\\Filters");
InitializeObjectAttributes(&ObjectAttributes,
&DirName,
OBJ_PERMANENT,
NULL,
NULL);
Status = NtCreateDirectoryObject(&Handle,
DIRECTORY_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create \\FileSystem\\Filters directory: 0x%lx\n", Status);
return FALSE;
}
NtClose(Handle);
/* Return success */
return TRUE;
}
CODE_SEG("INIT")
BOOLEAN
NTAPI
IopMarkBootPartition(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
OBJECT_ATTRIBUTES ObjectAttributes;
STRING DeviceString;
CHAR Buffer[256];
UNICODE_STRING DeviceName;
NTSTATUS Status;
HANDLE FileHandle;
IO_STATUS_BLOCK IoStatusBlock;
PFILE_OBJECT FileObject;
/* Build the ARC device name */
sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
RtlInitAnsiString(&DeviceString, Buffer);
Status = RtlAnsiStringToUnicodeString(&DeviceName, &DeviceString, TRUE);
if (!NT_SUCCESS(Status)) return FALSE;
/* Open it */
InitializeObjectAttributes(&ObjectAttributes,
&DeviceName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenFile(&FileHandle,
FILE_READ_ATTRIBUTES,
&ObjectAttributes,
&IoStatusBlock,
0,
FILE_NON_DIRECTORY_FILE);
if (!NT_SUCCESS(Status))
{
/* Fail */
KeBugCheckEx(INACCESSIBLE_BOOT_DEVICE,
(ULONG_PTR)&DeviceName,
Status,
0,
0);
}
/* Get the DO */
Status = ObReferenceObjectByHandle(FileHandle,
0,
IoFileObjectType,
KernelMode,
(PVOID *)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
/* Fail */
RtlFreeUnicodeString(&DeviceName);
return FALSE;
}
/* Mark it as the boot partition */
FileObject->DeviceObject->Flags |= DO_SYSTEM_BOOT_PARTITION;
/* Save a copy of the DO for the I/O Error Logger */
ObReferenceObject(FileObject->DeviceObject);
IopErrorLogObject = FileObject->DeviceObject;
/* Cleanup and return success */
RtlFreeUnicodeString(&DeviceName);
NtClose(FileHandle);
ObDereferenceObject(FileObject);
return TRUE;
}
CODE_SEG("INIT")
BOOLEAN
NTAPI
IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
LARGE_INTEGER ExpireTime;
NTSTATUS Status;
CHAR Buffer[256];
ANSI_STRING NtBootPath, RootString;
/* Initialize empty NT Boot Path */
RtlInitEmptyAnsiString(&NtBootPath, Buffer, sizeof(Buffer));
/* Initialize the lookaside lists */
IopInitLookasideLists();
/* Initialize all locks and lists */
ExInitializeResourceLite(&IopDatabaseResource);
ExInitializeResourceLite(&IopSecurityResource);
ExInitializeResourceLite(&IopDriverLoadResource);
[NTOSKRNL] - renamed Io volumes global to match Windows names (in case of debug) - renamed IopDereferenceVpb() to IopDereferenceVpbAndFree(), IopReferenceVpbForVerify() to IopReferenceVerifyVpb(), IopInitializeVpbForMount() to IopMountInitializeVpb(), IopLoadFileSystem() to IopLoadFileSystemDriver() - implemented IopDecrementDeviceObjectHandleCount(), IopInterlockedIncrementUlong(), IopInterlockedDecrementUlong(), IopNotifyAlreadyRegisteredFileSystems() and IoEnumerateRegisteredFiltersList() - halfplemented IopDecrementDeviceObjectRef() - implemented check for already registrered notification in IoRegisterFsRegistrationChange() - implemented sending notifications for already registered drivers to registrant in IoRegisterFsRegistrationChange() - implemented VPB freeing in IopDereferenceVpbAndFree() - acquire Io volumes lists once and forever for system shutdown, instead of keeping acquiring and releasing - reference device object in IopShutdownBaseFileSystems() before sending it the shutdown IRP. To ensure to keep it valid till the end - added a FS driver registration operations counter - use this counter to handle failed mounts - fixed: release locks before calling driver for mounting and reacquire them after - fixed check for boot partition failure (and associated bugcheck): check we are in boot phase 0 or 1 - simplified lock process by using only one lock (ie removed mutex). Also use only critical region where needed - fixed: ensure that locks are properly released when quitting a function - fixed wrong return in IopCreateVpb() - minor fixes around svn path=/trunk/; revision=52065
2011-06-02 17:43:44 +00:00
InitializeListHead(&IopDiskFileSystemQueueHead);
InitializeListHead(&IopCdRomFileSystemQueueHead);
InitializeListHead(&IopTapeFileSystemQueueHead);
InitializeListHead(&IopNetworkFileSystemQueueHead);
InitializeListHead(&DriverBootReinitListHead);
InitializeListHead(&DriverReinitListHead);
InitializeListHead(&ShutdownListHead);
InitializeListHead(&LastChanceShutdownListHead);
[NTOSKRNL] - renamed Io volumes global to match Windows names (in case of debug) - renamed IopDereferenceVpb() to IopDereferenceVpbAndFree(), IopReferenceVpbForVerify() to IopReferenceVerifyVpb(), IopInitializeVpbForMount() to IopMountInitializeVpb(), IopLoadFileSystem() to IopLoadFileSystemDriver() - implemented IopDecrementDeviceObjectHandleCount(), IopInterlockedIncrementUlong(), IopInterlockedDecrementUlong(), IopNotifyAlreadyRegisteredFileSystems() and IoEnumerateRegisteredFiltersList() - halfplemented IopDecrementDeviceObjectRef() - implemented check for already registrered notification in IoRegisterFsRegistrationChange() - implemented sending notifications for already registered drivers to registrant in IoRegisterFsRegistrationChange() - implemented VPB freeing in IopDereferenceVpbAndFree() - acquire Io volumes lists once and forever for system shutdown, instead of keeping acquiring and releasing - reference device object in IopShutdownBaseFileSystems() before sending it the shutdown IRP. To ensure to keep it valid till the end - added a FS driver registration operations counter - use this counter to handle failed mounts - fixed: release locks before calling driver for mounting and reacquire them after - fixed check for boot partition failure (and associated bugcheck): check we are in boot phase 0 or 1 - simplified lock process by using only one lock (ie removed mutex). Also use only critical region where needed - fixed: ensure that locks are properly released when quitting a function - fixed wrong return in IopCreateVpb() - minor fixes around svn path=/trunk/; revision=52065
2011-06-02 17:43:44 +00:00
InitializeListHead(&IopFsNotifyChangeQueueHead);
InitializeListHead(&IopErrorLogListHead);
KeInitializeSpinLock(&IoStatisticsLock);
KeInitializeSpinLock(&DriverReinitListLock);
KeInitializeSpinLock(&DriverBootReinitListLock);
KeInitializeSpinLock(&ShutdownListLock);
KeInitializeSpinLock(&IopLogListLock);
/* Initialize PnP notifications */
PiInitializeNotifications();
/* Initialize the reserve IRP */
if (!IopInitializeReserveIrp(&IopReserveIrpAllocator))
{
DPRINT1("IopInitializeReserveIrp failed!\n");
return FALSE;
}
/* Initialize Timer List Lock */
KeInitializeSpinLock(&IopTimerLock);
/* Initialize Timer List */
InitializeListHead(&IopTimerQueueHead);
/* Initialize the DPC/Timer which will call the other Timer Routines */
ExpireTime.QuadPart = -10000000;
KeInitializeDpc(&IopTimerDpc, IopTimerDispatch, NULL);
KeInitializeTimerEx(&IopTimer, SynchronizationTimer);
KeSetTimerEx(&IopTimer, ExpireTime, 1000, &IopTimerDpc);
/* Create Object Types */
if (!IopCreateObjectTypes())
{
DPRINT1("IopCreateObjectTypes failed!\n");
return FALSE;
}
/* Create Object Directories */
if (!IopCreateRootDirectories())
{
DPRINT1("IopCreateRootDirectories failed!\n");
return FALSE;
}
/* Initialize PnP manager */
IopInitializePlugPlayServices();
/* Initialize SHIM engine */
ApphelpCacheInitialize();
/* Initialize WMI */
WmiInitialize();
/* Initialize HAL Root Bus Driver */
HalInitPnpDriver();
/* Reenumerate what HAL has added (synchronously)
* This function call should eventually become a 2nd stage of the PnP initialization */
PiQueueDeviceAction(IopRootDeviceNode->PhysicalDeviceObject,
PiActionEnumRootDevices,
NULL,
NULL);
/* Make loader block available for the whole kernel */
IopLoaderBlock = LoaderBlock;
/* Load boot start drivers */
IopInitializeBootDrivers();
/* Call back drivers that asked for */
IopReinitializeBootDrivers();
/* Check if this was a ramdisk boot */
if (!_strnicmp(LoaderBlock->ArcBootDeviceName, "ramdisk(0)", 10))
{
/* Initialize the ramdisk driver */
IopStartRamdisk(LoaderBlock);
}
/* No one should need loader block any longer */
IopLoaderBlock = NULL;
/* Create ARC names for boot devices */
Status = IopCreateArcNames(LoaderBlock);
if (!NT_SUCCESS(Status))
{
DPRINT1("IopCreateArcNames failed: %lx\n", Status);
return FALSE;
}
/* Mark the system boot partition */
if (!IopMarkBootPartition(LoaderBlock))
{
DPRINT1("IopMarkBootPartition failed!\n");
return FALSE;
}
// the disk subsystem is initialized here and the SystemRoot is set too
// we can finally load other drivers from the boot volume
PnPBootDriversInitialized = TRUE;
#if !defined(_WINKD_) && defined(KDBG)
KD System Rewrite: - Totally dynamic based on the principle of Native Providers built-in the Kernel (like Screen, FileLog and Serial) and a pluggable Wrapper which is optionally compiled (Bochs, GDB) - Nothing changed in KDBG, except for that its settings (KDSERIAL/KDNOECHO) are now stored in KdbDebugState instead. - Wrappers are currently built uncondtionally. With rbuild, I'll make them easily removable. - Debug Log code simplified greatly, sped up and now supports printing even the first boot messages, which wasn't supported before. - Removed most of KDBG compile-time settings, ones which are needed are in include/dbg as macros now. - Left in some kdbg init code and break code, but it could be made to be used as a 'wrapper' for those functions. I will do it later. - Made a hack for KdpEnterDebuggerException..it seems to be called differently and at different times for GDB vs KDBG and I couldn't unite them. - KdpServiceDispatcher now does both the documented and ros-internal debug functions and will eventually be called through INT2D from keyboard.sys instead of as an API. All in all, this patch makes KD separated from KDBG and creates a pluggable architecture for creating future wrappers that don't require changing tons of code in the future. It improves the debug log by printing even the earliest debug messages to it and it removes many of the manual ifdef(KDBG) but making them automatic though a single macro file. It makes extra debugging functionality optional and it allows removal of a private API from our exports. svn path=/trunk/; revision=14799
2005-04-25 14:44:48 +00:00
/* Read KDB Data */
KdbInit();
KD System Rewrite: - Totally dynamic based on the principle of Native Providers built-in the Kernel (like Screen, FileLog and Serial) and a pluggable Wrapper which is optionally compiled (Bochs, GDB) - Nothing changed in KDBG, except for that its settings (KDSERIAL/KDNOECHO) are now stored in KdbDebugState instead. - Wrappers are currently built uncondtionally. With rbuild, I'll make them easily removable. - Debug Log code simplified greatly, sped up and now supports printing even the first boot messages, which wasn't supported before. - Removed most of KDBG compile-time settings, ones which are needed are in include/dbg as macros now. - Left in some kdbg init code and break code, but it could be made to be used as a 'wrapper' for those functions. I will do it later. - Made a hack for KdpEnterDebuggerException..it seems to be called differently and at different times for GDB vs KDBG and I couldn't unite them. - KdpServiceDispatcher now does both the documented and ros-internal debug functions and will eventually be called through INT2D from keyboard.sys instead of as an API. All in all, this patch makes KD separated from KDBG and creates a pluggable architecture for creating future wrappers that don't require changing tons of code in the future. It improves the debug log by printing even the earliest debug messages to it and it removes many of the manual ifdef(KDBG) but making them automatic though a single macro file. It makes extra debugging functionality optional and it allows removal of a private API from our exports. svn path=/trunk/; revision=14799
2005-04-25 14:44:48 +00:00
/* I/O is now setup for disk access, so phase 3 */
KdInitSystem(3, LoaderBlock);
#endif
/* Load system start drivers */
IopInitializeSystemDrivers();
PnpSystemInit = TRUE;
/* Reinitialize drivers that requested it */
IopReinitializeDrivers();
/* Convert SystemRoot from ARC to NT path */
Status = IopReassignSystemRoot(LoaderBlock, &NtBootPath);
if (!NT_SUCCESS(Status))
{
DPRINT1("IopReassignSystemRoot failed: %lx\n", Status);
return FALSE;
}
/* Set the ANSI_STRING for the root path */
RootString.MaximumLength = NtSystemRoot.MaximumLength / sizeof(WCHAR);
RootString.Length = 0;
RootString.Buffer = ExAllocatePoolWithTag(PagedPool,
RootString.MaximumLength,
TAG_IO);
/* Convert the path into the ANSI_STRING */
Status = RtlUnicodeStringToAnsiString(&RootString, &NtSystemRoot, FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlUnicodeStringToAnsiString failed: %lx\n", Status);
return FALSE;
}
/* Assign drive letters */
IoAssignDriveLetters(LoaderBlock,
&NtBootPath,
(PUCHAR)RootString.Buffer,
&RootString);
/* Update system root */
Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &RootString, FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT1("RtlAnsiStringToUnicodeString failed: %lx\n", Status);
return FALSE;
}
/* Load the System DLL and its Entrypoints */
Status = PsLocateSystemDll();
if (!NT_SUCCESS(Status))
{
DPRINT1("PsLocateSystemDll failed: %lx\n", Status);
return FALSE;
}
/* Return success */
return TRUE;
}
BOOLEAN
NTAPI
IoInitializeCrashDump(IN HANDLE PageFileHandle)
{
UNIMPLEMENTED;
return FALSE;
}
/* EOF */