b197d840a7d19bfd6e79396810ca95cc1c60ca96
[reactos.git] / reactos / boot / freeldr / freeldr / fs / fs.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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <freeldr.h>
21 #include <fs.h>
22 #include "fat.h"
23 #include "iso.h"
24 #include "ext2.h"
25 #include "ntfs.h"
26 #include "fsrec.h"
27 #include <disk.h>
28 #include <rtl.h>
29 #include <ui.h>
30 #include <arch.h>
31 #include <debug.h>
32 #include <machine.h>
33
34
35 /////////////////////////////////////////////////////////////////////////////////////////////
36 // DATA
37 /////////////////////////////////////////////////////////////////////////////////////////////
38
39 ULONG FsType = 0; // Type of filesystem on boot device, set by FsOpenVolume()
40
41 /////////////////////////////////////////////////////////////////////////////////////////////
42 // FUNCTIONS
43 /////////////////////////////////////////////////////////////////////////////////////////////
44
45 VOID FileSystemError(PCHAR ErrorString)
46 {
47 DbgPrint((DPRINT_FILESYSTEM, "%s\n", ErrorString));
48
49 UiMessageBox(ErrorString);
50 }
51
52 /*
53 *
54 * BOOL FsOpenVolume(ULONG DriveNumber, ULONGLONG StartSector, ULONGLONG SectorCount, int Type);
55 *
56 * This function is called to open a disk volume for file access.
57 * It must be called before any of the file functions will work.
58 *
59 */
60 static BOOL FsOpenVolume(ULONG DriveNumber, ULONGLONG StartSector, ULONGLONG SectorCount, int Type)
61 {
62 CHAR ErrorText[80];
63
64 FsType = Type;
65
66 switch (FsType)
67 {
68 case FS_FAT:
69 return FatOpenVolume(DriveNumber, StartSector, SectorCount);
70 case FS_EXT2:
71 return Ext2OpenVolume(DriveNumber, StartSector);
72 case FS_NTFS:
73 return NtfsOpenVolume(DriveNumber, StartSector);
74 case FS_ISO9660:
75 return IsoOpenVolume(DriveNumber);
76 default:
77 FsType = 0;
78 sprintf(ErrorText, "Unsupported file system. Type: 0x%x", Type);
79 FileSystemError(ErrorText);
80 }
81
82 return FALSE;
83 }
84 /*
85 *
86 * BOOL FsOpenBootVolume()
87 *
88 * This function is called to open the boot disk volume for file access.
89 * It must be called before any of the file functions will work.
90 */
91 BOOL FsOpenBootVolume()
92 {
93 ULONG DriveNumber;
94 ULONGLONG StartSector;
95 ULONGLONG SectorCount;
96 int Type;
97
98 if (! MachDiskGetBootVolume(&DriveNumber, &StartSector, &SectorCount, &Type))
99 {
100 FileSystemError("Unable to locate boot partition\n");
101 return FALSE;
102 }
103
104 return FsOpenVolume(DriveNumber, StartSector, SectorCount, Type);
105 }
106
107 BOOL FsOpenSystemVolume(char *SystemPath, char *RemainingPath, PULONG Device)
108 {
109 ULONG DriveNumber;
110 ULONGLONG StartSector;
111 ULONGLONG SectorCount;
112 int Type;
113
114 if (! MachDiskGetSystemVolume(SystemPath, RemainingPath, Device,
115 &DriveNumber, &StartSector, &SectorCount,
116 &Type))
117 {
118 FileSystemError("Unable to locate system partition\n");
119 return FALSE;
120 }
121
122 return FsOpenVolume(DriveNumber, StartSector, SectorCount, Type);
123 }
124
125
126 PFILE FsOpenFile(PCHAR FileName)
127 {
128 PFILE FileHandle = NULL;
129
130 //
131 // Print status message
132 //
133 DbgPrint((DPRINT_FILESYSTEM, "Opening file '%s'...\n", FileName));
134
135 //
136 // Check and see if the first character is '\' or '/' and remove it if so
137 //
138 while ((*FileName == '\\') || (*FileName == '/'))
139 {
140 FileName++;
141 }
142
143 //
144 // Check file system type and pass off to appropriate handler
145 //
146 switch (FsType)
147 {
148 case FS_FAT:
149 FileHandle = FatOpenFile(FileName);
150 break;
151 case FS_ISO9660:
152 FileHandle = IsoOpenFile(FileName);
153 break;
154 case FS_EXT2:
155 FileHandle = Ext2OpenFile(FileName);
156 break;
157 case FS_NTFS:
158 FileHandle = NtfsOpenFile(FileName);
159 break;
160 default:
161 FileSystemError("Error: Unknown filesystem.");
162 break;
163 }
164
165 #ifdef DEBUG
166 //
167 // Check return value
168 //
169 if (FileHandle != NULL)
170 {
171 DbgPrint((DPRINT_FILESYSTEM, "FsOpenFile() succeeded. FileHandle: 0x%x\n", FileHandle));
172 }
173 else
174 {
175 DbgPrint((DPRINT_FILESYSTEM, "FsOpenFile() failed.\n"));
176 }
177 #endif // defined DEBUG
178
179 return FileHandle;
180 }
181
182 VOID FsCloseFile(PFILE FileHandle)
183 {
184 }
185
186 /*
187 * ReadFile()
188 * returns number of bytes read or EOF
189 */
190 BOOL FsReadFile(PFILE FileHandle, ULONG BytesToRead, ULONG* BytesRead, PVOID Buffer)
191 {
192 ULONGLONG BytesReadBig;
193 BOOL Success;
194
195 //
196 // Set the number of bytes read equal to zero
197 //
198 if (BytesRead != NULL)
199 {
200 *BytesRead = 0;
201 }
202
203 switch (FsType)
204 {
205 case FS_FAT:
206
207 return FatReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
208
209 case FS_ISO9660:
210
211 return IsoReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
212
213 case FS_EXT2:
214
215 //return Ext2ReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
216 Success = Ext2ReadFile(FileHandle, BytesToRead, &BytesReadBig, Buffer);
217 *BytesRead = (ULONG)BytesReadBig;
218 return Success;
219
220 case FS_NTFS:
221
222 return NtfsReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
223
224 default:
225
226 FileSystemError("Unknown file system.");
227 return FALSE;
228 }
229
230 return FALSE;
231 }
232
233 ULONG FsGetFileSize(PFILE FileHandle)
234 {
235 switch (FsType)
236 {
237 case FS_FAT:
238
239 return FatGetFileSize(FileHandle);
240
241 case FS_ISO9660:
242
243 return IsoGetFileSize(FileHandle);
244
245 case FS_EXT2:
246
247 return Ext2GetFileSize(FileHandle);
248
249 case FS_NTFS:
250
251 return NtfsGetFileSize(FileHandle);
252
253 default:
254 FileSystemError("Unknown file system.");
255 break;
256 }
257
258 return 0;
259 }
260
261 VOID FsSetFilePointer(PFILE FileHandle, ULONG NewFilePointer)
262 {
263 switch (FsType)
264 {
265 case FS_FAT:
266
267 FatSetFilePointer(FileHandle, NewFilePointer);
268 break;
269
270 case FS_ISO9660:
271
272 IsoSetFilePointer(FileHandle, NewFilePointer);
273 break;
274
275 case FS_EXT2:
276
277 Ext2SetFilePointer(FileHandle, NewFilePointer);
278 break;
279
280 case FS_NTFS:
281
282 NtfsSetFilePointer(FileHandle, NewFilePointer);
283 break;
284
285 default:
286 FileSystemError("Unknown file system.");
287 break;
288 }
289 }
290
291 ULONG FsGetFilePointer(PFILE FileHandle)
292 {
293 switch (FsType)
294 {
295 case FS_FAT:
296
297 return FatGetFilePointer(FileHandle);
298 break;
299
300 case FS_ISO9660:
301
302 return IsoGetFilePointer(FileHandle);
303 break;
304
305 case FS_EXT2:
306
307 return Ext2GetFilePointer(FileHandle);
308 break;
309
310 case FS_NTFS:
311
312 return NtfsGetFilePointer(FileHandle);
313 break;
314
315 default:
316 FileSystemError("Unknown file system.");
317 break;
318 }
319
320 return 0;
321 }
322
323 BOOL FsIsEndOfFile(PFILE FileHandle)
324 {
325 if (FsGetFilePointer(FileHandle) >= FsGetFileSize(FileHandle))
326 {
327 return TRUE;
328 }
329 else
330 {
331 return FALSE;
332 }
333 }
334
335 /*
336 * FsGetNumPathParts()
337 * This function parses a path in the form of dir1\dir2\file1.ext
338 * and returns the number of parts it has (i.e. 3 - dir1,dir2,file1.ext)
339 */
340 ULONG FsGetNumPathParts(PCHAR Path)
341 {
342 size_t i;
343 ULONG num;
344
345 for (i=0,num=0; i<strlen(Path); i++)
346 {
347 if ((Path[i] == '\\') || (Path[i] == '/'))
348 {
349 num++;
350 }
351 }
352 num++;
353
354 DbgPrint((DPRINT_FILESYSTEM, "FatGetNumPathParts() Path = %s NumPathParts = %d\n", Path, num));
355
356 return num;
357 }
358
359 /*
360 * FsGetFirstNameFromPath()
361 * This function parses a path in the form of dir1\dir2\file1.ext
362 * and puts the first name of the path (e.g. "dir1") in buffer
363 * compatible with the MSDOS directory structure
364 */
365 VOID FsGetFirstNameFromPath(PCHAR Buffer, PCHAR Path)
366 {
367 size_t i;
368
369 // Copy all the characters up to the end of the
370 // string or until we hit a '\' character
371 // and put them in Buffer
372 for (i=0; i<strlen(Path); i++)
373 {
374 if ((Path[i] == '\\') || (Path[i] == '/'))
375 {
376 break;
377 }
378 else
379 {
380 Buffer[i] = Path[i];
381 }
382 }
383
384 Buffer[i] = 0;
385
386 DbgPrint((DPRINT_FILESYSTEM, "FatGetFirstNameFromPath() Path = %s FirstName = %s\n", Path, Buffer));
387 }