mirror of
https://github.com/reactos/reactos.git
synced 2024-11-10 08:43:28 +00:00
6638a5b899
svn path=/branches/reactos-yarotows/; revision=46732
568 lines
20 KiB
C
568 lines
20 KiB
C
/*
|
|
* 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
|
|
*
|
|
* 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
|
|
);
|
|
|
|
/* DATA ********************************************************************/
|
|
|
|
POBJECT_TYPE IoDeviceObjectType = NULL;
|
|
POBJECT_TYPE IoFileObjectType = NULL;
|
|
extern POBJECT_TYPE IoControllerObjectType;
|
|
extern UNICODE_STRING NtSystemRoot;
|
|
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];
|
|
|
|
GENERIC_MAPPING IopFileMapping = {
|
|
FILE_GENERIC_READ,
|
|
FILE_GENERIC_WRITE,
|
|
FILE_GENERIC_EXECUTE,
|
|
FILE_ALL_ACCESS};
|
|
|
|
extern LIST_ENTRY ShutdownListHead;
|
|
extern LIST_ENTRY LastChanceShutdownListHead;
|
|
extern KSPIN_LOCK ShutdownListLock;
|
|
extern POBJECT_TYPE IoAdapterObjectType;
|
|
ERESOURCE IopDatabaseResource;
|
|
extern ERESOURCE FileSystemListLock;
|
|
ERESOURCE IopSecurityResource;
|
|
extern KGUARDED_MUTEX FsChangeNotifyListLock;
|
|
extern KGUARDED_MUTEX PnpNotifyListLock;
|
|
extern LIST_ENTRY IopDiskFsListHead;
|
|
extern LIST_ENTRY IopCdRomFsListHead;
|
|
extern LIST_ENTRY IopTapeFsListHead;
|
|
extern LIST_ENTRY IopNetworkFsListHead;
|
|
extern LIST_ENTRY DriverBootReinitListHead;
|
|
extern LIST_ENTRY DriverReinitListHead;
|
|
extern LIST_ENTRY PnpNotifyListHead;
|
|
extern LIST_ENTRY FsChangeNotifyListHead;
|
|
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;
|
|
|
|
GENERAL_LOOKASIDE IoLargeIrpLookaside;
|
|
GENERAL_LOOKASIDE IoSmallIrpLookaside;
|
|
GENERAL_LOOKASIDE IopMdlLookasideList;
|
|
extern GENERAL_LOOKASIDE IoCompletionPacketLookaside;
|
|
|
|
#if defined (ALLOC_PRAGMA)
|
|
#pragma alloc_text(INIT, IoInitSystem)
|
|
#endif
|
|
|
|
/* INIT FUNCTIONS ************************************************************/
|
|
|
|
VOID
|
|
INIT_FUNCTION
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOLEAN
|
|
INIT_FUNCTION
|
|
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 = IopSecurityFile;
|
|
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 = IopSecurityFile;
|
|
ObjectTypeInitializer.QueryNameProcedure = IopQueryNameFile;
|
|
ObjectTypeInitializer.ParseProcedure = IopParseFile;
|
|
ObjectTypeInitializer.UseDefaultObject = FALSE;
|
|
if (!NT_SUCCESS(ObCreateObjectType(&Name,
|
|
&ObjectTypeInitializer,
|
|
NULL,
|
|
&IoFileObjectType))) return FALSE;
|
|
|
|
/* Success */
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN
|
|
INIT_FUNCTION
|
|
NTAPI
|
|
IopCreateRootDirectories()
|
|
{
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
UNICODE_STRING DirName;
|
|
HANDLE Handle;
|
|
|
|
/* Create the '\Driver' object directory */
|
|
RtlInitUnicodeString(&DirName, L"\\Driver");
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&DirName,
|
|
OBJ_PERMANENT,
|
|
NULL,
|
|
NULL);
|
|
if (!NT_SUCCESS(NtCreateDirectoryObject(&Handle,
|
|
DIRECTORY_ALL_ACCESS,
|
|
&ObjectAttributes))) return FALSE;
|
|
NtClose(Handle);
|
|
|
|
/* Create the '\FileSystem' object directory */
|
|
RtlInitUnicodeString(&DirName, L"\\FileSystem");
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
&DirName,
|
|
OBJ_PERMANENT,
|
|
NULL,
|
|
NULL);
|
|
if (!NT_SUCCESS(NtCreateDirectoryObject(&Handle,
|
|
DIRECTORY_ALL_ACCESS,
|
|
&ObjectAttributes))) return FALSE;
|
|
NtClose(Handle);
|
|
|
|
/* Return success */
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN
|
|
INIT_FUNCTION
|
|
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;
|
|
}
|
|
|
|
BOOLEAN
|
|
INIT_FUNCTION
|
|
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 */
|
|
ExInitializeResource(&IopDatabaseResource);
|
|
ExInitializeResource(&FileSystemListLock);
|
|
ExInitializeResource(&IopSecurityResource);
|
|
KeInitializeGuardedMutex(&FsChangeNotifyListLock);
|
|
KeInitializeGuardedMutex(&PnpNotifyListLock);
|
|
InitializeListHead(&IopDiskFsListHead);
|
|
InitializeListHead(&IopCdRomFsListHead);
|
|
InitializeListHead(&IopTapeFsListHead);
|
|
InitializeListHead(&IopNetworkFsListHead);
|
|
InitializeListHead(&DriverBootReinitListHead);
|
|
InitializeListHead(&DriverReinitListHead);
|
|
InitializeListHead(&PnpNotifyListHead);
|
|
InitializeListHead(&ShutdownListHead);
|
|
InitializeListHead(&LastChanceShutdownListHead);
|
|
InitializeListHead(&FsChangeNotifyListHead);
|
|
InitializeListHead(&IopErrorLogListHead);
|
|
KeInitializeSpinLock(&IoStatisticsLock);
|
|
KeInitializeSpinLock(&DriverReinitListLock);
|
|
KeInitializeSpinLock(&DriverBootReinitListLock);
|
|
KeInitializeSpinLock(&ShutdownListLock);
|
|
KeInitializeSpinLock(&IopLogListLock);
|
|
|
|
/* 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()) return FALSE;
|
|
|
|
/* Create Object Directories */
|
|
if (!IopCreateRootDirectories()) return FALSE;
|
|
|
|
/* Initialize PnP manager */
|
|
PnpInit();
|
|
|
|
/* Setup the group cache */
|
|
if (!NT_SUCCESS(PiInitCacheGroupInformation())) return FALSE;
|
|
|
|
/* 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);
|
|
}
|
|
|
|
/* Create ARC names for boot devices */
|
|
IopCreateArcNames(LoaderBlock);
|
|
|
|
/* Mark the system boot partition */
|
|
if (!IopMarkBootPartition(LoaderBlock)) return FALSE;
|
|
|
|
/* Initialize PnP root relations */
|
|
IopEnumerateDevice(IopRootDeviceNode->PhysicalDeviceObject);
|
|
|
|
#ifndef _WINKD_
|
|
/* Read KDB Data */
|
|
KdbInit();
|
|
|
|
/* I/O is now setup for disk access, so phase 3 */
|
|
KdInitSystem(3, LoaderBlock);
|
|
#endif
|
|
|
|
/* Load services for devices found by PnP manager */
|
|
IopInitializePnpServices(IopRootDeviceNode);
|
|
|
|
/* 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)) 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)) return FALSE;
|
|
|
|
/* Assign drive letters */
|
|
IoAssignDriveLetters(LoaderBlock,
|
|
&NtBootPath,
|
|
(PUCHAR)RootString.Buffer,
|
|
&RootString);
|
|
|
|
/* Update system root */
|
|
Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &RootString, FALSE);
|
|
if (!NT_SUCCESS(Status)) return FALSE;
|
|
|
|
/* Load the System DLL and its Entrypoints */
|
|
if (!NT_SUCCESS(PsLocateSystemDll())) return FALSE;
|
|
|
|
/* Return success */
|
|
return TRUE;
|
|
}
|
|
|
|
/* EOF */
|