From 7f453a2041a6f82974171b1e862c60b3a96214f3 Mon Sep 17 00:00:00 2001 From: maxton Date: Tue, 20 Dec 2016 14:49:32 -0500 Subject: [PATCH 1/3] Update kernel convention for xboxkrnl_rtl.cc --- src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc | 109 ++++++++++------------ 1 file changed, 48 insertions(+), 61 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc index 5b6806718..1bd4d28c7 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc @@ -188,61 +188,55 @@ void RtlFreeUnicodeString(pointer_t string) { DECLARE_XBOXKRNL_EXPORT(RtlFreeUnicodeString, ExportTag::kImplemented); // http://msdn.microsoft.com/en-us/library/ff562969 -SHIM_CALL RtlUnicodeStringToAnsiString_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t destination_ptr = SHIM_GET_ARG_32(0); - uint32_t source_ptr = SHIM_GET_ARG_32(1); - uint32_t alloc_dest = SHIM_GET_ARG_32(2); - - XELOGD("RtlUnicodeStringToAnsiString(%.8X, %.8X, %d)", destination_ptr, - source_ptr, alloc_dest); - +dword_result_t RtlUnicodeStringToAnsiString( + pointer_t destination_ptr, + pointer_t source_ptr, dword_t alloc_dest) { // NTSTATUS // _Inout_ PANSI_STRING DestinationString, // _In_ PCUNICODE_STRING SourceString, // _In_ BOOLEAN AllocateDestinationString - std::wstring unicode_str = xe::load_and_swap( - SHIM_MEM_ADDR(SHIM_MEM_32(source_ptr + 4))); + std::wstring unicode_str = + source_ptr->to_string(kernel_memory()->virtual_membase()); std::string ansi_str = xe::to_string(unicode_str); if (ansi_str.size() > 0xFFFF - 1) { - SHIM_SET_RETURN_32(X_STATUS_INVALID_PARAMETER_2); - return; + return X_STATUS_INVALID_PARAMETER_2; } X_STATUS result = X_STATUS_SUCCESS; if (alloc_dest) { uint32_t buffer_ptr = - kernel_state->memory()->SystemHeapAlloc(uint32_t(ansi_str.size() + 1)); - memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); - SHIM_SET_MEM_16(destination_ptr + 0, - static_cast(ansi_str.size())); - SHIM_SET_MEM_16(destination_ptr + 2, - static_cast(ansi_str.size() + 1)); - SHIM_SET_MEM_32(destination_ptr + 4, static_cast(buffer_ptr)); + kernel_memory()->SystemHeapAlloc(uint32_t(ansi_str.size() + 1)); + + memcpy(kernel_memory()->virtual_membase() + buffer_ptr, ansi_str.data(), + ansi_str.size() + 1); + destination_ptr->length = static_cast(ansi_str.size()); + destination_ptr->maximum_length = + static_cast(ansi_str.size() + 1); + destination_ptr->pointer = static_cast(buffer_ptr); } else { - uint32_t buffer_capacity = SHIM_MEM_16(destination_ptr + 2); - uint32_t buffer_ptr = SHIM_MEM_32(destination_ptr + 4); + uint32_t buffer_capacity = destination_ptr->maximum_length; + auto buffer_ptr = + kernel_memory()->virtual_membase() + destination_ptr->pointer; if (buffer_capacity < ansi_str.size() + 1) { // Too large - we just write what we can. result = X_STATUS_BUFFER_OVERFLOW; - memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), buffer_capacity - 1); + memcpy(buffer_ptr, ansi_str.data(), buffer_capacity - 1); } else { - memcpy(SHIM_MEM_ADDR(buffer_ptr), ansi_str.data(), ansi_str.size() + 1); + memcpy(buffer_ptr, ansi_str.data(), ansi_str.size() + 1); } - SHIM_SET_MEM_8(buffer_ptr + buffer_capacity - 1, 0); // \0 + buffer_ptr[buffer_capacity - 1] = 0; // \0 } - SHIM_SET_RETURN_32(result); + return result; } +DECLARE_XBOXKRNL_EXPORT(RtlUnicodeStringToAnsiString, ExportTag::kImplemented); -SHIM_CALL RtlMultiByteToUnicodeN_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t destination_ptr = SHIM_GET_ARG_32(0); - uint32_t destination_len = SHIM_GET_ARG_32(1); - uint32_t written_ptr = SHIM_GET_ARG_32(2); - uint32_t source_ptr = SHIM_GET_ARG_32(3); - uint32_t source_len = SHIM_GET_ARG_32(4); - +// https://msdn.microsoft.com/en-us/library/ff553113 +dword_result_t RtlMultiByteToUnicodeN(pointer_t destination_ptr, + dword_t destination_len, + lpdword_t written_ptr, + pointer_t source_ptr, + dword_t source_len) { uint32_t copy_len = destination_len >> 1; copy_len = copy_len < source_len ? copy_len : source_len; @@ -250,44 +244,41 @@ SHIM_CALL RtlMultiByteToUnicodeN_shim(PPCContext* ppc_context, // swapping. for (uint32_t i = 0; i < copy_len; i++) { - xe::store_and_swap( - SHIM_MEM_ADDR(destination_ptr + i * 2), - xe::load(SHIM_MEM_ADDR(source_ptr + i))); + destination_ptr[i] = source_ptr[i]; } - if (written_ptr != 0) { - SHIM_SET_MEM_32(written_ptr, copy_len << 1); + if (written_ptr.guest_address() != 0) { + *written_ptr = copy_len << 1; } - SHIM_SET_RETURN_32(0); + return 0; } +DECLARE_XBOXKRNL_EXPORT(RtlMultiByteToUnicodeN, + ExportTag::kImplemented | ExportTag::kSketchy); -SHIM_CALL RtlUnicodeToMultiByteN_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t destination_ptr = SHIM_GET_ARG_32(0); - uint32_t destination_len = SHIM_GET_ARG_32(1); - uint32_t written_ptr = SHIM_GET_ARG_32(2); - uint32_t source_ptr = SHIM_GET_ARG_32(3); - uint32_t source_len = SHIM_GET_ARG_32(4); - +// https://msdn.microsoft.com/en-us/library/ff553261 +dword_result_t RtlUnicodeToMultiByteN(pointer_t destination_ptr, + dword_t destination_len, + lpdword_t written_ptr, + pointer_t source_ptr, + dword_t source_len) { uint32_t copy_len = source_len >> 1; copy_len = copy_len < destination_len ? copy_len : destination_len; // TODO(benvanik): maybe use UnicodeToMultiByte on Win32? - - auto source = reinterpret_cast(SHIM_MEM_ADDR(source_ptr)); - auto destination = reinterpret_cast(SHIM_MEM_ADDR(destination_ptr)); for (uint32_t i = 0; i < copy_len; i++) { - uint16_t c = xe::byte_swap(*source++); - *destination++ = c < 256 ? (uint8_t)c : '?'; + uint16_t c = source_ptr[i]; + destination_ptr[i] = c < 256 ? (uint8_t)c : '?'; } - if (written_ptr != 0) { - SHIM_SET_MEM_32(written_ptr, copy_len); + if (written_ptr.guest_address() != 0) { + *written_ptr = copy_len; } - SHIM_SET_RETURN_32(0); + return 0; } +DECLARE_XBOXKRNL_EXPORT(RtlUnicodeToMultiByteN, + ExportTag::kImplemented | ExportTag::kSketchy); pointer_result_t RtlImageXexHeaderField(pointer_t xex_header, dword_t field_dword) { @@ -502,11 +493,7 @@ dword_result_t RtlTimeFieldsToTime(pointer_t time_fields_ptr, DECLARE_XBOXKRNL_EXPORT(RtlTimeFieldsToTime, ExportTag::kImplemented); void RegisterRtlExports(xe::cpu::ExportResolver* export_resolver, - KernelState* kernel_state) { - SHIM_SET_MAPPING("xboxkrnl.exe", RtlUnicodeStringToAnsiString, state); - SHIM_SET_MAPPING("xboxkrnl.exe", RtlMultiByteToUnicodeN, state); - SHIM_SET_MAPPING("xboxkrnl.exe", RtlUnicodeToMultiByteN, state); -} + KernelState* kernel_state) {} } // namespace xboxkrnl } // namespace kernel From 345b0703797e397003ede05c7c5cc9f782778805 Mon Sep 17 00:00:00 2001 From: maxton Date: Tue, 20 Dec 2016 15:21:50 -0500 Subject: [PATCH 2/3] Update kernel convention for xboxkrnl_ob.cc --- src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc | 66 +++++++++--------------- 1 file changed, 24 insertions(+), 42 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc index 4813792e5..898e5e3a6 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_ob.cc @@ -20,8 +20,9 @@ namespace xe { namespace kernel { namespace xboxkrnl { -SHIM_CALL ObOpenObjectByName_shim(PPCContext* ppc_context, - KernelState* kernel_state) { +dword_result_t ObOpenObjectByName(lpunknown_t obj_attributes_ptr, + lpunknown_t object_type_ptr, dword_t unk, + lpdword_t handle_ptr) { // r3 = ptr to info? // +0 = -4 // +4 = name ptr @@ -29,26 +30,21 @@ SHIM_CALL ObOpenObjectByName_shim(PPCContext* ppc_context, // r4 = ExEventObjectType | ExSemaphoreObjectType | ExTimerObjectType // r5 = 0 // r6 = out_ptr (handle?) - uint32_t obj_attributes_ptr = SHIM_GET_ARG_32(0); - uint32_t object_type_ptr = SHIM_GET_ARG_32(1); - uint32_t unk = SHIM_GET_ARG_32(2); - uint32_t handle_ptr = SHIM_GET_ARG_32(3); auto name = - X_ANSI_STRING::to_string_indirect(SHIM_MEM_BASE, obj_attributes_ptr + 4); - - XELOGD("ObOpenObjectByName(%.8X(name=%s), %.8X, %.8X, %.8X)", - obj_attributes_ptr, name.c_str(), object_type_ptr, unk, handle_ptr); + X_ANSI_STRING::to_string_indirect(kernel_memory()->virtual_membase(), + obj_attributes_ptr.guest_address() + 4); X_HANDLE handle = X_INVALID_HANDLE_VALUE; X_STATUS result = - kernel_state->object_table()->GetObjectByName(name, &handle); + kernel_state()->object_table()->GetObjectByName(name, &handle); if (XSUCCEEDED(result)) { - SHIM_SET_MEM_32(handle_ptr, handle); + *handle_ptr = handle; } - SHIM_SET_RETURN_32(result); + return result; } +DECLARE_XBOXKRNL_EXPORT(ObOpenObjectByName, ExportTag::kImplemented); dword_result_t ObOpenObjectByPointer(lpvoid_t object_ptr, lpdword_t out_handle_ptr) { @@ -78,18 +74,12 @@ dword_result_t ObLookupThreadByThreadId(dword_t thread_id, } DECLARE_XBOXKRNL_EXPORT(ObLookupThreadByThreadId, ExportTag::kImplemented); -SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t handle = SHIM_GET_ARG_32(0); - uint32_t object_type_ptr = SHIM_GET_ARG_32(1); - uint32_t out_object_ptr = SHIM_GET_ARG_32(2); - - XELOGD("ObReferenceObjectByHandle(%.8X, %.8X, %.8X)", handle, object_type_ptr, - out_object_ptr); - +dword_result_t ObReferenceObjectByHandle(dword_t handle, + dword_t object_type_ptr, + lpdword_t out_object_ptr) { X_STATUS result = X_STATUS_SUCCESS; - auto object = kernel_state->object_table()->LookupObject(handle); + auto object = kernel_state()->object_table()->LookupObject(handle); if (object) { // TODO(benvanik): verify type with object_type_ptr @@ -138,36 +128,32 @@ SHIM_CALL ObReferenceObjectByHandle_shim(PPCContext* ppc_context, // Caller takes the reference. // It's released in ObDereferenceObject. object->Retain(); - if (out_object_ptr) { - SHIM_SET_MEM_32(out_object_ptr, native_ptr); + if (out_object_ptr.guest_address()) { + *out_object_ptr = native_ptr; } } else { result = X_STATUS_INVALID_HANDLE; } - SHIM_SET_RETURN_32(result); + return result; } +DECLARE_XBOXKRNL_EXPORT(ObReferenceObjectByHandle, ExportTag::kImplemented); -SHIM_CALL ObDereferenceObject_shim(PPCContext* ppc_context, - KernelState* kernel_state) { - uint32_t native_ptr = SHIM_GET_ARG_32(0); - - XELOGD("ObDereferenceObject(%.8X)", native_ptr); - +dword_result_t ObDereferenceObject(dword_t native_ptr) { // Check if a dummy value from ObReferenceObjectByHandle. if (native_ptr == 0xDEADF00D) { - SHIM_SET_RETURN_32(0); - return; + return 0; } - void* object_ptr = SHIM_MEM_ADDR(native_ptr); - auto object = XObject::GetNativeObject(kernel_state, object_ptr); + auto object = XObject::GetNativeObject( + kernel_state(), kernel_memory()->virtual_membase() + native_ptr); if (object) { object->Release(); } - SHIM_SET_RETURN_32(0); + return 0; } +DECLARE_XBOXKRNL_EXPORT(ObDereferenceObject, ExportTag::kImplemented); dword_result_t ObCreateSymbolicLink(pointer_t path, pointer_t target) { @@ -231,11 +217,7 @@ dword_result_t NtClose(dword_t handle) { DECLARE_XBOXKRNL_EXPORT(NtClose, ExportTag::kImplemented); void RegisterObExports(xe::cpu::ExportResolver* export_resolver, - KernelState* kernel_state) { - SHIM_SET_MAPPING("xboxkrnl.exe", ObOpenObjectByName, state); - SHIM_SET_MAPPING("xboxkrnl.exe", ObReferenceObjectByHandle, state); - SHIM_SET_MAPPING("xboxkrnl.exe", ObDereferenceObject, state); -} + KernelState* kernel_state) {} } // namespace xboxkrnl } // namespace kernel From cc0adb95f15c9e668788c447f3744dd58b9606ce Mon Sep 17 00:00:00 2001 From: maxton Date: Tue, 20 Dec 2016 17:42:48 -0500 Subject: [PATCH 3/3] Add word pointer type --- src/xenia/kernel/util/shim_utils.h | 1 + src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/xenia/kernel/util/shim_utils.h b/src/xenia/kernel/util/shim_utils.h index 4c50abb82..6ac6a26fa 100644 --- a/src/xenia/kernel/util/shim_utils.h +++ b/src/xenia/kernel/util/shim_utils.h @@ -304,6 +304,7 @@ using qword_t = const shim::ParamBase&; using float_t = const shim::ParamBase&; using double_t = const shim::ParamBase&; using lpvoid_t = const shim::PointerParam&; +using lpword_t = const shim::PrimitivePointerParam&; using lpdword_t = const shim::PrimitivePointerParam&; using lpqword_t = const shim::PrimitivePointerParam&; using lpfloat_t = const shim::PrimitivePointerParam&; diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc index 1bd4d28c7..a8e129922 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_rtl.cc @@ -232,7 +232,7 @@ dword_result_t RtlUnicodeStringToAnsiString( DECLARE_XBOXKRNL_EXPORT(RtlUnicodeStringToAnsiString, ExportTag::kImplemented); // https://msdn.microsoft.com/en-us/library/ff553113 -dword_result_t RtlMultiByteToUnicodeN(pointer_t destination_ptr, +dword_result_t RtlMultiByteToUnicodeN(lpword_t destination_ptr, dword_t destination_len, lpdword_t written_ptr, pointer_t source_ptr, @@ -260,8 +260,7 @@ DECLARE_XBOXKRNL_EXPORT(RtlMultiByteToUnicodeN, dword_result_t RtlUnicodeToMultiByteN(pointer_t destination_ptr, dword_t destination_len, lpdword_t written_ptr, - pointer_t source_ptr, - dword_t source_len) { + lpword_t source_ptr, dword_t source_len) { uint32_t copy_len = source_len >> 1; copy_len = copy_len < destination_len ? copy_len : destination_len;