ReactOS  0.4.15-dev-4857-g47842d7
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 
17 extern "C"
18 {
19 // FIXME: Enabling _DEBUG at top level causes assertion failures... CORE-17505
20 int __cdecl _CrtDbgReport(int reportType, const char *filename, int linenumber, const char *moduleName, const char *format, ...);
21 int __cdecl _CrtDbgReportW(int reportType, const wchar_t *filename, int linenumber, const wchar_t *moduleName, const wchar_t *format, ...);
22 }
23 
24 namespace ATL
25 {
26 
27 template <UINT t_category = (1 << 19), UINT t_level = 0>
28 class CTraceCategoryEx
29 {
30 public:
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 
68 protected:
69  LPCTSTR m_name;
70 };
71 
72 class 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))
80 DEFINE_TRACE_CATEGORY(atlTraceGeneral, CTraceCategoryEx<>::TraceGeneral);
81 DEFINE_TRACE_CATEGORY(atlTraceCOM, CTraceCategoryEx<>::TraceCom);
82 DEFINE_TRACE_CATEGORY(atlTraceQI, CTraceCategoryEx<>::TraceQI);
83 DEFINE_TRACE_CATEGORY(atlTraceRegistrar, CTraceCategoryEx<>::TraceRegistrar);
84 DEFINE_TRACE_CATEGORY(atlTraceRefcount, CTraceCategoryEx<>::TraceRefcount);
85 DEFINE_TRACE_CATEGORY(atlTraceWindowing, CTraceCategoryEx<>::TraceWindowing);
86 DEFINE_TRACE_CATEGORY(atlTraceControls, CTraceCategoryEx<>::TraceControls);
87 DEFINE_TRACE_CATEGORY(atlTraceHosting, CTraceCategoryEx<>::TraceHosting);
88 DEFINE_TRACE_CATEGORY(atlTraceDBClient, CTraceCategoryEx<>::TraceDBClient);
89 DEFINE_TRACE_CATEGORY(atlTraceDBProvider, CTraceCategoryEx<>::TraceDBProvider);
90 DEFINE_TRACE_CATEGORY(atlTraceSnapin, CTraceCategoryEx<>::TraceSnapin);
91 DEFINE_TRACE_CATEGORY(atlTraceNotImpl, CTraceCategoryEx<>::TraceNotImpl);
92 DEFINE_TRACE_CATEGORY(atlTraceAllocation, CTraceCategoryEx<>::TraceAllocation);
93 DEFINE_TRACE_CATEGORY(atlTraceException, CTraceCategoryEx<>::TraceException);
94 DEFINE_TRACE_CATEGORY(atlTraceTime, CTraceCategoryEx<>::TraceTime);
95 DEFINE_TRACE_CATEGORY(atlTraceCache, CTraceCategoryEx<>::TraceCache);
96 DEFINE_TRACE_CATEGORY(atlTraceStencil, CTraceCategoryEx<>::TraceStencil);
97 DEFINE_TRACE_CATEGORY(atlTraceString, CTraceCategoryEx<>::TraceString);
98 DEFINE_TRACE_CATEGORY(atlTraceMap, CTraceCategoryEx<>::TraceMap);
99 DEFINE_TRACE_CATEGORY(atlTraceUtil, CTraceCategoryEx<>::TraceUtil);
100 DEFINE_TRACE_CATEGORY(atlTraceSecurity, CTraceCategoryEx<>::TraceSecurity);
101 DEFINE_TRACE_CATEGORY(atlTraceSync, CTraceCategoryEx<>::TraceSync);
102 DEFINE_TRACE_CATEGORY(atlTraceISAPI, CTraceCategoryEx<>::TraceISAPI);
103 #undef DEFINE_TRACE_CATEGORY
104 
105 struct 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 
127 struct 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 
146 protected:
147  static UINT s_categories;
148  static UINT s_level;
149 };
150 
151 DECLSPEC_SELECTANY UINT CTrace::s_categories = CTrace::EnableAllCategories;
152 DECLSPEC_SELECTANY UINT CTrace::s_level = CTrace::DefaultTraceLevel;
153 
154 template <typename X_CHAR>
155 inline VOID __stdcall
156 AtlTraceV(_In_opt_z_ const X_CHAR * file,
157  _In_ INT line,
158  _In_ const CTraceCategoryEasy& cat,
159  _In_ UINT level,
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 
188 template <typename X_CHAR>
189 inline VOID __stdcall
190 AtlTraceV(_In_opt_z_ const X_CHAR * file,
191  _In_ INT line,
192  _In_ const CTraceCategoryEasy& cat,
193  _In_ UINT level,
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 
222 template <typename X_CHAR, typename Y_CHAR>
223 inline VOID __cdecl
224 AtlTraceEx(_In_opt_z_ const X_CHAR * file,
225  _In_ INT line,
226  _In_ const CTraceCategoryEasy& cat,
227  _In_ UINT level,
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 
237 template <typename X_CHAR, typename Y_CHAR>
238 inline VOID __cdecl
239 AtlTraceEx(_In_opt_z_ const X_CHAR *file,
240  _In_ INT line,
241  _In_z_ _Printf_format_string_ const Y_CHAR *format,
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 
250 inline VOID __stdcall
251 AtlTraceEx(_In_opt_z_ PCTSTR file,
252  _In_ INT line,
253  _In_ DWORD value)
254 {
255  AtlTraceEx(file, line, TEXT("%ld (0x%lX)\n"), value, value);
256 }
257 
258 template <typename X_CHAR>
259 inline VOID __cdecl
260 AtlTrace(_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
292 using namespace ATL;
293 #endif
const uint16_t * PCWSTR
Definition: typedefs.h:57
GLint level
Definition: gl.h:1546
Definition: pdh_main.c:93
LPCSTR PCTSTR
Definition: ntbasedef.h:488
#define _CRT_WARN
Definition: crtdbg.h:19
#define __cdecl
Definition: accygwin.h:79
#define _In_opt_z_
Definition: ms_sal.h:314
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
STRSAFEAPI StringCchVPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat, va_list argList)
Definition: strsafe.h:490
#define DECLSPEC_SELECTANY
Definition: guiddef.h:40
const char * filename
Definition: ioapi.h:135
int32_t INT
Definition: typedefs.h:58
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define _snprintf
Definition: xmlstorage.h:200
#define L(x)
Definition: ntvdm.h:50
#define va_end(ap)
Definition: acmsvcex.h:90
unsigned int BOOL
Definition: ntddk_ex.h:94
STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:520
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
#define _In_
Definition: ms_sal.h:308
Definition: parser.c:48
char * va_list
Definition: acmsvcex.h:78
#define _In_z_
Definition: ms_sal.h:313
char TCHAR
Definition: xmlstorage.h:189
Definition: rosdlgs.h:5
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define _countof(array)
Definition: sndvol32.h:68
#define MAX_PATH
Definition: compat.h:34
unsigned long DWORD
Definition: ntddk_ex.h:95
va_start(ap, x)
#define __stdcall
Definition: typedefs.h:25
STRSAFEAPI StringCchVPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat, va_list argList)
Definition: strsafe.h:485
#define lstrcmp
Definition: winbase.h:3733
#define TEXT(s)
Definition: k32.h:26
_CRTIMP int __cdecl _vsnwprintf(wchar_t *_Dest, size_t _Count, const wchar_t *_Format, va_list _Args)
STRSAFEAPI StringCchLengthA(STRSAFE_LPCSTR psz, size_t cchMax, size_t *pcchLength)
Definition: strsafe.h:832
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
STRSAFEAPI StringCchLengthW(STRSAFE_LPCWSTR psz, size_t cchMax, size_t *pcchLength)
Definition: strsafe.h:842
#define _Printf_format_string_
Definition: ms_sal.h:561
#define _vsnprintf
Definition: xmlstorage.h:202
const char * PCSTR
Definition: typedefs.h:52
IN PCTCH IN DWORD cch
Definition: pager.h:36
GLsizei GLenum * categories
Definition: glext.h:11561
Definition: fci.c:126