Files
2026-08-09 13:27:53 +02:00

115 lines
3.3 KiB
C++

#include "Logging.h"
#include <windows.h>
#include <string>
#include <vector>
#include <iterator>
#include <cwchar>
namespace
{
std::wstring GetLogDirectory()
{
wchar_t localAppData[32768]{};
DWORD len = GetEnvironmentVariableW(L"LOCALAPPDATA", localAppData, static_cast<DWORD>(std::size(localAppData)));
if (len == 0 || len >= std::size(localAppData))
{
return {};
}
std::wstring base(localAppData);
std::wstring plandent = base + L"\\Plandent";
std::wstring hookDir = plandent + L"\\MstscScriptHook";
CreateDirectoryW(plandent.c_str(), nullptr);
CreateDirectoryW(hookDir.c_str(), nullptr);
return hookDir;
}
std::string ToUtf8(const std::wstring& value)
{
if (value.empty())
{
return {};
}
int needed = WideCharToMultiByte(CP_UTF8, 0, value.data(), static_cast<int>(value.size()), nullptr, 0, nullptr, nullptr);
if (needed <= 0)
{
return {};
}
std::string result(static_cast<size_t>(needed), '\0');
WideCharToMultiByte(CP_UTF8, 0, value.data(), static_cast<int>(value.size()), result.data(), needed, nullptr, nullptr);
return result;
}
}
namespace hook
{
std::wstring FormatWin32Error(unsigned long errorCode)
{
wchar_t* buffer = nullptr;
DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
DWORD length = FormatMessageW(flags, nullptr, errorCode, 0, reinterpret_cast<wchar_t*>(&buffer), 0, nullptr);
if (length == 0 || buffer == nullptr)
{
return L"Win32-Fehler " + std::to_wstring(errorCode);
}
std::wstring result(buffer, length);
LocalFree(buffer);
while (!result.empty() && (result.back() == L'\r' || result.back() == L'\n' || result.back() == L' '))
{
result.pop_back();
}
return result;
}
void Log(bool enabled, const std::wstring& message)
{
if (!enabled)
{
return;
}
std::wstring directory = GetLogDirectory();
if (directory.empty())
{
return;
}
SYSTEMTIME st{};
GetLocalTime(&st);
wchar_t prefix[128]{};
swprintf_s(prefix, std::size(prefix), L"%04u-%02u-%02u %02u:%02u:%02u.%03u [PID:%lu TID:%lu] ",
st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
GetCurrentProcessId(), GetCurrentThreadId());
std::wstring fullLine = std::wstring(prefix) + message + L"\r\n";
std::string utf8 = ToUtf8(fullLine);
if (utf8.empty())
{
return;
}
std::wstring logPath = directory + L"\\plugin.log";
HANDLE file = CreateFileW(
logPath.c_str(),
FILE_APPEND_DATA,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
nullptr,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
nullptr);
if (file == INVALID_HANDLE_VALUE)
{
return;
}
DWORD written = 0;
WriteFile(file, utf8.data(), static_cast<DWORD>(utf8.size()), &written, nullptr);
CloseHandle(file);
}
}