From d2753d6374b1ea3da10e3be7253868e80398deef Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 5 May 2024 12:06:59 +0300 Subject: [PATCH] [RTL] Add minimal wine debug support functions --- modules/rostests/apitests/rtl/testlist.c | 2 +- sdk/lib/rtl/CMakeLists.txt | 1 + sdk/lib/rtl/wine_debug.c | 187 +++++++++++++++++++++++ 3 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 sdk/lib/rtl/wine_debug.c diff --git a/modules/rostests/apitests/rtl/testlist.c b/modules/rostests/apitests/rtl/testlist.c index 62e2694add8..b0f113c7753 100644 --- a/modules/rostests/apitests/rtl/testlist.c +++ b/modules/rostests/apitests/rtl/testlist.c @@ -1,5 +1,5 @@ #define __ROS_LONG64__ - +#define wine_dbgstr_wn wine_dbgstr_wn_ #define STANDALONE #include diff --git a/sdk/lib/rtl/CMakeLists.txt b/sdk/lib/rtl/CMakeLists.txt index a37e1ab9407..efe2c90a40b 100644 --- a/sdk/lib/rtl/CMakeLists.txt +++ b/sdk/lib/rtl/CMakeLists.txt @@ -23,6 +23,7 @@ endif() list(APPEND SOURCE ${RTL_WINE_SOURCE} + wine_debug.c access.c acl.c appverifier.c diff --git a/sdk/lib/rtl/wine_debug.c b/sdk/lib/rtl/wine_debug.c new file mode 100644 index 00000000000..43f65b69406 --- /dev/null +++ b/sdk/lib/rtl/wine_debug.c @@ -0,0 +1,187 @@ + +#define WIN32_NO_STATUS +#include +#include +#include + +NTSTATUS NTAPI vDbgPrintExWithPrefix(PCCH, ULONG, ULONG, PCCH, va_list); + +static struct +{ + HANDLE thread; + void* allocations; +} s_alloactions[32]; + +static int find_thread_slot() +{ + HANDLE thread = NtCurrentTeb()->ClientId.UniqueThread; + for (int i = 0; i < ARRAYSIZE(s_alloactions); i++) + { + if (s_alloactions[i].thread == thread) + { + return i; + } + } + return -1; +} + +static int get_thread_slot() +{ + int slot = find_thread_slot(); + if (slot != -1) + { + return slot; + } + + HANDLE thread = NtCurrentTeb()->ClientId.UniqueThread; + for (int i = 0; i < ARRAYSIZE(s_alloactions); i++) + { + if (s_alloactions[i].thread == NULL) + { + if (InterlockedCompareExchangePointer(&s_alloactions[i].thread, thread, NULL) == NULL) + { + return i; + } + } + } + + return -1; +} + +static char *alloc_buffer(size_t size) +{ + int slot = get_thread_slot(); + if (slot == -1) + { + return NULL; + } + + void** buffer = (void**)RtlAllocateHeap(RtlGetProcessHeap(), 0, size + sizeof(void*)); + if (buffer == NULL) + { + return NULL; + } + + *buffer = s_alloactions[slot].allocations; + s_alloactions[slot].allocations = buffer; + + return (char*)(buffer + 1); +} + +static void free_buffers(void) +{ + int slot = find_thread_slot(); + if (slot != -1) + { + return; + } + + void* buffer = s_alloactions[slot].allocations; + while (buffer != NULL) + { + void* next = *(void**)buffer; + RtlFreeHeap(RtlGetProcessHeap(), 0, buffer); + buffer = next; + } + + s_alloactions[slot].allocations = NULL; + s_alloactions[slot].thread = NULL; +} + +const char *wine_dbg_vsprintf(const char *format, va_list valist) +{ + char* buffer; + int len; + + len = vsnprintf(NULL, 0, format, valist); + buffer = alloc_buffer(len + 1); + if (buffer == NULL) + { + return ""; + } + len = vsnprintf(buffer, len, format, valist); + buffer[len] = 0; + return buffer; +} + +/* printf with temp buffer allocation */ +const char *wine_dbg_sprintf( const char *format, ... ) +{ + const char *ret; + va_list valist; + + va_start(valist, format); + ret = wine_dbg_vsprintf( format, valist ); + va_end(valist); + return ret; +} + +const char *wine_dbgstr_wn( const WCHAR *str, int n ) +{ + if (!((ULONG_PTR)str >> 16)) + { + if (!str) return "(null)"; + return wine_dbg_sprintf("#%04x", LOWORD(str) ); + } + if (n == -1) + { + n = (int)wcslen(str); + } + if (n < 0) n = 0; + + return wine_dbg_sprintf("%.*S", n, str); +} + +/* From wine/dlls/ntdll/misc.c */ +LPCSTR debugstr_us( const UNICODE_STRING *us ) +{ + if (!us) return ""; + return debugstr_wn(us->Buffer, us->Length / sizeof(WCHAR)); +} + +static int default_dbg_vprintf( const char *format, va_list args ) +{ + return vDbgPrintExWithPrefix("", -1, 0, format, args); +} + +int wine_dbg_printf(const char *format, ... ) +{ + int ret; + va_list valist; + + va_start(valist, format); + ret = default_dbg_vprintf(format, valist); + va_end(valist); + free_buffers(); + return ret; +} + +static int winefmt_default_dbg_vlog( enum __wine_debug_class cls, struct __wine_debug_channel *channel, + const char *file, const char *func, const int line, const char *format, va_list args ) +{ + int ret = 0; + + ret += wine_dbg_printf("%04x:", HandleToULong(NtCurrentTeb()->ClientId.UniqueProcess) ); + ret += wine_dbg_printf("%04x:", HandleToULong(NtCurrentTeb()->ClientId.UniqueThread) ); + + if (format) + ret += default_dbg_vprintf(format, args); + return ret; +} + +#define __wine_dbg_get_channel_flags(channel) \ + ((channel) ? (channel)->flags : 0) + +int ros_dbg_log( enum __wine_debug_class cls, struct __wine_debug_channel *channel, + const char *file, const char *func, const int line, const char *format, ... ) +{ + int ret; + va_list valist; + + if (!(__wine_dbg_get_channel_flags(channel) & (1 << cls))) return -1; + + va_start(valist, format); + ret = winefmt_default_dbg_vlog(cls, channel, file, func, line, format, valist); + va_end(valist); + return ret; +}