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
IopInitLookasideLists(VOID)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
IopCreateObjectTypes(VOID)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
IopCreateRootDirectories(VOID)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
IopMarkBootPartition(IN PLOADER_PARAMETER_BLOCK LoaderBlock)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
IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)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
IoInitializeCrashDump(IN HANDLE PageFileHandle)650 IoInitializeCrashDump(IN HANDLE PageFileHandle)
651 {
652 UNIMPLEMENTED;
653 return FALSE;
654 }
655
656 /* EOF */
657