mirror of
https://github.com/gabime/spdlog.git
synced 2024-12-26 10:31:34 +08:00
Optimize win_eventlog to avoid string allocation
This commit is contained in:
parent
fccee959b1
commit
640921cd3f
@ -37,6 +37,7 @@ Windows Registry Editor Version 5.00
|
|||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
namespace sinks {
|
namespace sinks {
|
||||||
@ -55,7 +56,7 @@ struct win32_error : public spdlog_ex
|
|||||||
std::string system_message;
|
std::string system_message;
|
||||||
|
|
||||||
LPSTR format_message_result {};
|
LPSTR format_message_result {};
|
||||||
auto format_message_succeeded = FormatMessage(
|
auto format_message_succeeded = ::FormatMessage(
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
|
||||||
error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &format_message_result, 0, nullptr);
|
error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &format_message_result, 0, nullptr);
|
||||||
|
|
||||||
@ -65,7 +66,9 @@ struct win32_error : public spdlog_ex
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (format_message_result)
|
if (format_message_result)
|
||||||
|
{
|
||||||
LocalFree((HLOCAL)format_message_result);
|
LocalFree((HLOCAL)format_message_result);
|
||||||
|
}
|
||||||
|
|
||||||
return fmt::format("{}: {}{}", user_message, error_code, system_message);
|
return fmt::format("{}: {}{}", user_message, error_code, system_message);
|
||||||
}
|
}
|
||||||
@ -87,15 +90,19 @@ public:
|
|||||||
/** creates a wrapped SID copy */
|
/** creates a wrapped SID copy */
|
||||||
static sid_t duplicate_sid(PSID psid)
|
static sid_t duplicate_sid(PSID psid)
|
||||||
{
|
{
|
||||||
if (!IsValidSid(psid))
|
if (!::IsValidSid(psid))
|
||||||
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("sid_t::sid_t(): invalid SID received"));
|
SPDLOG_THROW(spdlog_ex("sid_t::sid_t(): invalid SID received"));
|
||||||
|
}
|
||||||
|
|
||||||
auto const sid_length {::GetLengthSid(psid)};
|
auto const sid_length {::GetLengthSid(psid)};
|
||||||
|
|
||||||
sid_t result;
|
sid_t result;
|
||||||
result.buffer_.resize(sid_length);
|
result.buffer_.resize(sid_length);
|
||||||
if (!CopySid(sid_length, (PSID) result.as_sid(), psid))
|
if (!::CopySid(sid_length, (PSID)result.as_sid(), psid))
|
||||||
|
{
|
||||||
SPDLOG_THROW(win32_error("CopySid"));
|
SPDLOG_THROW(win32_error("CopySid"));
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -112,34 +119,36 @@ public:
|
|||||||
/* create and init RAII holder for process token */
|
/* create and init RAII holder for process token */
|
||||||
struct process_token_t
|
struct process_token_t
|
||||||
{
|
{
|
||||||
HANDLE hToken_;
|
HANDLE token_handle_= INVALID_HANDLE_VALUE;
|
||||||
bool hasToken_;
|
explicit process_token_t(HANDLE process)
|
||||||
|
{
|
||||||
process_token_t(HANDLE process)
|
if (!::OpenProcessToken(process, TOKEN_QUERY, &token_handle_))
|
||||||
: hToken_(0)
|
|
||||||
, hasToken_(OpenProcessToken(process, TOKEN_QUERY, &hToken_))
|
|
||||||
{
|
{
|
||||||
if (!hasToken_)
|
|
||||||
SPDLOG_THROW(win32_error("OpenProcessToken"));
|
SPDLOG_THROW(win32_error("OpenProcessToken"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
~process_token_t()
|
~process_token_t()
|
||||||
{
|
{
|
||||||
if (hasToken_)
|
::CloseHandle(token_handle_);
|
||||||
CloseHandle(hToken_);
|
|
||||||
}
|
}
|
||||||
} current_process_token(GetCurrentProcess()); // GetCurrentProcess returns pseudohandle, no leak here!
|
|
||||||
|
} current_process_token(::GetCurrentProcess()); // GetCurrentProcess returns pseudohandle, no leak here!
|
||||||
|
|
||||||
// Get the required size, this is expected to fail with ERROR_INSUFFICIENT_BUFFER and return the token size
|
// Get the required size, this is expected to fail with ERROR_INSUFFICIENT_BUFFER and return the token size
|
||||||
DWORD tusize = 0;
|
DWORD tusize = 0;
|
||||||
GetTokenInformation(current_process_token.hToken_, TokenUser, NULL, 0, &tusize);
|
::GetTokenInformation(current_process_token.token_handle_, TokenUser, NULL, 0, &tusize);
|
||||||
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||||
|
{
|
||||||
SPDLOG_THROW(win32_error("GetTokenInformation"));
|
SPDLOG_THROW(win32_error("GetTokenInformation"));
|
||||||
|
}
|
||||||
|
|
||||||
// get user token
|
// get user token
|
||||||
std::vector<unsigned char> buffer(tusize);
|
std::vector<unsigned char> buffer(static_cast<size_t>(tusize));
|
||||||
if (!GetTokenInformation(current_process_token.hToken_, TokenUser, (LPVOID) buffer.data(), tusize, &tusize))
|
if (!GetTokenInformation(current_process_token.token_handle_, TokenUser, (LPVOID)buffer.data(), tusize, &tusize))
|
||||||
|
{
|
||||||
SPDLOG_THROW(win32_error("GetTokenInformation"));
|
SPDLOG_THROW(win32_error("GetTokenInformation"));
|
||||||
|
}
|
||||||
|
|
||||||
// create a wrapper of the SID data as stored in the user token
|
// create a wrapper of the SID data as stored in the user token
|
||||||
return sid_t::duplicate_sid(((TOKEN_USER*) buffer.data())->User.Sid);
|
return sid_t::duplicate_sid(((TOKEN_USER*) buffer.data())->User.Sid);
|
||||||
@ -213,9 +222,8 @@ protected:
|
|||||||
|
|
||||||
memory_buf_t formatted;
|
memory_buf_t formatted;
|
||||||
formatter_->format(msg, formatted);
|
formatter_->format(msg, formatted);
|
||||||
|
formatted.push_back('\0');
|
||||||
auto formatted_string = fmt::to_string(formatted);
|
LPCSTR lp_str = static_cast<LPCSTR>(formatted.data());
|
||||||
auto formatted_string_lpsz = formatted_string.c_str();
|
|
||||||
|
|
||||||
bool succeeded = ReportEvent(
|
bool succeeded = ReportEvent(
|
||||||
event_log_handle(),
|
event_log_handle(),
|
||||||
@ -225,7 +233,7 @@ protected:
|
|||||||
current_user_sid_.as_sid(),
|
current_user_sid_.as_sid(),
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
&formatted_string_lpsz,
|
&lp_str,
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
||||||
if (!succeeded)
|
if (!succeeded)
|
||||||
|
Loading…
Reference in New Issue
Block a user