[FREELDR]

- Some whitespace fixes in fs.h and code simplifications in fs.c
- Make FsOpenFile working correctly on non-ARC and ARC file names.
- Use FsOpenFile for opening ramdisks instead of ArcOpen (the file "handle" returned by FsOpenFile is just the FileId for ARC functions). Therefore we can open ramdisks files using Windows OSLOADER syntax, i.e. /RDPATH=the_image_file instead of being forced to append for example: net(0) (as in: /RDPATH=net(0)\the_image_file ): see http://lokniketan.org/index.php?title=PXE_booting_to_BARTPE#Work_with_files_in_the_TFTPBOOT_directory for an example of what I mean.

Part 1/2
CORE-9023

svn path=/trunk/; revision=65981
This commit is contained in:
Hermès Bélusca-Maïto 2015-01-04 23:41:14 +00:00
parent 5ef2270ad9
commit 614b562bb0
3 changed files with 171 additions and 163 deletions

View file

@ -120,9 +120,9 @@ VOID
NTAPI
RamDiskLoadVirtualFile(IN PCHAR FileName)
{
ULONG RamFile;
PFILE RamFile;
ULONG TotalRead, ChunkSize, Count;
PCHAR MsgBuffer = "Loading ramdisk...";
PCHAR MsgBuffer = "Loading RamDisk...";
ULONG PercentPerChunk, Percent;
FILEINFORMATION Information;
LARGE_INTEGER Position;
@ -136,99 +136,99 @@ RamDiskLoadVirtualFile(IN PCHAR FileName)
//
// Try opening the ramdisk file
//
ret = ArcOpen(FileName, OpenReadOnly, &RamFile);
if (ret == ESUCCESS)
RamFile = FsOpenFile(FileName);
if (!RamFile)
return;
//
// Get the file size
//
ret = ArcGetFileInformation(RamFile, &Information);
if (ret != ESUCCESS)
{
FsCloseFile(RamFile);
return;
}
//
// For now, limit RAM disks to 4GB
//
if (Information.EndingAddress.HighPart != 0)
{
UiMessageBox("RAM disk too big\n");
FsCloseFile(RamFile);
return;
}
gRamDiskSize = Information.EndingAddress.LowPart;
//
// Allocate memory for it
//
ChunkSize = 8 * 1024 * 1024;
if (gRamDiskSize < ChunkSize)
Percent = PercentPerChunk = 0;
else
Percent = PercentPerChunk = 100 / (gRamDiskSize / ChunkSize);
gRamDiskBase = MmAllocateMemoryWithType(gRamDiskSize, LoaderXIPRom);
if (!gRamDiskBase)
{
UiMessageBox("Failed to allocate memory for RAM disk\n");
FsCloseFile(RamFile);
return;
}
//
// Read it in chunks
//
for (TotalRead = 0; TotalRead < gRamDiskSize; TotalRead += ChunkSize)
{
//
// Get the file size
// Check if we're at the last chunk
//
ret = ArcGetFileInformation(RamFile, &Information);
if (ret != ESUCCESS)
if ((gRamDiskSize - TotalRead) < ChunkSize)
{
ArcClose(RamFile);
//
// Only need the actual data required
//
ChunkSize = gRamDiskSize - TotalRead;
}
//
// Draw progress
//
UiDrawProgressBarCenter(Percent, 100, MsgBuffer);
Percent += PercentPerChunk;
//
// Copy the contents
//
Position.HighPart = 0;
Position.LowPart = TotalRead;
ret = ArcSeek(RamFile, &Position, SeekAbsolute);
if (ret == ESUCCESS)
{
ret = ArcRead(RamFile,
(PVOID)((ULONG_PTR)gRamDiskBase + TotalRead),
ChunkSize,
&Count);
}
//
// Check for success
//
if (ret != ESUCCESS || Count != ChunkSize)
{
MmFreeMemory(gRamDiskBase);
gRamDiskBase = NULL;
gRamDiskSize = 0;
FsCloseFile(RamFile);
UiMessageBox("Failed to read RamDisk\n");
return;
}
//
// For now, limit RAM disks to 4GB
//
if (Information.EndingAddress.HighPart != 0)
{
UiMessageBox("RAM disk too big\n");
ArcClose(RamFile);
return;
}
gRamDiskSize = Information.EndingAddress.LowPart;
//
// Allocate memory for it
//
ChunkSize = 8 * 1024 * 1024;
if (gRamDiskSize < ChunkSize)
Percent = PercentPerChunk = 0;
else
Percent = PercentPerChunk = 100 / (gRamDiskSize / ChunkSize);
gRamDiskBase = MmAllocateMemoryWithType(gRamDiskSize, LoaderXIPRom);
if (!gRamDiskBase)
{
UiMessageBox("Failed to allocate memory for RAM disk\n");
ArcClose(RamFile);
return;
}
//
// Read it in chunks
//
for (TotalRead = 0; TotalRead < gRamDiskSize; TotalRead += ChunkSize)
{
//
// Check if we're at the last chunk
//
if ((gRamDiskSize - TotalRead) < ChunkSize)
{
//
// Only need the actual data required
//
ChunkSize = gRamDiskSize - TotalRead;
}
//
// Draw progress
//
UiDrawProgressBarCenter(Percent, 100, MsgBuffer);
Percent += PercentPerChunk;
//
// Copy the contents
//
Position.HighPart = 0;
Position.LowPart = TotalRead;
ret = ArcSeek(RamFile, &Position, SeekAbsolute);
if (ret == ESUCCESS)
{
ret = ArcRead(RamFile,
(PVOID)((ULONG_PTR)gRamDiskBase + TotalRead),
ChunkSize,
&Count);
}
//
// Check for success
//
if (ret != ESUCCESS || Count != ChunkSize)
{
MmFreeMemory(gRamDiskBase);
gRamDiskBase = NULL;
gRamDiskSize = 0;
ArcClose(RamFile);
UiMessageBox("Failed to read ramdisk\n");
return;
}
}
ArcClose(RamFile);
// Register a new device for the ramdisk
FsRegisterDevice("ramdisk(0)", &RamDiskVtbl);
}
FsCloseFile(RamFile);
// Register a new device for the ramdisk
FsRegisterDevice("ramdisk(0)", &RamDiskVtbl);
}

View file

@ -55,31 +55,6 @@ static LIST_ENTRY DeviceListHead;
/* ARC FUNCTIONS **************************************************************/
ARC_STATUS ArcClose(ULONG FileId)
{
LONG ret;
if (FileId >= MAX_FDS || !FileData[FileId].FuncTable)
return EBADF;
ret = FileData[FileId].FuncTable->Close(FileId);
if (ret == ESUCCESS)
{
FileData[FileId].FuncTable = NULL;
FileData[FileId].Specific = NULL;
FileData[FileId].DeviceId = -1;
}
return ret;
}
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
{
if (FileId >= MAX_FDS || !FileData[FileId].FuncTable)
return EBADF;
return FileData[FileId].FuncTable->GetFileInformation(FileId, Information);
}
ARC_STATUS ArcOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
{
ULONG Count, i, ret;
@ -239,6 +214,24 @@ ARC_STATUS ArcOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
return ret;
}
ARC_STATUS ArcClose(ULONG FileId)
{
LONG ret;
if (FileId >= MAX_FDS || !FileData[FileId].FuncTable)
return EBADF;
ret = FileData[FileId].FuncTable->Close(FileId);
if (ret == ESUCCESS)
{
FileData[FileId].FuncTable = NULL;
FileData[FileId].Specific = NULL;
FileData[FileId].DeviceId = -1;
}
return ret;
}
ARC_STATUS ArcRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
{
if (FileId >= MAX_FDS || !FileData[FileId].FuncTable)
@ -253,18 +246,24 @@ ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
return FileData[FileId].FuncTable->Seek(FileId, Position, SeekMode);
}
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
{
if (FileId >= MAX_FDS || !FileData[FileId].FuncTable)
return EBADF;
return FileData[FileId].FuncTable->GetFileInformation(FileId, Information);
}
/* FUNCTIONS ******************************************************************/
VOID FileSystemError(PCSTR ErrorString)
{
ERR("%s\n", ErrorString);
UiMessageBox(ErrorString);
}
PFILE FsOpenFile(PCSTR FileName)
{
CHAR FullPath[MAX_PATH];
CHAR FullPath[MAX_PATH] = "";
ULONG FileId;
LONG ret;
@ -274,9 +273,21 @@ PFILE FsOpenFile(PCSTR FileName)
TRACE("Opening file '%s'...\n", FileName);
//
// Create full file name
// Check whether FileName is a full path
// and if not, create a full file name.
//
MachDiskGetBootPath(FullPath, sizeof(FullPath));
// See ArcOpen: Search last ')', which delimits device and path.
//
if (strrchr(FileName, ')') == NULL)
{
/* This is not a full path. Use the current (i.e. boot) device. */
MachDiskGetBootPath(FullPath, sizeof(FullPath));
/* Append a path separator if needed */
if (FileName[0] != '\\' && FileName[0] != '/')
strcat(FullPath, "\\");
}
// Append (or just copy) the remaining file name.
strcat(FullPath, FileName);
//
@ -298,14 +309,10 @@ VOID FsCloseFile(PFILE FileHandle)
ULONG FileId = (ULONG)FileHandle;
//
// Close the handle
// Close the handle. Do not check for error,
// this function is supposed to always succeed.
//
ArcClose(FileId);
//
// Do not check for error; this function is
// supposed to always succeed
//
}
/*
@ -315,17 +322,21 @@ VOID FsCloseFile(PFILE FileHandle)
BOOLEAN FsReadFile(PFILE FileHandle, ULONG BytesToRead, ULONG* BytesRead, PVOID Buffer)
{
ULONG FileId = (ULONG)FileHandle;
LONG ret;
//
// Read the file
//
ret = ArcRead(FileId, Buffer, BytesToRead, BytesRead);
return (ArcRead(FileId, Buffer, BytesToRead, BytesRead) == ESUCCESS);
}
BOOLEAN FsGetFileInformation(PFILE FileHandle, FILEINFORMATION* Information)
{
ULONG FileId = (ULONG)FileHandle;
//
// Check for success
// Get file information
//
return (ret == ESUCCESS);
return (ArcGetFileInformation(FileId, Information) == ESUCCESS);
}
ULONG FsGetFileSize(PFILE FileHandle)
@ -357,16 +368,12 @@ VOID FsSetFilePointer(PFILE FileHandle, ULONG NewFilePointer)
LARGE_INTEGER Position;
//
// Set file position
// Set file position. Do not check for error,
// this function is supposed to always succeed.
//
Position.HighPart = 0;
Position.LowPart = NewFilePointer;
ArcSeek(FileId, &Position, SeekAbsolute);
//
// Do not check for error; this function is
// supposed to always succeed
//
}
/*

View file

@ -21,41 +21,42 @@
typedef struct tagDEVVTBL
{
ARC_CLOSE Close;
ARC_GET_FILE_INFORMATION GetFileInformation;
ARC_OPEN Open;
ARC_READ Read;
ARC_SEEK Seek;
LPCWSTR ServiceName;
ARC_CLOSE Close;
ARC_GET_FILE_INFORMATION GetFileInformation;
ARC_OPEN Open;
ARC_READ Read;
ARC_SEEK Seek;
LPCWSTR ServiceName;
} DEVVTBL;
#define FS_FAT 1
#define FS_NTFS 2
#define FS_EXT2 3
#define FS_ISO9660 5
#define FS_FAT 1
#define FS_NTFS 2
#define FS_EXT2 3
#define FS_ISO9660 5
#define PFILE ULONG
#define PFILE ULONG
ARC_STATUS ArcOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId);
ARC_STATUS ArcClose(ULONG FileId);
ARC_STATUS ArcRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count);
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode);
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION* Information);
VOID FileSystemError(PCSTR ErrorString);
PFILE FsOpenFile(PCSTR FileName);
VOID FsCloseFile(PFILE FileHandle);
BOOLEAN FsReadFile(PFILE FileHandle, ULONG BytesToRead, ULONG* BytesRead, PVOID Buffer);
BOOLEAN FsGetFileInformation(PFILE FileHandle, FILEINFORMATION* Information);
ULONG FsGetFileSize(PFILE FileHandle);
VOID FsSetFilePointer(PFILE FileHandle, ULONG NewFilePointer);
ULONG FsGetNumPathParts(PCSTR Path);
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path);
VOID FsRegisterDevice(CHAR* Prefix, const DEVVTBL* FuncTable);
LPCWSTR FsGetServiceName(ULONG FileId);
VOID FsSetDeviceSpecific(ULONG FileId, VOID* Specific);
VOID FsSetDeviceSpecific(ULONG FileId, VOID* Specific);
VOID* FsGetDeviceSpecific(ULONG FileId);
ULONG FsGetDeviceId(ULONG FileId);
VOID FsInit(VOID);
ARC_STATUS ArcClose(ULONG FileId);
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION* Information);
ARC_STATUS ArcOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId);
ARC_STATUS ArcRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count);
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode);
VOID FileSystemError(PCSTR ErrorString);
PFILE FsOpenFile(PCSTR FileName);
VOID FsCloseFile(PFILE FileHandle);
BOOLEAN FsReadFile(PFILE FileHandle, ULONG BytesToRead, ULONG* BytesRead, PVOID Buffer);
ULONG FsGetFileSize(PFILE FileHandle);
VOID FsSetFilePointer(PFILE FileHandle, ULONG NewFilePointer);
ULONG FsGetNumPathParts(PCSTR Path);
VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path);
VOID FsInit(VOID);
#define MAX_FDS 60