Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 38 additions & 15 deletions src/windows/WslcSDK/wslcsdk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,30 @@ std::pair<wil::com_ptr<IWSLCSessionManager>, HRESULT> CreateSessionManagerRaw()
{
wil::com_ptr<IWSLCSessionManager> result;
HRESULT hr = CoCreateInstance(__uuidof(WSLCSessionManager), nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&result));
if (SUCCEEDED(hr))
{
WSLCVersion minimumClientVersion{};
THROW_IF_FAILED(result->GetMinimumSupportedClientVersion(&minimumClientVersion));

decltype(wsl::shared::PackageVersion) requiredClientVersion{
minimumClientVersion.Major, minimumClientVersion.Minor, minimumClientVersion.Revision};

if (requiredClientVersion > wsl::shared::PackageVersion)
{
LOG_HR_MSG(
WSLC_E_SDK_UPDATE_NEEDED,
"WSLC SDK update required. Minimum supported version: %lu.%lu.%lu, current SDK version: %lu.%lu.%lu",
minimumClientVersion.Major,
minimumClientVersion.Minor,
minimumClientVersion.Revision,
WSL_PACKAGE_VERSION_MAJOR,
WSL_PACKAGE_VERSION_MINOR,
WSL_PACKAGE_VERSION_REVISION);

return {result, WSLC_E_SDK_UPDATE_NEEDED};
}
}

return {result, hr};
}

Expand Down Expand Up @@ -330,20 +354,6 @@ wil::com_ptr<IWSLCSessionManager> CreateSessionManager()
return result;
}

bool NeedsWslRuntimeInstalled()
{
auto hr = CreateSessionManagerRaw().second;

if (SUCCEEDED(hr))
{
return false;
}
else if (hr == REGDB_E_CLASSNOTREG)
{
return true;
}
THROW_HR(hr);
}
} // namespace

// SESSION DEFINITIONS
Expand Down Expand Up @@ -1346,7 +1356,20 @@ try
WslcComponentFlags componentCheck = WSLC_COMPONENT_FLAG_NONE;

WI_SetFlagIf(componentCheck, WSLC_COMPONENT_FLAG_VIRTUAL_MACHINE_PLATFORM, NeedsVirtualMachineServicesInstalled());
WI_SetFlagIf(componentCheck, WSLC_COMPONENT_FLAG_WSL_PACKAGE, NeedsWslRuntimeInstalled());

auto hr = CreateSessionManagerRaw().second;
if (hr == REGDB_E_CLASSNOTREG)
{
WI_SetFlag(componentCheck, WSLC_COMPONENT_FLAG_WSL_PACKAGE);
}
else if (hr == WSLC_E_SDK_UPDATE_NEEDED)
{
WI_SetFlag(componentCheck, WSLC_COMPONENT_FLAG_SDK_NEEDS_UPDATE);
}
else if (FAILED(hr))
{
THROW_HR(hr);
}

*canRun = componentCheck == WSLC_COMPONENT_FLAG_NONE ? TRUE : FALSE;
*missingComponents = componentCheck;
Expand Down
10 changes: 10 additions & 0 deletions src/windows/WslcSDK/wslcsdk.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ Module Name:

EXTERN_C_START

// WSLC specific error codes
#define WSLC_E_BASE (0x0600)
#define WSLC_E_IMAGE_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 1) /* 0x80040601 */
#define WSLC_E_CONTAINER_PREFIX_AMBIGUOUS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 2) /* 0x80040602 */
#define WSLC_E_CONTAINER_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 3) /* 0x80040603 */
#define WSLC_E_VOLUME_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 4) /* 0x80040604 */
#define WSLC_E_SDK_UPDATE_NEEDED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 5) /* 0x80040605 */

// Session values
#define WSLC_SESSION_OPTIONS_SIZE 80
#define WSLC_SESSION_OPTIONS_ALIGNMENT 8
Expand Down Expand Up @@ -494,6 +502,8 @@ typedef enum WslcComponentFlags
WSLC_COMPONENT_FLAG_VIRTUAL_MACHINE_PLATFORM = 1,
// The WSL runtime package, at an appropriate version to provide support for WSLC.
WSLC_COMPONENT_FLAG_WSL_PACKAGE = 2,
// Set if the WSLC SDK itself needs to be updated.
WSLC_COMPONENT_FLAG_SDK_NEEDS_UPDATE = 4,
} WslcComponentFlags;

DEFINE_ENUM_FLAG_OPERATORS(WslcComponentFlags);
Expand Down
35 changes: 27 additions & 8 deletions src/windows/service/exe/WSLCSessionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,6 @@ void WSLCSessionManagerImpl::ListSessions(_Out_ WSLCSessionInformation** Session
*SessionsCount = static_cast<ULONG>(sessionInfo.size());
}

void WSLCSessionManagerImpl::GetVersion(_Out_ WSLCVersion* Version)
{
Version->Major = WSL_PACKAGE_VERSION_MAJOR;
Version->Minor = WSL_PACKAGE_VERSION_MINOR;
Version->Revision = WSL_PACKAGE_VERSION_REVISION;
}

WSLCSessionInitSettings WSLCSessionManagerImpl::CreateSessionSettings(_In_ ULONG SessionId, _In_ DWORD CreatorPid, _In_ const WSLCSessionSettings* Settings)
{
WSLCSessionInitSettings sessionSettings{};
Expand Down Expand Up @@ -276,7 +269,33 @@ WSLCSessionManager::WSLCSessionManager(WSLCSessionManagerImpl* Impl) : COMImplCl

HRESULT WSLCSessionManager::GetVersion(_Out_ WSLCVersion* Version)
{
return CallImpl(&WSLCSessionManagerImpl::GetVersion, Version);
Version->Major = WSL_PACKAGE_VERSION_MAJOR;
Version->Minor = WSL_PACKAGE_VERSION_MINOR;
Version->Revision = WSL_PACKAGE_VERSION_REVISION;

return S_OK;
}

HRESULT WSLCSessionManager::GetMinimumSupportedClientVersion(_Out_ WSLCVersion* Version)
{
constexpr std::tuple<uint32_t, uint32_t, uint32_t> c_minClientVersion{2, 8, 0};

// If the current version is below the minimum version, return the current version for convenience.
// TODO: Remove once 2.8.0 is published.
if constexpr (wsl::shared::PackageVersion < c_minClientVersion)
{
Version->Major = WSL_PACKAGE_VERSION_MAJOR;
Version->Minor = WSL_PACKAGE_VERSION_MINOR;
Version->Revision = WSL_PACKAGE_VERSION_REVISION;
}
else
{
Version->Major = std::get<0>(c_minClientVersion);
Version->Minor = std::get<1>(c_minClientVersion);
Version->Revision = std::get<2>(c_minClientVersion);
}

return S_OK;
}

HRESULT WSLCSessionManager::CreateSession(const WSLCSessionSettings* WslcSessionSettings, WSLCSessionFlags Flags, IWSLCSession** WslcSession)
Expand Down
2 changes: 1 addition & 1 deletion src/windows/service/exe/WSLCSessionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ class WSLCSessionManagerImpl
WSLCSessionManagerImpl() = default;
~WSLCSessionManagerImpl();

void GetVersion(_Out_ WSLCVersion* Version);
void CreateSession(const WSLCSessionSettings* WslcSessionSettings, WSLCSessionFlags Flags, IWSLCSession** WslcSession);
void ListSessions(_Out_ WSLCSessionInformation** Sessions, _Out_ ULONG* SessionsCount);
void OpenSession(_In_ ULONG Id, _Out_ IWSLCSession** Session);
Expand Down Expand Up @@ -172,6 +171,7 @@ class DECLSPEC_UUID("a9b7a1b9-0671-405c-95f1-e0612cb4ce8f") WSLCSessionManager
WSLCSessionManager(wsl::windows::service::wslc::WSLCSessionManagerImpl* Impl);

IFACEMETHOD(GetVersion)(_Out_ WSLCVersion* Version) override;
IFACEMETHOD(GetMinimumSupportedClientVersion)(_Out_ WSLCVersion* Version) override;
IFACEMETHOD(CreateSession)(const WSLCSessionSettings* WslcSessionSettings, WSLCSessionFlags Flags, IWSLCSession** WslcSession) override;
IFACEMETHOD(ListSessions)(_Out_ WSLCSessionInformation** Sessions, _Out_ ULONG* SessionsCount) override;
IFACEMETHOD(OpenSession)(_In_ ULONG Id, _Out_ IWSLCSession** Session) override;
Expand Down
4 changes: 3 additions & 1 deletion src/windows/service/inc/wslc.idl
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,7 @@ typedef enum _WSLCSessionFlags
interface IWSLCSessionManager : IUnknown
{
HRESULT GetVersion([out] WSLCVersion* Version);
HRESULT GetMinimumSupportedClientVersion([out] WSLCVersion* Version);

// Session management.
HRESULT CreateSession([in, ref] const WSLCSessionSettings* Settings, WSLCSessionFlags Flags, [out] IWSLCSession** Session);
Expand All @@ -690,4 +691,5 @@ cpp_quote("#define WSLC_E_BASE (0x0600)")
cpp_quote("#define WSLC_E_IMAGE_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 1) /* 0x80040601 */")
cpp_quote("#define WSLC_E_CONTAINER_PREFIX_AMBIGUOUS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 2) /* 0x80040602 */")
cpp_quote("#define WSLC_E_CONTAINER_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 3) /* 0x80040603 */")
cpp_quote("#define WSLC_E_VOLUME_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 4) /* 0x80040604 */")
cpp_quote("#define WSLC_E_VOLUME_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 4) /* 0x80040604 */")
cpp_quote("#define WSLC_E_SDK_UPDATE_NEEDED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 5) /* 0x80040605 */")
25 changes: 25 additions & 0 deletions test/windows/WSLCTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,31 @@ class WSLCTests
VERIFY_ARE_EQUAL(version.Revision, WSL_PACKAGE_VERSION_REVISION);
}

TEST_METHOD(GetMinimumSupportedVersion)
{
WSL2_TEST_ONLY();

wil::com_ptr<IWSLCSessionManager> sessionManager;
VERIFY_SUCCEEDED(CoCreateInstance(__uuidof(WSLCSessionManager), nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&sessionManager)));

WSLCVersion version{};

VERIFY_SUCCEEDED(sessionManager->GetMinimumSupportedClientVersion(&version));

if (WSL_PACKAGE_VERSION_MAJOR < 2 || (WSL_PACKAGE_VERSION_MAJOR == 2 && WSL_PACKAGE_VERSION_MINOR < 8))
{
VERIFY_ARE_EQUAL(version.Major, WSL_PACKAGE_VERSION_MAJOR);
VERIFY_ARE_EQUAL(version.Minor, WSL_PACKAGE_VERSION_MINOR);
VERIFY_ARE_EQUAL(version.Revision, WSL_PACKAGE_VERSION_REVISION);
}
else
{
VERIFY_ARE_EQUAL(version.Major, 2);
VERIFY_ARE_EQUAL(version.Minor, 8);
VERIFY_ARE_EQUAL(version.Revision, 0);
}
}

static RunningWSLCProcess::ProcessResult RunCommand(IWSLCSession* session, const std::vector<std::string>& command, int timeout = 600000)
{
WSLCProcessLauncher process(command[0], command);
Expand Down