Skip to content

Commit 9167716

Browse files
committed
Windows: add Swift installer custom action
This adds the custom action that is needed for the Swift Installer. This is responsible for automating the deployment of the support files for the Windows SDK and Visual C++ SDK.
1 parent 9854e21 commit 9167716

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)