Reactos

[RTL] Add minimal wine debug support functions

+189 -1
+1 -1
modules/rostests/apitests/rtl/testlist.c
··· 1 1 #define __ROS_LONG64__ 2 - 2 + #define wine_dbgstr_wn wine_dbgstr_wn_ 3 3 #define STANDALONE 4 4 #include <apitest.h> 5 5
+1
sdk/lib/rtl/CMakeLists.txt
··· 23 23 24 24 list(APPEND SOURCE 25 25 ${RTL_WINE_SOURCE} 26 + wine_debug.c 26 27 access.c 27 28 acl.c 28 29 appverifier.c
+187
sdk/lib/rtl/wine_debug.c
··· 1 + 2 + #define WIN32_NO_STATUS 3 + #include <windef.h> 4 + #include <ndk/rtlfuncs.h> 5 + #include <wine/debug.h> 6 + 7 + NTSTATUS NTAPI vDbgPrintExWithPrefix(PCCH, ULONG, ULONG, PCCH, va_list); 8 + 9 + static struct 10 + { 11 + HANDLE thread; 12 + void* allocations; 13 + } s_alloactions[32]; 14 + 15 + static int find_thread_slot() 16 + { 17 + HANDLE thread = NtCurrentTeb()->ClientId.UniqueThread; 18 + for (int i = 0; i < ARRAYSIZE(s_alloactions); i++) 19 + { 20 + if (s_alloactions[i].thread == thread) 21 + { 22 + return i; 23 + } 24 + } 25 + return -1; 26 + } 27 + 28 + static int get_thread_slot() 29 + { 30 + int slot = find_thread_slot(); 31 + if (slot != -1) 32 + { 33 + return slot; 34 + } 35 + 36 + HANDLE thread = NtCurrentTeb()->ClientId.UniqueThread; 37 + for (int i = 0; i < ARRAYSIZE(s_alloactions); i++) 38 + { 39 + if (s_alloactions[i].thread == NULL) 40 + { 41 + if (InterlockedCompareExchangePointer(&s_alloactions[i].thread, thread, NULL) == NULL) 42 + { 43 + return i; 44 + } 45 + } 46 + } 47 + 48 + return -1; 49 + } 50 + 51 + static char *alloc_buffer(size_t size) 52 + { 53 + int slot = get_thread_slot(); 54 + if (slot == -1) 55 + { 56 + return NULL; 57 + } 58 + 59 + void** buffer = (void**)RtlAllocateHeap(RtlGetProcessHeap(), 0, size + sizeof(void*)); 60 + if (buffer == NULL) 61 + { 62 + return NULL; 63 + } 64 + 65 + *buffer = s_alloactions[slot].allocations; 66 + s_alloactions[slot].allocations = buffer; 67 + 68 + return (char*)(buffer + 1); 69 + } 70 + 71 + static void free_buffers(void) 72 + { 73 + int slot = find_thread_slot(); 74 + if (slot != -1) 75 + { 76 + return; 77 + } 78 + 79 + void* buffer = s_alloactions[slot].allocations; 80 + while (buffer != NULL) 81 + { 82 + void* next = *(void**)buffer; 83 + RtlFreeHeap(RtlGetProcessHeap(), 0, buffer); 84 + buffer = next; 85 + } 86 + 87 + s_alloactions[slot].allocations = NULL; 88 + s_alloactions[slot].thread = NULL; 89 + } 90 + 91 + const char *wine_dbg_vsprintf(const char *format, va_list valist) 92 + { 93 + char* buffer; 94 + int len; 95 + 96 + len = vsnprintf(NULL, 0, format, valist); 97 + buffer = alloc_buffer(len + 1); 98 + if (buffer == NULL) 99 + { 100 + return "<allocation failed>"; 101 + } 102 + len = vsnprintf(buffer, len, format, valist); 103 + buffer[len] = 0; 104 + return buffer; 105 + } 106 + 107 + /* printf with temp buffer allocation */ 108 + const char *wine_dbg_sprintf( const char *format, ... ) 109 + { 110 + const char *ret; 111 + va_list valist; 112 + 113 + va_start(valist, format); 114 + ret = wine_dbg_vsprintf( format, valist ); 115 + va_end(valist); 116 + return ret; 117 + } 118 + 119 + const char *wine_dbgstr_wn( const WCHAR *str, int n ) 120 + { 121 + if (!((ULONG_PTR)str >> 16)) 122 + { 123 + if (!str) return "(null)"; 124 + return wine_dbg_sprintf("#%04x", LOWORD(str) ); 125 + } 126 + if (n == -1) 127 + { 128 + n = (int)wcslen(str); 129 + } 130 + if (n < 0) n = 0; 131 + 132 + return wine_dbg_sprintf("%.*S", n, str); 133 + } 134 + 135 + /* From wine/dlls/ntdll/misc.c */ 136 + LPCSTR debugstr_us( const UNICODE_STRING *us ) 137 + { 138 + if (!us) return "<null>"; 139 + return debugstr_wn(us->Buffer, us->Length / sizeof(WCHAR)); 140 + } 141 + 142 + static int default_dbg_vprintf( const char *format, va_list args ) 143 + { 144 + return vDbgPrintExWithPrefix("", -1, 0, format, args); 145 + } 146 + 147 + int wine_dbg_printf(const char *format, ... ) 148 + { 149 + int ret; 150 + va_list valist; 151 + 152 + va_start(valist, format); 153 + ret = default_dbg_vprintf(format, valist); 154 + va_end(valist); 155 + free_buffers(); 156 + return ret; 157 + } 158 + 159 + static int winefmt_default_dbg_vlog( enum __wine_debug_class cls, struct __wine_debug_channel *channel, 160 + const char *file, const char *func, const int line, const char *format, va_list args ) 161 + { 162 + int ret = 0; 163 + 164 + ret += wine_dbg_printf("%04x:", HandleToULong(NtCurrentTeb()->ClientId.UniqueProcess) ); 165 + ret += wine_dbg_printf("%04x:", HandleToULong(NtCurrentTeb()->ClientId.UniqueThread) ); 166 + 167 + if (format) 168 + ret += default_dbg_vprintf(format, args); 169 + return ret; 170 + } 171 + 172 + #define __wine_dbg_get_channel_flags(channel) \ 173 + ((channel) ? (channel)->flags : 0) 174 + 175 + int ros_dbg_log( enum __wine_debug_class cls, struct __wine_debug_channel *channel, 176 + const char *file, const char *func, const int line, const char *format, ... ) 177 + { 178 + int ret; 179 + va_list valist; 180 + 181 + if (!(__wine_dbg_get_channel_flags(channel) & (1 << cls))) return -1; 182 + 183 + va_start(valist, format); 184 + ret = winefmt_default_dbg_vlog(cls, channel, file, func, line, format, valist); 185 + va_end(valist); 186 + return ret; 187 + }