NtCreateFile - Return error while trying to create directory with non-directory flag
This commit is contained in:
parent
749a59e424
commit
6fe668724e
|
@ -27,18 +27,6 @@ namespace xe {
|
|||
namespace kernel {
|
||||
namespace xboxkrnl {
|
||||
|
||||
struct CreateOptions {
|
||||
// https://processhacker.sourceforge.io/doc/ntioapi_8h.html
|
||||
static const uint32_t FILE_DIRECTORY_FILE = 0x00000001;
|
||||
// Optimization - files access will be sequential, not random.
|
||||
static const uint32_t FILE_SEQUENTIAL_ONLY = 0x00000004;
|
||||
static const uint32_t FILE_SYNCHRONOUS_IO_ALERT = 0x00000010;
|
||||
static const uint32_t FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020;
|
||||
static const uint32_t FILE_NON_DIRECTORY_FILE = 0x00000040;
|
||||
// Optimization - file access will be random, not sequential.
|
||||
static const uint32_t FILE_RANDOM_ACCESS = 0x00000800;
|
||||
};
|
||||
|
||||
static bool IsValidPath(const std::string_view s, bool is_pattern) {
|
||||
// TODO(gibbed): validate path components individually
|
||||
for (const auto& c : s) {
|
||||
|
@ -126,16 +114,15 @@ 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,
|
||||
&file_action);
|
||||
create_options, &vfs_file, &file_action);
|
||||
object_ref<XFile> file = nullptr;
|
||||
|
||||
X_HANDLE handle = X_INVALID_HANDLE_VALUE;
|
||||
if (XSUCCEEDED(result)) {
|
||||
// If true, desired_access SYNCHRONIZE flag must be set.
|
||||
bool synchronous =
|
||||
(create_options & CreateOptions::FILE_SYNCHRONOUS_IO_ALERT) ||
|
||||
(create_options & CreateOptions::FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
(create_options & vfs::CreateOptions::FILE_SYNCHRONOUS_IO_ALERT) ||
|
||||
(create_options & vfs::CreateOptions::FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
file = object_ref<XFile>(new XFile(kernel_state(), vfs_file, synchronous));
|
||||
|
||||
// Handle ref is incremented, so return that.
|
||||
|
|
|
@ -258,12 +258,17 @@ object_ref<XFile> XFile::Restore(KernelState* kernel_state,
|
|||
auto is_directory = stream->Read<bool>();
|
||||
auto is_synchronous = stream->Read<bool>();
|
||||
|
||||
uint32_t create_options = 0;
|
||||
if (is_directory) {
|
||||
create_options |= vfs::CreateOptions::FILE_DIRECTORY_FILE;
|
||||
}
|
||||
|
||||
XELOGD("XFile {:08X} ({})", file->handle(), abs_path);
|
||||
|
||||
vfs::File* vfs_file = nullptr;
|
||||
vfs::FileAction action;
|
||||
auto res = kernel_state->file_system()->OpenFile(
|
||||
nullptr, abs_path, vfs::FileDisposition::kOpen, access, is_directory,
|
||||
nullptr, abs_path, vfs::FileDisposition::kOpen, access, create_options,
|
||||
&vfs_file, &action);
|
||||
if (XFAILED(res)) {
|
||||
XELOGE("Failed to open XFile: error {:08X}", res);
|
||||
|
|
|
@ -17,6 +17,18 @@
|
|||
namespace xe {
|
||||
namespace vfs {
|
||||
|
||||
struct CreateOptions {
|
||||
// https://processhacker.sourceforge.io/doc/ntioapi_8h.html
|
||||
static const uint32_t FILE_DIRECTORY_FILE = 0x00000001;
|
||||
// Optimization - files access will be sequential, not random.
|
||||
static const uint32_t FILE_SEQUENTIAL_ONLY = 0x00000004;
|
||||
static const uint32_t FILE_SYNCHRONOUS_IO_ALERT = 0x00000010;
|
||||
static const uint32_t FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020;
|
||||
static const uint32_t FILE_NON_DIRECTORY_FILE = 0x00000040;
|
||||
// Optimization - file access will be random, not sequential.
|
||||
static const uint32_t FILE_RANDOM_ACCESS = 0x00000800;
|
||||
};
|
||||
|
||||
class Entry;
|
||||
|
||||
class File {
|
||||
|
|
|
@ -173,7 +173,7 @@ bool VirtualFileSystem::DeletePath(const std::string_view path) {
|
|||
X_STATUS VirtualFileSystem::OpenFile(Entry* root_entry,
|
||||
const std::string_view path,
|
||||
FileDisposition creation_disposition,
|
||||
uint32_t desired_access, bool is_directory,
|
||||
uint32_t desired_access, uint32_t create_options,
|
||||
File** out_file, FileAction* out_action) {
|
||||
// TODO(gibbed): should 'is_directory' remain as a bool or should it be
|
||||
// flipped to a generic FileAttributeFlags?
|
||||
|
@ -189,11 +189,21 @@ X_STATUS VirtualFileSystem::OpenFile(Entry* root_entry,
|
|||
desired_access |= FileAccess::kFileReadData | FileAccess::kFileWriteData;
|
||||
}
|
||||
|
||||
bool is_directory = create_options & CreateOptions::FILE_DIRECTORY_FILE;
|
||||
|
||||
// Lookup host device/parent path.
|
||||
// If no device or parent, fail.
|
||||
Entry* parent_entry = nullptr;
|
||||
Entry* entry = nullptr;
|
||||
|
||||
auto path_entry = ResolvePath(path);
|
||||
if (path_entry) {
|
||||
if (path_entry->attributes() & kFileAttributeDirectory &&
|
||||
create_options & CreateOptions::FILE_NON_DIRECTORY_FILE) {
|
||||
return X_STATUS_FILE_IS_A_DIRECTORY;
|
||||
}
|
||||
}
|
||||
|
||||
auto base_path = xe::utf8::find_base_guest_path(path);
|
||||
if (!base_path.empty()) {
|
||||
parent_entry = !root_entry ? ResolvePath(base_path)
|
||||
|
|
|
@ -46,8 +46,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,
|
||||
FileAction* out_action);
|
||||
uint32_t desired_access, uint32_t create_options,
|
||||
File** out_file, FileAction* out_action);
|
||||
|
||||
private:
|
||||
xe::global_critical_region global_critical_region_;
|
||||
|
|
Loading…
Reference in New Issue