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