https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d2753d6374b1ea3da10e3be7253868e80398deef

commit d2753d6374b1ea3da10e3be7253868e80398deef
Author:     Timo Kreuzer <timo.kreu...@reactos.org>
AuthorDate: Sun May 5 12:06:59 2024 +0300
Commit:     Timo Kreuzer <timo.kreu...@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;
+}

Reply via email to