- Fix KiDispatchException to unmask KI_EXCEPTION_INTERNAL when setting the exception...
[reactos.git] / reactos / boot / freeldr / freeldr / reactos / reactos.c
1 /*
2 * FreeLoader
3 *
4 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
5 * Copyright (C) 2005 Alex Ionescu <alex@relsoft.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include <freeldr.h>
23
24 #define NDEBUG
25 #include <debug.h>
26
27 ROS_LOADER_PARAMETER_BLOCK LoaderBlock;
28 char reactos_kernel_cmdline[255]; // Command line passed to kernel
29 LOADER_MODULE reactos_modules[64]; // Array to hold boot module info loaded for the kernel
30 char reactos_module_strings[64][256]; // Array to hold module names
31 unsigned long reactos_memory_map_descriptor_size;
32 memory_map_t reactos_memory_map[32]; // Memory map
33 ARC_DISK_SIGNATURE reactos_arc_disk_info[32]; // ARC Disk Information
34 char reactos_arc_strings[32][256];
35 unsigned long reactos_disk_count = 0;
36 CHAR szHalName[255];
37 CHAR szBootPath[255];
38 static CHAR szLoadingMsg[] = "Loading ReactOS...";
39 BOOLEAN FrLdrBootType;
40 extern ULONG_PTR KernelBase, KernelEntry;
41
42 PVOID
43 NTAPI
44 FrLdrLoadImage(IN PCHAR szFileName,
45 IN INT nPos,
46 IN ULONG ImageType)
47 {
48 PFILE FilePointer;
49 PCHAR szShortName;
50 CHAR szBuffer[256], szFullPath[256];
51 PVOID LoadBase;
52
53 /* Check if this the HAL being loaded */
54 if (!_stricmp(szFileName, "hal.dll"))
55 {
56 /* Use the boot.ini name instead */
57 szFileName = szHalName;
58 }
59
60 /* Extract filename without path */
61 szShortName = strrchr(szFileName, '\\');
62 if (!szShortName)
63 {
64 /* No path, leave it alone */
65 szShortName = szFileName;
66
67 /* Which means we need to build a path now */
68 strcpy(szBuffer, szFileName);
69 strcpy(szFullPath, szBootPath);
70 if (!FrLdrBootType)
71 {
72 strcat(szFullPath, "SYSTEM32\\DRIVERS\\");
73 }
74 else
75 {
76 strcat(szFullPath, "\\");
77 }
78 strcat(szFullPath, szBuffer);
79 szFileName = szFullPath;
80 }
81 else
82 {
83 /* Skip the path */
84 szShortName = szShortName + 1;
85 }
86
87 /* Open the image */
88 FilePointer = FsOpenFile(szFileName);
89 if (!FilePointer)
90 {
91 /* Return failure on the short name */
92 strcpy(szBuffer, szShortName);
93 strcat(szBuffer, " not found.");
94 UiMessageBox(szBuffer);
95 return FALSE;
96 }
97
98 /* Update the status bar with the current file */
99 strcpy(szBuffer, "Reading ");
100 strcat(szBuffer, szShortName);
101 UiDrawStatusText(szBuffer);
102
103 /* Do the actual loading */
104 LoadBase = FrLdrMapImage(FilePointer, szShortName, ImageType);
105
106 /* Update Processbar and return success */
107 if (!FrLdrBootType) UiDrawProgressBarCenter(nPos, 100, szLoadingMsg);
108 return LoadBase;
109 }
110
111 static BOOLEAN
112 FrLdrLoadNlsFile(PCSTR szFileName,
113 PCSTR szModuleName)
114 {
115 PFILE FilePointer;
116 CHAR value[256];
117 LPSTR p;
118
119 /* Open the Driver */
120 FilePointer = FsOpenFile(szFileName);
121
122 /* Make sure we did */
123 if (FilePointer == NULL) {
124
125 /* Fail if file wasn't opened */
126 strcpy(value, szFileName);
127 strcat(value, " not found.");
128 UiMessageBox(value);
129 return(FALSE);
130 }
131
132 /* Update the status bar with the current file */
133 strcpy(value, "Reading ");
134 p = strrchr(szFileName, '\\');
135 if (p == NULL) {
136
137 strcat(value, szFileName);
138
139 } else {
140
141 strcat(value, p + 1);
142 }
143 UiDrawStatusText(value);
144
145 /* Load the driver */
146 FrLdrLoadModule(FilePointer, szModuleName, NULL);
147 return(TRUE);
148 }
149
150 static BOOLEAN
151 FrLdrLoadNlsFiles(PCHAR szSystemRoot,
152 PCHAR szErrorOut)
153 {
154 LONG rc = ERROR_SUCCESS;
155 FRLDRHKEY hKey;
156 WCHAR szIdBuffer[80];
157 WCHAR szNameBuffer[80];
158 CHAR szFileName[256];
159 ULONG BufferSize;
160
161 /* open the codepage key */
162 rc = RegOpenKey(NULL,
163 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
164 &hKey);
165 if (rc != ERROR_SUCCESS) {
166
167 strcpy(szErrorOut, "Couldn't open CodePage registry key");
168 return(FALSE);
169 }
170
171 /* get ANSI codepage */
172 BufferSize = sizeof(szIdBuffer);
173 rc = RegQueryValue(hKey, L"ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
174 if (rc != ERROR_SUCCESS) {
175
176 strcpy(szErrorOut, "Couldn't get ACP NLS setting");
177 return(FALSE);
178 }
179
180 BufferSize = sizeof(szNameBuffer);
181 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
182 if (rc != ERROR_SUCCESS) {
183
184 strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
185 return(FALSE);
186 }
187
188 /* load ANSI codepage table */
189 sprintf(szFileName,"%ssystem32\\%S", szSystemRoot, szNameBuffer);
190 DbgPrint((DPRINT_REACTOS, "ANSI file: %s\n", szFileName));
191 if (!FrLdrLoadNlsFile(szFileName, "ansi.nls")) {
192
193 strcpy(szErrorOut, "Couldn't load ansi.nls");
194 return(FALSE);
195 }
196
197 /* get OEM codepage */
198 BufferSize = sizeof(szIdBuffer);
199 rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
200 if (rc != ERROR_SUCCESS) {
201
202 strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
203 return(FALSE);
204 }
205
206 BufferSize = sizeof(szNameBuffer);
207 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
208 if (rc != ERROR_SUCCESS) {
209
210 strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
211 return(FALSE);
212 }
213
214 /* load OEM codepage table */
215 sprintf(szFileName, "%ssystem32\\%S", szSystemRoot, szNameBuffer);
216 DbgPrint((DPRINT_REACTOS, "Oem file: %s\n", szFileName));
217 if (!FrLdrLoadNlsFile(szFileName, "oem.nls")) {
218
219 strcpy(szErrorOut, "Couldn't load oem.nls");
220 return(FALSE);
221 }
222
223 /* open the language key */
224 rc = RegOpenKey(NULL,
225 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
226 &hKey);
227 if (rc != ERROR_SUCCESS) {
228
229 strcpy(szErrorOut, "Couldn't open Language registry key");
230 return(FALSE);
231 }
232
233 /* get the Unicode case table */
234 BufferSize = sizeof(szIdBuffer);
235 rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize);
236 if (rc != ERROR_SUCCESS) {
237
238 strcpy(szErrorOut, "Couldn't get Language Default setting");
239 return(FALSE);
240 }
241
242 BufferSize = sizeof(szNameBuffer);
243 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
244 if (rc != ERROR_SUCCESS) {
245
246 strcpy(szErrorOut, "Language Default setting exists, but isn't readable");
247 return(FALSE);
248 }
249
250 /* load Unicode case table */
251 sprintf(szFileName, "%ssystem32\\%S", szSystemRoot, szNameBuffer);
252 DbgPrint((DPRINT_REACTOS, "Casemap file: %s\n", szFileName));
253 if (!FrLdrLoadNlsFile(szFileName, "casemap.nls")) {
254
255 strcpy(szErrorOut, "casemap.nls");
256 return(FALSE);
257 }
258
259 return(TRUE);
260 }
261
262 static VOID
263 FrLdrLoadBootDrivers(PCHAR szSystemRoot,
264 INT nPos)
265 {
266 LONG rc = 0;
267 FRLDRHKEY hGroupKey, hOrderKey, hServiceKey, hDriverKey;
268 WCHAR GroupNameBuffer[512];
269 WCHAR ServiceName[256];
270 ULONG OrderList[128];
271 ULONG BufferSize;
272 ULONG Index;
273 ULONG TagIndex;
274 LPWSTR GroupName;
275
276 ULONG ValueSize;
277 ULONG ValueType;
278 ULONG StartValue;
279 ULONG TagValue;
280 WCHAR DriverGroup[256];
281 ULONG DriverGroupSize;
282
283 CHAR ImagePath[256];
284 WCHAR TempImagePath[256];
285
286 /* get 'service group order' key */
287 rc = RegOpenKey(NULL,
288 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
289 &hGroupKey);
290 if (rc != ERROR_SUCCESS) {
291
292 DbgPrint((DPRINT_REACTOS, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc));
293 return;
294 }
295
296 /* get 'group order list' key */
297 rc = RegOpenKey(NULL,
298 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
299 &hOrderKey);
300 if (rc != ERROR_SUCCESS) {
301
302 DbgPrint((DPRINT_REACTOS, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc));
303 return;
304 }
305
306 /* enumerate drivers */
307 rc = RegOpenKey(NULL,
308 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
309 &hServiceKey);
310 if (rc != ERROR_SUCCESS) {
311
312 DbgPrint((DPRINT_REACTOS, "Failed to open the 'Services' key (rc %d)\n", (int)rc));
313 return;
314 }
315
316 /* Get the Name Group */
317 BufferSize = sizeof(GroupNameBuffer);
318 rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize);
319 DbgPrint((DPRINT_REACTOS, "RegQueryValue(): rc %d\n", (int)rc));
320 if (rc != ERROR_SUCCESS) return;
321 DbgPrint((DPRINT_REACTOS, "BufferSize: %d \n", (int)BufferSize));
322 DbgPrint((DPRINT_REACTOS, "GroupNameBuffer: '%S' \n", GroupNameBuffer));
323
324 /* Loop through each group */
325 GroupName = GroupNameBuffer;
326 while (*GroupName) {
327 DbgPrint((DPRINT_REACTOS, "Driver group: '%S'\n", GroupName));
328
329 /* Query the Order */
330 BufferSize = sizeof(OrderList);
331 rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize);
332 if (rc != ERROR_SUCCESS) OrderList[0] = 0;
333
334 /* enumerate all drivers */
335 for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) {
336
337 Index = 0;
338
339 while (TRUE) {
340
341 /* Get the Driver's Name */
342 ValueSize = sizeof(ServiceName);
343 rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
344 DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc));
345
346 /* Makre sure it's valid, and check if we're done */
347 if (rc == ERROR_NO_MORE_ITEMS) break;
348 if (rc != ERROR_SUCCESS) return;
349 DbgPrint((DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName));
350
351 /* open driver Key */
352 rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
353 if (rc == ERROR_SUCCESS)
354 {
355 /* Read the Start Value */
356 ValueSize = sizeof(ULONG);
357 rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
358 if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
359 DbgPrint((DPRINT_REACTOS, " Start: %x \n", (int)StartValue));
360
361 /* Read the Tag */
362 ValueSize = sizeof(ULONG);
363 rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
364 if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
365 DbgPrint((DPRINT_REACTOS, " Tag: %x \n", (int)TagValue));
366
367 /* Read the driver's group */
368 DriverGroupSize = sizeof(DriverGroup);
369 rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
370 DbgPrint((DPRINT_REACTOS, " Group: '%S' \n", DriverGroup));
371
372 /* Make sure it should be started */
373 if ((StartValue == 0) &&
374 (TagValue == OrderList[TagIndex]) &&
375 (_wcsicmp(DriverGroup, GroupName) == 0)) {
376
377 /* Get the Driver's Location */
378 ValueSize = sizeof(TempImagePath);
379 rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
380
381 /* Write the whole path if it suceeded, else prepare to fail */
382 if (rc != ERROR_SUCCESS) {
383 DbgPrint((DPRINT_REACTOS, " ImagePath: not found\n"));
384 sprintf(ImagePath, "%s\\system32\\drivers\\%S.sys", szSystemRoot, ServiceName);
385 } else if (TempImagePath[0] != L'\\') {
386 sprintf(ImagePath, "%s%S", szSystemRoot, TempImagePath);
387 } else {
388 sprintf(ImagePath, "%S", TempImagePath);
389 DbgPrint((DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath));
390 }
391
392 DbgPrint((DPRINT_REACTOS, " Loading driver: '%s'\n", ImagePath));
393
394 /* Update the position if needed */
395 if (nPos < 100) nPos += 5;
396
397 FrLdrLoadImage(ImagePath, nPos, 2);
398
399 } else {
400
401 DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
402 ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName));
403 }
404 }
405
406 Index++;
407 }
408 }
409
410 Index = 0;
411 while (TRUE) {
412
413 /* Get the Driver's Name */
414 ValueSize = sizeof(ServiceName);
415 rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
416
417 DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc));
418 if (rc == ERROR_NO_MORE_ITEMS) break;
419 if (rc != ERROR_SUCCESS) return;
420 DbgPrint((DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName));
421
422 /* open driver Key */
423 rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
424 if (rc == ERROR_SUCCESS)
425 {
426 /* Read the Start Value */
427 ValueSize = sizeof(ULONG);
428 rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
429 if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
430 DbgPrint((DPRINT_REACTOS, " Start: %x \n", (int)StartValue));
431
432 /* Read the Tag */
433 ValueSize = sizeof(ULONG);
434 rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
435 if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
436 DbgPrint((DPRINT_REACTOS, " Tag: %x \n", (int)TagValue));
437
438 /* Read the driver's group */
439 DriverGroupSize = sizeof(DriverGroup);
440 rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
441 DbgPrint((DPRINT_REACTOS, " Group: '%S' \n", DriverGroup));
442
443 for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) {
444 if (TagValue == OrderList[TagIndex]) break;
445 }
446
447 if ((StartValue == 0) &&
448 (TagIndex > OrderList[0]) &&
449 (_wcsicmp(DriverGroup, GroupName) == 0)) {
450
451 ValueSize = sizeof(TempImagePath);
452 rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
453 if (rc != ERROR_SUCCESS) {
454 DbgPrint((DPRINT_REACTOS, " ImagePath: not found\n"));
455 sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", szSystemRoot, ServiceName);
456 } else if (TempImagePath[0] != L'\\') {
457 sprintf(ImagePath, "%s%S", szSystemRoot, TempImagePath);
458 } else {
459 sprintf(ImagePath, "%S", TempImagePath);
460 DbgPrint((DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath));
461 }
462 DbgPrint((DPRINT_REACTOS, " Loading driver: '%s'\n", ImagePath));
463
464 if (nPos < 100) nPos += 5;
465
466 FrLdrLoadImage(ImagePath, nPos, 2);
467
468 } else {
469
470 DbgPrint((DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
471 ServiceName, StartValue, TagValue, DriverGroup, GroupName));
472 }
473 }
474
475 Index++;
476 }
477
478 /* Move to the next group name */
479 GroupName = GroupName + wcslen(GroupName) + 1;
480 }
481 }
482
483 VOID
484 LoadAndBootReactOS(PCSTR OperatingSystemName)
485 {
486 PFILE FilePointer;
487 CHAR name[255];
488 CHAR value[255];
489 CHAR SystemPath[255];
490 CHAR szKernelName[255];
491 CHAR szFileName[255];
492 CHAR MsgBuffer[256];
493 ULONG SectionId;
494 PIMAGE_NT_HEADERS NtHeader;
495 PVOID LoadBase;
496
497 ULONG_PTR Base;
498 ULONG Size;
499
500 extern BOOLEAN AcpiPresent;
501
502 //
503 // Open the operating system section
504 // specified in the .ini file
505 //
506 if (!IniOpenSection(OperatingSystemName, &SectionId))
507 {
508 sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);
509 UiMessageBox(MsgBuffer);
510 return;
511 }
512
513 UiDrawBackdrop();
514 UiDrawStatusText("Detecting Hardware...");
515 UiDrawProgressBarCenter(1, 100, szLoadingMsg);
516
517 /*
518 * Setup multiboot information structure
519 */
520 LoaderBlock.CommandLine = reactos_kernel_cmdline;
521 LoaderBlock.ModsCount = 0;
522 LoaderBlock.ModsAddr = reactos_modules;
523 LoaderBlock.DrivesAddr = reactos_arc_disk_info;
524 LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)(PVOID)&reactos_memory_map, 32) * sizeof(memory_map_t);
525 if (LoaderBlock.MmapLength)
526 {
527 ULONG i;
528
529 LoaderBlock.MmapAddr = (unsigned long)&reactos_memory_map;
530 reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
531 for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
532 {
533 if (BiosMemoryUsable == reactos_memory_map[i].type &&
534 0 == reactos_memory_map[i].base_addr_low)
535 {
536 LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024;
537 if (640 < LoaderBlock.MemLower)
538 {
539 LoaderBlock.MemLower = 640;
540 }
541 }
542 if (BiosMemoryUsable == reactos_memory_map[i].type &&
543 reactos_memory_map[i].base_addr_low <= 1024 * 1024 &&
544 1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low)
545 {
546 LoaderBlock.MemHigher = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024 - 1024;
547 }
548 }
549 }
550
551 /*
552 * Initialize the registry
553 */
554 RegInitializeRegistry();
555
556 /*
557 * Make sure the system path is set in the .ini file
558 */
559 if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))
560 {
561 UiMessageBox("System path not specified for selected operating system.");
562 return;
563 }
564
565 /*
566 * Special case for Live CD.
567 */
568 if (!_stricmp(SystemPath, "LiveCD"))
569 {
570 /* Normalize */
571 MachDiskGetBootPath(SystemPath, sizeof(SystemPath));
572 strcat(SystemPath, "\\reactos");
573 strcat(strcpy(reactos_kernel_cmdline, SystemPath),
574 " /MININT");
575 }
576 else
577 {
578 if (! MachDiskNormalizeSystemPath(SystemPath,
579 sizeof(SystemPath)))
580 {
581 UiMessageBox("Invalid system path");
582 return;
583 }
584 /* copy system path into kernel command line */
585 strcpy(reactos_kernel_cmdline, SystemPath);
586 }
587
588 /*
589 * Read the optional kernel parameters (if any)
590 */
591 if (IniReadSettingByName(SectionId, "Options", value, sizeof(value)))
592 {
593 strcat(reactos_kernel_cmdline, " ");
594 strcat(reactos_kernel_cmdline, value);
595 }
596
597 /*
598 * Detect hardware
599 */
600 MachHwDetect();
601 UiDrawProgressBarCenter(5, 100, szLoadingMsg);
602
603 if (AcpiPresent) LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE;
604 LoaderBlock.DrivesCount = reactos_disk_count;
605
606 UiDrawStatusText("Loading...");
607
608 /*
609 * Try to open system drive
610 */
611 if (!FsOpenSystemVolume(SystemPath, szBootPath, &LoaderBlock.BootDevice))
612 {
613 UiMessageBox("Failed to open boot drive.");
614 return;
615 }
616
617 /* append a backslash */
618 if ((strlen(szBootPath)==0) ||
619 szBootPath[strlen(szBootPath)] != '\\')
620 strcat(szBootPath, "\\");
621
622 DbgPrint((DPRINT_REACTOS,"SystemRoot: '%s'\n", szBootPath));
623
624 /*
625 * Find the kernel image name
626 * and try to load the kernel off the disk
627 */
628 if(IniReadSettingByName(SectionId, "Kernel", value, sizeof(value)))
629 {
630 /*
631 * Set the name and
632 */
633 if (value[0] == '\\')
634 {
635 strcpy(szKernelName, value);
636 }
637 else
638 {
639 strcpy(szKernelName, szBootPath);
640 strcat(szKernelName, "SYSTEM32\\");
641 strcat(szKernelName, value);
642 }
643 }
644 else
645 {
646 strcpy(value, "NTOSKRNL.EXE");
647 strcpy(szKernelName, szBootPath);
648 strcat(szKernelName, "SYSTEM32\\");
649 strcat(szKernelName, value);
650 }
651
652 /*
653 * Find the HAL image name
654 * and try to load the kernel off the disk
655 */
656 if(IniReadSettingByName(SectionId, "Hal", value, sizeof(value)))
657 {
658 /*
659 * Set the name and
660 */
661 if (value[0] == '\\')
662 {
663 strcpy(szHalName, value);
664 }
665 else
666 {
667 strcpy(szHalName, szBootPath);
668 strcat(szHalName, "SYSTEM32\\");
669 strcat(szHalName, value);
670 }
671 }
672 else
673 {
674 strcpy(value, "HAL.DLL");
675 strcpy(szHalName, szBootPath);
676 strcat(szHalName, "SYSTEM32\\");
677 strcat(szHalName, value);
678 }
679
680 /* Load the kernel */
681 LoadBase = FrLdrLoadImage(szKernelName, 5, 1);
682 if (!LoadBase) return;
683
684 /* Get the NT header, kernel base and kernel entry */
685 NtHeader = RtlImageNtHeader(LoadBase);
686 KernelBase = NtHeader->OptionalHeader.ImageBase;
687 KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
688 LoaderBlock.KernelBase = KernelBase;
689
690 /*
691 * Load the System hive from disk
692 */
693 strcpy(szFileName, szBootPath);
694 strcat(szFileName, "SYSTEM32\\CONFIG\\SYSTEM");
695
696 DbgPrint((DPRINT_REACTOS, "SystemHive: '%s'", szFileName));
697
698 FilePointer = FsOpenFile(szFileName);
699 if (FilePointer == NULL)
700 {
701 UiMessageBox("Could not find the System hive!");
702 return;
703 }
704
705 /*
706 * Update the status bar with the current file
707 */
708 strcpy(name, "Reading ");
709 strcat(name, value);
710 while (strlen(name) < 80)
711 strcat(name, " ");
712 UiDrawStatusText(name);
713
714 /*
715 * Load the System hive
716 */
717 Base = FrLdrLoadModule(FilePointer, szFileName, &Size);
718 if (Base == 0 || Size == 0)
719 {
720 UiMessageBox("Could not load the System hive!\n");
721 return;
722 }
723 DbgPrint((DPRINT_REACTOS, "SystemHive loaded at 0x%x size %u", (unsigned)Base, (unsigned)Size));
724
725 /*
726 * Import the loaded system hive
727 */
728 RegImportBinaryHive((PCHAR)Base, Size);
729
730 /*
731 * Initialize the 'CurrentControlSet' link
732 */
733 RegInitCurrentControlSet(FALSE);
734
735 UiDrawProgressBarCenter(15, 100, szLoadingMsg);
736
737 /*
738 * Export the hardware hive
739 */
740 Base = FrLdrCreateModule ("HARDWARE");
741 RegExportBinaryHive (L"\\Registry\\Machine\\HARDWARE", (PCHAR)Base, &Size);
742 FrLdrCloseModule (Base, Size);
743
744 UiDrawProgressBarCenter(20, 100, szLoadingMsg);
745
746 /*
747 * Load NLS files
748 */
749 if (!FrLdrLoadNlsFiles(szBootPath, MsgBuffer))
750 {
751 UiMessageBox(MsgBuffer);
752 return;
753 }
754 UiDrawProgressBarCenter(30, 100, szLoadingMsg);
755
756 /*
757 * Load boot drivers
758 */
759 FrLdrLoadBootDrivers(szBootPath, 40);
760 //UiUnInitialize("Booting ReactOS...");
761
762 /*
763 * Now boot the kernel
764 */
765 DiskStopFloppyMotor();
766 MachVideoPrepareForReactOS(FALSE);
767 FrLdrStartup(0x2badb002);
768 }
769
770 #undef DbgPrint
771 ULONG
772 DbgPrint(const char *Format, ...)
773 {
774 va_list ap;
775 CHAR Buffer[512];
776 ULONG Length;
777
778 va_start(ap, Format);
779
780 /* Construct a string */
781 Length = _vsnprintf(Buffer, 512, Format, ap);
782
783 /* Check if we went past the buffer */
784 if (Length == -1)
785 {
786 /* Terminate it if we went over-board */
787 Buffer[sizeof(Buffer) - 1] = '\n';
788
789 /* Put maximum */
790 Length = sizeof(Buffer);
791 }
792
793 /* Show it as a message box */
794 UiMessageBox(Buffer);
795
796 /* Cleanup and exit */
797 va_end(ap);
798 return 0;
799 }
800
801 /* EOF */