4 * Copyright (C) 1998-2002 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>
41 LoadKernel(PCHAR szFileName
, int nPos
)
47 szShortName
= strrchr(szFileName
, '\\');
48 if (szShortName
== NULL
)
49 szShortName
= szFileName
;
51 szShortName
= szShortName
+ 1;
53 FilePointer
= FsOpenFile(szFileName
);
54 if (FilePointer
== NULL
)
56 strcpy(szBuffer
, szShortName
);
57 strcat(szBuffer
, " not found.");
58 UiMessageBox(szBuffer
);
63 * Update the status bar with the current file
65 strcpy(szBuffer
, "Reading ");
66 strcat(szBuffer
, szShortName
);
67 UiDrawStatusText(szBuffer
);
72 MultiBootLoadKernel(FilePointer
);
74 UiDrawProgressBarCenter(nPos
, 100);
80 LoadSymbolFile(PCHAR szSystemRoot
,
84 CHAR SymbolFileName
[1024];
92 /* Get the path to the symbol store */
93 strcpy(SymbolFileName
, szSystemRoot
);
94 strcat(SymbolFileName
, "symbols\\");
96 /* Get the symbol filename from the module name */
97 Start
= strrchr(ModuleName
, '\\');
103 Ext
= strrchr(ModuleName
, '.');
105 Length
= Ext
- Start
;
107 Length
= strlen(Start
);
109 strncat(SymbolFileName
, Start
, Length
);
110 strcat(SymbolFileName
, ".sym");
112 FilePointer
= FsOpenFile((PCHAR
)&SymbolFileName
[0]);
113 if (FilePointer
== NULL
)
115 DbgPrint((DPRINT_REACTOS
, "Symbol file %s not loaded.\n", SymbolFileName
));
116 /* This is not critical */
120 DbgPrint((DPRINT_REACTOS
, "Symbol file %s is loaded.\n", SymbolFileName
));
123 * Update the status bar with the current file
125 strcpy(value
, "Reading ");
126 p
= strrchr(SymbolFileName
, '\\');
128 strcat(value
, SymbolFileName
);
130 strcat(value
, p
+ 1);
131 UiDrawStatusText(value
);
134 * Load the symbol file
136 MultiBootLoadModule(FilePointer
, SymbolFileName
, NULL
);
138 UiDrawProgressBarCenter(nPos
, 100);
144 LoadDriver(PCHAR szFileName
, int nPos
)
150 FilePointer
= FsOpenFile(szFileName
);
151 if (FilePointer
== NULL
)
153 strcpy(value
, szFileName
);
154 strcat(value
, " not found.");
160 * Update the status bar with the current file
162 strcpy(value
, "Reading ");
163 p
= strrchr(szFileName
, '\\');
165 strcat(value
, szFileName
);
167 strcat(value
, p
+ 1);
168 UiDrawStatusText(value
);
173 MultiBootLoadModule(FilePointer
, szFileName
, NULL
);
175 UiDrawProgressBarCenter(nPos
, 100);
183 LoadNlsFile(PCHAR szFileName
, PCHAR szModuleName
)
189 FilePointer
= FsOpenFile(szFileName
);
190 if (FilePointer
== NULL
)
192 strcpy(value
, szFileName
);
193 strcat(value
, " not found.");
199 * Update the status bar with the current file
201 strcpy(value
, "Reading ");
202 p
= strrchr(szFileName
, '\\');
204 strcat(value
, szFileName
);
206 strcat(value
, p
+ 1);
207 UiDrawStatusText(value
);
212 MultiBootLoadModule(FilePointer
, szModuleName
, NULL
);
220 LoadBootDrivers(PCHAR szSystemRoot
, int nPos
)
223 HKEY hGroupKey
, hServiceKey
, hDriverKey
;
224 char ValueBuffer
[512];
225 char ServiceName
[256];
233 UCHAR DriverGroup
[256];
236 UCHAR ImagePath
[256];
238 /* get 'service group order' key */
239 rc
= RegOpenKey(NULL
,
240 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
242 if (rc
!= ERROR_SUCCESS
)
244 DbgPrint((DPRINT_REACTOS
, "Failed to open the 'ServiceGroupOrder key (rc %d)\n", (int)rc
));
248 /* enumerate drivers */
249 rc
= RegOpenKey(NULL
,
250 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
252 if (rc
!= ERROR_SUCCESS
)
254 DbgPrint((DPRINT_REACTOS
, "Failed to open the 'Services' key (rc %d)\n", (int)rc
));
258 BufferSize
= sizeof(ValueBuffer
);
259 rc
= RegQueryValue(hGroupKey
, "List", NULL
, (PUCHAR
)ValueBuffer
, &BufferSize
);
260 DbgPrint((DPRINT_REACTOS
, "RegQueryValue(): rc %d\n", (int)rc
));
261 if (rc
!= ERROR_SUCCESS
)
264 DbgPrint((DPRINT_REACTOS
, "BufferSize: %d \n", (int)BufferSize
));
266 DbgPrint((DPRINT_REACTOS
, "ValueBuffer: '%s' \n", ValueBuffer
));
268 GroupName
= ValueBuffer
;
271 DbgPrint((DPRINT_REACTOS
, "Driver group: '%s'\n", GroupName
));
273 /* enumerate all drivers */
277 ValueSize
= sizeof(ValueBuffer
);
278 rc
= RegEnumKey(hServiceKey
, Index
, ServiceName
, &ValueSize
);
279 DbgPrint((DPRINT_REACTOS
, "RegEnumKey(): rc %d\n", (int)rc
));
280 if (rc
== ERROR_NO_MORE_ITEMS
)
282 if (rc
!= ERROR_SUCCESS
)
284 DbgPrint((DPRINT_REACTOS
, "Service %d: '%s'\n", (int)Index
, ServiceName
));
286 /* open driver Key */
287 rc
= RegOpenKey(hServiceKey
, ServiceName
, &hDriverKey
);
289 ValueSize
= sizeof(U32
);
290 rc
= RegQueryValue(hDriverKey
, "Start", &ValueType
, (PUCHAR
)&StartValue
, &ValueSize
);
291 DbgPrint((DPRINT_REACTOS
, " Start: %x \n", (int)StartValue
));
293 DriverGroupSize
= 256;
294 rc
= RegQueryValue(hDriverKey
, "Group", NULL
, (PUCHAR
)DriverGroup
, &DriverGroupSize
);
295 DbgPrint((DPRINT_REACTOS
, " Group: '%s' \n", DriverGroup
));
297 if ((StartValue
== 0) && (stricmp(DriverGroup
, GroupName
) == 0))
300 rc
= RegQueryValue(hDriverKey
,
305 if (rc
!= ERROR_SUCCESS
)
307 DbgPrint((DPRINT_REACTOS
, " ImagePath: not found\n"));
308 strcpy(ImagePath
, szSystemRoot
);
309 strcat(ImagePath
, "system32\\drivers\\");
310 strcat(ImagePath
, ServiceName
);
311 strcat(ImagePath
, ".sys");
315 DbgPrint((DPRINT_REACTOS
, " ImagePath: '%s'\n", ImagePath
));
317 DbgPrint((DPRINT_REACTOS
, " Loading driver: '%s'\n", ImagePath
));
322 LoadDriver(ImagePath
, nPos
);
323 LoadSymbolFile(szSystemRoot
, ImagePath
, nPos
);
327 DbgPrint((DPRINT_REACTOS
, " Skipping driver '%s' with Start %d and Group '%s' (Current group '%s')\n",
328 ImagePath
, StartValue
, DriverGroup
, GroupName
));
333 GroupName
= GroupName
+ strlen(GroupName
) + 1;
339 LoadNlsFiles(PCHAR szSystemRoot
)
341 S32 rc
= ERROR_SUCCESS
;
344 char szNameBuffer
[80];
345 char szFileName
[256];
348 /* open the codepage key */
349 rc
= RegOpenKey(NULL
,
350 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
352 if (rc
!= ERROR_SUCCESS
)
356 /* get ANSI codepage */
358 rc
= RegQueryValue(hKey
, "ACP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
359 if (rc
!= ERROR_SUCCESS
)
363 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)szNameBuffer
, &BufferSize
);
364 if (rc
!= ERROR_SUCCESS
)
368 /* load ANSI codepage table */
369 strcpy(szFileName
, szSystemRoot
);
370 strcat(szFileName
, "system32\\");
371 strcat(szFileName
, szNameBuffer
);
372 if (!LoadNlsFile(szFileName
, "ANSI.NLS"))
376 /* get OEM codepage */
378 rc
= RegQueryValue(hKey
, "OEMCP", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
379 if (rc
!= ERROR_SUCCESS
)
383 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)szNameBuffer
, &BufferSize
);
384 if (rc
!= ERROR_SUCCESS
)
387 /* load OEM codepage table */
388 strcpy(szFileName
, szSystemRoot
);
389 strcat(szFileName
, "system32\\");
390 strcat(szFileName
, szNameBuffer
);
391 if (!LoadNlsFile(szFileName
, "OEM.NLS"))
395 /* open the language key */
396 rc
= RegOpenKey(NULL
,
397 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
399 if (rc
!= ERROR_SUCCESS
)
403 /* get the Unicode case table */
405 rc
= RegQueryValue(hKey
, "Default", NULL
, (PUCHAR
)szIdBuffer
, &BufferSize
);
406 if (rc
!= ERROR_SUCCESS
)
410 rc
= RegQueryValue(hKey
, szIdBuffer
, NULL
, (PUCHAR
)szNameBuffer
, &BufferSize
);
411 if (rc
!= ERROR_SUCCESS
)
414 /* load Unicode case table */
415 strcpy(szFileName
, szSystemRoot
);
416 strcat(szFileName
, "system32\\");
417 strcat(szFileName
, szNameBuffer
);
418 if (!LoadNlsFile(szFileName
, "UNICASE.NLS"))
427 LoadAndBootReactOS(PUCHAR OperatingSystemName
)
432 char szKernelName
[1024];
433 char szHalName
[1024];
434 char szFileName
[1024];
435 char szBootPath
[256];
437 // int nNumDriverFiles=0;
438 // int nNumFilesLoaded=0;
447 // Open the operating system section
448 // specified in the .ini file
450 if (!IniOpenSection(OperatingSystemName
, &SectionId
))
452 sprintf(MsgBuffer
,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName
);
453 UiMessageBox(MsgBuffer
);
458 * Setup multiboot information structure
460 mb_info
.flags
= MB_INFO_FLAG_MEM_SIZE
| MB_INFO_FLAG_BOOT_DEVICE
| MB_INFO_FLAG_COMMAND_LINE
| MB_INFO_FLAG_MODULES
;
461 mb_info
.mem_lower
= GetConventionalMemorySize();
462 mb_info
.mem_upper
= GetExtendedMemorySize();
463 mb_info
.boot_device
= 0xffffffff;
464 mb_info
.cmdline
= (unsigned long)multiboot_kernel_cmdline
;
465 mb_info
.mods_count
= 0;
466 mb_info
.mods_addr
= (unsigned long)multiboot_modules
;
467 mb_info
.mmap_length
= (unsigned long)GetBiosMemoryMap((PBIOS_MEMORY_MAP
)&multiboot_memory_map
, 32) * sizeof(memory_map_t
);
468 if (mb_info
.mmap_length
)
470 mb_info
.mmap_addr
= (unsigned long)&multiboot_memory_map
;
471 mb_info
.flags
|= MB_INFO_FLAG_MEMORY_MAP
;
472 multiboot_memory_map_descriptor_size
= sizeof(memory_map_t
); // GetBiosMemoryMap uses a fixed value of 24
473 DbgPrint((DPRINT_REACTOS
, "memory map length: %d\n", mb_info
.mmap_length
));
474 DbgPrint((DPRINT_REACTOS
, "dumping memory map:\n"));
475 for (i
=0; i
<(mb_info
.mmap_length
/sizeof(memory_map_t
)); i
++)
477 DbgPrint((DPRINT_REACTOS
, "start: %x\t size: %x\t type %d\n",
478 multiboot_memory_map
[i
].base_addr_low
,
479 multiboot_memory_map
[i
].length_low
,
480 multiboot_memory_map
[i
].type
));
483 DbgPrint((DPRINT_REACTOS
, "low_mem = %d\n", mb_info
.mem_lower
));
484 DbgPrint((DPRINT_REACTOS
, "high_mem = %d\n", mb_info
.mem_upper
));
487 * Make sure the system path is set in the .ini file
489 if (!IniReadSettingByName(SectionId
, "SystemPath", value
, 1024))
491 UiMessageBox("System path not specified for selected operating system.");
498 if (!DissectArcPath(value
, szBootPath
, &BootDrive
, &BootPartition
))
500 sprintf(MsgBuffer
,"Invalid system path: '%s'", value
);
501 UiMessageBox(MsgBuffer
);
505 /* set boot drive and partition */
506 ((char *)(&mb_info
.boot_device
))[0] = (char)BootDrive
;
507 ((char *)(&mb_info
.boot_device
))[1] = (char)BootPartition
;
509 /* copy ARC path into kernel command line */
510 strcpy(multiboot_kernel_cmdline
, value
);
513 * Read the optional kernel parameters (if any)
515 if (IniReadSettingByName(SectionId
, "Options", value
, 1024))
517 strcat(multiboot_kernel_cmdline
, " ");
518 strcat(multiboot_kernel_cmdline
, value
);
521 /* append a backslash */
522 if ((strlen(szBootPath
)==0) ||
523 szBootPath
[strlen(szBootPath
)] != '\\')
524 strcat(szBootPath
, "\\");
526 DbgPrint((DPRINT_REACTOS
,"SystemRoot: '%s'\n", szBootPath
));
529 UiDrawStatusText("Loading...");
530 UiDrawProgressBarCenter(0, 100);
533 * Try to open boot drive
535 if (!FsOpenVolume(BootDrive
, BootPartition
))
537 UiMessageBox("Failed to open boot drive.");
542 * Find the kernel image name
543 * and try to load the kernel off the disk
545 if(IniReadSettingByName(SectionId
, "Kernel", value
, 1024))
550 if (value
[0] == '\\')
552 strcpy(szKernelName
, value
);
556 strcpy(szKernelName
, szBootPath
);
557 strcat(szKernelName
, "SYSTEM32\\");
558 strcat(szKernelName
, value
);
563 strcpy(value
, "NTOSKRNL.EXE");
564 strcpy(szKernelName
, szBootPath
);
565 strcat(szKernelName
, "SYSTEM32\\");
566 strcat(szKernelName
, value
);
569 if (!LoadKernel(szKernelName
, 5))
573 * Find the HAL image name
574 * and try to load the kernel off the disk
576 if(IniReadSettingByName(SectionId
, "Hal", value
, 1024))
581 if (value
[0] == '\\')
583 strcpy(szHalName
, value
);
587 strcpy(szHalName
, szBootPath
);
588 strcat(szHalName
, "SYSTEM32\\");
589 strcat(szHalName
, value
);
594 strcpy(value
, "HAL.DLL");
595 strcpy(szHalName
, szBootPath
);
596 strcat(szHalName
, "SYSTEM32\\");
597 strcat(szHalName
, value
);
600 if (!LoadDriver(szHalName
, 10))
604 * Find the System hive image name
605 * and try to load it off the disk
607 if(IniReadSettingByName(SectionId
, "SystemHive", value
, 1024))
612 if (value
[0] == '\\')
614 strcpy(szFileName
, value
);
618 strcpy(szFileName
, szBootPath
);
619 strcat(szFileName
, "SYSTEM32\\CONFIG\\");
620 strcat(szFileName
, value
);
625 strcpy(value
, "SYSTEM.HIV");
626 strcpy(szFileName
, szBootPath
);
627 strcat(szFileName
, "SYSTEM32\\CONFIG\\");
628 strcat(szFileName
, value
);
631 DbgPrint((DPRINT_REACTOS
, "SystemHive: '%s'", szFileName
));
633 FilePointer
= FsOpenFile(szFileName
);
634 if (FilePointer
== NULL
)
636 strcat(value
, " not found.");
642 * Update the status bar with the current file
644 strcpy(name
, "Reading ");
646 while (strlen(name
) < 80)
648 UiDrawStatusText(name
);
651 * Load the system hive
653 Base
= MultiBootLoadModule(FilePointer
, szFileName
, &Size
);
654 RegInitializeRegistry();
655 RegImportHive(Base
, Size
);
657 UiDrawProgressBarCenter(15, 100);
658 DbgPrint((DPRINT_REACTOS
, "SystemHive loaded at 0x%x size %u", (unsigned)Base
, (unsigned)Size
));
661 * Retrieve hardware information and create the hardware hive
665 Base
= MultiBootCreateModule(HARDWARE
.HIV
);
666 RegExportHive("\\Registry\\Machine\\HARDWARE", Base
, &Size
);
667 MultiBootCloseModule(Base
, Size
);
669 UiDrawProgressBarCenter(20, 100);
672 * Initialize the 'currentControlSet' link
674 RegInitCurrentControlSet(FALSE
);
680 if (!LoadNlsFiles(szBootPath
))
682 MessageBox("Failed to load NLS files\n");
687 LoadSymbolFile(szBootPath
, szKernelName
, 25);
688 LoadSymbolFile(szBootPath
, szHalName
, 25);
690 UiDrawProgressBarCenter(25, 100);
695 LoadBootDrivers(szBootPath
, 25);
699 * Clear the screen and redraw the backdrop and status bar
702 UiDrawStatusText("Press any key to boot");
707 strcpy(name
, "Kernel and Drivers loaded.\nPress any key to boot ");
708 strcat(name
, OperatingSystemName
);
713 UiUnInitialize("Booting ReactOS...");
716 * Now boot the kernel
718 DiskStopFloppyMotor();