Most of XamContent* methods, besides enumeration.

Progress on #152.
This commit is contained in:
Ben Vanik
2015-02-12 14:16:43 -08:00
parent 53eaeff690
commit dc731f6a31
25 changed files with 849 additions and 14 deletions

View File

@@ -103,8 +103,11 @@ X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state,
if (creation_disposition != FileDisposition::X_FILE_OPEN ||
desired_access & FileAccess::X_GENERIC_WRITE ||
desired_access & FileAccess::X_GENERIC_ALL) {
// We don't support any write modes.
XELOGW("Attempted to open the file/dir for create/write");
if (entry->is_read_only()) {
// We don't support any write modes.
XELOGW("Attempted to open the file/dir for create/write");
desired_access = FileAccess::X_GENERIC_READ;
}
}
XFile* file = nullptr;
@@ -113,7 +116,10 @@ X_STATUS NtCreateFile(PPCContext* ppc_state, KernelState* state,
info = X_FILE_DOES_NOT_EXIST;
} else {
// Open the file/directory.
result = fs->Open(std::move(entry), state, fs::Mode::READ,
result = fs->Open(std::move(entry), state,
desired_access == FileAccess::X_GENERIC_READ
? fs::Mode::READ
: fs::Mode::READ_WRITE,
false, // TODO(benvanik): pick async mode, if needed.
&file);
}
@@ -294,6 +300,92 @@ SHIM_CALL NtReadFile_shim(PPCContext* ppc_state, KernelState* state) {
SHIM_SET_RETURN_32(result);
}
SHIM_CALL NtWriteFile_shim(PPCContext* ppc_state, KernelState* state) {
uint32_t file_handle = SHIM_GET_ARG_32(0);
uint32_t event_handle = SHIM_GET_ARG_32(1);
uint32_t apc_routine_ptr = SHIM_GET_ARG_32(2);
uint32_t apc_context = SHIM_GET_ARG_32(3);
uint32_t io_status_block_ptr = SHIM_GET_ARG_32(4);
uint32_t buffer = SHIM_GET_ARG_32(5);
uint32_t buffer_length = SHIM_GET_ARG_32(6);
uint32_t byte_offset_ptr = SHIM_GET_ARG_32(7);
size_t byte_offset = byte_offset_ptr ? SHIM_MEM_64(byte_offset_ptr) : 0;
XELOGD("NtWriteFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %.8X(%d))",
file_handle, event_handle, apc_routine_ptr, apc_context,
io_status_block_ptr, buffer, buffer_length, byte_offset_ptr,
byte_offset);
// Async not supported yet.
assert_zero(apc_routine_ptr);
X_STATUS result = X_STATUS_SUCCESS;
uint32_t info = 0;
// Grab event to signal.
XEvent* ev = NULL;
bool signal_event = false;
if (event_handle) {
result = state->object_table()->GetObject(event_handle, (XObject**)&ev);
}
// Grab file.
XFile* file = NULL;
if (XSUCCEEDED(result)) {
result = state->object_table()->GetObject(file_handle, (XObject**)&file);
}
// Execute write.
if (XSUCCEEDED(result)) {
// Reset event before we begin.
if (ev) {
ev->Reset();
}
// TODO(benvanik): async path.
if (true) {
// Synchronous request.
if (!byte_offset_ptr || byte_offset == 0xFFFFFFFFfffffffe) {
// FILE_USE_FILE_POINTER_POSITION
byte_offset = -1;
}
// Write now.
size_t bytes_written = 0;
result = file->Write(SHIM_MEM_ADDR(buffer), buffer_length, byte_offset,
&bytes_written);
if (XSUCCEEDED(result)) {
info = (int32_t)bytes_written;
}
// Mark that we should signal the event now. We do this after
// we have written the info out.
signal_event = true;
} else {
// X_STATUS_PENDING if not returning immediately.
result = X_STATUS_PENDING;
info = 0;
}
}
if (io_status_block_ptr) {
SHIM_SET_MEM_32(io_status_block_ptr, result); // Status
SHIM_SET_MEM_32(io_status_block_ptr + 4, info); // Information
}
if (file) {
file->Release();
}
if (ev) {
if (signal_event) {
ev->Set(0, false);
}
ev->Release();
}
SHIM_SET_RETURN_32(result);
}
SHIM_CALL NtSetInformationFile_shim(PPCContext* ppc_state, KernelState* state) {
uint32_t file_handle = SHIM_GET_ARG_32(0);
uint32_t io_status_block_ptr = SHIM_GET_ARG_32(1);
@@ -629,6 +721,7 @@ void xe::kernel::xboxkrnl::RegisterIoExports(ExportResolver* export_resolver,
SHIM_SET_MAPPING("xboxkrnl.exe", NtCreateFile, state);
SHIM_SET_MAPPING("xboxkrnl.exe", NtOpenFile, state);
SHIM_SET_MAPPING("xboxkrnl.exe", NtReadFile, state);
SHIM_SET_MAPPING("xboxkrnl.exe", NtWriteFile, state);
SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryInformationFile, state);
SHIM_SET_MAPPING("xboxkrnl.exe", NtSetInformationFile, state);
SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryFullAttributesFile, state);