From 06ab8589b4b6fd59367fd1b3e6fb758cd656f11a Mon Sep 17 00:00:00 2001 From: Gliniak Date: Sun, 2 Aug 2020 17:09:32 +0200 Subject: [PATCH] [Kernel/IO] Return error creating dir as non-dir. [Kernel/IO] Return error when creating directory with non-directory flag in NtCreateFile. --- src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc | 3 ++- src/xenia/kernel/xfile.cc | 2 +- src/xenia/vfs/virtual_file_system.cc | 9 ++++++++- src/xenia/vfs/virtual_file_system.h | 3 ++- src/xenia/xbox.h | 1 + 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc index 6b0b6783b..5f19d7ca2 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc @@ -142,7 +142,8 @@ dword_result_t NtCreateFile(lpdword_t handle_out, dword_t desired_access, X_STATUS result = kernel_state()->file_system()->OpenFile( root_entry, target_path, vfs::FileDisposition((uint32_t)creation_disposition), desired_access, - (create_options & CreateOptions::FILE_DIRECTORY_FILE) != 0, &vfs_file, + (create_options & CreateOptions::FILE_DIRECTORY_FILE) != 0, + (create_options & CreateOptions::FILE_NON_DIRECTORY_FILE) != 0, &vfs_file, &file_action); object_ref file = nullptr; diff --git a/src/xenia/kernel/xfile.cc b/src/xenia/kernel/xfile.cc index ee749b9e7..dc4553505 100644 --- a/src/xenia/kernel/xfile.cc +++ b/src/xenia/kernel/xfile.cc @@ -266,7 +266,7 @@ object_ref XFile::Restore(KernelState* kernel_state, vfs::FileAction action; auto res = kernel_state->file_system()->OpenFile( nullptr, abs_path, vfs::FileDisposition::kOpen, access, is_directory, - &vfs_file, &action); + false, &vfs_file, &action); if (XFAILED(res)) { XELOGE("Failed to open XFile: error {:08X}", res); return object_ref(file); diff --git a/src/xenia/vfs/virtual_file_system.cc b/src/xenia/vfs/virtual_file_system.cc index 31cb82f66..c0f888318 100644 --- a/src/xenia/vfs/virtual_file_system.cc +++ b/src/xenia/vfs/virtual_file_system.cc @@ -172,7 +172,8 @@ X_STATUS VirtualFileSystem::OpenFile(Entry* root_entry, const std::string_view path, FileDisposition creation_disposition, uint32_t desired_access, bool is_directory, - File** out_file, FileAction* out_action) { + bool is_non_directory, File** out_file, + FileAction* out_action) { // TODO(gibbed): should 'is_directory' remain as a bool or should it be // flipped to a generic FileAttributeFlags? @@ -207,6 +208,12 @@ X_STATUS VirtualFileSystem::OpenFile(Entry* root_entry, entry = !root_entry ? ResolvePath(path) : root_entry->GetChild(path); } + if (entry) { + if (entry->attributes() & kFileAttributeDirectory && is_non_directory) { + return X_STATUS_FILE_IS_A_DIRECTORY; + } + } + // Check if exists (if we need it to), or that it doesn't (if it shouldn't). switch (creation_disposition) { case FileDisposition::kOpen: diff --git a/src/xenia/vfs/virtual_file_system.h b/src/xenia/vfs/virtual_file_system.h index 8d5b84697..49e9083dc 100644 --- a/src/xenia/vfs/virtual_file_system.h +++ b/src/xenia/vfs/virtual_file_system.h @@ -43,7 +43,8 @@ class VirtualFileSystem { X_STATUS OpenFile(Entry* root_entry, const std::string_view path, FileDisposition creation_disposition, - uint32_t desired_access, bool is_directory, File** out_file, + uint32_t desired_access, bool is_directory, + bool is_non_directory, File** out_file, FileAction* out_action); private: diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 62f4a1f65..2080b236c 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -64,6 +64,7 @@ typedef uint32_t X_STATUS; #define X_STATUS_PROCEDURE_NOT_FOUND ((X_STATUS)0xC000007AL) #define X_STATUS_INSUFFICIENT_RESOURCES ((X_STATUS)0xC000009AL) #define X_STATUS_MEMORY_NOT_ALLOCATED ((X_STATUS)0xC00000A0L) +#define X_STATUS_FILE_IS_A_DIRECTORY ((X_STATUS)0xC00000BAL) #define X_STATUS_NOT_SUPPORTED ((X_STATUS)0xC00000BBL) #define X_STATUS_INVALID_PARAMETER_1 ((X_STATUS)0xC00000EFL) #define X_STATUS_INVALID_PARAMETER_2 ((X_STATUS)0xC00000F0L)