From 6598556446730f3c66541747a95426f4c5a5505a Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 13 Feb 2015 10:43:56 -0800 Subject: [PATCH] Implementing RtlCompareString/RtlCompareStringN. Fixes #162. --- src/xenia/kernel/xboxkrnl_rtl.cc | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/xenia/kernel/xboxkrnl_rtl.cc b/src/xenia/kernel/xboxkrnl_rtl.cc index 454b77216..c435a1607 100644 --- a/src/xenia/kernel/xboxkrnl_rtl.cc +++ b/src/xenia/kernel/xboxkrnl_rtl.cc @@ -118,6 +118,49 @@ SHIM_CALL RtlFillMemoryUlong_shim(PPCContext* ppc_state, KernelState* state) { } } +SHIM_CALL RtlCompareString_shim(PPCContext* ppc_state, KernelState* state) { + uint32_t string_1_ptr = SHIM_GET_ARG_32(0); + uint32_t string_2_ptr = SHIM_GET_ARG_32(1); + uint32_t case_insensitive = SHIM_GET_ARG_32(2); + + XELOGD("RtlCompareString(%.8X, %.8X, %d)", string_1_ptr, string_2_ptr, + case_insensitive); + + auto string_1 = reinterpret_cast(SHIM_MEM_ADDR(string_1_ptr)); + auto string_2 = reinterpret_cast(SHIM_MEM_ADDR(string_2_ptr)); + int ret = case_insensitive ? strcasecmp(string_1, string_2) + : std::strcmp(string_1, string_2); + + SHIM_SET_RETURN_32(ret); +} + +SHIM_CALL RtlCompareStringN_shim(PPCContext* ppc_state, KernelState* state) { + uint32_t string_1_ptr = SHIM_GET_ARG_32(0); + uint32_t string_1_len = SHIM_GET_ARG_32(1); + uint32_t string_2_ptr = SHIM_GET_ARG_32(2); + uint32_t string_2_len = SHIM_GET_ARG_32(3); + uint32_t case_insensitive = SHIM_GET_ARG_32(4); + + XELOGD("RtlCompareStringN(%.8X, %d, %.8X, %, %d)", string_1_ptr, string_1_len, + string_2_ptr, string_2_len, case_insensitive); + + auto string_1 = reinterpret_cast(SHIM_MEM_ADDR(string_1_ptr)); + auto string_2 = reinterpret_cast(SHIM_MEM_ADDR(string_2_ptr)); + + if (string_1_len == 0xFFFF) { + string_1_len = std::strlen(string_1); + } + if (string_2_len == 0xFFFF) { + string_2_len = std::strlen(string_2); + } + auto len = std::min(string_1_len, string_2_len); + + int ret = case_insensitive ? strncasecmp(string_1, string_2, len) + : std::strncmp(string_1, string_2, len); + + SHIM_SET_RETURN_32(ret); +} + // typedef struct _STRING { // USHORT Length; // USHORT MaximumLength; @@ -643,6 +686,9 @@ void xe::kernel::xboxkrnl::RegisterRtlExports(ExportResolver* export_resolver, SHIM_SET_MAPPING("xboxkrnl.exe", RtlCompareMemoryUlong, state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlFillMemoryUlong, state); + SHIM_SET_MAPPING("xboxkrnl.exe", RtlCompareString, state); + SHIM_SET_MAPPING("xboxkrnl.exe", RtlCompareStringN, state); + SHIM_SET_MAPPING("xboxkrnl.exe", RtlInitAnsiString, state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlFreeAnsiString, state); SHIM_SET_MAPPING("xboxkrnl.exe", RtlInitUnicodeString, state);