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