static BOOL DebugMessageV(DWORD dwSize, LPCWSTR lpszMessage, va_list arglist) { LPWSTR lpszMsgBuf; HRESULT hResult; // Parameter checking. if( (NULL == lpszMessage) || (0 == dwSize) ) { return FALSE; } // Allocate memory for message buffer. lpszMsgBuf = new WCHAR[dwSize + 1]; if(NULL == lpszMsgBuf) return FALSE; // Pass the variable parameters to wvsprintf to be formated. hResult = StringCbVPrintfW(lpszMsgBuf, (dwSize + 1) * sizeof(WCHAR), lpszMessage, arglist); // Dump string to debug output. OutputDebugStringW(lpszMsgBuf); // Clean up. delete[] lpszMsgBuf; return SUCCEEDED(hResult); }
//-------------------------------------------------------------------------- // Local helper functions //-------------------------------------------------------------------------- BOOL __stdcall DebugPrint( LPCWSTR pszMessage, // Format string for the error message ... // args specified in the format string. ) { va_list arglist; // varargs list for processing the '...' parameter. WCHAR szMsgBuf[MAX_PATH] = {0}; // Use a stack error buffer so that we don't need to // allocate in the failure path. HRESULT hResult; // Result from formatting the string. if (NULL == pszMessage) { return FALSE; } // Pass the variable parameters to wvsprintf to be formated. va_start(arglist, pszMessage); hResult = StringCbVPrintfW(szMsgBuf, MAX_PATH*sizeof(szMsgBuf[0]), pszMessage, arglist); va_end(arglist); // Dump string to debug output. OutputDebugStringW(szMsgBuf); return SUCCEEDED(hResult); }
void _DBGPRINT( LPCWSTR kwszFunction, INT iLineNumber, LPCWSTR kwszDebugFormatString, ... ) { INT cbFormatString = 0; va_list args; PWCHAR wszDebugString = NULL; size_t st_Offset = 0; va_start( args, kwszDebugFormatString ); cbFormatString = _scwprintf( L"[%s:%d] ", kwszFunction, iLineNumber ) * sizeof( WCHAR ); cbFormatString += _vscwprintf( kwszDebugFormatString, args ) * sizeof( WCHAR ) + 2; /* Depending on the size of the format string, allocate space on the stack or the heap. */ wszDebugString = (PWCHAR)_malloca( cbFormatString ); /* Populate the buffer with the contents of the format string. */ StringCbPrintfW( wszDebugString, cbFormatString, L"[%s:%d] ", kwszFunction, iLineNumber ); StringCbLengthW( wszDebugString, cbFormatString, &st_Offset ); StringCbVPrintfW( &wszDebugString[st_Offset / sizeof(WCHAR)], cbFormatString - st_Offset, kwszDebugFormatString, args ); OutputDebugStringW( wszDebugString ); _freea( wszDebugString ); va_end( args ); }
// Handy function for logging. Works like printf() but outputs // to the debugger window since we have no console in a Win32 GUI. void GL::Utils::log(LPCWSTR format, ...) { WCHAR buf[200]; va_list ap; va_start(ap, format); (void)StringCbVPrintfW(buf, sizeof(buf)/sizeof(buf[0]), format, ap); va_end(ap); OutputDebugStringW(buf); }
void OutputDebugPrint(LPCWSTR szFormat, ...) { WCHAR szBuffer[1024]; va_list ap; va_start(ap, szFormat); StringCbVPrintfW(szBuffer, sizeof(szBuffer), szFormat, ap); va_end(ap); OutputDebugStringW(szBuffer); }
HRESULT StringCbPrintfW( LPWSTR pszDest, size_t cbDest, LPCWSTR pszFormat, ...) { va_list argList; HRESULT result; va_start(argList, pszFormat); result = StringCbVPrintfW(pszDest, cbDest, pszFormat, argList); va_end(argList); return result; }
BOOL WriteToLogPrintfV( IN PLOG_FILE LogFile, IN LPCWSTR Format, IN va_list args) { StringCbVPrintfW(LogFile->pBuffer, LogFile->cbBufferSize, Format, args); return WriteToLog(LogFile, LogFile->pBuffer, wcslen(LogFile->pBuffer) * sizeof(WCHAR)); }
static void fatal(dword dw, wchar_t* message, ...) { void *lpDisplayBuf, *lpMsgBuf; if(dw == 0) { // If no return code was specified, we assume that the message // contains a function name that failed. In that case, we retrieve // the system error message for the last-error code dw = GetLastError(); FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t*) &lpMsgBuf, 0, NULL ); // Allocate our buffer for the error message. lpDisplayBuf = (void*)LocalAlloc( LMEM_ZEROINIT, (lstrlenW((const wchar_t*)lpMsgBuf) + lstrlenW((const wchar_t*)message) + 47) * sizeof(wchar_t) ); StringCchPrintfW( (wchar_t*)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(wchar_t), L"FATAL: %s failed with error %d: %s", message, dw, lpMsgBuf ); } else { // Otherwise, we assume that the error message is a format string. va_list args = NULL; // Allocate buffer for our resulting format string. lpMsgBuf = (void*)LocalAlloc( LMEM_ZEROINIT, (lstrlenW((const wchar_t*)message) + 8) * sizeof(wchar_t) ); StringCchPrintfW( (wchar_t*)lpMsgBuf, LocalSize(lpMsgBuf) / sizeof(wchar_t), L"FATAL: %s", message ); // Might as well use the maximum allowed buffer, since there's no way I know of the // get the size of the resulting buff. lpDisplayBuf = (void*)LocalAlloc(LMEM_ZEROINIT, STRSAFE_MAX_CCH * sizeof(wchar_t)); va_start(args, lpMsgBuf); StringCbVPrintfW( (wchar_t*)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(wchar_t), lpMsgBuf, args ); va_end(args); } #ifndef NO_MSGBOX MessageBoxW(GetConsoleWindow(), (const wchar_t*)lpDisplayBuf, L"Fatal Error", MB_OK); #else wprintf(L"%s\n", lpDisplayBuf); #endif LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); ExitProcess(dw); }
// Print a debug string: helper method, called by wrapper methods. void DebugHelper::DebugVPrintfW(_In_z_ LPCWSTR pFormat, _In_opt_ va_list vl) { HRESULT hr = S_OK; SYSTEMTIME st = {0}; if (debugOutputBuffer && debugOutputBufferTemp) { GetLocalTime(&st); // Print the line's prefix. hr = StringCbPrintfW(debugOutputBufferTemp, debugOutputBufferLen, L"[T%lu: %02u/%02u/%02u @ %02u:%02u:%02u.%03u] %s\n", GetCurrentThreadId(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, pFormat); if (FAILED(hr)) { OutputDebugStringW(L"DebugHelper: Caller attempted to use a debug output format string that was too long!\n"); goto Cleanup; } if (vl != NULL) { // Print the given arguments as per the resultant format. hr = StringCbVPrintfW(debugOutputBuffer, debugOutputBufferLen, debugOutputBufferTemp, vl); } else { // If there is no argument return only the timestamp hr = StringCbCopy(debugOutputBuffer, debugOutputBufferLen, debugOutputBufferTemp); } if (FAILED(hr)) { OutputDebugStringW(L"DebugHelper: Caller attempted to print a debug string that was too long!\n"); goto Cleanup; } // Print the string to the debugger. OutputDebugStringW(debugOutputBuffer); } else { hr = E_POINTER; OutputDebugStringW(L"DebugHelper: Bad temporary buffer pointers\n"); goto Cleanup; } Cleanup: if (FAILED(hr)) { // Fail in a useful manner -- just display the caller's literal // format string in the debugger, without expanding any format // fields. (The output strings may still be useful to help diagnose // problems, whether or not any actual runtime values are shown.) OutputDebugStringW(pFormat); OutputDebugStringW(L"\n"); } return; }