51176716fcf07bea913b20ae055a17facc5c3e79
[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.120 2002/05/02 23:45:33 dwelch 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 <internal/v86m.h>
45 #include <internal/kd.h>
46 #include <internal/trap.h>
47 #include "../dbg/kdb.h"
48 #include <internal/registry.h>
49 #include <reactos/bugcodes.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
401 static VOID
402 InitSystemSharedUserPage (PCSZ ParameterLine)
403 {
404 UNICODE_STRING ArcDeviceName;
405 UNICODE_STRING ArcName;
406 UNICODE_STRING BootPath;
407 UNICODE_STRING DriveDeviceName;
408 UNICODE_STRING DriveName;
409 WCHAR DriveNameBuffer[20];
410 PCHAR ParamBuffer;
411 PWCHAR ArcNameBuffer;
412 PCHAR p;
413 NTSTATUS Status;
414 ULONG Length;
415 OBJECT_ATTRIBUTES ObjectAttributes;
416 HANDLE Handle;
417 ULONG i;
418 BOOLEAN BootDriveFound;
419
420 /*
421 * NOTE:
422 * The shared user page has been zeroed-out right after creation.
423 * There is NO need to do this again.
424 */
425
426 SharedUserData->NtProductType = NtProductWinNt;
427
428 BootDriveFound = FALSE;
429
430 /*
431 * Retrieve the current dos system path
432 * (e.g.: C:\reactos) from the given arc path
433 * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
434 * Format: "<arc_name>\<path> [options...]"
435 */
436
437 /* create local parameter line copy */
438 ParamBuffer = ExAllocatePool (PagedPool, 256);
439 strcpy (ParamBuffer, (char *)ParameterLine);
440 DPRINT("%s\n", ParamBuffer);
441
442 /* cut options off */
443 p = strchr (ParamBuffer, ' ');
444 if (p)
445 {
446 *p = 0;
447 }
448 DPRINT("%s\n", ParamBuffer);
449
450 /* extract path */
451 p = strchr (ParamBuffer, '\\');
452 if (p)
453 {
454 DPRINT("Boot path: %s\n", p);
455 RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
456 *p = 0;
457 }
458 else
459 {
460 DPRINT("Boot path: %s\n", "\\");
461 RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
462 }
463 DPRINT("Arc name: %s\n", ParamBuffer);
464
465 /* Only arc name left - build full arc name */
466 ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
467 swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer);
468 RtlInitUnicodeString (&ArcName, ArcNameBuffer);
469 DPRINT("Arc name: %wZ\n", &ArcName);
470
471 /* free ParamBuffer */
472 ExFreePool (ParamBuffer);
473
474 /* allocate arc device name string */
475 ArcDeviceName.Length = 0;
476 ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR);
477 ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
478
479 InitializeObjectAttributes (&ObjectAttributes,
480 &ArcName,
481 0,
482 NULL,
483 NULL);
484
485 Status = NtOpenSymbolicLinkObject (&Handle,
486 SYMBOLIC_LINK_ALL_ACCESS,
487 &ObjectAttributes);
488 RtlFreeUnicodeString (&ArcName);
489 if (!NT_SUCCESS(Status))
490 {
491 RtlFreeUnicodeString (&BootPath);
492 RtlFreeUnicodeString (&ArcDeviceName);
493 CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n",
494 Status);
495
496 KeBugCheck (0x0);
497 }
498
499 Status = NtQuerySymbolicLinkObject (Handle,
500 &ArcDeviceName,
501 &Length);
502 NtClose (Handle);
503 if (!NT_SUCCESS(Status))
504 {
505 RtlFreeUnicodeString (&BootPath);
506 RtlFreeUnicodeString (&ArcDeviceName);
507 CPRINT("NtQuerySymbolicObject() failed (Status %x)\n",
508 Status);
509
510 KeBugCheck (0x0);
511 }
512 DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
513
514
515 /* allocate device name string */
516 DriveDeviceName.Length = 0;
517 DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
518 DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
519
520 for (i = 0; i < 26; i++)
521 {
522 swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
523 RtlInitUnicodeString (&DriveName,
524 DriveNameBuffer);
525
526 InitializeObjectAttributes (&ObjectAttributes,
527 &DriveName,
528 0,
529 NULL,
530 NULL);
531
532 Status = NtOpenSymbolicLinkObject (&Handle,
533 SYMBOLIC_LINK_ALL_ACCESS,
534 &ObjectAttributes);
535 if (!NT_SUCCESS(Status))
536 {
537 DPRINT("Failed to open link %wZ\n",
538 &DriveName);
539 continue;
540 }
541
542 Status = NtQuerySymbolicLinkObject (Handle,
543 &DriveDeviceName,
544 &Length);
545 if (!NT_SUCCESS(Status))
546 {
547 DPRINT("Failed query open link %wZ\n",
548 &DriveName);
549 continue;
550 }
551 DPRINT("Opened link: %wZ ==> %wZ\n",
552 &DriveName, &DriveDeviceName);
553
554 if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE))
555 {
556 DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
557 swprintf(SharedUserData->NtSystemRoot,
558 L"%C:%wZ", 'A' + i, &BootPath);
559
560 BootDriveFound = TRUE;
561 }
562
563 NtClose (Handle);
564 }
565
566 RtlFreeUnicodeString (&BootPath);
567 RtlFreeUnicodeString (&DriveDeviceName);
568 RtlFreeUnicodeString (&ArcDeviceName);
569
570 DPRINT("DosDeviceMap: 0x%x\n", SharedUserData->DosDeviceMap);
571
572 if (BootDriveFound == FALSE)
573 {
574 DbgPrint("No system drive found!\n");
575 KeBugCheck (0x0);
576 }
577 }
578
579 #ifndef NDEBUG
580
581 VOID DumpBIOSMemoryMap(VOID)
582 {
583 ULONG i;
584
585 DbgPrint("Dumping BIOS memory map:\n");
586 DbgPrint("Memory map base: %d\n", KeLoaderBlock.MmapAddr);
587 DbgPrint("Memory map size: %d\n", KeLoaderBlock.MmapLength);
588 DbgPrint("Address range count: %d\n", KeMemoryMapRangeCount);
589 for (i = 0; i < KeMemoryMapRangeCount; i++)
590 {
591 DbgPrint("Range: Base (%08X) Length (%08X) Type (%02X)\n",
592 KeMemoryMap[i].BaseAddrLow,
593 KeMemoryMap[i].LengthLow,
594 KeMemoryMap[i].Type);
595 }
596 for (;;);
597 }
598
599 #endif /* !NDEBUG */
600
601 #if 1
602 // SEH Test
603
604 static ULONG Scratch;
605
606 EXCEPTION_DISPOSITION
607 ExpUnhandledException1(
608 PEXCEPTION_RECORD ExceptionRecord,
609 PEXCEPTION_REGISTRATION ExceptionRegistration,
610 PCONTEXT Context,
611 PVOID DispatcherContext)
612 {
613 DbgPrint("ExpUnhandledException1() called\n");
614 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord);
615 DbgPrint(" Flags 0x%X\n", ExceptionRecord->ExceptionFlags);
616 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration);
617 DbgPrint("Context 0x%X\n", Context);
618 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext);
619
620 Context->Eax = (ULONG)&Scratch;
621
622 return ExceptionContinueExecution;
623 }
624
625
626 EXCEPTION_DISPOSITION
627 ExpUnhandledException2(
628 PEXCEPTION_RECORD ExceptionRecord,
629 PEXCEPTION_REGISTRATION ExceptionRegistration,
630 PCONTEXT Context,
631 PVOID DispatcherContext)
632 {
633 DbgPrint("ExpUnhandledException2() called\n");
634 DbgPrint("ExceptionRecord 0x%X\n", ExceptionRecord);
635 DbgPrint(" Flags 0x%X\n", ExceptionRecord->ExceptionFlags);
636 DbgPrint("ExceptionRegistration 0x%X\n", ExceptionRegistration);
637 DbgPrint("Context 0x%X\n", Context);
638 DbgPrint("DispatcherContext 0x%X\n", DispatcherContext);
639
640 #if 1
641 Context->Eax = (ULONG)&Scratch;
642
643 return ExceptionContinueExecution;
644
645 #else
646
647 return ExceptionContinueSearch;
648
649 #endif
650 }
651
652
653 #if 1
654 // Put in mingw headers
655 extern VOID
656 CDECL
657 _local_unwind2(
658 PEXCEPTION_REGISTRATION RegistrationFrame,
659 DWORD TryLevel);
660
661 extern VOID
662 CDECL
663 _global_unwind2(
664 PVOID RegistrationFrame);
665
666 extern EXCEPTION_DISPOSITION
667 CDECL
668 _except_handler2(
669 PEXCEPTION_RECORD ExceptionRecord,
670 PEXCEPTION_REGISTRATION RegistrationFrame,
671 PCONTEXT Context,
672 PVOID DispatcherContext);
673
674 extern EXCEPTION_DISPOSITION
675 CDECL
676 _except_handler3(
677 PEXCEPTION_RECORD ExceptionRecord,
678 PEXCEPTION_REGISTRATION RegistrationFrame,
679 PCONTEXT Context,
680 PVOID DispatcherContext);
681
682 #endif
683
684 PRTL_EXCEPTION_REGISTRATION
685 CurrentRER(VOID)
686 {
687 ULONG Value;
688
689 __asm__("movl %%ebp, %0\n\t" : "=a" (Value));
690
691 return((PRTL_EXCEPTION_REGISTRATION)Value) - 1;
692 }
693
694 PULONG x;
695 PRTL_EXCEPTION_REGISTRATION TestER;
696 SCOPETABLE_ENTRY ScopeTable;
697 PEXCEPTION_REGISTRATION OSPtr;
698
699
700 DWORD CDECL SEHFilterRoutine(VOID)
701 {
702 DbgPrint("Within filter routine.\n");
703 return EXCEPTION_EXECUTE_HANDLER;
704 //return EXCEPTION_CONTINUE_EXECUTION;
705 }
706
707 VOID CDECL SEHHandlerRoutine(VOID)
708 {
709 DbgPrint("Within exception handler.\n");
710 DbgPrint("System halted.\n");
711 for (;;);
712 }
713
714
715 VOID SEHTest()
716 {
717 RTL_EXCEPTION_REGISTRATION ER;
718 LPEXCEPTION_POINTERS ExceptionPointers;
719 PVOID StandardESPInFrame;
720
721 __asm__ ("movl %%esp,%%eax;" : "=a" (StandardESPInFrame));
722 DbgPrint("StandardESPInFrame: 0x%X\n", StandardESPInFrame);
723
724 ExceptionPointers = NULL;
725
726 ER.OS.handler = _except_handler3;
727 __asm__ ("movl %%fs:0,%%eax;" : "=a" (ER.OS.prev));
728 DbgPrint("ER.OS.prev: 0x%X\n", ER.OS.prev);
729
730 ER.ScopeTable = &ScopeTable;
731 DbgPrint("ER.ScopeTable: 0x%X\n", ER.ScopeTable);
732 ER.TryLevel = -1;
733 __asm__ ("movl %%ebp,%%eax;" : "=a" (ER.Ebp));
734 DbgPrint("ER.Ebp: 0x%X\n", ER.Ebp);
735
736 ScopeTable.PreviousTryLevel = -1;
737 ScopeTable.FilterRoutine = SEHFilterRoutine;
738 DbgPrint("ScopeTable.FilterRoutine: 0x%X\n", ScopeTable.FilterRoutine);
739 ScopeTable.HandlerRoutine = SEHHandlerRoutine;
740 DbgPrint("ScopeTable.HandlerRoutine: 0x%X\n", ScopeTable.HandlerRoutine);
741
742
743 OSPtr = &ER.OS;
744 DbgPrint("OSPtr: 0x%X\n", OSPtr);
745
746 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (OSPtr));
747
748 /*__try1(__except_handler3)*/ if(1) {
749 ER.TryLevel = 0; // Entered first try... block
750
751 DbgPrint("Within guarded section.\n");
752 x = (PULONG)0xf2000000; *x = 0;
753 DbgPrint("After exception.\n");
754 } /* __except1 */ if(0) {
755 }
756
757 DbgPrint("After exception2.\n");
758
759 __asm__ ("movl %0,%%eax;movl %%eax,%%fs:0;" : : "m" (ER.OS.prev));
760 //KeGetCurrentKPCR()->ExceptionList = ER.OS.prev;
761
762 DbgPrint("Exiting.\n");
763 }
764
765 #endif
766
767 VOID
768 ExpInitializeExecutive(VOID)
769 {
770 ULONG i;
771 ULONG start;
772 ULONG length;
773 PCHAR name;
774 CHAR str[50];
775
776 /*
777 * Fail at runtime if someone has changed various structures without
778 * updating the offsets used for the assembler code.
779 */
780 assert(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
781 assert(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
782 assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
783 assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
784 assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
785 assert(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
786 assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
787 assert(FIELD_OFFSET(KPROCESS, DirectoryTableBase) ==
788 KPROCESS_DIRECTORY_TABLE_BASE);
789 assert(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
790 assert(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
791 assert(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
792
793 assert(FIELD_OFFSET(KPCR, ExceptionList) == KPCR_EXCEPTION_LIST);
794 assert(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
795 assert(FIELD_OFFSET(KPCR, CurrentThread) == KPCR_CURRENT_THREAD);
796
797 LdrInit1();
798
799 KeLowerIrql(DISPATCH_LEVEL);
800
801 NtEarlyInitVdm();
802
803 MmInit1(FirstKrnlPhysAddr,
804 LastKrnlPhysAddr,
805 LastKernelAddress,
806 (PADDRESS_RANGE)&KeMemoryMap,
807 KeMemoryMapRangeCount);
808
809 /* create default nls tables */
810 RtlpInitNlsTables();
811
812 /*
813 * Initialize the kernel debugger
814 */
815 KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
816
817 MmInit2();
818 KeInit2();
819
820 KeLowerIrql(PASSIVE_LEVEL);
821
822 if (!SeInit1())
823 KeBugCheck(SECURITY_INITIALIZATION_FAILED);
824
825 ObInit();
826 PiInitProcessManager();
827
828 KdInit1();
829
830 if (KdPollBreakIn ())
831 {
832 DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
833 }
834
835 /*
836 * Display version number and copyright/warranty message
837 */
838 HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
839 KERNEL_VERSION_BUILD_STR")\n");
840 HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
841 HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
842 "Public License, and you\n");
843 HalDisplayString("are welcome to change it and/or distribute copies of it "
844 "under certain\n");
845 HalDisplayString("conditions. There is absolutely no warranty for "
846 "ReactOS.\n\n");
847
848 /* Initialize all processors */
849 KeNumberProcessors = 0;
850
851 while (!HalAllProcessorsStarted())
852 {
853 PVOID ProcessorStack;
854
855 if (KeNumberProcessors != 0)
856 {
857 KePrepareForApplicationProcessorInit(KeNumberProcessors);
858 PsPrepareForApplicationProcessorInit(KeNumberProcessors);
859 }
860 /* Allocate a stack for use when booting the processor */
861 /* FIXME: The nonpaged memory for the stack is not released after use */
862 ProcessorStack =
863 ExAllocatePool(NonPagedPool, MM_STACK_SIZE) + MM_STACK_SIZE;
864 Ki386InitialStackArray[((int)KeNumberProcessors)] =
865 (PVOID)(ProcessorStack - MM_STACK_SIZE);
866 HalInitializeProcessor(KeNumberProcessors, ProcessorStack);
867 KeNumberProcessors++;
868 }
869
870 if (KeNumberProcessors > 1)
871 {
872 sprintf(str,
873 "Found %d system processors. [%lu MB Memory]\n",
874 KeNumberProcessors,
875 (KeLoaderBlock.MemHigher + 1088)/ 1024);
876 }
877 else
878 {
879 sprintf(str,
880 "Found 1 system processor. [%lu MB Memory]\n",
881 (KeLoaderBlock.MemHigher + 1088)/ 1024);
882 }
883 HalDisplayString(str);
884
885 /*
886 * Initialize various critical subsystems
887 */
888 HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
889
890 ExInit();
891 IoInit();
892 PoInit();
893 LdrInitModuleManagement();
894 CmInitializeRegistry();
895 NtInit();
896 MmInit3();
897 CcInit();
898 KdInit2();
899
900 /* Report all resources used by hal */
901 HalReportResourceUsage();
902
903 /*
904 * Initalize services loaded at boot time
905 */
906 DPRINT("%d files loaded\n",KeLoaderBlock.ModsCount);
907 for (i=0; i < KeLoaderBlock.ModsCount; i++)
908 {
909 CPRINT("Module: '%s' at %08lx, length 0x%08lx\n",
910 KeLoaderModules[i].String,
911 KeLoaderModules[i].ModStart,
912 KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart);
913 }
914
915 /* Pass 1: load nls files */
916 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
917 {
918 name = (PCHAR)KeLoaderModules[i].String;
919 if (RtlpCheckFileNameExtension(name, ".nls"))
920 {
921 ULONG Mod2Start = 0;
922 ULONG Mod2End = 0;
923 ULONG Mod3Start = 0;
924 ULONG Mod3End = 0;
925
926 name = (PCHAR)KeLoaderModules[i+1].String;
927 if (RtlpCheckFileNameExtension(name, ".nls"))
928 {
929 Mod2Start = (ULONG)KeLoaderModules[i+1].ModStart;
930 Mod2End = (ULONG)KeLoaderModules[i+1].ModEnd;
931
932 name = (PCHAR)KeLoaderModules[i+2].String;
933 if (RtlpCheckFileNameExtension(name, ".nls"))
934 {
935 Mod3Start = (ULONG)KeLoaderModules[i+2].ModStart;
936 Mod3End = (ULONG)KeLoaderModules[i+2].ModEnd;
937 }
938 }
939
940 /* Initialize nls sections */
941 RtlpInitNlsSections((ULONG)KeLoaderModules[i].ModStart,
942 (ULONG)KeLoaderModules[i].ModEnd,
943 Mod2Start,
944 Mod2End,
945 Mod3Start,
946 Mod3End);
947 break;
948 }
949 }
950
951 /* Pass 2: load registry chunks passed in */
952 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
953 {
954 start = KeLoaderModules[i].ModStart;
955 length = KeLoaderModules[i].ModEnd - start;
956 name = (PCHAR)KeLoaderModules[i].String;
957 if (RtlpCheckFileNameExtension(name, "") ||
958 RtlpCheckFileNameExtension(name, ".hiv"))
959 {
960 CPRINT("Process registry chunk at %08lx\n", start);
961 CmImportHive((PCHAR)start, length);
962 }
963 }
964
965 /*
966 * Enter the kernel debugger before starting up the boot drivers
967 */
968 #ifdef KDBG
969 KdbEnter();
970 #endif /* KDBG */
971
972 /* Pass 3: process boot loaded drivers */
973 for (i=1; i < KeLoaderBlock.ModsCount; i++)
974 {
975 start = KeLoaderModules[i].ModStart;
976 length = KeLoaderModules[i].ModEnd - start;
977 name = (PCHAR)KeLoaderModules[i].String;
978 if (RtlpCheckFileNameExtension(name, ".sys") ||
979 RtlpCheckFileNameExtension(name, ".sym"))
980 {
981 CPRINT("Processing module '%s' at %08lx, length 0x%08lx\n",
982 name, start, length);
983 LdrProcessDriver((PVOID)start, name, length);
984 }
985 }
986
987 /* Create ARC names for boot devices */
988 IoCreateArcNames();
989
990 /* Create the SystemRoot symbolic link */
991 CPRINT("CommandLine: %s\n", (PUCHAR)KeLoaderBlock.CommandLine);
992 IoCreateSystemRootLink((PUCHAR)KeLoaderBlock.CommandLine);
993
994 #ifdef DBGPRINT_FILE_LOG
995 /* On the assumption that we can now access disks start up the debug
996 logger thread */
997 DebugLogInit2();
998 #endif /* DBGPRINT_FILE_LOG */
999
1000
1001 #if 0
1002 CreateDefaultRegistry();
1003 #endif
1004
1005 PiInitDefaultLocale();
1006
1007 /*
1008 * Start the motherboard enumerator (the HAL)
1009 */
1010 HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
1011 #if 0
1012 /*
1013 * Load boot start drivers
1014 */
1015 IopLoadBootStartDrivers();
1016 #else
1017 /*
1018 * Load Auto configured drivers
1019 */
1020 LdrLoadAutoConfigDrivers();
1021 #endif
1022 /*
1023 * Assign drive letters
1024 */
1025 IoAssignDriveLetters ((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
1026 NULL,
1027 NULL,
1028 NULL);
1029
1030 /*
1031 * Initialize shared user page:
1032 * - set dos system path, dos device map, etc.
1033 */
1034 InitSystemSharedUserPage ((PUCHAR)KeLoaderBlock.CommandLine);
1035
1036 if (!SeInit2())
1037 KeBugCheck(SECURITY1_INITIALIZATION_FAILED);
1038
1039 /*
1040 * Launch initial process
1041 */
1042 LdrLoadInitialProcess();
1043
1044 PsTerminateSystemThread(STATUS_SUCCESS);
1045 }
1046
1047
1048 VOID
1049 KiSystemStartup(BOOLEAN BootProcessor)
1050 {
1051 HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
1052
1053 if (BootProcessor)
1054 {
1055 /* Never returns */
1056 ExpInitializeExecutive();
1057 KeBugCheck(0);
1058 }
1059 /* Do application processor initialization */
1060 KeApplicationProcessorInit();
1061 PsApplicationProcessorInit();
1062 KeLowerIrql(PASSIVE_LEVEL);
1063 PsIdleThreadMain(NULL);
1064 KeBugCheck(0);
1065 for(;;);
1066 }
1067
1068 VOID
1069 _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock)
1070 /*
1071 * FUNCTION: Called by the boot loader to start the kernel
1072 * ARGUMENTS:
1073 * LoaderBlock = Pointer to boot parameters initialized by the boot
1074 * loader
1075 * NOTE: The boot parameters are stored in low memory which will become
1076 * invalid after the memory managment is initialized so we make a local copy.
1077 */
1078 {
1079 ULONG i;
1080 ULONG size;
1081 ULONG last_kernel_address;
1082 extern ULONG _bss_end__;
1083 ULONG HalBase;
1084 ULONG DriverBase;
1085 ULONG DriverSize;
1086
1087 /* Low level architecture specific initialization */
1088 KeInit1();
1089
1090 /*
1091 * Copy the parameters to a local buffer because lowmem will go away
1092 */
1093 memcpy(&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
1094 memcpy(&KeLoaderModules[1], (PVOID)KeLoaderBlock.ModsAddr,
1095 sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
1096 KeLoaderBlock.ModsCount++;
1097 KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
1098
1099 if (((PUCHAR)_LoaderBlock->CommandLine)[0] == '(')
1100 {
1101 ULONG DiskNumber, PartNumber;
1102 PCH p;
1103 CHAR Temp[256];
1104 PCH options;
1105 PCH s1;
1106
1107 if (((PUCHAR)_LoaderBlock->CommandLine)[1] == 'h' &&
1108 ((PUCHAR)_LoaderBlock->CommandLine)[2] == 'd')
1109 {
1110 DiskNumber = ((PUCHAR)_LoaderBlock->CommandLine)[3] - '0';
1111 PartNumber = ((PUCHAR)_LoaderBlock->CommandLine)[5] - '0';
1112 }
1113 strcpy(Temp, &((PUCHAR)_LoaderBlock->CommandLine)[7]);
1114 if ((options = strchr(Temp, ' ')) != NULL)
1115 {
1116 *options = 0;
1117 options++;
1118 }
1119 else
1120 {
1121 options = "";
1122 }
1123 if ((s1 = strrchr(Temp, '/')) != NULL)
1124 {
1125 *s1 = 0;
1126 if ((s1 = strrchr(Temp, '/')) != NULL)
1127 {
1128 *s1 = 0;
1129 }
1130 }
1131 sprintf(KeLoaderCommandLine,
1132 "multi(0)disk(0)rdisk(%ld)partition(%ld)%s %s",
1133 DiskNumber, PartNumber + 1, Temp, options);
1134
1135 p = KeLoaderCommandLine;
1136 while (*p != 0 && *p != ' ')
1137 {
1138 if ((*p) == '/')
1139 {
1140 (*p) = '\\';
1141 }
1142 p++;
1143 }
1144 DPRINT1("Command Line: %s\n", KeLoaderCommandLine);
1145 }
1146 else
1147 {
1148 strcpy(KeLoaderCommandLine, (PUCHAR)_LoaderBlock->CommandLine);
1149 }
1150 KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
1151
1152 strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
1153 KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
1154 KeLoaderModules[0].ModStart = 0xC0000000;
1155 KeLoaderModules[0].ModEnd = PAGE_ROUND_UP((ULONG)&_bss_end__);
1156 for (i = 1; i < KeLoaderBlock.ModsCount; i++)
1157 {
1158 strcpy(KeLoaderModuleStrings[i], (PUCHAR)KeLoaderModules[i].String);
1159 KeLoaderModules[i].ModStart -= 0x200000;
1160 KeLoaderModules[i].ModStart += 0xc0000000;
1161 KeLoaderModules[i].ModEnd -= 0x200000;
1162 KeLoaderModules[i].ModEnd += 0xc0000000;
1163 KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
1164 }
1165
1166 #ifdef HAL_DBG
1167 HalnInitializeDisplay((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
1168 #endif
1169
1170 HalBase = KeLoaderModules[1].ModStart;
1171 DriverBase =
1172 PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
1173
1174 /*
1175 * Process hal.dll
1176 */
1177 LdrSafePEProcessModule((PVOID)HalBase, (PVOID)DriverBase, (PVOID)0xC0000000, &DriverSize);
1178
1179 LdrHalBase = (ULONG_PTR)DriverBase;
1180 last_kernel_address = DriverBase + DriverSize;
1181
1182 /*
1183 * Process ntoskrnl.exe
1184 */
1185 LdrSafePEProcessModule((PVOID)0xC0000000, (PVOID)0xC0000000, (PVOID)DriverBase, &DriverSize);
1186
1187 FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - 0xc0000000 + 0x200000;
1188 LastKrnlPhysAddr = last_kernel_address - 0xc0000000 + 0x200000;
1189 LastKernelAddress = last_kernel_address;
1190
1191 #ifndef ACPI
1192 /* FIXME: VMware does not like it when ReactOS is using the BIOS memory map */
1193 KeLoaderBlock.Flags &= ~MB_FLAGS_MMAP_INFO;
1194 #endif
1195
1196 KeMemoryMapRangeCount = 0;
1197 if (KeLoaderBlock.Flags & MB_FLAGS_MMAP_INFO)
1198 {
1199 /* We have a memory map from the nice BIOS */
1200 size = *((PULONG)(KeLoaderBlock.MmapAddr - sizeof(ULONG)));
1201 i = 0;
1202 while (i < KeLoaderBlock.MmapLength)
1203 {
1204 memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
1205 (PVOID)(KeLoaderBlock.MmapAddr + i),
1206 sizeof(ADDRESS_RANGE));
1207 KeMemoryMapRangeCount++;
1208 i += size;
1209 }
1210 }
1211
1212 KiSystemStartup(1);
1213 }
1214
1215 /* EOF */
1216