- Change DbgPrint prototype back to Alex's fix. His change was correct and my commit...
[reactos.git] / reactos / boot / freeldr / freeldr / reactos / reactos.c
1 /*
2 * FreeLoader
3 *
4 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
5 * Copyright (C) 2005 Alex Ionescu <alex@relsoft.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include <freeldr.h>
23
24 #define NDEBUG
25 #include <debug.h>
26
27 ROS_LOADER_PARAMETER_BLOCK LoaderBlock;
28 char reactos_kernel_cmdline[255]; // Command line passed to kernel
29 LOADER_MODULE reactos_modules[64]; // Array to hold boot module info loaded for the kernel
30 char reactos_module_strings[64][256]; // Array to hold module names
31 unsigned long reactos_memory_map_descriptor_size;
32 memory_map_t reactos_memory_map[32]; // Memory map
33
34 static CHAR szLoadingMsg[] = "Loading ReactOS...";
35
36 static BOOLEAN
37 NTAPI
38 FrLdrLoadKernel(PCHAR szFileName,
39 INT nPos)
40 {
41 PFILE FilePointer;
42 PCHAR szShortName;
43 CHAR szBuffer[256];
44
45 /* Extract Kernel filename without path */
46 szShortName = strrchr(szFileName, '\\');
47 if (szShortName == NULL) {
48
49 /* No path, leave it alone */
50 szShortName = szFileName;
51
52 } else {
53
54 /* Skip the path */
55 szShortName = szShortName + 1;
56 }
57
58 /* Open the Kernel */
59 FilePointer = FsOpenFile(szFileName);
60
61 /* Make sure it worked */
62 if (FilePointer == NULL) {
63
64 /* Return failure on the short name */
65 strcpy(szBuffer, szShortName);
66 strcat(szBuffer, " not found.");
67 UiMessageBox(szBuffer);
68 return(FALSE);
69 }
70
71 /* Update the status bar with the current file */
72 strcpy(szBuffer, "Reading ");
73 strcat(szBuffer, szShortName);
74 UiDrawStatusText(szBuffer);
75
76 /* Do the actual loading */
77 FrLdrMapKernel(FilePointer);
78
79 /* Update Processbar and return success */
80 UiDrawProgressBarCenter(nPos, 100, szLoadingMsg);
81 return(TRUE);
82 }
83
84 static VOID
85 FreeldrFreeMem(PVOID Area)
86 {
87 MmFreeMemory(Area);
88 }
89
90 static PVOID
91 FreeldrAllocMem(ULONG_PTR Size)
92 {
93 return MmAllocateMemory((ULONG) Size);
94 }
95
96 static BOOLEAN
97 FreeldrReadFile(PVOID FileContext, PVOID Buffer, ULONG Size)
98 {
99 ULONG BytesRead;
100
101 return FsReadFile((PFILE) FileContext, (ULONG) Size, &BytesRead, Buffer)
102 && Size == BytesRead;
103 }
104
105 static BOOLEAN
106 FreeldrSeekFile(PVOID FileContext, ULONG_PTR Position)
107 {
108 FsSetFilePointer((PFILE) FileContext, (ULONG) Position);
109 return TRUE;
110 }
111
112 static BOOLEAN
113 LoadKernelSymbols(PCHAR szKernelName, int nPos)
114 {
115 static ROSSYM_CALLBACKS FreeldrCallbacks =
116 {
117 FreeldrAllocMem,
118 FreeldrFreeMem,
119 FreeldrReadFile,
120 FreeldrSeekFile
121 };
122 PFILE FilePointer;
123 PROSSYM_INFO RosSymInfo;
124 ULONG Size;
125 ULONG_PTR Base;
126
127 RosSymInit(&FreeldrCallbacks);
128
129 FilePointer = FsOpenFile(szKernelName);
130 if (FilePointer == NULL)
131 {
132 return FALSE;
133 }
134 if (! RosSymCreateFromFile(FilePointer, &RosSymInfo))
135 {
136 return FALSE;
137 }
138 Base = FrLdrCreateModule("NTOSKRNL.SYM");
139 Size = RosSymGetRawDataLength(RosSymInfo);
140 RosSymGetRawData(RosSymInfo, (PVOID)Base);
141 FrLdrCloseModule(Base, Size);
142 RosSymDelete(RosSymInfo);
143 return TRUE;
144 }
145
146 static BOOLEAN
147 FrLdrLoadNlsFile(PCSTR szFileName,
148 PCSTR szModuleName)
149 {
150 PFILE FilePointer;
151 CHAR value[256];
152 LPSTR p;
153
154 /* Open the Driver */
155 FilePointer = FsOpenFile(szFileName);
156
157 /* Make sure we did */
158 if (FilePointer == NULL) {
159
160 /* Fail if file wasn't opened */
161 strcpy(value, szFileName);
162 strcat(value, " not found.");
163 UiMessageBox(value);
164 return(FALSE);
165 }
166
167 /* Update the status bar with the current file */
168 strcpy(value, "Reading ");
169 p = strrchr(szFileName, '\\');
170 if (p == NULL) {
171
172 strcat(value, szFileName);
173
174 } else {
175
176 strcat(value, p + 1);
177 }
178 UiDrawStatusText(value);
179
180 /* Load the driver */
181 FrLdrLoadModule(FilePointer, szModuleName, NULL);
182 return(TRUE);
183 }
184
185 static BOOLEAN
186 FrLdrLoadNlsFiles(PCHAR szSystemRoot,
187 PCHAR szErrorOut)
188 {
189 LONG rc = ERROR_SUCCESS;
190 FRLDRHKEY hKey;
191 WCHAR szIdBuffer[80];
192 WCHAR szNameBuffer[80];
193 CHAR szFileName[256];
194 ULONG BufferSize;
195
196 /* open the codepage key */
197 rc = RegOpenKey(NULL,
198 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage",
199 &hKey);
200 if (rc != ERROR_SUCCESS) {
201
202 strcpy(szErrorOut, "Couldn't open CodePage registry key");
203 return(FALSE);
204 }
205
206 /* get ANSI codepage */
207 BufferSize = sizeof(szIdBuffer);
208 rc = RegQueryValue(hKey, L"ACP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
209 if (rc != ERROR_SUCCESS) {
210
211 strcpy(szErrorOut, "Couldn't get ACP NLS setting");
212 return(FALSE);
213 }
214
215 BufferSize = sizeof(szNameBuffer);
216 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
217 if (rc != ERROR_SUCCESS) {
218
219 strcpy(szErrorOut, "ACP NLS Setting exists, but isn't readable");
220 return(FALSE);
221 }
222
223 /* load ANSI codepage table */
224 sprintf(szFileName,"%ssystem32\\%S", szSystemRoot, szNameBuffer);
225 DbgPrint((DPRINT_REACTOS, "ANSI file: %s\n", szFileName));
226 if (!FrLdrLoadNlsFile(szFileName, "ansi.nls")) {
227
228 strcpy(szErrorOut, "Couldn't load ansi.nls");
229 return(FALSE);
230 }
231
232 /* get OEM codepage */
233 BufferSize = sizeof(szIdBuffer);
234 rc = RegQueryValue(hKey, L"OEMCP", NULL, (PUCHAR)szIdBuffer, &BufferSize);
235 if (rc != ERROR_SUCCESS) {
236
237 strcpy(szErrorOut, "Couldn't get OEMCP NLS setting");
238 return(FALSE);
239 }
240
241 BufferSize = sizeof(szNameBuffer);
242 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
243 if (rc != ERROR_SUCCESS) {
244
245 strcpy(szErrorOut, "OEMCP NLS setting exists, but isn't readable");
246 return(FALSE);
247 }
248
249 /* load OEM codepage table */
250 sprintf(szFileName, "%ssystem32\\%S", szSystemRoot, szNameBuffer);
251 DbgPrint((DPRINT_REACTOS, "Oem file: %s\n", szFileName));
252 if (!FrLdrLoadNlsFile(szFileName, "oem.nls")) {
253
254 strcpy(szErrorOut, "Couldn't load oem.nls");
255 return(FALSE);
256 }
257
258 /* open the language key */
259 rc = RegOpenKey(NULL,
260 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language",
261 &hKey);
262 if (rc != ERROR_SUCCESS) {
263
264 strcpy(szErrorOut, "Couldn't open Language registry key");
265 return(FALSE);
266 }
267
268 /* get the Unicode case table */
269 BufferSize = sizeof(szIdBuffer);
270 rc = RegQueryValue(hKey, L"Default", NULL, (PUCHAR)szIdBuffer, &BufferSize);
271 if (rc != ERROR_SUCCESS) {
272
273 strcpy(szErrorOut, "Couldn't get Language Default setting");
274 return(FALSE);
275 }
276
277 BufferSize = sizeof(szNameBuffer);
278 rc = RegQueryValue(hKey, szIdBuffer, NULL, (PUCHAR)szNameBuffer, &BufferSize);
279 if (rc != ERROR_SUCCESS) {
280
281 strcpy(szErrorOut, "Language Default setting exists, but isn't readable");
282 return(FALSE);
283 }
284
285 /* load Unicode case table */
286 sprintf(szFileName, "%ssystem32\\%S", szSystemRoot, szNameBuffer);
287 DbgPrint((DPRINT_REACTOS, "Casemap file: %s\n", szFileName));
288 if (!FrLdrLoadNlsFile(szFileName, "casemap.nls")) {
289
290 strcpy(szErrorOut, "casemap.nls");
291 return(FALSE);
292 }
293
294 return(TRUE);
295 }
296
297 static BOOLEAN
298 FrLdrLoadDriver(PCHAR szFileName,
299 INT nPos)
300 {
301 PFILE FilePointer;
302 CHAR value[256];
303 LPSTR p;
304
305 /* Open the Driver */
306 FilePointer = FsOpenFile(szFileName);
307
308 /* Make sure we did */
309 if (FilePointer == NULL) {
310
311 /* Fail if file wasn't opened */
312 strcpy(value, szFileName);
313 strcat(value, " not found.");
314 UiMessageBox(value);
315 return(FALSE);
316 }
317
318 /* Update the status bar with the current file */
319 strcpy(value, "Reading ");
320 p = strrchr(szFileName, '\\');
321 if (p == NULL) {
322
323 strcat(value, szFileName);
324
325 } else {
326
327 strcat(value, p + 1);
328
329 }
330 UiDrawStatusText(value);
331
332 /* Load the driver */
333 FrLdrLoadModule(FilePointer, szFileName, NULL);
334
335 /* Update status and return */
336 UiDrawProgressBarCenter(nPos, 100, szLoadingMsg);
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 <= 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 FrLdrLoadDriver(ImagePath, nPos);
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 FrLdrLoadDriver(ImagePath, nPos);
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[1024];
566 CHAR value[1024];
567 CHAR SystemPath[1024];
568 CHAR szKernelName[1024];
569 CHAR szHalName[1024];
570 CHAR szFileName[1024];
571 CHAR szBootPath[256];
572 UINT i;
573 CHAR MsgBuffer[256];
574 ULONG SectionId;
575
576 ULONG_PTR Base;
577 ULONG Size;
578
579 extern ULONG PageDirectoryStart;
580 extern ULONG PageDirectoryEnd;
581 extern BOOLEAN AcpiPresent;
582
583 //
584 // Open the operating system section
585 // specified in the .ini file
586 //
587 if (!IniOpenSection(OperatingSystemName, &SectionId))
588 {
589 sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);
590 UiMessageBox(MsgBuffer);
591 return;
592 }
593
594 UiDrawBackdrop();
595 UiDrawStatusText("Detecting Hardware...");
596 UiDrawProgressBarCenter(1, 100, szLoadingMsg);
597
598 /*
599 * Setup multiboot information structure
600 */
601 LoaderBlock.Flags = MB_FLAGS_BOOT_DEVICE | MB_FLAGS_COMMAND_LINE | MB_FLAGS_MODULE_INFO;
602 LoaderBlock.PageDirectoryStart = (ULONG)&PageDirectoryStart;
603 LoaderBlock.PageDirectoryEnd = (ULONG)&PageDirectoryEnd;
604 LoaderBlock.BootDevice = 0xffffffff;
605 LoaderBlock.CommandLine = (unsigned long)reactos_kernel_cmdline;
606 LoaderBlock.ModsCount = 0;
607 LoaderBlock.ModsAddr = (unsigned long)reactos_modules;
608 LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)(PVOID)&reactos_memory_map, 32) * sizeof(memory_map_t);
609 if (LoaderBlock.MmapLength)
610 {
611 LoaderBlock.MmapAddr = (unsigned long)&reactos_memory_map;
612 LoaderBlock.Flags |= MB_FLAGS_MEM_INFO | MB_FLAGS_MMAP_INFO;
613 reactos_memory_map_descriptor_size = sizeof(memory_map_t); // GetBiosMemoryMap uses a fixed value of 24
614 DbgPrint((DPRINT_REACTOS, "memory map length: %d\n", LoaderBlock.MmapLength));
615 DbgPrint((DPRINT_REACTOS, "dumping memory map:\n"));
616 for (i=0; i<(LoaderBlock.MmapLength/sizeof(memory_map_t)); i++)
617 {
618 if (MEMTYPE_USABLE == reactos_memory_map[i].type &&
619 0 == reactos_memory_map[i].base_addr_low)
620 {
621 LoaderBlock.MemLower = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024;
622 if (640 < LoaderBlock.MemLower)
623 {
624 LoaderBlock.MemLower = 640;
625 }
626 }
627 if (MEMTYPE_USABLE == reactos_memory_map[i].type &&
628 reactos_memory_map[i].base_addr_low <= 1024 * 1024 &&
629 1024 * 1024 <= reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low)
630 {
631 LoaderBlock.MemHigher = (reactos_memory_map[i].base_addr_low + reactos_memory_map[i].length_low) / 1024 - 1024;
632 }
633 DbgPrint((DPRINT_REACTOS, "start: %x\t size: %x\t type %d\n",
634 reactos_memory_map[i].base_addr_low,
635 reactos_memory_map[i].length_low,
636 reactos_memory_map[i].type));
637 }
638 }
639 DbgPrint((DPRINT_REACTOS, "low_mem = %d\n", LoaderBlock.MemLower));
640 DbgPrint((DPRINT_REACTOS, "high_mem = %d\n", LoaderBlock.MemHigher));
641
642 /*
643 * Initialize the registry
644 */
645 RegInitializeRegistry();
646
647 /*
648 * Make sure the system path is set in the .ini file
649 */
650 if (!IniReadSettingByName(SectionId, "SystemPath", SystemPath, sizeof(SystemPath)))
651 {
652 UiMessageBox("System path not specified for selected operating system.");
653 return;
654 }
655
656 /*
657 * Special case for Live CD.
658 */
659 if (!_stricmp(SystemPath, "LiveCD"))
660 {
661 /* Normalize */
662 MachDiskGetBootPath(SystemPath, sizeof(SystemPath));
663 strcat(SystemPath, "\\reactos");
664 strcat(strcpy(reactos_kernel_cmdline, SystemPath),
665 " /MININT");
666 }
667 else
668 {
669 if (! MachDiskNormalizeSystemPath(SystemPath,
670 sizeof(SystemPath)))
671 {
672 UiMessageBox("Invalid system path");
673 return;
674 }
675 /* copy system path into kernel command line */
676 strcpy(reactos_kernel_cmdline, SystemPath);
677 }
678
679 /*
680 * Read the optional kernel parameters (if any)
681 */
682 if (IniReadSettingByName(SectionId, "Options", value, 1024))
683 {
684 strcat(reactos_kernel_cmdline, " ");
685 strcat(reactos_kernel_cmdline, value);
686 }
687
688 /*
689 * Detect hardware
690 */
691 MachHwDetect();
692 UiDrawProgressBarCenter(5, 100, szLoadingMsg);
693
694 if (AcpiPresent) LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE;
695
696 UiDrawStatusText("Loading...");
697
698 /*
699 * Try to open system drive
700 */
701 if (!FsOpenSystemVolume(SystemPath, szBootPath, &LoaderBlock.BootDevice))
702 {
703 UiMessageBox("Failed to open boot drive.");
704 return;
705 }
706
707 /* append a backslash */
708 if ((strlen(szBootPath)==0) ||
709 szBootPath[strlen(szBootPath)] != '\\')
710 strcat(szBootPath, "\\");
711
712 DbgPrint((DPRINT_REACTOS,"SystemRoot: '%s'\n", szBootPath));
713
714 /*
715 * Find the kernel image name
716 * and try to load the kernel off the disk
717 */
718 if(IniReadSettingByName(SectionId, "Kernel", value, 1024))
719 {
720 /*
721 * Set the name and
722 */
723 if (value[0] == '\\')
724 {
725 strcpy(szKernelName, value);
726 }
727 else
728 {
729 strcpy(szKernelName, szBootPath);
730 strcat(szKernelName, "SYSTEM32\\");
731 strcat(szKernelName, value);
732 }
733 }
734 else
735 {
736 strcpy(value, "NTOSKRNL.EXE");
737 strcpy(szKernelName, szBootPath);
738 strcat(szKernelName, "SYSTEM32\\");
739 strcat(szKernelName, value);
740 }
741
742 if (!FrLdrLoadKernel(szKernelName, 5)) return;
743
744 /*
745 * Find the HAL image name
746 * and try to load the kernel off the disk
747 */
748 if(IniReadSettingByName(SectionId, "Hal", value, 1024))
749 {
750 /*
751 * Set the name and
752 */
753 if (value[0] == '\\')
754 {
755 strcpy(szHalName, value);
756 }
757 else
758 {
759 strcpy(szHalName, szBootPath);
760 strcat(szHalName, "SYSTEM32\\");
761 strcat(szHalName, value);
762 }
763 }
764 else
765 {
766 strcpy(value, "HAL.DLL");
767 strcpy(szHalName, szBootPath);
768 strcat(szHalName, "SYSTEM32\\");
769 strcat(szHalName, value);
770 }
771
772 if (!FrLdrLoadDriver(szHalName, 10))
773 return;
774
775 #if 0
776 /* Load bootvid */
777 strcpy(value, "INBV.DLL");
778 strcpy(szHalName, szBootPath);
779 strcat(szHalName, "SYSTEM32\\");
780 strcat(szHalName, value);
781
782 if (!FrLdrLoadDriver(szHalName, 10))
783 return;
784 #endif
785 /*
786 * Load the System hive from disk
787 */
788 strcpy(szFileName, szBootPath);
789 strcat(szFileName, "SYSTEM32\\CONFIG\\SYSTEM");
790
791 DbgPrint((DPRINT_REACTOS, "SystemHive: '%s'", szFileName));
792
793 FilePointer = FsOpenFile(szFileName);
794 if (FilePointer == NULL)
795 {
796 UiMessageBox("Could not find the System hive!");
797 return;
798 }
799
800 /*
801 * Update the status bar with the current file
802 */
803 strcpy(name, "Reading ");
804 strcat(name, value);
805 while (strlen(name) < 80)
806 strcat(name, " ");
807 UiDrawStatusText(name);
808
809 /*
810 * Load the System hive
811 */
812 Base = FrLdrLoadModule(FilePointer, szFileName, &Size);
813 if (Base == 0 || Size == 0)
814 {
815 UiMessageBox("Could not load the System hive!\n");
816 return;
817 }
818 DbgPrint((DPRINT_REACTOS, "SystemHive loaded at 0x%x size %u", (unsigned)Base, (unsigned)Size));
819
820 /*
821 * Import the loaded system hive
822 */
823 RegImportBinaryHive((PCHAR)Base, Size);
824
825 /*
826 * Initialize the 'CurrentControlSet' link
827 */
828 RegInitCurrentControlSet(FALSE);
829
830 UiDrawProgressBarCenter(15, 100, szLoadingMsg);
831
832 /*
833 * Export the hardware hive
834 */
835 Base = FrLdrCreateModule ("HARDWARE");
836 RegExportBinaryHive (L"\\Registry\\Machine\\HARDWARE", (PCHAR)Base, &Size);
837 FrLdrCloseModule (Base, Size);
838
839 UiDrawProgressBarCenter(20, 100, szLoadingMsg);
840
841 /*
842 * Load NLS files
843 */
844 if (!FrLdrLoadNlsFiles(szBootPath, MsgBuffer))
845 {
846 UiMessageBox(MsgBuffer);
847 return;
848 }
849 UiDrawProgressBarCenter(30, 100, szLoadingMsg);
850
851 /*
852 * Load kernel symbols
853 */
854 LoadKernelSymbols(szKernelName, 30);
855 UiDrawProgressBarCenter(40, 100, szLoadingMsg);
856
857 /*
858 * Load boot drivers
859 */
860 FrLdrLoadBootDrivers(szBootPath, 40);
861 UiUnInitialize("Booting ReactOS...");
862
863 /*
864 * Now boot the kernel
865 */
866 DiskStopFloppyMotor();
867 MachVideoPrepareForReactOS();
868 FrLdrStartup(0x2badb002);
869 }
870
871 #undef DbgPrint
872 ULONG
873 DbgPrint(const char *Fmt, ...)
874 {
875 UiMessageBox(Fmt);
876 return 0;
877 }
878
879 /* EOF */