- Fix KiDispatchException to unmask KI_EXCEPTION_INTERNAL when setting the exception...
[reactos.git] / reactos / ntoskrnl / ex / init.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ex/init.c
5 * PURPOSE: Executive Initialization Code
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 * Eric Kohl (ekohl@rz-online.de)
8 */
9
10 /* INCLUDES ******************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 //#include <ntoskrnl/cm/newcm.h>
16 #include "ntoskrnl/cm/cm.h"
17 #include <ntverp.h>
18
19 /* DATA **********************************************************************/
20
21 /* NT Version Info */
22 ULONG NtMajorVersion = VER_PRODUCTMAJORVERSION;
23 ULONG NtMinorVersion = VER_PRODUCTMINORVERSION;
24 #if DBG
25 ULONG NtBuildNumber = VER_PRODUCTBUILD | 0xC0000000;
26 #else
27 ULONG NtBuildNumber = VER_PRODUCTBUILD;
28 #endif
29
30 /* NT System Info */
31 ULONG NtGlobalFlag;
32 ULONG ExSuiteMask;
33
34 /* Cm Version Info */
35 ULONG CmNtSpBuildNumber;
36 ULONG CmNtCSDVersion;
37 ULONG CmNtCSDReleaseType;
38 UNICODE_STRING CmVersionString;
39 UNICODE_STRING CmCSDVersionString;
40 CHAR NtBuildLab[] = KERNEL_VERSION_BUILD_STR;
41
42 /* Init flags and settings */
43 ULONG ExpInitializationPhase;
44 BOOLEAN ExpInTextModeSetup;
45 BOOLEAN IoRemoteBootClient;
46 ULONG InitSafeBootMode;
47 BOOLEAN InitIsWinPEMode, InitWinPEModeType;
48
49 /* NT Boot Path */
50 UNICODE_STRING NtSystemRoot;
51
52 /* NT Initial User Application */
53 WCHAR NtInitialUserProcessBuffer[128] = L"\\SystemRoot\\System32\\smss.exe";
54 ULONG NtInitialUserProcessBufferLength = sizeof(NtInitialUserProcessBuffer) -
55 sizeof(WCHAR);
56 ULONG NtInitialUserProcessBufferType = REG_SZ;
57
58 /* Boot NLS information */
59 PVOID ExpNlsTableBase;
60 ULONG ExpAnsiCodePageDataOffset, ExpOemCodePageDataOffset;
61 ULONG ExpUnicodeCaseTableDataOffset;
62 NLSTABLEINFO ExpNlsTableInfo;
63 ULONG ExpNlsTableSize;
64 PVOID ExpNlsSectionPointer;
65
66 /* CMOS Timer Sanity */
67 BOOLEAN ExCmosClockIsSane = TRUE;
68
69 /* FUNCTIONS ****************************************************************/
70
71 NTSTATUS
72 NTAPI
73 ExpCreateSystemRootLink(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
74 {
75 UNICODE_STRING LinkName;
76 OBJECT_ATTRIBUTES ObjectAttributes;
77 HANDLE LinkHandle;
78 NTSTATUS Status;
79 ANSI_STRING AnsiName;
80 CHAR Buffer[256];
81 ANSI_STRING TargetString;
82 UNICODE_STRING TargetName;
83
84 /* Initialize the ArcName tree */
85 RtlInitUnicodeString(&LinkName, L"\\ArcName");
86 InitializeObjectAttributes(&ObjectAttributes,
87 &LinkName,
88 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
89 NULL,
90 SePublicDefaultUnrestrictedSd);
91
92 /* Create it */
93 Status = NtCreateDirectoryObject(&LinkHandle,
94 DIRECTORY_ALL_ACCESS,
95 &ObjectAttributes);
96 if (!NT_SUCCESS(Status))
97 {
98 /* Failed */
99 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 1, 0, 0);
100 }
101
102 /* Close the LinkHandle */
103 NtClose(LinkHandle);
104
105 /* Initialize the Device tree */
106 RtlInitUnicodeString(&LinkName, L"\\Device");
107 InitializeObjectAttributes(&ObjectAttributes,
108 &LinkName,
109 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
110 NULL,
111 SePublicDefaultUnrestrictedSd);
112
113 /* Create it */
114 Status = NtCreateDirectoryObject(&LinkHandle,
115 DIRECTORY_ALL_ACCESS,
116 &ObjectAttributes);
117 if (!NT_SUCCESS(Status))
118 {
119 /* Failed */
120 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 2, 0, 0);
121 }
122
123 /* Close the LinkHandle */
124 ObCloseHandle(LinkHandle, KernelMode);
125
126 /* Create the system root symlink name */
127 RtlInitAnsiString(&AnsiName, "\\SystemRoot");
128 Status = RtlAnsiStringToUnicodeString(&LinkName, &AnsiName, TRUE);
129 if (!NT_SUCCESS(Status))
130 {
131 /* Failed */
132 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 3, 0, 0);
133 }
134
135 /* Initialize the attributes for the link */
136 InitializeObjectAttributes(&ObjectAttributes,
137 &LinkName,
138 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
139 NULL,
140 SePublicDefaultUnrestrictedSd);
141
142 /* Build the ARC name */
143 sprintf(Buffer,
144 "\\ArcName\\%s%s",
145 LoaderBlock->ArcBootDeviceName,
146 LoaderBlock->NtBootPathName);
147 Buffer[strlen(Buffer) - 1] = ANSI_NULL;
148
149 /* Convert it to Unicode */
150 RtlInitString(&TargetString, Buffer);
151 Status = RtlAnsiStringToUnicodeString(&TargetName,
152 &TargetString,
153 TRUE);
154 if (!NT_SUCCESS(Status))
155 {
156 /* We failed, bugcheck */
157 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 4, 0, 0);
158 }
159
160 /* Create it */
161 Status = NtCreateSymbolicLinkObject(&LinkHandle,
162 SYMBOLIC_LINK_ALL_ACCESS,
163 &ObjectAttributes,
164 &TargetName);
165
166 /* Free the strings */
167 RtlFreeUnicodeString(&LinkName);
168 RtlFreeUnicodeString(&TargetName);
169
170 /* Check if creating the link failed */
171 if (!NT_SUCCESS(Status))
172 {
173 /* Failed */
174 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 5, 0, 0);
175 }
176
177 /* Close the handle and return success */
178 ObCloseHandle(LinkHandle, KernelMode);
179 return STATUS_SUCCESS;
180 }
181
182 VOID
183 NTAPI
184 ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
185 {
186 LARGE_INTEGER SectionSize;
187 NTSTATUS Status;
188 HANDLE NlsSection;
189 PVOID SectionBase = NULL;
190 ULONG ViewSize = 0;
191 LARGE_INTEGER SectionOffset = {{0}};
192 PLIST_ENTRY ListHead, NextEntry;
193 PMEMORY_ALLOCATION_DESCRIPTOR MdBlock;
194
195 /* Check if this is boot-time phase 0 initialization */
196 if (!ExpInitializationPhase)
197 {
198 /* Loop the memory descriptors */
199 ListHead = &LoaderBlock->MemoryDescriptorListHead;
200 NextEntry = ListHead->Flink;
201 while (NextEntry != ListHead)
202 {
203 /* Get the current block */
204 MdBlock = CONTAINING_RECORD(NextEntry,
205 MEMORY_ALLOCATION_DESCRIPTOR,
206 ListEntry);
207
208 /* Check if this is an NLS block */
209 if (MdBlock->MemoryType == LoaderNlsData)
210 {
211 /* Increase the table size */
212 ExpNlsTableSize += MdBlock->PageCount * PAGE_SIZE;
213 }
214
215 /* Go to the next block */
216 NextEntry = MdBlock->ListEntry.Flink;
217 }
218
219 /*
220 * In NT, the memory blocks are contiguous, but in ReactOS they aren't,
221 * so unless someone fixes FreeLdr, we'll have to use this icky hack.
222 */
223 ExpNlsTableSize += 2 * PAGE_SIZE; // BIAS FOR FREELDR. HACK!
224
225 /* Allocate the a new buffer since loader memory will be freed */
226 ExpNlsTableBase = ExAllocatePoolWithTag(NonPagedPool,
227 ExpNlsTableSize,
228 TAG('R', 't', 'l', 'i'));
229 if (!ExpNlsTableBase) KeBugCheck(PHASE0_INITIALIZATION_FAILED);
230
231 /* Copy the codepage data in its new location. */
232 RtlCopyMemory(ExpNlsTableBase,
233 LoaderBlock->NlsData->AnsiCodePageData,
234 ExpNlsTableSize);
235
236 /* Initialize and reset the NLS TAbles */
237 RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase +
238 ExpAnsiCodePageDataOffset),
239 (PVOID)((ULONG_PTR)ExpNlsTableBase +
240 ExpOemCodePageDataOffset),
241 (PVOID)((ULONG_PTR)ExpNlsTableBase +
242 ExpUnicodeCaseTableDataOffset),
243 &ExpNlsTableInfo);
244 RtlResetRtlTranslations(&ExpNlsTableInfo);
245 return;
246 }
247
248 /* Set the section size */
249 SectionSize.QuadPart = ExpNlsTableSize;
250
251 /* Create the NLS Section */
252 Status = ZwCreateSection(&NlsSection,
253 SECTION_ALL_ACCESS,
254 NULL,
255 &SectionSize,
256 PAGE_READWRITE,
257 SEC_COMMIT,
258 NULL);
259 if (!NT_SUCCESS(Status))
260 {
261 /* Failed */
262 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 1, 0, 0);
263 }
264
265 /* Get a pointer to the section */
266 Status = ObReferenceObjectByHandle(NlsSection,
267 SECTION_ALL_ACCESS,
268 MmSectionObjectType,
269 KernelMode,
270 &ExpNlsSectionPointer,
271 NULL);
272 ZwClose(NlsSection);
273 if (!NT_SUCCESS(Status))
274 {
275 /* Failed */
276 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 2, 0, 0);
277 }
278
279 /* Map the NLS Section in system space */
280 Status = MmMapViewInSystemSpace(ExpNlsSectionPointer,
281 &SectionBase,
282 &ExpNlsTableSize);
283 if (!NT_SUCCESS(Status))
284 {
285 /* Failed */
286 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 3, 0, 0);
287 }
288
289 /* Copy the codepage data in its new location. */
290 RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize);
291
292 /* Free the previously allocated buffer and set the new location */
293 ExFreePool(ExpNlsTableBase);
294 ExpNlsTableBase = SectionBase;
295
296 /* Initialize the NLS Tables */
297 RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase +
298 ExpAnsiCodePageDataOffset),
299 (PVOID)((ULONG_PTR)ExpNlsTableBase +
300 ExpOemCodePageDataOffset),
301 (PVOID)((ULONG_PTR)ExpNlsTableBase +
302 ExpUnicodeCaseTableDataOffset),
303 &ExpNlsTableInfo);
304 RtlResetRtlTranslations(&ExpNlsTableInfo);
305
306 /* Reset the base to 0 */
307 SectionBase = NULL;
308
309 /* Map the section in the system process */
310 Status = MmMapViewOfSection(ExpNlsSectionPointer,
311 PsGetCurrentProcess(),
312 &SectionBase,
313 0L,
314 0L,
315 &SectionOffset,
316 &ViewSize,
317 ViewShare,
318 0L,
319 PAGE_READWRITE);
320 if (!NT_SUCCESS(Status))
321 {
322 /* Failed */
323 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 5, 0, 0);
324 }
325
326 /* Copy the table into the system process and set this as the base */
327 RtlCopyMemory(SectionBase, ExpNlsTableBase, ExpNlsTableSize);
328 ExpNlsTableBase = SectionBase;
329 }
330
331 NTSTATUS
332 NTAPI
333 ExpLoadInitialProcess(IN OUT PRTL_USER_PROCESS_INFORMATION ProcessInformation)
334 {
335 PRTL_USER_PROCESS_PARAMETERS ProcessParameters = NULL;
336 NTSTATUS Status;
337 ULONG Size;
338 PWSTR p;
339 UNICODE_STRING NullString = RTL_CONSTANT_STRING(L"");
340 UNICODE_STRING SmssName, Environment, SystemDriveString;
341 PVOID EnvironmentPtr = NULL;
342
343 /* Allocate memory for the process parameters */
344 Size = sizeof(RTL_USER_PROCESS_PARAMETERS) +
345 ((MAX_PATH * 6) * sizeof(WCHAR));
346 Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
347 (PVOID)&ProcessParameters,
348 0,
349 &Size,
350 MEM_COMMIT,
351 PAGE_READWRITE);
352 if (!NT_SUCCESS(Status))
353 {
354 /* Failed */
355 KeBugCheckEx(SESSION1_INITIALIZATION_FAILED, Status, 0, 0, 0);
356 }
357
358 /* Setup the basic header, and give the process the low 1MB to itself */
359 ProcessParameters->Length = Size;
360 ProcessParameters->MaximumLength = Size;
361 ProcessParameters->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED |
362 RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB;
363
364 /* Allocate a page for the environment */
365 Size = PAGE_SIZE;
366 Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
367 &EnvironmentPtr,
368 0,
369 &Size,
370 MEM_COMMIT,
371 PAGE_READWRITE);
372 if (!NT_SUCCESS(Status))
373 {
374 /* Failed */
375 KeBugCheckEx(SESSION2_INITIALIZATION_FAILED, Status, 0, 0, 0);
376 }
377
378 /* Write the pointer */
379 ProcessParameters->Environment = EnvironmentPtr;
380
381 /* Make a buffer for the DOS path */
382 p = (PWSTR)(ProcessParameters + 1);
383 ProcessParameters->CurrentDirectory.DosPath.Buffer = p;
384 ProcessParameters->
385 CurrentDirectory.DosPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
386
387 /* Copy the DOS path */
388 RtlCopyUnicodeString(&ProcessParameters->CurrentDirectory.DosPath,
389 &NtSystemRoot);
390
391 /* Make a buffer for the DLL Path */
392 p = (PWSTR)((PCHAR)ProcessParameters->CurrentDirectory.DosPath.Buffer +
393 ProcessParameters->CurrentDirectory.DosPath.MaximumLength);
394 ProcessParameters->DllPath.Buffer = p;
395 ProcessParameters->DllPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
396
397 /* Copy the DLL path and append the system32 directory */
398 RtlCopyUnicodeString(&ProcessParameters->DllPath,
399 &ProcessParameters->CurrentDirectory.DosPath);
400 RtlAppendUnicodeToString(&ProcessParameters->DllPath, L"\\System32");
401
402 /* Make a buffer for the image name */
403 p = (PWSTR)((PCHAR)ProcessParameters->DllPath.Buffer +
404 ProcessParameters->DllPath.MaximumLength);
405 ProcessParameters->ImagePathName.Buffer = p;
406 ProcessParameters->ImagePathName.MaximumLength = MAX_PATH * sizeof(WCHAR);
407
408 /* Make sure the buffer is a valid string which within the given length */
409 if ((NtInitialUserProcessBufferType != REG_SZ) ||
410 ((NtInitialUserProcessBufferLength != -1) &&
411 ((NtInitialUserProcessBufferLength < sizeof(WCHAR)) ||
412 (NtInitialUserProcessBufferLength >
413 sizeof(NtInitialUserProcessBuffer) - sizeof(WCHAR)))))
414 {
415 /* Invalid initial process string, bugcheck */
416 KeBugCheckEx(SESSION2_INITIALIZATION_FAILED,
417 (ULONG_PTR)STATUS_INVALID_PARAMETER,
418 NtInitialUserProcessBufferType,
419 NtInitialUserProcessBufferLength,
420 sizeof(NtInitialUserProcessBuffer));
421 }
422
423 /* Cut out anything after a space */
424 p = NtInitialUserProcessBuffer;
425 while (*p && *p != L' ') p++;
426
427 /* Set the image path length */
428 ProcessParameters->ImagePathName.Length =
429 (USHORT)((PCHAR)p - (PCHAR)NtInitialUserProcessBuffer);
430
431 /* Copy the actual buffer */
432 RtlCopyMemory(ProcessParameters->ImagePathName.Buffer,
433 NtInitialUserProcessBuffer,
434 ProcessParameters->ImagePathName.Length);
435
436 /* Null-terminate it */
437 ProcessParameters->
438 ImagePathName.Buffer[ProcessParameters->ImagePathName.Length /
439 sizeof(WCHAR)] = UNICODE_NULL;
440
441 /* Make a buffer for the command line */
442 p = (PWSTR)((PCHAR)ProcessParameters->ImagePathName.Buffer +
443 ProcessParameters->ImagePathName.MaximumLength);
444 ProcessParameters->CommandLine.Buffer = p;
445 ProcessParameters->CommandLine.MaximumLength = MAX_PATH * sizeof(WCHAR);
446
447 /* Add the image name to the command line */
448 RtlAppendUnicodeToString(&ProcessParameters->CommandLine,
449 NtInitialUserProcessBuffer);
450
451 /* Create the environment string */
452 RtlInitEmptyUnicodeString(&Environment,
453 ProcessParameters->Environment,
454 (USHORT)Size);
455
456 /* Append the DLL path to it */
457 RtlAppendUnicodeToString(&Environment, L"Path=" );
458 RtlAppendUnicodeStringToString(&Environment, &ProcessParameters->DllPath);
459 RtlAppendUnicodeStringToString(&Environment, &NullString );
460
461 /* Create the system drive string */
462 SystemDriveString = NtSystemRoot;
463 SystemDriveString.Length = 2 * sizeof(WCHAR);
464
465 /* Append it to the environment */
466 RtlAppendUnicodeToString(&Environment, L"SystemDrive=");
467 RtlAppendUnicodeStringToString(&Environment, &SystemDriveString);
468 RtlAppendUnicodeStringToString(&Environment, &NullString);
469
470 /* Append the system root to the environment */
471 RtlAppendUnicodeToString(&Environment, L"SystemRoot=");
472 RtlAppendUnicodeStringToString(&Environment, &NtSystemRoot);
473 RtlAppendUnicodeStringToString(&Environment, &NullString);
474
475 /* Create SMSS process */
476 SmssName = ProcessParameters->ImagePathName;
477 Status = RtlCreateUserProcess(&SmssName,
478 OBJ_CASE_INSENSITIVE,
479 RtlDeNormalizeProcessParams(
480 ProcessParameters),
481 NULL,
482 NULL,
483 NULL,
484 FALSE,
485 NULL,
486 NULL,
487 ProcessInformation);
488 if (!NT_SUCCESS(Status))
489 {
490 /* Failed */
491 KeBugCheckEx(SESSION3_INITIALIZATION_FAILED, Status, 0, 0, 0);
492 }
493
494 /* Resume the thread */
495 Status = ZwResumeThread(ProcessInformation->ThreadHandle, NULL);
496 if (!NT_SUCCESS(Status))
497 {
498 /* Failed */
499 KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
500 }
501
502 /* Return success */
503 return STATUS_SUCCESS;
504 }
505
506 ULONG
507 NTAPI
508 ExComputeTickCountMultiplier(IN ULONG ClockIncrement)
509 {
510 ULONG MsRemainder = 0, MsIncrement;
511 ULONG IncrementRemainder;
512 ULONG i;
513
514 /* Count the number of milliseconds for each clock interrupt */
515 MsIncrement = ClockIncrement / (10 * 1000);
516
517 /* Count the remainder from the division above, with 24-bit precision */
518 IncrementRemainder = ClockIncrement - (MsIncrement * (10 * 1000));
519 for (i= 0; i < 24; i++)
520 {
521 /* Shift the remainders */
522 MsRemainder <<= 1;
523 IncrementRemainder <<= 1;
524
525 /* Check if we've went past 1 ms */
526 if (IncrementRemainder >= (10 * 1000))
527 {
528 /* Increase the remainder by one, and substract from increment */
529 IncrementRemainder -= (10 * 1000);
530 MsRemainder |= 1;
531 }
532 }
533
534 /* Return the increment */
535 return (MsIncrement << 24) | MsRemainder;
536 }
537
538 BOOLEAN
539 NTAPI
540 ExpInitSystemPhase0(VOID)
541 {
542 /* Initialize EXRESOURCE Support */
543 ExpResourceInitialization();
544
545 /* Initialize the environment lock */
546 ExInitializeFastMutex(&ExpEnvironmentLock);
547
548 /* Initialize the lookaside lists and locks */
549 ExpInitLookasideLists();
550
551 /* Initialize the Firmware Table resource and listhead */
552 InitializeListHead(&ExpFirmwareTableProviderListHead);
553 ExInitializeResourceLite(&ExpFirmwareTableResource);
554
555 /* Set the suite mask to maximum and return */
556 ExSuiteMask = 0xFFFFFFFF;
557 return TRUE;
558 }
559
560 BOOLEAN
561 NTAPI
562 ExpInitSystemPhase1(VOID)
563 {
564 /* Initialize worker threads */
565 ExpInitializeWorkerThreads();
566
567 /* Initialize pushlocks */
568 ExpInitializePushLocks();
569
570 /* Initialize events and event pairs */
571 ExpInitializeEventImplementation();
572 ExpInitializeEventPairImplementation();
573
574 /* Initialize callbacks */
575 ExpInitializeCallbacks();
576
577 /* Initialize mutants */
578 ExpInitializeMutantImplementation();
579
580 /* Initialize semaphores */
581 ExpInitializeSemaphoreImplementation();
582
583 /* Initialize timers */
584 ExpInitializeTimerImplementation();
585
586 /* Initialize profiling */
587 ExpInitializeProfileImplementation();
588
589 /* Initialize UUIDs */
590 ExpInitUuids();
591
592 /* Initialize Win32K */
593 ExpWin32kInit();
594 return TRUE;
595 }
596
597 BOOLEAN
598 NTAPI
599 ExInitSystem(VOID)
600 {
601 /* Check the initialization phase */
602 switch (ExpInitializationPhase)
603 {
604 case 0:
605
606 /* Do Phase 0 */
607 return ExpInitSystemPhase0();
608
609 case 1:
610
611 /* Do Phase 1 */
612 return ExpInitSystemPhase1();
613
614 default:
615
616 /* Don't know any other phase! Bugcheck! */
617 KeBugCheck(UNEXPECTED_INITIALIZATION_CALL);
618 return FALSE;
619 }
620 }
621
622 BOOLEAN
623 NTAPI
624 ExpIsLoaderValid(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
625 {
626 PLOADER_PARAMETER_EXTENSION Extension;
627
628 /* Get the loader extension */
629 Extension = LoaderBlock->Extension;
630
631 /* Validate the size (larger structures are OK, we'll just ignore them) */
632 if (Extension->Size < sizeof(LOADER_PARAMETER_EXTENSION)) return FALSE;
633
634 /* Don't validate upper versions */
635 if (Extension->MajorVersion > 5) return TRUE;
636
637 /* Fail if this is NT 4 */
638 if (Extension->MajorVersion < 5) return FALSE;
639
640 /* Fail if this is XP */
641 if (Extension->MinorVersion < 2) return FALSE;
642
643 /* This is 2003 or newer, approve it */
644 return TRUE;
645 }
646
647 VOID
648 NTAPI
649 ExpLoadBootSymbols(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
650 {
651 ULONG i = 0;
652 PLIST_ENTRY NextEntry;
653 ULONG Count, Length;
654 PWCHAR Name;
655 PLDR_DATA_TABLE_ENTRY LdrEntry;
656 BOOLEAN OverFlow = FALSE;
657 CHAR NameBuffer[256];
658 ANSI_STRING SymbolString;
659
660 /* Loop the driver list */
661 NextEntry = LoaderBlock->LoadOrderListHead.Flink;
662 while (NextEntry != &LoaderBlock->LoadOrderListHead)
663 {
664 /* Skip the first two images */
665 if (i >= 2)
666 {
667 /* Get the entry */
668 LdrEntry = CONTAINING_RECORD(NextEntry,
669 LDR_DATA_TABLE_ENTRY,
670 InLoadOrderLinks);
671 if (LdrEntry->FullDllName.Buffer[0] == L'\\')
672 {
673 /* We have a name, read its data */
674 Name = LdrEntry->FullDllName.Buffer;
675 Length = LdrEntry->FullDllName.Length / sizeof(WCHAR);
676
677 /* Check if our buffer can hold it */
678 if (sizeof(NameBuffer) < Length + sizeof(ANSI_NULL))
679 {
680 /* It's too long */
681 OverFlow = TRUE;
682 }
683 else
684 {
685 /* Copy the name */
686 Count = 0;
687 do
688 {
689 /* Copy the character */
690 NameBuffer[Count++] = (CHAR)*Name++;
691 } while (Count < Length);
692
693 /* Null-terminate */
694 NameBuffer[Count] = ANSI_NULL;
695 }
696 }
697 else
698 {
699 /* This should be a driver, check if it fits */
700 if (sizeof(NameBuffer) <
701 (sizeof("\\System32\\Drivers\\") +
702 NtSystemRoot.Length / sizeof(WCHAR) - sizeof(UNICODE_NULL) +
703 LdrEntry->BaseDllName.Length / sizeof(WCHAR) +
704 sizeof(ANSI_NULL)))
705 {
706 /* Buffer too small */
707 OverFlow = TRUE;
708 while (TRUE);
709 }
710 else
711 {
712 /* Otherwise build the name. HACKED for GCC :( */
713 sprintf(NameBuffer,
714 "%S\\System32\\Drivers\\%S",
715 &SharedUserData->NtSystemRoot[2],
716 LdrEntry->BaseDllName.Buffer);
717 }
718 }
719
720 /* Check if the buffer was ok */
721 if (!OverFlow)
722 {
723 /* Initialize the ANSI_STRING for the debugger */
724 RtlInitString(&SymbolString, NameBuffer);
725
726 /* Load the symbols */
727 DbgLoadImageSymbols(&SymbolString,
728 LdrEntry->DllBase,
729 0xFFFFFFFF);
730 }
731 }
732
733 /* Go to the next entry */
734 i++;
735 NextEntry = NextEntry->Flink;
736 }
737
738 /* Check if we should break after symbol load */
739 if (KdBreakAfterSymbolLoad) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
740 }
741
742 VOID
743 NTAPI
744 ExpInitializeExecutive(IN ULONG Cpu,
745 IN PLOADER_PARAMETER_BLOCK LoaderBlock)
746 {
747 PNLS_DATA_BLOCK NlsData;
748 CHAR Buffer[256];
749 ANSI_STRING AnsiPath;
750 NTSTATUS Status;
751 PCHAR CommandLine, PerfMem;
752 ULONG PerfMemUsed;
753
754 /* Validate Loader */
755 if (!ExpIsLoaderValid(LoaderBlock))
756 {
757 /* Invalid loader version */
758 KeBugCheckEx(MISMATCHED_HAL,
759 3,
760 LoaderBlock->Extension->Size,
761 LoaderBlock->Extension->MajorVersion,
762 LoaderBlock->Extension->MinorVersion);
763 }
764
765 /* Initialize PRCB pool lookaside pointers */
766 ExInitPoolLookasidePointers();
767
768 /* Check if this is an application CPU */
769 if (Cpu)
770 {
771 /* Then simply initialize it with HAL */
772 if (!HalInitSystem(ExpInitializationPhase, LoaderBlock))
773 {
774 /* Initialization failed */
775 KeBugCheck(HAL_INITIALIZATION_FAILED);
776 }
777
778 /* We're done */
779 return;
780 }
781
782 /* Assume no text-mode or remote boot */
783 ExpInTextModeSetup = FALSE;
784 IoRemoteBootClient = FALSE;
785
786 /* Check if we have a setup loader block */
787 if (LoaderBlock->SetupLdrBlock)
788 {
789 /* Check if this is text-mode setup */
790 if (LoaderBlock->SetupLdrBlock->Flags & 1) ExpInTextModeSetup = TRUE;
791
792 /* Check if this is network boot */
793 if (LoaderBlock->SetupLdrBlock->Flags & 2)
794 {
795 /* Set variable */
796 IoRemoteBootClient = TRUE;
797
798 /* Make sure we're actually booting off the network */
799 ASSERT(!_memicmp(LoaderBlock->ArcBootDeviceName, "net(0)", 6));
800 }
801 }
802
803 /* Set phase to 0 */
804 ExpInitializationPhase = 0;
805
806 /* Get boot command line */
807 CommandLine = LoaderBlock->LoadOptions;
808 if (CommandLine)
809 {
810 /* Upcase it for comparison and check if we're in performance mode */
811 _strupr(CommandLine);
812 PerfMem = strstr(CommandLine, "PERFMEM");
813 if (PerfMem)
814 {
815 /* Check if the user gave a number of bytes to use */
816 PerfMem = strstr(PerfMem, "=");
817 if (PerfMem)
818 {
819 /* Read the number of pages we'll use */
820 PerfMemUsed = atol(PerfMem + 1) * (1024 * 1024 / PAGE_SIZE);
821 if (PerfMem)
822 {
823 /* FIXME: TODO */
824 DPRINT1("BBT performance mode not yet supported."
825 "/PERFMEM option ignored.\n");
826 }
827 }
828 }
829
830 /* Check if we're burning memory */
831 PerfMem = strstr(CommandLine, "BURNMEMORY");
832 if (PerfMem)
833 {
834 /* Check if the user gave a number of bytes to use */
835 PerfMem = strstr(PerfMem, "=");
836 if (PerfMem)
837 {
838 /* Read the number of pages we'll use */
839 PerfMemUsed = atol(PerfMem + 1) * (1024 * 1024 / PAGE_SIZE);
840 if (PerfMem)
841 {
842 /* FIXME: TODO */
843 DPRINT1("Burnable memory support not yet present."
844 "/BURNMEM option ignored.\n");
845 }
846 }
847 }
848 }
849
850 /* Setup NLS Base and offsets */
851 NlsData = LoaderBlock->NlsData;
852 ExpNlsTableBase = NlsData->AnsiCodePageData;
853 ExpAnsiCodePageDataOffset = 0;
854 ExpOemCodePageDataOffset = ((ULONG_PTR)NlsData->OemCodePageData -
855 (ULONG_PTR)NlsData->AnsiCodePageData);
856 ExpUnicodeCaseTableDataOffset = ((ULONG_PTR)NlsData->UnicodeCodePageData -
857 (ULONG_PTR)NlsData->AnsiCodePageData);
858
859 /* Initialize the NLS Tables */
860 RtlInitNlsTables((PVOID)((ULONG_PTR)ExpNlsTableBase +
861 ExpAnsiCodePageDataOffset),
862 (PVOID)((ULONG_PTR)ExpNlsTableBase +
863 ExpOemCodePageDataOffset),
864 (PVOID)((ULONG_PTR)ExpNlsTableBase +
865 ExpUnicodeCaseTableDataOffset),
866 &ExpNlsTableInfo);
867 RtlResetRtlTranslations(&ExpNlsTableInfo);
868
869 /* Now initialize the HAL */
870 if (!HalInitSystem(ExpInitializationPhase, LoaderBlock))
871 {
872 /* HAL failed to initialize, bugcheck */
873 KeBugCheck(HAL_INITIALIZATION_FAILED);
874 }
875
876 /* Make sure interrupts are active now */
877 _enable();
878
879 /* Clear the crypto exponent */
880 SharedUserData->CryptoExponent = 0;
881
882 /* Set global flags for the checked build */
883 #if DBG
884 NtGlobalFlag |= FLG_ENABLE_CLOSE_EXCEPTIONS |
885 FLG_ENABLE_KDEBUG_SYMBOL_LOAD;
886 #endif
887
888 /* Setup NT System Root Path */
889 sprintf(Buffer, "C:%s", LoaderBlock->NtBootPathName);
890
891 /* Convert to ANSI_STRING and null-terminate it */
892 RtlInitString(&AnsiPath, Buffer );
893 Buffer[--AnsiPath.Length] = ANSI_NULL;
894
895 /* Get the string from KUSER_SHARED_DATA's buffer */
896 RtlInitEmptyUnicodeString(&NtSystemRoot,
897 SharedUserData->NtSystemRoot,
898 sizeof(SharedUserData->NtSystemRoot));
899
900 /* Now fill it in */
901 Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &AnsiPath, FALSE);
902 if (!NT_SUCCESS(Status)) KEBUGCHECK(SESSION3_INITIALIZATION_FAILED);
903
904 /* Setup bugcheck messages */
905 KiInitializeBugCheck();
906
907 /* Setup initial system settings (FIXME: Needs Cm Rewrite) */
908 CmGetSystemControlValues(LoaderBlock->RegistryBase, CmControlVector);
909
910 /* Initialize the executive at phase 0 */
911 if (!ExInitSystem()) KEBUGCHECK(PHASE0_INITIALIZATION_FAILED);
912
913 /* Initialize the memory manager at phase 0 */
914 if (!MmInitSystem(0, LoaderBlock)) KeBugCheck(MEMORY1_INITIALIZATION_FAILED);
915
916 /* Load boot symbols */
917 ExpLoadBootSymbols(LoaderBlock);
918
919 /* Set system ranges */
920 SharedUserData->Reserved1 = (ULONG_PTR)MmHighestUserAddress;
921 SharedUserData->Reserved3 = (ULONG_PTR)MmSystemRangeStart;
922
923 /* Make a copy of the NLS Tables */
924 ExpInitNls(LoaderBlock);
925
926 /* Check if the user wants a kernel stack trace database */
927 if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB)
928 {
929 /* FIXME: TODO */
930 DPRINT1("Kernel-mode stack trace support not yet present."
931 "FLG_KERNEL_STACK_TRACE_DB flag ignored.\n");
932 }
933
934 /* Check if he wanted exception logging */
935 if (NtGlobalFlag & FLG_ENABLE_EXCEPTION_LOGGING)
936 {
937 /* FIXME: TODO */
938 DPRINT1("Kernel-mode exception logging support not yet present."
939 "FLG_ENABLE_EXCEPTION_LOGGING flag ignored.\n");
940 }
941
942 /* Initialize the Handle Table */
943 ExpInitializeHandleTables();
944
945 #if DBG
946 /* On checked builds, allocate the system call count table */
947 KeServiceDescriptorTable[0].Count =
948 ExAllocatePoolWithTag(NonPagedPool,
949 KiServiceLimit * sizeof(ULONG),
950 TAG('C', 'a', 'l', 'l'));
951
952 /* Use it for the shadow table too */
953 KeServiceDescriptorTableShadow[0].Count = KeServiceDescriptorTable[0].Count;
954
955 /* Make sure allocation succeeded */
956 if (KeServiceDescriptorTable[0].Count)
957 {
958 /* Zero the call counts to 0 */
959 RtlZeroMemory(KeServiceDescriptorTable[0].Count,
960 KiServiceLimit * sizeof(ULONG));
961 }
962 #endif
963
964 /* Create the Basic Object Manager Types to allow new Object Types */
965 if (!ObInit()) KEBUGCHECK(OBJECT_INITIALIZATION_FAILED);
966
967 /* Load basic Security for other Managers */
968 if (!SeInit()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
969
970 /* Initialize the Process Manager */
971 if (!PsInitSystem(LoaderBlock)) KEBUGCHECK(PROCESS_INITIALIZATION_FAILED);
972
973 /* Initialize the PnP Manager */
974 if (!PpInitSystem()) KEBUGCHECK(PP0_INITIALIZATION_FAILED);
975
976 /* Initialize the User-Mode Debugging Subsystem */
977 DbgkInitialize();
978
979 /* Calculate the tick count multiplier */
980 ExpTickCountMultiplier = ExComputeTickCountMultiplier(KeMaximumIncrement);
981 SharedUserData->TickCountMultiplier = ExpTickCountMultiplier;
982
983 /* Set the OS Version */
984 SharedUserData->NtMajorVersion = NtMajorVersion;
985 SharedUserData->NtMinorVersion = NtMinorVersion;
986
987 /* Set the machine type */
988 #if defined(_X86_)
989 SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_I386;
990 SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_I386;
991 #elif defined(_PPC_) // <3 Arty
992 SharedUserData->ImageNumberLow = IMAGE_FILE_MACHINE_POWERPC;
993 SharedUserData->ImageNumberHigh = IMAGE_FILE_MACHINE_POWERPC;
994 #elif
995 #error "Unsupported ReactOS Target"
996 #endif
997 }
998
999 VOID
1000 NTAPI
1001 Phase1InitializationDiscard(PVOID Context)
1002 {
1003 PLOADER_PARAMETER_BLOCK LoaderBlock = Context;
1004 PCHAR CommandLine, Y2KHackRequired;
1005 LARGE_INTEGER Timeout;
1006 NTSTATUS Status;
1007 TIME_FIELDS TimeFields;
1008 LARGE_INTEGER SystemBootTime, UniversalBootTime, OldTime;
1009 PRTL_USER_PROCESS_INFORMATION ProcessInfo;
1010 BOOLEAN SosEnabled, NoGuiBoot;
1011 ULONG YearHack = 0;
1012
1013 /* Allocate initial process information */
1014 ProcessInfo = ExAllocatePoolWithTag(NonPagedPool,
1015 sizeof(RTL_USER_PROCESS_INFORMATION),
1016 TAG('I', 'n', 'i', 't'));
1017 if (!ProcessInfo)
1018 {
1019 /* Bugcheck */
1020 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, STATUS_NO_MEMORY, 8, 0, 0);
1021 }
1022
1023 /* Set to phase 1 */
1024 ExpInitializationPhase = 1;
1025
1026 /* Set us at maximum priority */
1027 KeSetPriorityThread(KeGetCurrentThread(), HIGH_PRIORITY);
1028
1029 /* Do Phase 1 HAL Initialization */
1030 if (!HalInitSystem(1, LoaderBlock)) KeBugCheck(HAL1_INITIALIZATION_FAILED);
1031
1032 /* Get the command line and upcase it */
1033 CommandLine = _strupr(LoaderBlock->LoadOptions);
1034
1035 /* Check if GUI Boot is enabled */
1036 NoGuiBoot = (strstr(CommandLine, "NOGUIBOOT")) ? TRUE: FALSE;
1037
1038 /* Get the SOS setting */
1039 SosEnabled = strstr(CommandLine, "SOS") ? TRUE: FALSE;
1040
1041 /* Setup the boot driver */
1042 InbvEnableBootDriver(!NoGuiBoot);
1043 InbvDriverInitialize(LoaderBlock, 18);
1044
1045 /* Check if GUI boot is enabled */
1046 if (!NoGuiBoot)
1047 {
1048 /* It is, display the boot logo and enable printing strings */
1049 InbvEnableDisplayString(SosEnabled);
1050 DisplayBootBitmap(SosEnabled);
1051 }
1052 else
1053 {
1054 /* Release display ownership if not using GUI boot */
1055 InbvNotifyDisplayOwnershipLost(NULL);
1056
1057 /* Don't allow boot-time strings */
1058 InbvEnableDisplayString(FALSE);
1059 }
1060
1061 /* Check if this is LiveCD (WinPE) mode */
1062 if (strstr(CommandLine, "MININT"))
1063 {
1064 /* Setup WinPE Settings */
1065 InitIsWinPEMode = TRUE;
1066 InitWinPEModeType |= (strstr(CommandLine, "INRAM")) ? 0x80000000 : 1;
1067 }
1068
1069 /* FIXME: Print product name, version, and build */
1070
1071 /* Initialize Power Subsystem in Phase 0 */
1072 if (!PoInitSystem(0, AcpiTableDetected)) KeBugCheck(INTERNAL_POWER_ERROR);
1073
1074 /* Check for Y2K hack */
1075 Y2KHackRequired = strstr(CommandLine, "YEAR");
1076 if (Y2KHackRequired) Y2KHackRequired = strstr(Y2KHackRequired, "=");
1077 if (Y2KHackRequired) YearHack = atol(Y2KHackRequired + 1);
1078
1079 /* Query the clock */
1080 if ((ExCmosClockIsSane) && (HalQueryRealTimeClock(&TimeFields)))
1081 {
1082 /* Check if we're using the Y2K hack */
1083 if (Y2KHackRequired) TimeFields.Year = (CSHORT)YearHack;
1084
1085 /* Convert to time fields */
1086 RtlTimeFieldsToTime(&TimeFields, &SystemBootTime);
1087 UniversalBootTime = SystemBootTime;
1088
1089 #if 0 // FIXME: Won't work until we can read registry data here
1090 /* FIXME: This assumes that the RTC is not already in GMT */
1091 ExpTimeZoneBias.QuadPart = Int32x32To64(ExpLastTimeZoneBias * 60,
1092 10000000);
1093
1094 /* Set the boot time-zone bias */
1095 SharedUserData->TimeZoneBias.High2Time = ExpTimeZoneBias.HighPart;
1096 SharedUserData->TimeZoneBias.LowPart = ExpTimeZoneBias.LowPart;
1097 SharedUserData->TimeZoneBias.High1Time = ExpTimeZoneBias.HighPart;
1098
1099 /* Convert the boot time to local time, and set it */
1100 UniversalBootTime.QuadPart = SystemBootTime.QuadPart +
1101 ExpTimeZoneBias.QuadPart;
1102 #endif
1103
1104 /* Update the system time */
1105 KeSetSystemTime(&UniversalBootTime, &OldTime, FALSE, NULL);
1106
1107 /* Remember this as the boot time */
1108 KeBootTime = UniversalBootTime;
1109 KeBootTimeBias = 0;
1110 }
1111
1112 /* Initialize all processors */
1113 if (!HalAllProcessorsStarted()) KeBugCheck(HAL1_INITIALIZATION_FAILED);
1114
1115 /* FIXME: Print CPU and Memory */
1116
1117 /* Update the progress bar */
1118 InbvUpdateProgressBar(5);
1119
1120 /* Call OB initialization again */
1121 if (!ObInit()) KeBugCheck(OBJECT1_INITIALIZATION_FAILED);
1122
1123 /* Initialize Basic System Objects and Worker Threads */
1124 if (!ExInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 1, 0);
1125
1126 /* Initialize the later stages of the kernel */
1127 if (!KeInitSystem()) KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 2, 0);
1128
1129 /* Call KD Providers at Phase 1 */
1130 if (!KdInitSystem(ExpInitializationPhase, KeLoaderBlock))
1131 {
1132 /* Failed, bugcheck */
1133 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, 0, 0, 3, 0);
1134 }
1135
1136 /* Initialize the SRM in Phase 1 */
1137 if (!SeInit()) KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
1138
1139 /* Update the progress bar */
1140 InbvUpdateProgressBar(10);
1141
1142 /* Create SystemRoot Link */
1143 Status = ExpCreateSystemRootLink(LoaderBlock);
1144 if (!NT_SUCCESS(Status))
1145 {
1146 /* Failed to create the system root link */
1147 KeBugCheckEx(SYMBOLIC_INITIALIZATION_FAILED, Status, 0, 0, 0);
1148 }
1149
1150 /* Set up Region Maps, Sections and the Paging File */
1151 if (!MmInitSystem(1, LoaderBlock)) KeBugCheck(MEMORY1_INITIALIZATION_FAILED);
1152
1153 /* Create NLS section */
1154 ExpInitNls(KeLoaderBlock);
1155
1156 /* Initialize Cache Views */
1157 if (!CcInitializeCacheManager()) KeBugCheck(CACHE_INITIALIZATION_FAILED);
1158
1159 /* Initialize the Registry */
1160 if (!CmInitSystem1()) KeBugCheck(CONFIG_INITIALIZATION_FAILED);
1161
1162 /* Update progress bar */
1163 InbvUpdateProgressBar(15);
1164
1165 /* Update timezone information */
1166 ExRefreshTimeZoneInformation(&SystemBootTime);
1167
1168 /* Initialize the File System Runtime Library */
1169 if (!FsRtlInitSystem()) KeBugCheck(FILE_INITIALIZATION_FAILED);
1170
1171 /* Report all resources used by HAL */
1172 HalReportResourceUsage();
1173
1174 /* Call the debugger DLL once we have KD64 6.0 support */
1175 //KdDebuggerInitialize1(LoaderBlock);
1176
1177 /* Setup PnP Manager in phase 1 */
1178 if (!PpInitSystem()) KeBugCheck(PP1_INITIALIZATION_FAILED);
1179
1180 /* Update progress bar */
1181 InbvUpdateProgressBar(20);
1182
1183 /* Initialize LPC */
1184 if (!LpcInitSystem()) KeBugCheck(LPC_INITIALIZATION_FAILED);
1185
1186 /* Initialize the I/O Subsystem */
1187 if (!IoInitSystem(KeLoaderBlock)) KeBugCheck(IO1_INITIALIZATION_FAILED);
1188
1189 /* Unmap Low memory, and initialize the MPW and Balancer Thread */
1190 MmInitSystem(2, LoaderBlock);
1191
1192 /* Update progress bar */
1193 InbvUpdateProgressBar(80);
1194
1195 /* Initialize VDM support */
1196 KeI386VdmInitialize();
1197
1198 /* Initialize Power Subsystem in Phase 1*/
1199 if (!PoInitSystem(1, AcpiTableDetected)) KeBugCheck(INTERNAL_POWER_ERROR);
1200
1201 /* Initialize the Process Manager at Phase 1 */
1202 if (!PsInitSystem(LoaderBlock)) KeBugCheck(PROCESS1_INITIALIZATION_FAILED);
1203
1204 /* Update progress bar */
1205 InbvUpdateProgressBar(85);
1206
1207 /* Make sure nobody touches the loader block again */
1208 if (LoaderBlock == KeLoaderBlock) KeLoaderBlock = NULL;
1209 LoaderBlock = Context = NULL;
1210
1211 /* Update progress bar */
1212 InbvUpdateProgressBar(90);
1213
1214 /* Launch initial process */
1215 Status = ExpLoadInitialProcess(ProcessInfo);
1216
1217 /* Update progress bar */
1218 InbvUpdateProgressBar(100);
1219
1220 /* Allow strings to be displayed */
1221 InbvEnableDisplayString(TRUE);
1222
1223 /* Wait 5 seconds for it to initialize */
1224 Timeout.QuadPart = Int32x32To64(5, -10000000);
1225 Status = ZwWaitForSingleObject(ProcessInfo->ProcessHandle, FALSE, &Timeout);
1226 if (InbvBootDriverInstalled) FinalizeBootLogo();
1227
1228 if (Status == STATUS_SUCCESS)
1229 {
1230 /* Bugcheck the system if SMSS couldn't initialize */
1231 KeBugCheck(SESSION5_INITIALIZATION_FAILED);
1232 }
1233
1234 /* Close process handles */
1235 ZwClose(ProcessInfo->ThreadHandle);
1236 ZwClose(ProcessInfo->ProcessHandle);
1237
1238 /* FIXME: We should free the initial process' memory!*/
1239
1240 /* Increase init phase */
1241 ExpInitializationPhase += 1;
1242
1243 /* Free the process information */
1244 ExFreePool(ProcessInfo);
1245 }
1246
1247 VOID
1248 NTAPI
1249 Phase1Initialization(IN PVOID Context)
1250 {
1251 /* Do the .INIT part of Phase 1 which we can free later */
1252 Phase1InitializationDiscard(Context);
1253
1254 /* Jump into zero page thread */
1255 MmZeroPageThreadMain(NULL);
1256 }
1257