ReactOS 0.4.15-dev-8093-g3285f69
miscboot.c
Go to the documentation of this file.
1/*
2 * FreeLoader
3 * Copyright (C) 1998-2003 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 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.
18 */
19
20#if defined(_M_IX86) || defined(_M_AMD64)
21
22/* INCLUDES *******************************************************************/
23
24#include <freeldr.h>
25
26#include <debug.h>
28
29/* FUNCTIONS ******************************************************************/
30
36LoadAndBootSector(
37 _In_ ULONG Argc,
38 _In_ PCHAR Argv[],
39 _In_ PCHAR Envp[])
40{
42 PCSTR ArgValue;
43 PCSTR BootPath;
45 UCHAR BiosDriveNumber = 0;
47 ULONG LoadAddress;
48 ULONG FileId;
50 CHAR ArcPath[MAX_PATH];
51
52#if DBG
53 /* Ensure the boot type is the one expected */
54 ArgValue = GetArgumentValue(Argc, Argv, "BootType");
55 if (!ArgValue || !*ArgValue || _stricmp(ArgValue, "BootSector") != 0)
56 {
57 ERR("Unexpected boot type '%s', aborting\n", ArgValue ? ArgValue : "n/a");
58 return EINVAL;
59 }
60#endif
61
62 /* Find all the message box settings and run them */
63 UiShowMessageBoxesInArgv(Argc, Argv);
64
65 /*
66 * Check whether we have a "BootPath" value (takes precedence
67 * over both "BootDrive" and "BootPartition").
68 */
69 BootPath = GetArgumentValue(Argc, Argv, "BootPath");
70 if (!BootPath || !*BootPath)
71 {
72 /* We don't have one, check whether we use "BootDrive" and "BootPartition" */
73
74 /* Retrieve the boot drive (optional, fall back to using default path otherwise) */
75 ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
76 if (ArgValue && *ArgValue)
77 {
78 BiosDriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
79
80 /* Retrieve the boot partition (optional, fall back to zero otherwise) */
82 ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
83 if (ArgValue && *ArgValue)
84 PartitionNumber = atoi(ArgValue);
85 }
86 else
87 {
88 /* Fall back to using the system partition as default path */
89 BootPath = GetArgumentValue(Argc, Argv, "SystemPartition");
90 }
91 }
92
93 /*
94 * The ARC "BootPath" value takes precedence over
95 * both the BiosDriveNumber and PartitionNumber options.
96 */
97 if (BootPath && *BootPath)
98 {
99 /*
100 * Retrieve the BIOS drive and partition numbers; verify also that the
101 * path is "valid" in the sense that it must not contain any file name.
102 */
103 FileName = NULL;
104 if (!DissectArcPath(BootPath, &FileName, &BiosDriveNumber, &PartitionNumber) ||
105 (FileName && *FileName))
106 {
107 UiMessageBox("Currently unsupported BootPath value:\n%s", BootPath);
108 return EINVAL;
109 }
110 }
111 else
112 {
113 /* We don't have one, so construct the corresponding ARC path */
114 ConstructArcPath(ArcPath, "", BiosDriveNumber, PartitionNumber);
115 *strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
116 BootPath = ArcPath;
117 }
118
119 FileName = NULL;
120 if (strstr(BootPath, ")partition()") || strstr(BootPath, ")partition(0)"))
121 {
122 /*
123 * The partition specifier is zero i.e. the device is accessed
124 * in an unpartitioned fashion, do not retrieve a file name.
125 *
126 * NOTE: If we access a floppy drive, we would not have a
127 * partition specifier, and PartitionNumber would be == 0,
128 * so don't check explicitly for PartitionNumber because
129 * we want to retrieve a file name.
130 */
131 }
132 else
133 {
134 /* Retrieve the file name, if any, and normalize
135 * the pointer to make subsequent tests simpler */
136 FileName = GetArgumentValue(Argc, Argv, "BootSectorFile");
137 if (FileName && !*FileName)
138 FileName = NULL;
139 }
140
141
142 /* If we load a boot sector file, reset the drive number
143 * so as to use the original boot drive/partition */
144 if (FileName)
145 BiosDriveNumber = 0;
146 if (!BiosDriveNumber)
147 {
148 BiosDriveNumber = FrldrBootDrive;
150 }
151
152
153 /* Open the boot sector file or the volume */
154 if (FileName)
155 Status = FsOpenFile(FileName, BootPath, OpenReadOnly, &FileId);
156 else
157 Status = ArcOpen((PSTR)BootPath, OpenReadOnly, &FileId);
158 if (Status != ESUCCESS)
159 {
160 UiMessageBox("Unable to open %s", FileName ? FileName : BootPath);
161 return Status;
162 }
163
164#if defined(SARCH_PC98)
165 LoadAddress = Pc98GetBootSectorLoadAddress(BiosDriveNumber);
166#else
167 LoadAddress = 0x7C00;
168#endif
169
170 /*
171 * Now try to load the boot sector: disk MBR (when PartitionNumber == 0),
172 * partition VBR or boot sector file. If this fails, abort.
173 */
174 Status = ArcRead(FileId, UlongToPtr(LoadAddress), 512, &BytesRead);
175 ArcClose(FileId);
176 if ((Status != ESUCCESS) || (BytesRead != 512))
177 {
178 PCSTR WhatFailed;
179
180 if (FileName)
181 WhatFailed = "boot sector file";
182 else if (PartitionNumber != 0)
183 WhatFailed = "partition's boot sector";
184 else
185 WhatFailed = "MBR boot sector";
186
187 UiMessageBox("Unable to load %s.", WhatFailed);
188 return EIO;
189 }
190
191 /* Check for validity */
192 if (*(USHORT*)UlongToPtr(LoadAddress + 0x1FE) != 0xAA55)
193 {
194 UiMessageBox("Invalid boot sector magic (0xAA55)");
195 return ENOEXEC;
196 }
197
198 UiUnInitialize("Booting...");
199 IniCleanup();
200
201#ifndef UEFIBOOT
202 /* Boot the loaded sector code */
204#endif
205 /* Must not return! */
206 return ESUCCESS;
207}
208
209#endif /* _M_IX86 || _M_AMD64 */
210
211/* EOF */
#define EINVAL
Definition: acclib.h:90
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define EIO
Definition: acclib.h:81
PSTR GetArgumentValue(_In_ ULONG Argc, _In_ PCHAR Argv[], _In_ PCSTR ArgumentName)
Definition: arcsupp.c:42
BOOLEAN DissectArcPath(IN PCSTR ArcPath, OUT PCSTR *Path OPTIONAL, OUT PUCHAR DriveNumber, OUT PULONG PartitionNumber)
Definition: arcname.c:25
VOID ConstructArcPath(PCHAR ArcPath, PCHAR SystemFolder, UCHAR Disk, ULONG Partition)
Definition: arcname.c:175
#define DriveMapGetBiosDriveNumber(DeviceName)
Definition: hardware.h:35
#define ERR(fmt,...)
Definition: debug.h:113
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
ARC_STATUS ArcClose(ULONG FileId)
Definition: fs.c:220
ARC_STATUS ArcOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fs.c:56
ARC_STATUS FsOpenFile(IN PCSTR FileName, IN PCSTR DefaultPath OPTIONAL, IN OPENMODE OpenMode, OUT PULONG FileId)
Definition: fs.c:268
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:238
VOID UiShowMessageBoxesInArgv(IN ULONG Argc, IN PCHAR Argv[])
Definition: ui.c:568
VOID UiUnInitialize(PCSTR BootText)
Definition: ui.c:224
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
#define _stricmp
Definition: cat.c:22
#define NULL
Definition: types.h:112
#define MAX_PATH
Definition: compat.h:34
#define ENOEXEC
Definition: errno.h:14
#define UlongToPtr(u)
Definition: config.h:106
struct _FileName FileName
Definition: fatprocs.h:896
Status
Definition: gdiplustypes.h:25
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
VOID IniCleanup(VOID)
Definition: inifile.c:238
ULONG Pc98GetBootSectorLoadAddress(IN UCHAR DriveNumber)
Definition: machpc98.c:44
VOID __cdecl ChainLoadBiosBootSectorCode(IN UCHAR BootDrive OPTIONAL, IN ULONG BootPartition OPTIONAL)
Definition: machpc.c:1745
#define _In_
Definition: ms_sal.h:308
#define ANSI_NULL
unsigned short USHORT
Definition: pedump.c:61
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
@ ESUCCESS
Definition: arc.h:32
ULONG ARC_STATUS
Definition: arc.h:4
@ OpenReadOnly
Definition: arc.h:65
char * PSTR
Definition: typedefs.h:51
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
UCHAR FrldrBootDrive
Definition: uefidisk.c:47
ULONG FrldrBootPartition
Definition: uefidisk.c:48
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2061
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175