Skip to content

Commit 9e2c19f

Browse files
authored
Merge pull request #1 from compnerd/Windows-CustomActions
Windows: add Swift installer custom action
2 parents 9854e21 + 9167716 commit 9e2c19f

File tree

9 files changed

+1865
-0
lines changed

9 files changed

+1865
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright © 2021 Saleem Abdulrasool <[email protected]>
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
4+
#ifndef SWIFT_INSTALLER_HEADERS_LOGGING_HH
5+
#define SWIFT_INSTALLER_HEADERS_LOGGING_HH
6+
7+
#define WIN32_LEAN_AND_MEAN
8+
#define VC_EXTRA_LEAN
9+
#define NOMINMAX
10+
#include <Windows.h>
11+
#include <MsiQuery.h>
12+
#include <Msi.h>
13+
14+
#include <string>
15+
#include <sstream>
16+
17+
namespace msi::logging {
18+
enum class severity {
19+
info, /// INSTALLMESSAGE_INFO
20+
warning, /// INSTALLMESSAGE_WARNING
21+
error, /// INSTALLMESSAGE_ERROR
22+
fatal, /// INSTALLMESSAGE_FATALEXIT
23+
};
24+
25+
class log_message {
26+
MSIHANDLE install_;
27+
const severity severity_;
28+
const char *file_;
29+
const unsigned line_;
30+
std::ostringstream stream_;
31+
32+
template <typename Value_>
33+
friend log_message &operator<<(log_message &, const Value_ &) noexcept;
34+
35+
public:
36+
log_message(MSIHANDLE install, severity severity,
37+
const char *file, unsigned line);
38+
~log_message();
39+
40+
log_message(const log_message &) = delete;
41+
log_message &operator=(const log_message &) = delete;
42+
43+
std::string str() { return stream_.str(); }
44+
severity severity() const { return severity_; }
45+
};
46+
47+
template <typename Value_>
48+
log_message &operator<<(log_message &message, const Value_ &value) noexcept {
49+
message.stream_ << value;
50+
return message;
51+
}
52+
53+
extern template
54+
log_message &operator<<<std::wstring>(log_message &,
55+
const std::wstring &) noexcept;
56+
}
57+
58+
#define LOG(Install,Severity) \
59+
msi::logging::log_message(Install, msi::logging::severity::##Severity, \
60+
__FILE__, __LINE__)
61+
62+
#endif
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright © 2021 Saleem Abdulrasool <[email protected]>
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
4+
#ifndef SWIFT_INSTALLER_HEADERS_SCOPED_RAII_HH
5+
#define SWIFT_INSTALLER_HEADERS_SCOPED_RAII_HH
6+
7+
#define WIN32_LEAN_AND_MEAN
8+
#define VC_EXTRA_LEAN
9+
#define NOMINMAX
10+
#include <Windows.h>
11+
#include <objbase.h>
12+
13+
namespace windows {
14+
namespace raii {
15+
class hkey {
16+
HKEY hKey_;
17+
18+
public:
19+
explicit hkey(HKEY hKey) noexcept : hKey_(hKey) {}
20+
21+
// TODO(compnerd) log failure
22+
~hkey() noexcept { (void)RegCloseKey(hKey_); }
23+
};
24+
25+
class com_initializer {
26+
HRESULT hr_;
27+
28+
public:
29+
enum threading_model { multithreaded };
30+
31+
explicit com_initializer() {
32+
hr_ = ::CoInitializeEx(nullptr,
33+
COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
34+
}
35+
36+
explicit com_initializer(threading_model) {
37+
hr_ = ::CoInitializeEx(nullptr,
38+
COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
39+
}
40+
41+
~com_initializer() {
42+
if (SUCCEEDED(hr_))
43+
::CoUninitialize();
44+
}
45+
46+
bool succeeded() const { return SUCCEEDED(hr_); }
47+
};
48+
}
49+
}
50+
51+
#endif
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright © 2021 Saleem Abdulrasool <[email protected]>
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
4+
#ifndef SWIFT_INSTALLER_HEADERS_SWIFT_INSTALLER_HH
5+
#define SWIFT_INSTALLER_HEADERS_SWIFT_INSTALLER_HH
6+
7+
#define WIN32_LEAN_AND_MEAN
8+
#define VC_EXTRA_LEAN
9+
#define NOMINMAX
10+
#include <Windows.h>
11+
#include <msi.h>
12+
13+
#if defined(_WINDLL)
14+
# if defined(SwiftInstaller_EXPORTS)
15+
# define SWIFT_INSTALLER_API __declspec(dllexport)
16+
# else
17+
# define SWIFT_INSTALLER_API __declspec(dllimport)
18+
# endif
19+
#else
20+
# define SWIFT_INSTALLER_API
21+
#endif
22+
23+
#if defined(__cplusplus)
24+
extern "C" {
25+
#endif
26+
27+
UINT SWIFT_INSTALLER_API
28+
SwiftInstaller_InstallAuxiliaryFiles(MSIHANDLE hInstall);
29+
30+
#if defined(__cplusplus)
31+
}
32+
#endif
33+
34+
#endif
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright © 2021 Saleem Abdulrasool <[email protected]>
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
4+
#define WIN32_LEAN_AND_MEAN
5+
#define VC_EXTRA_LEAN
6+
#define NOMINMAX
7+
#include <Windows.h>
8+
9+
extern "C" BOOL APIENTRY
10+
DllMain(HANDLE hModule, DWORD ulReason, LPVOID lpReserved) {
11+
switch (ulReason) {
12+
case DLL_PROCESS_ATTACH:
13+
break;
14+
case DLL_PROCESS_DETACH:
15+
break;
16+
}
17+
18+
return TRUE;
19+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright © 2021 Saleem Abdulrasool <[email protected]>
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
4+
#include "logging.hh"
5+
6+
#include <cassert>
7+
#include <codecvt>
8+
#include <iomanip>
9+
#include <string>
10+
#include <vector>
11+
12+
namespace {
13+
std::string to_string(const msi::logging::severity &severity) {
14+
switch (severity) {
15+
case msi::logging::severity::info: return "INFO";
16+
case msi::logging::severity::warning: return "WARN";
17+
case msi::logging::severity::error: return "ERROR";
18+
case msi::logging::severity::fatal: return "FATAL";
19+
}
20+
__assume(false);
21+
}
22+
}
23+
24+
namespace msi::logging {
25+
log_message::log_message(MSIHANDLE install, msi::logging::severity severity,
26+
const char *file, unsigned line)
27+
: install_(install), severity_(severity), file_(file), line_(line) {
28+
std::string_view filename(file);
29+
30+
auto separator = filename.find_last_of("\\/");
31+
if (separator != std::string_view::npos)
32+
filename.remove_prefix(separator + 1);
33+
34+
SYSTEMTIME time;
35+
GetLocalTime(&time);
36+
37+
stream_ << "[\\[]"
38+
// TODO(compnerd) should we size the pid and tid?
39+
<< GetCurrentProcessId() << ':' << GetCurrentThreadId() << ':'
40+
<< std::setfill('0')
41+
<< std::setw(2) << time.wMonth
42+
<< std::setw(2) << time.wDay
43+
<< '/'
44+
<< std::setw(2) << time.wHour
45+
<< std::setw(2) << time.wMinute
46+
<< std::setw(2) << time.wSecond
47+
<< '.'
48+
<< std::setw(3) << time.wMilliseconds
49+
<< ':'
50+
<< to_string(severity_)
51+
<< ':' << filename << '(' << line << ')'
52+
<< "[\\]]" << ' ';
53+
}
54+
55+
log_message::~log_message() {
56+
std::string message = stream_.str();
57+
58+
PMSIHANDLE record;
59+
record = MsiCreateRecord(0);
60+
(void)MsiRecordSetStringA(record, 0, message.c_str());
61+
(void)MsiProcessMessage(install_, INSTALLMESSAGE_INFO, record);
62+
}
63+
64+
template <>
65+
log_message &operator<<<std::wstring>(log_message &message,
66+
const std::wstring &str) noexcept {
67+
std::wstring_convert<std::codecvt_utf8<std::wstring::traits_type::char_type>,
68+
std::wstring::traits_type::char_type> utf8;
69+
message.stream_ << utf8.to_bytes(str.data(), str.data() + str.size());
70+
return message;
71+
}
72+
}

0 commit comments

Comments
 (0)