535f9d6efabb71a07881a8405bcbc4d8cc913d55
[reactos.git] / boot / freeldr / freeldr / miscboot.c
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 #ifdef _M_IX86
21
22 /* INCLUDES *******************************************************************/
23
24 #include <freeldr.h>
25
26 /* FUNCTIONS ******************************************************************/
27
28 ARC_STATUS
29 LoadAndBootBootSector(
30 IN ULONG Argc,
31 IN PCHAR Argv[],
32 IN PCHAR Envp[])
33 {
34 PCSTR FileName;
35 ULONG FileId;
36 ULONG BytesRead;
37
38 /* Find all the message box settings and run them */
39 UiShowMessageBoxesInArgv(Argc, Argv);
40
41 /* Read the file name */
42 FileName = GetArgumentValue(Argc, Argv, "BootSectorFile");
43 if (!FileName)
44 {
45 UiMessageBox("Boot sector file not specified for selected OS!");
46 return EINVAL;
47 }
48
49 FileId = FsOpenFile(FileName);
50 if (!FileId)
51 {
52 UiMessageBox("%s not found.", FileName);
53 return ENOENT;
54 }
55
56 /* Read boot sector */
57 if ((ArcRead(FileId, (PVOID)0x7c00, 512, &BytesRead) != ESUCCESS) || (BytesRead != 512))
58 {
59 UiMessageBox("Unable to read boot sector.");
60 return EIO;
61 }
62
63 ArcClose(FileId);
64
65 /* Check for validity */
66 if (*((USHORT*)(0x7c00 + 0x1fe)) != 0xaa55)
67 {
68 UiMessageBox("Invalid boot sector magic (0xaa55)");
69 return ENOEXEC;
70 }
71
72 UiUnInitialize("Booting...");
73 IniCleanup();
74
75 /*
76 * Don't stop the floppy drive motor when we
77 * are just booting a bootsector, or drive, or partition.
78 * If we were to stop the floppy motor then
79 * the BIOS wouldn't be informed and if the
80 * next read is to a floppy then the BIOS will
81 * still think the motor is on and this will
82 * result in a read error.
83 */
84 // DiskStopFloppyMotor();
85 /* NOTE: Don't touch FrldrBootDrive */
86 ChainLoadBiosBootSectorCode();
87 Reboot(); /* Must not return! */
88 return ESUCCESS;
89 }
90
91 static ARC_STATUS
92 LoadAndBootPartitionOrDrive(
93 IN UCHAR DriveNumber,
94 IN ULONG PartitionNumber OPTIONAL)
95 {
96 ULONG FileId;
97 ULONG BytesRead;
98 CHAR ArcPath[MAX_PATH];
99
100 /* Construct the corresponding ARC path */
101 ConstructArcPath(ArcPath, "", DriveNumber, PartitionNumber);
102 *strrchr(ArcPath, '\\') = ANSI_NULL; // Trim the trailing path separator.
103 if (ArcOpen(ArcPath, OpenReadOnly, &FileId) != ESUCCESS)
104 {
105 UiMessageBox("Unable to open %s", ArcPath);
106 return ENOENT;
107 }
108
109 /*
110 * Now try to read the partition boot sector or the MBR (when PartitionNumber == 0).
111 * If this fails then abort.
112 */
113 if ((ArcRead(FileId, (PVOID)0x7c00, 512, &BytesRead) != ESUCCESS) || (BytesRead != 512))
114 {
115 if (PartitionNumber != 0)
116 UiMessageBox("Unable to read partition's boot sector.");
117 else
118 UiMessageBox("Unable to read MBR boot sector.");
119 return EIO;
120 }
121
122 ArcClose(FileId);
123
124 /* Check for validity */
125 if (*((USHORT*)(0x7c00 + 0x1fe)) != 0xaa55)
126 {
127 UiMessageBox("Invalid boot sector magic (0xaa55)");
128 return ENOEXEC;
129 }
130
131 UiUnInitialize("Booting...");
132 IniCleanup();
133
134 /*
135 * Don't stop the floppy drive motor when we
136 * are just booting a bootsector, or drive, or partition.
137 * If we were to stop the floppy motor then
138 * the BIOS wouldn't be informed and if the
139 * next read is to a floppy then the BIOS will
140 * still think the motor is on and this will
141 * result in a read error.
142 */
143 // DiskStopFloppyMotor();
144 FrldrBootDrive = DriveNumber;
145 FrldrBootPartition = PartitionNumber;
146 ChainLoadBiosBootSectorCode();
147 Reboot(); /* Must not return! */
148 return ESUCCESS;
149 }
150
151 ARC_STATUS
152 LoadAndBootPartition(
153 IN ULONG Argc,
154 IN PCHAR Argv[],
155 IN PCHAR Envp[])
156 {
157 PCSTR ArgValue;
158 UCHAR DriveNumber;
159 ULONG PartitionNumber;
160
161 /* Find all the message box settings and run them */
162 UiShowMessageBoxesInArgv(Argc, Argv);
163
164 /* Read the boot drive */
165 ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
166 if (!ArgValue)
167 {
168 UiMessageBox("Boot drive not specified for selected OS!");
169 return EINVAL;
170 }
171 DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
172
173 /* Read the boot partition */
174 ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
175 if (!ArgValue)
176 {
177 UiMessageBox("Boot partition not specified for selected OS!");
178 return EINVAL;
179 }
180 PartitionNumber = atoi(ArgValue);
181
182 return LoadAndBootPartitionOrDrive(DriveNumber, PartitionNumber);
183 }
184
185 ARC_STATUS
186 LoadAndBootDrive(
187 IN ULONG Argc,
188 IN PCHAR Argv[],
189 IN PCHAR Envp[])
190 {
191 PCSTR ArgValue;
192 UCHAR DriveNumber;
193
194 /* Find all the message box settings and run them */
195 UiShowMessageBoxesInArgv(Argc, Argv);
196
197 /* Read the boot drive */
198 ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
199 if (!ArgValue)
200 {
201 UiMessageBox("Boot drive not specified for selected OS!");
202 return EINVAL;
203 }
204 DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
205
206 return LoadAndBootPartitionOrDrive(DriveNumber, 0);
207 }
208
209 #endif // _M_IX86