| 1 | /*++ |
| 2 | |
| 3 | Copyright (c) Microsoft. All rights reserved. |
| 4 | |
| 5 | Module Name: |
| 6 | |
| 7 | WslcService.cpp |
| 8 | |
| 9 | Abstract: |
| 10 | |
| 11 | This file contains the implementation of the WinRT wrapper for the WSLC SDK WslcService class. |
| 12 | |
| 13 | --*/ |
| 14 | |
| 15 | #include "precomp.h" |
| 16 | #include "WslcService.h" |
| 17 | #include "Microsoft.WSL.Containers.WslcService.g.cpp" |
| 18 | #include "ServiceVersion.h" |
| 19 | #include "InstallProgress.h" |
| 20 | |
| 21 | using namespace winrt::Windows::Foundation; |
| 22 | using namespace winrt::Windows::Foundation::Collections; |
| 23 | |
| 24 | namespace winrt::Microsoft::WSL::Containers::implementation { |
| 25 | |
| 26 | namespace { |
| 27 | WslcComponentFlags GetComponentsForInstall(const winrt::Microsoft::WSL::Containers::InstallOptions& options) |
| 28 | { |
| 29 | WslcComponentFlags result = WslcComponentFlags::WSLC_COMPONENT_FLAG_NONE; |
| 30 | bool shouldCheckMissingComponents = true; |
| 31 | |
| 32 | if (options) |
| 33 | { |
| 34 | auto components = options.Components(); |
| 35 | if (components) |
| 36 | { |
| 37 | shouldCheckMissingComponents = false; |
| 38 | |
| 39 | for (const auto& component : components) |
| 40 | { |
| 41 | switch (component) |
| 42 | { |
| 43 | case Component::VirtualMachinePlatform: |
| 44 | result |= WslcComponentFlags::WSLC_COMPONENT_FLAG_VIRTUAL_MACHINE_PLATFORM; |
| 45 | break; |
| 46 | case Component::WslPackage: |
| 47 | result |= WslcComponentFlags::WSLC_COMPONENT_FLAG_WSL_PACKAGE; |
| 48 | break; |
| 49 | case Component::SdkNeedsUpdate: |
| 50 | THROW_HR(WSLC_E_SDK_UPDATE_NEEDED); |
| 51 | default: |
| 52 | THROW_HR(E_INVALIDARG); |
| 53 | } |
| 54 | } |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | if (shouldCheckMissingComponents) |
| 59 | { |
| 60 | winrt::check_hresult(WslcGetMissingComponents(&result)); |
| 61 | } |
| 62 | |
| 63 | return result; |
| 64 | } |
| 65 | |
| 66 | WslcInstallOptions GetOptionsForInstall(const winrt::Microsoft::WSL::Containers::InstallOptions& options) |
| 67 | { |
| 68 | WslcInstallOptions result = WslcInstallOptions::WSLC_INSTALL_OPTION_NONE; |
| 69 | |
| 70 | if (options) |
| 71 | { |
| 72 | if (options.Repair()) |
| 73 | { |
| 74 | result |= WslcInstallOptions::WSLC_INSTALL_OPTION_REPAIR; |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | return result; |
| 79 | } |
| 80 | |
| 81 | void CALLBACK InstallProgressCallback(WslcComponentFlags component, uint32_t progressSteps, uint32_t totalSteps, PVOID context) noexcept |
| 82 | { |
| 83 | try |
| 84 | { |
| 85 | auto installProgress = winrt::make<implementation::InstallProgress>( |
| 86 | static_cast<winrt::Microsoft::WSL::Containers::Component>(component), progressSteps, totalSteps); |
| 87 | ProgressCallbackHelper<decltype(installProgress)>::ReportProgress(context, installProgress); |
| 88 | } |
| 89 | CATCH_LOG(); |
| 90 | } |
| 91 | } // namespace |
| 92 | |
| 93 | winrt::Windows::Foundation::Collections::IVectorView<winrt::Microsoft::WSL::Containers::Component> WslcService::GetMissingComponents() |
| 94 | { |
| 95 | WslcComponentFlags missing; |
| 96 | winrt::check_hresult(WslcGetMissingComponents(&missing)); |
| 97 | |
| 98 | auto result = winrt::single_threaded_vector<winrt::Microsoft::WSL::Containers::Component>(); |
| 99 | if (WI_IsFlagSet(missing, WSLC_COMPONENT_FLAG_VIRTUAL_MACHINE_PLATFORM)) |
| 100 | { |
| 101 | result.Append(winrt::Microsoft::WSL::Containers::Component::VirtualMachinePlatform); |
| 102 | } |
| 103 | if (WI_IsFlagSet(missing, WSLC_COMPONENT_FLAG_WSL_PACKAGE)) |
| 104 | { |
| 105 | result.Append(winrt::Microsoft::WSL::Containers::Component::WslPackage); |
| 106 | } |
| 107 | if (WI_IsFlagSet(missing, WSLC_COMPONENT_FLAG_SDK_NEEDS_UPDATE)) |
| 108 | { |
| 109 | result.Append(winrt::Microsoft::WSL::Containers::Component::SdkNeedsUpdate); |
| 110 | } |
| 111 | return result.GetView(); |
| 112 | } |
| 113 | |
| 114 | winrt::Microsoft::WSL::Containers::ServiceVersion WslcService::GetVersion() |
| 115 | { |
| 116 | WslcVersion version; |
| 117 | winrt::check_hresult(WslcGetVersion(&version)); |
| 118 | return winrt::make<implementation::ServiceVersion>(version.major, version.minor, version.revision); |
| 119 | } |
| 120 | |
| 121 | IAsyncActionWithProgress<winrt::Microsoft::WSL::Containers::InstallProgress> WslcService::InstallWithDependenciesAsync( |
| 122 | winrt::Microsoft::WSL::Containers::InstallOptions options) |
| 123 | { |
| 124 | auto components = GetComponentsForInstall(options); |
| 125 | auto wslcOptions = GetOptionsForInstall(options); |
| 126 | |
| 127 | co_await winrt::resume_background(); |
| 128 | |
| 129 | auto context = ProgressCallbackHelper<winrt::Microsoft::WSL::Containers::InstallProgress>{co_await winrt::get_progress_token()}; |
| 130 | winrt::check_hresult(WslcInstallWithDependencies(components, wslcOptions, InstallProgressCallback, &context)); |
| 131 | } |
| 132 | |
| 133 | void WslcService::InstallWithDependencies(winrt::Microsoft::WSL::Containers::InstallOptions options) |
| 134 | { |
| 135 | auto components = GetComponentsForInstall(options); |
| 136 | auto wslcOptions = GetOptionsForInstall(options); |
| 137 | winrt::check_hresult(WslcInstallWithDependencies(components, wslcOptions, nullptr, nullptr)); |
| 138 | } |
| 139 | } // namespace winrt::Microsoft::WSL::Containers::implementation |