Changes in v1.7.1 (8/7/2002) (brianp)

- Symbolic links on EXT2/3 are now supported

svn path=/trunk/; revision=3320
This commit is contained in:
Brian Palmer 2002-08-08 04:28:08 +00:00
parent f5ac842ed4
commit 3cb41fbb8b
4 changed files with 146 additions and 22 deletions

View file

@ -1,3 +1,7 @@
Changes in v1.7.1 (8/7/2002) (brianp)
- Symbolic links on EXT2/3 are now supported
Changes in v1.7 (8/6/2002) (brianp)
- EXT2/EXT3 file system support.

View file

@ -90,24 +90,96 @@ FILE* Ext2OpenFile(PUCHAR FileName)
{
EXT2_FILE_INFO TempExt2FileInfo;
PEXT2_FILE_INFO FileHandle;
UCHAR SymLinkPath[EXT3_NAME_LEN];
UCHAR FullPath[EXT3_NAME_LEN * 2];
U32 Index;
DbgPrint((DPRINT_FILESYSTEM, "Ext2OpenFile() FileName = %s\n", FileName));
RtlZeroMemory(SymLinkPath, EXT3_NAME_LEN);
// Lookup the file in the file system
if (!Ext2LookupFile(FileName, &TempExt2FileInfo))
{
return NULL;
}
FileHandle = MmAllocateMemory(sizeof(EXT2_FILE_INFO));
if (FileHandle == NULL)
// If we got a symbolic link then fix up the path
// and re-call this function
if ((TempExt2FileInfo.Inode.i_mode & EXT2_S_IFMT) == EXT2_S_IFLNK)
{
return NULL;
DbgPrint((DPRINT_FILESYSTEM, "File is a symbolic link\n"));
// Now read in the symbolic link path
if (!Ext2ReadFile(&TempExt2FileInfo, TempExt2FileInfo.FileSize, NULL, SymLinkPath))
{
if (TempExt2FileInfo.FileBlockList != NULL)
{
MmFreeMemory(TempExt2FileInfo.FileBlockList);
}
return NULL;
}
DbgPrint((DPRINT_FILESYSTEM, "Symbolic link path = %s\n", SymLinkPath));
// Get the full path
if (SymLinkPath[0] == '/' || SymLinkPath[0] == '\\')
{
// Symbolic link is an absolute path
// So copy it to FullPath, but skip over
// the '/' char at the beginning
strcpy(FullPath, &SymLinkPath[1]);
}
else
{
// Symbolic link is a relative path
// Copy the first part of the path
strcpy(FullPath, FileName);
// Remove the last part of the path
for (Index=strlen(FullPath); Index>0; )
{
Index--;
if (FullPath[Index] == '/' || FullPath[Index] == '\\')
{
break;
}
}
FullPath[Index] = '\0';
// Concatenate the symbolic link
strcat(FullPath, "/");
strcat(FullPath, SymLinkPath);
}
DbgPrint((DPRINT_FILESYSTEM, "Full file path = %s\n", FullPath));
if (TempExt2FileInfo.FileBlockList != NULL)
{
MmFreeMemory(TempExt2FileInfo.FileBlockList);
}
return Ext2OpenFile(FullPath);
}
else
{
FileHandle = MmAllocateMemory(sizeof(EXT2_FILE_INFO));
RtlCopyMemory(FileHandle, &TempExt2FileInfo, sizeof(EXT2_FILE_INFO));
if (FileHandle == NULL)
{
if (TempExt2FileInfo.FileBlockList != NULL)
{
MmFreeMemory(TempExt2FileInfo.FileBlockList);
}
return (FILE*)FileHandle;
return NULL;
}
RtlCopyMemory(FileHandle, &TempExt2FileInfo, sizeof(EXT2_FILE_INFO));
return (FILE*)FileHandle;
}
}
/*
@ -181,21 +253,37 @@ BOOL Ext2LookupFile(PUCHAR FileName, PEXT2_FILE_INFO Ext2FileInfoPointer)
return FALSE;
}
if ((InodeData.i_mode & EXT2_S_IFMT) != EXT2_S_IFREG)
if (((InodeData.i_mode & EXT2_S_IFMT) != EXT2_S_IFREG) &&
((InodeData.i_mode & EXT2_S_IFMT) != EXT2_S_IFLNK))
{
FileSystemError("Inode is not a regular file.");
FileSystemError("Inode is not a regular file or symbolic link.");
return FALSE;
}
// Set the drive number
Ext2FileInfoPointer->DriveNumber = Ext2DriveNumber;
Ext2FileInfoPointer->FileBlockList = Ext2ReadBlockPointerList(&InodeData);
// If it's a regular file or a regular symbolic link
// then get the block pointer list otherwise it must
// be a fast symbolic link which doesn't have a block list
if (((InodeData.i_mode & EXT2_S_IFMT) == EXT2_S_IFREG) ||
((InodeData.i_mode & EXT2_S_IFMT) == EXT2_S_IFLNK && InodeData.i_size > 60))
{
Ext2FileInfoPointer->FileBlockList = Ext2ReadBlockPointerList(&InodeData);
if (Ext2FileInfoPointer->FileBlockList == NULL)
{
return FALSE;
}
}
else
{
Ext2FileInfoPointer->FileBlockList = NULL;
}
Ext2FileInfoPointer->FilePointer = 0;
Ext2FileInfoPointer->FileSize = Ext2GetInodeFileSize(&InodeData);
if (Ext2FileInfoPointer->FileBlockList == NULL)
{
return FALSE;
}
RtlCopyMemory(&Ext2FileInfoPointer->Inode, &InodeData, sizeof(EXT2_INODE));
return TRUE;
}
@ -272,6 +360,19 @@ BOOL Ext2ReadFile(FILE *FileHandle, U64 BytesToRead, U64* BytesRead, PVOID Buffe
*BytesRead = 0;
}
// Make sure we have the block pointer list if we need it
if (Ext2FileInfo->FileBlockList == NULL)
{
// Block pointer list is NULL
// so this better be a fast symbolic link or else
if (((Ext2FileInfo->Inode.i_mode & EXT2_S_IFMT) != EXT2_S_IFLNK) ||
(Ext2FileInfo->FileSize > 60))
{
FileSystemError("Block pointer list is NULL and file is not a fast symbolic link.");
return FALSE;
}
}
//
// If they are trying to read past the
// end of the file then return success
@ -291,6 +392,24 @@ BOOL Ext2ReadFile(FILE *FileHandle, U64 BytesToRead, U64* BytesRead, PVOID Buffe
BytesToRead = (Ext2FileInfo->FileSize - Ext2FileInfo->FilePointer);
}
// Check if this is a fast symbolic link
// if so then the read is easy
if (((Ext2FileInfo->Inode.i_mode & EXT2_S_IFMT) == EXT2_S_IFLNK) &&
(Ext2FileInfo->FileSize <= 60))
{
DbgPrint((DPRINT_FILESYSTEM, "Reading fast symbolic link data\n"));
// Copy the data from the link
RtlCopyMemory(Buffer, (PVOID)(Ext2FileInfo->Inode.i_block) + Ext2FileInfo->FilePointer, BytesToRead);
if (BytesRead != NULL)
{
*BytesRead = BytesToRead;
}
return TRUE;
}
//
// Ok, now we have to perform at most 3 calculations
// I'll draw you a picture (using nifty ASCII art):

View file

@ -650,15 +650,16 @@ typedef struct ext3_dir_entry_2 EXT2_DIR_ENTRY, *PEXT2_DIR_ENTRY;
#define EXT2_S_IFDIR 0x4000 // Directory
#define EXT2_S_IFBLK 0x6000 // Block device
#define EXT2_S_IFREG 0x8000 // Regular file
#define EXT2_S_IFSOCK 0xA000 // Socket
#define EXT2_S_IFLNK 0xC000 // Symbolic link
#define EXT2_S_IFLNK 0xA000 // Symbolic link
#define EXT2_S_IFSOCK 0xC000 // Socket
typedef struct
{
U64 FileSize; // File size
U64 FilePointer; // File pointer
U32* FileBlockList; // File block list
U8 DriveNumber; // Drive number of open file
U64 FileSize; // File size
U64 FilePointer; // File pointer
U32* FileBlockList; // File block list
U8 DriveNumber; // Drive number of open file
EXT2_INODE Inode; // File's inode
} EXT2_FILE_INFO, * PEXT2_FILE_INFO;

View file

@ -22,7 +22,7 @@
/* just some stuff */
#define VERSION "FreeLoader v1.7"
#define VERSION "FreeLoader v1.7.1"
#define COPYRIGHT "Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>"
#define AUTHOR_EMAIL "<brianp@sginet.com>"
#define BY_AUTHOR "by Brian Palmer"
@ -36,7 +36,7 @@
//
#define FREELOADER_MAJOR_VERSION 1
#define FREELOADER_MINOR_VERSION 7
#define FREELOADER_PATCH_VERSION 0
#define FREELOADER_PATCH_VERSION 1
PUCHAR GetFreeLoaderVersionString(VOID);