115 lines
3.3 KiB
C++
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);
|
|
}
|
|
}
|