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