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