mirror of
https://github.com/reactos/reactos.git
synced 2026-05-23 15:50:29 +08:00
[FREELDR] ArcGetFileInformation(): Set Information->FileName, Length, and Attributes for filesystems (#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`.
This commit is contained in:
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -143,33 +143,35 @@ typedef struct
|
||||
} FATX_DIRENTRY, * PFATX_DIRENTRY;
|
||||
#include <poppack.h>
|
||||
|
||||
typedef struct _FAT_VOLUME_INFO *PFAT_VOLUME_INFO;
|
||||
#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)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
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 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 _FAT_FILE_INFO
|
||||
{
|
||||
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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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 == '\\')
|
||||
{
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1186,6 +1212,7 @@ ARC_STATUS BtrFsOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
|
||||
{
|
||||
PBTRFS_INFO BtrFsInfo;
|
||||
ULONG DeviceId;
|
||||
ULONG FileNameLength;
|
||||
u64 inr;
|
||||
u8 type;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -111,7 +111,7 @@ PEXT_FILE_INFO ExtOpenFile(PEXT_VOLUME_INFO Volume, PCSTR FileName)
|
||||
PEXT_FILE_INFO FileHandle;
|
||||
CHAR SymLinkPath[EXT_DIR_ENTRY_MAX_NAME_LENGTH];
|
||||
CHAR FullPath[EXT_DIR_ENTRY_MAX_NAME_LENGTH * 2];
|
||||
ULONG_PTR Index;
|
||||
SIZE_T Index;
|
||||
|
||||
TRACE("ExtOpenFile() FileName = \"%s\"\n", FileName);
|
||||
|
||||
@@ -209,8 +209,8 @@ PEXT_FILE_INFO ExtOpenFile(PEXT_VOLUME_INFO Volume, PCSTR FileName)
|
||||
*/
|
||||
BOOLEAN ExtLookupFile(PEXT_VOLUME_INFO Volume, PCSTR FileName, PEXT_FILE_INFO ExtFileInfo)
|
||||
{
|
||||
UINT32 i;
|
||||
ULONG NumberOfPathParts;
|
||||
ULONG i;
|
||||
CHAR PathPart[261];
|
||||
PVOID DirectoryBuffer;
|
||||
ULONG DirectoryInode = EXT_ROOT_INODE;
|
||||
@@ -302,18 +302,41 @@ BOOLEAN ExtLookupFile(PEXT_VOLUME_INFO Volume, PCSTR FileName, PEXT_FILE_INFO Ex
|
||||
|
||||
ExtFileInfo->FilePointer = 0;
|
||||
ExtFileInfo->FileSize = ExtGetInodeFileSize(&InodeData);
|
||||
RtlCopyMemory(&ExtFileInfo->Inode, &InodeData, sizeof(EXT_INODE));
|
||||
RtlCopyMemory(&ExtFileInfo->Inode, &InodeData, sizeof(InodeData));
|
||||
|
||||
/* Map the attributes to ARC file attributes */
|
||||
ExtFileInfo->Attributes = 0;
|
||||
if (!(InodeData.Mode & (_S_IWUSR | _S_IWGRP | _S_IWOTH)))
|
||||
ExtFileInfo->Attributes |= ReadOnlyFile;
|
||||
if (_S_ISDIR(InodeData.Mode))
|
||||
ExtFileInfo->Attributes |= DirectoryFile;
|
||||
|
||||
/* Set hidden attribute for all entries starting with '.' */
|
||||
if ((DirectoryEntry.NameLen >= 2 && DirectoryEntry.Name[0] == '.') &&
|
||||
((DirectoryEntry.NameLen == 2 && DirectoryEntry.Name[1] != '.') ||
|
||||
DirectoryEntry.NameLen >= 3))
|
||||
{
|
||||
ExtFileInfo->Attributes |= HiddenFile;
|
||||
}
|
||||
|
||||
/* Copy the file name, perhaps truncated */
|
||||
ExtFileInfo->FileNameLength = DirectoryEntry.NameLen; // (ULONG)strlen(PathPart);
|
||||
ExtFileInfo->FileNameLength = min(ExtFileInfo->FileNameLength, sizeof(ExtFileInfo->FileName) - 1);
|
||||
RtlCopyMemory(ExtFileInfo->FileName, DirectoryEntry.Name /*PathPart*/, ExtFileInfo->FileNameLength);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN ExtSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PEXT_DIR_ENTRY DirectoryEntry)
|
||||
{
|
||||
ULONG CurrentOffset = 0;
|
||||
PEXT_DIR_ENTRY CurrentDirectoryEntry;
|
||||
PEXT_DIR_ENTRY CurrentDirectoryEntry;
|
||||
ULONG CurrentOffset = 0;
|
||||
SIZE_T FileNameLen;
|
||||
|
||||
TRACE("ExtSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectorySize = %d FileName = \"%s\"\n", DirectoryBuffer, DirectorySize, FileName);
|
||||
|
||||
FileNameLen = strlen(FileName);
|
||||
|
||||
while (CurrentOffset < DirectorySize)
|
||||
{
|
||||
CurrentDirectoryEntry = (PEXT_DIR_ENTRY)((ULONG_PTR)DirectoryBuffer + CurrentOffset);
|
||||
@@ -342,11 +365,10 @@ BOOLEAN ExtSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG DirectorySi
|
||||
}
|
||||
TRACE("\"\n\n");
|
||||
|
||||
if (strlen(FileName) == CurrentDirectoryEntry->NameLen &&
|
||||
!_strnicmp(FileName, CurrentDirectoryEntry->Name, CurrentDirectoryEntry->NameLen))
|
||||
if ((FileNameLen == CurrentDirectoryEntry->NameLen) &&
|
||||
(_strnicmp(FileName, CurrentDirectoryEntry->Name, FileNameLen) == 0))
|
||||
{
|
||||
RtlCopyMemory(DirectoryEntry, CurrentDirectoryEntry, sizeof(EXT_DIR_ENTRY));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1285,6 +1307,14 @@ ARC_STATUS ExtGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
|
||||
Information->EndingAddress.QuadPart = FileHandle->FileSize;
|
||||
Information->CurrentAddress.QuadPart = FileHandle->FilePointer;
|
||||
|
||||
/* Set the ARC file attributes */
|
||||
Information->Attributes = FileHandle->Attributes;
|
||||
|
||||
/* Copy the file name, perhaps truncated, and NUL-terminated */
|
||||
Information->FileNameLength = min(FileHandle->FileNameLength, sizeof(Information->FileName) - 1);
|
||||
RtlCopyMemory(Information->FileName, FileHandle->FileName, Information->FileNameLength);
|
||||
Information->FileName[Information->FileNameLength] = ANSI_NULL;
|
||||
|
||||
TRACE("ExtGetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
|
||||
FileId, Information->EndingAddress.QuadPart, Information->CurrentAddress.QuadPart);
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ DBG_DEFAULT_CHANNEL(FILESYSTEM);
|
||||
|
||||
ULONG FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, ULONGLONG PartitionSectorCount);
|
||||
PVOID FatBufferDirectory(PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, ULONG* EntryCountPointer, BOOLEAN RootDirectory);
|
||||
BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG EntryCount, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer);
|
||||
ARC_STATUS FatLookupFile(PFAT_VOLUME_INFO Volume, PCSTR FileName, PFAT_FILE_INFO FatFileInfoPointer);
|
||||
void FatParseShortFileName(PCHAR Buffer, PDIRENTRY DirEntry);
|
||||
static BOOLEAN FatGetFatEntry(PFAT_VOLUME_INFO Volume, UINT32 Cluster, PUINT32 ClusterPointer);
|
||||
@@ -503,7 +502,7 @@ PVOID FatBufferDirectory(PFAT_VOLUME_INFO Volume, ULONG DirectoryStartCluster, U
|
||||
return DirectoryBuffer->Data;
|
||||
}
|
||||
|
||||
BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
|
||||
static BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID DirectoryBuffer, ULONG DirectorySize, PCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
|
||||
{
|
||||
ULONG EntryCount;
|
||||
ULONG CurrentEntry;
|
||||
@@ -557,7 +556,7 @@ BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID Directory
|
||||
// Check if this is a LFN entry
|
||||
// If so it needs special handling
|
||||
//
|
||||
if (DirEntry->Attr == ATTR_LONG_NAME)
|
||||
if (DirEntry->Attr == FAT_ATTR_LONG_NAME)
|
||||
{
|
||||
//
|
||||
// Check to see if this is a deleted LFN entry, if so continue
|
||||
@@ -640,7 +639,7 @@ BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID Directory
|
||||
// Check for the volume label attribute
|
||||
// and skip over this entry if found
|
||||
//
|
||||
if (DirEntry->Attr & ATTR_VOLUMENAME)
|
||||
if (DirEntry->Attr & FAT_ATTR_VOLUMENAME)
|
||||
{
|
||||
RtlZeroMemory(ShortNameBuffer, 13 * sizeof(UCHAR));
|
||||
RtlZeroMemory(LfnNameBuffer, 261 * sizeof(UCHAR));
|
||||
@@ -667,8 +666,7 @@ BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID Directory
|
||||
//
|
||||
// See if the file name matches either the short or long name
|
||||
//
|
||||
if (((strlen(FileName) == strlen(LfnNameBuffer)) && (_stricmp(FileName, LfnNameBuffer) == 0)) ||
|
||||
((strlen(FileName) == strlen(ShortNameBuffer)) && (_stricmp(FileName, ShortNameBuffer) == 0)))
|
||||
if ((_stricmp(FileName, LfnNameBuffer) == 0) || (_stricmp(FileName, ShortNameBuffer) == 0))
|
||||
{
|
||||
//
|
||||
// We found the entry, now fill in the FAT_FILE_INFO struct
|
||||
@@ -681,7 +679,9 @@ BOOLEAN FatSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID Directory
|
||||
FatFileInfoPointer->StartCluster = StartCluster;
|
||||
|
||||
TRACE("MSDOS Directory Entry:\n");
|
||||
TRACE("FileName[11] = %c%c%c%c%c%c%c%c%c%c%c\n", DirEntry->FileName[0], DirEntry->FileName[1], DirEntry->FileName[2], DirEntry->FileName[3], DirEntry->FileName[4], DirEntry->FileName[5], DirEntry->FileName[6], DirEntry->FileName[7], DirEntry->FileName[8], DirEntry->FileName[9], DirEntry->FileName[10]);
|
||||
TRACE("FileName[11] = %c%c%c%c%c%c%c%c%c%c%c\n",
|
||||
DirEntry->FileName[0], DirEntry->FileName[1], DirEntry->FileName[2], DirEntry->FileName[3], DirEntry->FileName[4],
|
||||
DirEntry->FileName[5], DirEntry->FileName[6], DirEntry->FileName[7], DirEntry->FileName[8], DirEntry->FileName[9], DirEntry->FileName[10]);
|
||||
TRACE("Attr = 0x%x\n", DirEntry->Attr);
|
||||
TRACE("ReservedNT = 0x%x\n", DirEntry->ReservedNT);
|
||||
TRACE("TimeInTenths = %d\n", DirEntry->TimeInTenths);
|
||||
@@ -734,8 +734,8 @@ static BOOLEAN FatXSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID D
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (FileNameLen == DirEntry->FileNameSize &&
|
||||
0 == _strnicmp(FileName, DirEntry->FileName, FileNameLen))
|
||||
if ((FileNameLen == DirEntry->FileNameSize) &&
|
||||
(_strnicmp(FileName, DirEntry->FileName, FileNameLen) == 0))
|
||||
{
|
||||
/*
|
||||
* We found the entry, now fill in the FAT_FILE_INFO struct
|
||||
@@ -773,8 +773,8 @@ static BOOLEAN FatXSearchDirectoryBufferForFile(PFAT_VOLUME_INFO Volume, PVOID D
|
||||
*/
|
||||
ARC_STATUS FatLookupFile(PFAT_VOLUME_INFO Volume, PCSTR FileName, PFAT_FILE_INFO FatFileInfoPointer)
|
||||
{
|
||||
UINT32 i;
|
||||
ULONG NumberOfPathParts;
|
||||
ULONG i;
|
||||
CHAR PathPart[261];
|
||||
PVOID DirectoryBuffer;
|
||||
ULONG DirectoryStartCluster = 0;
|
||||
@@ -788,6 +788,8 @@ ARC_STATUS FatLookupFile(PFAT_VOLUME_INFO Volume, PCSTR FileName, PFAT_FILE_INFO
|
||||
/* Skip leading path separator, if any */
|
||||
if (*FileName == '\\' || *FileName == '/')
|
||||
++FileName;
|
||||
PathPart[0] = ANSI_NULL;
|
||||
|
||||
//
|
||||
// Figure out how many sub-directories we are nested in
|
||||
//
|
||||
@@ -847,7 +849,7 @@ ARC_STATUS FatLookupFile(PFAT_VOLUME_INFO Volume, PCSTR FileName, PFAT_FILE_INFO
|
||||
//
|
||||
// Check if current entry is a directory
|
||||
//
|
||||
if (!(FatFileInfo.Attributes & ATTR_DIRECTORY))
|
||||
if (!(FatFileInfo.Attributes & FAT_ATTR_DIRECTORY))
|
||||
{
|
||||
return ENOTDIR;
|
||||
}
|
||||
@@ -855,7 +857,25 @@ ARC_STATUS FatLookupFile(PFAT_VOLUME_INFO Volume, PCSTR FileName, PFAT_FILE_INFO
|
||||
}
|
||||
}
|
||||
|
||||
RtlCopyMemory(FatFileInfoPointer, &FatFileInfo, sizeof(FAT_FILE_INFO));
|
||||
RtlCopyMemory(FatFileInfoPointer, &FatFileInfo, sizeof(FatFileInfo));
|
||||
|
||||
/* Re-map the attributes to ARC file attributes */
|
||||
FatFileInfoPointer->Attributes = 0;
|
||||
if (FatFileInfo.Attributes & FAT_ATTR_READONLY)
|
||||
FatFileInfoPointer->Attributes |= ReadOnlyFile;
|
||||
if (FatFileInfo.Attributes & FAT_ATTR_HIDDEN)
|
||||
FatFileInfoPointer->Attributes |= HiddenFile;
|
||||
if (FatFileInfo.Attributes & FAT_ATTR_SYSTEM)
|
||||
FatFileInfoPointer->Attributes |= SystemFile;
|
||||
if (FatFileInfo.Attributes & FAT_ATTR_ARCHIVE)
|
||||
FatFileInfoPointer->Attributes |= ArchiveFile;
|
||||
if (FatFileInfo.Attributes & FAT_ATTR_DIRECTORY)
|
||||
FatFileInfoPointer->Attributes |= DirectoryFile;
|
||||
|
||||
/* Copy the file name, perhaps truncated */
|
||||
FatFileInfoPointer->FileNameLength = (ULONG)strlen(PathPart);
|
||||
FatFileInfoPointer->FileNameLength = min(FatFileInfoPointer->FileNameLength, sizeof(FatFileInfoPointer->FileName) - 1);
|
||||
RtlCopyMemory(FatFileInfoPointer->FileName, PathPart, FatFileInfoPointer->FileNameLength);
|
||||
|
||||
return ESUCCESS;
|
||||
}
|
||||
@@ -1411,6 +1431,14 @@ ARC_STATUS FatGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
|
||||
Information->EndingAddress.LowPart = FileHandle->FileSize;
|
||||
Information->CurrentAddress.LowPart = FileHandle->FilePointer;
|
||||
|
||||
/* Set the ARC file attributes */
|
||||
Information->Attributes = FileHandle->Attributes;
|
||||
|
||||
/* Copy the file name, perhaps truncated, and NUL-terminated */
|
||||
Information->FileNameLength = min(FileHandle->FileNameLength, sizeof(Information->FileName) - 1);
|
||||
RtlCopyMemory(Information->FileName, FileHandle->FileName, Information->FileNameLength);
|
||||
Information->FileName[Information->FileNameLength] = ANSI_NULL;
|
||||
|
||||
TRACE("FatGetFileInformation(%lu) -> FileSize = %lu, FilePointer = 0x%lx\n",
|
||||
FileId, Information->EndingAddress.LowPart, Information->CurrentAddress.LowPart);
|
||||
|
||||
@@ -1442,7 +1470,7 @@ ARC_STATUS FatOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
|
||||
//
|
||||
// Check if caller opened what he expected (dir vs file)
|
||||
//
|
||||
IsDirectory = (TempFileInfo.Attributes & ATTR_DIRECTORY) != 0;
|
||||
IsDirectory = !!(TempFileInfo.Attributes & DirectoryFile);
|
||||
if (IsDirectory && OpenMode != OpenDirectory)
|
||||
return EISDIR;
|
||||
else if (!IsDirectory && OpenMode != OpenReadOnly)
|
||||
|
||||
@@ -101,16 +101,14 @@ static BOOLEAN IsoSearchDirectoryBufferForFile(PVOID DirectoryBuffer, ULONG Dire
|
||||
Name[i] = ANSI_NULL;
|
||||
TRACE("Name '%s'\n", Name);
|
||||
|
||||
if (strlen(FileName) == strlen(Name) && _stricmp(FileName, Name) == 0)
|
||||
if (_stricmp(FileName, Name) == 0)
|
||||
{
|
||||
IsoFileInfoPointer->FileStart = Record->ExtentLocationL;
|
||||
IsoFileInfoPointer->FileSize = Record->DataLengthL;
|
||||
IsoFileInfoPointer->FilePointer = 0;
|
||||
IsoFileInfoPointer->Directory = !!(Record->FileFlags & 0x02);
|
||||
|
||||
IsoFileInfoPointer->Attributes = Record->FileFlags;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,6 +185,7 @@ static ARC_STATUS IsoLookupFile(PCSTR FileName, ULONG DeviceId, PISO_FILE_INFO I
|
||||
CHAR* PathPart;
|
||||
ARC_STATUS Status;
|
||||
BOOLEAN DoFullLookup;
|
||||
UCHAR FileAttributes;
|
||||
|
||||
TRACE("IsoLookupFile() FileName = %s\n", FileName);
|
||||
|
||||
@@ -226,6 +225,7 @@ static ARC_STATUS IsoLookupFile(PCSTR FileName, ULONG DeviceId, PISO_FILE_INFO I
|
||||
/* Skip leading path separator, if any */
|
||||
if (*FileName == '\\' || *FileName == '/')
|
||||
++FileName;
|
||||
PathPart[0] = ANSI_NULL;
|
||||
|
||||
/* Figure out how many sub-directories we are nested in */
|
||||
NumberOfPathParts = FsGetNumPathParts(FileName);
|
||||
@@ -298,6 +298,19 @@ static ARC_STATUS IsoLookupFile(PCSTR FileName, ULONG DeviceId, PISO_FILE_INFO I
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-map the attributes to ARC file attributes */
|
||||
FileAttributes = IsoFileInfo->Attributes;
|
||||
IsoFileInfo->Attributes = ReadOnlyFile;
|
||||
if (FileAttributes & ISO_ATTR_HIDDEN)
|
||||
IsoFileInfo->Attributes |= HiddenFile;
|
||||
if (FileAttributes & ISO_ATTR_DIRECTORY)
|
||||
IsoFileInfo->Attributes |= DirectoryFile;
|
||||
|
||||
/* Copy the file name, perhaps truncated */
|
||||
IsoFileInfo->FileNameLength = (ULONG)strlen(PathPart);
|
||||
IsoFileInfo->FileNameLength = min(IsoFileInfo->FileNameLength, sizeof(IsoFileInfo->FileName) - 1);
|
||||
RtlCopyMemory(IsoFileInfo->FileName, PathPart, IsoFileInfo->FileNameLength);
|
||||
|
||||
return ESUCCESS;
|
||||
}
|
||||
|
||||
@@ -318,6 +331,14 @@ ARC_STATUS IsoGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
|
||||
Information->EndingAddress.LowPart = FileHandle->FileSize;
|
||||
Information->CurrentAddress.LowPart = FileHandle->FilePointer;
|
||||
|
||||
/* Set the ARC file attributes */
|
||||
Information->Attributes = FileHandle->Attributes;
|
||||
|
||||
/* Copy the file name, perhaps truncated, and NUL-terminated */
|
||||
Information->FileNameLength = min(FileHandle->FileNameLength, sizeof(Information->FileName) - 1);
|
||||
RtlCopyMemory(Information->FileName, FileHandle->FileName, Information->FileNameLength);
|
||||
Information->FileName[Information->FileNameLength] = ANSI_NULL;
|
||||
|
||||
TRACE("IsoGetFileInformation(%lu) -> FileSize = %lu, FilePointer = 0x%lx\n",
|
||||
FileId, Information->EndingAddress.LowPart, Information->CurrentAddress.LowPart);
|
||||
|
||||
|
||||
@@ -509,7 +509,11 @@ VOID NtfsPrintFile(PNTFS_INDEX_ENTRY IndexEntry)
|
||||
}
|
||||
#endif
|
||||
|
||||
static BOOLEAN NtfsCompareFileName(PCHAR FileName, PNTFS_INDEX_ENTRY IndexEntry)
|
||||
static BOOLEAN
|
||||
NtfsCompareFileName(
|
||||
_In_ PCCH FileName,
|
||||
_In_ SIZE_T FileNameLen,
|
||||
_In_ PNTFS_INDEX_ENTRY IndexEntry)
|
||||
{
|
||||
PWCHAR EntryFileName;
|
||||
UCHAR EntryFileNameLength;
|
||||
@@ -522,7 +526,7 @@ static BOOLEAN NtfsCompareFileName(PCHAR FileName, PNTFS_INDEX_ENTRY IndexEntry)
|
||||
NtfsPrintFile(IndexEntry);
|
||||
#endif
|
||||
|
||||
if (strlen(FileName) != EntryFileNameLength)
|
||||
if (FileNameLen != EntryFileNameLength)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
@@ -540,7 +544,13 @@ static BOOLEAN NtfsCompareFileName(PCHAR FileName, PNTFS_INDEX_ENTRY IndexEntry)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN NtfsFindMftRecord(PNTFS_VOLUME_INFO Volume, ULONGLONG MFTIndex, PCHAR FileName, ULONGLONG *OutMFTIndex)
|
||||
static BOOLEAN
|
||||
NtfsFindMftRecord(
|
||||
_In_ PNTFS_VOLUME_INFO Volume,
|
||||
_In_ ULONGLONG MFTIndex,
|
||||
_In_ PCSTR FileName,
|
||||
_Out_ PULONGLONG OutMFTIndex,
|
||||
_Out_ PULONG FileAttributes)
|
||||
{
|
||||
PNTFS_MFT_RECORD MftRecord;
|
||||
//ULONG Magic;
|
||||
@@ -555,6 +565,9 @@ static BOOLEAN NtfsFindMftRecord(PNTFS_VOLUME_INFO Volume, ULONGLONG MFTIndex, P
|
||||
PNTFS_INDEX_ENTRY IndexEntry, IndexEntryEnd;
|
||||
ULONG RecordOffset;
|
||||
ULONG IndexBlockSize;
|
||||
SIZE_T FileNameLen;
|
||||
|
||||
FileNameLen = strlen(FileName);
|
||||
|
||||
MftRecord = FrLdrTempAlloc(Volume->MftRecordSize, TAG_NTFS_MFT);
|
||||
if (MftRecord == NULL)
|
||||
@@ -592,14 +605,15 @@ static BOOLEAN NtfsFindMftRecord(PNTFS_VOLUME_INFO Volume, ULONGLONG MFTIndex, P
|
||||
while (IndexEntry < IndexEntryEnd &&
|
||||
!(IndexEntry->Flags & NTFS_INDEX_ENTRY_END))
|
||||
{
|
||||
if (NtfsCompareFileName(FileName, IndexEntry))
|
||||
if (NtfsCompareFileName(FileName, FileNameLen, IndexEntry))
|
||||
{
|
||||
*OutMFTIndex = (IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK);
|
||||
*FileAttributes = IndexEntry->FileName.FileAttributes;
|
||||
FrLdrTempFree(IndexRecord, TAG_NTFS_INDEX_REC);
|
||||
FrLdrTempFree(MftRecord, TAG_NTFS_MFT);
|
||||
return TRUE;
|
||||
}
|
||||
IndexEntry = (PNTFS_INDEX_ENTRY)((PCHAR)IndexEntry + IndexEntry->Length);
|
||||
IndexEntry = (PNTFS_INDEX_ENTRY)((PCHAR)IndexEntry + IndexEntry->Length);
|
||||
}
|
||||
|
||||
if (IndexRoot->IndexHeader.Flags & NTFS_LARGE_INDEX)
|
||||
@@ -670,19 +684,20 @@ static BOOLEAN NtfsFindMftRecord(PNTFS_VOLUME_INFO Volume, ULONGLONG MFTIndex, P
|
||||
|
||||
/* FIXME */
|
||||
IndexEntry = (PNTFS_INDEX_ENTRY)(IndexRecord + 0x18 + *(USHORT *)(IndexRecord + 0x18));
|
||||
IndexEntryEnd = (PNTFS_INDEX_ENTRY)(IndexRecord + IndexBlockSize);
|
||||
IndexEntryEnd = (PNTFS_INDEX_ENTRY)(IndexRecord + IndexBlockSize);
|
||||
|
||||
while (IndexEntry < IndexEntryEnd &&
|
||||
!(IndexEntry->Flags & NTFS_INDEX_ENTRY_END))
|
||||
{
|
||||
if (NtfsCompareFileName(FileName, IndexEntry))
|
||||
if (NtfsCompareFileName(FileName, FileNameLen, IndexEntry))
|
||||
{
|
||||
TRACE("File found\n");
|
||||
*OutMFTIndex = (IndexEntry->Data.Directory.IndexedFile & NTFS_MFT_MASK);
|
||||
*FileAttributes = IndexEntry->FileName.FileAttributes;
|
||||
NtfsReleaseAttributeContext(IndexAllocationCtx);
|
||||
FrLdrTempFree(BitmapData, TAG_NTFS_BITMAP);
|
||||
FrLdrTempFree(IndexRecord, TAG_NTFS_INDEX_REC);
|
||||
FrLdrTempFree(MftRecord, TAG_NTFS_MFT);
|
||||
NtfsReleaseAttributeContext(IndexAllocationCtx);
|
||||
return TRUE;
|
||||
}
|
||||
IndexEntry = (PNTFS_INDEX_ENTRY)((PCHAR)IndexEntry + IndexEntry->Length);
|
||||
@@ -706,12 +721,13 @@ static BOOLEAN NtfsFindMftRecord(PNTFS_VOLUME_INFO Volume, ULONGLONG MFTIndex, P
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOLEAN NtfsLookupFile(PNTFS_VOLUME_INFO Volume, PCSTR FileName, PNTFS_MFT_RECORD MftRecord, PNTFS_ATTR_CONTEXT *DataContext)
|
||||
static BOOLEAN NtfsLookupFile(PNTFS_VOLUME_INFO Volume, PCSTR FileName, PNTFS_MFT_RECORD MftRecord, PNTFS_FILE_HANDLE FileHandle)
|
||||
{
|
||||
ULONG NumberOfPathParts;
|
||||
CHAR PathPart[261];
|
||||
ULONG i;
|
||||
ULONGLONG CurrentMFTIndex;
|
||||
UCHAR i;
|
||||
ULONG FileAttributes;
|
||||
CHAR PathPart[261];
|
||||
|
||||
TRACE("NtfsLookupFile() FileName = %s\n", FileName);
|
||||
|
||||
@@ -720,7 +736,9 @@ static BOOLEAN NtfsLookupFile(PNTFS_VOLUME_INFO Volume, PCSTR FileName, PNTFS_MF
|
||||
/* Skip leading path separator, if any */
|
||||
if (*FileName == '\\' || *FileName == '/')
|
||||
++FileName;
|
||||
PathPart[0] = ANSI_NULL;
|
||||
|
||||
/* Figure out how many sub-directories we are nested in and loop once for each part */
|
||||
NumberOfPathParts = FsGetNumPathParts(FileName);
|
||||
for (i = 0; i < NumberOfPathParts; i++)
|
||||
{
|
||||
@@ -731,7 +749,7 @@ static BOOLEAN NtfsLookupFile(PNTFS_VOLUME_INFO Volume, PCSTR FileName, PNTFS_MF
|
||||
FileName++;
|
||||
|
||||
TRACE("- Lookup: %s\n", PathPart);
|
||||
if (!NtfsFindMftRecord(Volume, CurrentMFTIndex, PathPart, &CurrentMFTIndex))
|
||||
if (!NtfsFindMftRecord(Volume, CurrentMFTIndex, PathPart, &CurrentMFTIndex, &FileAttributes))
|
||||
{
|
||||
TRACE("- Failed\n");
|
||||
return FALSE;
|
||||
@@ -745,13 +763,31 @@ static BOOLEAN NtfsLookupFile(PNTFS_VOLUME_INFO Volume, PCSTR FileName, PNTFS_MF
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*DataContext = NtfsFindAttribute(Volume, MftRecord, NTFS_ATTR_TYPE_DATA, L"");
|
||||
if (*DataContext == NULL)
|
||||
FileHandle->DataContext = NtfsFindAttribute(Volume, MftRecord, NTFS_ATTR_TYPE_DATA, L"");
|
||||
if (FileHandle->DataContext == NULL)
|
||||
{
|
||||
TRACE("NtfsLookupFile: Can't find data attribute\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Map the attributes to ARC file attributes */
|
||||
FileHandle->Attributes = 0;
|
||||
if (FileAttributes & NTFS_FILE_ATTR_READONLY)
|
||||
FileHandle->Attributes |= ReadOnlyFile;
|
||||
if (FileAttributes & NTFS_FILE_ATTR_HIDDEN)
|
||||
FileHandle->Attributes |= HiddenFile;
|
||||
if (FileAttributes & NTFS_FILE_ATTR_SYSTEM)
|
||||
FileHandle->Attributes |= SystemFile;
|
||||
if (FileAttributes & NTFS_FILE_ATTR_ARCHIVE)
|
||||
FileHandle->Attributes |= ArchiveFile;
|
||||
if (FileAttributes & NTFS_FILE_ATTR_DIRECTORY)
|
||||
FileHandle->Attributes |= DirectoryFile;
|
||||
|
||||
/* Copy the file name, perhaps truncated */
|
||||
FileHandle->FileNameLength = (ULONG)strlen(PathPart);
|
||||
FileHandle->FileNameLength = min(FileHandle->FileNameLength, sizeof(FileHandle->FileName) - 1);
|
||||
RtlCopyMemory(FileHandle->FileName, PathPart, FileHandle->FileNameLength);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -773,6 +809,14 @@ ARC_STATUS NtfsGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
|
||||
Information->EndingAddress.QuadPart = NtfsGetAttributeSize(&FileHandle->DataContext->Record);
|
||||
Information->CurrentAddress.QuadPart = FileHandle->Offset;
|
||||
|
||||
/* Set the ARC file attributes */
|
||||
Information->Attributes = FileHandle->Attributes;
|
||||
|
||||
/* Copy the file name, perhaps truncated, and NUL-terminated */
|
||||
Information->FileNameLength = min(FileHandle->FileNameLength, sizeof(Information->FileName) - 1);
|
||||
RtlCopyMemory(Information->FileName, FileHandle->FileName, Information->FileNameLength);
|
||||
Information->FileName[Information->FileNameLength] = ANSI_NULL;
|
||||
|
||||
TRACE("NtfsGetFileInformation(%lu) -> FileSize = %llu, FilePointer = 0x%llx\n",
|
||||
FileId, Information->EndingAddress.QuadPart, Information->CurrentAddress.QuadPart);
|
||||
|
||||
@@ -816,7 +860,7 @@ ARC_STATUS NtfsOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
|
||||
// Search file entry
|
||||
//
|
||||
MftRecord = (PNTFS_MFT_RECORD)(FileHandle + 1);
|
||||
if (!NtfsLookupFile(Volume, Path, MftRecord, &FileHandle->DataContext))
|
||||
if (!NtfsLookupFile(Volume, Path, MftRecord, FileHandle))
|
||||
{
|
||||
FrLdrTempFree(FileHandle, TAG_NTFS_FILE);
|
||||
return ENOENT;
|
||||
|
||||
@@ -131,6 +131,8 @@ static ARC_STATUS PxeClose(ULONG FileId)
|
||||
|
||||
static ARC_STATUS PxeGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
|
||||
{
|
||||
PCSTR FileName;
|
||||
|
||||
if (_OpenFile == NO_FILE || FileId != _OpenFile)
|
||||
return EBADF;
|
||||
|
||||
@@ -140,6 +142,23 @@ static ARC_STATUS PxeGetFileInformation(ULONG FileId, FILEINFORMATION* Informati
|
||||
|
||||
Information->Type = NetworkPeripheral;
|
||||
|
||||
/* Set the ARC file attributes */
|
||||
Information->Attributes = ReadOnlyFile;
|
||||
|
||||
/* Search for the last path separator. Slashes are used as separators,
|
||||
* for supporting TFTP servers on POSIX systems (see PxeOpen()) */
|
||||
FileName = strrchr(_OpenFileName, '/');
|
||||
if (FileName)
|
||||
++FileName; // Go past it.
|
||||
else
|
||||
FileName = _OpenFileName; // No separator: file name without directory.
|
||||
|
||||
/* Copy the file name, perhaps truncated, and NUL-terminated */
|
||||
Information->FileNameLength = (ULONG)strlen(FileName);
|
||||
Information->FileNameLength = min(Information->FileNameLength, sizeof(Information->FileName) - 1);
|
||||
RtlCopyMemory(Information->FileName, FileName, Information->FileNameLength);
|
||||
Information->FileName[Information->FileNameLength] = ANSI_NULL;
|
||||
|
||||
TRACE("PxeGetFileInformation(%lu) -> FileSize = %lu, FilePointer = 0x%lx\n",
|
||||
FileId, Information->EndingAddress.LowPart, Information->CurrentAddress.LowPart);
|
||||
|
||||
@@ -165,7 +184,8 @@ static ARC_STATUS PxeOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
|
||||
++Path;
|
||||
|
||||
/* Retrieve the path length without NULL terminator */
|
||||
PathLen = min(strlen(Path), sizeof(_OpenFileName) - 1);
|
||||
PathLen = strlen(Path);
|
||||
PathLen = min(PathLen, sizeof(_OpenFileName) - 1);
|
||||
|
||||
/* Lowercase the path and always use slashes as separators,
|
||||
* for supporting TFTP servers on POSIX systems */
|
||||
|
||||
@@ -66,14 +66,23 @@ typedef enum _OPENMODE
|
||||
OpenWriteOnly,
|
||||
OpenReadWrite,
|
||||
CreateWriteOnly,
|
||||
CreateReadOnly,
|
||||
CreateReadWrite,
|
||||
SupersedeWriteOnly,
|
||||
SupersedeReadOnly,
|
||||
SupersedeReadWrite,
|
||||
OpenDirectory,
|
||||
CreateDirectory,
|
||||
} OPENMODE;
|
||||
|
||||
typedef enum _FILEATTRIBUTES
|
||||
{
|
||||
ReadOnlyFile = 0x01,
|
||||
HiddenFile = 0x02,
|
||||
SystemFile = 0x04,
|
||||
ArchiveFile = 0x08,
|
||||
DirectoryFile = 0x10,
|
||||
DeleteFile = 0x20
|
||||
} FILEATTRIBUTES;
|
||||
|
||||
typedef enum _IDENTIFIER_FLAG
|
||||
{
|
||||
Failed = 0x01,
|
||||
@@ -225,7 +234,7 @@ typedef struct _FILEINFORMATION
|
||||
CONFIGURATION_TYPE Type;
|
||||
ULONG FileNameLength;
|
||||
UCHAR Attributes;
|
||||
CHAR Filename[32];
|
||||
CHAR FileName[32];
|
||||
} FILEINFORMATION;
|
||||
|
||||
typedef
|
||||
|
||||
Reference in New Issue
Block a user