[Setup] add support for embedded MSIX packages (#13263)

This commit is contained in:
Andrey Nekrasov
2021-09-21 15:15:59 +03:00
committed by GitHub
parent f4531130b6
commit 7fe63cdb50
13 changed files with 263 additions and 78 deletions

View File

@@ -1,13 +1,17 @@
#include "stdafx.h"
#include "resource.h"
#include <ProjectTelemetry.h>
#include "../../src/common/utils/MsiUtils.h"
#include "../../src/common/updating/installer.h"
#include "../../src/common/version/version.h"
#include "../../installer/PowerToysBootstrapper/bootstrapper/RcResource.h"
using namespace std;
HINSTANCE DLL_HANDLE = nullptr;
TRACELOGGING_DEFINE_PROVIDER(
g_hProvider,
"Microsoft.PowerToysInstaller",
@@ -21,6 +25,78 @@ const DWORD USERNAME_LEN = UNLEN + 1; // User Name + '\0'
static const wchar_t* POWERTOYS_EXE_COMPONENT = L"{A2C66D91-3485-4D00-B04D-91844E6B345B}";
static const wchar_t* POWERTOYS_UPGRADE_CODE = L"{42B84BF7-5FBF-473B-9C8B-049DC16F7708}";
UINT __stdcall InstallEmbeddedMSIXCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
hr = WcaInitialize(hInstall, "InstallEmbeddedMSIXCA");
ExitOnFailure(hr, "Failed to initialize");
if (auto msix = RcResource::create(IDR_BIN_MSIX_HELLO_PACKAGE, L"BIN", DLL_HANDLE))
{
WcaLog(LOGMSG_STANDARD, "Extracted MSIX");
// TODO: Use to activate embedded MSIX
const auto msix_path = std::filesystem::temp_directory_path() / "hello_package.msix";
if (!msix->saveAsFile(msix_path))
{
ExitOnFailure(hr, "Failed to save msix");
}
WcaLog(LOGMSG_STANDARD, "Saved MSIX");
using namespace winrt::Windows::Management::Deployment;
using namespace winrt::Windows::Foundation;
Uri msix_uri{ msix_path.wstring() };
PackageManager pm;
auto result = pm.AddPackageAsync(msix_uri, nullptr, DeploymentOptions::None).get();
if (!result)
{
ExitOnFailure(hr, "Failed to AddPackage");
}
WcaLog(LOGMSG_STANDARD, "MSIX[s] were installed!");
}
else
{
ExitOnFailure(hr, "Failed to extract msix");
}
LExit:
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
return WcaFinalize(er);
}
UINT __stdcall UninstallEmbeddedMSIXCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
using namespace winrt::Windows::Management::Deployment;
using namespace winrt::Windows::Foundation;
// TODO: This must be replaced with the actual publisher and package name
const wchar_t package_name[] = L"46b35c25-b593-48d5-aeb1-d3e9c3b796e9";
const wchar_t publisher[] = L"CN=yuyoyuppe";
PackageManager pm;
hr = WcaInitialize(hInstall, "UninstallEmbeddedMSIXCA");
ExitOnFailure(hr, "Failed to initialize");
for (const auto& p : pm.FindPackagesForUser({}, package_name, publisher))
{
auto result = pm.RemovePackageAsync(p.Id().FullName()).get();
if (result)
{
WcaLog(LOGMSG_STANDARD, "MSIX was uninstalled!");
}
else
{
WcaLog(LOGMSG_STANDARD, "Couldn't uninstall MSIX!");
}
}
LExit:
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
return WcaFinalize(er);
}
// Creates a Scheduled Task to run at logon for the current user.
// The path of the executable to run should be passed as the CustomActionData (Value).
// Based on the Task Scheduler Logon Trigger Example:
@@ -42,12 +118,12 @@ UINT __stdcall CreateScheduledTaskCA(MSIHANDLE hInstall)
ITaskSettings* pSettings = nullptr;
ITriggerCollection* pTriggerCollection = nullptr;
IRegisteredTask* pRegisteredTask = nullptr;
IPrincipal * pPrincipal = nullptr;
ITrigger * pTrigger = nullptr;
ILogonTrigger * pLogonTrigger = nullptr;
IAction * pAction = nullptr;
IActionCollection * pActionCollection = nullptr;
IExecAction * pExecAction = nullptr;
IPrincipal* pPrincipal = nullptr;
ITrigger* pTrigger = nullptr;
ILogonTrigger* pLogonTrigger = nullptr;
IAction* pAction = nullptr;
IActionCollection* pActionCollection = nullptr;
IExecAction* pExecAction = nullptr;
LPWSTR wszExecutablePath = nullptr;
@@ -190,7 +266,6 @@ UINT __stdcall CreateScheduledTaskCA(MSIHANDLE hInstall)
pActionCollection->Release();
ExitOnFailure(hr, "Cannot create the action: %x", hr);
// QI for the executable task pointer.
hr = pAction->QueryInterface(
IID_IExecAction, (void**)&pExecAction);
@@ -302,7 +377,7 @@ UINT __stdcall RemoveScheduledTasksCA(MSIHANDLE hInstall)
ITaskService* pService = nullptr;
ITaskFolder* pTaskFolder = nullptr;
IRegisteredTaskCollection* pTaskCollection = nullptr;
ITaskFolder * pRootFolder = nullptr;
ITaskFolder* pRootFolder = nullptr;
LONG numTasks = 0;
hr = WcaInitialize(hInstall, "RemoveScheduledTasksCA");
@@ -589,9 +664,8 @@ UINT __stdcall DetectPrevInstallPathCA(MSIHANDLE hInstall)
MsiSetPropertyW(hInstall, L"INSTALLFOLDER", install_path->data());
}
}
catch(...)
catch (...)
{
}
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
return WcaFinalize(er);
@@ -609,7 +683,7 @@ UINT __stdcall CertifyVirtualCameraDriverCA(MSIHANDLE hInstall)
HCERTSTORE hCertStore = nullptr;
HANDLE hfile = nullptr;
DWORD size = INVALID_FILE_SIZE;
char * pFileContent = nullptr;
char* pFileContent = nullptr;
hr = WcaInitialize(hInstall, "CertifyVirtualCameraDriverCA");
ExitOnFailure(hr, "Failed to initialize", hr);
@@ -648,11 +722,11 @@ UINT __stdcall CertifyVirtualCameraDriverCA(MSIHANDLE hInstall)
}
if (!CertAddEncodedCertificateToStore(hCertStore,
X509_ASN_ENCODING,
(const BYTE*)pFileContent,
size,
CERT_STORE_ADD_ALWAYS,
nullptr))
X509_ASN_ENCODING,
(const BYTE*)pFileContent,
size,
CERT_STORE_ADD_ALWAYS,
nullptr))
{
hr = GetLastError();
ExitOnFailure(hr, "Adding certificate failed", hr);
@@ -678,13 +752,11 @@ LExit:
MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_WARNING + MB_OK), hRecord);
}
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
return WcaFinalize(er);
#endif
}
UINT __stdcall InstallVirtualCameraDriverCA(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
@@ -793,7 +865,7 @@ UINT __stdcall TerminateProcessesCA(MSIHANDLE hInstall)
}
wchar_t processName[MAX_PATH] = L"<unknown>";
HANDLE hProcess{OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE, FALSE, procID)};
HANDLE hProcess{ OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE, FALSE, procID) };
if (!hProcess)
{
continue;
@@ -819,7 +891,7 @@ UINT __stdcall TerminateProcessesCA(MSIHANDLE hInstall)
GetWindowThreadProcessId(hwnd, &windowProcID);
if (windowProcID == targetProcID)
{
DWORD_PTR _ {};
DWORD_PTR _{};
SendMessageTimeoutA(hwnd, WM_CLOSE, 0, 0, SMTO_BLOCK, timeout, &_);
}
return TRUE;
@@ -837,7 +909,6 @@ UINT __stdcall TerminateProcessesCA(MSIHANDLE hInstall)
return WcaFinalize(er);
}
// DllMain - Initialize and cleanup WiX custom action utils.
extern "C" BOOL WINAPI DllMain(__in HINSTANCE hInst, __in ULONG ulReason, __in LPVOID)
{
@@ -846,6 +917,7 @@ extern "C" BOOL WINAPI DllMain(__in HINSTANCE hInst, __in ULONG ulReason, __in L
case DLL_PROCESS_ATTACH:
WcaGlobalInitialize(hInst);
TraceLoggingRegister(g_hProvider);
DLL_HANDLE = hInst;
break;
case DLL_PROCESS_DETACH: