Fixing opening files for write.

This commit is contained in:
Ben Vanik 2015-05-18 22:22:55 -07:00
parent 53c807de5d
commit dc7717e650
3 changed files with 40 additions and 13 deletions

View File

@ -140,9 +140,25 @@ X_STATUS HostPathEntry::Open(KernelState* kernel_state, Mode mode, bool async,
// TODO(benvanik): plumb through proper disposition/access mode. // TODO(benvanik): plumb through proper disposition/access mode.
DWORD desired_access = DWORD desired_access =
is_read_only() ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE); is_read_only() ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE);
// mode == Mode::READ ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE); if (mode == Mode::READ_APPEND) {
desired_access |= FILE_APPEND_DATA;
}
DWORD share_mode = FILE_SHARE_READ; DWORD share_mode = FILE_SHARE_READ;
DWORD creation_disposition = mode == Mode::READ ? OPEN_EXISTING : OPEN_ALWAYS; DWORD creation_disposition;
switch (mode) {
case Mode::READ:
creation_disposition = OPEN_EXISTING;
break;
case Mode::READ_WRITE:
creation_disposition = OPEN_ALWAYS;
break;
case Mode::READ_APPEND:
creation_disposition = OPEN_EXISTING;
break;
default:
assert_unhandled_case(mode);
break;
}
DWORD flags_and_attributes = async ? FILE_FLAG_OVERLAPPED : 0; DWORD flags_and_attributes = async ? FILE_FLAG_OVERLAPPED : 0;
HANDLE file = HANDLE file =
CreateFile(local_path_.c_str(), desired_access, share_mode, NULL, CreateFile(local_path_.c_str(), desired_access, share_mode, NULL,

View File

@ -35,6 +35,7 @@ class Device;
enum class Mode { enum class Mode {
READ, READ,
READ_WRITE, READ_WRITE,
READ_APPEND,
}; };
class MemoryMapping { class MemoryMapping {

View File

@ -60,10 +60,13 @@ struct FileDisposition {
}; };
struct FileAccess { struct FileAccess {
static const uint32_t X_GENERIC_READ = 1 << 0; static const uint32_t X_GENERIC_READ = 0x80000000;
static const uint32_t X_GENERIC_WRITE = 1 << 1; static const uint32_t X_GENERIC_WRITE = 0x40000000;
static const uint32_t X_GENERIC_EXECUTE = 1 << 2; static const uint32_t X_GENERIC_EXECUTE = 0x20000000;
static const uint32_t X_GENERIC_ALL = 1 << 3; static const uint32_t X_GENERIC_ALL = 0x10000000;
static const uint32_t X_FILE_READ_DATA = 0x00000001;
static const uint32_t X_FILE_WRITE_DATA = 0x00000002;
static const uint32_t X_FILE_APPEND_DATA = 0x00000004;
}; };
X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state, X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state,
@ -100,9 +103,11 @@ X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state,
entry = fs->ResolvePath(object_name); entry = fs->ResolvePath(object_name);
} }
if (creation_disposition != FileDisposition::X_FILE_OPEN || bool wants_write = desired_access & FileAccess::X_GENERIC_WRITE ||
desired_access & FileAccess::X_GENERIC_WRITE || desired_access & FileAccess::X_GENERIC_ALL ||
desired_access & FileAccess::X_GENERIC_ALL) { desired_access & FileAccess::X_FILE_WRITE_DATA ||
desired_access & FileAccess::X_FILE_APPEND_DATA;
if (wants_write) {
if (entry && entry->is_read_only()) { if (entry && entry->is_read_only()) {
// We don't support any write modes. // We don't support any write modes.
XELOGW("Attempted to open the file/dir for create/write"); XELOGW("Attempted to open the file/dir for create/write");
@ -116,10 +121,15 @@ X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state,
info = X_FILE_DOES_NOT_EXIST; info = X_FILE_DOES_NOT_EXIST;
} else { } else {
// Open the file/directory. // Open the file/directory.
result = fs->Open(std::move(entry), state, fs::Mode mode;
desired_access & FileAccess::X_GENERIC_WRITE if (desired_access & FileAccess::X_FILE_APPEND_DATA) {
? fs::Mode::READ_WRITE mode = fs::Mode::READ_APPEND;
: fs::Mode::READ, } else if (wants_write) {
mode = fs::Mode::READ_WRITE;
} else {
mode = fs::Mode::READ;
}
result = fs->Open(std::move(entry), state, mode,
false, // TODO(benvanik): pick async mode, if needed. false, // TODO(benvanik): pick async mode, if needed.
&file); &file);
} }