diff --git a/msix/ubuntu-pro-agent-launcher/console.cpp b/msix/ubuntu-pro-agent-launcher/console.cpp index a573a03e6..6c8287e2b 100644 --- a/msix/ubuntu-pro-agent-launcher/console.cpp +++ b/msix/ubuntu-pro-agent-launcher/console.cpp @@ -90,7 +90,7 @@ Process PseudoConsole::StartProcess(std::wstring commandLine) { si.StartupInfo.dwFlags = STARTF_USESTDHANDLES; si.lpAttributeList = attributes.get(); - Process p{0}; + Process p{}; if (!CreateProcessW(NULL, commandLine.data(), NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &si.StartupInfo, &p)) { @@ -133,7 +133,7 @@ int EventLoop::Run() { DispatchMessage(&msg); } else { // invoke the listener subscribed to the handle that was signaled. - if (auto done = listeners_[signaledIndex](handles_[signaledIndex]); + if (auto done = listeners_.at(signaledIndex)(handles_.at(signaledIndex)); done.has_value()) { return done.value(); } diff --git a/msix/ubuntu-pro-agent-launcher/console.hpp b/msix/ubuntu-pro-agent-launcher/console.hpp index 8af931d17..36ee0f457 100644 --- a/msix/ubuntu-pro-agent-launcher/console.hpp +++ b/msix/ubuntu-pro-agent-launcher/console.hpp @@ -5,13 +5,32 @@ #include #include #include +#include #include +#include namespace up4w { // An RAII wrapper around the PROCESS_INFORMATION structure to ease preventing // HANDLE leaks. struct Process : PROCESS_INFORMATION { - ~Process() { + Process(Process const& other) = delete; + Process& operator=(Process const& other) = delete; + Process(Process&& other) noexcept { *this = std::move(other); } + Process& operator=(Process&& other) noexcept { + hProcess = std::exchange(other.hProcess, nullptr); + hThread = std::exchange(other.hThread, nullptr); + dwProcessId = std::exchange(other.dwProcessId, 0); + dwThreadId = std::exchange(other.dwThreadId, 0); + return *this; + } + Process() noexcept { + hProcess = nullptr; + hThread = nullptr; + dwProcessId = 0; + dwThreadId = 0; + } + + ~Process() noexcept { if (hThread != nullptr && hThread != INVALID_HANDLE_VALUE) { CloseHandle(hThread); } diff --git a/msix/ubuntu-pro-agent-launcher/error.cpp b/msix/ubuntu-pro-agent-launcher/error.cpp index c040ecc94..fcc312c60 100644 --- a/msix/ubuntu-pro-agent-launcher/error.cpp +++ b/msix/ubuntu-pro-agent-launcher/error.cpp @@ -3,8 +3,8 @@ #include namespace up4w { -std::wstring MakePathRelativeToEnvDir(std::wstring_view destination, - std::wstring_view envDir) { +std::wstring UnderLocalAppDataPath(std::wstring_view destination) { + std::wstring_view localAppData = L"LOCALAPPDATA"; std::wstring resultPath{}; resultPath.resize(MAX_PATH); @@ -12,11 +12,15 @@ std::wstring MakePathRelativeToEnvDir(std::wstring_view destination, static_cast(resultPath.capacity() - destination.size() - 1); auto length = - GetEnvironmentVariable(envDir.data(), resultPath.data(), truncatedLength); + GetEnvironmentVariable(localAppData.data(), resultPath.data(), truncatedLength); if (length == 0) { return {}; } + if (length > truncatedLength) { + throw hresult_exception{CO_E_PATHTOOLONG}; + } + resultPath.insert(length, destination.data()); return resultPath; } @@ -26,7 +30,7 @@ void LogSingleShot(std::filesystem::path const& logFilePath, auto const time = std::chrono::current_zone()->to_local(std::chrono::system_clock::now()); - std::ofstream logfile{logFilePath}; + std::ofstream logfile{logFilePath, std::ios::app}; logfile << std::format("{:%Y-%m-%d %T}: {}\n", time, message); } diff --git a/msix/ubuntu-pro-agent-launcher/error.hpp b/msix/ubuntu-pro-agent-launcher/error.hpp index 0693b3d0a..a818ec93f 100644 --- a/msix/ubuntu-pro-agent-launcher/error.hpp +++ b/msix/ubuntu-pro-agent-launcher/error.hpp @@ -54,10 +54,9 @@ class hresult_exception { }; /// Computes the absolute path resulting of joining the [destination] into the -/// value of the environment variable [envDir]. Returns empty string if the +/// value of the environment variable [LOCALAPPDATA]. Returns empty string if the /// environment variable is undefined. -std::wstring MakePathRelativeToEnvDir(std::wstring_view destination, - std::wstring_view envDir); +std::wstring UnderLocalAppDataPath(std::wstring_view destination); // Opens the log file, writes the message with a timestamp and closes it. void LogSingleShot(std::filesystem::path const& logFilePath, diff --git a/msix/ubuntu-pro-agent-launcher/main.cpp b/msix/ubuntu-pro-agent-launcher/main.cpp index 29974d345..884dd870c 100644 --- a/msix/ubuntu-pro-agent-launcher/main.cpp +++ b/msix/ubuntu-pro-agent-launcher/main.cpp @@ -12,9 +12,8 @@ #include "error.hpp" std::filesystem::path const& logPath() { - static std::filesystem::path localAppDataPath = - up4w::MakePathRelativeToEnvDir( - L"\\Ubuntu Pro\\ubuntu-pro-agent-launcher.log", L"LOCALAPPDATA"); + static std::filesystem::path localAppDataPath = up4w::UnderLocalAppDataPath( + L"\\Ubuntu Pro\\ubuntu-pro-agent-launcher.log"); return localAppDataPath; } @@ -80,4 +79,12 @@ int WINAPI wWinMain(HINSTANCE, HINSTANCE, PWSTR pCmdLine, int) try { up4w::LogSingleShot(localAppDataPath, err.what()); return 3; +} catch (...) { + std::filesystem::path const& localAppDataPath = logPath(); + if (localAppDataPath.empty()) { + return 1; + } + + up4w::LogSingleShot(localAppDataPath, "An unknown exception was thrown.\n"); + return 4; }