4 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include <multiboot.h>
38 #define IsRecognizedPartition(P) \
39 ((P) == PARTITION_FAT_12 || \
40 (P) == PARTITION_FAT_16 || \
41 (P) == PARTITION_HUGE || \
42 (P) == PARTITION_IFS || \
43 (P) == PARTITION_FAT32 || \
44 (P) == PARTITION_FAT32_XINT13 || \
45 (P) == PARTITION_XINT13)
48 LoadKernel(PCHAR szFileName
, int nPos
)
54 szShortName
= strrchr(szFileName
, '\\');
55 if (szShortName
== NULL
)
56 szShortName
= szFileName
;
58 szShortName
= szShortName
+ 1;
60 FilePointer
= FsOpenFile(szFileName
);
61 if (FilePointer
== NULL
)
63 strcpy(szBuffer
, szShortName
);
64 strcat(szBuffer
, " not found.");
65 UiMessageBox(szBuffer
);
70 * Update the status bar with the current file
72 strcpy(szBuffer
, "Reading ");
73 strcat(szBuffer
, szShortName
);
74 UiDrawStatusText(szBuffer
);
79 MultiBootLoadKernel(FilePointer
);
81 UiDrawProgressBarCenter(nPos
, 100, "Loading ReactOS...");
87 LoadSymbolFile(PCHAR szSystemRoot
,
91 CHAR SymbolFileName
[1024];
99 /* Get the path to the symbol store */
100 strcpy(SymbolFileName
, szSystemRoot
);
101 strcat(SymbolFileName
, "symbols\\");
103 /* Get the symbol filename from the module name */
104 Start
= strrchr(ModuleName
, '\\');
110 Ext
= strrchr(ModuleName
, '.');
112 Length
= Ext
- Start
;
114 Length
= strlen(Start
);
116 strncat(SymbolFileName
, Start
, Length
);
117 strcat(SymbolFileName
, ".sym");
119 FilePointer
= FsOpenFile((PCHAR
)&SymbolFileName
[0]);
120 if (FilePointer
== NULL
)
122 DbgPrint((DPRINT_REACTOS
, "Symbol file %s not loaded.\n", SymbolFileName
));
123 /* This is not critical */
127 DbgPrint((DPRINT_REACTOS
, "Symbol file %s is loaded.\n", SymbolFileName
));
130 * Update the status bar with the current file
132 strcpy(value
, "Reading ");
133 p
= strrchr(SymbolFileName
, '\\');
135 strcat(value
, SymbolFileName
);
137 strcat(value
, p
+ 1);
138 UiDrawStatusText(value
);
141 * Load the symbol file
143 MultiBootLoadModule(FilePointer
, SymbolFileName
, NULL
);
145 UiDrawProgressBarCenter(nPos
, 100, "Loading ReactOS...");
151 LoadDriver(PCHAR szFileName
, int nPos
)
157 FilePointer
= FsOpenFile(szFileName
);
158 if (FilePointer
== NULL
)
160 strcpy(value
, szFileName
);
161 strcat(value
, " not found.");
167 * Update the status bar with the current file
169 strcpy(value
, "Reading ");
170 p
= strrchr(szFileName
, '\\');
172 strcat(value
, szFileName
);
174 strcat(value
, p
+ 1);
175 UiDrawStatusText(value
);
180 MultiBootLoadModule(FilePointer
, szFileName
, NULL
);
182 UiDrawProgressBarCenter(nPos
, 100, "Loading ReactOS...");
190 LoadNlsFile(PCHAR szFileName
, PCHAR szModuleName
)
196 FilePointer
= FsOpenFile(szFileName
);
197 if (FilePointer
== NULL
)
199 strcpy(value
, szFileName
);
200 strcat(value
, " not found.");
206 * Update the status bar with the current file
208 strcpy(value
, "Reading ");
209 p
= strrchr(szFileName
, '\\');
211 strcat(value
, szFileName
);
213 strcat(value
, p
+ 1);
214 UiDrawStatusText(value
);
219 MultiBootLoadModule(FilePointer
, szModuleName
, NULL
);
227 LoadBootDrivers(PCHAR szSystemRoot
, int nPos
)
230 HKEY hGroupKey
, hServiceKey
, hDriverKey
;
231 char ValueBuffer
[512];
232 char ServiceName
[256];
240 UCHAR DriverGroup
[256];
243 UCHAR ImagePath
[256];
245 /* get 'service group order' key */
246 rc
= RegOpenKey(NULL
,
247 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
249 if (rc
!= ERROR_SUCCESS
)
251 DbgPrint((DPRINT_REACTOS
, "Failed to open the 'ServiceGroupOrder key (rc %d)\n", (int)rc
));
255 /* enumerate drivers */
256 rc
= RegOpenKey(NULL
,
257 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
259 if (rc
!= ERROR_SUCCESS
)
261 DbgPrint((DPRINT_REACTOS
, "Failed to open the 'Services' key (rc %d)\n", (int)rc
));
265 BufferSize
= sizeof(ValueBuffer
);
266 rc
= RegQueryValue(hGroupKey
, "List", NULL
, (PUCHAR
)ValueBuffer
, &BufferSize
);
267 DbgPrint((DPRINT_REACTOS
, "RegQueryValue(): rc %d\n", (int)rc
));
268 if (rc
!= ERROR_SUCCESS
)
271 DbgPrint((DPRINT_REACTOS
, "BufferSize: %d \n", (int)BufferSize
));
273 DbgPrint((DPRINT_REACTOS
, "ValueBuffer: '%s' \n", ValueBuffer
));
275 GroupName
= ValueBuffer
;
278 DbgPrint((DPRINT_REACTOS
, "Driver group: '%s'\n", GroupName
));
280 /* enumerate all drivers */
284 ValueSize
= sizeof(ValueBuffer
);
285 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
);
286 DbgPrint((DPRINT_REACTOS
, "RegEnumKey(): rc %d\n", (int)rc
));
287 if (rc
== ERROR_NO_MORE_ITEMS
)
289 if (rc
!= ERROR_SUCCESS
)
291 DbgPrint((DPRINT_REACTOS
, "Service %d: '%s'\n", (int)Index
, ServiceName
));
293 /* open driver Key */
294 rc
= RegOpenKey(hServiceKey
, ServiceName
, &hDriverKey
);
296 ValueSize
= sizeof(U32
);
297 rc
= RegQueryValue(hDriverKey
, "Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
298 DbgPrint((DPRINT_REACTOS
, " Start: %x \n", (int)StartValue
));
300 DriverGroupSize
= 256;
301 rc
= RegQueryValue(hDriverKey
, "Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
302 DbgPrint((DPRINT_REACTOS
, " Group: '%s' \n", DriverGroup
));
304 if ((StartValue
== 0) && (stricmp(DriverGroup
, GroupName
) == 0))
307 rc
= RegQueryValue(hDriverKey
,
312 if (rc
!= ERROR_SUCCESS
)
314 DbgPrint((DPRINT_REACTOS
, " ImagePath: not found\n"));
315 strcpy(ImagePath
, szSystemRoot
);
316 strcat(ImagePath
, "system32\\drivers\\");
317 strcat(ImagePath
, ServiceName
);
318 strcat(ImagePath
, ".sys");
322 DbgPrint((DPRINT_REACTOS
, " ImagePath: '%s'\n", ImagePath
));
324 DbgPrint((DPRINT_REACTOS
, " Loading driver: '%s'\n", ImagePath
));
329 LoadDriver(ImagePath
, nPos
);
330 LoadSymbolFile(szSystemRoot
, ImagePath
, nPos
);
334 DbgPrint((DPRINT_REACTOS
, " Skipping driver '%s' with Start %d and Group '%s' (Current group '%s')\n",
335 ImagePath
, StartValue
, DriverGroup
, GroupName
));
340 GroupName
= GroupName
+ strlen(GroupName
) + 1;
346 LoadNlsFiles(PCHAR szSystemRoot
)
348 S32 rc
= ERROR_SUCCESS
;
351 char szNameBuffer
[80];
352 char szFileName
[256];
355 /* open the codepage key */
356 rc
= RegOpenKey(NULL
,
357 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
359 if (rc
!= ERROR_SUCCESS
)
363 /* get ANSI codepage */
365 rc
= RegQueryValue(hKey
, "ACP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
366 if (rc
!= ERROR_SUCCESS
)
370 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)szNameBuffer
, &BufferSize
);
371 if (rc
!= ERROR_SUCCESS
)
375 /* load ANSI codepage table */
376 strcpy(szFileName
, szSystemRoot
);
377 strcat(szFileName
, "system32\\");
378 strcat(szFileName
, szNameBuffer
);
379 if (!LoadNlsFile(szFileName
, "ANSI.NLS"))
383 /* get OEM codepage */
385 rc
= RegQueryValue(hKey
, "OEMCP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
386 if (rc
!= ERROR_SUCCESS
)
390 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)szNameBuffer
, &BufferSize
);
391 if (rc
!= ERROR_SUCCESS
)
394 /* load OEM codepage table */
395 strcpy(szFileName
, szSystemRoot
);
396 strcat(szFileName
, "system32\\");
397 strcat(szFileName
, szNameBuffer
);
398 if (!LoadNlsFile(szFileName
, "OEM.NLS"))
402 /* open the language key */
403 rc
= RegOpenKey(NULL
,
404 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
406 if (rc
!= ERROR_SUCCESS
)
410 /* get the Unicode case table */
412 rc
= RegQueryValue(hKey
, "Default", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
413 if (rc
!= ERROR_SUCCESS
)
417 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)szNameBuffer
, &BufferSize
);
418 if (rc
!= ERROR_SUCCESS
)
421 /* load Unicode case table */
422 strcpy(szFileName
, szSystemRoot
);
423 strcat(szFileName
, "system32\\");
424 strcat(szFileName
, szNameBuffer
);
425 if (!LoadNlsFile(szFileName
, "UNICASE.NLS"))
434 LoadAndBootReactOS(PUCHAR OperatingSystemName
)
439 char szKernelName
[1024];
440 char szHalName
[1024];
441 char szFileName
[1024];
442 char szBootPath
[256];
444 // int nNumDriverFiles=0;
445 // int nNumFilesLoaded=0;
452 PARTITION_TABLE_ENTRY PartitionTableEntry
;
454 BOOL TextHive
= FALSE
;
457 // Open the operating system section
458 // specified in the .ini file
460 if (!IniOpenSection(OperatingSystemName
, &SectionId
))
462 sprintf(MsgBuffer
,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName
);
463 UiMessageBox(MsgBuffer
);
468 * Setup multiboot information structure
470 mb_info
.flags
= MB_INFO_FLAG_MEM_SIZE
| MB_INFO_FLAG_BOOT_DEVICE
| MB_INFO_FLAG_COMMAND_LINE
| MB_INFO_FLAG_MODULES
;
471 mb_info
.mem_lower
= GetConventionalMemorySize();
472 mb_info
.mem_upper
= GetExtendedMemorySize();
473 mb_info
.boot_device
= 0xffffffff;
474 mb_info
.cmdline
= (unsigned long)multiboot_kernel_cmdline
;
475 mb_info
.mods_count
= 0;
476 mb_info
.mods_addr
= (unsigned long)multiboot_modules
;
477 mb_info
.mmap_length
= (unsigned long)GetBiosMemoryMap((PBIOS_MEMORY_MAP
)&multiboot_memory_map
, 32) * sizeof(memory_map_t
);
478 if (mb_info
.mmap_length
)
480 mb_info
.mmap_addr
= (unsigned long)&multiboot_memory_map
;
481 mb_info
.flags
|= MB_INFO_FLAG_MEMORY_MAP
;
482 multiboot_memory_map_descriptor_size
= sizeof(memory_map_t
); // GetBiosMemoryMap uses a fixed value of 24
483 DbgPrint((DPRINT_REACTOS
, "memory map length: %d\n", mb_info
.mmap_length
));
484 DbgPrint((DPRINT_REACTOS
, "dumping memory map:\n"));
485 for (i
=0; i
<(mb_info
.mmap_length
/sizeof(memory_map_t
)); i
++)
487 DbgPrint((DPRINT_REACTOS
, "start: %x\t size: %x\t type %d\n",
488 multiboot_memory_map
[i
].base_addr_low
,
489 multiboot_memory_map
[i
].length_low
,
490 multiboot_memory_map
[i
].type
));
493 DbgPrint((DPRINT_REACTOS
, "low_mem = %d\n", mb_info
.mem_lower
));
494 DbgPrint((DPRINT_REACTOS
, "high_mem = %d\n", mb_info
.mem_upper
));
497 * Make sure the system path is set in the .ini file
499 if (!IniReadSettingByName(SectionId
, "SystemPath", value
, 1024))
501 UiMessageBox("System path not specified for selected operating system.");
508 if (!DissectArcPath(value
, szBootPath
, &BootDrive
, &BootPartition
))
510 sprintf(MsgBuffer
,"Invalid system path: '%s'", value
);
511 UiMessageBox(MsgBuffer
);
515 /* set boot drive and partition */
516 ((char *)(&mb_info
.boot_device
))[0] = (char)BootDrive
;
517 ((char *)(&mb_info
.boot_device
))[1] = (char)BootPartition
;
519 /* recalculate the boot partition for freeldr */
524 if (!DiskGetPartitionEntry(BootDrive
, ++i
, &PartitionTableEntry
))
529 if (IsRecognizedPartition(PartitionTableEntry
.SystemIndicator
))
531 if (++rosPartition
== BootPartition
)
538 if (BootPartition
== 0)
540 sprintf(MsgBuffer
,"Invalid system path: '%s'", value
);
541 UiMessageBox(MsgBuffer
);
545 /* copy ARC path into kernel command line */
546 strcpy(multiboot_kernel_cmdline
, value
);
549 * Read the optional kernel parameters (if any)
551 if (IniReadSettingByName(SectionId
, "Options", value
, 1024))
553 strcat(multiboot_kernel_cmdline
, " ");
554 strcat(multiboot_kernel_cmdline
, value
);
557 /* append a backslash */
558 if ((strlen(szBootPath
)==0) ||
559 szBootPath
[strlen(szBootPath
)] != '\\')
560 strcat(szBootPath
, "\\");
562 DbgPrint((DPRINT_REACTOS
,"SystemRoot: '%s'\n", szBootPath
));
565 UiDrawStatusText("Loading...");
566 UiDrawProgressBarCenter(0, 100, "Loading ReactOS...");
569 * Try to open boot drive
571 if (!FsOpenVolume(BootDrive
, BootPartition
))
573 UiMessageBox("Failed to open boot drive.");
578 * Find the kernel image name
579 * and try to load the kernel off the disk
581 if(IniReadSettingByName(SectionId
, "Kernel", value
, 1024))
586 if (value
[0] == '\\')
588 strcpy(szKernelName
, value
);
592 strcpy(szKernelName
, szBootPath
);
593 strcat(szKernelName
, "SYSTEM32\\");
594 strcat(szKernelName
, value
);
599 strcpy(value
, "NTOSKRNL.EXE");
600 strcpy(szKernelName
, szBootPath
);
601 strcat(szKernelName
, "SYSTEM32\\");
602 strcat(szKernelName
, value
);
605 if (!LoadKernel(szKernelName
, 5))
609 * Find the HAL image name
610 * and try to load the kernel off the disk
612 if(IniReadSettingByName(SectionId
, "Hal", value
, 1024))
617 if (value
[0] == '\\')
619 strcpy(szHalName
, value
);
623 strcpy(szHalName
, szBootPath
);
624 strcat(szHalName
, "SYSTEM32\\");
625 strcat(szHalName
, value
);
630 strcpy(value
, "HAL.DLL");
631 strcpy(szHalName
, szBootPath
);
632 strcat(szHalName
, "SYSTEM32\\");
633 strcat(szHalName
, value
);
636 if (!LoadDriver(szHalName
, 10))
640 * Load the System hive from disk
642 strcpy(szFileName
, szBootPath
);
643 strcat(szFileName
, "SYSTEM32\\CONFIG\\SYSTEM");
645 DbgPrint((DPRINT_REACTOS
, "SystemHive: '%s'", szFileName
));
647 FilePointer
= FsOpenFile(szFileName
);
648 if (FilePointer
== NULL
)
650 strcpy(szFileName
, szBootPath
);
651 strcat(szFileName
, "SYSTEM32\\CONFIG\\SYSTEM.HIV");
653 DbgPrint((DPRINT_REACTOS
, "SystemHive: '%s'", szFileName
));
655 FilePointer
= FsOpenFile(szFileName
);
656 if (FilePointer
== NULL
)
658 UiMessageBox("Could not find the system hive!");
668 * Update the status bar with the current file
670 strcpy(name
, "Reading ");
672 while (strlen(name
) < 80)
674 UiDrawStatusText(name
);
677 * Load the system hive
679 Base
= MultiBootLoadModule(FilePointer
, szFileName
, &Size
);
680 RegInitializeRegistry();
684 RegImportTextHive(Base
, Size
);
688 RegImportBinaryHive(Base
, Size
);
691 UiDrawProgressBarCenter(15, 100, "Loading ReactOS...");
692 DbgPrint((DPRINT_REACTOS
, "SystemHive loaded at 0x%x size %u", (unsigned)Base
, (unsigned)Size
));
700 * Export the hardware hive
702 Base
= MultiBootCreateModule ("HARDWARE");
703 RegExportBinaryHive ("\\Registry\\Machine\\HARDWARE", Base
, &Size
);
704 MultiBootCloseModule (Base
, Size
);
706 UiDrawProgressBarCenter(20, 100, "Loading ReactOS...");
709 * Initialize the 'currentControlSet' link
711 RegInitCurrentControlSet(FALSE
);
717 if (!LoadNlsFiles(szBootPath
))
719 MessageBox("Failed to load NLS files\n");
724 LoadSymbolFile(szBootPath
, szKernelName
, 25);
725 LoadSymbolFile(szBootPath
, szHalName
, 25);
727 UiDrawProgressBarCenter(25, 100, "Loading ReactOS...");
732 LoadBootDrivers(szBootPath
, 25);
736 * Clear the screen and redraw the backdrop and status bar
739 UiDrawStatusText("Press any key to boot");
745 strcpy(name
, "Kernel and Drivers loaded.\nPress any key to boot ");
746 strcat(name
, OperatingSystemName
);
751 UiUnInitialize("Booting ReactOS...");
754 * Now boot the kernel
756 DiskStopFloppyMotor();