Skip to content

Windows: add Swift installer custom action #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright © 2021 Saleem Abdulrasool <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause

#ifndef SWIFT_INSTALLER_HEADERS_LOGGING_HH
#define SWIFT_INSTALLER_HEADERS_LOGGING_HH

#define WIN32_LEAN_AND_MEAN
#define VC_EXTRA_LEAN
#define NOMINMAX
#include <Windows.h>
#include <MsiQuery.h>
#include <Msi.h>

#include <string>
#include <sstream>

namespace msi::logging {
enum class severity {
info, /// INSTALLMESSAGE_INFO
warning, /// INSTALLMESSAGE_WARNING
error, /// INSTALLMESSAGE_ERROR
fatal, /// INSTALLMESSAGE_FATALEXIT
};

class log_message {
MSIHANDLE install_;
const severity severity_;
const char *file_;
const unsigned line_;
std::ostringstream stream_;

template <typename Value_>
friend log_message &operator<<(log_message &, const Value_ &) noexcept;

public:
log_message(MSIHANDLE install, severity severity,
const char *file, unsigned line);
~log_message();

log_message(const log_message &) = delete;
log_message &operator=(const log_message &) = delete;

std::string str() { return stream_.str(); }
severity severity() const { return severity_; }
};

template <typename Value_>
log_message &operator<<(log_message &message, const Value_ &value) noexcept {
message.stream_ << value;
return message;
}

extern template
log_message &operator<<<std::wstring>(log_message &,
const std::wstring &) noexcept;
}

#define LOG(Install,Severity) \
msi::logging::log_message(Install, msi::logging::severity::##Severity, \
__FILE__, __LINE__)

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright © 2021 Saleem Abdulrasool <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause

#ifndef SWIFT_INSTALLER_HEADERS_SCOPED_RAII_HH
#define SWIFT_INSTALLER_HEADERS_SCOPED_RAII_HH

#define WIN32_LEAN_AND_MEAN
#define VC_EXTRA_LEAN
#define NOMINMAX
#include <Windows.h>
#include <objbase.h>

namespace windows {
namespace raii {
class hkey {
HKEY hKey_;

public:
explicit hkey(HKEY hKey) noexcept : hKey_(hKey) {}

// TODO(compnerd) log failure
~hkey() noexcept { (void)RegCloseKey(hKey_); }
};

class com_initializer {
HRESULT hr_;

public:
enum threading_model { multithreaded };

explicit com_initializer() {
hr_ = ::CoInitializeEx(nullptr,
COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
}

explicit com_initializer(threading_model) {
hr_ = ::CoInitializeEx(nullptr,
COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
}

~com_initializer() {
if (SUCCEEDED(hr_))
::CoUninitialize();
}

bool succeeded() const { return SUCCEEDED(hr_); }
};
}
}

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright © 2021 Saleem Abdulrasool <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause

#ifndef SWIFT_INSTALLER_HEADERS_SWIFT_INSTALLER_HH
#define SWIFT_INSTALLER_HEADERS_SWIFT_INSTALLER_HH

#define WIN32_LEAN_AND_MEAN
#define VC_EXTRA_LEAN
#define NOMINMAX
#include <Windows.h>
#include <msi.h>

#if defined(_WINDLL)
# if defined(SwiftInstaller_EXPORTS)
# define SWIFT_INSTALLER_API __declspec(dllexport)
# else
# define SWIFT_INSTALLER_API __declspec(dllimport)
# endif
#else
# define SWIFT_INSTALLER_API
#endif

#if defined(__cplusplus)
extern "C" {
#endif

UINT SWIFT_INSTALLER_API
SwiftInstaller_InstallAuxiliaryFiles(MSIHANDLE hInstall);

#if defined(__cplusplus)
}
#endif

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright © 2021 Saleem Abdulrasool <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause

#define WIN32_LEAN_AND_MEAN
#define VC_EXTRA_LEAN
#define NOMINMAX
#include <Windows.h>

extern "C" BOOL APIENTRY
DllMain(HANDLE hModule, DWORD ulReason, LPVOID lpReserved) {
switch (ulReason) {
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
}

return TRUE;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright © 2021 Saleem Abdulrasool <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause

#include "logging.hh"

#include <cassert>
#include <codecvt>
#include <iomanip>
#include <string>
#include <vector>

namespace {
std::string to_string(const msi::logging::severity &severity) {
switch (severity) {
case msi::logging::severity::info: return "INFO";
case msi::logging::severity::warning: return "WARN";
case msi::logging::severity::error: return "ERROR";
case msi::logging::severity::fatal: return "FATAL";
}
__assume(false);
}
}

namespace msi::logging {
log_message::log_message(MSIHANDLE install, msi::logging::severity severity,
const char *file, unsigned line)
: install_(install), severity_(severity), file_(file), line_(line) {
std::string_view filename(file);

auto separator = filename.find_last_of("\\/");
if (separator != std::string_view::npos)
filename.remove_prefix(separator + 1);

SYSTEMTIME time;
GetLocalTime(&time);

stream_ << "[\\[]"
// TODO(compnerd) should we size the pid and tid?
<< GetCurrentProcessId() << ':' << GetCurrentThreadId() << ':'
<< std::setfill('0')
<< std::setw(2) << time.wMonth
<< std::setw(2) << time.wDay
<< '/'
<< std::setw(2) << time.wHour
<< std::setw(2) << time.wMinute
<< std::setw(2) << time.wSecond
<< '.'
<< std::setw(3) << time.wMilliseconds
<< ':'
<< to_string(severity_)
<< ':' << filename << '(' << line << ')'
<< "[\\]]" << ' ';
}

log_message::~log_message() {
std::string message = stream_.str();

PMSIHANDLE record;
record = MsiCreateRecord(0);
(void)MsiRecordSetStringA(record, 0, message.c_str());
(void)MsiProcessMessage(install_, INSTALLMESSAGE_INFO, record);
}

template <>
log_message &operator<<<std::wstring>(log_message &message,
const std::wstring &str) noexcept {
std::wstring_convert<std::codecvt_utf8<std::wstring::traits_type::char_type>,
std::wstring::traits_type::char_type> utf8;
message.stream_ << utf8.to_bytes(str.data(), str.data() + str.size());
return message;
}
}
Loading