mirror of
https://github.com/reactos/reactos.git
synced 2024-11-26 21:13:30 +08:00
[RTL] Add minimal wine debug support functions
This commit is contained in:
parent
626b06bb5a
commit
d2753d6374
@ -1,5 +1,5 @@
|
||||
#define __ROS_LONG64__
|
||||
|
||||
#define wine_dbgstr_wn wine_dbgstr_wn_
|
||||
#define STANDALONE
|
||||
#include <apitest.h>
|
||||
|
||||
|
@ -23,6 +23,7 @@ endif()
|
||||
|
||||
list(APPEND SOURCE
|
||||
${RTL_WINE_SOURCE}
|
||||
wine_debug.c
|
||||
access.c
|
||||
acl.c
|
||||
appverifier.c
|
||||
|
187
sdk/lib/rtl/wine_debug.c
Normal file
187
sdk/lib/rtl/wine_debug.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user