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