1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Kernel 4 * FILE: ntoskrnl/io/iomgr/iomgr.c 5 * PURPOSE: I/O Manager Initialization and Misc Utility Functions 6 * 7 * PROGRAMMERS: David Welch (welch@mcmail.com) 8 */ 9 10 /* INCLUDES ****************************************************************/ 11 12 #include <ntoskrnl.h> 13 #define NDEBUG 14 #include <debug.h> 15 16 ULONG IopTraceLevel = 0; 17 BOOLEAN PnpSystemInit = FALSE; 18 19 VOID 20 NTAPI 21 IopTimerDispatch( 22 IN PKDPC Dpc, 23 IN PVOID DeferredContext, 24 IN PVOID SystemArgument1, 25 IN PVOID SystemArgument2 26 ); 27 28 BOOLEAN 29 NTAPI 30 WmiInitialize( 31 VOID); 32 33 /* DATA ********************************************************************/ 34 35 POBJECT_TYPE IoDeviceObjectType = NULL; 36 POBJECT_TYPE IoFileObjectType = NULL; 37 extern POBJECT_TYPE IoControllerObjectType; 38 BOOLEAN IoCountOperations = TRUE; 39 ULONG IoReadOperationCount = 0; 40 LARGE_INTEGER IoReadTransferCount = {{0, 0}}; 41 ULONG IoWriteOperationCount = 0; 42 LARGE_INTEGER IoWriteTransferCount = {{0, 0}}; 43 ULONG IoOtherOperationCount = 0; 44 LARGE_INTEGER IoOtherTransferCount = {{0, 0}}; 45 KSPIN_LOCK IoStatisticsLock = 0; 46 ULONG IopNumTriageDumpDataBlocks; 47 PVOID IopTriageDumpDataBlocks[64]; 48 49 GENERIC_MAPPING IopFileMapping = { 50 FILE_GENERIC_READ, 51 FILE_GENERIC_WRITE, 52 FILE_GENERIC_EXECUTE, 53 FILE_ALL_ACCESS}; 54 55 extern LIST_ENTRY ShutdownListHead; 56 extern LIST_ENTRY LastChanceShutdownListHead; 57 extern KSPIN_LOCK ShutdownListLock; 58 extern POBJECT_TYPE IoAdapterObjectType; 59 extern ERESOURCE IopDatabaseResource; 60 ERESOURCE IopSecurityResource; 61 extern ERESOURCE IopDriverLoadResource; 62 extern KGUARDED_MUTEX PnpNotifyListLock; 63 extern LIST_ENTRY IopDiskFileSystemQueueHead; 64 extern LIST_ENTRY IopCdRomFileSystemQueueHead; 65 extern LIST_ENTRY IopTapeFileSystemQueueHead; 66 extern LIST_ENTRY IopNetworkFileSystemQueueHead; 67 extern LIST_ENTRY DriverBootReinitListHead; 68 extern LIST_ENTRY DriverReinitListHead; 69 extern LIST_ENTRY PnpNotifyListHead; 70 extern LIST_ENTRY IopFsNotifyChangeQueueHead; 71 extern LIST_ENTRY IopErrorLogListHead; 72 extern LIST_ENTRY IopTimerQueueHead; 73 extern KDPC IopTimerDpc; 74 extern KTIMER IopTimer; 75 extern KSPIN_LOCK IoStatisticsLock; 76 extern KSPIN_LOCK DriverReinitListLock; 77 extern KSPIN_LOCK DriverBootReinitListLock; 78 extern KSPIN_LOCK IopLogListLock; 79 extern KSPIN_LOCK IopTimerLock; 80 81 extern PDEVICE_OBJECT IopErrorLogObject; 82 83 GENERAL_LOOKASIDE IoLargeIrpLookaside; 84 GENERAL_LOOKASIDE IoSmallIrpLookaside; 85 GENERAL_LOOKASIDE IopMdlLookasideList; 86 extern GENERAL_LOOKASIDE IoCompletionPacketLookaside; 87 88 PLOADER_PARAMETER_BLOCK IopLoaderBlock; 89 90 #if defined (ALLOC_PRAGMA) 91 #pragma alloc_text(INIT, IoInitSystem) 92 #endif 93 94 /* INIT FUNCTIONS ************************************************************/ 95 96 VOID 97 INIT_FUNCTION 98 NTAPI 99 IopInitLookasideLists(VOID) 100 { 101 ULONG LargeIrpSize, SmallIrpSize, MdlSize; 102 LONG i; 103 PKPRCB Prcb; 104 PGENERAL_LOOKASIDE CurrentList = NULL; 105 106 /* Calculate the sizes */ 107 LargeIrpSize = sizeof(IRP) + (8 * sizeof(IO_STACK_LOCATION)); 108 SmallIrpSize = sizeof(IRP) + sizeof(IO_STACK_LOCATION); 109 MdlSize = sizeof(MDL) + (23 * sizeof(PFN_NUMBER)); 110 111 /* Initialize the Lookaside List for I\O Completion */ 112 ExInitializeSystemLookasideList(&IoCompletionPacketLookaside, 113 NonPagedPool, 114 sizeof(IOP_MINI_COMPLETION_PACKET), 115 IOC_TAG1, 116 32, 117 &ExSystemLookasideListHead); 118 119 /* Initialize the Lookaside List for Large IRPs */ 120 ExInitializeSystemLookasideList(&IoLargeIrpLookaside, 121 NonPagedPool, 122 LargeIrpSize, 123 IO_LARGEIRP, 124 64, 125 &ExSystemLookasideListHead); 126 127 128 /* Initialize the Lookaside List for Small IRPs */ 129 ExInitializeSystemLookasideList(&IoSmallIrpLookaside, 130 NonPagedPool, 131 SmallIrpSize, 132 IO_SMALLIRP, 133 32, 134 &ExSystemLookasideListHead); 135 136 /* Initialize the Lookaside List for MDLs */ 137 ExInitializeSystemLookasideList(&IopMdlLookasideList, 138 NonPagedPool, 139 MdlSize, 140 TAG_MDL, 141 128, 142 &ExSystemLookasideListHead); 143 144 /* Allocate the global lookaside list buffer */ 145 CurrentList = ExAllocatePoolWithTag(NonPagedPool, 146 4 * KeNumberProcessors * 147 sizeof(GENERAL_LOOKASIDE), 148 TAG_IO); 149 150 /* Loop all processors */ 151 for (i = 0; i < KeNumberProcessors; i++) 152 { 153 /* Get the PRCB for this CPU */ 154 Prcb = KiProcessorBlock[i]; 155 DPRINT("Setting up lookaside for CPU: %x, PRCB: %p\n", i, Prcb); 156 157 /* Write IRP credit limit */ 158 Prcb->LookasideIrpFloat = 512 / KeNumberProcessors; 159 160 /* Set the I/O Completion List */ 161 Prcb->PPLookasideList[LookasideCompletionList].L = &IoCompletionPacketLookaside; 162 if (CurrentList) 163 { 164 /* Initialize the Lookaside List for mini-packets */ 165 ExInitializeSystemLookasideList(CurrentList, 166 NonPagedPool, 167 sizeof(IOP_MINI_COMPLETION_PACKET), 168 IO_SMALLIRP_CPU, 169 32, 170 &ExSystemLookasideListHead); 171 Prcb->PPLookasideList[LookasideCompletionList].P = CurrentList; 172 CurrentList++; 173 174 } 175 else 176 { 177 Prcb->PPLookasideList[LookasideCompletionList].P = &IoCompletionPacketLookaside; 178 } 179 180 /* Set the Large IRP List */ 181 Prcb->PPLookasideList[LookasideLargeIrpList].L = &IoLargeIrpLookaside; 182 if (CurrentList) 183 { 184 /* Initialize the Lookaside List for Large IRPs */ 185 ExInitializeSystemLookasideList(CurrentList, 186 NonPagedPool, 187 LargeIrpSize, 188 IO_LARGEIRP_CPU, 189 64, 190 &ExSystemLookasideListHead); 191 Prcb->PPLookasideList[LookasideLargeIrpList].P = CurrentList; 192 CurrentList++; 193 194 } 195 else 196 { 197 Prcb->PPLookasideList[LookasideLargeIrpList].P = &IoLargeIrpLookaside; 198 } 199 200 /* Set the Small IRP List */ 201 Prcb->PPLookasideList[LookasideSmallIrpList].L = &IoSmallIrpLookaside; 202 if (CurrentList) 203 { 204 /* Initialize the Lookaside List for Small IRPs */ 205 ExInitializeSystemLookasideList(CurrentList, 206 NonPagedPool, 207 SmallIrpSize, 208 IO_SMALLIRP_CPU, 209 32, 210 &ExSystemLookasideListHead); 211 Prcb->PPLookasideList[LookasideSmallIrpList].P = CurrentList; 212 CurrentList++; 213 214 } 215 else 216 { 217 Prcb->PPLookasideList[LookasideSmallIrpList].P = &IoSmallIrpLookaside; 218 } 219 220 /* Set the MDL Completion List */ 221 Prcb->PPLookasideList[LookasideMdlList].L = &IopMdlLookasideList; 222 if (CurrentList) 223 { 224 /* Initialize the Lookaside List for MDLs */ 225 ExInitializeSystemLookasideList(CurrentList, 226 NonPagedPool, 227 SmallIrpSize, 228 TAG_MDL, 229 128, 230 &ExSystemLookasideListHead); 231 232 Prcb->PPLookasideList[LookasideMdlList].P = CurrentList; 233 CurrentList++; 234 235 } 236 else 237 { 238 Prcb->PPLookasideList[LookasideMdlList].P = &IopMdlLookasideList; 239 } 240 } 241 } 242 243 BOOLEAN 244 INIT_FUNCTION 245 NTAPI 246 IopCreateObjectTypes(VOID) 247 { 248 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; 249 UNICODE_STRING Name; 250 251 /* Initialize default settings */ 252 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); 253 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); 254 ObjectTypeInitializer.PoolType = NonPagedPool; 255 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; 256 ObjectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS; 257 ObjectTypeInitializer.UseDefaultObject = TRUE; 258 ObjectTypeInitializer.GenericMapping = IopFileMapping; 259 260 /* Do the Adapter Type */ 261 RtlInitUnicodeString(&Name, L"Adapter"); 262 if (!NT_SUCCESS(ObCreateObjectType(&Name, 263 &ObjectTypeInitializer, 264 NULL, 265 &IoAdapterObjectType))) return FALSE; 266 267 /* Do the Controller Type */ 268 RtlInitUnicodeString(&Name, L"Controller"); 269 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(CONTROLLER_OBJECT); 270 if (!NT_SUCCESS(ObCreateObjectType(&Name, 271 &ObjectTypeInitializer, 272 NULL, 273 &IoControllerObjectType))) return FALSE; 274 275 /* Do the Device Type */ 276 RtlInitUnicodeString(&Name, L"Device"); 277 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DEVICE_OBJECT); 278 ObjectTypeInitializer.DeleteProcedure = IopDeleteDevice; 279 ObjectTypeInitializer.ParseProcedure = IopParseDevice; 280 ObjectTypeInitializer.SecurityProcedure = IopGetSetSecurityObject; 281 ObjectTypeInitializer.CaseInsensitive = TRUE; 282 if (!NT_SUCCESS(ObCreateObjectType(&Name, 283 &ObjectTypeInitializer, 284 NULL, 285 &IoDeviceObjectType))) return FALSE; 286 287 /* Initialize the Driver object type */ 288 RtlInitUnicodeString(&Name, L"Driver"); 289 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DRIVER_OBJECT); 290 ObjectTypeInitializer.DeleteProcedure = IopDeleteDriver; 291 ObjectTypeInitializer.ParseProcedure = NULL; 292 ObjectTypeInitializer.SecurityProcedure = NULL; 293 if (!NT_SUCCESS(ObCreateObjectType(&Name, 294 &ObjectTypeInitializer, 295 NULL, 296 &IoDriverObjectType))) return FALSE; 297 298 /* Initialize the I/O Completion object type */ 299 RtlInitUnicodeString(&Name, L"IoCompletion"); 300 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KQUEUE); 301 ObjectTypeInitializer.ValidAccessMask = IO_COMPLETION_ALL_ACCESS; 302 ObjectTypeInitializer.InvalidAttributes |= OBJ_PERMANENT; 303 ObjectTypeInitializer.GenericMapping = IopCompletionMapping; 304 ObjectTypeInitializer.DeleteProcedure = IopDeleteIoCompletion; 305 if (!NT_SUCCESS(ObCreateObjectType(&Name, 306 &ObjectTypeInitializer, 307 NULL, 308 &IoCompletionType))) return FALSE; 309 310 /* Initialize the File object type */ 311 RtlInitUnicodeString(&Name, L"File"); 312 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(FILE_OBJECT); 313 ObjectTypeInitializer.InvalidAttributes |= OBJ_EXCLUSIVE; 314 ObjectTypeInitializer.MaintainHandleCount = TRUE; 315 ObjectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS; 316 ObjectTypeInitializer.GenericMapping = IopFileMapping; 317 ObjectTypeInitializer.CloseProcedure = IopCloseFile; 318 ObjectTypeInitializer.DeleteProcedure = IopDeleteFile; 319 ObjectTypeInitializer.SecurityProcedure = IopGetSetSecurityObject; 320 ObjectTypeInitializer.QueryNameProcedure = IopQueryNameFile; 321 ObjectTypeInitializer.ParseProcedure = IopParseFile; 322 ObjectTypeInitializer.UseDefaultObject = FALSE; 323 if (!NT_SUCCESS(ObCreateObjectType(&Name, 324 &ObjectTypeInitializer, 325 NULL, 326 &IoFileObjectType))) return FALSE; 327 328 /* Success */ 329 return TRUE; 330 } 331 332 BOOLEAN 333 INIT_FUNCTION 334 NTAPI 335 IopCreateRootDirectories(VOID) 336 { 337 OBJECT_ATTRIBUTES ObjectAttributes; 338 UNICODE_STRING DirName; 339 HANDLE Handle; 340 NTSTATUS Status; 341 342 /* Create the '\Driver' object directory */ 343 RtlInitUnicodeString(&DirName, L"\\Driver"); 344 InitializeObjectAttributes(&ObjectAttributes, 345 &DirName, 346 OBJ_PERMANENT, 347 NULL, 348 NULL); 349 Status = NtCreateDirectoryObject(&Handle, 350 DIRECTORY_ALL_ACCESS, 351 &ObjectAttributes); 352 if (!NT_SUCCESS(Status)) 353 { 354 DPRINT1("Failed to create \\Driver directory: 0x%lx\n", Status); 355 return FALSE; 356 } 357 NtClose(Handle); 358 359 /* Create the '\FileSystem' object directory */ 360 RtlInitUnicodeString(&DirName, L"\\FileSystem"); 361 InitializeObjectAttributes(&ObjectAttributes, 362 &DirName, 363 OBJ_PERMANENT, 364 NULL, 365 NULL); 366 Status = NtCreateDirectoryObject(&Handle, 367 DIRECTORY_ALL_ACCESS, 368 &ObjectAttributes); 369 if (!NT_SUCCESS(Status)) 370 { 371 DPRINT1("Failed to create \\FileSystem directory: 0x%lx\n", Status); 372 return FALSE; 373 } 374 NtClose(Handle); 375 376 /* Create the '\FileSystem' object directory */ 377 RtlInitUnicodeString(&DirName, L"\\FileSystem\\Filters"); 378 InitializeObjectAttributes(&ObjectAttributes, 379 &DirName, 380 OBJ_PERMANENT, 381 NULL, 382 NULL); 383 Status = NtCreateDirectoryObject(&Handle, 384 DIRECTORY_ALL_ACCESS, 385 &ObjectAttributes); 386 if (!NT_SUCCESS(Status)) 387 { 388 DPRINT1("Failed to create \\FileSystem\\Filters directory: 0x%lx\n", Status); 389 return FALSE; 390 } 391 NtClose(Handle); 392 393 /* Return success */ 394 return TRUE; 395 } 396 397 BOOLEAN 398 INIT_FUNCTION 399 NTAPI 400 IopMarkBootPartition(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 401 { 402 OBJECT_ATTRIBUTES ObjectAttributes; 403 STRING DeviceString; 404 CHAR Buffer[256]; 405 UNICODE_STRING DeviceName; 406 NTSTATUS Status; 407 HANDLE FileHandle; 408 IO_STATUS_BLOCK IoStatusBlock; 409 PFILE_OBJECT FileObject; 410 411 /* Build the ARC device name */ 412 sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName); 413 RtlInitAnsiString(&DeviceString, Buffer); 414 Status = RtlAnsiStringToUnicodeString(&DeviceName, &DeviceString, TRUE); 415 if (!NT_SUCCESS(Status)) return FALSE; 416 417 /* Open it */ 418 InitializeObjectAttributes(&ObjectAttributes, 419 &DeviceName, 420 OBJ_CASE_INSENSITIVE, 421 NULL, 422 NULL); 423 Status = ZwOpenFile(&FileHandle, 424 FILE_READ_ATTRIBUTES, 425 &ObjectAttributes, 426 &IoStatusBlock, 427 0, 428 FILE_NON_DIRECTORY_FILE); 429 if (!NT_SUCCESS(Status)) 430 { 431 /* Fail */ 432 KeBugCheckEx(INACCESSIBLE_BOOT_DEVICE, 433 (ULONG_PTR)&DeviceName, 434 Status, 435 0, 436 0); 437 } 438 439 /* Get the DO */ 440 Status = ObReferenceObjectByHandle(FileHandle, 441 0, 442 IoFileObjectType, 443 KernelMode, 444 (PVOID *)&FileObject, 445 NULL); 446 if (!NT_SUCCESS(Status)) 447 { 448 /* Fail */ 449 RtlFreeUnicodeString(&DeviceName); 450 return FALSE; 451 } 452 453 /* Mark it as the boot partition */ 454 FileObject->DeviceObject->Flags |= DO_SYSTEM_BOOT_PARTITION; 455 456 /* Save a copy of the DO for the I/O Error Logger */ 457 ObReferenceObject(FileObject->DeviceObject); 458 IopErrorLogObject = FileObject->DeviceObject; 459 460 /* Cleanup and return success */ 461 RtlFreeUnicodeString(&DeviceName); 462 NtClose(FileHandle); 463 ObDereferenceObject(FileObject); 464 return TRUE; 465 } 466 467 BOOLEAN 468 INIT_FUNCTION 469 NTAPI 470 IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 471 { 472 LARGE_INTEGER ExpireTime; 473 NTSTATUS Status; 474 CHAR Buffer[256]; 475 ANSI_STRING NtBootPath, RootString; 476 477 /* Initialize empty NT Boot Path */ 478 RtlInitEmptyAnsiString(&NtBootPath, Buffer, sizeof(Buffer)); 479 480 /* Initialize the lookaside lists */ 481 IopInitLookasideLists(); 482 483 /* Initialize all locks and lists */ 484 ExInitializeResourceLite(&IopDatabaseResource); 485 ExInitializeResourceLite(&IopSecurityResource); 486 ExInitializeResourceLite(&IopDriverLoadResource); 487 KeInitializeGuardedMutex(&PnpNotifyListLock); 488 InitializeListHead(&IopDiskFileSystemQueueHead); 489 InitializeListHead(&IopCdRomFileSystemQueueHead); 490 InitializeListHead(&IopTapeFileSystemQueueHead); 491 InitializeListHead(&IopNetworkFileSystemQueueHead); 492 InitializeListHead(&DriverBootReinitListHead); 493 InitializeListHead(&DriverReinitListHead); 494 InitializeListHead(&PnpNotifyListHead); 495 InitializeListHead(&ShutdownListHead); 496 InitializeListHead(&LastChanceShutdownListHead); 497 InitializeListHead(&IopFsNotifyChangeQueueHead); 498 InitializeListHead(&IopErrorLogListHead); 499 KeInitializeSpinLock(&IoStatisticsLock); 500 KeInitializeSpinLock(&DriverReinitListLock); 501 KeInitializeSpinLock(&DriverBootReinitListLock); 502 KeInitializeSpinLock(&ShutdownListLock); 503 KeInitializeSpinLock(&IopLogListLock); 504 505 /* Initialize Timer List Lock */ 506 KeInitializeSpinLock(&IopTimerLock); 507 508 /* Initialize Timer List */ 509 InitializeListHead(&IopTimerQueueHead); 510 511 /* Initialize the DPC/Timer which will call the other Timer Routines */ 512 ExpireTime.QuadPart = -10000000; 513 KeInitializeDpc(&IopTimerDpc, IopTimerDispatch, NULL); 514 KeInitializeTimerEx(&IopTimer, SynchronizationTimer); 515 KeSetTimerEx(&IopTimer, ExpireTime, 1000, &IopTimerDpc); 516 517 /* Create Object Types */ 518 if (!IopCreateObjectTypes()) 519 { 520 DPRINT1("IopCreateObjectTypes failed!\n"); 521 return FALSE; 522 } 523 524 /* Create Object Directories */ 525 if (!IopCreateRootDirectories()) 526 { 527 DPRINT1("IopCreateRootDirectories failed!\n"); 528 return FALSE; 529 } 530 531 /* Initialize PnP manager */ 532 IopInitializePlugPlayServices(); 533 534 /* Initialize SHIM engine */ 535 ApphelpCacheInitialize(); 536 537 /* Initialize WMI */ 538 WmiInitialize(); 539 540 /* Initialize HAL Root Bus Driver */ 541 HalInitPnpDriver(); 542 543 /* Make loader block available for the whole kernel */ 544 IopLoaderBlock = LoaderBlock; 545 546 /* Load boot start drivers */ 547 IopInitializeBootDrivers(); 548 549 /* Call back drivers that asked for */ 550 IopReinitializeBootDrivers(); 551 552 /* Check if this was a ramdisk boot */ 553 if (!_strnicmp(LoaderBlock->ArcBootDeviceName, "ramdisk(0)", 10)) 554 { 555 /* Initialize the ramdisk driver */ 556 IopStartRamdisk(LoaderBlock); 557 } 558 559 /* No one should need loader block any longer */ 560 IopLoaderBlock = NULL; 561 562 /* Create ARC names for boot devices */ 563 Status = IopCreateArcNames(LoaderBlock); 564 if (!NT_SUCCESS(Status)) 565 { 566 DPRINT1("IopCreateArcNames failed: %lx\n", Status); 567 return FALSE; 568 } 569 570 /* Mark the system boot partition */ 571 if (!IopMarkBootPartition(LoaderBlock)) 572 { 573 DPRINT1("IopMarkBootPartition failed!\n"); 574 return FALSE; 575 } 576 577 /* Initialize PnP root relations */ 578 IopEnumerateDevice(IopRootDeviceNode->PhysicalDeviceObject); 579 580 #ifndef _WINKD_ 581 /* Read KDB Data */ 582 KdbInit(); 583 584 /* I/O is now setup for disk access, so phase 3 */ 585 KdInitSystem(3, LoaderBlock); 586 #endif 587 588 /* Load services for devices found by PnP manager */ 589 IopInitializePnpServices(IopRootDeviceNode); 590 591 /* Load system start drivers */ 592 IopInitializeSystemDrivers(); 593 PnpSystemInit = TRUE; 594 595 /* Reinitialize drivers that requested it */ 596 IopReinitializeDrivers(); 597 598 /* Convert SystemRoot from ARC to NT path */ 599 Status = IopReassignSystemRoot(LoaderBlock, &NtBootPath); 600 if (!NT_SUCCESS(Status)) 601 { 602 DPRINT1("IopReassignSystemRoot failed: %lx\n", Status); 603 return FALSE; 604 } 605 606 /* Set the ANSI_STRING for the root path */ 607 RootString.MaximumLength = NtSystemRoot.MaximumLength / sizeof(WCHAR); 608 RootString.Length = 0; 609 RootString.Buffer = ExAllocatePoolWithTag(PagedPool, 610 RootString.MaximumLength, 611 TAG_IO); 612 613 /* Convert the path into the ANSI_STRING */ 614 Status = RtlUnicodeStringToAnsiString(&RootString, &NtSystemRoot, FALSE); 615 if (!NT_SUCCESS(Status)) 616 { 617 DPRINT1("RtlUnicodeStringToAnsiString failed: %lx\n", Status); 618 return FALSE; 619 } 620 621 /* Assign drive letters */ 622 IoAssignDriveLetters(LoaderBlock, 623 &NtBootPath, 624 (PUCHAR)RootString.Buffer, 625 &RootString); 626 627 /* Update system root */ 628 Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &RootString, FALSE); 629 if (!NT_SUCCESS(Status)) 630 { 631 DPRINT1("RtlAnsiStringToUnicodeString failed: %lx\n", Status); 632 return FALSE; 633 } 634 635 /* Load the System DLL and its Entrypoints */ 636 Status = PsLocateSystemDll(); 637 if (!NT_SUCCESS(Status)) 638 { 639 DPRINT1("PsLocateSystemDll failed: %lx\n", Status); 640 return FALSE; 641 } 642 643 /* Return success */ 644 return TRUE; 645 } 646 647 /* EOF */ 648