ch::current_zone(), ch::floor<ch::milliseconds>(ch::system_clock::now())
};
- if (enabled_ && logFile_.is_open()) {
- const auto logMsg = FormatLogMessage(lm, true);
- logFile_.write(logMsg.c_str(), logMsg.length());
- logFile_.flush();
+ {
+ // logMutex_ also guards logFile_, which EnableLogFile can close
+ // concurrently from another thread.
+ const std::scoped_lock<std::mutex> lock(logMutex_);
+ if (enabled_ && logFile_.is_open()) {
+ const auto logMsg = FormatLogMessage(lm, true);
+ logFile_.write(logMsg.c_str(), logMsg.length());
+ logFile_.flush();
+ }
}
{
va_list ap;
va_start(ap, fmt);
- vswprintf_s(buf, fmt, ap);
+ // _TRUNCATE: oversized messages (e.g. containing long external strings)
+ // must be cut short, not trip the invalid-parameter handler.
+ _vsnwprintf_s(buf, ARRAY_SIZE(buf), _TRUNCATE, fmt, ap);
StoreMessage(LogLevel::Debug, buf);
va_end(ap);
va_list ap;
va_start(ap, fmt);
- vswprintf_s(buf, fmt, ap);
+ _vsnwprintf_s(buf, ARRAY_SIZE(buf), _TRUNCATE, fmt, ap);
StoreMessage(LogLevel::Info, buf);
va_end(ap);
va_list ap;
va_start(ap, fmt);
- vswprintf_s(buf, fmt, ap);
+ _vsnwprintf_s(buf, ARRAY_SIZE(buf), _TRUNCATE, fmt, ap);
StoreMessage(LogLevel::Warning, buf);
va_end(ap);
va_list ap;
va_start(ap, fmt);
- vswprintf_s(buf, fmt, ap);
+ _vsnwprintf_s(buf, ARRAY_SIZE(buf), _TRUNCATE, fmt, ap);
StoreMessage(LogLevel::Error, buf);
va_end(ap);
return;
}
const std::wstring errorMsgText{ reinterpret_cast<wchar_t *>(lpMsgBuf) };
- const std::wstring errorMsg = std::vformat(
+ const std::wstring errorMsg = SafeVFormat(
WMi18n::GetInstance().GetTranslationW("general.error.winapi.text"),
- std::make_wformat_args(
- functionName,
- lastError,
- errorMsgText));
- StoreMessage(LogLevel::Error, static_cast<const wchar_t *>(lpMsgBuf));
+ functionName,
+ lastError,
+ errorMsgText);
+ StoreMessage(LogLevel::Error, errorMsg.c_str());
LocalFree(lpMsgBuf);
}