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