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