Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion boot/freeldr/freeldr/include/fs/btrfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ typedef u64 __u64;

#define BTRFS_DEV_ITEMS_OBJECTID 1ULL

#define BTRFS_FT_UNKNOWN 0
#define BTRFS_FT_REG_FILE 1
#define BTRFS_FT_DIR 2
#define BTRFS_FT_SYMLINK 7
Expand Down Expand Up @@ -416,6 +417,9 @@ typedef struct {
u64 position;
struct btrfs_inode_item inode;
PBTRFS_INFO Volume;
} btrfs_file_info, * pbtrfs_file_info;
ULONG FileNameLength;
UCHAR Attributes;
CHAR FileName[RTL_FIELD_SIZE(FILEINFORMATION, FileName)];
} btrfs_file_info, *pbtrfs_file_info;

const DEVVTBL* BtrFsMount(ULONG DeviceId);
11 changes: 7 additions & 4 deletions boot/freeldr/freeldr/include/fs/ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,14 @@ typedef struct _EXT_VOLUME_INFO *PEXT_VOLUME_INFO;

typedef struct _EXT_FILE_INFO
{
ULONGLONG FileSize; // File size
ULONGLONG FilePointer; // File pointer
PULONG FileBlockList; // File block list
EXT_INODE Inode; // File's inode
PEXT_VOLUME_INFO Volume;
PULONG FileBlockList; // File block list
EXT_INODE Inode; // File inode
ULONGLONG FileSize; // File size
ULONGLONG FilePointer; // File pointer
ULONG FileNameLength;
UCHAR Attributes;
CHAR FileName[RTL_FIELD_SIZE(FILEINFORMATION, FileName)];
} EXT_FILE_INFO, *PEXT_FILE_INFO;

const DEVVTBL* ExtMount(ULONG DeviceId);
52 changes: 27 additions & 25 deletions boot/freeldr/freeldr/include/fs/fat.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,33 +143,35 @@ typedef struct
} FATX_DIRENTRY, * PFATX_DIRENTRY;
#include <poppack.h>

#define FAT_ATTR_NORMAL 0x00
#define FAT_ATTR_READONLY 0x01
#define FAT_ATTR_HIDDEN 0x02
#define FAT_ATTR_SYSTEM 0x04
#define FAT_ATTR_VOLUMENAME 0x08
#define FAT_ATTR_DIRECTORY 0x10
#define FAT_ATTR_ARCHIVE 0x20
#define FAT_ATTR_LONG_NAME (FAT_ATTR_READONLY | FAT_ATTR_HIDDEN | FAT_ATTR_SYSTEM | FAT_ATTR_VOLUMENAME)

#define FAT12 1
#define FAT16 2
#define FAT32 3
#define FATX16 4
#define FATX32 5

#define ISFATX(FT) ((FT) == FATX16 || (FT) == FATX32)

typedef struct _FAT_VOLUME_INFO *PFAT_VOLUME_INFO;

typedef struct
typedef struct _FAT_FILE_INFO
{
PFAT_VOLUME_INFO Volume;
ULONG FileSize; /* File size */
ULONG FilePointer; /* File pointer */
ULONG CurrentCluster; /* The cluster for file pointer */
ULONG StartCluster; /* The first cluster for file */
UCHAR Attributes; /* File attributes */
} FAT_FILE_INFO, * PFAT_FILE_INFO;

#define ATTR_NORMAL 0x00
#define ATTR_READONLY 0x01
#define ATTR_HIDDEN 0x02
#define ATTR_SYSTEM 0x04
#define ATTR_VOLUMENAME 0x08
#define ATTR_DIRECTORY 0x10
#define ATTR_ARCHIVE 0x20
#define ATTR_LONG_NAME (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUMENAME)

#define FAT12 1
#define FAT16 2
#define FAT32 3
#define FATX16 4
#define FATX32 5

#define ISFATX(FT) ((FT) == FATX16 || (FT) == FATX32)
PFAT_VOLUME_INFO Volume;
ULONG FileSize; // File size
ULONG FilePointer; // File pointer
ULONG CurrentCluster; // Cluster for file pointer
ULONG StartCluster; // File first cluster
ULONG FileNameLength;
UCHAR Attributes;
CHAR FileName[RTL_FIELD_SIZE(FILEINFORMATION, FileName)];
} FAT_FILE_INFO, *PFAT_FILE_INFO;

const DEVVTBL* FatMount(ULONG DeviceId);
10 changes: 9 additions & 1 deletion boot/freeldr/freeldr/include/fs/iso.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,21 @@ typedef struct _PVD
} PVD, *PPVD;
#include <poppack.h>

#define ISO_ATTR_HIDDEN 0x01 // CD_ATTRIBUTE_HIDDEN
#define ISO_ATTR_DIRECTORY 0x02 // CD_ATTRIBUTE_DIRECTORY
#define ISO_ATTR_ASSOC 0x04 // CD_ATTRIBUTE_ASSOC
#define ISO_ATTR_MULTI 0x80 // CD_ATTRIBUTE_MULTI

typedef struct _ISO_FILE_INFO
{
// PISO_VOLUME_INFO Volume;
ULONG FileStart; // File start sector
ULONG FileSize; // File size
ULONG FilePointer; // File pointer
BOOLEAN Directory;
ULONG DriveNumber;
ULONG FileNameLength;
UCHAR Attributes;
CHAR FileName[RTL_FIELD_SIZE(FILEINFORMATION, FileName)];
} ISO_FILE_INFO, *PISO_FILE_INFO;

const DEVVTBL* IsoMount(ULONG DeviceId);
21 changes: 15 additions & 6 deletions boot/freeldr/freeldr/include/fs/ntfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@
#define NTFS_FILE_NAME_DOS 2
#define NTFS_FILE_NAME_WIN32_AND_DOS 3

#define NTFS_FILE_ATTR_NORMAL 0x00
#define NTFS_FILE_ATTR_READONLY 0x01
#define NTFS_FILE_ATTR_HIDDEN 0x02
#define NTFS_FILE_ATTR_SYSTEM 0x04
// 0x08, 0x10 are unused.
#define NTFS_FILE_ATTR_ARCHIVE 0x20
#define NTFS_FILE_ATTR_DIRECTORY 0x10000000

#define NTFS_MFT_MASK 0x0000FFFFFFFFFFFFULL

#include <pshpack1.h>
Expand Down Expand Up @@ -240,13 +248,14 @@ typedef struct

typedef struct _NTFS_VOLUME_INFO *PNTFS_VOLUME_INFO;

#include <pshpack1.h>
typedef struct
typedef struct _NTFS_FILE_HANDLE
{
PNTFS_ATTR_CONTEXT DataContext;
ULONGLONG Offset;
PNTFS_VOLUME_INFO Volume;
PNTFS_VOLUME_INFO Volume;
PNTFS_ATTR_CONTEXT DataContext;
ULONGLONG Offset;
ULONG FileNameLength;
UCHAR Attributes;
CHAR FileName[RTL_FIELD_SIZE(FILEINFORMATION, FileName)];
} NTFS_FILE_HANDLE, *PNTFS_FILE_HANDLE;
#include <poppack.h>

const DEVVTBL* NtfsMount(ULONG DeviceId);
62 changes: 55 additions & 7 deletions boot/freeldr/freeldr/lib/fs/btrfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/* Some code was taken from u-boot, https://github.com/u-boot/u-boot/tree/master/fs/btrfs */

#include <freeldr.h>
#include "fs/stat.h"

#include <debug.h>
DBG_DEFAULT_CHANNEL(FILESYSTEM);
Expand Down Expand Up @@ -1051,15 +1052,16 @@ static inline const char *skip_current_directories(const char *cur)

static u64 btrfs_lookup_path(PBTRFS_INFO BtrFsInfo,
const struct btrfs_root_item *root, u64 inr, const char *path,
u8 *type_p, struct btrfs_inode_item *inode_item_p, int symlink_limit)
u8 *type_p, struct btrfs_inode_item *inode_item_p, int symlink_limit,
_Out_opt_ PCHAR filename_buffer, _Inout_ PULONG filename_length)
{
struct btrfs_dir_item item;
struct btrfs_inode_item inode_item;
u8 type = BTRFS_FT_DIR;
int len, have_inode = 0;
const char *cur = path;
struct btrfs_disk_key key;
char *link_target = NULL;
const char *last_elem;
int last_elem_len;

if (*cur == '/' || *cur == '\\')
{
Expand All @@ -1078,6 +1080,10 @@ static u64 btrfs_lookup_path(PBTRFS_INFO BtrFsInfo,
return INVALID_INODE;
}

/* Save the pointer/length of the current path element */
last_elem = cur;
last_elem_len = len;

if (len == 1 && cur[0] == '.')
break;

Expand Down Expand Up @@ -1109,6 +1115,8 @@ static u64 btrfs_lookup_path(PBTRFS_INFO BtrFsInfo,

if (type == BTRFS_FT_SYMLINK && symlink_limit >= 0)
{
char *link_target = NULL;

if (!symlink_limit)
{
TRACE("%s: Too much symlinks!\n");
Expand All @@ -1119,7 +1127,9 @@ static u64 btrfs_lookup_path(PBTRFS_INFO BtrFsInfo,
if (!btrfs_readlink(BtrFsInfo, root, item.location.objectid, &link_target))
return INVALID_INODE;

inr = btrfs_lookup_path(BtrFsInfo, root, inr, link_target, &type, &inode_item, symlink_limit - 1);
inr = btrfs_lookup_path(BtrFsInfo, root, inr, link_target,
&type, &inode_item, symlink_limit - 1,
NULL, NULL);

FrLdrTempFree(link_target, TAG_BTRFS_LINK);

Expand All @@ -1144,6 +1154,7 @@ static u64 btrfs_lookup_path(PBTRFS_INFO BtrFsInfo,
{
if (!have_inode)
{
struct btrfs_disk_key key;
key.objectid = inr;
key.type = BTRFS_INODE_ITEM_KEY;
key.offset = 0;
Expand All @@ -1155,6 +1166,13 @@ static u64 btrfs_lookup_path(PBTRFS_INFO BtrFsInfo,
*inode_item_p = inode_item;
}

if (filename_buffer)
{
/* Copy the file name, perhaps truncated */
*filename_length = min(*filename_length, last_elem_len);
RtlCopyMemory(filename_buffer, last_elem, *filename_length);
}

return inr;
}

Expand All @@ -1176,6 +1194,14 @@ ARC_STATUS BtrFsGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Information->EndingAddress.QuadPart = phandle->inode.size;
Information->CurrentAddress.QuadPart = phandle->position;

/* Set the ARC file attributes */
Information->Attributes = phandle->Attributes;

/* Copy the file name, perhaps truncated, and NUL-terminated */
Information->FileNameLength = min(phandle->FileNameLength, sizeof(Information->FileName) - 1);
RtlCopyMemory(Information->FileName, phandle->FileName, Information->FileNameLength);
Information->FileName[Information->FileNameLength] = ANSI_NULL;

TRACE("BtrFsGetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
FileId, Information->EndingAddress.QuadPart, Information->CurrentAddress.QuadPart);

Expand All @@ -1186,6 +1212,7 @@ ARC_STATUS BtrFsOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
{
PBTRFS_INFO BtrFsInfo;
ULONG DeviceId;
ULONG FileNameLength;
u64 inr;
u8 type;

Expand All @@ -1202,22 +1229,43 @@ ARC_STATUS BtrFsOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
DeviceId = FsGetDeviceId(*FileId);
BtrFsInfo = BtrFsVolumes[DeviceId];

temp_file_info.FileNameLength = 0;
temp_file_info.FileName[0] = ANSI_NULL;
FileNameLength = sizeof(temp_file_info.FileName) - 1;

inr = btrfs_lookup_path(BtrFsInfo, &BtrFsInfo->FsRoot,
BtrFsInfo->FsRoot.root_dirid,
Path, &type, &temp_file_info.inode, 40);

Path, &type, &temp_file_info.inode, 40,
temp_file_info.FileName, &FileNameLength);
if (inr == INVALID_INODE)
{
TRACE("Cannot lookup file %s\n", Path);
return ENOENT;
}

if (type != BTRFS_FT_REG_FILE)
{
TRACE("Not a regular file: %s\n", Path);
return EISDIR;
}

temp_file_info.FileNameLength = FileNameLength;

/* Map the attributes to ARC file attributes. NOTE: We don't look
* at the "user.DOSATTRIB" (EA_DOSATTRIB) WinBtrfs-compatible XATTR. */
temp_file_info.Attributes = 0;
if (!(temp_file_info.inode.mode & (_S_IWUSR | _S_IWGRP | _S_IWOTH)))
temp_file_info.Attributes |= ReadOnlyFile;
if (_S_ISDIR(temp_file_info.inode.mode))
temp_file_info.Attributes |= DirectoryFile;

/* Set hidden attribute for all entries starting with '.' */
if ((temp_file_info.FileNameLength >= 2 && temp_file_info.FileName[0] == '.') &&
((temp_file_info.FileNameLength == 2 && temp_file_info.FileName[1] != '.') ||
temp_file_info.FileNameLength >= 3))
{
temp_file_info.Attributes |= HiddenFile;
}

TRACE("found inode inr=%llu size=%llu\n", inr, temp_file_info.inode.size);

temp_file_info.inr = inr;
Expand Down
Loading