diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc index 63ad15009..fba20d814 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc @@ -109,7 +109,9 @@ dword_result_t NtCreateFile(lpdword_t handle_out, dword_t desired_access, vfs::FileAction file_action; X_STATUS result = kernel_state()->file_system()->OpenFile( target_path, vfs::FileDisposition((uint32_t)creation_disposition), - desired_access, &vfs_file, &file_action); + desired_access, + (create_options & CreateOptions::FILE_DIRECTORY_FILE) != 0, &vfs_file, + &file_action); object_ref file = nullptr; X_HANDLE handle = X_INVALID_HANDLE_VALUE; diff --git a/src/xenia/kernel/xfile.cc b/src/xenia/kernel/xfile.cc index 8f0dc8f51..68461edce 100644 --- a/src/xenia/kernel/xfile.cc +++ b/src/xenia/kernel/xfile.cc @@ -8,6 +8,7 @@ */ #include "xenia/kernel/xfile.h" +#include "xenia/vfs/virtual_file_system.h" #include "xenia/base/byte_stream.h" #include "xenia/base/logging.h" @@ -178,6 +179,8 @@ bool XFile::Save(ByteStream* stream) { stream->Write(file_->entry()->absolute_path()); stream->Write(position_); stream->Write(file_access()); + stream->Write( + (file_->entry()->attributes() & vfs::kFileAttributeDirectory) != 0); stream->Write(is_synchronous_); return true; @@ -195,6 +198,7 @@ object_ref XFile::Restore(KernelState* kernel_state, auto abs_path = stream->Read(); uint64_t position = stream->Read(); auto access = stream->Read(); + auto is_directory = stream->Read(); auto is_synchronous = stream->Read(); XELOGD("XFile %.8X (%s)", file->handle(), abs_path.c_str()); @@ -202,7 +206,8 @@ object_ref XFile::Restore(KernelState* kernel_state, vfs::File* vfs_file = nullptr; vfs::FileAction action; auto res = kernel_state->file_system()->OpenFile( - abs_path, vfs::FileDisposition::kOpen, access, &vfs_file, &action); + abs_path, vfs::FileDisposition::kOpen, access, is_directory, &vfs_file, + &action); if (XFAILED(res)) { XELOGE("Failed to open XFile: error %.8X", res); return object_ref(file); diff --git a/src/xenia/vfs/virtual_file_system.cc b/src/xenia/vfs/virtual_file_system.cc index 951ea032c..acef5e865 100644 --- a/src/xenia/vfs/virtual_file_system.cc +++ b/src/xenia/vfs/virtual_file_system.cc @@ -181,8 +181,11 @@ bool VirtualFileSystem::DeletePath(const std::string& path) { X_STATUS VirtualFileSystem::OpenFile(const std::string& path, FileDisposition creation_disposition, - uint32_t desired_access, File** out_file, - FileAction* out_action) { + uint32_t desired_access, bool is_directory, + File** out_file, FileAction* out_action) { + // TODO(gibbed): should 'is_directory' remaina s a bool or should it be + // flipped to a generic FileAttributeFlags? + // Cleanup access. if (desired_access & FileAccess::kGenericRead) { desired_access |= FileAccess::kFileReadData; @@ -285,7 +288,8 @@ X_STATUS VirtualFileSystem::OpenFile(const std::string& path, } if (!entry) { // Create if needed (either new or as a replacement). - entry = CreatePath(path, kFileAttributeNormal); + entry = CreatePath( + path, !directory ? kFileAttributeNormal : kFileAttributeDirectory); if (!entry) { return X_STATUS_ACCESS_DENIED; } diff --git a/src/xenia/vfs/virtual_file_system.h b/src/xenia/vfs/virtual_file_system.h index 4eb0fb27d..94a2872ec 100644 --- a/src/xenia/vfs/virtual_file_system.h +++ b/src/xenia/vfs/virtual_file_system.h @@ -43,7 +43,7 @@ class VirtualFileSystem { X_STATUS OpenFile(const std::string& path, FileDisposition creation_disposition, - uint32_t desired_access, File** out_file, + uint32_t desired_access, bool is_directory, File** out_file, FileAction* out_action); private: