HRESULT StringCbPrintfExA( LPSTR pszDest, size_t cbDest, LPSTR * ppszDestEnd, size_t * pcbRemaining, DWORD dwFlags, LPCSTR pszFormat, ...) { va_list argList; HRESULT result; va_start(argList, pszFormat); result = StringCbVPrintfExA(pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, argList); va_end(argList); return result; }
HRESULT TunnelSend(PCSTR Format, ...) { HRESULT hRes=S_OK; va_list Args; int iResult; size_t cbRemaining; if(FAILED(hRes=TunnelIsUp())) { dbgout("[sync] TunnelSend: tunnel is unavailable\n"); return hRes; } va_start(Args, Format); hRes = StringCbVPrintfExA(SendBuffer, MAX_SEND, NULL, &cbRemaining, STRSAFE_NULL_ON_FAILURE, Format, Args); va_end(Args); if (FAILED(hRes)) return hRes; #if VERBOSE >= 2 dbgout("[sync] send 0x%x bytes, %s\n", MAX_SEND-cbRemaining, SendBuffer); #endif iResult = send(g_Sock, (const char *)SendBuffer, MAX_SEND-((unsigned int)cbRemaining), 0); if(iResult == SOCKET_ERROR) { iResult = WSAGetLastError(); dbgout("[sync] send failed with error %d, 0x%x\n", iResult, g_Sock); WsaErrMsg(iResult); g_Synchronized=FALSE; TunnelClose(); hRes=E_FAIL; } return hRes; }
/**---------------------------------------------------------------------------- \brief \param \return \code \endcode -----------------------------------------------------------------------------*/ void DebugMessage( const char* Function, int Line, const char* LogPrefix, const char* fmt, ... ) { _ASSERTE(NULL != LogPrefix); if (NULL == LogPrefix) return; _ASSERTE(NULL != fmt); if (NULL == fmt) return; char log_buffer[4096] = { 0 }; size_t remain = sizeof(log_buffer); char* pos = log_buffer; va_list args; // 프로세스 정보 // char name_buffer[MAX_PATH + 1] = { 0 }; char *name = name_buffer; name_buffer[0] = '\0'; DWORD len = GetModuleFileNameA(NULL, name_buffer, sizeof(name_buffer)); if (len>0) name = get_filename_part(name_buffer, len); // format string 파라미터를 Multibyte / WideChar 가 잘 못 들어온 경우등 // 에러가 발생할 수 있어서 해당 함수를 찾기위한 디버그 코드 // e.g. %s => L"debug string...." or %S => "debug string" // size_t remain_b = remain; char* pos_b = pos; HRESULT hRes = StringCbPrintfExA( pos, remain, &pos, &remain, 0, "%-18s(%04u:%04u), %s %s() ", name, GetCurrentProcessId(), GetCurrentThreadId(), LogPrefix, Function ); if (S_OK != hRes) { OutputDebugStringA("StringCbPrintfExA() failed, more log buffer needed...?"); return; } remain_b = remain; pos_b = pos; va_start(args, fmt); hRes = StringCbVPrintfExA( pos, remain, &pos, &remain, 0, fmt, args ); if (S_OK != hRes) { // 한글 같은 unicode 문자열이 있는 경우 발생할 수 있음 // StringCbPrintfExA( pos_b, remain_b, &pos_b, &remain_b, 0, "invalid function call parameters, line=%d", Line ); remain = remain_b; pos = pos_b; } va_end(args); hRes = StringCbPrintfExA( pos, remain, &pos, &remain, 0, "%s", "\r\n" ); if (!SUCCEEDED(hRes)) { OutputDebugStringA("StringCbPrintfExA() failed, more log buffer needed...?"); return; } OutputDebugStringA(log_buffer); }
/** * @brief * @param * @see * @remarks * @code * @endcode * @return **/ void log_write_fmt( _In_ uint32_t log_level, _In_z_ const char* function, _In_z_ const char* fmt, _In_ ... ) { if (NULL == fmt) return; char log_buffer[2048]; size_t remain = sizeof(log_buffer); char* pos = log_buffer; va_list args; // log level switch (log_level) { case log_level_debug: StringCbPrintfExA(pos, remain, &pos, &remain, 0, "%s", "[DEBG] "); break; case log_level_info: StringCbPrintfExA(pos, remain, &pos, &remain, 0, "%s", "[INFO] "); break; case log_level_warn: StringCbPrintfExA(pos, remain, &pos, &remain, 0, "%s", "[WARN] "); break; case log_level_error: StringCbPrintfExA(pos, remain, &pos, &remain, 0, "%s", "[EROR] "); break; default: _ASSERTE(!"never reach here!"); return; } //> show process name if (true == _show_process_name) { StringCbPrintfExA( pos, remain, &pos, &remain, 0, "%ws", get_current_module_fileEx().c_str() ); } //> show pid, tid if (true == _show_pid_tid) { StringCbPrintfExA( pos, remain, &pos, &remain, 0, "(%+5u:%+5u) : ", GetCurrentProcessId(), GetCurrentThreadId() ); } //> show function name if (true == _show_function_name) { StringCbPrintfExA(pos, remain, &pos, &remain, 0, "%s : ", function); } va_start(args,fmt); HRESULT hRes = StringCbVPrintfExA( pos, remain, &pos, &remain, 0, fmt, args ); if (S_OK != hRes) { // invalid character 가 끼어있는 경우 발생 할 수 있음 StringCbPrintfExA( pos, remain, &pos, &remain, 0, "invalid function call parameters" ); } va_end(args); // line feed StringCbPrintfExA(pos, remain, &pos, &remain, 0, "\n"); // Let's write logs. switch (log_level) { case log_level_error: // same as log_level_critical write_to_console(wtc_red, log_buffer); break; case log_level_info: case log_level_warn: write_to_console(wtc_green, log_buffer); break; default: write_to_console(wtc_none, log_buffer); } OutputDebugStringA(log_buffer); }