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