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