mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
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:
parent
f5ac842ed4
commit
3cb41fbb8b
4 changed files with 146 additions and 22 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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));
|
||||
|
||||
if (FileHandle == NULL)
|
||||
{
|
||||
if (TempExt2FileInfo.FileBlockList != NULL)
|
||||
{
|
||||
MmFreeMemory(TempExt2FileInfo.FileBlockList);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// 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);
|
||||
Ext2FileInfoPointer->FilePointer = 0;
|
||||
Ext2FileInfoPointer->FileSize = Ext2GetInodeFileSize(&InodeData);
|
||||
|
||||
if (Ext2FileInfoPointer->FileBlockList == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Ext2FileInfoPointer->FileBlockList = NULL;
|
||||
}
|
||||
|
||||
Ext2FileInfoPointer->FilePointer = 0;
|
||||
Ext2FileInfoPointer->FileSize = Ext2GetInodeFileSize(&InodeData);
|
||||
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):
|
||||
|
|
|
@ -650,8 +650,8 @@ 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
|
||||
{
|
||||
|
@ -659,6 +659,7 @@ typedef struct
|
|||
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;
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue