ReactOS 0.4.16-dev-2104-gb84fa49
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{
41#if defined(SARCH_XBOX)
42 UiMessageBox("Boot sector booting is not supported on XBOX.");
43 return ENOEXEC;
44#endif
46 PCSTR ArgValue;
47 PCSTR BootPath;
49 UCHAR BiosDriveNumber = 0;
51 ULONG LoadAddress;
52 ULONG FileId;
54 CHAR ArcPath[MAX_PATH];
55
56#if DBG
57 /* Ensure the boot type is the one expected */
58 ArgValue = GetArgumentValue(Argc, Argv, "BootType");
59 if (!ArgValue || !*ArgValue || _stricmp(ArgValue, "BootSector") != 0)
60 {
61 ERR("Unexpected boot type '%s', aborting\n", ArgValue ? ArgValue : "n/a");
62 return EINVAL;
63 }
64#endif
65
66 /* Find all the message box settings and run them */
67 UiShowMessageBoxesInArgv(Argc, Argv);
68
69 /*
70 * Check whether we have a "BootPath" value (takes precedence
71 * over both "BootDrive" and "BootPartition").
72 */
73 BootPath = GetArgumentValue(Argc, Argv, "BootPath");
74 if (!BootPath || !*BootPath)
75 {
76 /* We don't have one, check whether we use "BootDrive" and "BootPartition" */
77
78 /* Retrieve the boot drive (optional, fall back to using default path otherwise) */
79 ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
80 if (ArgValue && *ArgValue)
81 {
82 BiosDriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
83
84 /* Retrieve the boot partition (optional, fall back to zero otherwise) */
86 ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
87 if (ArgValue && *ArgValue)
88 PartitionNumber = atoi(ArgValue);
89 }
90 else
91 {
92 /* Fall back to using the system partition as default path */
93 BootPath = GetArgumentValue(Argc, Argv, "SystemPartition");
94 }
95 }
96
97 /*
98 * The ARC "BootPath" value takes precedence over
99 * both the BiosDriveNumber and PartitionNumber options.
100 */
101 if (BootPath && *BootPath)
102 {
103 /*
104 * Retrieve the BIOS drive and partition numbers; verify also that the
105 * path is "valid" in the sense that it must not contain any file name.
106 */
107 FileName = NULL;
108 if (!DissectArcPath(BootPath, &FileName, &BiosDriveNumber, &PartitionNumber) ||
109 (FileName && *FileName))
110 {
111 UiMessageBox("Currently unsupported BootPath value:\n%s", BootPath);
112 return EINVAL;
113 }
114 }
115 else
116 {
117 /* We don't have one, so construct the corresponding ARC path */
118 ConstructArcPath(ArcPath, "", BiosDriveNumber, PartitionNumber);
119 *strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
120 BootPath = ArcPath;
121 }
122
123 FileName = NULL;
124 if (strstr(BootPath, ")partition()") || strstr(BootPath, ")partition(0)"))
125 {
126 /*
127 * The partition specifier is zero i.e. the device is accessed
128 * in an unpartitioned fashion, do not retrieve a file name.
129 *
130 * NOTE: If we access a floppy drive, we would not have a
131 * partition specifier, and PartitionNumber would be == 0,
132 * so don't check explicitly for PartitionNumber because
133 * we want to retrieve a file name.
134 */
135 }
136 else
137 {
138 /* Retrieve the file name, if any, and normalize
139 * the pointer to make subsequent tests simpler */
140 FileName = GetArgumentValue(Argc, Argv, "BootSectorFile");
141 if (FileName && !*FileName)
142 FileName = NULL;
143 }
144
145
146 /* If we load a boot sector file, reset the drive number
147 * so as to use the original boot drive/partition */
148 if (FileName)
149 BiosDriveNumber = 0;
150 if (!BiosDriveNumber)
151 {
152 BiosDriveNumber = FrldrGetBootDrive();
154 }
155
156
157 /* Open the boot sector file or the volume */
158 if (FileName)
159 Status = FsOpenFile(FileName, BootPath, OpenReadOnly, &FileId);
160 else
161 Status = ArcOpen((PSTR)BootPath, OpenReadOnly, &FileId);
162 if (Status != ESUCCESS)
163 {
164 UiMessageBox("Unable to open %s", FileName ? FileName : BootPath);
165 return Status;
166 }
167
168 LoadAddress = MachGetBootSectorLoadAddress(BiosDriveNumber);
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 */
ULONG MachGetBootSectorLoadAddress(IN UCHAR DriveNumber)
Definition: arcemul.c:65
PSTR GetArgumentValue(_In_ ULONG Argc, _In_ PCHAR Argv[], _In_ PCSTR ArgumentName)
Definition: arcsupp.c:42
#define ERR(fmt,...)
Definition: precomp.h:57
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 DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
ARC_STATUS ArcOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: fs.c:219
ARC_STATUS FsOpenFile(IN PCSTR FileName, IN PCSTR DefaultPath OPTIONAL, IN OPENMODE OpenMode, OUT PULONG FileId)
Definition: fs.c:478
ARC_STATUS ArcClose(_In_ ULONG FileId)
Definition: fs.c:409
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:448
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 EINVAL
Definition: errno.h:44
#define ENOEXEC
Definition: errno.h:31
#define EIO
Definition: errno.h:28
_ACRTIMP int __cdecl atoi(const char *)
Definition: string.c:1715
_ACRTIMP char *__cdecl strstr(const char *, const char *)
Definition: string.c:3415
_ACRTIMP char *__cdecl strrchr(const char *, int)
Definition: string.c:3298
#define UlongToPtr(u)
Definition: config.h:106
struct _FileName FileName
Definition: fatprocs.h:897
ULONG FrldrGetBootPartition(VOID)
Definition: freeldr.c:206
UCHAR FrldrGetBootDrive(VOID)
Definition: freeldr.c:201
Status
Definition: gdiplustypes.h:25
VOID IniCleanup(VOID)
Definition: inifile.c:243
VOID __cdecl ChainLoadBiosBootSectorCode(IN UCHAR BootDrive OPTIONAL, IN ULONG BootPartition OPTIONAL)
Definition: machpc.c:1752
#define _In_
Definition: no_sal2.h:158
#define ANSI_NULL
unsigned short USHORT
Definition: pedump.c:61
@ 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
_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