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 LIST_ENTRY IopDiskFileSystemQueueHead; 63 extern LIST_ENTRY IopCdRomFileSystemQueueHead; 64 extern LIST_ENTRY IopTapeFileSystemQueueHead; 65 extern LIST_ENTRY IopNetworkFileSystemQueueHead; 66 extern LIST_ENTRY DriverBootReinitListHead; 67 extern LIST_ENTRY DriverReinitListHead; 68 extern LIST_ENTRY IopFsNotifyChangeQueueHead; 69 extern LIST_ENTRY IopErrorLogListHead; 70 extern LIST_ENTRY IopTimerQueueHead; 71 extern KDPC IopTimerDpc; 72 extern KTIMER IopTimer; 73 extern KSPIN_LOCK IoStatisticsLock; 74 extern KSPIN_LOCK DriverReinitListLock; 75 extern KSPIN_LOCK DriverBootReinitListLock; 76 extern KSPIN_LOCK IopLogListLock; 77 extern KSPIN_LOCK IopTimerLock; 78 79 extern PDEVICE_OBJECT IopErrorLogObject; 80 extern BOOLEAN PnPBootDriversInitialized; 81 82 GENERAL_LOOKASIDE IoLargeIrpLookaside; 83 GENERAL_LOOKASIDE IoSmallIrpLookaside; 84 GENERAL_LOOKASIDE IopMdlLookasideList; 85 extern GENERAL_LOOKASIDE IoCompletionPacketLookaside; 86 87 PLOADER_PARAMETER_BLOCK IopLoaderBlock; 88 89 /* INIT FUNCTIONS ************************************************************/ 90 91 CODE_SEG("INIT") 92 VOID 93 NTAPI 94 IopInitLookasideLists(VOID) 95 { 96 ULONG LargeIrpSize, SmallIrpSize, MdlSize; 97 LONG i; 98 PKPRCB Prcb; 99 PGENERAL_LOOKASIDE CurrentList = NULL; 100 101 /* Calculate the sizes */ 102 LargeIrpSize = sizeof(IRP) + (8 * sizeof(IO_STACK_LOCATION)); 103 SmallIrpSize = sizeof(IRP) + sizeof(IO_STACK_LOCATION); 104 MdlSize = sizeof(MDL) + (23 * sizeof(PFN_NUMBER)); 105 106 /* Initialize the Lookaside List for I\O Completion */ 107 ExInitializeSystemLookasideList(&IoCompletionPacketLookaside, 108 NonPagedPool, 109 sizeof(IOP_MINI_COMPLETION_PACKET), 110 IOC_TAG1, 111 32, 112 &ExSystemLookasideListHead); 113 114 /* Initialize the Lookaside List for Large IRPs */ 115 ExInitializeSystemLookasideList(&IoLargeIrpLookaside, 116 NonPagedPool, 117 LargeIrpSize, 118 IO_LARGEIRP, 119 64, 120 &ExSystemLookasideListHead); 121 122 123 /* Initialize the Lookaside List for Small IRPs */ 124 ExInitializeSystemLookasideList(&IoSmallIrpLookaside, 125 NonPagedPool, 126 SmallIrpSize, 127 IO_SMALLIRP, 128 32, 129 &ExSystemLookasideListHead); 130 131 /* Initialize the Lookaside List for MDLs */ 132 ExInitializeSystemLookasideList(&IopMdlLookasideList, 133 NonPagedPool, 134 MdlSize, 135 TAG_MDL, 136 128, 137 &ExSystemLookasideListHead); 138 139 /* Allocate the global lookaside list buffer */ 140 CurrentList = ExAllocatePoolWithTag(NonPagedPool, 141 4 * KeNumberProcessors * 142 sizeof(GENERAL_LOOKASIDE), 143 TAG_IO); 144 145 /* Loop all processors */ 146 for (i = 0; i < KeNumberProcessors; i++) 147 { 148 /* Get the PRCB for this CPU */ 149 Prcb = KiProcessorBlock[i]; 150 DPRINT("Setting up lookaside for CPU: %x, PRCB: %p\n", i, Prcb); 151 152 /* Write IRP credit limit */ 153 Prcb->LookasideIrpFloat = 512 / KeNumberProcessors; 154 155 /* Set the I/O Completion List */ 156 Prcb->PPLookasideList[LookasideCompletionList].L = &IoCompletionPacketLookaside; 157 if (CurrentList) 158 { 159 /* Initialize the Lookaside List for mini-packets */ 160 ExInitializeSystemLookasideList(CurrentList, 161 NonPagedPool, 162 sizeof(IOP_MINI_COMPLETION_PACKET), 163 IO_SMALLIRP_CPU, 164 32, 165 &ExSystemLookasideListHead); 166 Prcb->PPLookasideList[LookasideCompletionList].P = CurrentList; 167 CurrentList++; 168 169 } 170 else 171 { 172 Prcb->PPLookasideList[LookasideCompletionList].P = &IoCompletionPacketLookaside; 173 } 174 175 /* Set the Large IRP List */ 176 Prcb->PPLookasideList[LookasideLargeIrpList].L = &IoLargeIrpLookaside; 177 if (CurrentList) 178 { 179 /* Initialize the Lookaside List for Large IRPs */ 180 ExInitializeSystemLookasideList(CurrentList, 181 NonPagedPool, 182 LargeIrpSize, 183 IO_LARGEIRP_CPU, 184 64, 185 &ExSystemLookasideListHead); 186 Prcb->PPLookasideList[LookasideLargeIrpList].P = CurrentList; 187 CurrentList++; 188 189 } 190 else 191 { 192 Prcb->PPLookasideList[LookasideLargeIrpList].P = &IoLargeIrpLookaside; 193 } 194 195 /* Set the Small IRP List */ 196 Prcb->PPLookasideList[LookasideSmallIrpList].L = &IoSmallIrpLookaside; 197 if (CurrentList) 198 { 199 /* Initialize the Lookaside List for Small IRPs */ 200 ExInitializeSystemLookasideList(CurrentList, 201 NonPagedPool, 202 SmallIrpSize, 203 IO_SMALLIRP_CPU, 204 32, 205 &ExSystemLookasideListHead); 206 Prcb->PPLookasideList[LookasideSmallIrpList].P = CurrentList; 207 CurrentList++; 208 209 } 210 else 211 { 212 Prcb->PPLookasideList[LookasideSmallIrpList].P = &IoSmallIrpLookaside; 213 } 214 215 /* Set the MDL Completion List */ 216 Prcb->PPLookasideList[LookasideMdlList].L = &IopMdlLookasideList; 217 if (CurrentList) 218 { 219 /* Initialize the Lookaside List for MDLs */ 220 ExInitializeSystemLookasideList(CurrentList, 221 NonPagedPool, 222 SmallIrpSize, 223 TAG_MDL, 224 128, 225 &ExSystemLookasideListHead); 226 227 Prcb->PPLookasideList[LookasideMdlList].P = CurrentList; 228 CurrentList++; 229 230 } 231 else 232 { 233 Prcb->PPLookasideList[LookasideMdlList].P = &IopMdlLookasideList; 234 } 235 } 236 } 237 238 CODE_SEG("INIT") 239 BOOLEAN 240 NTAPI 241 IopCreateObjectTypes(VOID) 242 { 243 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; 244 UNICODE_STRING Name; 245 246 /* Initialize default settings */ 247 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); 248 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); 249 ObjectTypeInitializer.PoolType = NonPagedPool; 250 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; 251 ObjectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS; 252 ObjectTypeInitializer.UseDefaultObject = TRUE; 253 ObjectTypeInitializer.GenericMapping = IopFileMapping; 254 255 /* Do the Adapter Type */ 256 RtlInitUnicodeString(&Name, L"Adapter"); 257 if (!NT_SUCCESS(ObCreateObjectType(&Name, 258 &ObjectTypeInitializer, 259 NULL, 260 &IoAdapterObjectType))) return FALSE; 261 262 /* Do the Controller Type */ 263 RtlInitUnicodeString(&Name, L"Controller"); 264 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(CONTROLLER_OBJECT); 265 if (!NT_SUCCESS(ObCreateObjectType(&Name, 266 &ObjectTypeInitializer, 267 NULL, 268 &IoControllerObjectType))) return FALSE; 269 270 /* Do the Device Type */ 271 RtlInitUnicodeString(&Name, L"Device"); 272 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DEVICE_OBJECT); 273 ObjectTypeInitializer.DeleteProcedure = IopDeleteDevice; 274 ObjectTypeInitializer.ParseProcedure = IopParseDevice; 275 ObjectTypeInitializer.SecurityProcedure = IopGetSetSecurityObject; 276 ObjectTypeInitializer.CaseInsensitive = TRUE; 277 if (!NT_SUCCESS(ObCreateObjectType(&Name, 278 &ObjectTypeInitializer, 279 NULL, 280 &IoDeviceObjectType))) return FALSE; 281 282 /* Initialize the Driver object type */ 283 RtlInitUnicodeString(&Name, L"Driver"); 284 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DRIVER_OBJECT); 285 ObjectTypeInitializer.DeleteProcedure = IopDeleteDriver; 286 ObjectTypeInitializer.ParseProcedure = NULL; 287 ObjectTypeInitializer.SecurityProcedure = NULL; 288 if (!NT_SUCCESS(ObCreateObjectType(&Name, 289 &ObjectTypeInitializer, 290 NULL, 291 &IoDriverObjectType))) return FALSE; 292 293 /* Initialize the I/O Completion object type */ 294 RtlInitUnicodeString(&Name, L"IoCompletion"); 295 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KQUEUE); 296 ObjectTypeInitializer.ValidAccessMask = IO_COMPLETION_ALL_ACCESS; 297 ObjectTypeInitializer.InvalidAttributes |= OBJ_PERMANENT; 298 ObjectTypeInitializer.GenericMapping = IopCompletionMapping; 299 ObjectTypeInitializer.DeleteProcedure = IopDeleteIoCompletion; 300 if (!NT_SUCCESS(ObCreateObjectType(&Name, 301 &ObjectTypeInitializer, 302 NULL, 303 &IoCompletionType))) return FALSE; 304 305 /* Initialize the File object type */ 306 RtlInitUnicodeString(&Name, L"File"); 307 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(FILE_OBJECT); 308 ObjectTypeInitializer.InvalidAttributes |= OBJ_EXCLUSIVE; 309 ObjectTypeInitializer.MaintainHandleCount = TRUE; 310 ObjectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS; 311 ObjectTypeInitializer.GenericMapping = IopFileMapping; 312 ObjectTypeInitializer.CloseProcedure = IopCloseFile; 313 ObjectTypeInitializer.DeleteProcedure = IopDeleteFile; 314 ObjectTypeInitializer.SecurityProcedure = IopGetSetSecurityObject; 315 ObjectTypeInitializer.QueryNameProcedure = IopQueryName; 316 ObjectTypeInitializer.ParseProcedure = IopParseFile; 317 ObjectTypeInitializer.UseDefaultObject = FALSE; 318 if (!NT_SUCCESS(ObCreateObjectType(&Name, 319 &ObjectTypeInitializer, 320 NULL, 321 &IoFileObjectType))) return FALSE; 322 323 /* Success */ 324 return TRUE; 325 } 326 327 CODE_SEG("INIT") 328 BOOLEAN 329 NTAPI 330 IopCreateRootDirectories(VOID) 331 { 332 OBJECT_ATTRIBUTES ObjectAttributes; 333 UNICODE_STRING DirName; 334 HANDLE Handle; 335 NTSTATUS Status; 336 337 /* Create the '\Driver' object directory */ 338 RtlInitUnicodeString(&DirName, L"\\Driver"); 339 InitializeObjectAttributes(&ObjectAttributes, 340 &DirName, 341 OBJ_PERMANENT, 342 NULL, 343 NULL); 344 Status = NtCreateDirectoryObject(&Handle, 345 DIRECTORY_ALL_ACCESS, 346 &ObjectAttributes); 347 if (!NT_SUCCESS(Status)) 348 { 349 DPRINT1("Failed to create \\Driver directory: 0x%lx\n", Status); 350 return FALSE; 351 } 352 NtClose(Handle); 353 354 /* Create the '\FileSystem' object directory */ 355 RtlInitUnicodeString(&DirName, L"\\FileSystem"); 356 InitializeObjectAttributes(&ObjectAttributes, 357 &DirName, 358 OBJ_PERMANENT, 359 NULL, 360 NULL); 361 Status = NtCreateDirectoryObject(&Handle, 362 DIRECTORY_ALL_ACCESS, 363 &ObjectAttributes); 364 if (!NT_SUCCESS(Status)) 365 { 366 DPRINT1("Failed to create \\FileSystem directory: 0x%lx\n", Status); 367 return FALSE; 368 } 369 NtClose(Handle); 370 371 /* Create the '\FileSystem' object directory */ 372 RtlInitUnicodeString(&DirName, L"\\FileSystem\\Filters"); 373 InitializeObjectAttributes(&ObjectAttributes, 374 &DirName, 375 OBJ_PERMANENT, 376 NULL, 377 NULL); 378 Status = NtCreateDirectoryObject(&Handle, 379 DIRECTORY_ALL_ACCESS, 380 &ObjectAttributes); 381 if (!NT_SUCCESS(Status)) 382 { 383 DPRINT1("Failed to create \\FileSystem\\Filters directory: 0x%lx\n", Status); 384 return FALSE; 385 } 386 NtClose(Handle); 387 388 /* Return success */ 389 return TRUE; 390 } 391 392 CODE_SEG("INIT") 393 BOOLEAN 394 NTAPI 395 IopMarkBootPartition(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 396 { 397 OBJECT_ATTRIBUTES ObjectAttributes; 398 STRING DeviceString; 399 CHAR Buffer[256]; 400 UNICODE_STRING DeviceName; 401 NTSTATUS Status; 402 HANDLE FileHandle; 403 IO_STATUS_BLOCK IoStatusBlock; 404 PFILE_OBJECT FileObject; 405 406 /* Build the ARC device name */ 407 sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName); 408 RtlInitAnsiString(&DeviceString, Buffer); 409 Status = RtlAnsiStringToUnicodeString(&DeviceName, &DeviceString, TRUE); 410 if (!NT_SUCCESS(Status)) return FALSE; 411 412 /* Open it */ 413 InitializeObjectAttributes(&ObjectAttributes, 414 &DeviceName, 415 OBJ_CASE_INSENSITIVE, 416 NULL, 417 NULL); 418 Status = ZwOpenFile(&FileHandle, 419 FILE_READ_ATTRIBUTES, 420 &ObjectAttributes, 421 &IoStatusBlock, 422 0, 423 FILE_NON_DIRECTORY_FILE); 424 if (!NT_SUCCESS(Status)) 425 { 426 /* Fail */ 427 KeBugCheckEx(INACCESSIBLE_BOOT_DEVICE, 428 (ULONG_PTR)&DeviceName, 429 Status, 430 0, 431 0); 432 } 433 434 /* Get the DO */ 435 Status = ObReferenceObjectByHandle(FileHandle, 436 0, 437 IoFileObjectType, 438 KernelMode, 439 (PVOID *)&FileObject, 440 NULL); 441 if (!NT_SUCCESS(Status)) 442 { 443 /* Fail */ 444 RtlFreeUnicodeString(&DeviceName); 445 return FALSE; 446 } 447 448 /* Mark it as the boot partition */ 449 FileObject->DeviceObject->Flags |= DO_SYSTEM_BOOT_PARTITION; 450 451 /* Save a copy of the DO for the I/O Error Logger */ 452 ObReferenceObject(FileObject->DeviceObject); 453 IopErrorLogObject = FileObject->DeviceObject; 454 455 /* Cleanup and return success */ 456 RtlFreeUnicodeString(&DeviceName); 457 NtClose(FileHandle); 458 ObDereferenceObject(FileObject); 459 return TRUE; 460 } 461 462 CODE_SEG("INIT") 463 BOOLEAN 464 NTAPI 465 IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 466 { 467 LARGE_INTEGER ExpireTime; 468 NTSTATUS Status; 469 CHAR Buffer[256]; 470 ANSI_STRING NtBootPath, RootString; 471 472 /* Initialize empty NT Boot Path */ 473 RtlInitEmptyAnsiString(&NtBootPath, Buffer, sizeof(Buffer)); 474 475 /* Initialize the lookaside lists */ 476 IopInitLookasideLists(); 477 478 /* Initialize all locks and lists */ 479 ExInitializeResourceLite(&IopDatabaseResource); 480 ExInitializeResourceLite(&IopSecurityResource); 481 ExInitializeResourceLite(&IopDriverLoadResource); 482 InitializeListHead(&IopDiskFileSystemQueueHead); 483 InitializeListHead(&IopCdRomFileSystemQueueHead); 484 InitializeListHead(&IopTapeFileSystemQueueHead); 485 InitializeListHead(&IopNetworkFileSystemQueueHead); 486 InitializeListHead(&DriverBootReinitListHead); 487 InitializeListHead(&DriverReinitListHead); 488 InitializeListHead(&ShutdownListHead); 489 InitializeListHead(&LastChanceShutdownListHead); 490 InitializeListHead(&IopFsNotifyChangeQueueHead); 491 InitializeListHead(&IopErrorLogListHead); 492 KeInitializeSpinLock(&IoStatisticsLock); 493 KeInitializeSpinLock(&DriverReinitListLock); 494 KeInitializeSpinLock(&DriverBootReinitListLock); 495 KeInitializeSpinLock(&ShutdownListLock); 496 KeInitializeSpinLock(&IopLogListLock); 497 498 /* Initialize PnP notifications */ 499 PiInitializeNotifications(); 500 501 /* Initialize the reserve IRP */ 502 if (!IopInitializeReserveIrp(&IopReserveIrpAllocator)) 503 { 504 DPRINT1("IopInitializeReserveIrp failed!\n"); 505 return FALSE; 506 } 507 508 /* Initialize Timer List Lock */ 509 KeInitializeSpinLock(&IopTimerLock); 510 511 /* Initialize Timer List */ 512 InitializeListHead(&IopTimerQueueHead); 513 514 /* Initialize the DPC/Timer which will call the other Timer Routines */ 515 ExpireTime.QuadPart = -10000000; 516 KeInitializeDpc(&IopTimerDpc, IopTimerDispatch, NULL); 517 KeInitializeTimerEx(&IopTimer, SynchronizationTimer); 518 KeSetTimerEx(&IopTimer, ExpireTime, 1000, &IopTimerDpc); 519 520 /* Create Object Types */ 521 if (!IopCreateObjectTypes()) 522 { 523 DPRINT1("IopCreateObjectTypes failed!\n"); 524 return FALSE; 525 } 526 527 /* Create Object Directories */ 528 if (!IopCreateRootDirectories()) 529 { 530 DPRINT1("IopCreateRootDirectories failed!\n"); 531 return FALSE; 532 } 533 534 /* Initialize PnP manager */ 535 IopInitializePlugPlayServices(); 536 537 /* Initialize SHIM engine */ 538 ApphelpCacheInitialize(); 539 540 /* Initialize WMI */ 541 WmiInitialize(); 542 543 /* Initialize HAL Root Bus Driver */ 544 HalInitPnpDriver(); 545 546 /* Reenumerate what HAL has added (synchronously) 547 * This function call should eventually become a 2nd stage of the PnP initialization */ 548 PiQueueDeviceAction(IopRootDeviceNode->PhysicalDeviceObject, 549 PiActionEnumRootDevices, 550 NULL, 551 NULL); 552 553 /* Make loader block available for the whole kernel */ 554 IopLoaderBlock = LoaderBlock; 555 556 /* Load boot start drivers */ 557 IopInitializeBootDrivers(); 558 559 /* Call back drivers that asked for */ 560 IopReinitializeBootDrivers(); 561 562 /* Check if this was a ramdisk boot */ 563 if (!_strnicmp(LoaderBlock->ArcBootDeviceName, "ramdisk(0)", 10)) 564 { 565 /* Initialize the ramdisk driver */ 566 IopStartRamdisk(LoaderBlock); 567 } 568 569 /* No one should need loader block any longer */ 570 IopLoaderBlock = NULL; 571 572 /* Create ARC names for boot devices */ 573 Status = IopCreateArcNames(LoaderBlock); 574 if (!NT_SUCCESS(Status)) 575 { 576 DPRINT1("IopCreateArcNames failed: %lx\n", Status); 577 return FALSE; 578 } 579 580 /* Mark the system boot partition */ 581 if (!IopMarkBootPartition(LoaderBlock)) 582 { 583 DPRINT1("IopMarkBootPartition failed!\n"); 584 return FALSE; 585 } 586 587 /* The disk subsystem is initialized here and the SystemRoot is set too. 588 * We can finally load other drivers from the boot volume. */ 589 PnPBootDriversInitialized = TRUE; 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 BOOLEAN 648 NTAPI 649 IoInitializeCrashDump(IN HANDLE PageFileHandle) 650 { 651 UNIMPLEMENTED; 652 return FALSE; 653 } 654 655 /* EOF */ 656