diff --git a/.gitignore b/.gitignore index 9169294b6..cdb56176c 100644 --- a/.gitignore +++ b/.gitignore @@ -70,4 +70,5 @@ directory.build.targets test-storage/ *.vhdx *.tar -*.etl \ No newline at end of file +*.etl +*.lscache diff --git a/CMakeLists.txt b/CMakeLists.txt index bb25dd0c4..7549663d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,6 +113,7 @@ find_package(NUGET REQUIRED) find_package(VERSION REQUIRED) find_package(MC REQUIRED) find_package(Appx REQUIRED) +find_package(CSharp REQUIRED) # Download nuget packages restore_nuget_packages() @@ -157,6 +158,9 @@ find_nuget_package(Microsoft.Windows.SDK.NET.Ref WINDOWS_SDK_DOTNET /) find_nuget_package(Microsoft.Xaml.Behaviors.WinUI.Managed XAML_BEHAVIORS /) find_nuget_package(WinUIEx WINUIEX /) +# WSLC C# API packages +find_nuget_package(Microsoft.Windows.CsWinRT CSWINRT /) + set(WSLG_TS_PLUGIN_DLL "WSLDVCPlugin.dll") set(SUPPORTED_LANGS cs-CZ;da-DK;de-DE;en-GB;en-US;es-ES;fi-FI;fr-FR;hu-HU;it-IT;ja-JP;ko-KR;nb-NO;nl-NL;pl-PL;pt-BR;pt-PT;ru-RU;sv-SE;tr-TR;zh-CN;zh-TW) diff --git a/cmake/FindCSharp.cmake b/cmake/FindCSharp.cmake new file mode 100644 index 000000000..d6a40733a --- /dev/null +++ b/cmake/FindCSharp.cmake @@ -0,0 +1,15 @@ +function(configure_csharp_target TARGET) + set(TARGET_PLATFORM_MIN_VERSION "10.0.19041.0") + target_compile_options(${TARGET} PRIVATE "/langversion:latest" "/debug:full") + set_target_properties( + ${TARGET} PROPERTIES + VS_GLOBAL_TargetPlatformVersion "${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}" + VS_GLOBAL_TargetPlatformMinVersion "${TARGET_PLATFORM_MIN_VERSION}" + VS_GLOBAL_WindowsSdkPackageVersion "${WINDOWS_SDK_DOTNET_VERSION}" + VS_GLOBAL_AppendRuntimeIdentifierToOutputPath false + VS_GLOBAL_GenerateAssemblyInfo false + VS_GLOBAL_TargetLatestRuntimePatch false + DOTNET_SDK "Microsoft.NET.Sdk" + DOTNET_TARGET_FRAMEWORK "net8.0-windows${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}" + ) +endfunction() \ No newline at end of file diff --git a/cmake/FindIDL.cmake b/cmake/FindIDL.cmake index ac3965ec6..845841840 100644 --- a/cmake/FindIDL.cmake +++ b/cmake/FindIDL.cmake @@ -81,4 +81,49 @@ function(add_idl target idl_files_with_proxy idl_files_no_proxy) DEPENDS ${TARGET_OUTPUTS} SOURCES ${idl_files_with_proxy} ${idl_files_no_proxy}) -endfunction() \ No newline at end of file +endfunction() + +function(add_idl_winrt target idl_file) + set(OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}) + file(TO_NATIVE_PATH ${OUTPUT_DIR} OUTPUT_DIR) # midl is picky about path formats + file(MAKE_DIRECTORY ${OUTPUT_DIR}) + + set(IDL_DEFINITIONS "") + + get_directory_property(IDL_DEFS COMPILE_DEFINITIONS ) + foreach(e ${IDL_DEFS}) + set(IDL_DEFINITIONS ${IDL_DEFINITIONS} /D${e}) + endforeach() + + string(TOLOWER ${TARGET_PLATFORM} IDL_ENV) + + cmake_host_system_information( + RESULT WINDOWS_SDK_DIR + QUERY WINDOWS_REGISTRY "HKLM/SOFTWARE/Microsoft/Windows Kits/Installed Roots" + VALUE "KitsRoot10") + set(WINRT_METADATA_DIR "${WINDOWS_SDK_DIR}\\UnionMetadata\\${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") + set(WINRT_REFERENCE "${WINRT_METADATA_DIR}\\Windows.winmd") + set(WINRT_INCLUDE "${WINDOWS_SDK_DIR}\\Include\\${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}\\winrt") + + cmake_path(GET idl_file STEM IDL_NAME) + + set(IDL_WINMD ${OUTPUT_DIR}/${IDL_NAME}.winmd) + + add_custom_command( + OUTPUT ${IDL_WINMD} + COMMAND midl /nologo /nomidl /winrt /metadata_dir "${WINRT_METADATA_DIR}" /reference "${WINRT_REFERENCE}" /I "${WINRT_INCLUDE}" /env "${IDL_ENV}" /h nul /winmd ${IDL_WINMD} ${idl_file} ${IDL_DEFINITIONS} + COMMAND cppwinrt -input ${IDL_WINMD} -reference "${WINRT_REFERENCE}" -output ${OUTPUT_DIR} -comp ${OUTPUT_DIR}/implementation_base -optimize -pch precomp.h -prefix + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + DEPENDS ${idl_file} + MAIN_DEPENDENCY ${idl_file} + VERBATIM + ) + + set_source_files_properties(${IDL_WINMD} PROPERTIES GENERATED TRUE) + + add_custom_target(${target} + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target} + DEPENDS ${IDL_WINMD} + SOURCES ${idl_file}) + +endfunction() diff --git a/nuget/CMakeLists.txt b/nuget/CMakeLists.txt index f0271a832..f4d43426c 100644 --- a/nuget/CMakeLists.txt +++ b/nuget/CMakeLists.txt @@ -1,4 +1,5 @@ set(NUGET_PACKAGES Microsoft.WSL.PluginApi.nuspec Microsoft.WSL.Containers.nuspec) +set(NUGET_TARGET_FRAMEWORK "net8.0-windows10.0.19041.0") # generate vars with native paths since nuget won't accept unix path separators cmake_path(NATIVE_PATH CMAKE_SOURCE_DIR CMAKE_SOURCE_DIR_NATIVE) diff --git a/nuget/Microsoft.WSL.Containers.nuspec.in b/nuget/Microsoft.WSL.Containers.nuspec.in index 0c8628ed5..cadc9c285 100644 --- a/nuget/Microsoft.WSL.Containers.nuspec.in +++ b/nuget/Microsoft.WSL.Containers.nuspec.in @@ -11,13 +11,22 @@ en-us MIT docs\README.MD + + + - - - - - + + + + + + + + + + + diff --git a/nuget/Microsoft.WSL.Containers/build/Microsoft.WSL.Containers.common.targets b/nuget/Microsoft.WSL.Containers/build/Microsoft.WSL.Containers.common.targets deleted file mode 100644 index 2454f2555..000000000 --- a/nuget/Microsoft.WSL.Containers/build/Microsoft.WSL.Containers.common.targets +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/nuget/Microsoft.WSL.Containers/build/native/Microsoft.WSL.Containers.targets b/nuget/Microsoft.WSL.Containers/build/native/Microsoft.WSL.Containers.targets index 09823c7b0..abd559faa 100644 --- a/nuget/Microsoft.WSL.Containers/build/native/Microsoft.WSL.Containers.targets +++ b/nuget/Microsoft.WSL.Containers/build/native/Microsoft.WSL.Containers.targets @@ -1,8 +1,10 @@ - - $(Platform) + + $(Platform) + <_wslcIsInvalidPlatform Condition="'$(WslcPlatform)' != 'x64' and '$(WslcPlatform)' != 'arm64'">true + @@ -16,11 +18,17 @@ %(AdditionalDependencies) - $(MSBuildThisFileDirectory)..\..\runtimes\win-$(Platform); + $(MSBuildThisFileDirectory)..\..\runtimes\win-$(WslcPlatform); %(AdditionalLibraryDirectories) - + + + + + + + \ No newline at end of file diff --git a/nuget/Microsoft.WSL.Containers/build/net/Microsoft.WSL.Containers.targets b/nuget/Microsoft.WSL.Containers/build/net/Microsoft.WSL.Containers.targets index 245e57a2c..ecc7f902f 100644 --- a/nuget/Microsoft.WSL.Containers/build/net/Microsoft.WSL.Containers.targets +++ b/nuget/Microsoft.WSL.Containers/build/net/Microsoft.WSL.Containers.targets @@ -1,14 +1,31 @@ - - x64 - arm64 - + + + + + <_wslcPlatform Condition="$(RuntimeIdentifier.EndsWith('-x64'))">x64 + <_wslcPlatform Condition="$(RuntimeIdentifier.EndsWith('-arm64'))">arm64 + <_wslcInvalidPlatformProperty Condition="'$(_wslcPlatform)' == ''">RuntimeIdentifier + <_wslcInvalidPlatform Condition="'$(_wslcPlatform)' == ''">$(RuntimeIdentifier) + + + + + <_wslcPlatform Condition="'$(PlatformTarget)' == 'x64'">x64 + <_wslcPlatform Condition="'$(PlatformTarget)' == 'arm64'">arm64 + <_wslcInvalidPlatformProperty Condition="'$(_wslcPlatform)' == ''">PlatformTarget + <_wslcInvalidPlatform Condition="'$(_wslcPlatform)' == ''">$(PlatformTarget) + - - $(Platform) - - - + + + + + + + + \ No newline at end of file diff --git a/nuget/Microsoft.WSL.Containers/cmake/Microsoft.WSL.ContainersConfig.cmake b/nuget/Microsoft.WSL.Containers/cmake/Microsoft.WSL.ContainersConfig.cmake index 0ea5f0642..4829bed47 100644 --- a/nuget/Microsoft.WSL.Containers/cmake/Microsoft.WSL.ContainersConfig.cmake +++ b/nuget/Microsoft.WSL.Containers/cmake/Microsoft.WSL.ContainersConfig.cmake @@ -47,7 +47,7 @@ add_library(Microsoft.WSL.Containers::SDK SHARED IMPORTED GLOBAL) set_target_properties(Microsoft.WSL.Containers::SDK PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${_wslcsdk_include_dir}" IMPORTED_IMPLIB "${_wslcsdk_lib_dir}/wslcsdk.lib" - IMPORTED_LOCATION "${_wslcsdk_lib_dir}/wslcsdk.dll" + IMPORTED_LOCATION "${_wslcsdk_lib_dir}/native/wslcsdk.dll" ) # Clean up temporary variables diff --git a/packages.config b/packages.config index 01bb7e7b8..2ac880cef 100644 --- a/packages.config +++ b/packages.config @@ -12,6 +12,7 @@ + diff --git a/src/windows/WslcSDK/CMakeLists.txt b/src/windows/WslcSDK/CMakeLists.txt index cbb0e059d..1acc7133f 100644 --- a/src/windows/WslcSDK/CMakeLists.txt +++ b/src/windows/WslcSDK/CMakeLists.txt @@ -6,6 +6,7 @@ set(SOURCES WslcsdkPrivate.cpp ) set(HEADERS + Defaults.h IOCallback.h ProgressCallback.h TerminationCallback.h @@ -14,8 +15,15 @@ set(HEADERS ) add_library(wslcsdk SHARED ${SOURCES} ${HEADERS} wslcsdk.def) -set_target_properties(wslcsdk PROPERTIES EXCLUDE_FROM_ALL FALSE) -add_dependencies(wslcsdk wslserviceidl) -target_link_libraries(wslcsdk ${COMMON_LINK_LIBRARIES} legacy_stdio_definitions common) -target_precompile_headers(wslcsdk REUSE_FROM common) -set_target_properties(wslcsdk PROPERTIES FOLDER windows) +set_target_properties(wslcsdk + PROPERTIES + EXCLUDE_FROM_ALL FALSE + FOLDER windows +) + +add_subdirectory(winrt) +add_subdirectory(csharp) + +add_dependencies(wslcsdk wslserviceidl wslcsdkwinrt) +target_link_libraries(wslcsdk ${COMMON_LINK_LIBRARIES} legacy_stdio_definitions common wslcsdkwinrt) +target_precompile_headers(wslcsdk REUSE_FROM common) \ No newline at end of file diff --git a/src/windows/WslcSDK/Defaults.h b/src/windows/WslcSDK/Defaults.h new file mode 100644 index 000000000..8e61e597f --- /dev/null +++ b/src/windows/WslcSDK/Defaults.h @@ -0,0 +1,22 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + Defaults.h + +Abstract: + + Contains default values for settings used in the WSL Container SDK. + +--*/ + +#pragma once + +constexpr uint32_t s_DefaultCPUCount = 2; +constexpr uint32_t s_DefaultMemoryMB = 2000; +// Maximum value per use with HVSOCKET_CONNECT_TIMEOUT_MAX +constexpr ULONG s_DefaultBootTimeout = 300000; +// Default to 1 GB +constexpr UINT64 s_DefaultStorageSize = 1000 * 1000 * 1000; diff --git a/src/windows/WslcSDK/csharp/CMakeLists.txt b/src/windows/WslcSDK/csharp/CMakeLists.txt new file mode 100644 index 000000000..ed7efcff8 --- /dev/null +++ b/src/windows/WslcSDK/csharp/CMakeLists.txt @@ -0,0 +1,29 @@ +enable_language(CSharp) + +add_library(wslcsdkcs SHARED) +configure_csharp_target(wslcsdkcs) + +set(WSLCSDK_WINMD "${CMAKE_CURRENT_BINARY_DIR}/../winrt/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}/wslcsdk.winmd") + +target_sources(wslcsdkcs + PRIVATE + "${WSLCSDK_WINMD}" + "${CMAKE_CURRENT_SOURCE_DIR}/WinRTActivation.cs" +) + +set_source_files_properties( + "${WSLCSDK_WINMD}" + PROPERTIES + GENERATED TRUE + VS_TOOL_OVERRIDE "CsWinRTInputs" +) + +set_target_properties( + wslcsdkcs PROPERTIES + FOLDER windows + LINKER_LANGUAGE CSharp + VS_PACKAGE_REFERENCES "Microsoft.Windows.CsWinRT_${CSWINRT_VERSION}" + VS_GLOBAL_CsWinRTIncludes "Microsoft.WSL.Containers" +) + +add_dependencies(wslcsdkcs wslcsdkwinrt) diff --git a/src/windows/WslcSDK/csharp/WinRTActivation.cs b/src/windows/WslcSDK/csharp/WinRTActivation.cs new file mode 100644 index 000000000..663b74ac0 --- /dev/null +++ b/src/windows/WslcSDK/csharp/WinRTActivation.cs @@ -0,0 +1,69 @@ +// Copyright (C) Microsoft Corporation. All rights reserved. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using WinRT; + +namespace Microsoft.WSL.Containers; + +internal static class WinRTActivation +{ + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + private delegate int DllGetActivationFactoryFn(IntPtr classId, out IntPtr factory); + + private static DllGetActivationFactoryFn s_getDllFactory; + + [ModuleInitializer] + internal static void Initialize() + { + s_getDllFactory = Marshal.GetDelegateForFunctionPointer( + NativeLibrary.GetExport( + NativeLibrary.Load("wslcsdk.dll", typeof(WinRTActivation).Assembly, DllImportSearchPath.AssemblyDirectory), + "DllGetActivationFactory")); + + var previousHandler = ActivationFactory.ActivationHandler; + ActivationFactory.ActivationHandler = (typeName, iid) => + typeName.StartsWith("Microsoft.WSL.Containers.", StringComparison.Ordinal) + ? GetActivationFactory(typeName, iid) + : previousHandler?.Invoke(typeName, iid) ?? IntPtr.Zero; + } + + private static IntPtr GetActivationFactory(string typeName, Guid iid) + { + WindowsCreateString(typeName, (uint)typeName.Length, out var hstring); + try + { + if (s_getDllFactory(hstring, out var factory) < 0) + { + return IntPtr.Zero; + } + + if (iid == IID_IActivationFactory) + { + return factory; + } + + try + { + return Marshal.QueryInterface(factory, ref iid, out var queried) >= 0 ? queried : IntPtr.Zero; + } + finally + { + Marshal.Release(factory); + } + } + finally + { + WindowsDeleteString(hstring); + } + } + + private static readonly Guid IID_IActivationFactory = new(0x00000035, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); + + [DllImport("combase.dll", CharSet = CharSet.Unicode)] + private static extern int WindowsCreateString(string sourceString, uint length, out IntPtr hstring); + + [DllImport("combase.dll")] + private static extern int WindowsDeleteString(IntPtr hstring); +} diff --git a/src/windows/WslcSDK/winrt/CMakeLists.txt b/src/windows/WslcSDK/winrt/CMakeLists.txt new file mode 100644 index 000000000..3e14ea22f --- /dev/null +++ b/src/windows/WslcSDK/winrt/CMakeLists.txt @@ -0,0 +1,38 @@ +add_idl_winrt(wslcsdkwinrtidl "wslcsdk.idl") +set_target_properties(wslcsdkwinrtidl PROPERTIES FOLDER windows) + +set(SOURCES + Session.cpp + SessionSettings.cpp + VhdRequirements.cpp +) + +set(HEADERS + Helpers.h + Session.h + SessionSettings.h + VhdRequirements.h +) + +add_library(wslcsdkwinrt STATIC ${SOURCES} ${HEADERS}) +add_dependencies(wslcsdkwinrt wslcsdkwinrtidl) + +set(MODULE_G_CPP ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}/module.g.cpp) +target_sources(wslcsdkwinrt PRIVATE ${MODULE_G_CPP}) +set_source_files_properties( + ${MODULE_G_CPP} + PROPERTIES + GENERATED TRUE) + +target_precompile_headers(wslcsdkwinrt PRIVATE precomp.h) +target_include_directories(wslcsdkwinrt PRIVATE + ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE} + ${CMAKE_SOURCE_DIR}/src/windows/WslcSDK +) + +set_target_properties( + wslcsdkwinrt + PROPERTIES + FOLDER windows + EXCLUDE_FROM_ALL FALSE +) diff --git a/src/windows/WslcSDK/winrt/Helpers.h b/src/windows/WslcSDK/winrt/Helpers.h new file mode 100644 index 000000000..2b87192a1 --- /dev/null +++ b/src/windows/WslcSDK/winrt/Helpers.h @@ -0,0 +1,81 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + Helpers.h + +Abstract: + + This file contains helpers for the WinRT wrapper of WSLC SDK. + +--*/ + +#pragma once + +#define THROW_MSG_IF_FAILED(hr, msg) \ + do \ + { \ + auto _hr = (hr); \ + if (FAILED(_hr)) \ + { \ + auto _msg = (msg).get(); \ + if (!_msg) \ + { \ + throw winrt::hresult_error(_hr); \ + } \ + else \ + { \ + throw winrt::hresult_error(_hr, winrt::to_hstring(_msg)); \ + } \ + } \ + } while (0) + +template +struct implementation_type; + +#define DEFINE_TYPE_HELPERS(__type__) \ + template <> \ + struct implementation_type \ + { \ + using type = winrt::Microsoft::WSL::Containers::implementation::__type__; \ + }; + +namespace winrt::Microsoft::WSL::Containers::implementation { +template +auto* GetStructPointer(const T& obj) +{ + return obj ? winrt::get_self::type>(obj)->ToStructPointer() : nullptr; +} + +template +auto* GetHandlePointer(const T& obj) +{ + return obj ? winrt::get_self::type>(obj)->ToHandlePointer() : nullptr; +} + +template +auto GetHandle(const T& obj) +{ + return obj ? winrt::get_self::type>(obj)->ToHandle() : nullptr; +} + +template +auto* GetStructPointer(const winrt::com_ptr& obj) +{ + return obj ? obj->ToStructPointer() : nullptr; +} + +template +auto* GetHandlePointer(const winrt::com_ptr& obj) +{ + return obj ? obj->ToHandlePointer() : nullptr; +} + +template +auto GetHandle(const winrt::com_ptr& obj) +{ + return obj ? obj->ToHandle() : nullptr; +} +} // namespace winrt::Microsoft::WSL::Containers::implementation \ No newline at end of file diff --git a/src/windows/WslcSDK/winrt/Session.cpp b/src/windows/WslcSDK/winrt/Session.cpp new file mode 100644 index 000000000..daf4894f6 --- /dev/null +++ b/src/windows/WslcSDK/winrt/Session.cpp @@ -0,0 +1,56 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + Session.cpp + +Abstract: + + This file contains the implementation of the WinRT wrapper for the WSLC SDK Session class. + +--*/ + +#include "precomp.h" + +#include "Session.h" +#include "Microsoft.WSL.Containers.Session.g.cpp" + +namespace WSLC = winrt::Microsoft::WSL::Containers; + +namespace winrt::Microsoft::WSL::Containers { + +implementation::Session::~Session() +{ + if (m_session) + { + WslcReleaseSession(m_session); + m_session = nullptr; + } +} + +WSLC::Session implementation::Session::Create(WSLC::SessionSettings const& settings) +{ + auto session = winrt::make_self(); + wil::unique_cotaskmem_string errorMessage; + auto hr = WslcCreateSession(implementation::GetStructPointer(settings), implementation::GetHandlePointer(session), &errorMessage); + THROW_MSG_IF_FAILED(hr, errorMessage); + return *session; +} + +void implementation::Session::Terminate() +{ + winrt::check_hresult(WslcTerminateSession(m_session)); +} + +WslcSession implementation::Session::ToHandle() +{ + return m_session; +} + +WslcSession* implementation::Session::ToHandlePointer() +{ + return &m_session; +} +} // namespace winrt::Microsoft::WSL::Containers diff --git a/src/windows/WslcSDK/winrt/Session.h b/src/windows/WslcSDK/winrt/Session.h new file mode 100644 index 000000000..a6d1c6b0e --- /dev/null +++ b/src/windows/WslcSDK/winrt/Session.h @@ -0,0 +1,43 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + Session.h + +Abstract: + + This file contains the definition of the WinRT wrapper for the WSLC SDK Session class. + +--*/ + +#pragma once +#include "Microsoft.WSL.Containers.Session.g.h" +#include "SessionSettings.h" +#include "Helpers.h" + +namespace winrt::Microsoft::WSL::Containers::implementation { +struct Session : SessionT +{ + Session() = default; + ~Session(); + + static winrt::Microsoft::WSL::Containers::Session Create(winrt::Microsoft::WSL::Containers::SessionSettings const& settings); + void Terminate(); + + WslcSession ToHandle(); + WslcSession* ToHandlePointer(); + +private: + WslcSession m_session{nullptr}; +}; +} // namespace winrt::Microsoft::WSL::Containers::implementation + +namespace winrt::Microsoft::WSL::Containers::factory_implementation { +struct Session : SessionT +{ +}; +} // namespace winrt::Microsoft::WSL::Containers::factory_implementation + +DEFINE_TYPE_HELPERS(Session); \ No newline at end of file diff --git a/src/windows/WslcSDK/winrt/SessionSettings.cpp b/src/windows/WslcSDK/winrt/SessionSettings.cpp new file mode 100644 index 000000000..33aca61b2 --- /dev/null +++ b/src/windows/WslcSDK/winrt/SessionSettings.cpp @@ -0,0 +1,99 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + SessionSettings.cpp + +Abstract: + + This file contains the implementation of the WinRT wrapper for the WSLC SDK SessionSettings class. + +--*/ + +#include "precomp.h" +#include "SessionSettings.h" +#include "Microsoft.WSL.Containers.SessionSettings.g.cpp" + +namespace WSLC = winrt::Microsoft::WSL::Containers; + +namespace winrt::Microsoft::WSL::Containers { +implementation::SessionSettings::SessionSettings(hstring const& name, hstring const& storagePath) : + m_name(name), m_storagePath(storagePath) +{ + winrt::check_hresult(WslcInitSessionSettings(m_name.c_str(), m_storagePath.c_str(), &m_sessionSettings)); +} + +hstring implementation::SessionSettings::Name() +{ + return hstring{m_name}; +} + +hstring implementation::SessionSettings::StoragePath() +{ + return hstring{m_storagePath}; +} + +uint32_t implementation::SessionSettings::CpuCount() +{ + return m_cpuCount; +} + +void implementation::SessionSettings::CpuCount(uint32_t value) +{ + m_cpuCount = value; + winrt::check_hresult(WslcSetSessionSettingsCpuCount(&m_sessionSettings, m_cpuCount)); +} + +uint32_t implementation::SessionSettings::MemoryMb() +{ + return m_memoryMb; +} + +void implementation::SessionSettings::MemoryMb(uint32_t value) +{ + m_memoryMb = value; + winrt::check_hresult(WslcSetSessionSettingsMemory(&m_sessionSettings, m_memoryMb)); +} + +uint32_t implementation::SessionSettings::TimeoutMS() +{ + return m_timeoutMS; +} + +void implementation::SessionSettings::TimeoutMS(uint32_t value) +{ + m_timeoutMS = value; + winrt::check_hresult(WslcSetSessionSettingsTimeout(&m_sessionSettings, m_timeoutMS)); +} + +WSLC::VhdRequirements implementation::SessionSettings::VhdRequirements() +{ + return m_vhdRequirements; +} + +void implementation::SessionSettings::VhdRequirements(WSLC::VhdRequirements const& value) +{ + m_vhdRequirements = value; + auto vhdRequirements = + m_vhdRequirements ? winrt::get_self(m_vhdRequirements)->ToStructPointer() : nullptr; + winrt::check_hresult(WslcSetSessionSettingsVhd(&m_sessionSettings, vhdRequirements)); +} + +WSLC::SessionFeatureFlags implementation::SessionSettings::FeatureFlags() +{ + return m_featureFlags; +} + +void implementation::SessionSettings::FeatureFlags(WSLC::SessionFeatureFlags const& value) +{ + m_featureFlags = value; + winrt::check_hresult(WslcSetSessionSettingsFeatureFlags(&m_sessionSettings, static_cast(m_featureFlags))); +} + +WslcSessionSettings* implementation::SessionSettings::ToStructPointer() +{ + return &m_sessionSettings; +} +} // namespace winrt::Microsoft::WSL::Containers diff --git a/src/windows/WslcSDK/winrt/SessionSettings.h b/src/windows/WslcSDK/winrt/SessionSettings.h new file mode 100644 index 000000000..113acf214 --- /dev/null +++ b/src/windows/WslcSDK/winrt/SessionSettings.h @@ -0,0 +1,60 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + SessionSettings.h + +Abstract: + + This file contains the definition of the WinRT wrapper for the WSLC SDK SessionSettings class. + +--*/ + +#pragma once +#include "Microsoft.WSL.Containers.SessionSettings.g.h" +#include "VhdRequirements.h" +#include "Helpers.h" +#include "Defaults.h" + +namespace winrt::Microsoft::WSL::Containers::implementation { +struct SessionSettings : SessionSettingsT +{ + SessionSettings() = default; + + SessionSettings(hstring const& name, hstring const& storagePath); + hstring Name(); + hstring StoragePath(); + uint32_t CpuCount(); + void CpuCount(uint32_t value); + uint32_t MemoryMb(); + void MemoryMb(uint32_t value); + uint32_t TimeoutMS(); + void TimeoutMS(uint32_t value); + winrt::Microsoft::WSL::Containers::VhdRequirements VhdRequirements(); + void VhdRequirements(winrt::Microsoft::WSL::Containers::VhdRequirements const& value); + winrt::Microsoft::WSL::Containers::SessionFeatureFlags FeatureFlags(); + void FeatureFlags(winrt::Microsoft::WSL::Containers::SessionFeatureFlags const& value); + + WslcSessionSettings* ToStructPointer(); + +private: + WslcSessionSettings m_sessionSettings{}; + std::wstring m_name; + std::wstring m_storagePath; + uint32_t m_cpuCount{s_DefaultCPUCount}; + uint32_t m_memoryMb{s_DefaultMemoryMB}; + uint32_t m_timeoutMS{s_DefaultBootTimeout}; + winrt::Microsoft::WSL::Containers::VhdRequirements m_vhdRequirements{nullptr}; + winrt::Microsoft::WSL::Containers::SessionFeatureFlags m_featureFlags{winrt::Microsoft::WSL::Containers::SessionFeatureFlags::None}; +}; +} // namespace winrt::Microsoft::WSL::Containers::implementation + +namespace winrt::Microsoft::WSL::Containers::factory_implementation { +struct SessionSettings : SessionSettingsT +{ +}; +} // namespace winrt::Microsoft::WSL::Containers::factory_implementation + +DEFINE_TYPE_HELPERS(SessionSettings); \ No newline at end of file diff --git a/src/windows/WslcSDK/winrt/VhdRequirements.cpp b/src/windows/WslcSDK/winrt/VhdRequirements.cpp new file mode 100644 index 000000000..7084c6ee6 --- /dev/null +++ b/src/windows/WslcSDK/winrt/VhdRequirements.cpp @@ -0,0 +1,47 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + VhdRequirements.cpp + +Abstract: + + This file contains the implementation of the WinRT wrapper for the WSLC SDK VhdRequirements class. + +--*/ + +#include "precomp.h" +#include "VhdRequirements.h" +#include "Microsoft.WSL.Containers.VhdRequirements.g.cpp" + +namespace winrt::Microsoft::WSL::Containers::implementation { +VhdRequirements::VhdRequirements(hstring const& name, uint64_t sizeInBytes, winrt::Microsoft::WSL::Containers::VhdType const& type) : + m_name(winrt::to_string(name)) +{ + m_vhdRequirements.name = m_name.c_str(); + m_vhdRequirements.sizeBytes = sizeInBytes; + m_vhdRequirements.type = static_cast(type); +} + +hstring VhdRequirements::Name() +{ + return winrt::to_hstring(m_name); +} + +uint64_t VhdRequirements::SizeInBytes() +{ + return m_vhdRequirements.sizeBytes; +} + +winrt::Microsoft::WSL::Containers::VhdType VhdRequirements::Type() +{ + return static_cast(m_vhdRequirements.type); +} + +WslcVhdRequirements* VhdRequirements::ToStructPointer() +{ + return &m_vhdRequirements; +} +} // namespace winrt::Microsoft::WSL::Containers::implementation \ No newline at end of file diff --git a/src/windows/WslcSDK/winrt/VhdRequirements.h b/src/windows/WslcSDK/winrt/VhdRequirements.h new file mode 100644 index 000000000..e26a9745c --- /dev/null +++ b/src/windows/WslcSDK/winrt/VhdRequirements.h @@ -0,0 +1,43 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + VhdRequirements.h + +Abstract: + + This file contains the definition of the WinRT wrapper for the WSLC SDK VhdRequirements class. + +--*/ + +#pragma once +#include "Microsoft.WSL.Containers.VhdRequirements.g.h" +#include "Helpers.h" + +namespace winrt::Microsoft::WSL::Containers::implementation { +struct VhdRequirements : VhdRequirementsT +{ + VhdRequirements() = default; + + VhdRequirements(hstring const& name, uint64_t sizeInBytes, winrt::Microsoft::WSL::Containers::VhdType const& type); + hstring Name(); + uint64_t SizeInBytes(); + winrt::Microsoft::WSL::Containers::VhdType Type(); + + WslcVhdRequirements* ToStructPointer(); + +private: + std::string m_name; + WslcVhdRequirements m_vhdRequirements{nullptr}; +}; +} // namespace winrt::Microsoft::WSL::Containers::implementation + +namespace winrt::Microsoft::WSL::Containers::factory_implementation { +struct VhdRequirements : VhdRequirementsT +{ +}; +} // namespace winrt::Microsoft::WSL::Containers::factory_implementation + +DEFINE_TYPE_HELPERS(VhdRequirements); \ No newline at end of file diff --git a/src/windows/WslcSDK/winrt/precomp.h b/src/windows/WslcSDK/winrt/precomp.h new file mode 100644 index 000000000..44d0d436c --- /dev/null +++ b/src/windows/WslcSDK/winrt/precomp.h @@ -0,0 +1,22 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + precomp.h + +Abstract: + + The precompiled header for WslcSDK/winrt. + +--*/ + +#pragma once + +#include "wslcsdk.h" + +#include +#include + +#include diff --git a/src/windows/WslcSDK/winrt/wslcsdk.idl b/src/windows/WslcSDK/winrt/wslcsdk.idl new file mode 100644 index 000000000..d2b8befdb --- /dev/null +++ b/src/windows/WslcSDK/winrt/wslcsdk.idl @@ -0,0 +1,59 @@ +/*++ + +Copyright (c) Microsoft. All rights reserved. + +Module Name: + + wslcsdk.idl + +Abstract: + + This file contains the definition of a WinRT projection of the WSL Container SDK API. + +--*/ + +namespace Microsoft.WSL.Containers +{ + runtimeclass SessionSettings + { + SessionSettings(String name, String storagePath); + + String Name { get; }; + String StoragePath { get; }; + + UInt32 CpuCount { get; set; }; + UInt32 MemoryMb { get; set; }; + UInt32 TimeoutMS { get; set; }; + VhdRequirements VhdRequirements { get; set; }; + SessionFeatureFlags FeatureFlags { get; set; }; + }; + + runtimeclass Session + { + static Session Create(SessionSettings settings); + + void Terminate(); + }; + + [flags] + enum SessionFeatureFlags + { + None = 0x00000000, + EnableGpu = 0x00000004 + }; + + enum VhdType + { + Dynamic = 0, + Fixed = 1, + }; + + runtimeclass VhdRequirements + { + VhdRequirements(String name, UInt64 sizeInBytes, VhdType type); + + String Name { get; }; + UInt64 SizeInBytes { get; }; + VhdType Type { get; }; + }; +} \ No newline at end of file diff --git a/src/windows/WslcSDK/wslcsdk.cpp b/src/windows/WslcSDK/wslcsdk.cpp index 1d7d80cdb..f9a63a38e 100644 --- a/src/windows/WslcSDK/wslcsdk.cpp +++ b/src/windows/WslcSDK/wslcsdk.cpp @@ -15,6 +15,7 @@ Module Name: #include "wslcsdk.h" #include "WslcsdkPrivate.h" +#include "Defaults.h" #include "ProgressCallback.h" #include "TerminationCallback.h" #include "Localization.h" @@ -26,12 +27,6 @@ using namespace std::string_view_literals; using namespace wsl::windows::common::wslutil; namespace { -constexpr uint32_t s_DefaultCPUCount = 2; -constexpr uint32_t s_DefaultMemoryMB = 2000; -// Maximum value per use with HVSOCKET_CONNECT_TIMEOUT_MAX -constexpr ULONG s_DefaultBootTimeout = 300000; -// Default to 1 GB -constexpr UINT64 s_DefaultStorageSize = 1000 * 1000 * 1000; #define WSLC_FLAG_VALUE_ASSERT(_wlsc_name_, _wslc_name_) \ static_assert(_wlsc_name_ == _wslc_name_, "Flag values differ: " #_wlsc_name_ " != " #_wslc_name_); diff --git a/src/windows/WslcSDK/wslcsdk.def b/src/windows/WslcSDK/wslcsdk.def index 4b78e4376..23a3a1c7f 100644 --- a/src/windows/WslcSDK/wslcsdk.def +++ b/src/windows/WslcSDK/wslcsdk.def @@ -70,8 +70,5 @@ WslcGetMissingComponents WslcGetVersion WslcInstallWithDependencies - - - - - +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE diff --git a/src/windows/wslsettings/CMakeLists.txt b/src/windows/wslsettings/CMakeLists.txt index 6b1983527..ef6f04d8a 100644 --- a/src/windows/wslsettings/CMakeLists.txt +++ b/src/windows/wslsettings/CMakeLists.txt @@ -1,6 +1,6 @@ set(TargetApp wslsettings) -project(${TargetApp} LANGUAGES CSharp) +enable_language(CSharp) # needed for csharp_set_xaml_cs_properties include(CSharpUtilities) @@ -183,21 +183,16 @@ csharp_set_xaml_cs_properties( Views/Settings/ShellPage.xaml.cs ) +configure_csharp_target(${TargetApp}) + set_property( SOURCE App.xaml PROPERTY VS_XAML_TYPE "ApplicationDefinition" ) -# Set the C# language version (defaults to 3.0). -set( - CMAKE_CSharp_FLAGS - "/langversion:latest" -) - target_compile_options( ${TargetApp} - PRIVATE "/debug:full" PRIVATE "/unsafe" ) @@ -218,23 +213,6 @@ Microsoft.Xaml.Behaviors.WinUI.Managed_${XAML_BEHAVIORS_VERSION};\ WinUIEx_${WINUIEX_VERSION}" ) -set( - TARGET_PLATFORM_VERSION - "10.0.26100.0" -) -set( - WINDOWS_TARGET_PLATFORM_VERSION - "windows${TARGET_PLATFORM_VERSION}" -) -set( - TARGET_PLATFORM_MIN_VERSION - "10.0.19041.0" -) -set( - WINDOWS_TARGET_PLATFORM_MIN_VERSION - "windows${TARGET_PLATFORM_MIN_VERSION}" -) - set_target_properties( ${TargetApp} PROPERTIES # ----- Dotnet, Windows App SDK and WinUI stuff starts here ----- @@ -252,16 +230,8 @@ set_target_properties( VS_GLOBAL_Platform "${TARGET_PLATFORM}" VS_GLOBAL_Platforms "${TARGET_PLATFORM}" VS_GLOBAL_PlatformTarget "${TARGET_PLATFORM}" - VS_GLOBAL_TargetPlatformVersion "${TARGET_PLATFORM_VERSION}" - VS_GLOBAL_TargetPlatformMinVersion "${TARGET_PLATFORM_MIN_VERSION}" - VS_GLOBAL_WindowsSdkPackageVersion "${WINDOWS_SDK_DOTNET_VERSION}" VS_GLOBAL_ImplicitUsings enable VS_GLOBAL_Nullable enable - VS_GLOBAL_AppendRuntimeIdentifierToOutputPath false - VS_GLOBAL_GenerateAssemblyInfo false - VS_GLOBAL_TargetLatestRuntimePatch false - DOTNET_SDK "Microsoft.NET.Sdk" - DOTNET_TARGET_FRAMEWORK "net8.0-${WINDOWS_TARGET_PLATFORM_VERSION}" ) configure_file(