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