[freeldr] Rework the ramdisk driver to let it be a full device, instead of a deprecat...
[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[] = "ReactOS is loading files...";
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)
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)
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)
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) {
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) {
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 /* HACK */
269 wcscpy(szNameBuffer, L"c_1252.nls");
270 }
271
272 /* load ANSI codepage table */
273 sprintf(szFileName,"%ssystem32\\%S", szSystemRoot, szNameBuffer);
274 DPRINTM(DPRINT_REACTOS, "ANSI file: %s\n", szFileName);
275 if (!FrLdrLoadNlsFile(szFileName, "ansi.nls")) {
276
277 strcpy(szErrorOut, "Couldn't load ansi.nls");
278 return(FALSE);
279 }
280
281 /* get OEM codepage */
282 BufferSize = sizeof(szIdBuffer);
283 rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
284 if (rc != ERROR_SUCCESS) {
285
286 strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
287 return(FALSE);
288 }
289
290 BufferSize = sizeof(szNameBuffer);
291 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
292 if (rc != ERROR_SUCCESS) {
293
294 //strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
295 //return(FALSE);
296
297 /* HACK */
298 wcscpy(szNameBuffer, L"c_437.nls");
299 }
300
301 /* load OEM codepage table */
302 sprintf(szFileName, "%ssystem32\\%S", szSystemRoot, szNameBuffer);
303 DPRINTM(DPRINT_REACTOS, "Oem file: %s\n", szFileName);
304 if (!FrLdrLoadNlsFile(szFileName, "oem.nls")) {
305
306 strcpy(szErrorOut, "Couldn't load oem.nls");
307 return(FALSE);
308 }
309
310 /* open the language key */
311 rc = RegOpenKey(NULL,
312 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
313 &hKey);
314 if (rc != ERROR_SUCCESS) {
315
316 strcpy(szErrorOut, "Couldn't open Language registry key");
317 return(FALSE);
318 }
319
320 /* get the Unicode case table */
321 BufferSize = sizeof(szIdBuffer);
322 rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize);
323 if (rc != ERROR_SUCCESS) {
324
325 strcpy(szErrorOut, "Couldn't get Language Default setting");
326 return(FALSE);
327 }
328
329 BufferSize = sizeof(szNameBuffer);
330 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
331 if (rc != ERROR_SUCCESS) {
332
333 sprintf(szErrorOut, "Language Default setting exists, but isn't readable (%S)", szIdBuffer);
334 return(FALSE);
335 }
336
337 /* load Unicode case table */
338 sprintf(szFileName, "%ssystem32\\%S", szSystemRoot, szNameBuffer);
339 DPRINTM(DPRINT_REACTOS, "Casemap file: %s\n", szFileName);
340 if (!FrLdrLoadNlsFile(szFileName, "casemap.nls")) {
341
342 strcpy(szErrorOut, "casemap.nls");
343 return(FALSE);
344 }
345
346 return(TRUE);
347 }
348
349 static VOID
350 FrLdrLoadBootDrivers(PCHAR szSystemRoot,
351 INT nPos)
352 {
353 LONG rc = 0;
354 FRLDRHKEY hGroupKey, hOrderKey, hServiceKey, hDriverKey;
355 WCHAR GroupNameBuffer[512];
356 WCHAR ServiceName[256];
357 ULONG OrderList[128];
358 ULONG BufferSize;
359 ULONG Index;
360 ULONG TagIndex;
361 LPWSTR GroupName;
362
363 ULONG ValueSize;
364 ULONG ValueType;
365 ULONG StartValue;
366 ULONG TagValue;
367 WCHAR DriverGroup[256];
368 ULONG DriverGroupSize;
369
370 CHAR ImagePath[256];
371 WCHAR TempImagePath[256];
372
373 /* get 'service group order' key */
374 rc = RegOpenKey(NULL,
375 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
376 &hGroupKey);
377 if (rc != ERROR_SUCCESS) {
378
379 DPRINTM(DPRINT_REACTOS, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc);
380 return;
381 }
382
383 /* get 'group order list' key */
384 rc = RegOpenKey(NULL,
385 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
386 &hOrderKey);
387 if (rc != ERROR_SUCCESS) {
388
389 DPRINTM(DPRINT_REACTOS, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc);
390 return;
391 }
392
393 /* enumerate drivers */
394 rc = RegOpenKey(NULL,
395 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
396 &hServiceKey);
397 if (rc != ERROR_SUCCESS) {
398
399 DPRINTM(DPRINT_REACTOS, "Failed to open the 'Services' key (rc %d)\n", (int)rc);
400 return;
401 }
402
403 /* Get the Name Group */
404 BufferSize = sizeof(GroupNameBuffer);
405 rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize);
406 DPRINTM(DPRINT_REACTOS, "RegQueryValue(): rc %d\n", (int)rc);
407 if (rc != ERROR_SUCCESS) return;
408 DPRINTM(DPRINT_REACTOS, "BufferSize: %d \n", (int)BufferSize);
409 DPRINTM(DPRINT_REACTOS, "GroupNameBuffer: '%S' \n", GroupNameBuffer);
410
411 /* Loop through each group */
412 GroupName = GroupNameBuffer;
413 while (*GroupName) {
414 DPRINTM(DPRINT_REACTOS, "Driver group: '%S'\n", GroupName);
415
416 /* Query the Order */
417 BufferSize = sizeof(OrderList);
418 rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize);
419 if (rc != ERROR_SUCCESS) OrderList[0] = 0;
420
421 /* enumerate all drivers */
422 for (TagIndex = 1; TagIndex <= SWAPD(OrderList[0]); TagIndex++) {
423
424 Index = 0;
425
426 while (TRUE) {
427
428 /* Get the Driver's Name */
429 ValueSize = sizeof(ServiceName);
430 rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
431 DPRINTM(DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
432
433 /* Makre sure it's valid, and check if we're done */
434 if (rc == ERROR_NO_MORE_ITEMS) break;
435 if (rc != ERROR_SUCCESS) return;
436 DPRINTM(DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
437
438 /* open driver Key */
439 rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
440 if (rc == ERROR_SUCCESS)
441 {
442 /* Read the Start Value */
443 ValueSize = sizeof(ULONG);
444 rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
445 if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
446 DPRINTM(DPRINT_REACTOS, " Start: %x \n", (int)StartValue);
447
448 /* Read the Tag */
449 ValueSize = sizeof(ULONG);
450 rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
451 if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
452 DPRINTM(DPRINT_REACTOS, " Tag: %x \n", (int)TagValue);
453
454 /* Read the driver's group */
455 DriverGroupSize = sizeof(DriverGroup);
456 rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
457 DPRINTM(DPRINT_REACTOS, " Group: '%S' \n", DriverGroup);
458
459 /* Make sure it should be started */
460 if ((StartValue == 0) &&
461 (TagValue == OrderList[TagIndex]) &&
462 (_wcsicmp(DriverGroup, GroupName) == 0)) {
463
464 /* Get the Driver's Location */
465 ValueSize = sizeof(TempImagePath);
466 rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
467
468 /* Write the whole path if it suceeded, else prepare to fail */
469 if (rc != ERROR_SUCCESS) {
470 DPRINTM(DPRINT_REACTOS, " ImagePath: not found\n");
471 sprintf(ImagePath, "%s\\system32\\drivers\\%S.sys", szSystemRoot, ServiceName);
472 } else if (TempImagePath[0] != L'\\') {
473 sprintf(ImagePath, "%s%S", szSystemRoot, TempImagePath);
474 } else {
475 sprintf(ImagePath, "%S", TempImagePath);
476 DPRINTM(DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath);
477 }
478
479 DPRINTM(DPRINT_REACTOS, " Loading driver: '%s'\n", ImagePath);
480
481 /* Update the position if needed */
482 if (nPos < 100) nPos += 5;
483
484 FrLdrLoadImage(ImagePath, nPos, 2);
485
486 } else {
487
488 DPRINTM(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
493 Index++;
494 }
495 }
496
497 Index = 0;
498 while (TRUE) {
499
500 /* Get the Driver's Name */
501 ValueSize = sizeof(ServiceName);
502 rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
503
504 DPRINTM(DPRINT_REACTOS, "RegEnumKey(): rc %d\n", (int)rc);
505 if (rc == ERROR_NO_MORE_ITEMS) break;
506 if (rc != ERROR_SUCCESS) return;
507 DPRINTM(DPRINT_REACTOS, "Service %d: '%S'\n", (int)Index, ServiceName);
508
509 /* open driver Key */
510 rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
511 if (rc == ERROR_SUCCESS)
512 {
513 /* Read the Start Value */
514 ValueSize = sizeof(ULONG);
515 rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
516 if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
517 DPRINTM(DPRINT_REACTOS, " Start: %x \n", (int)StartValue);
518
519 /* Read the Tag */
520 ValueSize = sizeof(ULONG);
521 rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
522 if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
523 DPRINTM(DPRINT_REACTOS, " Tag: %x \n", (int)TagValue);
524
525 /* Read the driver's group */
526 DriverGroupSize = sizeof(DriverGroup);
527 rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
528 DPRINTM(DPRINT_REACTOS, " Group: '%S' \n", DriverGroup);
529
530 for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) {
531 if (TagValue == OrderList[TagIndex]) break;
532 }
533
534 if ((StartValue == 0) &&
535 (TagIndex > OrderList[0]) &&
536 (_wcsicmp(DriverGroup, GroupName) == 0)) {
537
538 ValueSize = sizeof(TempImagePath);
539 rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
540 if (rc != ERROR_SUCCESS) {
541 DPRINTM(DPRINT_REACTOS, " ImagePath: not found\n");
542 sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", szSystemRoot, ServiceName);
543 } else if (TempImagePath[0] != L'\\') {
544 sprintf(ImagePath, "%s%S", szSystemRoot, TempImagePath);
545 } else {
546 sprintf(ImagePath, "%S", TempImagePath);
547 DPRINTM(DPRINT_REACTOS, " ImagePath: '%s'\n", ImagePath);
548 }
549 DPRINTM(DPRINT_REACTOS, " Loading driver: '%s'\n", ImagePath);
550
551 if (nPos < 100) nPos += 5;
552
553 FrLdrLoadImage(ImagePath, nPos, 2);
554
555 } else {
556
557 DPRINTM(DPRINT_REACTOS, " Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
558 ServiceName, StartValue, TagValue, DriverGroup, GroupName);
559 }
560 }
561
562 Index++;
563 }
564
565 /* Move to the next group name */
566 GroupName = GroupName + wcslen(GroupName) + 1;
567 }
568 }
569
570 VOID
571 LoadAndBootReactOS(PCSTR OperatingSystemName)
572 {
573 PFILE FilePointer;
574 CHAR name[255];
575 CHAR value[255];
576 CHAR SystemPath[255];
577 CHAR LivePath[255];
578 CHAR szKernelName[255];
579 CHAR szFileName[255];
580 CHAR MsgBuffer[256];
581 ULONG_PTR SectionId;
582 PIMAGE_NT_HEADERS NtHeader;
583 PVOID LoadBase;
584 ULONG_PTR Base;
585 ULONG Size;
586
587 //
588 // Backdrop
589 //
590 UiDrawBackdrop();
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 // Read the command line
605 //
606 if (IniReadSettingByName(SectionId, "Options", value, sizeof(value)))
607 {
608 //
609 // Check if a ramdisk file was given
610 //
611 PCHAR File;
612 File = strstr(value, "/RDIMAGEPATH=");
613 if (File)
614 {
615 //
616 // Copy the file name and everything else after it
617 //
618 strcpy(szFileName, File + 13);
619
620 //
621 // Null-terminate
622 //
623 *strstr(szFileName, " ") = ANSI_NULL;
624
625 //
626 // Load the ramdisk
627 //
628 RamDiskLoadVirtualFile(szFileName);
629 }
630 }
631
632 /*
633 * Setup multiboot information structure
634 */
635 UiDrawProgressBarCenter(1, 100, szLoadingMsg);
636 UiDrawStatusText("Detecting Hardware...");
637 LoaderBlock.CommandLine = reactos_kernel_cmdline;
638 LoaderBlock.PageDirectoryStart = (ULONG_PTR)&PageDirectoryStart;
639 LoaderBlock.PageDirectoryEnd = (ULONG_PTR)&PageDirectoryEnd;
640 LoaderBlock.ModsCount = 0;
641 LoaderBlock.ModsAddr = reactos_modules;
642 LoaderBlock.DrivesAddr = reactos_arc_disk_info;
643 LoaderBlock.RdAddr = (ULONG_PTR)gRamDiskBase;
644 LoaderBlock.RdLength = gRamDiskSize;
645 LoaderBlock.MmapLength = (SIZE_T)MachVtbl.GetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
646 if (LoaderBlock.MmapLength)
647 {
648 ULONG i;
649 LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO;
650 LoaderBlock.MmapAddr = (ULONG_PTR)&reactos_memory_map;
651 reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
652 for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
653 {
654 #ifdef _M_PPC
655 ULONG tmp;
656 /* Also swap from long long to high/low
657 * We also have unusable memory that will be available to kernel
658 * land. Mark it here.
659 */
660 if (BiosMemoryAcpiReclaim == reactos_memory_map[i].type)
661 {
662 reactos_memory_map[i].type = BiosMemoryUsable;
663 }
664
665 tmp = reactos_memory_map[i].base_addr_low;
666 reactos_memory_map[i].base_addr_low = reactos_memory_map[i].base_addr_high;
667 reactos_memory_map[i].base_addr_high = tmp;
668 tmp = reactos_memory_map[i].length_low;
669 reactos_memory_map[i].length_low = reactos_memory_map[i].length_high;
670 reactos_memory_map[i].length_high = tmp;
671 #endif
672
673 if (BiosMemoryUsable == reactos_memory_map[i].type &&
674 0 == reactos_memory_map[i].base_addr_low)
675 {
676 LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024;
677 if (640 < LoaderBlock.MemLower)
678 {
679 LoaderBlock.MemLower = 640;
680 }
681 }
682 if (BiosMemoryUsable == reactos_memory_map[i].type &&
683 reactos_memory_map[i].base_addr_low <= 1024 * 1024 &&
684 1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low)
685 {
686 LoaderBlock.MemHigher = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024 - 1024;
687 }
688 }
689 }
690
691 /*
692 * Initialize the registry
693 */
694 RegInitializeRegistry();
695
696 /*
697 * Make sure the system path is set in the .ini file
698 */
699 if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))
700 {
701 UiMessageBox("System path not specified for selected operating system.");
702 return;
703 }
704
705 /*
706 * Special case for Live CD.
707 */
708 if (!_strnicmp(SystemPath, "LiveCD", strlen("LiveCD")))
709 {
710 /* Use everything following the "LiveCD" string as the path */
711 strcpy(LivePath, SystemPath + strlen("LiveCD"));
712 /* Normalize */
713 MachDiskGetBootPath(SystemPath, sizeof(SystemPath));
714 strcat(SystemPath, LivePath);
715 strcat(strcpy(reactos_kernel_cmdline, SystemPath),
716 " /MININT");
717 }
718 else
719 {
720 if (! MachDiskNormalizeSystemPath(SystemPath,
721 sizeof(SystemPath)))
722 {
723 UiMessageBox("Invalid system path");
724 return;
725 }
726 /* copy system path into kernel command line */
727 strcpy(reactos_kernel_cmdline, SystemPath);
728 }
729
730 /*
731 * Read the optional kernel parameters (if any)
732 */
733 if (IniReadSettingByName(SectionId, "Options", value, sizeof(value)))
734 {
735 strcat(reactos_kernel_cmdline, " ");
736 strcat(reactos_kernel_cmdline, value);
737 }
738
739 /*
740 * Detect hardware
741 */
742 LoaderBlock.ArchExtra = (ULONG_PTR)MachHwDetect();
743 UiDrawProgressBarCenter(5, 100, szLoadingMsg);
744
745 LoaderBlock.DrivesCount = reactos_disk_count;
746
747 UiDrawStatusText("Loading...");
748
749 /* Get boot path */
750 if (strchr(SystemPath, '\\') != NULL)
751 strcpy(szBootPath, strchr(SystemPath, '\\'));
752 else
753 szBootPath[0] = '\0';
754
755 /* append a backslash */
756 if ((strlen(szBootPath)==0) ||
757 szBootPath[strlen(szBootPath)] != '\\')
758 strcat(szBootPath, "\\");
759
760 DPRINTM(DPRINT_REACTOS,"SystemRoot: '%s'\n", szBootPath);
761 strcpy(SystemRoot, szBootPath);
762
763 /*
764 * Find the kernel image name
765 * and try to load the kernel off the disk
766 */
767 if(IniReadSettingByName(SectionId, "Kernel", value, sizeof(value)))
768 {
769 /*
770 * Set the name and
771 */
772 if (value[0] == '\\')
773 {
774 strcpy(szKernelName, value);
775 }
776 else
777 {
778 strcpy(szKernelName, szBootPath);
779 strcat(szKernelName, "SYSTEM32\\");
780 strcat(szKernelName, value);
781 }
782 }
783 else
784 {
785 strcpy(value, "NTOSKRNL.EXE");
786 strcpy(szKernelName, szBootPath);
787 strcat(szKernelName, "SYSTEM32\\");
788 strcat(szKernelName, value);
789 }
790
791 /*
792 * Find the HAL image name
793 * and try to load the kernel off the disk
794 */
795 if(IniReadSettingByName(SectionId, "Hal", value, sizeof(value)))
796 {
797 /*
798 * Set the name and
799 */
800 if (value[0] == '\\')
801 {
802 strcpy(szHalName, value);
803 }
804 else
805 {
806 strcpy(szHalName, szBootPath);
807 strcat(szHalName, "SYSTEM32\\");
808 strcat(szHalName, value);
809 }
810 }
811 else
812 {
813 strcpy(value, "HAL.DLL");
814 strcpy(szHalName, szBootPath);
815 strcat(szHalName, "SYSTEM32\\");
816 strcat(szHalName, value);
817 }
818
819 /* Load the kernel */
820 LoadBase = FrLdrLoadImage(szKernelName, 5, 1);
821 if (!LoadBase) return;
822
823 /* Get the NT header, kernel base and kernel entry */
824 NtHeader = RtlImageNtHeader(LoadBase);
825 KernelBase = SWAPD(NtHeader->OptionalHeader.ImageBase);
826 KernelEntryPoint = (ROS_KERNEL_ENTRY_POINT)(KernelBase + SWAPD(NtHeader->OptionalHeader.AddressOfEntryPoint));
827 LoaderBlock.KernelBase = KernelBase;
828
829 /*
830 * Load the System hive from disk
831 */
832 strcpy(szFileName, szBootPath);
833 strcat(szFileName, "SYSTEM32\\CONFIG\\SYSTEM");
834
835 DPRINTM(DPRINT_REACTOS, "SystemHive: '%s'", szFileName);
836
837 FilePointer = FsOpenFile(szFileName);
838 if (!FilePointer)
839 {
840 UiMessageBox("Could not find the System hive!");
841 return;
842 }
843
844 /*
845 * Update the status bar with the current file
846 */
847 strcpy(name, "Reading ");
848 strcat(name, value);
849 while (strlen(name) < 80)
850 strcat(name, " ");
851 UiDrawStatusText(name);
852
853 /*
854 * Load the System hive
855 */
856 Base = FrLdrLoadModule(FilePointer, szFileName, &Size);
857 if (Base == 0 || Size == 0)
858 {
859 UiMessageBox("Could not load the System hive!\n");
860 return;
861 }
862 DPRINTM(DPRINT_REACTOS, "SystemHive loaded at 0x%x size %u\n", (unsigned)Base, (unsigned)Size);
863
864 /*
865 * Import the loaded system hive
866 */
867 RegImportBinaryHive((PCHAR)Base, Size);
868
869 /*
870 * Initialize the 'CurrentControlSet' link
871 */
872 RegInitCurrentControlSet(FALSE);
873
874 UiDrawProgressBarCenter(15, 100, szLoadingMsg);
875
876 UiDrawProgressBarCenter(20, 100, szLoadingMsg);
877
878 /*
879 * Load NLS files
880 */
881 if (!FrLdrLoadNlsFiles(szBootPath, MsgBuffer))
882 {
883 UiMessageBox(MsgBuffer);
884 return;
885 }
886 UiDrawProgressBarCenter(30, 100, szLoadingMsg);
887
888 /*
889 * Load boot drivers
890 */
891 FrLdrLoadBootDrivers(szBootPath, 40);
892 //UiUnInitialize("Booting ReactOS...");
893
894 //
895 // Perform architecture-specific pre-boot configuration
896 //
897 MachPrepareForReactOS(FALSE);
898
899 //
900 // Setup paging and jump to kernel
901 //
902 FrLdrStartup(0x2badb002);
903 }
904
905 /* EOF */