Move freeldr to reactos\boot\freeldr.
[reactos.git] / reactos / boot / freeldr / freeldr / reactos / reactos.c
1 /*
2 * FreeLoader
3 *
4 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
5 *
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.
10 *
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.
15 *
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.
19 */
20
21 #include <freeldr.h>
22 #include <debug.h>
23 #include <arch.h>
24 #include <reactos.h>
25 #include <rtl.h>
26 #include <disk.h>
27 #include <fs.h>
28 #include <ui.h>
29 #include <multiboot.h>
30 #include <mm.h>
31 #include <machine.h>
32 #include <inifile.h>
33
34 #include "registry.h"
35
36
37 #define NDEBUG
38
39 #define IsRecognizedPartition(P) \
40 ((P) == PARTITION_FAT_12 || \
41 (P) == PARTITION_FAT_16 || \
42 (P) == PARTITION_HUGE || \
43 (P) == PARTITION_IFS || \
44 (P) == PARTITION_EXT2 || \
45 (P) == PARTITION_FAT32 || \
46 (P) == PARTITION_FAT32_XINT13 || \
47 (P) == PARTITION_XINT13)
48
49 static BOOL
50 LoadKernel(PCHAR szFileName, int nPos)
51 {
52 PFILE FilePointer;
53 PCHAR szShortName;
54 char szBuffer[256];
55
56 szShortName = strrchr(szFileName, '\\');
57 if (szShortName == NULL)
58 szShortName = szFileName;
59 else
60 szShortName = szShortName + 1;
61
62 FilePointer = FsOpenFile(szFileName);
63 if (FilePointer == NULL)
64 {
65 strcpy(szBuffer, szShortName);
66 strcat(szBuffer, " not found.");
67 UiMessageBox(szBuffer);
68 return(FALSE);
69 }
70
71 /*
72 * Update the status bar with the current file
73 */
74 strcpy(szBuffer, "Reading ");
75 strcat(szBuffer, szShortName);
76 UiDrawStatusText(szBuffer);
77
78 /*
79 * Load the kernel
80 */
81 MultiBootLoadKernel(FilePointer);
82
83 UiDrawProgressBarCenter(nPos, 100, "Loading ReactOS...");
84
85 return(TRUE);
86 }
87
88 static BOOL
89 LoadSymbolFile(PCHAR szSystemRoot,
90 PCHAR ModuleName,
91 int nPos)
92 {
93 CHAR SymbolFileName[1024];
94 PFILE FilePointer;
95 U32 Length;
96 PCHAR Start;
97 PCHAR Ext;
98 char value[256];
99 char *p;
100
101 /* Get the path to the symbol store */
102 strcpy(SymbolFileName, szSystemRoot);
103 strcat(SymbolFileName, "symbols\\");
104
105 /* Get the symbol filename from the module name */
106 Start = strrchr(ModuleName, '\\');
107 if (Start == NULL)
108 Start = ModuleName;
109 else
110 Start++;
111
112 Ext = strrchr(ModuleName, '.');
113 if (Ext != NULL)
114 Length = Ext - Start;
115 else
116 Length = strlen(Start);
117
118 strncat(SymbolFileName, Start, Length);
119 strcat(SymbolFileName, ".sym");
120
121 FilePointer = FsOpenFile((PCHAR)&SymbolFileName[0]);
122 if (FilePointer == NULL)
123 {
124 DbgPrint((DPRINT_REACTOS, "Symbol file %s not loaded.\n", SymbolFileName));
125 /* This is not critical */
126 return FALSE;
127 }
128
129 DbgPrint((DPRINT_REACTOS, "Symbol file %s is loaded.\n", SymbolFileName));
130
131 /*
132 * Update the status bar with the current file
133 */
134 strcpy(value, "Reading ");
135 p = strrchr(SymbolFileName, '\\');
136 if (p == NULL)
137 strcat(value, SymbolFileName);
138 else
139 strcat(value, p + 1);
140 UiDrawStatusText(value);
141
142 /*
143 * Load the symbol file
144 */
145 MultiBootLoadModule(FilePointer, SymbolFileName, NULL);
146
147 UiDrawProgressBarCenter(nPos, 100, "Loading ReactOS...");
148
149 return (TRUE);
150 }
151
152
153 static BOOL
154 LoadDriver(PCHAR szFileName, int nPos)
155 {
156 PFILE FilePointer;
157 char value[256];
158 char *p;
159
160 FilePointer = FsOpenFile(szFileName);
161 if (FilePointer == NULL)
162 {
163 strcpy(value, szFileName);
164 strcat(value, " not found.");
165 UiMessageBox(value);
166 return(FALSE);
167 }
168
169 /*
170 * Update the status bar with the current file
171 */
172 strcpy(value, "Reading ");
173 p = strrchr(szFileName, '\\');
174 if (p == NULL)
175 strcat(value, szFileName);
176 else
177 strcat(value, p + 1);
178 UiDrawStatusText(value);
179
180 /*
181 * Load the driver
182 */
183 MultiBootLoadModule(FilePointer, szFileName, NULL);
184
185 UiDrawProgressBarCenter(nPos, 100, "Loading ReactOS...");
186
187 return(TRUE);
188 }
189
190
191 static BOOL
192 LoadNlsFile(PCHAR szFileName, PCHAR szModuleName)
193 {
194 PFILE FilePointer;
195 char value[256];
196 char *p;
197
198 FilePointer = FsOpenFile(szFileName);
199 if (FilePointer == NULL)
200 {
201 strcpy(value, szFileName);
202 strcat(value, " not found.");
203 UiMessageBox(value);
204 return(FALSE);
205 }
206
207 /*
208 * Update the status bar with the current file
209 */
210 strcpy(value, "Reading ");
211 p = strrchr(szFileName, '\\');
212 if (p == NULL)
213 strcat(value, szFileName);
214 else
215 strcat(value, p + 1);
216 UiDrawStatusText(value);
217
218 /*
219 * Load the driver
220 */
221 MultiBootLoadModule(FilePointer, szModuleName, NULL);
222
223 return(TRUE);
224 }
225
226
227 static VOID
228 LoadBootDrivers(PCHAR szSystemRoot, int nPos)
229 {
230 S32 rc = 0;
231 HKEY hGroupKey, hOrderKey, hServiceKey, hDriverKey;
232 char GroupNameBuffer[512];
233 char ServiceName[256];
234 U32 OrderList[128];
235 U32 BufferSize;
236 U32 Index;
237 U32 TagIndex;
238 char *GroupName;
239
240 U32 ValueSize;
241 U32 ValueType;
242 U32 StartValue;
243 U32 TagValue;
244 UCHAR DriverGroup[256];
245 U32 DriverGroupSize;
246
247 UCHAR ImagePath[256];
248 UCHAR TempImagePath[256];
249
250 /* get 'service group order' key */
251 rc = RegOpenKey(NULL,
252 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
253 &hGroupKey);
254 if (rc != ERROR_SUCCESS)
255 {
256 DbgPrint((DPRINT_REACTOS, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc));
257 return;
258 }
259
260 /* get 'group order list' key */
261 rc = RegOpenKey(NULL,
262 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
263 &hOrderKey);
264 if (rc != ERROR_SUCCESS)
265 {
266 DbgPrint((DPRINT_REACTOS, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc));
267 return;
268 }
269
270 /* enumerate drivers */
271 rc = RegOpenKey(NULL,
272 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
273 &hServiceKey);
274 if (rc != ERROR_SUCCESS)
275 {
276 DbgPrint((DPRINT_REACTOS, "Failed to open the 'Services' key (rc %d)\n", (int)rc));
277 return;
278 }
279
280 BufferSize = sizeof(GroupNameBuffer);
281 rc = RegQueryValue(hGroupKey, "List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize);
282 DbgPrint((DPRINT_REACTOS, "RegQueryValue(): rc %d\n", (int)rc));
283 if (rc != ERROR_SUCCESS)
284 return;
285
286 DbgPrint((DPRINT_REACTOS, "BufferSize: %d \n", (int)BufferSize));
287
288 DbgPrint((DPRINT_REACTOS, "GroupNameBuffer: '%s' \n", GroupNameBuffer));
289
290 GroupName = GroupNameBuffer;
291 while (*GroupName)
292 {
293 DbgPrint((DPRINT_REACTOS, "Driver group: '%s'\n", GroupName));
294
295 BufferSize = sizeof(OrderList);
296 rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize);
297 if (rc != ERROR_SUCCESS)
298 {
299 OrderList[0] = 0;
300 }
301
302 for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++)
303 {
304 /* enumerate all drivers */
305 Index = 0;
306 while (TRUE)
307 {
308 ValueSize = sizeof(ServiceName);
309 rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
310 DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc));
311 if (rc == ERROR_NO_MORE_ITEMS)
312 break;
313 if (rc != ERROR_SUCCESS)
314 return;
315 DbgPrint((DPRINT_REACTOS, "Service %d: '%s'\n", (int)Index, ServiceName));
316
317 /* open driver Key */
318 rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
319
320 ValueSize = sizeof(U32);
321 rc = RegQueryValue(hDriverKey, "Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
322 DbgPrint((DPRINT_REACTOS, " Start: %x \n", (int)StartValue));
323
324 ValueSize = sizeof(U32);
325 rc = RegQueryValue(hDriverKey, "Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
326 if (rc != ERROR_SUCCESS)
327 {
328 TagValue = (U32)-1;
329 }
330 DbgPrint((DPRINT_REACTOS, " Tag: %x \n", (int)TagValue));
331
332
333 DriverGroupSize = 256;
334 rc = RegQueryValue(hDriverKey, "Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
335 DbgPrint((DPRINT_REACTOS, " Group: '%s' \n", DriverGroup));
336
337 if ((StartValue == 0) && (TagValue == OrderList[TagIndex]) &&(stricmp(DriverGroup, GroupName) == 0))
338 {
339 ValueSize = 256;
340 rc = RegQueryValue(hDriverKey,
341 "ImagePath",
342 NULL,
343 (PUCHAR)TempImagePath,
344 &ValueSize);
345 if (rc != ERROR_SUCCESS)
346 {
347 DbgPrint((DPRINT_REACTOS, " ImagePath: not found\n"));
348 strcpy(ImagePath, szSystemRoot);
349 strcat(ImagePath, "system32\\drivers\\");
350 strcat(ImagePath, ServiceName);
351 strcat(ImagePath, ".sys");
352 }
353 else if (TempImagePath[0] != '\\')
354 {
355 strcpy(ImagePath, szSystemRoot);
356 strcat(ImagePath, TempImagePath);
357 }
358 else
359 {
360 strcpy(ImagePath, TempImagePath);
361 DbgPrint((DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath));
362 }
363 DbgPrint((DPRINT_REACTOS, " Loading driver: '%s'\n", ImagePath));
364
365 if (nPos < 100)
366 nPos += 5;
367
368 LoadDriver(ImagePath, nPos);
369 LoadSymbolFile(szSystemRoot, ImagePath, nPos);
370 }
371 else
372 {
373 DbgPrint((DPRINT_REACTOS, " Skipping driver '%s' with Start %d, Tag %d and Group '%s' (Current Tag %d, current group '%s')\n",
374 ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName));
375 }
376 Index++;
377 }
378 }
379
380 Index = 0;
381 while (TRUE)
382 {
383 ValueSize = sizeof(ServiceName);
384 rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
385 DbgPrint((DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc));
386 if (rc == ERROR_NO_MORE_ITEMS)
387 break;
388 if (rc != ERROR_SUCCESS)
389 return;
390 DbgPrint((DPRINT_REACTOS, "Service %d: '%s'\n", (int)Index, ServiceName));
391
392 /* open driver Key */
393 rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
394
395 ValueSize = sizeof(U32);
396 rc = RegQueryValue(hDriverKey, "Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
397 DbgPrint((DPRINT_REACTOS, " Start: %x \n", (int)StartValue));
398
399 ValueSize = sizeof(U32);
400 rc = RegQueryValue(hDriverKey, "Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
401 if (rc != ERROR_SUCCESS)
402 {
403 TagValue = (U32)-1;
404 }
405 DbgPrint((DPRINT_REACTOS, " Tag: %x \n", (int)TagValue));
406
407 DriverGroupSize = 256;
408 rc = RegQueryValue(hDriverKey, "Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
409 DbgPrint((DPRINT_REACTOS, " Group: '%s' \n", DriverGroup));
410
411 for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++)
412 {
413 if (TagValue == OrderList[TagIndex])
414 break;
415 }
416
417 if ((StartValue == 0) && (TagIndex > OrderList[0]) && (stricmp(DriverGroup, GroupName) == 0))
418 {
419 ValueSize = 256;
420 rc = RegQueryValue(hDriverKey,
421 "ImagePath",
422 NULL,
423 (PUCHAR)TempImagePath,
424 &ValueSize);
425 if (rc != ERROR_SUCCESS)
426 {
427 DbgPrint((DPRINT_REACTOS, " ImagePath: not found\n"));
428 strcpy(ImagePath, szSystemRoot);
429 strcat(ImagePath, "system32\\drivers\\");
430 strcat(ImagePath, ServiceName);
431 strcat(ImagePath, ".sys");
432 }
433 else if (TempImagePath[0] != '\\')
434 {
435 strcpy(ImagePath, szSystemRoot);
436 strcat(ImagePath, TempImagePath);
437 }
438 else
439 {
440 strcpy(ImagePath, TempImagePath);
441 DbgPrint((DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath));
442 }
443 DbgPrint((DPRINT_REACTOS, " Loading driver: '%s'\n", ImagePath));
444
445 if (nPos < 100)
446 nPos += 5;
447
448 LoadDriver(ImagePath, nPos);
449 LoadSymbolFile(szSystemRoot, ImagePath, nPos);
450 }
451 else
452 {
453 DbgPrint((DPRINT_REACTOS, " Skipping driver '%s' with Start %d, Tag %d and Group '%s' (Current group '%s')\n",
454 ServiceName, StartValue, TagValue, DriverGroup, GroupName));
455 }
456 Index++;
457 }
458
459 GroupName = GroupName + strlen(GroupName) + 1;
460 }
461 }
462
463
464 static BOOL
465 LoadNlsFiles(PCHAR szSystemRoot, PCHAR szErrorOut)
466 {
467 S32 rc = ERROR_SUCCESS;
468 HKEY hKey;
469 char szIdBuffer[80];
470 char szNameBuffer[80];
471 char szFileName[256];
472 U32 BufferSize;
473
474 /* open the codepage key */
475 rc = RegOpenKey(NULL,
476 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
477 &hKey);
478 if (rc != ERROR_SUCCESS) {
479 strcpy(szErrorOut, "Couldn't open CodePage registry key");
480 return(FALSE);
481 }
482
483
484 /* get ANSI codepage */
485 BufferSize = 80;
486 rc = RegQueryValue(hKey, "ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
487 if (rc != ERROR_SUCCESS) {
488 strcpy(szErrorOut, "Couldn't get ACP NLS setting");
489 return(FALSE);
490 }
491
492 BufferSize = 80;
493 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
494 if (rc != ERROR_SUCCESS) {
495 strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
496 return(FALSE);
497 }
498
499 /* load ANSI codepage table */
500 strcpy(szFileName, szSystemRoot);
501 strcat(szFileName, "system32\\");
502 strcat(szFileName, szNameBuffer);
503 DbgPrint((DPRINT_REACTOS, "ANSI file: %s\n", szFileName));
504 if (!LoadNlsFile(szFileName, "ansi.nls")) {
505 strcpy(szErrorOut, "Couldn't load ansi.nls");
506 return(FALSE);
507 }
508
509 /* get OEM codepage */
510 BufferSize = 80;
511 rc = RegQueryValue(hKey, "OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
512 if (rc != ERROR_SUCCESS) {
513 strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
514 return(FALSE);
515 }
516
517 BufferSize = 80;
518 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
519 if (rc != ERROR_SUCCESS) {
520 strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
521 return(FALSE);
522 }
523
524 /* load OEM codepage table */
525 strcpy(szFileName, szSystemRoot);
526 strcat(szFileName, "system32\\");
527 strcat(szFileName, szNameBuffer);
528 DbgPrint((DPRINT_REACTOS, "Oem file: %s\n", szFileName));
529 if (!LoadNlsFile(szFileName, "oem.nls")) {
530 strcpy(szErrorOut, "Couldn't load oem.nls");
531 return(FALSE);
532 }
533
534 /* open the language key */
535 rc = RegOpenKey(NULL,
536 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
537 &hKey);
538 if (rc != ERROR_SUCCESS) {
539 strcpy(szErrorOut, "Couldn't open Language registry key");
540 return(FALSE);
541 }
542
543 /* get the Unicode case table */
544 BufferSize = 80;
545 rc = RegQueryValue(hKey, "Default", NULL, (PUCHAR)szIdBuffer, &BufferSize);
546 if (rc != ERROR_SUCCESS) {
547 strcpy(szErrorOut, "Couldn't get Language Default setting");
548 return(FALSE);
549 }
550
551 BufferSize = 80;
552 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
553 if (rc != ERROR_SUCCESS) {
554 strcpy(szErrorOut,
555 "Language Default setting exists, but isn't readable");
556 return(FALSE);
557 }
558
559 /* load Unicode case table */
560 strcpy(szFileName, szSystemRoot);
561 strcat(szFileName, "system32\\");
562 strcat(szFileName, szNameBuffer);
563 DbgPrint((DPRINT_REACTOS, "Casemap file: %s\n", szFileName));
564 if (!LoadNlsFile(szFileName, "casemap.nls")) {
565 strcpy(szErrorOut, "casemap.nls");
566 return(FALSE);
567 }
568
569 return(TRUE);
570 }
571
572
573 void
574 LoadAndBootReactOS(PUCHAR OperatingSystemName)
575 {
576 PFILE FilePointer;
577 char name[1024];
578 char value[1024];
579 char szKernelName[1024];
580 char szHalName[1024];
581 char szFileName[1024];
582 char szBootPath[256];
583 int i;
584 char MsgBuffer[256];
585 U32 SectionId;
586
587 char* Base;
588 U32 Size;
589
590 PARTITION_TABLE_ENTRY PartitionTableEntry;
591 U32 rosPartition;
592
593 //
594 // Open the operating system section
595 // specified in the .ini file
596 //
597 if (!IniOpenSection(OperatingSystemName, &SectionId))
598 {
599 sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);
600 UiMessageBox(MsgBuffer);
601 return;
602 }
603
604 /*
605 * Setup multiboot information structure
606 */
607 mb_info.flags = MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_BOOT_DEVICE | MB_INFO_FLAG_COMMAND_LINE | MB_INFO_FLAG_MODULES;
608 mb_info.boot_device = 0xffffffff;
609 mb_info.cmdline = (unsigned long)multiboot_kernel_cmdline;
610 mb_info.mods_count = 0;
611 mb_info.mods_addr = (unsigned long)multiboot_modules;
612 mb_info.mmap_length = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)(PVOID)&multiboot_memory_map, 32) * sizeof(memory_map_t);
613 if (mb_info.mmap_length)
614 {
615 mb_info.mmap_addr = (unsigned long)&multiboot_memory_map;
616 mb_info.flags |= MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_MEMORY_MAP;
617 multiboot_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
618 DbgPrint((DPRINT_REACTOS, "memory map length: %d\n", mb_info.mmap_length));
619 DbgPrint((DPRINT_REACTOS, "dumping memory map:\n"));
620 for (i=0; i<(mb_info.mmap_length/sizeof(memory_map_t)); i++)
621 {
622 if (MEMTYPE_USABLE == multiboot_memory_map[i].type &&
623 0 == multiboot_memory_map[i].base_addr_low)
624 {
625 mb_info.mem_lower = (multiboot_memory_map[i].base_addr_low + multiboot_memory_map[i].length_low) / 1024;
626 if (640 < mb_info.mem_lower)
627 {
628 mb_info.mem_lower = 640;
629 }
630 }
631 if (MEMTYPE_USABLE == multiboot_memory_map[i].type &&
632 multiboot_memory_map[i].base_addr_low <= 1024 * 1024 &&
633 1024 * 1024 <= multiboot_memory_map[i].base_addr_low + multiboot_memory_map[i].length_low)
634 {
635 mb_info.mem_upper = (multiboot_memory_map[i].base_addr_low + multiboot_memory_map[i].length_low) / 1024 - 1024;
636 }
637 DbgPrint((DPRINT_REACTOS, "start: %x\t size: %x\t type %d\n",
638 multiboot_memory_map[i].base_addr_low,
639 multiboot_memory_map[i].length_low,
640 multiboot_memory_map[i].type));
641 }
642 }
643 DbgPrint((DPRINT_REACTOS, "low_mem = %d\n", mb_info.mem_lower));
644 DbgPrint((DPRINT_REACTOS, "high_mem = %d\n", mb_info.mem_upper));
645
646 /*
647 * Initialize the registry
648 */
649 RegInitializeRegistry();
650
651 /*
652 * Make sure the system path is set in the .ini file
653 */
654 if (!IniReadSettingByName(SectionId, "SystemPath", value, 1024))
655 {
656 UiMessageBox("System path not specified for selected operating system.");
657 return;
658 }
659
660 /*
661 * Special case for Live CD.
662 */
663 if (!stricmp(value, "LiveCD"))
664 {
665 strcpy(szBootPath, "\\reactos");
666
667 /* Set kernel command line */
668 sprintf(multiboot_kernel_cmdline,
669 "multi(0)disk(0)cdrom(%u)\\reactos /MININT",
670 (unsigned int)BootDrive);
671 }
672 else
673 {
674 /*
675 * Verify system path
676 */
677 if (!DissectArcPath(value, szBootPath, &BootDrive, &BootPartition))
678 {
679 sprintf(MsgBuffer,"Invalid system path: '%s'", value);
680 UiMessageBox(MsgBuffer);
681 return;
682 }
683
684 /* recalculate the boot partition for freeldr */
685 i = 0;
686 rosPartition = 0;
687 while (1)
688 {
689 if (!MachDiskGetPartitionEntry(BootDrive, ++i, &PartitionTableEntry))
690 {
691 BootPartition = 0;
692 break;
693 }
694 if (IsRecognizedPartition(PartitionTableEntry.SystemIndicator))
695 {
696 if (++rosPartition == BootPartition)
697 {
698 BootPartition = i;
699 break;
700 }
701 }
702 }
703
704 if (BootPartition == 0)
705 {
706 sprintf(MsgBuffer,"Invalid system path: '%s'", value);
707 UiMessageBox(MsgBuffer);
708 return;
709 }
710
711 /* copy ARC path into kernel command line */
712 strcpy(multiboot_kernel_cmdline, value);
713 }
714
715 /* Set boot drive and partition */
716 ((char *)(&mb_info.boot_device))[0] = (char)BootDrive;
717 ((char *)(&mb_info.boot_device))[1] = (char)BootPartition;
718
719 /*
720 * Read the optional kernel parameters (if any)
721 */
722 if (IniReadSettingByName(SectionId, "Options", value, 1024))
723 {
724 strcat(multiboot_kernel_cmdline, " ");
725 strcat(multiboot_kernel_cmdline, value);
726 }
727
728 /* append a backslash */
729 if ((strlen(szBootPath)==0) ||
730 szBootPath[strlen(szBootPath)] != '\\')
731 strcat(szBootPath, "\\");
732
733 DbgPrint((DPRINT_REACTOS,"SystemRoot: '%s'\n", szBootPath));
734
735
736 UiDrawBackdrop();
737 UiDrawStatusText("Detecting Hardware...");
738
739 /*
740 * Detect hardware
741 */
742 MachHwDetect();
743
744
745 UiDrawStatusText("Loading...");
746 UiDrawProgressBarCenter(0, 100, "Loading ReactOS...");
747
748 /*
749 * Try to open boot drive
750 */
751 if (!FsOpenVolume(BootDrive, BootPartition))
752 {
753 UiMessageBox("Failed to open boot drive.");
754 return;
755 }
756
757 /*
758 * Find the kernel image name
759 * and try to load the kernel off the disk
760 */
761 if(IniReadSettingByName(SectionId, "Kernel", value, 1024))
762 {
763 /*
764 * Set the name and
765 */
766 if (value[0] == '\\')
767 {
768 strcpy(szKernelName, value);
769 }
770 else
771 {
772 strcpy(szKernelName, szBootPath);
773 strcat(szKernelName, "SYSTEM32\\");
774 strcat(szKernelName, value);
775 }
776 }
777 else
778 {
779 strcpy(value, "NTOSKRNL.EXE");
780 strcpy(szKernelName, szBootPath);
781 strcat(szKernelName, "SYSTEM32\\");
782 strcat(szKernelName, value);
783 }
784
785 if (!LoadKernel(szKernelName, 5))
786 return;
787
788 /*
789 * Find the HAL image name
790 * and try to load the kernel off the disk
791 */
792 if(IniReadSettingByName(SectionId, "Hal", value, 1024))
793 {
794 /*
795 * Set the name and
796 */
797 if (value[0] == '\\')
798 {
799 strcpy(szHalName, value);
800 }
801 else
802 {
803 strcpy(szHalName, szBootPath);
804 strcat(szHalName, "SYSTEM32\\");
805 strcat(szHalName, value);
806 }
807 }
808 else
809 {
810 strcpy(value, "HAL.DLL");
811 strcpy(szHalName, szBootPath);
812 strcat(szHalName, "SYSTEM32\\");
813 strcat(szHalName, value);
814 }
815
816 if (!LoadDriver(szHalName, 10))
817 return;
818
819 /*
820 * Load the System hive from disk
821 */
822 strcpy(szFileName, szBootPath);
823 strcat(szFileName, "SYSTEM32\\CONFIG\\SYSTEM");
824
825 DbgPrint((DPRINT_REACTOS, "SystemHive: '%s'", szFileName));
826
827 FilePointer = FsOpenFile(szFileName);
828 if (FilePointer == NULL)
829 {
830 UiMessageBox("Could not find the System hive!");
831 return;
832 }
833
834 /*
835 * Update the status bar with the current file
836 */
837 strcpy(name, "Reading ");
838 strcat(name, value);
839 while (strlen(name) < 80)
840 strcat(name, " ");
841 UiDrawStatusText(name);
842
843 /*
844 * Load the System hive
845 */
846 Base = MultiBootLoadModule(FilePointer, szFileName, &Size);
847 if (Base == NULL || Size == 0)
848 {
849 UiMessageBox("Could not load the System hive!\n");
850 return;
851 }
852 DbgPrint((DPRINT_REACTOS, "SystemHive loaded at 0x%x size %u", (unsigned)Base, (unsigned)Size));
853
854 /*
855 * Import the loaded system hive
856 */
857 RegImportBinaryHive(Base, Size);
858
859 /*
860 * Initialize the 'CurrentControlSet' link
861 */
862 RegInitCurrentControlSet(FALSE);
863
864 UiDrawProgressBarCenter(15, 100, "Loading ReactOS...");
865
866 /*
867 * Export the hardware hive
868 */
869 Base = MultiBootCreateModule ("HARDWARE");
870 RegExportBinaryHive ("\\Registry\\Machine\\HARDWARE", Base, &Size);
871 MultiBootCloseModule (Base, Size);
872
873 UiDrawProgressBarCenter(20, 100, "Loading ReactOS...");
874
875 /*
876 * Load NLS files
877 */
878 if (!LoadNlsFiles(szBootPath, MsgBuffer))
879 {
880 UiMessageBox(MsgBuffer);
881 return;
882 }
883 UiDrawProgressBarCenter(25, 100, "Loading ReactOS...");
884
885 /*
886 * Load symbol files
887 */
888 LoadSymbolFile(szBootPath, szKernelName, 30);
889 LoadSymbolFile(szBootPath, szHalName, 30);
890
891 UiDrawProgressBarCenter(30, 100, "Loading ReactOS...");
892
893 /*
894 * Load boot drivers
895 */
896 LoadBootDrivers(szBootPath, 30);
897
898
899 #if 0
900 /*
901 * Clear the screen and redraw the backdrop and status bar
902 */
903 UiDrawBackdrop();
904 UiDrawStatusText("Press any key to boot");
905
906 /*
907 * Wait for user
908 */
909 strcpy(name, "Kernel and Drivers loaded.\nPress any key to boot ");
910 strcat(name, OperatingSystemName);
911 strcat(name, ".");
912 MessageBox(name);
913 #endif
914
915 UiUnInitialize("Booting ReactOS...");
916
917 /*
918 * Now boot the kernel
919 */
920 DiskStopFloppyMotor();
921 boot_reactos();
922 }
923
924 /* EOF */