https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d2753d6374b1ea3da10e3…
commit d2753d6374b1ea3da10e3be7253868e80398deef
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Sun May 5 12:06:59 2024 +0300
Commit: Timo Kreuzer <timo.kreuzer(a)reactos.org>
CommitDate: Tue Nov 5 10:54:21 2024 +0200
[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(-)
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 <apitest.h>
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 <windef.h>
+#include <ndk/rtlfuncs.h>
+#include <wine/debug.h>
+
+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 "<allocation failed>";
+ }
+ 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 "<null>";
+ 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;
+}