From ab1ba9a5084c69825b9e24e43968143ec8989e92 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Wed, 16 Oct 2013 21:32:53 -0700 Subject: [PATCH] Partially implemented NtQueryFullAttributes. Enough to get past the ShaderDump test most games seem to do. --- .../kernel/modules/xboxkrnl/xboxkrnl_io.cc | 57 +++++++++++++------ src/xenia/kernel/shim_utils.h | 1 + src/xenia/kernel/xbox.h | 57 ++++++++++++++++++- 3 files changed, 97 insertions(+), 18 deletions(-) diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_io.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_io.cc index 310833e58..505c4ee7a 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_io.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_io.cc @@ -39,26 +39,14 @@ SHIM_CALL NtCreateFile_shim( uint32_t share_access = SHIM_GET_ARG_32(6); uint32_t creation_disposition = SHIM_GET_ARG_32(7); - struct OBJECT_ATTRIBUTES { - uint32_t root_directory; - uint32_t object_name_ptr; - uint32_t attributes; - } attrs; - attrs.root_directory = SHIM_MEM_32(object_attributes_ptr); - attrs.object_name_ptr = SHIM_MEM_32(object_attributes_ptr + 4); - attrs.attributes = SHIM_MEM_32(object_attributes_ptr + 8); - X_ANSI_STRING object_name; - object_name.length = SHIM_MEM_16(attrs.object_name_ptr); - object_name.maximum_length = SHIM_MEM_16(attrs.object_name_ptr + 2); - object_name.buffer = - (char*)SHIM_MEM_ADDR(SHIM_MEM_32(attrs.object_name_ptr + 4)); + X_OBJECT_ATTRIBUTES attrs(SHIM_MEM_BASE, object_attributes_ptr); XELOGD( "NtCreateFile(%.8X, %.8X, %.8X(%s), %.8X, %.8X, %.8X, %d, %d)", handle_ptr, desired_access, object_attributes_ptr, - object_name.buffer, + attrs.object_name.buffer, io_status_block_ptr, allocation_size_ptr, file_attributes, @@ -76,7 +64,7 @@ SHIM_CALL NtCreateFile_shim( // Resolve the file using the virtual file system. FileSystem* fs = state->filesystem(); - Entry* entry = fs->ResolvePath(object_name.buffer); + Entry* entry = fs->ResolvePath(attrs.object_name.buffer); XFile* file = NULL; if (entry && entry->type() == Entry::kTypeFile) { // Open the file. @@ -231,12 +219,49 @@ SHIM_CALL NtReadFile_shim( SHIM_CALL NtQueryInformationFile_shim( xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t file_handle = SHIM_GET_ARG_32(0); + uint32_t io_status_block_ptr = SHIM_GET_ARG_32(1); + uint32_t file_info_ptr = SHIM_GET_ARG_32(2); + uint32_t length = SHIM_GET_ARG_32(3); + uint32_t file_info_class = SHIM_GET_ARG_32(4); + + XELOGD( + "NtQueryInformationFile(%.8X, %.8X, %.8X, %.8X, %.8X)", + file_handle, + io_status_block_ptr, + file_info_ptr, + length, + file_info_class); + SHIM_SET_RETURN(X_STATUS_NO_SUCH_FILE); } SHIM_CALL NtQueryFullAttributesFile_shim( xe_ppc_state_t* ppc_state, KernelState* state) { - SHIM_SET_RETURN(X_STATUS_NO_SUCH_FILE); + uint32_t object_attributes_ptr = SHIM_GET_ARG_32(0); + uint32_t file_info_ptr = SHIM_GET_ARG_32(1); + + X_OBJECT_ATTRIBUTES attrs(SHIM_MEM_BASE, object_attributes_ptr); + + XELOGD( + "NtQueryFullAttributesFile(%.8X(%s), %.8X)", + object_attributes_ptr, + attrs.object_name.buffer, + file_info_ptr); + + X_STATUS result = X_STATUS_NO_SUCH_FILE; + + // Resolve the file using the virtual file system. + FileSystem* fs = state->filesystem(); + Entry* entry = fs->ResolvePath(attrs.object_name.buffer); + if (entry && entry->type() == Entry::kTypeFile) { + // Found. + // TODO(benvanik): set file_info_ptr data + XEASSERTALWAYS(); + result = X_STATUS_SUCCESS; + } + + SHIM_SET_RETURN(result); } SHIM_CALL NtQueryVolumeInformationFile_shim( diff --git a/src/xenia/kernel/shim_utils.h b/src/xenia/kernel/shim_utils.h index dcde6e25b..16120245b 100644 --- a/src/xenia/kernel/shim_utils.h +++ b/src/xenia/kernel/shim_utils.h @@ -30,6 +30,7 @@ namespace kernel { (xe_kernel_export_shim_fn)export_name##_shim, \ NULL); +#define SHIM_MEM_BASE ppc_state->membase #define SHIM_MEM_ADDR(a) (a ? (ppc_state->membase + a) : NULL) #define SHIM_MEM_16(a) (uint16_t)XEGETUINT16BE(SHIM_MEM_ADDR(a)) diff --git a/src/xenia/kernel/xbox.h b/src/xenia/kernel/xbox.h index 1e4f95f23..05db3e193 100644 --- a/src/xenia/kernel/xbox.h +++ b/src/xenia/kernel/xbox.h @@ -107,11 +107,64 @@ typedef uint32_t X_STATUS; #define X_LANGUAGE_JAPANESE 2 -typedef struct { +class X_ANSI_STRING { +public: uint16_t length; uint16_t maximum_length; char* buffer; -} X_ANSI_STRING; + + X_ANSI_STRING() { + Zero(); + } + X_ANSI_STRING(const uint8_t* base, uint32_t p) { + Read(base, p); + } + void Read(const uint8_t* base, uint32_t p) { + length = XEGETUINT16BE(base + p); + maximum_length = XEGETUINT16BE(base + p + 2); + if (maximum_length) { + buffer = (char*)(base + XEGETUINT32BE(base + p + 4)); + } else { + buffer = 0; + } + } + void Zero() { + length = maximum_length = 0; + buffer = 0; + } +}; + + +class X_OBJECT_ATTRIBUTES { +public: + uint32_t root_directory; + uint32_t object_name_ptr; + X_ANSI_STRING object_name; + uint32_t attributes; + + X_OBJECT_ATTRIBUTES() { + Zero(); + } + X_OBJECT_ATTRIBUTES(const uint8_t* base, uint32_t p) { + Read(base, p); + } + void Read(const uint8_t* base, uint32_t p) { + root_directory = XEGETUINT32BE(base + p); + object_name_ptr = XEGETUINT32BE(base + p + 4); + if (object_name_ptr) { + object_name.Read(base, object_name_ptr); + } else { + object_name.Zero(); + } + attributes = XEGETUINT32BE(base + p + 8); + } + void Zero() { + root_directory = 0; + object_name_ptr = 0; + object_name.Zero(); + attributes = 0; + } +}; } // namespace kernel