2025-11-28 00:35:46 +09:00

170 lines
7.2 KiB
C

/////////////////////////////////////////////////////////////////////////
// Copyright © 2008 Microsoft Corporation. All rights reserved.
//
// This file may contain preliminary information or inaccuracies,
// and may not correctly represent any associated Microsoft
// Product as commercially released. All Materials are provided entirely
// “AS IS.” To the extent permitted by law, MICROSOFT MAKES NO
// WARRANTY OF ANY KIND, DISCLAIMS ALL EXPRESS, IMPLIED AND STATUTORY
// WARRANTIES, AND ASSUMES NO LIABILITY TO YOU FOR ANY DAMAGES OF
// ANY TYPE IN CONNECTION WITH THESE MATERIALS OR ANY INTELLECTUAL PROPERTY IN THEM.
//
#pragma once
/////////////////////////////////////////////////////////////////////////
// utility macros
//
#define GEN_EVAL(X) X
#define GEN_STRINGIZE_ARG(X) #X
#define GEN_STRINGIZE(X) GEN_EVAL(GEN_STRINGIZE_ARG(X))
#define GEN_MERGE(A, B) A##B
#define GEN_MAKE_W(A) GEN_MERGE(L, A)
#define GEN_WSTRINGIZE(X) GEN_MAKE_W(GEN_STRINGIZE_ARG(X))
#define __WFILE__ GEN_MAKE_W(GEN_EVAL(__FILE__))
#define __WFUNCTION__ GEN_MAKE_W(GEN_EVAL(__FUNCTION__))
// Helper macros to print a GUID using printf-style formatting
#define WSTR_GUID_FMT L"{%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x}"
#define GUID_PRINTF_ARG( X ) \
(X).Data1, \
(X).Data2, \
(X).Data3, \
(X).Data4[0], (X).Data4[1], (X).Data4[2], (X).Data4[3], \
(X).Data4[4], (X).Data4[5], (X).Data4[6], (X).Data4[7]
// Helper macro for quick treatment of case statements for error codes
#define CHECK_CASE_FOR_CONSTANT(value) \
case value: return wstring(GEN_MAKE_W(#value));
#define BOOL2TXT(b) ((b)? L"TRUE": L"FALSE")
// Max buffer size for logging/tracing
const int MAX_VPRINTF_BUFFER_SIZE = 4096;
// Generic macro for variable parameter expansion
// Safely truncate the expansion if the buffer is not big enough
#define VPRINTF_VAR_PARAMS(buffer,param) \
{ \
buffer.resize(MAX_VPRINTF_BUFFER_SIZE, L'\0'); \
va_list marker; \
va_start( marker, param ); \
HRESULT hr = StringCchVPrintfW( \
WString2Buffer(buffer), \
buffer.length(), \
param.c_str(), \
marker ); \
if (FAILED(hr) \
&& (hr != STRSAFE_E_INSUFFICIENT_BUFFER)) \
throw(hr); \
va_end( marker ); \
}
// Macro that express the position in the source file (provided for better tracing)
#define DBG_INFO __WFILE__ , __LINE__, __WFUNCTION__
//
// Very simple ASSERT definition
//
#ifdef _DEBUG
#define _ASSERTE(x) { \
if (!(x)) \
{ \
wprintf(L"\nASSERTION FAILED: %S\n", #x); \
wprintf(L"- File: %s\n- Line: %d\n- Function: %s\n", DBG_INFO); \
wprintf(L"\nPress <ENTER> to continue..."); \
getchar(); \
} \
}
#else
#define _ASSERTE(x)
#endif
/////////////////////////////////////////////////////////////////////////////
// Error-treatment macros
//
//
// Macro to execute a COM API and to test its result.
// - The macro will execute the call given in its parameter
// - The macro will examine the returned HRESULT
// - If an failed HRESULT is returned, an explanatory text is written to the console
// and an error is thrown. VSHADOW.EXE will then terminate
//
// Example
// - API: HRESULT CoCreateInstance()
// - Sample Usage: CHECK_COM( CoCreateInstance() )
//
#define CHECK_COM( Call ) CHECK_COM_ERROR( Call, #Call )
#define CHECK_COM_ERROR( ErrorCode, Text ) \
{ \
ft.Trace(DBG_INFO, L"Executing COM call '%s'", GEN_WSTRINGIZE(Text)); \
HRESULT hrInternal = ErrorCode; \
if (FAILED(hrInternal)) \
{ \
ft.WriteLine(L"\nERROR: COM call %s failed.", GEN_WSTRINGIZE(Text)); \
ft.WriteLine(L"- Returned HRESULT = 0x%08lx", hrInternal); \
ft.WriteLine(L"- Error text: %s", FunctionTracer::HResult2String(hrInternal).c_str()); \
ft.WriteLine(L"- Please re-run VSHADOW.EXE with the /tracing option to get more details");\
throw(hrInternal); \
} \
}
//
// Macro to execute a Win32 API and to test its result.
// - The macro will execute the call given in its parameter
// - The macro will examine the returned BOOL (we assume that the API returns a BOOL.
// - If FALSE is returned, an explanatory text is written to the console
// and an error is thrown. VSHADOW.EXE will then terminate.
//
#define CHECK_WIN32( Call ) \
{ \
BOOL bRes = Call; \
if (!bRes) \
CHECK_WIN32_ERROR(GetLastError(), #Call); \
}
#define CHECK_WIN32_ERROR( ErrorCode, Text ) \
{ \
ft.Trace(DBG_INFO, L"Executing Win32 call '%s'", GEN_WSTRINGIZE(Text)); \
DWORD dwLastError = ErrorCode; \
HRESULT hrInternal = HRESULT_FROM_WIN32(dwLastError); \
if (dwLastError != NOERROR) \
{ \
ft.WriteLine(L"\nERROR: Win32 call %s failed.", GEN_WSTRINGIZE(Text)); \
ft.WriteLine(L"- GetLastError() == %ld", dwLastError); \
ft.WriteLine(L"- Error text: %s", FunctionTracer::HResult2String(hrInternal).c_str()); \
ft.WriteLine(L"- Please re-run VSHADOW.EXE with the /tracing option to get more details");\
throw(hrInternal); \
} \
}