ReactOS 0.4.15-dev-5865-g640e228
atltrace.h
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS ATL
3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE: Providing ATLTRACE macro
5 * COPYRIGHT: Copyright 2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#pragma once
9
10#include "atldef.h"
11
12#if DBG // FIXME: We should use _DEBUG instead of DBG. CORE-17505
13
14#include <stdio.h>
15#include <crtdbg.h>
16
17extern "C"
18{
19// FIXME: Enabling _DEBUG at top level causes assertion failures... CORE-17505
20int __cdecl _CrtDbgReport(int reportType, const char *filename, int linenumber, const char *moduleName, const char *format, ...);
21int __cdecl _CrtDbgReportW(int reportType, const wchar_t *filename, int linenumber, const wchar_t *moduleName, const wchar_t *format, ...);
22}
23
24namespace ATL
25{
26
27template <UINT t_category = (1 << 19), UINT t_level = 0>
28class CTraceCategoryEx
29{
30public:
31 enum
32 {
33 TraceGeneral = (1 << 0),
34 TraceCom = (1 << 1),
35 TraceQI = (1 << 2),
36 TraceRegistrar = (1 << 3),
37 TraceRefcount = (1 << 4),
38 TraceWindowing = (1 << 5),
39 TraceControls = (1 << 6),
40 TraceHosting = (1 << 7),
41 TraceDBClient = (1 << 8),
42 TraceDBProvider = (1 << 9),
43 TraceSnapin = (1 << 10),
44 TraceNotImpl = (1 << 11),
45 TraceAllocation = (1 << 12),
46 TraceException = (1 << 13),
47 TraceTime = (1 << 14),
48 TraceCache = (1 << 15),
49 TraceStencil = (1 << 16),
50 TraceString = (1 << 17),
51 TraceMap = (1 << 18),
52 TraceUtil = (1 << 19),
53 TraceSecurity = (1 << 20),
54 TraceSync = (1 << 21),
55 TraceISAPI = (1 << 22),
56 TraceUser = TraceUtil
57 };
58
59 CTraceCategoryEx(LPCTSTR name = NULL) : m_name(name)
60 {
61 }
62
63 static UINT GetLevel() { return t_level; }
64 static UINT GetCategory() { return t_category; }
65 operator UINT() const { return GetCategory(); }
66 LPCTSTR GetCategoryName() const { return m_name; }
67
68protected:
69 LPCTSTR m_name;
70};
71
72class CTraceCategory : public CTraceCategoryEx<>
73{
74 CTraceCategory(LPCTSTR name = NULL) : CTraceCategoryEx<>(name)
75 {
76 }
77};
78
79#define DEFINE_TRACE_CATEGORY(name, cat) extern const DECLSPEC_SELECTANY CTraceCategoryEx<cat, 0> name(TEXT(#name))
80DEFINE_TRACE_CATEGORY(atlTraceGeneral, CTraceCategoryEx<>::TraceGeneral);
81DEFINE_TRACE_CATEGORY(atlTraceCOM, CTraceCategoryEx<>::TraceCom);
82DEFINE_TRACE_CATEGORY(atlTraceQI, CTraceCategoryEx<>::TraceQI);
83DEFINE_TRACE_CATEGORY(atlTraceRegistrar, CTraceCategoryEx<>::TraceRegistrar);
84DEFINE_TRACE_CATEGORY(atlTraceRefcount, CTraceCategoryEx<>::TraceRefcount);
85DEFINE_TRACE_CATEGORY(atlTraceWindowing, CTraceCategoryEx<>::TraceWindowing);
86DEFINE_TRACE_CATEGORY(atlTraceControls, CTraceCategoryEx<>::TraceControls);
87DEFINE_TRACE_CATEGORY(atlTraceHosting, CTraceCategoryEx<>::TraceHosting);
88DEFINE_TRACE_CATEGORY(atlTraceDBClient, CTraceCategoryEx<>::TraceDBClient);
89DEFINE_TRACE_CATEGORY(atlTraceDBProvider, CTraceCategoryEx<>::TraceDBProvider);
90DEFINE_TRACE_CATEGORY(atlTraceSnapin, CTraceCategoryEx<>::TraceSnapin);
91DEFINE_TRACE_CATEGORY(atlTraceNotImpl, CTraceCategoryEx<>::TraceNotImpl);
92DEFINE_TRACE_CATEGORY(atlTraceAllocation, CTraceCategoryEx<>::TraceAllocation);
93DEFINE_TRACE_CATEGORY(atlTraceException, CTraceCategoryEx<>::TraceException);
94DEFINE_TRACE_CATEGORY(atlTraceTime, CTraceCategoryEx<>::TraceTime);
95DEFINE_TRACE_CATEGORY(atlTraceCache, CTraceCategoryEx<>::TraceCache);
96DEFINE_TRACE_CATEGORY(atlTraceStencil, CTraceCategoryEx<>::TraceStencil);
97DEFINE_TRACE_CATEGORY(atlTraceString, CTraceCategoryEx<>::TraceString);
98DEFINE_TRACE_CATEGORY(atlTraceMap, CTraceCategoryEx<>::TraceMap);
99DEFINE_TRACE_CATEGORY(atlTraceUtil, CTraceCategoryEx<>::TraceUtil);
100DEFINE_TRACE_CATEGORY(atlTraceSecurity, CTraceCategoryEx<>::TraceSecurity);
101DEFINE_TRACE_CATEGORY(atlTraceSync, CTraceCategoryEx<>::TraceSync);
102DEFINE_TRACE_CATEGORY(atlTraceISAPI, CTraceCategoryEx<>::TraceISAPI);
103#undef DEFINE_TRACE_CATEGORY
104
105struct CTraceCategoryEasy
106{
107 UINT m_category;
108 UINT m_level;
109 LPCTSTR m_name;
110
111 template <UINT t_category, UINT t_level>
112 CTraceCategoryEasy(const CTraceCategoryEx<t_category, t_level>& cat)
113 {
114 m_category = t_category;
115 m_level = t_level;
116 m_name = cat.GetCategoryName();
117 }
118
119 operator UINT() const { return m_category; }
120
121 BOOL IsGeneral() const
122 {
123 return lstrcmp(m_name, TEXT("atlTraceGeneral")) == 0;
124 }
125};
126
127struct CTrace
128{
129 enum
130 {
131 DefaultTraceLevel = 0,
132 DisableTracing = 0xFFFFFFFF,
133 EnableAllCategories = 0xFFFFFFFF
134 };
135
136 static UINT GetLevel() { return s_level; }
137 static UINT GetCategories() { return s_categories; }
138 static void SetLevel(UINT level) { s_level = level; }
139 static void SetCategories(UINT categories) { s_categories = categories; }
140
141 static bool IsTracingEnabled(UINT category, UINT level)
142 {
143 return (s_level != DisableTracing && s_level >= level && (s_categories & category));
144 }
145
146protected:
147 static UINT s_categories;
148 static UINT s_level;
149};
150
151DECLSPEC_SELECTANY UINT CTrace::s_categories = CTrace::EnableAllCategories;
152DECLSPEC_SELECTANY UINT CTrace::s_level = CTrace::DefaultTraceLevel;
153
154template <typename X_CHAR>
155inline VOID __stdcall
156AtlTraceV(_In_opt_z_ const X_CHAR * file,
157 _In_ INT line,
158 _In_ const CTraceCategoryEasy& cat,
161 _In_ va_list va)
162{
163 char szBuff[1024], szFile[MAX_PATH];
164 size_t cch = 0;
165 const BOOL bUnicode = (sizeof(TCHAR) == 2);
166
167 if (!CTrace::IsTracingEnabled(cat, level))
168 return;
169
170#ifdef _STRSAFE_H_INCLUDED_
171 StringCchPrintfA(szFile, _countof(szFile), ((sizeof(X_CHAR) == 2) ? "%ls" : "%hs"), file);
172 if (!cat.IsGeneral())
173 {
174 StringCchPrintfA(szBuff, _countof(szBuff), (bUnicode ? "%ls - " : "%hs - "), cat.m_name);
175 StringCchLengthA(szBuff, _countof(szBuff), &cch);
176 }
177 StringCchVPrintfA(&szBuff[cch], _countof(szBuff) - cch, format, va);
178#else
179 _snprintf(szFile, _countof(szFile), ((sizeof(X_CHAR) == 2) ? "%ls" : "%hs"), file);
180 if (!cat.IsGeneral())
181 cch = _snprintf(szBuff, _countof(szBuff), (bUnicode ? "%ls - " : "%hs - "), cat.m_name);
182 _vsnprintf(&szBuff[cch], _countof(szBuff) - cch, format, va);
183#endif
184
185 _CrtDbgReport(_CRT_WARN, szFile, line, NULL, "%hs", szBuff);
186}
187
188template <typename X_CHAR>
189inline VOID __stdcall
190AtlTraceV(_In_opt_z_ const X_CHAR * file,
191 _In_ INT line,
192 _In_ const CTraceCategoryEasy& cat,
195 _In_ va_list va)
196{
197 WCHAR szBuff[1024], szFile[MAX_PATH];
198 size_t cch = 0;
199 const BOOL bUnicode = (sizeof(TCHAR) == 2);
200
201 if (!CTrace::IsTracingEnabled(cat, level))
202 return;
203
204#ifdef _STRSAFE_H_INCLUDED_
205 StringCchPrintfW(szFile, _countof(szFile), ((sizeof(X_CHAR) == 2) ? L"%ls" : L"%hs"), file);
206 if (!cat.IsGeneral())
207 {
208 StringCchPrintfW(szBuff, _countof(szBuff), (bUnicode ? L"%ls - " : L"%hs - "), cat.m_name);
209 StringCchLengthW(szBuff, _countof(szBuff), &cch);
210 }
211 StringCchVPrintfW(&szBuff[cch], _countof(szBuff) - cch, format, va);
212#else
213 _snwprintf(szFile, _countof(szFile), ((sizeof(X_CHAR) == 2) ? L"%ls" : L"%hs"), file);
214 if (!cat.IsGeneral())
215 cch = _snwprintf(szBuff, _countof(szBuff), (bUnicode ? L"%ls - " : L"%hs - "), cat.m_name);
216 _vsnwprintf(&szBuff[cch], _countof(szBuff) - cch, format, va);
217#endif
218
219 _CrtDbgReportW(_CRT_WARN, szFile, line, NULL, L"%ls", szBuff);
220}
221
222template <typename X_CHAR, typename Y_CHAR>
223inline VOID __cdecl
224AtlTraceEx(_In_opt_z_ const X_CHAR * file,
225 _In_ INT line,
226 _In_ const CTraceCategoryEasy& cat,
228 _In_z_ _Printf_format_string_ const Y_CHAR * format,
229 ...)
230{
231 va_list va;
232 va_start(va, format);
233 AtlTraceV(file, line, cat, level, format, va);
234 va_end(va);
235}
236
237template <typename X_CHAR, typename Y_CHAR>
238inline VOID __cdecl
239AtlTraceEx(_In_opt_z_ const X_CHAR *file,
240 _In_ INT line,
242 ...)
243{
244 va_list va;
245 va_start(va, format);
246 AtlTraceV(file, line, atlTraceGeneral, 0, format, va);
247 va_end(va);
248}
249
250inline VOID __stdcall
251AtlTraceEx(_In_opt_z_ PCTSTR file,
252 _In_ INT line,
254{
255 AtlTraceEx(file, line, TEXT("%ld (0x%lX)\n"), value, value);
256}
257
258template <typename X_CHAR>
259inline VOID __cdecl
260AtlTrace(_In_z_ _Printf_format_string_ const X_CHAR *format, ...)
261{
262 va_list va;
263 va_start(va, format);
264 AtlTraceV(NULL, -1, atlTraceGeneral, 0, format, va);
265 va_end(va);
266}
267
268} // namespace ATL
269
270#endif // DBG
271
272#ifndef ATLTRACE
273 #if DBG // FIXME: We should use _DEBUG instead of DBG. CORE-17505
274 #define ATLTRACE(format, ...) ATL::AtlTraceEx(__FILE__, __LINE__, format, ##__VA_ARGS__)
275 #else
276 #define ATLTRACE(format, ...) ((void)0)
277 #endif
278#endif
279
280#define ATLTRACE2 ATLTRACE
281
282#if DBG // FIXME: We should use _DEBUG instead of DBG. CORE-17505
283 #define ATLTRACENOTIMPL(funcname) do { \
284 ATLTRACE(atlTraceNotImpl, 0, #funcname " is not implemented.\n"); \
285 return E_NOTIMPL; \
286 } while (0)
287#else
288 #define ATLTRACENOTIMPL(funcname) return E_NOTIMPL
289#endif
290
291#ifndef _ATL_NO_AUTOMATIC_NAMESPACE
292using namespace ATL;
293#endif
#define __cdecl
Definition: accygwin.h:79
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define _CRT_WARN
Definition: crtdbg.h:19
EXTERN_C int __cdecl _CrtDbgReportW(int reportType, const wchar_t *filename, int linenumber, const wchar_t *moduleName, const wchar_t *format,...)
Definition: dbgrpt.cpp:316
EXTERN_C int __cdecl _CrtDbgReport(int reportType, const char *filename, int linenumber, const char *moduleName, const char *format,...)
Definition: dbgrpt.cpp:264
#define NULL
Definition: types.h:112
#define MAX_PATH
Definition: compat.h:34
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint level
Definition: gl.h:1546
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLsizei GLenum * categories
Definition: glext.h:11561
_CRTIMP int __cdecl _vsnwprintf(wchar_t *_Dest, size_t _Count, const wchar_t *_Format, va_list _Args)
const char * filename
Definition: ioapi.h:137
#define TEXT(s)
Definition: k32.h:26
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
#define _In_z_
Definition: ms_sal.h:313
#define _In_opt_z_
Definition: ms_sal.h:314
#define _In_
Definition: ms_sal.h:308
#define _Printf_format_string_
Definition: ms_sal.h:561
Definition: rosdlgs.h:6
unsigned int UINT
Definition: ndis.h:50
LPCSTR PCTSTR
Definition: ntbasedef.h:488
#define L(x)
Definition: ntvdm.h:50
#define DECLSPEC_SELECTANY
Definition: guiddef.h:40
#define _countof(array)
Definition: sndvol32.h:68
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
STRSAFEAPI StringCchLengthA(STRSAFE_LPCSTR psz, size_t cchMax, size_t *pcchLength)
Definition: strsafe.h:832
STRSAFEAPI StringCchVPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat, va_list argList)
Definition: strsafe.h:490
STRSAFEAPI StringCchLengthW(STRSAFE_LPCWSTR psz, size_t cchMax, size_t *pcchLength)
Definition: strsafe.h:842
STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:520
STRSAFEAPI StringCchVPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat, va_list argList)
Definition: strsafe.h:485
Definition: fci.c:127
Definition: parser.c:49
const uint16_t * PCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
#define __stdcall
Definition: typedefs.h:25
const char * PCSTR
Definition: typedefs.h:52
Definition: pdh_main.c:94
#define lstrcmp
Definition: winbase.h:3743
char TCHAR
Definition: xmlstorage.h:189
#define _vsnprintf
Definition: xmlstorage.h:202
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define _snprintf
Definition: xmlstorage.h:200