Started security manager initialization.
[reactos.git] / reactos / ntoskrnl / ke / main.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: main.c,v 1.114 2002/02/20 20:14:22 ekohl Exp $
20 *
21 * PROJECT: ReactOS kernel
22 * FILE: ntoskrnl/ke/main.c
23 * PURPOSE: Initalizes the kernel
24 * PROGRAMMER: David Welch (welch@cwcom.net)
25 * UPDATE HISTORY:
26 * 28/05/98: Created
27 */
28
29 /* INCLUDES *****************************************************************/
30
31 #include <ddk/ntddk.h>
32 #include <internal/ntoskrnl.h>
33 #include <reactos/resource.h>
34 #include <internal/mm.h>
35 #include <internal/module.h>
36 #include <internal/ldr.h>
37 #include <internal/ex.h>
38 #include <internal/ps.h>
39 #include <internal/ke.h>
40 #include <internal/io.h>
41 #include <internal/po.h>
42 #include <internal/cc.h>
43 #include <internal/se.h>
44 #include <napi/shared_data.h>
45 #include <internal/v86m.h>
46 #include <internal/kd.h>
47 #include <internal/trap.h>
48 #include "../dbg/kdb.h"
49 #include <internal/registry.h>
50 #include <reactos/bugcodes.h>
51
52 #ifdef HALDBG
53 #include <internal/ntosdbg.h>
54 #else
55 #define ps(args...)
56 #endif
57
58 #define NDEBUG
59 #include <internal/debug.h>
60
61 /* GLOBALS *******************************************************************/
62
63 ULONG EXPORTED NtBuildNumber = KERNEL_VERSION_BUILD;
64 ULONG EXPORTED NtGlobalFlag = 0;
65 CHAR EXPORTED KeNumberProcessors;
66 LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock;
67 static LOADER_MODULE KeLoaderModules[64];
68 static UCHAR KeLoaderModuleStrings[64][256];
69 static UCHAR KeLoaderCommandLine[256];
70 static ADDRESS_RANGE KeMemoryMap[64];
71 static ULONG KeMemoryMapRangeCount;
72 static ULONG FirstKrnlPhysAddr;
73 static ULONG LastKrnlPhysAddr;
74 static ULONG LastKernelAddress;
75 volatile BOOLEAN Initialized = FALSE;
76
77 extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
78
79 typedef struct
80 {
81 LPWSTR ServiceName;
82 LPWSTR DeviceDesc;
83 LPWSTR Group;
84 DWORD Start;
85 DWORD Type;
86 } SERVICE, *PSERVICE;
87
88 SERVICE Services[] = {
89 {L"pci", L"PCI Bus Driver", L"Boot Bus Extender", 0, 1},
90 {L"keyboard", L"Standard Keyboard Driver", L"Base", 0, 1},
91 {L"blue", L"Bluescreen Driver", L"Base", 0, 1},
92 {L"vidport", L"Video Port Driver", L"Base", 0, 1},
93 {L"vgamp", L"VGA Miniport", L"Base", 0, 1},
94 {L"minixfs", L"Minix File System", L"File system", 0, 1},
95 {L"msfs", L"Mail Slot File System", L"File system", 0, 1},
96 {L"npfs", L"Named Pipe File System", L"File system", 0, 1},
97 {L"psaux", L"PS/2 Auxillary Port Driver", L"", 0, 1},
98 {L"mouclass", L"Mouse Class Driver", L"Pointer Class", 0, 1},
99 {L"ndis", L"NDIS System Driver", L"NDIS Wrapper", 0, 1},
100 {L"ne2000", L"Novell Eagle 2000 Driver", L"NDIS", 0, 1},
101 {L"afd", L"AFD Networking Support Environment", L"TDI", 0, 1},
102 {NULL,}
103 };
104
105 /* FUNCTIONS ****************************************************************/
106
107 #define FULLREG
108
109 VOID CreateDefaultRegistryForLegacyDriver(
110 PSERVICE Service)
111 {
112 #ifdef FULLREG
113 WCHAR LegacyDriver[] = L"LegacyDriver";
114 #endif
115 WCHAR InstancePath[MAX_PATH];
116 WCHAR KeyNameBuffer[MAX_PATH];
117 WCHAR Name[MAX_PATH];
118 UNICODE_STRING KeyName;
119 HANDLE KeyHandle;
120 #ifdef FULLREG
121 DWORD DwordData;
122 #endif
123 ULONG Length;
124 NTSTATUS Status;
125 WCHAR ImagePath[MAX_PATH];
126
127 /* Enum section */
128 wcscpy(Name, Service->ServiceName);
129 _wcsupr(Name);
130 wcscpy(InstancePath, L"Root\\LEGACY_");
131 wcscat(InstancePath, Name);
132 wcscat(InstancePath, L"\\0000");
133
134 wcscpy(KeyNameBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
135 wcscat(KeyNameBuffer, InstancePath);
136
137 RtlInitUnicodeString(&KeyName, KeyNameBuffer);
138
139 DPRINT("Key name is %S\n", KeyName.Buffer);
140
141 Status = RtlpCreateRegistryKeyPath(KeyName.Buffer);
142 if (!NT_SUCCESS(Status))
143 {
144 DPRINT1("RtlpCreateRegistryKeyPath() failed with status %x\n", Status);
145 return;
146 }
147
148 Status = RtlpGetRegistryHandle(
149 RTL_REGISTRY_ENUM,
150 InstancePath,
151 TRUE,
152 &KeyHandle);
153 if (!NT_SUCCESS(Status))
154 {
155 DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
156 return;
157 }
158 #ifdef FULLREG
159 DwordData = 0;
160 Length = sizeof(DWORD);
161 Status = RtlWriteRegistryValue(
162 RTL_REGISTRY_HANDLE,
163 (PWSTR)KeyHandle,
164 L"Capabilities",
165 REG_DWORD,
166 (LPWSTR)&DwordData,
167 Length);
168 if (!NT_SUCCESS(Status))
169 {
170 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
171 NtClose(KeyHandle);
172 return;
173 }
174
175 Length = (wcslen(LegacyDriver) + 1) * sizeof(WCHAR);
176 Status = RtlWriteRegistryValue(
177 RTL_REGISTRY_HANDLE,
178 (PWSTR)KeyHandle,
179 L"Class",
180 REG_SZ,
181 LegacyDriver,
182 Length);
183 if (!NT_SUCCESS(Status))
184 {
185 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
186 NtClose(KeyHandle);
187 return;
188 }
189 #endif
190 Length = (wcslen(Service->DeviceDesc) + 1) * sizeof(WCHAR);
191 Status = RtlWriteRegistryValue(
192 RTL_REGISTRY_HANDLE,
193 (PWSTR)KeyHandle,
194 L"DeviceDesc",
195 REG_SZ,
196 Service->DeviceDesc,
197 Length);
198 if (!NT_SUCCESS(Status))
199 {
200 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
201 NtClose(KeyHandle);
202 return;
203 }
204 #ifdef FULLREG
205 DwordData = 0;
206 Length = Length = sizeof(DWORD);
207 Status = RtlWriteRegistryValue(
208 RTL_REGISTRY_HANDLE,
209 (PWSTR)KeyHandle,
210 L"Legacy",
211 REG_DWORD,
212 (LPWSTR)&DwordData,
213 sizeof(DWORD));
214 if (!NT_SUCCESS(Status))
215 {
216 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
217 NtClose(KeyHandle);
218 return;
219 }
220 #endif
221 Length = (wcslen(Service->ServiceName) + 1) * sizeof(WCHAR);
222 Status = RtlWriteRegistryValue(
223 RTL_REGISTRY_HANDLE,
224 (PWSTR)KeyHandle,
225 L"Service",
226 REG_SZ,
227 Service->ServiceName,
228 Length);
229 if (!NT_SUCCESS(Status))
230 {
231 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
232 NtClose(KeyHandle);
233 return;
234 }
235
236 NtClose(KeyHandle);
237
238
239 /* Services section */
240
241 Status = RtlpGetRegistryHandle(
242 RTL_REGISTRY_SERVICES,
243 Service->ServiceName,
244 TRUE,
245 &KeyHandle);
246 if (!NT_SUCCESS(Status))
247 {
248 DPRINT1("RtlpGetRegistryHandle() failed (Status %x)\n", Status);
249 return;
250 }
251 #ifdef FULLREG
252 Length = (wcslen(Service->DeviceDesc) + 1) * sizeof(WCHAR);
253 Status = RtlWriteRegistryValue(
254 RTL_REGISTRY_HANDLE,
255 (PWSTR)KeyHandle,
256 L"DisplayName",
257 REG_SZ,
258 Service->DeviceDesc,
259 Length);
260 if (!NT_SUCCESS(Status))
261 {
262 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
263 NtClose(KeyHandle);
264 return;
265 }
266
267 DwordData = 1;
268 Length = sizeof(DWORD);
269 Status = RtlWriteRegistryValue(
270 RTL_REGISTRY_HANDLE,
271 (PWSTR)KeyHandle,
272 L"ErrorControl",
273 REG_DWORD,
274 (LPWSTR)&DwordData,
275 Length);
276 if (!NT_SUCCESS(Status))
277 {
278 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
279 NtClose(KeyHandle);
280 return;
281 }
282
283 Length = (wcslen(Service->Group) + 1) * sizeof(WCHAR);
284 Status = RtlWriteRegistryValue(
285 RTL_REGISTRY_HANDLE,
286 (PWSTR)KeyHandle,
287 L"Group",
288 REG_SZ,
289 Service->Group,
290 Length);
291 if (!NT_SUCCESS(Status))
292 {
293 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
294 NtClose(KeyHandle);
295 return;
296 }
297 #endif
298 wcscpy(ImagePath, L"\\SystemRoot\\System32\\drivers\\");
299 wcscat(ImagePath, Service->ServiceName);
300 wcscat(ImagePath, L".sys");
301
302 Length = (wcslen(ImagePath) + 1) * sizeof(WCHAR);
303 Status = RtlWriteRegistryValue(
304 RTL_REGISTRY_HANDLE,
305 (PWSTR)KeyHandle,
306 L"ImagePath",
307 REG_SZ,
308 ImagePath,
309 Length);
310 if (!NT_SUCCESS(Status))
311 {
312 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
313 NtClose(KeyHandle);
314 return;
315 }
316 #ifdef FULLREG
317 DwordData = Service->Start;
318 Length = sizeof(DWORD);
319 Status = RtlWriteRegistryValue(
320 RTL_REGISTRY_HANDLE,
321 (PWSTR)KeyHandle,
322 L"Start",
323 REG_DWORD,
324 (LPWSTR)&DwordData,
325 Length);
326 if (!NT_SUCCESS(Status))
327 {
328 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
329 NtClose(KeyHandle);
330 return;
331 }
332
333 DwordData = Service->Type;
334 Length = sizeof(DWORD);
335 Status = RtlWriteRegistryValue(
336 RTL_REGISTRY_HANDLE,
337 (PWSTR)KeyHandle,
338 L"Type",
339 REG_DWORD,
340 (LPWSTR)&DwordData,
341 Length);
342 if (!NT_SUCCESS(Status))
343 {
344 DPRINT1("RtlWriteRegistryValue() failed (Status %x)\n", Status);
345 NtClose(KeyHandle);
346 return;
347 }
348 #endif
349 NtClose(KeyHandle);
350 }
351
352 VOID CreateDefaultRegistry()
353 {
354 NTSTATUS Status;
355 ULONG i;
356
357 Status = RtlpCreateRegistryKeyPath(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
358 if (!NT_SUCCESS(Status))
359 {
360 CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
361 return;
362 }
363
364 Status = RtlpCreateRegistryKeyPath(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
365 if (!NT_SUCCESS(Status))
366 {
367 CPRINT("RtlpCreateRegistryKeyPath() (Status %x)\n", Status);
368 return;
369 }
370
371 for (i = 0; Services[i].ServiceName != NULL; i++)
372 {
373 CreateDefaultRegistryForLegacyDriver(&Services[i]);
374 }
375 }
376
377
378 static BOOLEAN
379 RtlpCheckFileNameExtension(PCHAR FileName,
380 PCHAR Extension)
381 {
382 PCHAR Ext;
383
384 Ext = strrchr(FileName, '.');
385 if ((Extension == NULL) || (*Extension == 0))
386 {
387 if (Ext == NULL)
388 return TRUE;
389 else
390 return FALSE;
391 }
392 if (*Extension != '.')
393 Ext++;
394
395 if (_stricmp(Ext, Extension) == 0)
396 return TRUE;
397 else
398 return FALSE;
399 }
400
401 static VOID
402 CreateSystemRootLink (PCSZ ParameterLine)
403 {
404 UNICODE_STRING LinkName;
405 UNICODE_STRING DeviceName;
406 UNICODE_STRING ArcName;
407 UNICODE_STRING BootPath;
408 PCHAR ParamBuffer;
409 PWCHAR ArcNameBuffer;
410 PCHAR p;
411 NTSTATUS Status;
412 ULONG Length;
413 OBJECT_ATTRIBUTES ObjectAttributes;
414 HANDLE Handle;
415
416 /* create local parameter line copy */
417 ParamBuffer = ExAllocatePool (PagedPool, 256);
418 strcpy (ParamBuffer, (char *)ParameterLine);
419
420 DPRINT("%s\n", ParamBuffer);
421 /* Format: <arc_name>\<path> [options...] */
422
423 /* cut options off */
424 p = strchr (ParamBuffer, ' ');
425 if (p)
426 *p = 0;
427 DPRINT("%s\n", ParamBuffer);
428
429 /* extract path */
430 p = strchr (ParamBuffer, '\\');
431 if (p)
432 {
433 DPRINT("Boot path: %s\n", p);
434 RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
435 *p = 0;
436 }
437 else
438 {
439 DPRINT("Boot path: %s\n", "\\");
440 RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
441 }
442 DPRINT("Arc name: %s\n", ParamBuffer);
443
444 /* Only arc name left - build full arc name */
445 ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
446 swprintf (ArcNameBuffer,
447 L"\\ArcName\\%S", ParamBuffer);
448 RtlInitUnicodeString (&ArcName, ArcNameBuffer);
449 DPRINT("Arc name: %wZ\n", &ArcName);
450
451 /* free ParamBuffer */
452 ExFreePool (ParamBuffer);
453
454 /* allocate device name string */
455 DeviceName.Length = 0;
456 DeviceName.MaximumLength = 256 * sizeof(WCHAR);
457 DeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
458
459 InitializeObjectAttributes (&ObjectAttributes,
460 &ArcName,
461 0,
462 NULL,
463 NULL);
464
465 Status = NtOpenSymbolicLinkObject (&Handle,
466 SYMBOLIC_LINK_ALL_ACCESS,
467 &ObjectAttributes);
468 if (!NT_SUCCESS(Status))
469 {
470 RtlFreeUnicodeString (&BootPath);
471 RtlFreeUnicodeString (&DeviceName);
472 DPRINT1("NtOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n",
473 &ArcName,
474 Status);
475 RtlFreeUnicodeString (&ArcName);
476
477 KeBugCheck (0x0);
478 }
479 RtlFreeUnicodeString (&ArcName);
480
481 Status = NtQuerySymbolicLinkObject (Handle,
482 &DeviceName,
483 &Length);
484 NtClose (Handle);
485 if (!NT_SUCCESS(Status))
486 {
487 RtlFreeUnicodeString (&BootPath);
488 RtlFreeUnicodeString (&DeviceName);
489 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
490 Status);
491
492 KeBugCheck (0x0);
493 }
494 DPRINT("Length: %lu DeviceName: %wZ\n", Length, &DeviceName);
495
496 RtlAppendUnicodeStringToString (&DeviceName,
497 &BootPath);
498
499 RtlFreeUnicodeString (&BootPath);
500 DPRINT("DeviceName: %wZ\n", &DeviceName);
501
502 /* create the '\SystemRoot' link */
503 RtlInitUnicodeString (&LinkName,
504 L"\\SystemRoot");
505
506 Status = IoCreateSymbolicLink (&LinkName,
507 &DeviceName);
508 RtlFreeUnicodeString (&DeviceName);
509 if (!NT_SUCCESS(Status))
510 {
511 CPRINT("IoCreateSymbolicLink() failed (Status %x)\n",
512 Status);
513
514 KeBugCheck (0x0);
515 }
516
517 /* Check if '\SystemRoot'(LinkName) can be opened, otherwise crash it! */
518 InitializeObjectAttributes (&ObjectAttributes,
519 &LinkName,
520 0,
521 NULL,
522 NULL);
523
524 Status = NtOpenSymbolicLinkObject (&Handle,
525 SYMBOLIC_LINK_ALL_ACCESS,
526 &ObjectAttributes);
527 if (!NT_SUCCESS(Status))
528 {
529 CPRINT("NtOpenSymbolicLinkObject() failed to open '\\SystemRoot' (Status %x)\n",
530 Status);
531 KeBugCheck (0x0);
532 }
533 NtClose(Handle);
534 }
535
536
537 static VOID
538 InitSystemSharedUserPage (PCSZ ParameterLine)
539 {
540 PKUSER_SHARED_DATA SharedPage;
541
542 UNICODE_STRING ArcDeviceName;
543 UNICODE_STRING ArcName;
544 UNICODE_STRING BootPath;
545 UNICODE_STRING DriveDeviceName;
546 UNICODE_STRING DriveName;
547 WCHAR DriveNameBuffer[20];
548 PCHAR ParamBuffer;
549 PWCHAR ArcNameBuffer;
550 PCHAR p;
551 NTSTATUS Status;
552 ULONG Length;
553 OBJECT_ATTRIBUTES ObjectAttributes;
554 HANDLE Handle;
555 ULONG i;
556 BOOLEAN BootDriveFound;
557
558 SharedPage = (PKUSER_SHARED_DATA)KERNEL_SHARED_DATA_BASE;
559 SharedPage->DosDeviceMap = 0;
560 SharedPage->NtProductType = NtProductWinNt;
561 for (i = 0; i < 32; i++)
562 {
563 SharedPage->DosDeviceDriveType[i] = 0;
564 }
565
566 BootDriveFound = FALSE;
567
568 /*
569 * Retrieve the current dos system path
570 * (e.g.: C:\reactos) from the given arc path
571 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
572 * Format: "<arc_name>\<path> [options...]"
573 */
574
575 /* create local parameter line copy */
576 ParamBuffer = ExAllocatePool (PagedPool, 256);
577 strcpy (ParamBuffer, (char *)ParameterLine);
578 DPRINT("%s\n", ParamBuffer);
579
580 /* cut options off */
581 p = strchr (ParamBuffer, ' ');
582 if (p)
583 {
584 *p = 0;
585 }
586 DPRINT("%s\n", ParamBuffer);
587
588 /* extract path */
589 p = strchr (ParamBuffer, '\\');
590 if (p)
591 {
592 DPRINT("Boot path: %s\n", p);
593 RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
594 *p = 0;
595 }
596 else
597 {
598 DPRINT("Boot path: %s\n", "\\");
599 RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
600 }
601 DPRINT("Arc name: %s\n", ParamBuffer);
602
603 /* Only arc name left - build full arc name */
604 ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
605 swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer);
606 RtlInitUnicodeString (&ArcName, ArcNameBuffer);
607 DPRINT("Arc name: %wZ\n", &ArcName);
608
609 /* free ParamBuffer */
610 ExFreePool (ParamBuffer);
611
612 /* allocate arc device name string */
613 ArcDeviceName.Length = 0;
614 ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR);
615 ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
616
617 InitializeObjectAttributes (&ObjectAttributes,
618 &ArcName,
619 0,
620 NULL,
621 NULL);
622
623 Status = NtOpenSymbolicLinkObject (&Handle,
624 SYMBOLIC_LINK_ALL_ACCESS,
625 &ObjectAttributes);
626 RtlFreeUnicodeString (&ArcName);
627 if (!NT_SUCCESS(Status))
628 {
629 RtlFreeUnicodeString (&BootPath);
630 RtlFreeUnicodeString (&ArcDeviceName);
631 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
632 Status);
633
634 KeBugCheck (0x0);
635 }
636
637 Status = NtQuerySymbolicLinkObject (Handle,
638 &ArcDeviceName,
639 &Length);
640 NtClose (Handle);
641 if (!NT_SUCCESS(Status))
642 {
643 RtlFreeUnicodeString (&BootPath);
644 RtlFreeUnicodeString (&ArcDeviceName);
645 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
646 Status);
647
648 KeBugCheck (0x0);
649 }
650 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
651
652
653 /* allocate device name string */
654 DriveDeviceName.Length = 0;
655 DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
656 DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
657
658 for (i = 0; i < 26; i++)
659 {
660 swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
661 RtlInitUnicodeString (&DriveName,
662 DriveNameBuffer);
663
664 InitializeObjectAttributes (&ObjectAttributes,
665 &DriveName,
666 0,
667 NULL,
668 NULL);
669
670 Status = NtOpenSymbolicLinkObject (&Handle,
671 SYMBOLIC_LINK_ALL_ACCESS,
672 &ObjectAttributes);
673 if (!NT_SUCCESS(Status))
674 {
675 DPRINT("Failed to open link %wZ\n",
676 &DriveName);
677 continue;
678 }
679
680 Status = NtQuerySymbolicLinkObject (Handle,
681 &DriveDeviceName,
682 &Length);
683 if (!NT_SUCCESS(Status))
684 {
685 DPRINT("Failed query open link %wZ\n",
686 &DriveName);
687 continue;
688 }
689 DPRINT("Opened link: %wZ ==> %wZ\n",
690 &DriveName, &DriveDeviceName);
691
692 if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE))
693 {
694 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
695 swprintf (SharedPage->NtSystemRoot,
696 L"%C:%wZ", 'A' + i, &BootPath);
697
698 BootDriveFound = TRUE;
699 }
700
701 NtClose (Handle);
702
703 /* set bit in dos drives bitmap (drive available) */
704 SharedPage->DosDeviceMap |= (1<<i);
705 }
706
707 RtlFreeUnicodeString (&BootPath);
708 RtlFreeUnicodeString (&DriveDeviceName);
709 RtlFreeUnicodeString (&ArcDeviceName);
710
711 DPRINT("DosDeviceMap: 0x%x\n", SharedPage->DosDeviceMap);
712
713 if (BootDriveFound == FALSE)
714 {
715 DbgPrint("No system drive found!\n");
716 KeBugCheck (0x0);
717 }
718 }
719
720 #ifndef NDEBUG
721
722 VOID DumpBIOSMemoryMap(VOID)
723 {
724 ULONG i;
725
726 DbgPrint("Dumping BIOS memory map:\n");
727 DbgPrint("Memory map base: %d\n", KeLoaderBlock.MmapAddr);
728 DbgPrint("Memory map size: %d\n", KeLoaderBlock.MmapLength);
729 DbgPrint("Address range count: %d\n", KeMemoryMapRangeCount);
730 for (i = 0; i < KeMemoryMapRangeCount; i++)
731 {
732 DbgPrint("Range: Base (%08X) Length (%08X) Type (%02X)\n",
733 KeMemoryMap[i].BaseAddrLow,
734 KeMemoryMap[i].LengthLow,
735 KeMemoryMap[i].Type);
736 }
737 for (;;);
738 }
739
740 #endif /* !NDEBUG */
741
742 #if 1
743 // SEH Test
744
745 static ULONG Scratch;
746
747 EXCEPTION_DISPOSITION
748 ExpUnhandledException1(
749 PEXCEPTION_RECORD ExceptionRecord,
750 PEXCEPTION_REGISTRATION ExceptionRegistration,
751 PCONTEXT Context,
752 PVOID DispatcherContext)
753 {
754 DbgPrint("ExpUnhandledException1() called\n");
755 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord);
756 DbgPrint(" Flags 0x%X\n", ExceptionRecord->ExceptionFlags);
757 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration);
758 DbgPrint("Context 0x%X\n", Context);
759 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext);
760
761 Context->Eax = (ULONG)&Scratch;
762
763 return ExceptionContinueExecution;
764 }
765
766
767 EXCEPTION_DISPOSITION
768 ExpUnhandledException2(
769 PEXCEPTION_RECORD ExceptionRecord,
770 PEXCEPTION_REGISTRATION ExceptionRegistration,
771 PCONTEXT Context,
772 PVOID DispatcherContext)
773 {
774 DbgPrint("ExpUnhandledException2() called\n");
775 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord);
776 DbgPrint(" Flags 0x%X\n", ExceptionRecord->ExceptionFlags);
777 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration);
778 DbgPrint("Context 0x%X\n", Context);
779 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext);
780
781 #if 1
782 Context->Eax = (ULONG)&Scratch;
783
784 return ExceptionContinueExecution;
785
786 #else
787
788 return ExceptionContinueSearch;
789
790 #endif
791 }
792
793
794 #if 1
795 // Put in mingw headers
796 extern VOID
797 CDECL
798 _local_unwind2(
799 PEXCEPTION_REGISTRATION RegistrationFrame,
800 DWORD TryLevel);
801
802 extern VOID
803 CDECL
804 _global_unwind2(
805 PVOID RegistrationFrame);
806
807 extern EXCEPTION_DISPOSITION
808 CDECL
809 _except_handler2(
810 PEXCEPTION_RECORD ExceptionRecord,
811 PEXCEPTION_REGISTRATION RegistrationFrame,
812 PCONTEXT Context,
813 PVOID DispatcherContext);
814
815 extern EXCEPTION_DISPOSITION
816 CDECL
817 _except_handler3(
818 PEXCEPTION_RECORD ExceptionRecord,
819 PEXCEPTION_REGISTRATION RegistrationFrame,
820 PCONTEXT Context,
821 PVOID DispatcherContext);
822
823 #endif
824
825 PRTL_EXCEPTION_REGISTRATION
826 CurrentRER(VOID)
827 {
828 ULONG Value;
829
830 __asm__("movl %%ebp, %0\n\t" : "=a" (Value));
831
832 return((PRTL_EXCEPTION_REGISTRATION)Value) - 1;
833 }
834
835 PULONG x;
836 PRTL_EXCEPTION_REGISTRATION TestER;
837 SCOPETABLE_ENTRY ScopeTable;
838 PEXCEPTION_REGISTRATION OSPtr;
839
840
841 DWORD CDECL SEHFilterRoutine(VOID)
842 {
843 DbgPrint("Within filter routine.\n");
844 return EXCEPTION_EXECUTE_HANDLER;
845 //return EXCEPTION_CONTINUE_EXECUTION;
846 }
847
848 VOID CDECL SEHHandlerRoutine(VOID)
849 {
850 DbgPrint("Within exception handler.\n");
851 DbgPrint("System halted.\n");
852 for (;;);
853 }
854
855
856 VOID SEHTest()
857 {
858 RTL_EXCEPTION_REGISTRATION ER;
859 LPEXCEPTION_POINTERS ExceptionPointers;
860 PVOID StandardESPInFrame;
861
862 __asm__ ("movl %%esp,%%eax;" : "=a" (StandardESPInFrame));
863 DbgPrint("StandardESPInFrame: 0x%X\n", StandardESPInFrame);
864
865 ExceptionPointers = NULL;
866
867 ER.OS.handler = _except_handler3;
868 __asm__ ("movl %%fs:0,%%eax;" : "=a" (ER.OS.prev));
869 DbgPrint("ER.OS.prev: 0x%X\n", ER.OS.prev);
870
871 ER.ScopeTable = &ScopeTable;
872 DbgPrint("ER.ScopeTable: 0x%X\n", ER.ScopeTable);
873 ER.TryLevel = -1;
874 __asm__ ("movl %%ebp,%%eax;" : "=a" (ER.Ebp));
875 DbgPrint("ER.Ebp: 0x%X\n", ER.Ebp);
876
877 ScopeTable.PreviousTryLevel = -1;
878 ScopeTable.FilterRoutine = SEHFilterRoutine;
879 DbgPrint("ScopeTable.FilterRoutine: 0x%X\n", ScopeTable.FilterRoutine);
880 ScopeTable.HandlerRoutine = SEHHandlerRoutine;
881 DbgPrint("ScopeTable.HandlerRoutine: 0x%X\n", ScopeTable.HandlerRoutine);
882
883
884 OSPtr = &ER.OS;
885 DbgPrint("OSPtr: 0x%X\n", OSPtr);
886
887 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (OSPtr));
888
889 /*__try1(__except_handler3)*/ if(1) {
890 ER.TryLevel = 0; // Entered first try... block
891
892 DbgPrint("Within guarded section.\n");
893 x = (PULONG)0xf2000000; *x = 0;
894 DbgPrint("After exception.\n");
895 } /* __except1 */ if(0) {
896 }
897
898 DbgPrint("After exception2.\n");
899
900 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (ER.OS.prev));
901 //KeGetCurrentKPCR()->ExceptionList = ER.OS.prev;
902
903 DbgPrint("Exiting.\n");
904 }
905
906 #endif
907
908 VOID
909 ExpInitializeExecutive(VOID)
910 {
911 ULONG i;
912 ULONG start;
913 ULONG length;
914 PCHAR name;
915 CHAR str[50];
916
917 /*
918 * Fail at runtime if someone has changed various structures without
919 * updating the offsets used for the assembler code.
920 */
921 assert(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
922 assert(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
923 assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
924 assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
925 assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
926 assert(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
927 assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
928 assert(FIELD_OFFSET(KPROCESS, DirectoryTableBase) ==
929 KPROCESS_DIRECTORY_TABLE_BASE);
930 assert(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
931 assert(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
932 assert(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
933
934 assert(FIELD_OFFSET(KPCR, ExceptionList) == KPCR_EXCEPTION_LIST);
935 assert(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
936 assert(FIELD_OFFSET(KPCR, CurrentThread) == KPCR_CURRENT_THREAD);
937
938 LdrInit1();
939
940 KeLowerIrql(DISPATCH_LEVEL);
941
942 NtEarlyInitVdm();
943
944 MmInit1(FirstKrnlPhysAddr,
945 LastKrnlPhysAddr,
946 LastKernelAddress,
947 (PADDRESS_RANGE)&KeMemoryMap,
948 KeMemoryMapRangeCount);
949
950 /* create default nls tables */
951 RtlpInitNlsTables();
952
953 /*
954 * Initialize the kernel debugger
955 */
956 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
957
958 MmInit2();
959 KeInit2();
960
961 KeLowerIrql(PASSIVE_LEVEL);
962
963 if (!SeInit1())
964 KeBugCheck(SECURITY_INITIALIZATION_FAILED);
965
966 ObInit();
967 PiInitProcessManager();
968
969 KdInit1();
970
971 if (KdPollBreakIn ())
972 {
973 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
974 }
975
976 /*
977 * Display version number and copyright/warranty message
978 */
979 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
980 KERNEL_VERSION_BUILD_STR")\n");
981 HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
982 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
983 "Public License, and you\n");
984 HalDisplayString("are welcome to change it and/or distribute copies of it "
985 "under certain\n");
986 HalDisplayString("conditions. There is absolutely no warranty for "
987 "ReactOS.\n\n");
988
989 /* Initialize all processors */
990 KeNumberProcessors = 0;
991
992 while (!HalAllProcessorsStarted())
993 {
994 PVOID ProcessorStack;
995
996 if (KeNumberProcessors != 0)
997 {
998 KePrepareForApplicationProcessorInit(KeNumberProcessors);
999 PsPrepareForApplicationProcessorInit(KeNumberProcessors);
1000 }
1001 /* Allocate a stack for use when booting the processor */
1002 /* FIXME: The nonpaged memory for the stack is not released after use */
1003 ProcessorStack =
1004 ExAllocatePool(NonPagedPool, MM_STACK_SIZE) + MM_STACK_SIZE;
1005 Ki386InitialStackArray[((int)KeNumberProcessors)] =
1006 (PVOID)(ProcessorStack - MM_STACK_SIZE);
1007 HalInitializeProcessor(KeNumberProcessors, ProcessorStack);
1008 KeNumberProcessors++;
1009 }
1010
1011 if (KeNumberProcessors > 1)
1012 {
1013 sprintf(str,
1014 "Found %d system processors. [%lu MB Memory]\n",
1015 KeNumberProcessors,
1016 (KeLoaderBlock.MemHigher + 1088)/ 1024);
1017 }
1018 else
1019 {
1020 sprintf(str,
1021 "Found 1 system processor. [%lu MB Memory]\n",
1022 (KeLoaderBlock.MemHigher + 1088)/ 1024);
1023 }
1024 HalDisplayString(str);
1025
1026 /*
1027 * Initialize various critical subsystems
1028 */
1029 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
1030
1031 ExInit();
1032 IoInit();
1033 PoInit();
1034 LdrInitModuleManagement();
1035 CmInitializeRegistry();
1036 NtInit();
1037 MmInit3();
1038 CcInit();
1039 KdInit2();
1040
1041 /* Report all resources used by hal */
1042 HalReportResourceUsage();
1043
1044 /*
1045 * Initalize services loaded at boot time
1046 */
1047 DPRINT("%d files loaded\n",KeLoaderBlock.ModsCount);
1048 for (i=0; i < KeLoaderBlock.ModsCount; i++)
1049 {
1050 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
1051 KeLoaderModules[i].String,
1052 KeLoaderModules[i].ModStart,
1053 KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
1054 }
1055
1056 /* Pass 1: load nls files */
1057 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
1058 {
1059 name = (PCHAR)KeLoaderModules[i].String;
1060 if (RtlpCheckFileNameExtension(name, ".nls"))
1061 {
1062 ULONG Mod2Start = 0;
1063 ULONG Mod2End = 0;
1064 ULONG Mod3Start = 0;
1065 ULONG Mod3End = 0;
1066
1067 name = (PCHAR)KeLoaderModules[i+1].String;
1068 if (RtlpCheckFileNameExtension(name, ".nls"))
1069 {
1070 Mod2Start = (ULONG)KeLoaderModules[i+1].ModStart;
1071 Mod2End = (ULONG)KeLoaderModules[i+1].ModEnd;
1072
1073 name = (PCHAR)KeLoaderModules[i+2].String;
1074 if (RtlpCheckFileNameExtension(name, ".nls"))
1075 {
1076 Mod3Start = (ULONG)KeLoaderModules[i+2].ModStart;
1077 Mod3End = (ULONG)KeLoaderModules[i+2].ModEnd;
1078 }
1079 }
1080
1081 /* Initialize nls sections */
1082 RtlpInitNlsSections((ULONG)KeLoaderModules[i].ModStart,
1083 (ULONG)KeLoaderModules[i].ModEnd,
1084 Mod2Start,
1085 Mod2End,
1086 Mod3Start,
1087 Mod3End);
1088 break;
1089 }
1090 }
1091
1092 /* Pass 2: load registry chunks passed in */
1093 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
1094 {
1095 start = KeLoaderModules[i].ModStart;
1096 length = KeLoaderModules[i].ModEnd - start;
1097 name = (PCHAR)KeLoaderModules[i].String;
1098 if (RtlpCheckFileNameExtension(name, "") ||
1099 RtlpCheckFileNameExtension(name, ".hiv"))
1100 {
1101 CPRINT("Process registry chunk at %08lx\n", start);
1102 CmImportHive((PCHAR)start, length);
1103 }
1104 }
1105
1106 /*
1107 * Enter the kernel debugger before starting up the boot drivers
1108 */
1109 #ifdef KDBG
1110 KdbEnter();
1111 #endif /* KDBG */
1112
1113 /* Pass 3: process boot loaded drivers */
1114 for (i=1; i < KeLoaderBlock.ModsCount; i++)
1115 {
1116 start = KeLoaderModules[i].ModStart;
1117 length = KeLoaderModules[i].ModEnd - start;
1118 name = (PCHAR)KeLoaderModules[i].String;
1119 if (RtlpCheckFileNameExtension(name, ".sys") ||
1120 RtlpCheckFileNameExtension(name, ".sym"))
1121 {
1122 CPRINT("Processing module '%s' at %08lx, length 0x%08lx\n",
1123 name, start, length);
1124 LdrProcessDriver((PVOID)start, name, length);
1125 }
1126 }
1127
1128 /* Create the SystemRoot symbolic link */
1129 CPRINT("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
1130
1131 CreateSystemRootLink ((PUCHAR)KeLoaderBlock.CommandLine);
1132
1133 #ifdef DBGPRINT_FILE_LOG
1134 /* On the assumption that we can now access disks start up the debug
1135 logger thread */
1136 DebugLogInit2();
1137 #endif /* DBGPRINT_FILE_LOG */
1138
1139
1140 CmInitializeRegistry2();
1141
1142 #if 0
1143 CreateDefaultRegistry();
1144 #endif
1145
1146 PiInitDefaultLocale();
1147
1148 /*
1149 * Start the motherboard enumerator (the HAL)
1150 */
1151 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
1152 #if 0
1153 /*
1154 * Load boot start drivers
1155 */
1156 IopLoadBootStartDrivers();
1157 #else
1158 /*
1159 * Load Auto configured drivers
1160 */
1161 LdrLoadAutoConfigDrivers();
1162 #endif
1163 /*
1164 * Assign drive letters
1165 */
1166 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
1167 NULL,
1168 NULL,
1169 NULL);
1170
1171 /*
1172 * Initialize shared user page:
1173 * - set dos system path, dos device map, etc.
1174 */
1175 InitSystemSharedUserPage ((PUCHAR)KeLoaderBlock.CommandLine);
1176
1177 if (!SeInit2())
1178 KeBugCheck(SECURITY1_INITIALIZATION_FAILED);
1179
1180 /*
1181 * Launch initial process
1182 */
1183 LdrLoadInitialProcess();
1184
1185 PsTerminateSystemThread(STATUS_SUCCESS);
1186 }
1187
1188
1189 VOID
1190 KiSystemStartup(BOOLEAN BootProcessor)
1191 {
1192 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
1193
1194 if (BootProcessor)
1195 {
1196 /* Never returns */
1197 ExpInitializeExecutive();
1198 KeBugCheck(0);
1199 }
1200 /* Do application processor initialization */
1201 KeApplicationProcessorInit();
1202 PsApplicationProcessorInit();
1203 KeLowerIrql(PASSIVE_LEVEL);
1204 PsIdleThreadMain(NULL);
1205 KeBugCheck(0);
1206 for(;;);
1207 }
1208
1209 VOID
1210 _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
1211 /*
1212 * FUNCTION: Called by the boot loader to start the kernel
1213 * ARGUMENTS:
1214 * LoaderBlock = Pointer to boot parameters initialized by the boot
1215 * loader
1216 * NOTE: The boot parameters are stored in low memory which will become
1217 * invalid after the memory managment is initialized so we make a local copy.
1218 */
1219 {
1220 ULONG i;
1221 ULONG size;
1222 ULONG last_kernel_address;
1223 extern ULONG _bss_end__;
1224 ULONG HalBase;
1225 ULONG DriverBase;
1226 ULONG DriverSize;
1227
1228 /* Low level architecture specific initialization */
1229 KeInit1();
1230
1231 /*
1232 * Copy the parameters to a local buffer because lowmem will go away
1233 */
1234 memcpy (&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
1235 memcpy (&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
1236 sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
1237 KeLoaderBlock.ModsCount++;
1238 KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
1239
1240 /*
1241 * FIXME: Preliminary hack!!!! Add boot device to beginning of command line.
1242 * This should be done by the boot loader.
1243 */
1244 strcpy (KeLoaderCommandLine,
1245 "multi(0)disk(0)rdisk(0)partition(1)\\reactos /DEBUGPORT=SCREEN");
1246 strcat (KeLoaderCommandLine, (PUCHAR)KeLoaderBlock.CommandLine);
1247
1248 KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
1249 strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
1250 KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
1251 KeLoaderModules[0].ModStart = 0xC0000000;
1252 KeLoaderModules[0].ModEnd = PAGE_ROUND_UP((ULONG)&_bss_end__);
1253 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
1254 {
1255 strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
1256 KeLoaderModules[i].ModStart -= 0x200000;
1257 KeLoaderModules[i].ModStart += 0xc0000000;
1258 KeLoaderModules[i].ModEnd -= 0x200000;
1259 KeLoaderModules[i].ModEnd += 0xc0000000;
1260 KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
1261 }
1262
1263 #ifdef HAL_DBG
1264 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
1265 #endif
1266
1267 HalBase = KeLoaderModules[1].ModStart;
1268 DriverBase = KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd;
1269
1270 /*
1271 * Process hal.dll
1272 */
1273 LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)0xC0000000, &DriverSize);
1274
1275 LdrHalBase = (ULONG_PTR)DriverBase;
1276 last_kernel_address = DriverBase + DriverSize;
1277
1278 /*
1279 * Process ntoskrnl.exe
1280 */
1281 LdrSafePEProcessModule((PVOID)0xC0000000, (PVOID)0xC0000000, (PVOID)DriverBase, &DriverSize);
1282
1283 FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000;
1284 LastKrnlPhysAddr = last_kernel_address - 0xc0000000 + 0x200000;
1285 LastKernelAddress = last_kernel_address;
1286
1287 #ifndef ACPI
1288 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
1289 KeLoaderBlock.Flags &= ~MB_FLAGS_MMAP_INFO;
1290 #endif
1291
1292 KeMemoryMapRangeCount = 0;
1293 if (KeLoaderBlock.Flags & MB_FLAGS_MMAP_INFO)
1294 {
1295 /* We have a memory map from the nice BIOS */
1296 size = *((PULONG)(KeLoaderBlock.MmapAddr - sizeof(ULONG)));
1297 i = 0;
1298 while (i < KeLoaderBlock.MmapLength)
1299 {
1300 memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
1301 (PVOID)(KeLoaderBlock.MmapAddr + i),
1302 sizeof(ADDRESS_RANGE));
1303 KeMemoryMapRangeCount++;
1304 i += size;
1305 }
1306 }
1307
1308 KiSystemStartup(1);
1309 }
1310
1311 /* EOF */
1312