diff --git a/src/xenia/kernel/modules/xboxkrnl/objects/xfile.cc b/src/xenia/kernel/modules/xboxkrnl/objects/xfile.cc index 99683afd0..4db262a47 100644 --- a/src/xenia/kernel/modules/xboxkrnl/objects/xfile.cc +++ b/src/xenia/kernel/modules/xboxkrnl/objects/xfile.cc @@ -10,15 +10,16 @@ #include #include -#include using namespace xe; using namespace xe::kernel; +using namespace xe::kernel::fs; using namespace xe::kernel::xboxkrnl; -XFile::XFile(KernelState* kernel_state) : +XFile::XFile(KernelState* kernel_state, FileEntry* entry) : + entry_(entry), XObject(kernel_state, kTypeFile) { } diff --git a/src/xenia/kernel/modules/xboxkrnl/objects/xfile.h b/src/xenia/kernel/modules/xboxkrnl/objects/xfile.h index 5cb53747e..5cd7d3cce 100644 --- a/src/xenia/kernel/modules/xboxkrnl/objects/xfile.h +++ b/src/xenia/kernel/modules/xboxkrnl/objects/xfile.h @@ -13,6 +13,7 @@ #include #include +#include namespace xe { @@ -22,10 +23,11 @@ namespace xboxkrnl { class XFile : public XObject { public: - XFile(KernelState* kernel_state); + XFile(KernelState* kernel_state, fs::FileEntry* entry); virtual ~XFile(); private: + fs::FileEntry* entry_; }; diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_io.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_io.cc index 766010c9d..610a0e6b4 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_io.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_io.cc @@ -12,11 +12,12 @@ #include #include #include -#include +#include using namespace xe; using namespace xe::kernel; +using namespace xe::kernel::fs; using namespace xe::kernel::xboxkrnl; @@ -25,6 +26,100 @@ namespace kernel { namespace xboxkrnl { +SHIM_CALL NtCreateFile_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + uint32_t handle_ptr = SHIM_GET_ARG_32(0); + uint32_t desired_access = SHIM_GET_ARG_32(1); + uint32_t object_attributes_ptr = SHIM_GET_ARG_32(2); + uint32_t io_status_block_ptr = SHIM_GET_ARG_32(3); + uint32_t allocation_size_ptr = SHIM_GET_ARG_32(4); + uint32_t file_attributes = SHIM_GET_ARG_32(5); + 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)); + + XELOGD( + "NtCreateFile(%.8X, %.8X, %.8X(%s), %.8X, %.8X, %.8X, %d, %d)", + handle_ptr, + desired_access, + object_attributes_ptr, + object_name.buffer, + io_status_block_ptr, + allocation_size_ptr, + file_attributes, + share_access, + creation_disposition); + + uint64_t allocation_size = 0; // is this correct??? + if (allocation_size_ptr != 0) { + allocation_size = SHIM_MEM_64(allocation_size_ptr); + } + + X_STATUS result = X_STATUS_NO_SUCH_FILE; + uint32_t info = X_FILE_DOES_NOT_EXIST; + uint32_t handle; + + // Resolve the file using the virtual file system. + FileSystem* fs = state->filesystem(); + Entry* entry = fs->ResolvePath(object_name.buffer); + if (entry && entry->type() == Entry::kTypeFile) { + // Create file handle wrapper. + FileEntry* file_entry = (FileEntry*)entry; + XFile* file = new XFile(state, file_entry); + handle = file->handle(); + result = X_STATUS_SUCCESS; + info = X_FILE_OPENED; + } + + 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 (XSUCCEEDED(result)) { + if (handle_ptr) { + SHIM_SET_MEM_32(handle_ptr, handle); + } + } + SHIM_SET_RETURN(result); +} + +SHIM_CALL NtOpenFile_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + SHIM_SET_RETURN(X_STATUS_NO_SUCH_FILE); +} + +SHIM_CALL NtReadFile_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + SHIM_SET_RETURN(X_STATUS_NO_SUCH_FILE); +} + +SHIM_CALL NtQueryInformationFile_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + 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); +} + +SHIM_CALL NtQueryVolumeInformationFile_shim( + xe_ppc_state_t* ppc_state, KernelState* state) { + SHIM_SET_RETURN(X_STATUS_NO_SUCH_FILE); +} } // namespace xboxkrnl @@ -34,4 +129,10 @@ namespace xboxkrnl { void xe::kernel::xboxkrnl::RegisterIoExports( ExportResolver* export_resolver, KernelState* state) { + 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", NtQueryInformationFile, state); + SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryFullAttributesFile, state); + SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryVolumeInformationFile, state); } diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_nt.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_nt.cc index 3a74361c0..7a022b9e5 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_nt.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_nt.cc @@ -12,7 +12,6 @@ #include #include #include -#include using namespace xe; @@ -25,80 +24,12 @@ namespace kernel { namespace xboxkrnl { -X_STATUS xeNtCreateFile( - uint32_t* handle_ptr, uint32_t desired_access, void* object_attributes_ptr, - void* io_status_block_ptr, uint64_t allocation_size, uint32_t file_attributes, - uint32_t share_access, uint32_t creation_disposition) { - KernelState* state = shared_kernel_state_; - XEASSERTNOTNULL(state); - return X_STATUS_NO_SUCH_FILE; -} - -SHIM_CALL NtCreateFile_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { - uint32_t handle_ptr = SHIM_GET_ARG_32(0); - uint32_t desired_access = SHIM_GET_ARG_32(1); - uint32_t object_attributes_ptr = SHIM_GET_ARG_32(2); - uint32_t io_status_block_ptr = SHIM_GET_ARG_32(3); - uint32_t allocation_size_ptr = SHIM_GET_ARG_32(4); - uint32_t file_attributes = SHIM_GET_ARG_32(5); - uint32_t share_access = SHIM_GET_ARG_32(6); - uint32_t creation_disposition = SHIM_GET_ARG_32(7); - - XELOGD( - "NtCreateFile(%.8X, %.8X, %.8X, %.8X, %.8X, %.8X, %d, %d)", - handle_ptr, - desired_access, - object_attributes_ptr, - io_status_block_ptr, - allocation_size_ptr, - file_attributes, - share_access, - creation_disposition); - - // object_attributes is: - // void *root_directory - // _STRING *object_name <- probably initialized by previous RtlInitAnsiString call - // uint32_t attributes - - uint64_t allocation_size = 0; // is this correct??? - if (allocation_size_ptr != 0) { - allocation_size = SHIM_MEM_64(allocation_size_ptr); - } - - uint32_t handle; - X_STATUS result = xeNtCreateFile( - &handle, desired_access, SHIM_MEM_ADDR(object_attributes_ptr), SHIM_MEM_ADDR(io_status_block_ptr), - allocation_size, file_attributes, share_access, creation_disposition); - - if (XSUCCEEDED(result)) { - if (handle_ptr) { - SHIM_SET_MEM_32(handle_ptr, handle); - } - } - SHIM_SET_RETURN(result); -} - -SHIM_CALL NtQueryInformationFile_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { - SHIM_SET_RETURN(X_STATUS_NO_SUCH_FILE); -} - -SHIM_CALL NtReadFile_shim( - xe_ppc_state_t* ppc_state, KernelState* state) { - 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); -} - SHIM_CALL NtClose_shim( xe_ppc_state_t* ppc_state, KernelState* state) { SHIM_SET_RETURN(X_STATUS_NO_SUCH_FILE); } + } // namespace xboxkrnl } // namespace kernel } // namespace xe @@ -107,8 +38,4 @@ SHIM_CALL NtClose_shim( void xe::kernel::xboxkrnl::RegisterNtExports( ExportResolver* export_resolver, KernelState* state) { SHIM_SET_MAPPING("xboxkrnl.exe", NtClose, state); - SHIM_SET_MAPPING("xboxkrnl.exe", NtCreateFile, state); - SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryFullAttributesFile, state); - SHIM_SET_MAPPING("xboxkrnl.exe", NtQueryInformationFile, state); - SHIM_SET_MAPPING("xboxkrnl.exe", NtReadFile, state); } diff --git a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc index b07843247..622f9a094 100644 --- a/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/modules/xboxkrnl/xboxkrnl_rtl.cc @@ -176,10 +176,16 @@ void xeRtlInitAnsiString(uint32_t destination_ptr, uint32_t source_ptr) { const char* source = source_ptr ? (char*)IMPL_MEM_ADDR(source_ptr) : NULL; - uint16_t length = source ? (uint16_t)xestrlena(source) : 0; - IMPL_SET_MEM_16(destination_ptr + 2, length * 2); - IMPL_SET_MEM_16(destination_ptr + 0, length * 2); - IMPL_SET_MEM_32(destination_ptr + 4, source_ptr); + if (source) { + uint16_t length = (uint16_t)xestrlena(source); + IMPL_SET_MEM_16(destination_ptr + 0, length); + IMPL_SET_MEM_16(destination_ptr + 2, length + 1); + IMPL_SET_MEM_32(destination_ptr + 4, source_ptr); + } else { + IMPL_SET_MEM_16(destination_ptr + 0, 0); + IMPL_SET_MEM_16(destination_ptr + 2, 0); + IMPL_SET_MEM_32(destination_ptr + 4, 0); + } } @@ -243,10 +249,16 @@ void xeRtlInitUnicodeString(uint32_t destination_ptr, uint32_t source_ptr) { const wchar_t* source = source_ptr ? (const wchar_t*)IMPL_MEM_ADDR(source_ptr) : NULL; - uint16_t length = source ? (uint16_t)xestrlenw(source) : 0; - IMPL_SET_MEM_16(destination_ptr + 0, length * 2); - IMPL_SET_MEM_16(destination_ptr + 2, length * 2); - IMPL_SET_MEM_32(destination_ptr + 4, source_ptr); + if (source) { + uint16_t length = (uint16_t)xestrlenw(source); + IMPL_SET_MEM_16(destination_ptr + 0, length * 2); + IMPL_SET_MEM_16(destination_ptr + 2, (length + 1) * 2); + IMPL_SET_MEM_32(destination_ptr + 4, source_ptr); + } else { + IMPL_SET_MEM_16(destination_ptr + 0, 0); + IMPL_SET_MEM_16(destination_ptr + 2, 0); + IMPL_SET_MEM_32(destination_ptr + 4, 0); + } } diff --git a/src/xenia/kernel/xbox.h b/src/xenia/kernel/xbox.h index 82e17c4d7..e1304eb9d 100644 --- a/src/xenia/kernel/xbox.h +++ b/src/xenia/kernel/xbox.h @@ -64,6 +64,14 @@ typedef uint32_t X_STATUS; #define X_MEM_HEAP 0x40000000 #define X_MEM_16MB_PAGES 0x80000000 // from Valve SDK +// FILE_*, used by NtOpenFile +#define X_FILE_SUPERSEDED 0x00000000 +#define X_FILE_OPENED 0x00000001 +#define X_FILE_CREATED 0x00000002 +#define X_FILE_OVERWRITTEN 0x00000003 +#define X_FILE_EXISTS 0x00000004 +#define X_FILE_DOES_NOT_EXIST 0x00000005 + // PAGE_*, used by NtAllocateVirtualMemory #define X_PAGE_NOACCESS 0x00000001 @@ -98,6 +106,13 @@ typedef uint32_t X_STATUS; #define X_LANGUAGE_JAPANESE 2 +typedef struct { + uint16_t length; + uint16_t maximum_length; + char* buffer; +} X_ANSI_STRING; + + } // namespace kernel } // namespace xe