286e3afbb52f912a2ce1d0f3ba65cd03771ac860
[reactos.git] / freeldr / freeldr / reactos.c
1 /*
2 * FreeLoader
3 * Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include "freeldr.h"
21 #include "asmcode.h"
22 #include "reactos.h"
23 #include "stdlib.h"
24 #include "fs.h"
25 #include "tui.h"
26 #include "multiboot.h"
27 #include "arcname.h"
28 #include "memory.h"
29 #include "parseini.h"
30
31 BOOL LoadReactOSKernel(PUCHAR OperatingSystemName);
32 BOOL LoadReactOSDrivers(PUCHAR OperatingSystemName);
33
34 void LoadAndBootReactOS(PUCHAR OperatingSystemName)
35 {
36 PFILE FilePointer;
37 char name[1024];
38 char value[1024];
39 char szFileName[1024];
40 char szBootPath[256];
41 int i;
42 int nNumDriverFiles=0;
43 int nNumFilesLoaded=0;
44 char MsgBuffer[256];
45 ULONG SectionId;
46
47 //
48 // Open the operating system section
49 // specified in the .ini file
50 //
51 if (!OpenSection(OperatingSystemName, &SectionId))
52 {
53 sprintf(MsgBuffer,"Operating System section '%s' not found in freeldr.ini", OperatingSystemName);
54 MessageBox(MsgBuffer);
55 return;
56 }
57
58 /*
59 * Setup multiboot information structure
60 */
61 mb_info.flags = MB_INFO_FLAG_MEM_SIZE | MB_INFO_FLAG_BOOT_DEVICE | MB_INFO_FLAG_COMMAND_LINE | MB_INFO_FLAG_MODULES;
62 mb_info.mem_lower = GetConventionalMemorySize();
63 mb_info.mem_upper = GetExtendedMemorySize();
64 mb_info.boot_device = 0xffffffff;
65 mb_info.cmdline = (unsigned long)multiboot_kernel_cmdline;
66 mb_info.mods_count = 0;
67 mb_info.mods_addr = (unsigned long)multiboot_modules;
68 mb_info.mmap_length = GetBiosMemoryMap(&multiboot_memory_map);
69 if (mb_info.mmap_length)
70 {
71 mb_info.mmap_addr = (unsigned long)&multiboot_memory_map;
72 mb_info.flags |= MB_INFO_FLAG_MEMORY_MAP;
73 //printf("memory map length: %d\n", mb_info.mmap_length);
74 //printf("dumping memory map:\n");
75 //for (i=0; i<(mb_info.mmap_length / 4); i++)
76 //{
77 // printf("0x%x\n", ((unsigned long *)&multiboot_memory_map)[i]);
78 //}
79 //getch();
80 }
81 //printf("low_mem = %d\n", mb_info.mem_lower);
82 //printf("high_mem = %d\n", mb_info.mem_upper);
83
84 /*
85 * Make sure the system path is set in the .ini file
86 */
87 if (!ReadSectionSettingByName(SectionId, "SystemPath", value, 1024))
88 {
89 MessageBox("System path not specified for selected operating system.");
90 return;
91 }
92
93 /*
94 * Verify system path
95 */
96 if (!DissectArcPath(value, szBootPath, &BootDrive, &BootPartition))
97 {
98 sprintf(MsgBuffer,"Invalid system path: '%s'", value);
99 MessageBox(MsgBuffer);
100 return;
101 }
102
103 /* set boot drive and partition */
104 ((char *)(&mb_info.boot_device))[0] = (char)BootDrive;
105 ((char *)(&mb_info.boot_device))[1] = (char)BootPartition;
106
107 /* copy ARC path into kernel command line */
108 strcpy(multiboot_kernel_cmdline, value);
109
110 /*
111 * Read the optional kernel parameters (if any)
112 */
113 if (ReadSectionSettingByName(SectionId, "Options", value, 1024))
114 {
115 strcat(multiboot_kernel_cmdline, " ");
116 strcat(multiboot_kernel_cmdline, value);
117 }
118
119 /* append a backslash */
120 if ((strlen(szBootPath)==0) ||
121 szBootPath[strlen(szBootPath)] != '\\')
122 strcat(szBootPath, "\\");
123
124 /*
125 * Find the kernel image name
126 */
127 if(!ReadSectionSettingByName(SectionId, "Kernel", value, 1024))
128 {
129 MessageBox("Kernel image file not specified for selected operating system.");
130 return;
131 }
132
133 /*
134 * Find the hal image name
135 */
136 if(!ReadSectionSettingByName(SectionId, "Hal", value, 1024))
137 {
138 MessageBox("HAL image file not specified for selected operating system.");
139 return;
140 }
141
142 DrawBackdrop();
143
144 DrawStatusText(" Loading...");
145 DrawProgressBar(0);
146
147 /*
148 * Try to open boot drive
149 */
150 if (!OpenDiskDrive(BootDrive, BootPartition))
151 {
152 MessageBox("Failed to open boot drive.");
153 return;
154 }
155
156 /*
157 * Parse the ini file and count the kernel, hal and drivers
158 */
159 for (i=1; i<=GetNumSectionItems(SectionId); i++)
160 {
161 /*
162 * Read the setting and check if it's a driver
163 */
164 ReadSectionSettingByNumber(SectionId, i, name, 1024, value, 1024);
165 if ((stricmp(name, "Kernel") == 0) ||
166 (stricmp(name, "Hal") == 0) ||
167 (stricmp(name, "Driver") == 0))
168 nNumDriverFiles++;
169 }
170
171 /*
172 * Find the kernel image name
173 * and try to load the kernel off the disk
174 */
175 if(ReadSectionSettingByName(SectionId, "Kernel", value, 1024))
176 {
177 /*
178 * Set the name and try to open the PE image
179 */
180 //strcpy(szFileName, szBootPath);
181 //strcat(szFileName, value);
182 strcpy(szFileName, value);
183
184 FilePointer = OpenFile(szFileName);
185 if (FilePointer == NULL)
186 {
187 strcat(value, " not found.");
188 MessageBox(value);
189 return;
190 }
191
192 /*
193 * Update the status bar with the current file
194 */
195 strcpy(name, " Reading ");
196 strcat(name, value);
197 while (strlen(name) < 80)
198 strcat(name, " ");
199 DrawStatusText(name);
200
201 /*
202 * Load the kernel image
203 */
204 MultiBootLoadKernel(FilePointer);
205
206 nNumFilesLoaded++;
207 DrawProgressBar((nNumFilesLoaded * 100) / nNumDriverFiles);
208 }
209
210 /*
211 * Find the HAL image name
212 * and try to load the kernel off the disk
213 */
214 if(ReadSectionSettingByName(SectionId, "Hal", value, 1024))
215 {
216 /*
217 * Set the name and try to open the PE image
218 */
219 //strcpy(szFileName, szBootPath);
220 //strcat(szFileName, value);
221 strcpy(szFileName, value);
222
223 FilePointer = OpenFile(szFileName);
224 if (FilePointer == NULL)
225 {
226 strcat(value, " not found.");
227 MessageBox(value);
228 return;
229 }
230
231 /*
232 * Update the status bar with the current file
233 */
234 strcpy(name, " Reading ");
235 strcat(name, value);
236 while (strlen(name) < 80)
237 strcat(name, " ");
238 DrawStatusText(name);
239
240 /*
241 * Load the HAL image
242 */
243 MultiBootLoadModule(FilePointer, szFileName);
244
245 nNumFilesLoaded++;
246 DrawProgressBar((nNumFilesLoaded * 100) / nNumDriverFiles);
247 }
248
249 /*
250 * Parse the ini file and load the kernel and
251 * load all the drivers specified
252 */
253 for (i=1; i<=GetNumSectionItems(SectionId); i++)
254 {
255 /*
256 * Read the setting and check if it's a driver
257 */
258 ReadSectionSettingByNumber(SectionId, i, name, 1024, value, 1024);
259 if (stricmp(name, "Driver") == 0)
260 {
261 /*
262 * Set the name and try to open the PE image
263 */
264 //strcpy(szFileName, szBootPath);
265 //strcat(szFileName, value);
266 strcpy(szFileName, value);
267
268 FilePointer = OpenFile(szFileName);
269 if (FilePointer == NULL)
270 {
271 strcat(value, " not found.");
272 MessageBox(value);
273 return;
274 }
275
276 /*
277 * Update the status bar with the current file
278 */
279 strcpy(name, " Reading ");
280 strcat(name, value);
281 while (strlen(name) < 80)
282 strcat(name, " ");
283 DrawStatusText(name);
284
285 /*
286 * Load the driver
287 */
288 MultiBootLoadModule(FilePointer, szFileName);
289
290
291 nNumFilesLoaded++;
292 DrawProgressBar((nNumFilesLoaded * 100) / nNumDriverFiles);
293 }
294 else if (stricmp(name, "MessageBox") == 0)
295 {
296 DrawStatusText(" Press ENTER to continue");
297 MessageBox(value);
298 }
299 else if (stricmp(name, "MessageLine") == 0)
300 MessageLine(value);
301 else if (stricmp(name, "ReOpenBootDrive") == 0)
302 {
303 if (!OpenDiskDrive(BootDrive, BootPartition))
304 {
305 MessageBox("Failed to open boot drive.");
306 return;
307 }
308 }
309 }
310
311 /*
312 * Clear the screen and redraw the backdrop and status bar
313 */
314 DrawBackdrop();
315 DrawStatusText(" Press any key to boot");
316
317 /*
318 * Wait for user
319 */
320 strcpy(name, "Kernel and Drivers loaded.\nPress any key to boot ");
321 strcat(name, OperatingSystemName);
322 strcat(name, ".");
323 //MessageBox(name);
324
325 RestoreScreen(ScreenBuffer);
326
327 /*
328 * Now boot the kernel
329 */
330 stop_floppy();
331 boot_reactos();
332 }
333