Added system hive support.
[reactos.git] / freeldr / freeldr / reactos / reactos.c
1 /*
2 * FreeLoader
3 *
4 * Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "../freeldr.h"
22 #include "../asmcode.h"
23 #include "reactos.h"
24 #include "../stdlib.h"
25 #include "../fs.h"
26 #include "../tui.h"
27 #include "../multiboot.h"
28 #include "../arcname.h"
29 #include "../memory.h"
30 #include "../parseini.h"
31
32 #include "registry.h"
33
34
35 #define NDEBUG
36
37
38 static BOOL
39 LoadKernel(PCHAR szFileName, int nPos)
40 {
41 PFILE FilePointer;
42 PCHAR szShortName;
43 char szBuffer[256];
44
45 szShortName = strrchr(szFileName, '\\');
46 if (szShortName == NULL)
47 szShortName = szFileName;
48 else
49 szShortName = szShortName + 1;
50
51 FilePointer = OpenFile(szFileName);
52 if (FilePointer == NULL)
53 {
54 strcat(szBuffer, szShortName);
55 strcat(szBuffer, " not found.");
56 MessageBox(szBuffer);
57 return(FALSE);
58 }
59
60 /*
61 * Update the status bar with the current file
62 */
63 strcpy(szBuffer, " Reading ");
64 strcat(szBuffer, szShortName);
65 DrawStatusText(szBuffer);
66
67 /*
68 * Load the kernel
69 */
70 MultiBootLoadKernel(FilePointer);
71
72 DrawProgressBar(nPos);
73
74 return(TRUE);
75 }
76
77
78 static BOOL
79 LoadDriver(PCHAR szFileName, int nPos)
80 {
81 PFILE FilePointer;
82 char value[256];
83 char *p;
84
85 FilePointer = OpenFile(szFileName);
86 if (FilePointer == NULL)
87 {
88 strcat(value, szFileName);
89 strcat(value, " not found.");
90 MessageBox(value);
91 return(FALSE);
92 }
93
94 /*
95 * Update the status bar with the current file
96 */
97 strcpy(value, " Reading ");
98 p = strrchr(szFileName, '\\');
99 if (p == NULL)
100 strcat(value, szFileName);
101 else
102 strcat(value, p + 1);
103 while (strlen(value) < 80)
104 strcat(value, " ");
105 DrawStatusText(value);
106
107 /*
108 * Load the driver
109 */
110 MultiBootLoadModule(FilePointer, szFileName, NULL);
111
112 DrawProgressBar(nPos);
113
114 return(TRUE);
115 }
116
117
118 static VOID
119 LoadBootDrivers(PCHAR szSystemRoot, int nPos)
120 {
121 LONG rc = 0;
122 HKEY hGroupKey, hServiceKey, hDriverKey;
123 char ValueBuffer[256];
124 char ServiceName[256];
125 ULONG BufferSize;
126 ULONG Index;
127 char *s, *p;
128 char GroupName[256];
129 ULONG len;
130 BOOL done;
131
132 ULONG ValueSize;
133 ULONG ValueType;
134 ULONG StartValue;
135 UCHAR DriverGroup[256];
136 ULONG DriverGroupSize;
137
138 UCHAR ImagePath[256];
139
140 /* get 'service group order' key */
141 rc = RegOpenKey(NULL,
142 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
143 &hGroupKey);
144 // printf("RegOpenKey(): rc %d\n", (int)rc);
145 if (rc != ERROR_SUCCESS)
146 return;
147
148 /* enumerate drivers */
149 rc = RegOpenKey(NULL,
150 "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
151 &hServiceKey);
152 // printf("RegOpenKey(): rc %d\n", (int)rc);
153 if (rc != ERROR_SUCCESS)
154 return;
155
156 // printf("hKey: %x\n", (int)hKey);
157
158 BufferSize = 256;
159 rc = RegQueryValue(hGroupKey, "List", NULL, (PUCHAR)ValueBuffer, &BufferSize);
160 // printf("RegQueryValue(): rc %d\n", (int)rc);
161 if (rc != ERROR_SUCCESS)
162 return;
163
164
165 // printf("BufferSize: %d \n", (int)BufferSize);
166
167 // printf("ValueBuffer: '%s' \n", ValueBuffer);
168
169 done = FALSE;
170 s = ValueBuffer;
171 do
172 {
173 p = strchr(s, ';');
174 if (p != NULL)
175 {
176 len = p - s;
177 memcpy(GroupName, s, len);
178 GroupName[len] = 0;
179 s = p + 1;
180 }
181 else
182 {
183 strcpy(GroupName, s);
184 done = TRUE;
185 }
186 // printf("Driver group: '%s'\n", GroupName);
187
188 /* enumerate all drivers */
189 Index = 0;
190 while (TRUE)
191 {
192 ValueSize = 256;
193 rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
194 // printf("RegEnumKey(): rc %d\n", (int)rc);
195 if (rc == ERROR_NO_MORE_ITEMS)
196 break;
197 if (rc != ERROR_SUCCESS)
198 return;
199 // printf("Service %d: '%s'\n", (int)Index, ServiceName);
200
201 /* open driver Key */
202 rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
203
204 ValueSize = sizeof(ULONG);
205 rc = RegQueryValue(hDriverKey, "Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
206 // printf(" Start: %x \n", (int)StartValue);
207
208 DriverGroupSize = 256;
209 rc = RegQueryValue(hDriverKey, "Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
210 // printf(" Group: %s \n", DriverGroup);
211
212 if ((StartValue == 0) && (stricmp(DriverGroup, GroupName) == 0))
213 {
214 ValueSize = 256;
215 rc = RegQueryValue(hDriverKey,
216 "ImagePathName",
217 NULL,
218 (PUCHAR)ImagePath,
219 &ValueSize);
220 if (rc != ERROR_SUCCESS)
221 {
222 // printf(" ImagePath: not found\n");
223 strcpy(ImagePath, szSystemRoot);
224 strcat(ImagePath, "system32\\drivers\\");
225 strcat(ImagePath, ServiceName);
226 strcat(ImagePath, ".sys");
227 }
228 else
229 {
230 // printf(" ImagePath: '%s'\n", ImagePath);
231 }
232 // printf(" Loading driver: '%s'\n", ImagePath);
233
234 LoadDriver(ImagePath, nPos);
235
236 if (nPos < 100)
237 nPos += 5;
238 }
239 Index++;
240 }
241 }
242 while(done == FALSE);
243
244 }
245
246 void LoadAndBootReactOS(PUCHAR OperatingSystemName)
247 {
248 PFILE FilePointer;
249 char name[1024];
250 char value[1024];
251 char szFileName[1024];
252 char szBootPath[256];
253 // int i;
254 // int nNumDriverFiles=0;
255 // int nNumFilesLoaded=0;
256 char MsgBuffer[256];
257 ULONG SectionId;
258
259 char* Base;
260 ULONG Size;
261
262 //
263 // Open the operating system section
264 // specified in the .ini file
265 //
266 if (!OpenSection(OperatingSystemName, &SectionId))
267 {
268 sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);
269 MessageBox(MsgBuffer);
270 return;
271 }
272
273 /*
274 * Setup multiboot information structure
275 */
276 mb_info.flags = MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_BOOT_DEVICE | MB_INFO_FLAG_COMMAND_LINE | MB_INFO_FLAG_MODULES;
277 mb_info.mem_lower = GetConventionalMemorySize();
278 mb_info.mem_upper = GetExtendedMemorySize();
279 mb_info.boot_device = 0xffffffff;
280 mb_info.cmdline = (unsigned long)multiboot_kernel_cmdline;
281 mb_info.mods_count = 0;
282 mb_info.mods_addr = (unsigned long)multiboot_modules;
283 mb_info.mmap_length = GetBiosMemoryMap(&multiboot_memory_map);
284 if (mb_info.mmap_length)
285 {
286 mb_info.mmap_addr = (unsigned long)&multiboot_memory_map;
287 mb_info.flags |= MB_INFO_FLAG_MEMORY_MAP;
288 //printf("memory map length: %d\n", mb_info.mmap_length);
289 //printf("dumping memory map:\n");
290 //for (i=0; i<(mb_info.mmap_length / 4); i++)
291 //{
292 // printf("0x%x\n", ((unsigned long *)&multiboot_memory_map)[i]);
293 //}
294 //getch();
295 }
296 //printf("low_mem = %d\n", mb_info.mem_lower);
297 //printf("high_mem = %d\n", mb_info.mem_upper);
298 //getch();
299
300 /*
301 * Make sure the system path is set in the .ini file
302 */
303 if (!ReadSectionSettingByName(SectionId, "SystemPath", value, 1024))
304 {
305 MessageBox("System path not specified for selected operating system.");
306 return;
307 }
308
309 /*
310 * Verify system path
311 */
312 if (!DissectArcPath(value, szBootPath, &BootDrive, &BootPartition))
313 {
314 sprintf(MsgBuffer,"Invalid system path: '%s'", value);
315 MessageBox(MsgBuffer);
316 return;
317 }
318
319 /* set boot drive and partition */
320 ((char *)(&mb_info.boot_device))[0] = (char)BootDrive;
321 ((char *)(&mb_info.boot_device))[1] = (char)BootPartition;
322
323 /* copy ARC path into kernel command line */
324 strcpy(multiboot_kernel_cmdline, value);
325
326 /*
327 * Read the optional kernel parameters (if any)
328 */
329 if (ReadSectionSettingByName(SectionId, "Options", value, 1024))
330 {
331 strcat(multiboot_kernel_cmdline, " ");
332 strcat(multiboot_kernel_cmdline, value);
333 }
334
335 /* append a backslash */
336 if ((strlen(szBootPath)==0) ||
337 szBootPath[strlen(szBootPath)] != '\\')
338 strcat(szBootPath, "\\");
339
340 #ifndef NDEBUG
341 sprintf(MsgBuffer,"SystemRoot: '%s'", szBootPath);
342 MessageBox(MsgBuffer);
343 #endif
344
345 DrawBackdrop();
346
347 DrawStatusText(" Loading...");
348 DrawProgressBar(0);
349
350 /*
351 * Try to open boot drive
352 */
353 if (!OpenDiskDrive(BootDrive, BootPartition))
354 {
355 MessageBox("Failed to open boot drive.");
356 return;
357 }
358
359 /*
360 * Find the kernel image name
361 * and try to load the kernel off the disk
362 */
363 if(ReadSectionSettingByName(SectionId, "Kernel", value, 1024))
364 {
365 /*
366 * Set the name and
367 */
368 if (value[0] == '\\')
369 {
370 strcpy(szFileName, value);
371 }
372 else
373 {
374 strcpy(szFileName, szBootPath);
375 strcat(szFileName, "SYSTEM32\\");
376 strcat(szFileName, value);
377 }
378 }
379 else
380 {
381 strcpy(value, "NTOSKRNL.EXE");
382 strcpy(szFileName, szBootPath);
383 strcat(szFileName, "SYSTEM32\\");
384 strcat(szFileName, value);
385 }
386
387 if (!LoadKernel(szFileName, 5))
388 return;
389
390 /*
391 * Find the HAL image name
392 * and try to load the kernel off the disk
393 */
394 if(ReadSectionSettingByName(SectionId, "Hal", value, 1024))
395 {
396 /*
397 * Set the name and
398 */
399 if (value[0] == '\\')
400 {
401 strcpy(szFileName, value);
402 }
403 else
404 {
405 strcpy(szFileName, szBootPath);
406 strcat(szFileName, "SYSTEM32\\");
407 strcat(szFileName, value);
408 }
409 }
410 else
411 {
412 strcpy(value, "HAL.DLL");
413 strcpy(szFileName, szBootPath);
414 strcat(szFileName, "SYSTEM32\\");
415 strcat(szFileName, value);
416 }
417
418 if (!LoadDriver(szFileName, 10))
419 return;
420
421 /*
422 * Find the System hive image name
423 * and try to load it off the disk
424 */
425 if(ReadSectionSettingByName(SectionId, "SystemHive", value, 1024))
426 {
427 /*
428 * Set the name and
429 */
430 if (value[0] == '\\')
431 {
432 strcpy(szFileName, value);
433 }
434 else
435 {
436 strcpy(szFileName, szBootPath);
437 strcat(szFileName, "SYSTEM32\\CONFIG\\");
438 strcat(szFileName, value);
439 }
440 }
441 else
442 {
443 strcpy(value, "SYSTEM.HIV");
444 strcpy(szFileName, szBootPath);
445 strcat(szFileName, "SYSTEM32\\CONFIG\\");
446 strcat(szFileName, value);
447 }
448
449 #ifndef NDEBUG
450 sprintf(MsgBuffer,"SystemHive: '%s'", szFileName);
451 MessageBox(MsgBuffer);
452 #endif
453
454 FilePointer = OpenFile(szFileName);
455 if (FilePointer == NULL)
456 {
457 strcat(value, " not found.");
458 MessageBox(value);
459 return;
460 }
461
462 /*
463 * Update the status bar with the current file
464 */
465 strcpy(name, " Reading ");
466 strcat(name, value);
467 while (strlen(name) < 80)
468 strcat(name, " ");
469 DrawStatusText(name);
470
471 /*
472 * Load the system hive
473 */
474 Base = MultiBootLoadModule(FilePointer, szFileName, &Size);
475 RegInitializeRegistry();
476 RegImportHive(Base, Size);
477
478 DrawProgressBar(15);
479
480 #ifndef NDEBUG
481 sprintf(MsgBuffer,"SystemHive loaded at 0x%x size %u", (unsigned)Base, (unsigned)Size);
482 MessageBox(MsgBuffer);
483 #endif
484
485 /*
486 * retrieve hardware information and create the hardware hive
487 */
488 // DetectHardware();
489 // Base = MultiBootCreateModule(HARDWARE.HIV);
490 // RegExportHardwareHive(Base, &Size);
491 // MultiBootCloseModule(Base, Size);
492
493 DrawProgressBar(20);
494
495 /*
496 * load NLS files
497 */
498 // LoadNlsFiles(szBootPath);
499
500 DrawProgressBar(25);
501
502 /*
503 * load boot drivers
504 */
505 LoadBootDrivers(szBootPath, 30);
506
507
508 /*
509 * Clear the screen and redraw the backdrop and status bar
510 */
511 DrawBackdrop();
512 DrawStatusText(" Press any key to boot");
513
514 /*
515 * Wait for user
516 */
517 strcpy(name, "Kernel and Drivers loaded.\nPress any key to boot ");
518 strcat(name, OperatingSystemName);
519 strcat(name, ".");
520 //MessageBox(name);
521
522 RestoreScreen(ScreenBuffer);
523
524 /*
525 * Now boot the kernel
526 */
527 stop_floppy();
528 boot_reactos();
529 }
530