File: Installer.cpp

package info (click to toggle)
mediainfo 25.10-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,656 kB
  • sloc: cpp: 18,871; objc: 3,102; xml: 1,426; sh: 1,328; python: 263; makefile: 212
file content (135 lines) | stat: -rw-r--r-- 3,746 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*  Copyright (c) MediaArea.net SARL. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license that can
 *  be found in the License.html file in the root of the source tree.
 */

// Functions for registration and removal of MediaInfo sparse package

#include "pch.h"
#include "Installer.h"

using namespace winrt::Windows::ApplicationModel;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
using namespace winrt::Windows::Management::Deployment;

using namespace MediaInfo_SparsePackage::Installer;

const std::wstring SparsePackageName = L"MediaInfo";
const std::wstring SparsePackageFileName = L"MediaInfo_SparsePackage.msix";

static const std::wstring GetInstallationPath() {
    std::filesystem::path module_path{ wil::GetModuleFileNameW<std::wstring>(wil::GetModuleInstanceHandle()) };
    return module_path.remove_filename().wstring();
}

static Package GetSparsePackage()
{
    PackageManager packageManager;
    IIterable<Package> packages;

    try {
        packages = packageManager.FindPackages();
    }
    catch (winrt::hresult_error) {
        return NULL;
    }

    for (const Package& package : packages) {
        if (package.Id().Name() != SparsePackageName)
            continue;

        return package;
    }

    return NULL;
}

static HRESULT RegisterSparsePackage()
{
    // Cannot handle sparse packages in safe-mode
    if (GetSystemMetrics(SM_CLEANBOOT) > 0)
        return S_FALSE;

    PackageManager packageManager;
    StagePackageOptions options;

    const std::wstring externalLocation = GetInstallationPath();
    const std::wstring sparsePkgPath = externalLocation + L"\\" + SparsePackageFileName;

    Uri externalUri(externalLocation);
    Uri packageUri(sparsePkgPath);

    options.ExternalLocationUri(externalUri);

    auto deploymentOperation = packageManager.StagePackageByUriAsync(packageUri, options);
    auto deployResult = deploymentOperation.get();

    if (FAILED(deployResult.ExtendedErrorCode()))
        return deployResult.ExtendedErrorCode();

    Package package = GetSparsePackage();
    if (package == NULL)
        return S_FALSE;

    winrt::hstring familyName = package.Id().FamilyName();
    deploymentOperation = packageManager.ProvisionPackageForAllUsersAsync(familyName);
    deployResult = deploymentOperation.get();

    if (FAILED(deployResult.ExtendedErrorCode()))
        return deployResult.ExtendedErrorCode();

    return S_OK;
}


static HRESULT UnregisterSparsePackage()
{
    // Cannot handle sparse packages in safe-mode
    if (GetSystemMetrics(SM_CLEANBOOT) > 0)
        return S_FALSE;

    const Package package = GetSparsePackage();
    if (package == NULL)
        return S_FALSE;

    PackageManager packageManager;
    winrt::hstring fullName = package.Id().FullName();
    auto deploymentOperation = packageManager.RemovePackageAsync(fullName, RemovalOptions::RemoveForAllUsers);
    auto deployResult = deploymentOperation.get();

    if (FAILED(deployResult.ExtendedErrorCode()))
        return deployResult.ExtendedErrorCode();

    return S_OK;
}

STDAPI MediaInfo_SparsePackage::Installer::Install()
{
    HRESULT result;

    // remove any old existing versions first
    result = UnregisterSparsePackage();
    if (FAILED(result))
        return result;

    result = RegisterSparsePackage();
    if (FAILED(result))
        return result;

    SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);

    return S_OK;
}

STDAPI MediaInfo_SparsePackage::Installer::Uninstall()
{
    HRESULT result = UnregisterSparsePackage();
    if (FAILED(result))
        return result;

    SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);

    return S_OK;
}