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