Skip to content

Commit c7d4040

Browse files
committed
[FREELDR] ArcGetFileInformation(): Set Information->FileName, Length, and Attributes for filesystems (reactos#8420)
CORE-9023 Add support for all the supported filesystems: FAT/FATX, NTFS, ISO, EXT, BTRFS, as well as for files loaded via PXE. arc.h: - Add `FILEATTRIBUTES` enumeration; - Remove non-existing `CreateReadOnly` and `SupersedeReadOnly` `OPENMODE` values; add missing `CreateReadWrite`.
1 parent eec9ca1 commit c7d4040

File tree

12 files changed

+314
-88
lines changed

12 files changed

+314
-88
lines changed

boot/freeldr/freeldr/include/fs/btrfs.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ typedef u64 __u64;
7171

7272
#define BTRFS_DEV_ITEMS_OBJECTID 1ULL
7373

74+
#define BTRFS_FT_UNKNOWN 0
7475
#define BTRFS_FT_REG_FILE 1
7576
#define BTRFS_FT_DIR 2
7677
#define BTRFS_FT_SYMLINK 7
@@ -416,6 +417,9 @@ typedef struct {
416417
u64 position;
417418
struct btrfs_inode_item inode;
418419
PBTRFS_INFO Volume;
419-
} btrfs_file_info, * pbtrfs_file_info;
420+
ULONG FileNameLength;
421+
UCHAR Attributes;
422+
CHAR FileName[RTL_FIELD_SIZE(FILEINFORMATION, FileName)];
423+
} btrfs_file_info, *pbtrfs_file_info;
420424

421425
const DEVVTBL* BtrFsMount(ULONG DeviceId);

boot/freeldr/freeldr/include/fs/ext.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,14 @@ typedef struct _EXT_VOLUME_INFO *PEXT_VOLUME_INFO;
220220

221221
typedef struct _EXT_FILE_INFO
222222
{
223-
ULONGLONG FileSize; // File size
224-
ULONGLONG FilePointer; // File pointer
225-
PULONG FileBlockList; // File block list
226-
EXT_INODE Inode; // File's inode
227223
PEXT_VOLUME_INFO Volume;
224+
PULONG FileBlockList; // File block list
225+
EXT_INODE Inode; // File inode
226+
ULONGLONG FileSize; // File size
227+
ULONGLONG FilePointer; // File pointer
228+
ULONG FileNameLength;
229+
UCHAR Attributes;
230+
CHAR FileName[RTL_FIELD_SIZE(FILEINFORMATION, FileName)];
228231
} EXT_FILE_INFO, *PEXT_FILE_INFO;
229232

230233
const DEVVTBL* ExtMount(ULONG DeviceId);

boot/freeldr/freeldr/include/fs/fat.h

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -143,33 +143,35 @@ typedef struct
143143
} FATX_DIRENTRY, * PFATX_DIRENTRY;
144144
#include <poppack.h>
145145

146+
#define FAT_ATTR_NORMAL 0x00
147+
#define FAT_ATTR_READONLY 0x01
148+
#define FAT_ATTR_HIDDEN 0x02
149+
#define FAT_ATTR_SYSTEM 0x04
150+
#define FAT_ATTR_VOLUMENAME 0x08
151+
#define FAT_ATTR_DIRECTORY 0x10
152+
#define FAT_ATTR_ARCHIVE 0x20
153+
#define FAT_ATTR_LONG_NAME (FAT_ATTR_READONLY | FAT_ATTR_HIDDEN | FAT_ATTR_SYSTEM | FAT_ATTR_VOLUMENAME)
154+
155+
#define FAT12 1
156+
#define FAT16 2
157+
#define FAT32 3
158+
#define FATX16 4
159+
#define FATX32 5
160+
161+
#define ISFATX(FT) ((FT) == FATX16 || (FT) == FATX32)
162+
146163
typedef struct _FAT_VOLUME_INFO *PFAT_VOLUME_INFO;
147164

148-
typedef struct
165+
typedef struct _FAT_FILE_INFO
149166
{
150-
PFAT_VOLUME_INFO Volume;
151-
ULONG FileSize; /* File size */
152-
ULONG FilePointer; /* File pointer */
153-
ULONG CurrentCluster; /* The cluster for file pointer */
154-
ULONG StartCluster; /* The first cluster for file */
155-
UCHAR Attributes; /* File attributes */
156-
} FAT_FILE_INFO, * PFAT_FILE_INFO;
157-
158-
#define ATTR_NORMAL 0x00
159-
#define ATTR_READONLY 0x01
160-
#define ATTR_HIDDEN 0x02
161-
#define ATTR_SYSTEM 0x04
162-
#define ATTR_VOLUMENAME 0x08
163-
#define ATTR_DIRECTORY 0x10
164-
#define ATTR_ARCHIVE 0x20
165-
#define ATTR_LONG_NAME (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUMENAME)
166-
167-
#define FAT12 1
168-
#define FAT16 2
169-
#define FAT32 3
170-
#define FATX16 4
171-
#define FATX32 5
172-
173-
#define ISFATX(FT) ((FT) == FATX16 || (FT) == FATX32)
167+
PFAT_VOLUME_INFO Volume;
168+
ULONG FileSize; // File size
169+
ULONG FilePointer; // File pointer
170+
ULONG CurrentCluster; // Cluster for file pointer
171+
ULONG StartCluster; // File first cluster
172+
ULONG FileNameLength;
173+
UCHAR Attributes;
174+
CHAR FileName[RTL_FIELD_SIZE(FILEINFORMATION, FileName)];
175+
} FAT_FILE_INFO, *PFAT_FILE_INFO;
174176

175177
const DEVVTBL* FatMount(ULONG DeviceId);

boot/freeldr/freeldr/include/fs/iso.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,21 @@ typedef struct _PVD
8989
} PVD, *PPVD;
9090
#include <poppack.h>
9191

92+
#define ISO_ATTR_HIDDEN 0x01 // CD_ATTRIBUTE_HIDDEN
93+
#define ISO_ATTR_DIRECTORY 0x02 // CD_ATTRIBUTE_DIRECTORY
94+
#define ISO_ATTR_ASSOC 0x04 // CD_ATTRIBUTE_ASSOC
95+
#define ISO_ATTR_MULTI 0x80 // CD_ATTRIBUTE_MULTI
9296

9397
typedef struct _ISO_FILE_INFO
9498
{
99+
// PISO_VOLUME_INFO Volume;
95100
ULONG FileStart; // File start sector
96101
ULONG FileSize; // File size
97102
ULONG FilePointer; // File pointer
98-
BOOLEAN Directory;
103+
ULONG DriveNumber;
104+
ULONG FileNameLength;
105+
UCHAR Attributes;
106+
CHAR FileName[RTL_FIELD_SIZE(FILEINFORMATION, FileName)];
99107
} ISO_FILE_INFO, *PISO_FILE_INFO;
100108

101109
const DEVVTBL* IsoMount(ULONG DeviceId);

boot/freeldr/freeldr/include/fs/ntfs.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@
6565
#define NTFS_FILE_NAME_DOS 2
6666
#define NTFS_FILE_NAME_WIN32_AND_DOS 3
6767

68+
#define NTFS_FILE_ATTR_NORMAL 0x00
69+
#define NTFS_FILE_ATTR_READONLY 0x01
70+
#define NTFS_FILE_ATTR_HIDDEN 0x02
71+
#define NTFS_FILE_ATTR_SYSTEM 0x04
72+
// 0x08, 0x10 are unused.
73+
#define NTFS_FILE_ATTR_ARCHIVE 0x20
74+
#define NTFS_FILE_ATTR_DIRECTORY 0x10000000
75+
6876
#define NTFS_MFT_MASK 0x0000FFFFFFFFFFFFULL
6977

7078
#include <pshpack1.h>
@@ -240,13 +248,14 @@ typedef struct
240248

241249
typedef struct _NTFS_VOLUME_INFO *PNTFS_VOLUME_INFO;
242250

243-
#include <pshpack1.h>
244-
typedef struct
251+
typedef struct _NTFS_FILE_HANDLE
245252
{
246-
PNTFS_ATTR_CONTEXT DataContext;
247-
ULONGLONG Offset;
248-
PNTFS_VOLUME_INFO Volume;
253+
PNTFS_VOLUME_INFO Volume;
254+
PNTFS_ATTR_CONTEXT DataContext;
255+
ULONGLONG Offset;
256+
ULONG FileNameLength;
257+
UCHAR Attributes;
258+
CHAR FileName[RTL_FIELD_SIZE(FILEINFORMATION, FileName)];
249259
} NTFS_FILE_HANDLE, *PNTFS_FILE_HANDLE;
250-
#include <poppack.h>
251260

252261
const DEVVTBL* NtfsMount(ULONG DeviceId);

boot/freeldr/freeldr/lib/fs/btrfs.c

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
/* Some code was taken from u-boot, https://github.com/u-boot/u-boot/tree/master/fs/btrfs */
99

1010
#include <freeldr.h>
11+
#include "fs/stat.h"
1112

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

10521053
static u64 btrfs_lookup_path(PBTRFS_INFO BtrFsInfo,
10531054
const struct btrfs_root_item *root, u64 inr, const char *path,
1054-
u8 *type_p, struct btrfs_inode_item *inode_item_p, int symlink_limit)
1055+
u8 *type_p, struct btrfs_inode_item *inode_item_p, int symlink_limit,
1056+
_Out_opt_ PCHAR filename_buffer, _Inout_ PULONG filename_length)
10551057
{
10561058
struct btrfs_dir_item item;
10571059
struct btrfs_inode_item inode_item;
10581060
u8 type = BTRFS_FT_DIR;
10591061
int len, have_inode = 0;
10601062
const char *cur = path;
1061-
struct btrfs_disk_key key;
1062-
char *link_target = NULL;
1063+
const char *last_elem;
1064+
int last_elem_len;
10631065

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

1083+
/* Save the pointer/length of the current path element */
1084+
last_elem = cur;
1085+
last_elem_len = len;
1086+
10811087
if (len == 1 && cur[0] == '.')
10821088
break;
10831089

@@ -1109,6 +1115,8 @@ static u64 btrfs_lookup_path(PBTRFS_INFO BtrFsInfo,
11091115

11101116
if (type == BTRFS_FT_SYMLINK && symlink_limit >= 0)
11111117
{
1118+
char *link_target = NULL;
1119+
11121120
if (!symlink_limit)
11131121
{
11141122
TRACE("%s: Too much symlinks!\n");
@@ -1119,7 +1127,9 @@ static u64 btrfs_lookup_path(PBTRFS_INFO BtrFsInfo,
11191127
if (!btrfs_readlink(BtrFsInfo, root, item.location.objectid, &link_target))
11201128
return INVALID_INODE;
11211129

1122-
inr = btrfs_lookup_path(BtrFsInfo, root, inr, link_target, &type, &inode_item, symlink_limit - 1);
1130+
inr = btrfs_lookup_path(BtrFsInfo, root, inr, link_target,
1131+
&type, &inode_item, symlink_limit - 1,
1132+
NULL, NULL);
11231133

11241134
FrLdrTempFree(link_target, TAG_BTRFS_LINK);
11251135

@@ -1144,6 +1154,7 @@ static u64 btrfs_lookup_path(PBTRFS_INFO BtrFsInfo,
11441154
{
11451155
if (!have_inode)
11461156
{
1157+
struct btrfs_disk_key key;
11471158
key.objectid = inr;
11481159
key.type = BTRFS_INODE_ITEM_KEY;
11491160
key.offset = 0;
@@ -1155,6 +1166,13 @@ static u64 btrfs_lookup_path(PBTRFS_INFO BtrFsInfo,
11551166
*inode_item_p = inode_item;
11561167
}
11571168

1169+
if (filename_buffer)
1170+
{
1171+
/* Copy the file name, perhaps truncated */
1172+
*filename_length = min(*filename_length, last_elem_len);
1173+
RtlCopyMemory(filename_buffer, last_elem, *filename_length);
1174+
}
1175+
11581176
return inr;
11591177
}
11601178

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

1197+
/* Set the ARC file attributes */
1198+
Information->Attributes = phandle->Attributes;
1199+
1200+
/* Copy the file name, perhaps truncated, and NUL-terminated */
1201+
Information->FileNameLength = min(phandle->FileNameLength, sizeof(Information->FileName) - 1);
1202+
RtlCopyMemory(Information->FileName, phandle->FileName, Information->FileNameLength);
1203+
Information->FileName[Information->FileNameLength] = ANSI_NULL;
1204+
11791205
TRACE("BtrFsGetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
11801206
FileId, Information->EndingAddress.QuadPart, Information->CurrentAddress.QuadPart);
11811207

@@ -1186,6 +1212,7 @@ ARC_STATUS BtrFsOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
11861212
{
11871213
PBTRFS_INFO BtrFsInfo;
11881214
ULONG DeviceId;
1215+
ULONG FileNameLength;
11891216
u64 inr;
11901217
u8 type;
11911218

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

1232+
temp_file_info.FileNameLength = 0;
1233+
temp_file_info.FileName[0] = ANSI_NULL;
1234+
FileNameLength = sizeof(temp_file_info.FileName) - 1;
1235+
12051236
inr = btrfs_lookup_path(BtrFsInfo, &BtrFsInfo->FsRoot,
12061237
BtrFsInfo->FsRoot.root_dirid,
1207-
Path, &type, &temp_file_info.inode, 40);
1208-
1238+
Path, &type, &temp_file_info.inode, 40,
1239+
temp_file_info.FileName, &FileNameLength);
12091240
if (inr == INVALID_INODE)
12101241
{
12111242
TRACE("Cannot lookup file %s\n", Path);
12121243
return ENOENT;
12131244
}
1214-
12151245
if (type != BTRFS_FT_REG_FILE)
12161246
{
12171247
TRACE("Not a regular file: %s\n", Path);
12181248
return EISDIR;
12191249
}
12201250

1251+
temp_file_info.FileNameLength = FileNameLength;
1252+
1253+
/* Map the attributes to ARC file attributes. NOTE: We don't look
1254+
* at the "user.DOSATTRIB" (EA_DOSATTRIB) WinBtrfs-compatible XATTR. */
1255+
temp_file_info.Attributes = 0;
1256+
if (!(temp_file_info.inode.mode & (_S_IWUSR | _S_IWGRP | _S_IWOTH)))
1257+
temp_file_info.Attributes |= ReadOnlyFile;
1258+
if (_S_ISDIR(temp_file_info.inode.mode))
1259+
temp_file_info.Attributes |= DirectoryFile;
1260+
1261+
/* Set hidden attribute for all entries starting with '.' */
1262+
if ((temp_file_info.FileNameLength >= 2 && temp_file_info.FileName[0] == '.') &&
1263+
((temp_file_info.FileNameLength == 2 && temp_file_info.FileName[1] != '.') ||
1264+
temp_file_info.FileNameLength >= 3))
1265+
{
1266+
temp_file_info.Attributes |= HiddenFile;
1267+
}
1268+
12211269
TRACE("found inode inr=%llu size=%llu\n", inr, temp_file_info.inode.size);
12221270

12231271
temp_file_info.inr = inr;

0 commit comments

Comments
 (0)