Skip to content

Add a new API to query the earliest supported client version#40067

Draft
OneBlue wants to merge 2 commits intofeature/wsl-for-appsfrom
user/oneblue/client-version-check
Draft

Add a new API to query the earliest supported client version#40067
OneBlue wants to merge 2 commits intofeature/wsl-for-appsfrom
user/oneblue/client-version-check

Conversation

@OneBlue
Copy link
Copy Markdown
Collaborator

@OneBlue OneBlue commented Apr 1, 2026

Summary of the Pull Request

This change adds a new COM API to check the earliest supported client version, and SDK logic to fail with a specific error code if the SDK is too old

PR Checklist

  • Closes: Link to issue #xxx
  • Communication: I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected
  • Tests: Added/updated if needed and all pass
  • Localization: All end user facing strings can be localized
  • Dev docs: Added/updated if needed
  • Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

Detailed Description of the Pull Request / Additional comments

Validation Steps Performed

Copilot AI review requested due to automatic review settings April 1, 2026 21:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new WSLC COM API intended to let clients query the minimum (earliest) supported client version, and adds SDK-side gating that fails with a WSLC-specific HRESULT when the SDK is older than what the runtime requires.

Changes:

  • Adds GetMinimumSupportedClientVersion to the session manager COM surface and implements it in the service.
  • Adds a new WSLC-specific HRESULT (WSLC_E_SDK_UPDATED_NEEDED) and SDK logic to enforce a minimum supported client version.
  • Refactors GetVersion implementation in WSLCSessionManager (moves it out of the Impl forwarding path).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

File Description
src/windows/WslcSDK/wslcsdk.h Adds WSLC HRESULT macro definitions for SDK consumers.
src/windows/WslcSDK/wslcsdk.cpp Calls new COM method and throws a WSLC-specific error if SDK version is too old.
src/windows/service/inc/wslc.idl Extends COM interface with a new method and adds an exported HRESULT constant.
src/windows/service/exe/WSLCSessionManager.h / .cpp Implements the new minimum-supported-version query on the service side.

Comment on lines +23 to +29
// 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_UPDATED_NEEDED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 5) /* 0x80040605 */
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WSLC error codes are now defined in this public header, but internal SDK code also includes the MIDL-generated wslc.h (via WslcsdkPrivate.h), which already defines these macros via cpp_quote. This will cause macro redefinition warnings (often /WX) when building the SDK. Consider wrapping these #defines with #ifndef guards or moving the shared HRESULT definitions to a single header included by both.

Suggested change
// 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_UPDATED_NEEDED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 5) /* 0x80040605 */
// WSLC specific error codes
#ifndef WSLC_E_BASE
#define WSLC_E_BASE (0x0600)
#endif
#ifndef WSLC_E_IMAGE_NOT_FOUND
#define WSLC_E_IMAGE_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 1) /* 0x80040601 */
#endif
#ifndef WSLC_E_CONTAINER_PREFIX_AMBIGUOUS
#define WSLC_E_CONTAINER_PREFIX_AMBIGUOUS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 2) /* 0x80040602 */
#endif
#ifndef WSLC_E_CONTAINER_NOT_FOUND
#define WSLC_E_CONTAINER_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 3) /* 0x80040603 */
#endif
#ifndef WSLC_E_VOLUME_NOT_FOUND
#define WSLC_E_VOLUME_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 4) /* 0x80040604 */
#endif
#ifndef WSLC_E_SDK_UPDATED_NEEDED
#define WSLC_E_SDK_UPDATED_NEEDED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 5) /* 0x80040605 */
#endif

Copilot uses AI. Check for mistakes.
#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_UPDATED_NEEDED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 5) /* 0x80040605 */
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new HRESULT name WSLC_E_SDK_UPDATED_NEEDED appears to have a typo/awkward tense ("UPDATED" vs "UPDATE"). Since this constant is part of the public API surface (IDL + SDK header), it’s best to correct the name now (e.g., WSLC_E_SDK_UPDATE_NEEDED/WSLC_E_SDK_UPDATE_REQUIRED) before it becomes a compatibility burden.

Suggested change
#define WSLC_E_SDK_UPDATED_NEEDED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 5) /* 0x80040605 */
#define WSLC_E_SDK_UPDATE_NEEDED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 5) /* 0x80040605 */

Copilot uses AI. Check for mistakes.
decltype(wsl::shared::PackageVersion) requiredClientVersion{
minimumClientVersion.Major, minimumClientVersion.Minor, minimumClientVersion.Revision};

THROW_HR_IF_MSG(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This throw would go into CreateSessionManager and instead we would return the HR so that CanRun succeeds with a missing component rather than failing. Really with this API I think the SDK stuff would be refactored in several ways.

@benhillis
Copy link
Copy Markdown
Member

I spoke with @OneBlue, I think we should consider COM interface versioning a bit more. The problem with this solution is it required a checked-in version, and versions are controlled by git tags, so there is a chicken and egg problem.

@JohnMcPMS
Copy link
Copy Markdown
Member

I spoke with @OneBlue, I think we should consider COM interface versioning a bit more. The problem with this solution is it required a checked-in version, and versions are controlled by git tags, so there is a chicken and egg problem.

His original idea for a IsClientVersionCompatible moves the problem to deciding about already released versions and allows for the same binary choice but removes the ability to know to what version one must upgrade. Given that this upgrade choice is a development time one for the SDK consumer, it seems acceptable.

No matter how we do this, we would only want to break older SDK usage if it were a security issue. We can do that anyway, just less gracefully, without anything new (ex. making all ISession1 functions fail; must use ISession2 instead). The question becomes if it is worth building up the pre-check if it is extremely rare to happen and then no clients actually bother. A very specific HRESULT and documentation is probably good enough without the extra work from everyone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants