3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
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.
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.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 /* INCLUDES *******************************************************************/
26 /* FUNCTIONS ******************************************************************/
29 LoadAndBootBootSector(
38 UCHAR DriveNumber
= 0;
39 ULONG PartitionNumber
= 0;
42 CHAR ArcPath
[MAX_PATH
];
44 /* Find all the message box settings and run them */
45 UiShowMessageBoxesInArgv(Argc
, Argv
);
48 * Check whether we have a "BootPath" value (takes precedence
49 * over both "BootDrive" and "BootPartition").
51 BootPath
= GetArgumentValue(Argc
, Argv
, "BootPath");
52 if (!BootPath
|| !*BootPath
)
54 /* We don't have one, check whether we use "BootDrive" and "BootPartition" */
56 /* Retrieve the boot drive (optional, fall back to using default path otherwise) */
57 ArgValue
= GetArgumentValue(Argc
, Argv
, "BootDrive");
58 if (ArgValue
&& *ArgValue
)
60 DriveNumber
= DriveMapGetBiosDriveNumber(ArgValue
);
62 /* Retrieve the boot partition (not optional and cannot be zero) */
64 ArgValue
= GetArgumentValue(Argc
, Argv
, "BootPartition");
65 if (ArgValue
&& *ArgValue
)
66 PartitionNumber
= atoi(ArgValue
);
67 if (PartitionNumber
== 0)
69 UiMessageBox("Boot partition cannot be 0!");
73 /* Construct the corresponding ARC path */
74 ConstructArcPath(ArcPath
, "", DriveNumber
, PartitionNumber
);
75 *strrchr(ArcPath
, '\\') = ANSI_NULL
; // Trim the trailing path separator.
81 /* Fall back to using the system partition as default path */
82 BootPath
= GetArgumentValue(Argc
, Argv
, "SystemPartition");
86 /* Retrieve the file name */
87 FileName
= GetArgumentValue(Argc
, Argv
, "BootSectorFile");
88 if (!FileName
|| !*FileName
)
90 UiMessageBox("Boot sector file not specified for selected OS!");
94 /* Open the boot sector file */
95 Status
= FsOpenFile(FileName
, BootPath
, OpenReadOnly
, &FileId
);
96 if (Status
!= ESUCCESS
)
98 UiMessageBox("Unable to open %s", FileName
);
102 /* Now try to load the boot sector. If this fails then abort. */
103 Status
= ArcRead(FileId
, (PVOID
)0x7c00, 512, &BytesRead
);
105 if ((Status
!= ESUCCESS
) || (BytesRead
!= 512))
107 UiMessageBox("Unable to load boot sector.");
111 /* Check for validity */
112 if (*((USHORT
*)(0x7c00 + 0x1fe)) != 0xaa55)
114 UiMessageBox("Invalid boot sector magic (0xaa55)");
118 UiUnInitialize("Booting...");
122 * Don't stop the floppy drive motor when we
123 * are just booting a bootsector, or drive, or partition.
124 * If we were to stop the floppy motor then
125 * the BIOS wouldn't be informed and if the
126 * next read is to a floppy then the BIOS will
127 * still think the motor is on and this will
128 * result in a read error.
130 // DiskStopFloppyMotor();
131 ChainLoadBiosBootSectorCode(0 /*DriveNumber*/, 0 /*PartitionNumber*/);
132 /* Must not return! */
137 LoadAndBootPartitionOrDrive(
138 IN UCHAR DriveNumber
,
139 IN ULONG PartitionNumber OPTIONAL
,
140 IN PCSTR BootPath OPTIONAL
)
145 CHAR ArcPath
[MAX_PATH
];
148 * If the user specifies an ARC "BootPath" value, it takes precedence
149 * over both the DriveNumber and PartitionNumber options.
151 if (BootPath
&& *BootPath
)
153 PCSTR FileName
= NULL
;
156 * Retrieve the BIOS drive and partition numbers; verify also that the
157 * path is "valid" in the sense that it must not contain any file name.
159 if (!DissectArcPath(BootPath
, &FileName
, &DriveNumber
, &PartitionNumber
) ||
160 (FileName
&& *FileName
))
167 /* We don't have one, so construct the corresponding ARC path */
168 ConstructArcPath(ArcPath
, "", DriveNumber
, PartitionNumber
);
169 *strrchr(ArcPath
, '\\') = ANSI_NULL
; // Trim the trailing path separator.
174 /* Open the volume */
175 Status
= ArcOpen((PSTR
)BootPath
, OpenReadOnly
, &FileId
);
176 if (Status
!= ESUCCESS
)
178 UiMessageBox("Unable to open %s", BootPath
);
183 * Now try to load the partition boot sector or the MBR (when PartitionNumber == 0).
184 * If this fails then abort.
186 Status
= ArcRead(FileId
, (PVOID
)0x7c00, 512, &BytesRead
);
188 if ((Status
!= ESUCCESS
) || (BytesRead
!= 512))
190 if (PartitionNumber
!= 0)
191 UiMessageBox("Unable to load partition's boot sector.");
193 UiMessageBox("Unable to load MBR boot sector.");
197 /* Check for validity */
198 if (*((USHORT
*)(0x7c00 + 0x1fe)) != 0xaa55)
200 UiMessageBox("Invalid boot sector magic (0xaa55)");
204 UiUnInitialize("Booting...");
208 * Don't stop the floppy drive motor when we
209 * are just booting a bootsector, or drive, or partition.
210 * If we were to stop the floppy motor then
211 * the BIOS wouldn't be informed and if the
212 * next read is to a floppy then the BIOS will
213 * still think the motor is on and this will
214 * result in a read error.
216 // DiskStopFloppyMotor();
217 ChainLoadBiosBootSectorCode(DriveNumber
, PartitionNumber
);
218 /* Must not return! */
223 LoadAndBootPartition(
230 UCHAR DriveNumber
= 0;
231 ULONG PartitionNumber
= 0;
233 /* Find all the message box settings and run them */
234 UiShowMessageBoxesInArgv(Argc
, Argv
);
237 * Check whether we have a "BootPath" value (takes precedence
238 * over both "BootDrive" and "BootPartition").
240 BootPath
= GetArgumentValue(Argc
, Argv
, "BootPath");
241 if (!BootPath
|| !*BootPath
)
243 /* We don't have one */
245 /* Retrieve the boot drive */
246 ArgValue
= GetArgumentValue(Argc
, Argv
, "BootDrive");
247 if (!ArgValue
|| !*ArgValue
)
249 UiMessageBox("Boot drive not specified for selected OS!");
252 DriveNumber
= DriveMapGetBiosDriveNumber(ArgValue
);
254 /* Retrieve the boot partition (optional, fall back to zero otherwise) */
256 ArgValue
= GetArgumentValue(Argc
, Argv
, "BootPartition");
257 if (ArgValue
&& *ArgValue
)
258 PartitionNumber
= atoi(ArgValue
);
261 return LoadAndBootPartitionOrDrive(DriveNumber
, PartitionNumber
, BootPath
);
272 UCHAR DriveNumber
= 0;
274 /* Find all the message box settings and run them */
275 UiShowMessageBoxesInArgv(Argc
, Argv
);
277 /* Check whether we have a "BootPath" value (takes precedence over "BootDrive") */
278 BootPath
= GetArgumentValue(Argc
, Argv
, "BootPath");
279 if (BootPath
&& *BootPath
)
282 * We have one, check that it does not contain any
283 * "partition()" specification, and fail if so.
285 if (strstr(BootPath
, ")partition("))
287 UiMessageBox("Invalid 'BootPath' value!");
293 /* We don't, retrieve the boot drive value instead */
294 ArgValue
= GetArgumentValue(Argc
, Argv
, "BootDrive");
295 if (!ArgValue
|| !*ArgValue
)
297 UiMessageBox("Boot drive not specified for selected OS!");
300 DriveNumber
= DriveMapGetBiosDriveNumber(ArgValue
);
303 return LoadAndBootPartitionOrDrive(DriveNumber
, 0, BootPath
);