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