4 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
5 * Copyright (C) 2005 Alex Ionescu <alex@relsoft.net>
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.
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.
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.
25 extern ULONG PageDirectoryStart
;
26 extern ULONG PageDirectoryEnd
;
28 ROS_LOADER_PARAMETER_BLOCK LoaderBlock
;
29 char reactos_kernel_cmdline
[255]; // Command line passed to kernel
30 LOADER_MODULE reactos_modules
[64]; // Array to hold boot module info loaded for the kernel
31 char reactos_module_strings
[64][256]; // Array to hold module names
32 // Make this a single struct to guarantee that these elements are nearby in
34 reactos_mem_data_t reactos_mem_data
;
35 ARC_DISK_SIGNATURE reactos_arc_disk_info
[32]; // ARC Disk Information
36 char reactos_arc_strings
[32][256];
37 unsigned long reactos_disk_count
= 0;
38 char reactos_arc_hardware_data
[HW_MAX_ARC_HEAP_SIZE
] = {0};
43 static CHAR szLoadingMsg
[] = "Loading ReactOS...";
44 BOOLEAN FrLdrBootType
;
46 ROS_KERNEL_ENTRY_POINT KernelEntryPoint
;
49 FrLdrLoadDriver(PCHAR szFileName
,
53 CHAR value
[256], *FinalSlash
;
56 if (!_stricmp(szFileName
, "hal.dll"))
58 /* Use the boot.ini name instead */
59 szFileName
= szHalName
;
62 FinalSlash
= strrchr(szFileName
, '\\');
64 szFileName
= FinalSlash
+ 1;
67 FilePointer
= FsOpenFile(szFileName
);
69 /* Try under the system root in the main dir and drivers */
70 if (FilePointer
== NULL
)
72 strcpy(value
, SystemRoot
);
73 if(value
[strlen(value
)-1] != '\\')
75 strcat(value
, szFileName
);
76 FilePointer
= FsOpenFile(value
);
79 if (FilePointer
== NULL
)
81 strcpy(value
, SystemRoot
);
82 if(value
[strlen(value
)-1] != '\\')
84 strcat(value
, "SYSTEM32\\");
85 strcat(value
, szFileName
);
86 FilePointer
= FsOpenFile(value
);
89 if (FilePointer
== NULL
)
91 strcpy(value
, SystemRoot
);
92 if(value
[strlen(value
)-1] != '\\')
94 strcat(value
, "SYSTEM32\\DRIVERS\\");
95 strcat(value
, szFileName
);
96 FilePointer
= FsOpenFile(value
);
99 /* Make sure we did */
100 if (FilePointer
== NULL
) {
102 /* Fail if file wasn't opened */
103 strcpy(value
, szFileName
);
104 strcat(value
, " not found.");
108 /* Update the status bar with the current file */
109 strcpy(value
, "Reading ");
110 p
= strrchr(szFileName
, '\\');
113 strcat(value
, szFileName
);
117 strcat(value
, p
+ 1);
120 UiDrawStatusText(value
);
122 /* Load the driver */
123 FrLdrReadAndMapImage(FilePointer
, szFileName
, 0);
125 /* Update status and return */
126 UiDrawProgressBarCenter(nPos
, 100, szLoadingMsg
);
132 FrLdrLoadImage(IN PCHAR szFileName
,
138 CHAR szBuffer
[256], szFullPath
[256];
141 /* Extract filename without path */
142 szShortName
= strrchr(szFileName
, '\\');
145 /* No path, leave it alone */
146 szShortName
= szFileName
;
148 /* Which means we need to build a path now */
149 strcpy(szBuffer
, szFileName
);
150 strcpy(szFullPath
, szBootPath
);
153 strcat(szFullPath
, "SYSTEM32\\DRIVERS\\");
157 strcat(szFullPath
, "\\");
159 strcat(szFullPath
, szBuffer
);
160 szFileName
= szFullPath
;
165 szShortName
= szShortName
+ 1;
169 FilePointer
= FsOpenFile(szFileName
);
172 /* Return failure on the short name */
173 strcpy(szBuffer
, szShortName
);
174 strcat(szBuffer
, " not found.");
175 UiMessageBox(szBuffer
);
179 /* Update the status bar with the current file */
180 strcpy(szBuffer
, "Reading ");
181 strcat(szBuffer
, szShortName
);
182 UiDrawStatusText(szBuffer
);
184 /* Do the actual loading */
185 LoadBase
= FrLdrReadAndMapImage(FilePointer
, szShortName
, ImageType
);
187 /* Update Processbar and return success */
188 if (!FrLdrBootType
) UiDrawProgressBarCenter(nPos
, 100, szLoadingMsg
);
193 FrLdrLoadNlsFile(PCSTR szFileName
,
200 /* Open the Driver */
201 FilePointer
= FsOpenFile(szFileName
);
203 /* Make sure we did */
204 if (FilePointer
== NULL
) {
206 /* Fail if file wasn't opened */
207 strcpy(value
, szFileName
);
208 strcat(value
, " not found.");
213 /* Update the status bar with the current file */
214 strcpy(value
, "Reading ");
215 p
= strrchr(szFileName
, '\\');
218 strcat(value
, szFileName
);
222 strcat(value
, p
+ 1);
224 UiDrawStatusText(value
);
226 /* Load the driver */
227 FrLdrLoadModule(FilePointer
, szModuleName
, NULL
);
232 FrLdrLoadNlsFiles(PCHAR szSystemRoot
,
235 LONG rc
= ERROR_SUCCESS
;
237 WCHAR szIdBuffer
[80];
238 WCHAR szNameBuffer
[80];
239 CHAR szFileName
[256];
242 /* open the codepage key */
243 rc
= RegOpenKey(NULL
,
244 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
246 if (rc
!= ERROR_SUCCESS
) {
248 strcpy(szErrorOut
, "Couldn't open CodePage registry key");
252 /* get ANSI codepage */
253 BufferSize
= sizeof(szIdBuffer
);
254 rc
= RegQueryValue(hKey
, L
"ACP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
255 if (rc
!= ERROR_SUCCESS
) {
257 strcpy(szErrorOut
, "Couldn't get ACP NLS setting");
261 BufferSize
= sizeof(szNameBuffer
);
262 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)szNameBuffer
, &BufferSize
);
263 if (rc
!= ERROR_SUCCESS
) {
265 strcpy(szErrorOut
, "ACP NLS Setting exists, but isn't readable");
269 /* load ANSI codepage table */
270 sprintf(szFileName
,"%ssystem32\\%S", szSystemRoot
, szNameBuffer
);
271 DbgPrint((DPRINT_REACTOS
, "ANSI file: %s\n", szFileName
));
272 if (!FrLdrLoadNlsFile(szFileName
, "ansi.nls")) {
274 strcpy(szErrorOut
, "Couldn't load ansi.nls");
278 /* get OEM codepage */
279 BufferSize
= sizeof(szIdBuffer
);
280 rc
= RegQueryValue(hKey
, L
"OEMCP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
281 if (rc
!= ERROR_SUCCESS
) {
283 strcpy(szErrorOut
, "Couldn't get OEMCP NLS setting");
287 BufferSize
= sizeof(szNameBuffer
);
288 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)szNameBuffer
, &BufferSize
);
289 if (rc
!= ERROR_SUCCESS
) {
291 strcpy(szErrorOut
, "OEMCP NLS setting exists, but isn't readable");
295 /* load OEM codepage table */
296 sprintf(szFileName
, "%ssystem32\\%S", szSystemRoot
, szNameBuffer
);
297 DbgPrint((DPRINT_REACTOS
, "Oem file: %s\n", szFileName
));
298 if (!FrLdrLoadNlsFile(szFileName
, "oem.nls")) {
300 strcpy(szErrorOut
, "Couldn't load oem.nls");
304 /* open the language key */
305 rc
= RegOpenKey(NULL
,
306 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
308 if (rc
!= ERROR_SUCCESS
) {
310 strcpy(szErrorOut
, "Couldn't open Language registry key");
314 /* get the Unicode case table */
315 BufferSize
= sizeof(szIdBuffer
);
316 rc
= RegQueryValue(hKey
, L
"Default", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
317 if (rc
!= ERROR_SUCCESS
) {
319 strcpy(szErrorOut
, "Couldn't get Language Default setting");
323 BufferSize
= sizeof(szNameBuffer
);
324 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)szNameBuffer
, &BufferSize
);
325 if (rc
!= ERROR_SUCCESS
) {
327 strcpy(szErrorOut
, "Language Default setting exists, but isn't readable");
331 /* load Unicode case table */
332 sprintf(szFileName
, "%ssystem32\\%S", szSystemRoot
, szNameBuffer
);
333 DbgPrint((DPRINT_REACTOS
, "Casemap file: %s\n", szFileName
));
334 if (!FrLdrLoadNlsFile(szFileName
, "casemap.nls")) {
336 strcpy(szErrorOut
, "casemap.nls");
344 FrLdrLoadBootDrivers(PCHAR szSystemRoot
,
348 FRLDRHKEY hGroupKey
, hOrderKey
, hServiceKey
, hDriverKey
;
349 WCHAR GroupNameBuffer
[512];
350 WCHAR ServiceName
[256];
351 ULONG OrderList
[128];
361 WCHAR DriverGroup
[256];
362 ULONG DriverGroupSize
;
365 WCHAR TempImagePath
[256];
367 /* get 'service group order' key */
368 rc
= RegOpenKey(NULL
,
369 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
371 if (rc
!= ERROR_SUCCESS
) {
373 DbgPrint((DPRINT_REACTOS
, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc
));
377 /* get 'group order list' key */
378 rc
= RegOpenKey(NULL
,
379 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
381 if (rc
!= ERROR_SUCCESS
) {
383 DbgPrint((DPRINT_REACTOS
, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc
));
387 /* enumerate drivers */
388 rc
= RegOpenKey(NULL
,
389 L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
391 if (rc
!= ERROR_SUCCESS
) {
393 DbgPrint((DPRINT_REACTOS
, "Failed to open the 'Services' key (rc %d)\n", (int)rc
));
397 /* Get the Name Group */
398 BufferSize
= sizeof(GroupNameBuffer
);
399 rc
= RegQueryValue(hGroupKey
, L
"List", NULL
, (PUCHAR
)GroupNameBuffer
, &BufferSize
);
400 DbgPrint((DPRINT_REACTOS
, "RegQueryValue(): rc %d\n", (int)rc
));
401 if (rc
!= ERROR_SUCCESS
) return;
402 DbgPrint((DPRINT_REACTOS
, "BufferSize: %d \n", (int)BufferSize
));
403 DbgPrint((DPRINT_REACTOS
, "GroupNameBuffer: '%S' \n", GroupNameBuffer
));
405 /* Loop through each group */
406 GroupName
= GroupNameBuffer
;
408 DbgPrint((DPRINT_REACTOS
, "Driver group: '%S'\n", GroupName
));
410 /* Query the Order */
411 BufferSize
= sizeof(OrderList
);
412 rc
= RegQueryValue(hOrderKey
, GroupName
, NULL
, (PUCHAR
)OrderList
, &BufferSize
);
413 if (rc
!= ERROR_SUCCESS
) OrderList
[0] = 0;
415 /* enumerate all drivers */
416 for (TagIndex
= 1; TagIndex
<= SWAPD(OrderList
[0]); TagIndex
++) {
422 /* Get the Driver's Name */
423 ValueSize
= sizeof(ServiceName
);
424 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
);
425 DbgPrint((DPRINT_REACTOS
, "RegEnumKey(): rc %d\n", (int)rc
));
427 /* Makre sure it's valid, and check if we're done */
428 if (rc
== ERROR_NO_MORE_ITEMS
) break;
429 if (rc
!= ERROR_SUCCESS
) return;
430 DbgPrint((DPRINT_REACTOS
, "Service %d: '%S'\n", (int)Index
, ServiceName
));
432 /* open driver Key */
433 rc
= RegOpenKey(hServiceKey
, ServiceName
, &hDriverKey
);
434 if (rc
== ERROR_SUCCESS
)
436 /* Read the Start Value */
437 ValueSize
= sizeof(ULONG
);
438 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
439 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
440 DbgPrint((DPRINT_REACTOS
, " Start: %x \n", (int)StartValue
));
443 ValueSize
= sizeof(ULONG
);
444 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
445 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
446 DbgPrint((DPRINT_REACTOS
, " Tag: %x \n", (int)TagValue
));
448 /* Read the driver's group */
449 DriverGroupSize
= sizeof(DriverGroup
);
450 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
451 DbgPrint((DPRINT_REACTOS
, " Group: '%S' \n", DriverGroup
));
453 /* Make sure it should be started */
454 if ((StartValue
== 0) &&
455 (TagValue
== OrderList
[TagIndex
]) &&
456 (_wcsicmp(DriverGroup
, GroupName
) == 0)) {
458 /* Get the Driver's Location */
459 ValueSize
= sizeof(TempImagePath
);
460 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
462 /* Write the whole path if it suceeded, else prepare to fail */
463 if (rc
!= ERROR_SUCCESS
) {
464 DbgPrint((DPRINT_REACTOS
, " ImagePath: not found\n"));
465 sprintf(ImagePath
, "%s\\system32\\drivers\\%S.sys", szSystemRoot
, ServiceName
);
466 } else if (TempImagePath
[0] != L
'\\') {
467 sprintf(ImagePath
, "%s%S", szSystemRoot
, TempImagePath
);
469 sprintf(ImagePath
, "%S", TempImagePath
);
470 DbgPrint((DPRINT_REACTOS
, " ImagePath: '%s'\n", ImagePath
));
473 DbgPrint((DPRINT_REACTOS
, " Loading driver: '%s'\n", ImagePath
));
475 /* Update the position if needed */
476 if (nPos
< 100) nPos
+= 5;
478 FrLdrLoadImage(ImagePath
, nPos
, 2);
482 DbgPrint((DPRINT_REACTOS
, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
483 ServiceName
, StartValue
, TagValue
, DriverGroup
, OrderList
[TagIndex
], GroupName
));
494 /* Get the Driver's Name */
495 ValueSize
= sizeof(ServiceName
);
496 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
);
498 DbgPrint((DPRINT_REACTOS
, "RegEnumKey(): rc %d\n", (int)rc
));
499 if (rc
== ERROR_NO_MORE_ITEMS
) break;
500 if (rc
!= ERROR_SUCCESS
) return;
501 DbgPrint((DPRINT_REACTOS
, "Service %d: '%S'\n", (int)Index
, ServiceName
));
503 /* open driver Key */
504 rc
= RegOpenKey(hServiceKey
, ServiceName
, &hDriverKey
);
505 if (rc
== ERROR_SUCCESS
)
507 /* Read the Start Value */
508 ValueSize
= sizeof(ULONG
);
509 rc
= RegQueryValue(hDriverKey
, L
"Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
510 if (rc
!= ERROR_SUCCESS
) StartValue
= (ULONG
)-1;
511 DbgPrint((DPRINT_REACTOS
, " Start: %x \n", (int)StartValue
));
514 ValueSize
= sizeof(ULONG
);
515 rc
= RegQueryValue(hDriverKey
, L
"Tag", &ValueType
, (PUCHAR
)&TagValue
, &ValueSize
);
516 if (rc
!= ERROR_SUCCESS
) TagValue
= (ULONG
)-1;
517 DbgPrint((DPRINT_REACTOS
, " Tag: %x \n", (int)TagValue
));
519 /* Read the driver's group */
520 DriverGroupSize
= sizeof(DriverGroup
);
521 rc
= RegQueryValue(hDriverKey
, L
"Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
522 DbgPrint((DPRINT_REACTOS
, " Group: '%S' \n", DriverGroup
));
524 for (TagIndex
= 1; TagIndex
<= OrderList
[0]; TagIndex
++) {
525 if (TagValue
== OrderList
[TagIndex
]) break;
528 if ((StartValue
== 0) &&
529 (TagIndex
> OrderList
[0]) &&
530 (_wcsicmp(DriverGroup
, GroupName
) == 0)) {
532 ValueSize
= sizeof(TempImagePath
);
533 rc
= RegQueryValue(hDriverKey
, L
"ImagePath", NULL
, (PUCHAR
)TempImagePath
, &ValueSize
);
534 if (rc
!= ERROR_SUCCESS
) {
535 DbgPrint((DPRINT_REACTOS
, " ImagePath: not found\n"));
536 sprintf(ImagePath
, "%ssystem32\\drivers\\%S.sys", szSystemRoot
, ServiceName
);
537 } else if (TempImagePath
[0] != L
'\\') {
538 sprintf(ImagePath
, "%s%S", szSystemRoot
, TempImagePath
);
540 sprintf(ImagePath
, "%S", TempImagePath
);
541 DbgPrint((DPRINT_REACTOS
, " ImagePath: '%s'\n", ImagePath
));
543 DbgPrint((DPRINT_REACTOS
, " Loading driver: '%s'\n", ImagePath
));
545 if (nPos
< 100) nPos
+= 5;
547 FrLdrLoadImage(ImagePath
, nPos
, 2);
551 DbgPrint((DPRINT_REACTOS
, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
552 ServiceName
, StartValue
, TagValue
, DriverGroup
, GroupName
));
559 /* Move to the next group name */
560 GroupName
= GroupName
+ wcslen(GroupName
) + 1;
565 LoadAndBootReactOS(PCSTR OperatingSystemName
)
570 CHAR SystemPath
[255];
571 CHAR szKernelName
[255];
572 CHAR szFileName
[255];
575 PIMAGE_NT_HEADERS NtHeader
;
581 // Open the operating system section
582 // specified in the .ini file
584 if (!IniOpenSection(OperatingSystemName
, &SectionId
))
586 sprintf(MsgBuffer
,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName
);
587 UiMessageBox(MsgBuffer
);
592 UiDrawStatusText("Detecting Hardware...");
593 UiDrawProgressBarCenter(1, 100, szLoadingMsg
);
596 * Setup multiboot information structure
598 LoaderBlock
.CommandLine
= reactos_kernel_cmdline
;
599 LoaderBlock
.PageDirectoryStart
= (ULONG_PTR
)&PageDirectoryStart
;
600 LoaderBlock
.PageDirectoryEnd
= (ULONG_PTR
)&PageDirectoryEnd
;
601 LoaderBlock
.ModsCount
= 0;
602 LoaderBlock
.ModsAddr
= reactos_modules
;
603 LoaderBlock
.DrivesAddr
= reactos_arc_disk_info
;
604 LoaderBlock
.RdAddr
= (ULONG_PTR
)gRamDiskBase
;
605 LoaderBlock
.RdLength
= gRamDiskSize
;
606 LoaderBlock
.MmapLength
= (SIZE_T
)MachGetMemoryMap((PBIOS_MEMORY_MAP
)reactos_memory_map
, 32) * sizeof(memory_map_t
);
607 if (LoaderBlock
.MmapLength
)
610 LoaderBlock
.Flags
|= MB_FLAGS_MEM_INFO
| MB_FLAGS_MMAP_INFO
;
611 LoaderBlock
.MmapAddr
= (ULONG_PTR
)&reactos_memory_map
;
612 reactos_memory_map_descriptor_size
= sizeof(memory_map_t
); // GetBiosMemoryMap uses a fixed value of 24
613 for (i
=0; i
<(LoaderBlock
.MmapLength
/sizeof(memory_map_t
)); i
++)
617 /* Also swap from long long to high/low
618 * We also have unusable memory that will be available to kernel
619 * land. Mark it here.
621 if (BiosMemoryAcpiReclaim
== reactos_memory_map
[i
].type
)
623 reactos_memory_map
[i
].type
= BiosMemoryUsable
;
626 tmp
= reactos_memory_map
[i
].base_addr_low
;
627 reactos_memory_map
[i
].base_addr_low
= reactos_memory_map
[i
].base_addr_high
;
628 reactos_memory_map
[i
].base_addr_high
= tmp
;
629 tmp
= reactos_memory_map
[i
].length_low
;
630 reactos_memory_map
[i
].length_low
= reactos_memory_map
[i
].length_high
;
631 reactos_memory_map
[i
].length_high
= tmp
;
634 if (BiosMemoryUsable
== reactos_memory_map
[i
].type
&&
635 0 == reactos_memory_map
[i
].base_addr_low
)
637 LoaderBlock
.MemLower
= (reactos_memory_map
[i
].base_addr_low
+ reactos_memory_map
[i
].length_low
) / 1024;
638 if (640 < LoaderBlock
.MemLower
)
640 LoaderBlock
.MemLower
= 640;
643 if (BiosMemoryUsable
== reactos_memory_map
[i
].type
&&
644 reactos_memory_map
[i
].base_addr_low
<= 1024 * 1024 &&
645 1024 * 1024 <= reactos_memory_map
[i
].base_addr_low
+ reactos_memory_map
[i
].length_low
)
647 LoaderBlock
.MemHigher
= (reactos_memory_map
[i
].base_addr_low
+ reactos_memory_map
[i
].length_low
) / 1024 - 1024;
653 * Initialize the registry
655 RegInitializeRegistry();
658 * Make sure the system path is set in the .ini file
660 if (!IniReadSettingByName(SectionId
, "SystemPath", SystemPath
, sizeof(SystemPath
)))
662 UiMessageBox("System path not specified for selected operating system.");
667 * Special case for Live CD.
669 if (!_stricmp(SystemPath
, "LiveCD"))
672 MachDiskGetBootPath(SystemPath
, sizeof(SystemPath
));
673 strcat(SystemPath
, "\\reactos");
674 strcat(strcpy(reactos_kernel_cmdline
, SystemPath
),
679 if (! MachDiskNormalizeSystemPath(SystemPath
,
682 UiMessageBox("Invalid system path");
685 /* copy system path into kernel command line */
686 strcpy(reactos_kernel_cmdline
, SystemPath
);
690 * Read the optional kernel parameters (if any)
692 if (IniReadSettingByName(SectionId
, "Options", value
, sizeof(value
)))
694 strcat(reactos_kernel_cmdline
, " ");
695 strcat(reactos_kernel_cmdline
, value
);
701 LoaderBlock
.ArchExtra
= (ULONG_PTR
)MachHwDetect();
702 UiDrawProgressBarCenter(5, 100, szLoadingMsg
);
704 LoaderBlock
.DrivesCount
= reactos_disk_count
;
706 UiDrawStatusText("Loading...");
709 // If we have a ramdisk, this will switch to the ramdisk disk routines
710 // which read from memory instead of using the firmware. This has to be done
711 // after hardware detection, since hardware detection will require using the
712 // real routines in order to perform disk-detection (just because we're on a
713 // ram-boot doesn't mean the user doesn't have actual disks installed too!)
715 RamDiskSwitchFromBios();
718 * Try to open system drive
720 if (!FsOpenSystemVolume(SystemPath
, szBootPath
, &LoaderBlock
.BootDevice
))
722 UiMessageBox("Failed to open system drive.");
726 /* append a backslash */
727 if ((strlen(szBootPath
)==0) ||
728 szBootPath
[strlen(szBootPath
)] != '\\')
729 strcat(szBootPath
, "\\");
731 DbgPrint((DPRINT_REACTOS
,"SystemRoot: '%s'\n", szBootPath
));
732 strcpy(SystemRoot
, szBootPath
);
735 * Find the kernel image name
736 * and try to load the kernel off the disk
738 if(IniReadSettingByName(SectionId
, "Kernel", value
, sizeof(value
)))
743 if (value
[0] == '\\')
745 strcpy(szKernelName
, value
);
749 strcpy(szKernelName
, szBootPath
);
750 strcat(szKernelName
, "SYSTEM32\\");
751 strcat(szKernelName
, value
);
756 strcpy(value
, "NTOSKRNL.EXE");
757 strcpy(szKernelName
, szBootPath
);
758 strcat(szKernelName
, "SYSTEM32\\");
759 strcat(szKernelName
, value
);
763 * Find the HAL image name
764 * and try to load the kernel off the disk
766 if(IniReadSettingByName(SectionId
, "Hal", value
, sizeof(value
)))
771 if (value
[0] == '\\')
773 strcpy(szHalName
, value
);
777 strcpy(szHalName
, szBootPath
);
778 strcat(szHalName
, "SYSTEM32\\");
779 strcat(szHalName
, value
);
784 strcpy(value
, "HAL.DLL");
785 strcpy(szHalName
, szBootPath
);
786 strcat(szHalName
, "SYSTEM32\\");
787 strcat(szHalName
, value
);
790 /* Load the kernel */
791 LoadBase
= FrLdrLoadImage(szKernelName
, 5, 1);
792 if (!LoadBase
) return;
794 /* Get the NT header, kernel base and kernel entry */
795 NtHeader
= RtlImageNtHeader(LoadBase
);
796 KernelBase
= SWAPD(NtHeader
->OptionalHeader
.ImageBase
);
797 KernelEntryPoint
= (ROS_KERNEL_ENTRY_POINT
)(KernelBase
+ SWAPD(NtHeader
->OptionalHeader
.AddressOfEntryPoint
));
798 LoaderBlock
.KernelBase
= KernelBase
;
801 * Load the System hive from disk
803 strcpy(szFileName
, szBootPath
);
804 strcat(szFileName
, "SYSTEM32\\CONFIG\\SYSTEM");
806 DbgPrint((DPRINT_REACTOS
, "SystemHive: '%s'", szFileName
));
808 FilePointer
= FsOpenFile(szFileName
);
809 if (FilePointer
== NULL
)
811 UiMessageBox("Could not find the System hive!");
816 * Update the status bar with the current file
818 strcpy(name
, "Reading ");
820 while (strlen(name
) < 80)
822 UiDrawStatusText(name
);
825 * Load the System hive
827 Base
= FrLdrLoadModule(FilePointer
, szFileName
, &Size
);
828 if (Base
== 0 || Size
== 0)
830 UiMessageBox("Could not load the System hive!\n");
833 DbgPrint((DPRINT_REACTOS
, "SystemHive loaded at 0x%x size %u", (unsigned)Base
, (unsigned)Size
));
836 * Import the loaded system hive
838 RegImportBinaryHive((PCHAR
)Base
, Size
);
841 * Initialize the 'CurrentControlSet' link
843 RegInitCurrentControlSet(FALSE
);
845 UiDrawProgressBarCenter(15, 100, szLoadingMsg
);
847 UiDrawProgressBarCenter(20, 100, szLoadingMsg
);
852 if (!FrLdrLoadNlsFiles(szBootPath
, MsgBuffer
))
854 UiMessageBox(MsgBuffer
);
857 UiDrawProgressBarCenter(30, 100, szLoadingMsg
);
862 FrLdrLoadBootDrivers(szBootPath
, 40);
863 //UiUnInitialize("Booting ReactOS...");
866 // Perform architecture-specific pre-boot configuration
868 MachPrepareForReactOS(FALSE
);
871 // Setup paging and jump to kernel
873 FrLdrStartup(0x2badb002);
879 DbgPrint(const char *Format
, ...)
885 va_start(ap
, Format
);
887 /* Construct a string */
888 Length
= _vsnprintf(Buffer
, 512, Format
, ap
);
890 /* Check if we went past the buffer */
893 /* Terminate it if we went over-board */
894 Buffer
[sizeof(Buffer
) - 1] = '\n';
897 Length
= sizeof(Buffer
);
900 /* Show it as a message box */
901 UiMessageBox(Buffer
);
903 /* Cleanup and exit */
908 VOID
DebugPrintChar(UCHAR Character
);
911 DbgPrint(const char *Format
, ...)
918 va_start(ap
, Format
);
920 /* Construct a string */
921 Length
= _vsnprintf(Buffer
, 512, Format
, ap
);
923 /* Check if we went past the buffer */
926 /* Terminate it if we went over-board */
927 Buffer
[sizeof(Buffer
) - 1] = '\n';
930 Length
= sizeof(Buffer
);
935 DebugPrintChar(*ptr
++);