From 1b12949dd2c08c972bd31540fc84097c04def708 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 16 Oct 2013 22:41:31 -0700 Subject: [PATCH] NtQueryFullAttributesFile. --- .../xboxkrnl/fs/devices/disc_image_entry.cc | 12 +++++++ .../xboxkrnl/fs/devices/disc_image_entry.h | 2 ++ .../xboxkrnl/fs/devices/disc_image_file.cc | 13 ++----- .../xboxkrnl/fs/devices/disc_image_file.h | 2 +- .../xboxkrnl/fs/devices/host_path_entry.cc | 20 +++++++++++ .../xboxkrnl/fs/devices/host_path_entry.h | 2 ++ .../xboxkrnl/fs/devices/host_path_file.cc | 20 ++--------- .../xboxkrnl/fs/devices/host_path_file.h | 2 +- src/xenia/kernel/modules/xboxkrnl/fs/entry.h | 3 ++ .../kernel/modules/xboxkrnl/objects/xfile.cc | 6 ---- .../kernel/modules/xboxkrnl/objects/xfile.h | 36 +++++++++++++------ .../kernel/modules/xboxkrnl/xboxkrnl_io.cc | 26 ++++---------- 12 files changed, 77 insertions(+), 67 deletions(-) diff --git a/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_entry.cc b/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_entry.cc index 4a7bc7b7f..2af71c8f0 100644 --- a/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_entry.cc +++ b/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_entry.cc @@ -52,6 +52,18 @@ DiscImageEntry::~DiscImageEntry() { xe_mmap_release(mmap_); } +X_STATUS DiscImageEntry::QueryInfo(XFileInfo* out_info) { + XEASSERTNOTNULL(out_info); + out_info->creation_time = 0; + out_info->last_access_time = 0; + out_info->last_write_time = 0; + out_info->change_time = 0; + out_info->allocation_size = 2048; + out_info->file_length = gdfx_entry_->size; + out_info->attributes = gdfx_entry_->attributes; + return X_STATUS_SUCCESS; +} + MemoryMapping* DiscImageEntry::CreateMemoryMapping( xe_file_mode file_mode, const size_t offset, const size_t length) { if (file_mode & kXEFileModeWrite) { diff --git a/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_entry.h b/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_entry.h index abe42efae..95ad83faf 100644 --- a/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_entry.h +++ b/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_entry.h @@ -33,6 +33,8 @@ public: xe_mmap_ref mmap() const { return mmap_; } GDFXEntry* gdfx_entry() const { return gdfx_entry_; } + virtual X_STATUS QueryInfo(XFileInfo* out_info); + virtual MemoryMapping* CreateMemoryMapping( xe_file_mode file_mode, const size_t offset, const size_t length); diff --git a/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_file.cc b/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_file.cc index 892da3dc9..ccd48a6ad 100644 --- a/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_file.cc +++ b/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_file.cc @@ -29,17 +29,8 @@ DiscImageFile::DiscImageFile( DiscImageFile::~DiscImageFile() { } -X_STATUS DiscImageFile::QueryInfo(FileInfo* out_info) { - XEASSERTNOTNULL(out_info); - GDFXEntry* gdfx_entry = entry_->gdfx_entry(); - out_info->creation_time = 0; - out_info->last_access_time = 0; - out_info->last_write_time = 0; - out_info->change_time = 0; - out_info->allocation_size = 2048; - out_info->file_length = gdfx_entry->size; - out_info->attributes = gdfx_entry->attributes; - return X_STATUS_SUCCESS; +X_STATUS DiscImageFile::QueryInfo(XFileInfo* out_info) { + return entry_->QueryInfo(out_info); } X_STATUS DiscImageFile::ReadSync( diff --git a/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_file.h b/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_file.h index 9e1b0a2ce..e8f6f3e19 100644 --- a/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_file.h +++ b/src/xenia/kernel/modules/xboxkrnl/fs/devices/disc_image_file.h @@ -30,7 +30,7 @@ public: DiscImageEntry* entry); virtual ~DiscImageFile(); - virtual X_STATUS QueryInfo(FileInfo* out_info); + virtual X_STATUS QueryInfo(XFileInfo* out_info); protected: virtual X_STATUS ReadSync( diff --git a/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_entry.cc b/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_entry.cc index c3c21afc7..2c2320235 100644 --- a/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_entry.cc +++ b/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_entry.cc @@ -48,6 +48,26 @@ HostPathEntry::~HostPathEntry() { xe_free(local_path_); } +X_STATUS HostPathEntry::QueryInfo(XFileInfo* out_info) { + XEASSERTNOTNULL(out_info); + + WIN32_FILE_ATTRIBUTE_DATA data; + if (!GetFileAttributesEx( + local_path_, GetFileExInfoStandard, &data)) { + return X_STATUS_ACCESS_DENIED; + } + +#define COMBINE_TIME(t) (((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime) + out_info->creation_time = COMBINE_TIME(data.ftCreationTime); + out_info->last_access_time = COMBINE_TIME(data.ftLastAccessTime); + out_info->last_write_time = COMBINE_TIME(data.ftLastWriteTime); + out_info->change_time = COMBINE_TIME(data.ftLastWriteTime); + out_info->allocation_size = 4096; + out_info->file_length = ((uint64_t)data.nFileSizeHigh << 32) | data.nFileSizeLow; + out_info->attributes = (X_FILE_ATTRIBUTES)data.dwFileAttributes; + return X_STATUS_SUCCESS; +} + MemoryMapping* HostPathEntry::CreateMemoryMapping( xe_file_mode file_mode, const size_t offset, const size_t length) { xe_mmap_ref mmap = xe_mmap_open(file_mode, local_path_, offset, length); diff --git a/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_entry.h b/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_entry.h index fe3c88b23..ab77a4ccc 100644 --- a/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_entry.h +++ b/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_entry.h @@ -30,6 +30,8 @@ public: const xechar_t* local_path() { return local_path_; } + virtual X_STATUS QueryInfo(XFileInfo* out_info); + virtual MemoryMapping* CreateMemoryMapping( xe_file_mode file_mode, const size_t offset, const size_t length); diff --git a/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_file.cc b/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_file.cc index 074a55af3..d0e391f9f 100644 --- a/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_file.cc +++ b/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_file.cc @@ -29,24 +29,8 @@ HostPathFile::~HostPathFile() { CloseHandle(file_handle_); } -X_STATUS HostPathFile::QueryInfo(FileInfo* out_info) { - XEASSERTNOTNULL(out_info); - - WIN32_FILE_ATTRIBUTE_DATA data; - if (!GetFileAttributesEx( - entry_->local_path(), GetFileExInfoStandard, &data)) { - return X_STATUS_ACCESS_DENIED; - } - -#define COMBINE_TIME(t) (((uint64_t)t.dwHighDateTime << 32) | t.dwLowDateTime) - out_info->creation_time = COMBINE_TIME(data.ftCreationTime); - out_info->last_access_time = COMBINE_TIME(data.ftLastAccessTime); - out_info->last_write_time = COMBINE_TIME(data.ftLastWriteTime); - out_info->change_time = COMBINE_TIME(data.ftLastWriteTime); - out_info->allocation_size = 4096; - out_info->file_length = ((uint64_t)data.nFileSizeHigh << 32) | data.nFileSizeLow; - out_info->attributes = (X_FILE_ATTRIBUTES)data.dwFileAttributes; - return X_STATUS_SUCCESS; +X_STATUS HostPathFile::QueryInfo(XFileInfo* out_info) { + return entry_->QueryInfo(out_info); } X_STATUS HostPathFile::ReadSync( diff --git a/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_file.h b/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_file.h index 5949eb6b9..70193bee1 100644 --- a/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_file.h +++ b/src/xenia/kernel/modules/xboxkrnl/fs/devices/host_path_file.h @@ -30,7 +30,7 @@ public: HostPathEntry* entry, HANDLE file_handle); virtual ~HostPathFile(); - virtual X_STATUS QueryInfo(FileInfo* out_info); + virtual X_STATUS QueryInfo(XFileInfo* out_info); protected: virtual X_STATUS ReadSync( diff --git a/src/xenia/kernel/modules/xboxkrnl/fs/entry.h b/src/xenia/kernel/modules/xboxkrnl/fs/entry.h index be1ed24af..6602fac38 100644 --- a/src/xenia/kernel/modules/xboxkrnl/fs/entry.h +++ b/src/xenia/kernel/modules/xboxkrnl/fs/entry.h @@ -21,6 +21,7 @@ namespace kernel { namespace xboxkrnl { class KernelState; class XFile; +class XFileInfo; namespace fs { class Device; @@ -55,6 +56,8 @@ public: const char* path() const { return path_; } const char* name() const { return name_; } + virtual X_STATUS QueryInfo(XFileInfo* out_info) = 0; + virtual MemoryMapping* CreateMemoryMapping( xe_file_mode file_mode, const size_t offset, const size_t length) = 0; diff --git a/src/xenia/kernel/modules/xboxkrnl/objects/xfile.cc b/src/xenia/kernel/modules/xboxkrnl/objects/xfile.cc index 89a9a73d2..ee4484994 100644 --- a/src/xenia/kernel/modules/xboxkrnl/objects/xfile.cc +++ b/src/xenia/kernel/modules/xboxkrnl/objects/xfile.cc @@ -38,12 +38,6 @@ X_STATUS XFile::Wait(uint32_t wait_reason, uint32_t processor_mode, wait_reason, processor_mode, alertable, opt_timeout); } -X_STATUS XFile::QueryInfo(FileInfo* out_info) { - XEASSERTNOTNULL(out_info); - xe_zero_struct(out_info, sizeof(FileInfo)); - return X_STATUS_NOT_IMPLEMENTED; -} - X_STATUS XFile::Read(void* buffer, size_t buffer_length, size_t byte_offset, size_t* out_bytes_read) { if (byte_offset == -1) { diff --git a/src/xenia/kernel/modules/xboxkrnl/objects/xfile.h b/src/xenia/kernel/modules/xboxkrnl/objects/xfile.h index b95c05fa0..55bb806d4 100644 --- a/src/xenia/kernel/modules/xboxkrnl/objects/xfile.h +++ b/src/xenia/kernel/modules/xboxkrnl/objects/xfile.h @@ -22,10 +22,32 @@ namespace xboxkrnl { class XAsyncRequest; class XEvent; +class XFileInfo { +public: + // FILE_NETWORK_OPEN_INFORMATION + uint64_t creation_time; + uint64_t last_access_time; + uint64_t last_write_time; + uint64_t change_time; + uint64_t allocation_size; + uint64_t file_length; + X_FILE_ATTRIBUTES attributes; + + void Write(uint8_t* base, uint32_t p) { + XESETUINT64BE(base + p, creation_time); + XESETUINT64BE(base + p + 8, last_access_time); + XESETUINT64BE(base + p + 16, last_write_time); + XESETUINT64BE(base + p + 24, change_time); + XESETUINT64BE(base + p + 32, allocation_size); + XESETUINT64BE(base + p + 40, file_length); + XESETUINT32BE(base + p + 48, attributes); + XESETUINT32BE(base + p + 52, 0); // pad + } +}; + class XFile : public XObject { public: - XFile(KernelState* kernel_state, uint32_t desired_access); virtual ~XFile(); size_t position() const { return position_; } @@ -34,16 +56,7 @@ public: virtual X_STATUS Wait(uint32_t wait_reason, uint32_t processor_mode, uint32_t alertable, uint64_t* opt_timeout); - typedef struct { - uint64_t creation_time; - uint64_t last_access_time; - uint64_t last_write_time; - uint64_t change_time; - uint64_t allocation_size; - uint64_t file_length; - X_FILE_ATTRIBUTES attributes; - } FileInfo; - virtual X_STATUS QueryInfo(FileInfo* out_info); + virtual X_STATUS QueryInfo(XFileInfo* out_info) = 0; X_STATUS Read(void* buffer, size_t buffer_length, size_t byte_offset, size_t* out_bytes_read); @@ -51,6 +64,7 @@ public: XAsyncRequest* request); protected: + XFile(KernelState* kernel_state, uint32_t desired_access); virtual X_STATUS ReadSync( void* buffer, size_t buffer_length, size_t byte_offset, size_t* out_bytes_read) = 0; diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_io.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_io.cc index e86356d77..659134f44 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_io.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_io.cc @@ -322,25 +322,11 @@ SHIM_CALL NtQueryInformationFile_shim( // ULONG Unknown; // }; XEASSERT(length == 56); - XFile::FileInfo file_info; + XFileInfo file_info; result = file->QueryInfo(&file_info); if (XSUCCEEDED(result)) { info = 56; - SHIM_SET_MEM_64(file_info_ptr, - file_info.creation_time); - SHIM_SET_MEM_64(file_info_ptr + 8, - file_info.last_access_time); - SHIM_SET_MEM_64(file_info_ptr + 16, - file_info.last_write_time); - SHIM_SET_MEM_64(file_info_ptr + 24, - file_info.change_time); - SHIM_SET_MEM_64(file_info_ptr + 32, - file_info.allocation_size); - SHIM_SET_MEM_64(file_info_ptr + 40, - file_info.file_length); - SHIM_SET_MEM_32(file_info_ptr + 48, - file_info.attributes); - SHIM_SET_MEM_32(file_info_ptr + 52, 0); // Unknown! + file_info.Write(SHIM_MEM_BASE, file_info_ptr); } break; default: @@ -386,9 +372,11 @@ SHIM_CALL NtQueryFullAttributesFile_shim( Entry* entry = fs->ResolvePath(attrs.object_name.buffer); if (entry && entry->type() == Entry::kTypeFile) { // Found. - // TODO(benvanik): set file_info_ptr data - XEASSERTALWAYS(); - result = X_STATUS_SUCCESS; + XFileInfo file_info; + result = entry->QueryInfo(&file_info); + if (XSUCCEEDED(result)) { + file_info.Write(SHIM_MEM_BASE, file_info_ptr); + } } SHIM_SET_RETURN(result);