[FREELDR] Diverse enhancements.
[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, (void*)0x7c00, 512, &BytesRead) != ESUCCESS ||
58 (BytesRead != 512))
59 {
60 UiMessageBox("Unable to read boot sector.");
61 return EIO;
62 }
63
64 /* Check for validity */
65 if (*((USHORT*)(0x7c00 + 0x1fe)) != 0xaa55)
66 {
67 UiMessageBox("Invalid boot sector magic (0xaa55)");
68 return ENOEXEC;
69 }
70
71 UiUnInitialize("Booting...");
72 IniCleanup();
73
74 /*
75 * Don't stop the floppy drive motor when we
76 * are just booting a bootsector, or drive, or partition.
77 * If we were to stop the floppy motor then
78 * the BIOS wouldn't be informed and if the
79 * next read is to a floppy then the BIOS will
80 * still think the motor is on and this will
81 * result in a read error.
82 */
83 // DiskStopFloppyMotor();
84 // DisableA20();
85 ChainLoadBiosBootSectorCode();
86 return ESUCCESS;
87 }
88
89 ARC_STATUS
90 LoadAndBootPartition(
91 IN ULONG Argc,
92 IN PCHAR Argv[],
93 IN PCHAR Envp[])
94 {
95 PCSTR ArgValue;
96 PARTITION_TABLE_ENTRY PartitionTableEntry;
97 UCHAR DriveNumber;
98 ULONG PartitionNumber;
99
100 /* Find all the message box settings and run them */
101 UiShowMessageBoxesInArgv(Argc, Argv);
102
103 /* Read the boot drive */
104 ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
105 if (!ArgValue)
106 {
107 UiMessageBox("Boot drive not specified for selected OS!");
108 return EINVAL;
109 }
110 DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
111
112 /* Read the boot partition */
113 ArgValue = GetArgumentValue(Argc, Argv, "BootPartition");
114 if (!ArgValue)
115 {
116 UiMessageBox("Boot partition not specified for selected OS!");
117 return EINVAL;
118 }
119 PartitionNumber = atoi(ArgValue);
120
121 /* Get the partition table entry */
122 if (!DiskGetPartitionEntry(DriveNumber, PartitionNumber, &PartitionTableEntry))
123 {
124 return ENOENT;
125 }
126
127 /* Now try to read the partition boot sector. If this fails then abort. */
128 if (!MachDiskReadLogicalSectors(DriveNumber, PartitionTableEntry.SectorCountBeforePartition, 1, (PVOID)0x7C00))
129 {
130 UiMessageBox("Unable to read partition's boot sector.");
131 return EIO;
132 }
133
134 /* Check for validity */
135 if (*((USHORT*)(0x7c00 + 0x1fe)) != 0xaa55)
136 {
137 UiMessageBox("Invalid boot sector magic (0xaa55)");
138 return ENOEXEC;
139 }
140
141 UiUnInitialize("Booting...");
142 IniCleanup();
143
144 /*
145 * Don't stop the floppy drive motor when we
146 * are just booting a bootsector, or drive, or partition.
147 * If we were to stop the floppy motor then
148 * the BIOS wouldn't be informed and if the
149 * next read is to a floppy then the BIOS will
150 * still think the motor is on and this will
151 * result in a read error.
152 */
153 // DiskStopFloppyMotor();
154 // DisableA20();
155 FrldrBootDrive = DriveNumber;
156 ChainLoadBiosBootSectorCode();
157 return ESUCCESS;
158 }
159
160 ARC_STATUS
161 LoadAndBootDrive(
162 IN ULONG Argc,
163 IN PCHAR Argv[],
164 IN PCHAR Envp[])
165 {
166 PCSTR ArgValue;
167 UCHAR DriveNumber;
168
169 /* Find all the message box settings and run them */
170 UiShowMessageBoxesInArgv(Argc, Argv);
171
172 /* Read the boot drive */
173 ArgValue = GetArgumentValue(Argc, Argv, "BootDrive");
174 if (!ArgValue)
175 {
176 UiMessageBox("Boot drive not specified for selected OS!");
177 return EINVAL;
178 }
179 DriveNumber = DriveMapGetBiosDriveNumber(ArgValue);
180
181 /* Now try to read the boot sector (or mbr). If this fails then abort. */
182 if (!MachDiskReadLogicalSectors(DriveNumber, 0, 1, (PVOID)0x7C00))
183 {
184 UiMessageBox("Unable to read boot sector");
185 return EIO;
186 }
187
188 /* Check for validity */
189 if (*((USHORT*)(0x7c00 + 0x1fe)) != 0xaa55)
190 {
191 UiMessageBox("Invalid boot sector magic (0xaa55)");
192 return ENOEXEC;
193 }
194
195 UiUnInitialize("Booting...");
196 IniCleanup();
197
198 /*
199 * Don't stop the floppy drive motor when we
200 * are just booting a bootsector, or drive, or partition.
201 * If we were to stop the floppy motor then
202 * the BIOS wouldn't be informed and if the
203 * next read is to a floppy then the BIOS will
204 * still think the motor is on and this will
205 * result in a read error.
206 */
207 // DiskStopFloppyMotor();
208 // DisableA20();
209 FrldrBootDrive = DriveNumber;
210 ChainLoadBiosBootSectorCode();
211 return ESUCCESS;
212 }
213
214 #endif // _M_IX86