1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <sal/config.h>
18 #define WIN32_LEAN_AND_MEAN
24 // Replacements for functions used in
25 // workdir/UnpackedTarball/onlineupdate/onlineupdate/source/update/common/pathhash.cpp but not
28 extern "C" wchar_t* _wcslwr(wchar_t* str
)
30 for (auto p
= str
; *p
!= L
'\0'; ++p
)
32 if (*p
>= L
'A' && *p
<= L
'Z')
40 extern "C" wchar_t* wcsncpy(wchar_t* strDest
, wchar_t const* strSource
, std::size_t count
)
42 for (std::size_t i
= 0; i
!= count
; ++i
)
44 strDest
[i
] = *strSource
;
45 if (*strSource
!= L
'\0')
55 bool getProperty(MSIHANDLE handle
, wchar_t const* name
, std::wstring
* value
)
58 if (MsiGetPropertyW(handle
, name
, const_cast<wchar_t*>(L
""), &n
) != ERROR_MORE_DATA
59 || n
== std::numeric_limits
<DWORD
>::max())
64 auto buf
= std::make_unique
<wchar_t[]>(n
);
65 if (MsiGetPropertyW(handle
, name
, buf
.get(), &n
) != ERROR_SUCCESS
)
69 if (n
!= 0 && buf
[n
- 1] == L
'\\')
73 value
->assign(buf
.get(), n
);
77 typedef std::unique_ptr
<void, decltype(&CloseHandle
)> CloseHandleGuard
;
79 CloseHandleGuard
guard(HANDLE handle
) { return CloseHandleGuard(handle
, CloseHandle
); }
81 bool runExecutable(std::wstring
const& installLocation
, wchar_t const* argument
)
83 std::wstring
cmdline(L
"\"");
84 cmdline
+= installLocation
;
85 cmdline
+= L
"\\program\\update_service.exe\" ";
87 auto const n
= cmdline
.size() + 1;
88 auto const buf
= std::make_unique
<wchar_t[]>(n
);
89 std::copy_n(cmdline
.data(), n
, buf
.get());
92 PROCESS_INFORMATION pi
{};
93 if (!CreateProcessW(nullptr, buf
.get(), nullptr, nullptr, FALSE
, CREATE_NO_WINDOW
, nullptr,
98 auto const g(guard(pi
.hProcess
));
99 DWORD res
= WaitForSingleObject(pi
.hProcess
, INFINITE
);
100 if (res
!= WAIT_OBJECT_0
)
105 if (!GetExitCodeProcess(pi
.hProcess
, &ec
))
116 bool writeRegistry(std::wstring
const& installLocation
)
118 WCHAR path
[MAX_PATH
+ 1];
119 if (!CalculateRegistryPathFromFilePath(installLocation
.c_str(), path
))
124 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE
, (std::wstring(path
) + L
"\\0").c_str(), 0, nullptr,
125 REG_OPTION_NON_VOLATILE
, KEY_WRITE
| KEY_WOW64_64KEY
, nullptr, &key
,
132 if (RegSetValueExW(key
, L
"issuer", 0, REG_SZ
,
133 reinterpret_cast<BYTE
const*>(L
"Certum Code Signing 2021 CA"),
134 sizeof L
"Certum Code Signing 2021 CA")
139 if (RegSetValueExW(key
, L
"name", 0, REG_SZ
,
140 reinterpret_cast<BYTE
const*>(L
"The Document Foundation"),
141 sizeof L
"The Document Foundation")
146 if (RegCloseKey(key
) != ERROR_SUCCESS
)
153 bool deleteRegistry(std::wstring
const& installLocation
)
155 WCHAR path
[MAX_PATH
+ 1];
156 if (!CalculateRegistryPathFromFilePath(installLocation
.c_str(), path
))
160 if (RegDeleteTreeW(HKEY_LOCAL_MACHINE
, path
) != ERROR_SUCCESS
)
168 extern "C" __declspec(dllexport
) UINT __stdcall
PrepareUpdateservice(MSIHANDLE handle
)
171 if (!getProperty(handle
, L
"INSTALLLOCATION", &loc
))
173 return ERROR_INSTALL_FAILURE
;
176 if (MsiSetPropertyW(handle
, L
"install_updateservice", loc
.c_str()) != ERROR_SUCCESS
)
180 if (MsiSetPropertyW(handle
, L
"uninstall_updateservice", loc
.c_str()) != ERROR_SUCCESS
)
184 return ok
? ERROR_SUCCESS
: ERROR_INSTALL_FAILURE
;
187 extern "C" __declspec(dllexport
) UINT __stdcall
InstallUpdateservice(MSIHANDLE handle
)
190 if (!getProperty(handle
, L
"CustomActionData", &loc
))
192 return ERROR_INSTALL_FAILURE
;
195 if (!runExecutable(loc
, L
"install"))
199 if (!writeRegistry(loc
))
203 return ok
? ERROR_SUCCESS
: ERROR_INSTALL_FAILURE
;
206 extern "C" __declspec(dllexport
) UINT __stdcall
UninstallUpdateservice(MSIHANDLE handle
)
209 if (!getProperty(handle
, L
"CustomActionData", &loc
))
211 return ERROR_INSTALL_FAILURE
;
214 if (!runExecutable(loc
, L
"uninstall"))
218 if (!deleteRegistry(loc
))
222 return ok
? ERROR_SUCCESS
: ERROR_INSTALL_FAILURE
;
225 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */