diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn index 32f89c72a6..117c98cb82 100644 --- a/rtc_base/BUILD.gn +++ b/rtc_base/BUILD.gn @@ -764,6 +764,7 @@ rtc_static_library("rtc_base_generic") { "win32.h", "win32filesystem.cc", "win32filesystem.h", + "win32securityerrors.cc", "win32window.cc", "win32window.h", ] diff --git a/rtc_base/httpcommon.cc b/rtc_base/httpcommon.cc index e60ad477a8..345b4aa28b 100644 --- a/rtc_base/httpcommon.cc +++ b/rtc_base/httpcommon.cc @@ -11,6 +11,7 @@ #include #if defined(WEBRTC_WIN) +#define WIN32_LEAN_AND_MEAN #include #include #include @@ -30,80 +31,10 @@ #include "rtc_base/socketaddress.h" namespace rtc { -namespace { + #if defined(WEBRTC_WIN) -/////////////////////////////////////////////////////////////////////////////// -// ConstantToLabel can be used to easily generate string names from constant -// values. This can be useful for logging descriptive names of error messages. -// Usage: -// const ConstantToLabel LIBRARY_ERRORS[] = { -// KLABEL(SOME_ERROR), -// KLABEL(SOME_OTHER_ERROR), -// ... -// LASTLABEL -// } -// -// int err = LibraryFunc(); -// LOG(LS_ERROR) << "LibraryFunc returned: " -// << GetErrorName(err, LIBRARY_ERRORS); -struct ConstantToLabel { int value; const char * label; }; - -const char* LookupLabel(int value, const ConstantToLabel entries[]) { - for (int i = 0; entries[i].label; ++i) { - if (value == entries[i].value) { - return entries[i].label; - } - } - return 0; -} - -std::string GetErrorName(int err, const ConstantToLabel* err_table) { - if (err == 0) - return "No error"; - - if (err_table != 0) { - if (const char* value = LookupLabel(err, err_table)) - return value; - } - - char buffer[16]; - snprintf(buffer, sizeof(buffer), "0x%08x", err); - return buffer; -} - -#define KLABEL(x) { x, #x } -#define LASTLABEL { 0, 0 } - -const ConstantToLabel SECURITY_ERRORS[] = { - KLABEL(SEC_I_COMPLETE_AND_CONTINUE), - KLABEL(SEC_I_COMPLETE_NEEDED), - KLABEL(SEC_I_CONTEXT_EXPIRED), - KLABEL(SEC_I_CONTINUE_NEEDED), - KLABEL(SEC_I_INCOMPLETE_CREDENTIALS), - KLABEL(SEC_I_RENEGOTIATE), - KLABEL(SEC_E_CERT_EXPIRED), - KLABEL(SEC_E_INCOMPLETE_MESSAGE), - KLABEL(SEC_E_INSUFFICIENT_MEMORY), - KLABEL(SEC_E_INTERNAL_ERROR), - KLABEL(SEC_E_INVALID_HANDLE), - KLABEL(SEC_E_INVALID_TOKEN), - KLABEL(SEC_E_LOGON_DENIED), - KLABEL(SEC_E_NO_AUTHENTICATING_AUTHORITY), - KLABEL(SEC_E_NO_CREDENTIALS), - KLABEL(SEC_E_NOT_OWNER), - KLABEL(SEC_E_OK), - KLABEL(SEC_E_SECPKG_NOT_FOUND), - KLABEL(SEC_E_TARGET_UNKNOWN), - KLABEL(SEC_E_UNKNOWN_CREDENTIALS), - KLABEL(SEC_E_UNSUPPORTED_FUNCTION), - KLABEL(SEC_E_UNTRUSTED_ROOT), - KLABEL(SEC_E_WRONG_PRINCIPAL), - LASTLABEL -}; -#undef KLABEL -#undef LASTLABEL -#endif // defined(WEBRTC_WIN) -} // namespace +extern const ConstantLabel SECURITY_ERRORS[]; +#endif ////////////////////////////////////////////////////////////////////// // Enum - TODO: expose globally later? @@ -934,7 +865,7 @@ HttpAuthResult HttpAuthenticate( ret = InitializeSecurityContextA(&neg->cred, &neg->ctx, spn, flags, 0, SECURITY_NATIVE_DREP, &in_buf_desc, 0, &neg->ctx, &out_buf_desc, &ret_flags, &lifetime); if (FAILED(ret)) { RTC_LOG(LS_ERROR) << "InitializeSecurityContext returned: " - << GetErrorName(ret, SECURITY_ERRORS); + << ErrorName(ret, SECURITY_ERRORS); return HAR_ERROR; } } else if (neg->specified_credentials) { @@ -1000,7 +931,7 @@ HttpAuthResult HttpAuthenticate( SECPKG_CRED_OUTBOUND, 0, pauth_id, 0, 0, &cred, &lifetime); if (ret != SEC_E_OK) { RTC_LOG(LS_ERROR) << "AcquireCredentialsHandle error: " - << GetErrorName(ret, SECURITY_ERRORS); + << ErrorName(ret, SECURITY_ERRORS); return HAR_IGNORE; } @@ -1010,7 +941,7 @@ HttpAuthResult HttpAuthenticate( ret = InitializeSecurityContextA(&cred, 0, spn, flags, 0, SECURITY_NATIVE_DREP, 0, 0, &ctx, &out_buf_desc, &ret_flags, &lifetime); if (FAILED(ret)) { RTC_LOG(LS_ERROR) << "InitializeSecurityContext returned: " - << GetErrorName(ret, SECURITY_ERRORS); + << ErrorName(ret, SECURITY_ERRORS); FreeCredentialsHandle(&cred); return HAR_IGNORE; } @@ -1024,7 +955,7 @@ HttpAuthResult HttpAuthenticate( if ((ret == SEC_I_COMPLETE_NEEDED) || (ret == SEC_I_COMPLETE_AND_CONTINUE)) { ret = CompleteAuthToken(&neg->ctx, &out_buf_desc); RTC_LOG(LS_VERBOSE) << "CompleteAuthToken returned: " - << GetErrorName(ret, SECURITY_ERRORS); + << ErrorName(ret, SECURITY_ERRORS); if (FAILED(ret)) { return HAR_ERROR; } diff --git a/rtc_base/logging.cc b/rtc_base/logging.cc index 5d071405fc..522468c066 100644 --- a/rtc_base/logging.cc +++ b/rtc_base/logging.cc @@ -29,6 +29,8 @@ static const int kMaxLogLineSize = 1024 - 60; #endif // WEBRTC_MAC && !defined(WEBRTC_IOS) || WEBRTC_ANDROID +static const char kLibjingle[] = "libjingle"; + #include #include @@ -39,7 +41,7 @@ static const int kMaxLogLineSize = 1024 - 60; #include "rtc_base/criticalsection.h" #include "rtc_base/logging.h" -#include "rtc_base/platform_thread_types.h" +#include "rtc_base/platform_thread.h" #include "rtc_base/stringencode.h" #include "rtc_base/stringutils.h" #include "rtc_base/timeutils.h" @@ -69,6 +71,32 @@ const char* FilenameFromPath(const char* file) { CriticalSection g_log_crit; } // namespace +///////////////////////////////////////////////////////////////////////////// +// Constant Labels +///////////////////////////////////////////////////////////////////////////// + +const char* FindLabel(int value, const ConstantLabel entries[]) { + for (int i = 0; entries[i].label; ++i) { + if (value == entries[i].value) { + return entries[i].label; + } + } + return 0; +} + +std::string ErrorName(int err, const ConstantLabel* err_table) { + if (err == 0) + return "No error"; + + if (err_table != 0) { + if (const char* value = FindLabel(err, err_table)) + return value; + } + + char buffer[16]; + snprintf(buffer, sizeof(buffer), "0x%08x", err); + return buffer; +} ///////////////////////////////////////////////////////////////////////////// // LogMessage @@ -89,8 +117,9 @@ LogMessage::LogMessage(const char* file, int line, LoggingSeverity sev, LogErrorContext err_ctx, - int err) - : severity_(sev) { + int err, + const char* module) + : severity_(sev), tag_(kLibjingle) { if (timestamp_) { // Use SystemTimeMillis so that even if tests use fake clocks, the timestamp // in log messages represents the real system time. @@ -121,10 +150,12 @@ LogMessage::LogMessage(const char* file, #ifdef WEBRTC_WIN case ERRCTX_HRESULT: { char msgbuf[256]; - DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS; + DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM; + HMODULE hmod = GetModuleHandleA(module); + if (hmod) + flags |= FORMAT_MESSAGE_FROM_HMODULE; if (DWORD len = FormatMessageA( - flags, nullptr, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + flags, hmod, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), msgbuf, sizeof(msgbuf) / sizeof(msgbuf[0]), nullptr)) { while ((len > 0) && isspace(static_cast(msgbuf[len-1]))) { @@ -149,20 +180,19 @@ LogMessage::LogMessage(const char* file, } } -#if defined(WEBRTC_ANDROID) LogMessage::LogMessage(const char* file, int line, LoggingSeverity sev, - const char* tag) + const std::string& tag) : LogMessage(file, line, sev, ERRCTX_NONE, - 0 /* err */) { + 0 /* err */, + nullptr /* module */) { tag_ = tag; print_stream_ << tag << ": "; } -#endif LogMessage::~LogMessage() { if (!extra_.empty()) @@ -171,11 +201,7 @@ LogMessage::~LogMessage() { const std::string& str = print_stream_.str(); if (severity_ >= g_dbg_sev) { -#if defined(WEBRTC_ANDROID) OutputToDebug(str, severity_, tag_); -#else - OutputToDebug(str, severity_); -#endif } CritScope cs(&g_log_crit); @@ -296,8 +322,19 @@ void LogMessage::ConfigureLogging(const char* params) { // from the command line, we'll see the output there. Otherwise, create // our own console window. // Note: These methods fail if a console already exists, which is fine. - if (!AttachConsole(ATTACH_PARENT_PROCESS)) + bool success = false; + typedef BOOL (WINAPI* PFN_AttachConsole)(DWORD); + if (HINSTANCE kernel32 = ::LoadLibrary(L"kernel32.dll")) { + // AttachConsole is defined on WinXP+. + if (PFN_AttachConsole attach_console = reinterpret_cast + (::GetProcAddress(kernel32, "AttachConsole"))) { + success = (FALSE != attach_console(ATTACH_PARENT_PROCESS)); + } + ::FreeLibrary(kernel32); + } + if (!success) { ::AllocConsole(); + } } #endif // WEBRTC_WIN @@ -313,14 +350,9 @@ void LogMessage::UpdateMinLogSeverity() g_min_sev = min_sev; } -#if defined(WEBRTC_ANDROID) void LogMessage::OutputToDebug(const std::string& str, LoggingSeverity severity, - const char* tag) { -#else -void LogMessage::OutputToDebug(const std::string& str, - LoggingSeverity severity) { -#endif + const std::string& tag) { bool log_to_stderr = log_to_stderr_; #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) && defined(NDEBUG) // On the Mac, all stderr output goes to the Console log and causes clutter. @@ -341,8 +373,7 @@ void LogMessage::OutputToDebug(const std::string& str, if (key != nullptr) { CFRelease(key); } -#endif // defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) && defined(NDEBUG) - +#endif #if defined(WEBRTC_WIN) // Always log to the debugger. // Perhaps stderr should be controlled by a preference, as on Mac? @@ -357,7 +388,6 @@ void LogMessage::OutputToDebug(const std::string& str, } } #endif // WEBRTC_WIN - #if defined(WEBRTC_ANDROID) // Android's logging facility uses severity to log messages but we // need to map libjingle's severity levels to Android ones first. @@ -366,7 +396,7 @@ void LogMessage::OutputToDebug(const std::string& str, int prio; switch (severity) { case LS_SENSITIVE: - __android_log_write(ANDROID_LOG_INFO, tag, "SENSITIVE"); + __android_log_write(ANDROID_LOG_INFO, tag.c_str(), "SENSITIVE"); if (log_to_stderr) { fprintf(stderr, "SENSITIVE"); fflush(stderr); @@ -393,14 +423,15 @@ void LogMessage::OutputToDebug(const std::string& str, int idx = 0; const int max_lines = size / kMaxLogLineSize + 1; if (max_lines == 1) { - __android_log_print(prio, tag, "%.*s", size, str.c_str()); + __android_log_print(prio, tag.c_str(), "%.*s", size, str.c_str()); } else { while (size > 0) { const int len = std::min(size, kMaxLogLineSize); // Use the size of the string in the format (str may have \0 in the // middle). - __android_log_print(prio, tag, "[%d/%d] %.*s", line + 1, max_lines, len, - str.c_str() + idx); + __android_log_print(prio, tag.c_str(), "[%d/%d] %.*s", + line + 1, max_lines, + len, str.c_str() + idx); idx += len; size -= len; ++line; diff --git a/rtc_base/logging.h b/rtc_base/logging.h index d91db9abf5..0865379a4b 100644 --- a/rtc_base/logging.h +++ b/rtc_base/logging.h @@ -26,8 +26,9 @@ // RTC_LOG_F(sev) Like RTC_LOG(), but includes the name of the current function. // RTC_LOG_T(sev) Like RTC_LOG(), but includes the this pointer. // RTC_LOG_T_F(sev) Like RTC_LOG_F(), but includes the this pointer. -// RTC_LOG_GLE(sev [, mod]) attempt to add a string description of the -// HRESULT returned by GetLastError. +// RTC_LOG_GLE(M)(sev [, mod]) attempt to add a string description of the +// HRESULT returned by GetLastError. The "M" variant allows searching of a +// DLL's string table for the error description. // RTC_LOG_ERRNO(sev) attempts to add a string description of an errno-derived // error. errno and associated facilities exist on both Windows and POSIX, // but on Windows they only apply to the C/C++ runtime. @@ -67,6 +68,29 @@ namespace rtc { +/////////////////////////////////////////////////////////////////////////////// +// ConstantLabel can be used to easily generate string names from constant +// values. This can be useful for logging descriptive names of error messages. +// Usage: +// const ConstantLabel LIBRARY_ERRORS[] = { +// KLABEL(SOME_ERROR), +// KLABEL(SOME_OTHER_ERROR), +// ... +// LASTLABEL +// } +// +// int err = LibraryFunc(); +// LOG(LS_ERROR) << "LibraryFunc returned: " +// << ErrorName(err, LIBRARY_ERRORS); + +struct ConstantLabel { int value; const char * label; }; +#define KLABEL(x) { x, #x } +#define TLABEL(x, y) { x, y } +#define LASTLABEL { 0, 0 } + +const char* FindLabel(int value, const ConstantLabel entries[]); +std::string ErrorName(int err, const ConstantLabel* err_table); + #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) // Returns a UTF8 description from an OS X Status error. std::string DescriptionFromOSStatus(OSStatus err); @@ -124,11 +148,13 @@ class LogMessage { int line, LoggingSeverity sev, LogErrorContext err_ctx = ERRCTX_NONE, - int err = 0); + int err = 0, + const char* module = nullptr); -#if defined(WEBRTC_ANDROID) - LogMessage(const char* file, int line, LoggingSeverity sev, const char* tag); -#endif + LogMessage(const char* file, + int line, + LoggingSeverity sev, + const std::string& tag); ~LogMessage(); @@ -187,13 +213,9 @@ class LogMessage { static void UpdateMinLogSeverity(); // These write out the actual log messages. -#if defined(WEBRTC_ANDROID) static void OutputToDebug(const std::string& msg, LoggingSeverity severity, - const char* tag); -#else - static void OutputToDebug(const std::string& msg, LoggingSeverity severity); -#endif + const std::string& tag); // The ostream that buffers the formatted message before output std::ostringstream print_stream_; @@ -201,10 +223,8 @@ class LogMessage { // The severity level of this message LoggingSeverity severity_; -#if defined(WEBRTC_ANDROID) // The Android debug output tag. - const char* tag_ = "libjingle"; -#endif + std::string tag_; // String data generated in the constructor, that should be appended to // the message before output. @@ -293,6 +313,8 @@ inline bool LogCheckLevel(LoggingSeverity sev) { RTC_LOG_E(sev, HRESULT, err) #define RTC_LOG_GLE(sev) \ RTC_LOG_GLE_EX(sev, GetLastError()) +#define RTC_LOG_GLEM(sev, mod) \ + RTC_LOG_E(sev, HRESULT, GetLastError(), mod) #define RTC_LOG_ERR_EX(sev, err) \ RTC_LOG_GLE_EX(sev, err) #define RTC_LOG_ERR(sev) \ @@ -309,11 +331,9 @@ inline bool LogCheckLevel(LoggingSeverity sev) { RTC_LOG_ERRNO(sev) #endif // WEBRTC_WIN -#if defined(WEBRTC_ANDROID) #define RTC_LOG_TAG(sev, tag) \ RTC_LOG_SEVERITY_PRECONDITION(sev) \ rtc::LogMessage(nullptr, 0, sev, tag).stream() -#endif // The RTC_DLOG macros are equivalent to their RTC_LOG counterparts except that // they only generate code in debug builds. diff --git a/rtc_base/socketadapters.cc b/rtc_base/socketadapters.cc index 814f23b290..48e7898d60 100644 --- a/rtc_base/socketadapters.cc +++ b/rtc_base/socketadapters.cc @@ -16,6 +16,7 @@ #include #if defined(WEBRTC_WIN) +#define WIN32_LEAN_AND_MEAN #include #include #include diff --git a/rtc_base/win32securityerrors.cc b/rtc_base/win32securityerrors.cc new file mode 100644 index 0000000000..2f8530a6bc --- /dev/null +++ b/rtc_base/win32securityerrors.cc @@ -0,0 +1,49 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rtc_base/logging.h" +#include "rtc_base/win32.h" + +namespace rtc { + +/////////////////////////////////////////////////////////////////////////////// + +extern const ConstantLabel SECURITY_ERRORS[]; + +const ConstantLabel SECURITY_ERRORS[] = { + KLABEL(SEC_I_COMPLETE_AND_CONTINUE), + KLABEL(SEC_I_COMPLETE_NEEDED), + KLABEL(SEC_I_CONTEXT_EXPIRED), + KLABEL(SEC_I_CONTINUE_NEEDED), + KLABEL(SEC_I_INCOMPLETE_CREDENTIALS), + KLABEL(SEC_I_RENEGOTIATE), + KLABEL(SEC_E_CERT_EXPIRED), + KLABEL(SEC_E_INCOMPLETE_MESSAGE), + KLABEL(SEC_E_INSUFFICIENT_MEMORY), + KLABEL(SEC_E_INTERNAL_ERROR), + KLABEL(SEC_E_INVALID_HANDLE), + KLABEL(SEC_E_INVALID_TOKEN), + KLABEL(SEC_E_LOGON_DENIED), + KLABEL(SEC_E_NO_AUTHENTICATING_AUTHORITY), + KLABEL(SEC_E_NO_CREDENTIALS), + KLABEL(SEC_E_NOT_OWNER), + KLABEL(SEC_E_OK), + KLABEL(SEC_E_SECPKG_NOT_FOUND), + KLABEL(SEC_E_TARGET_UNKNOWN), + KLABEL(SEC_E_UNKNOWN_CREDENTIALS), + KLABEL(SEC_E_UNSUPPORTED_FUNCTION), + KLABEL(SEC_E_UNTRUSTED_ROOT), + KLABEL(SEC_E_WRONG_PRINCIPAL), + LASTLABEL +}; + +/////////////////////////////////////////////////////////////////////////////// + +} // namespace rtc diff --git a/sdk/android/src/jni/pc/logging.cc b/sdk/android/src/jni/pc/logging.cc index 4fb8215b1e..48d400081c 100644 --- a/sdk/android/src/jni/pc/logging.cc +++ b/sdk/android/src/jni/pc/logging.cc @@ -51,8 +51,7 @@ JNI_FUNCTION_DECLARATION(void, jstring j_message) { std::string message = JavaToStdString(jni, JavaParamRef(j_message)); std::string tag = JavaToStdString(jni, JavaParamRef(j_tag)); - RTC_LOG_TAG(static_cast(j_severity), tag.c_str()) - << message; + RTC_LOG_TAG(static_cast(j_severity), tag) << message; } } // namespace jni