Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
694443e
Add Clang requirement to vswhere usage
JohnMcPMS Feb 9, 2026
437a912
EOD checkin - session settings done, creation needs work
JohnMcPMS Feb 10, 2026
4216049
Primary session management implemented, needs TODOs looked at, needs …
JohnMcPMS Feb 10, 2026
cb3f04d
Merge from user/rechfr
JohnMcPMS Feb 10, 2026
5fca876
Post-merge fixes and implementations
JohnMcPMS Feb 10, 2026
243d358
Pull image almost impl
JohnMcPMS Feb 11, 2026
ca94797
WSLA error info wrapper and use
JohnMcPMS Feb 11, 2026
6ca21d3
Merge from user/richfr
JohnMcPMS Feb 11, 2026
d15c57e
Merge branch 'user/richfr' into sdk-session
JohnMcPMS Feb 11, 2026
694734e
Update for wsla feature merge
JohnMcPMS Feb 11, 2026
3181022
Implement for demo and fixes for same
JohnMcPMS Feb 12, 2026
37e9a89
Swap to always attach at container start
JohnMcPMS Feb 12, 2026
877bf26
Merge from user/richfr
JohnMcPMS Feb 12, 2026
4557def
Update for pull and implement container flags and delete
JohnMcPMS Feb 12, 2026
7f800ed
clang format
JohnMcPMS Feb 12, 2026
d33a7fa
implement getprocessexitevent
JohnMcPMS Feb 12, 2026
144d00c
Merge branch 'feature/wsl-for-apps' into sdk-session
JohnMcPMS Feb 12, 2026
bc357c7
cleanup
JohnMcPMS Feb 12, 2026
0bdb1df
clang format
JohnMcPMS Feb 12, 2026
f542a14
clang format
JohnMcPMS Feb 12, 2026
c65c4a2
Update src/windows/WslcSDK/ProgressCallback.h
JohnMcPMS Feb 12, 2026
61f1c5e
PR feedback
JohnMcPMS Feb 13, 2026
32d797b
clang format
JohnMcPMS Feb 13, 2026
713dff4
Revert cmake cp
JohnMcPMS Feb 13, 2026
fd8d237
Merge remote-tracking branch 'upstream/feature/wsl-for-apps' into sdk…
JohnMcPMS Feb 13, 2026
42a4313
PR feedback
JohnMcPMS Feb 13, 2026
fa31680
PR feedback
JohnMcPMS Feb 13, 2026
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
2 changes: 1 addition & 1 deletion src/shared/inc/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class MessageWriter

// Write an array of strings.
// Each field is prefixed with its size as int32_t, and the array ends with a -1 terminator.
void WriteStringArray(unsigned int& Index, const char** String, size_t Count)
void WriteStringArray(unsigned int& Index, const char* const* String, size_t Count)
{
size_t totalSize = sizeof(int32_t); // The array ends with a '-1' terminator.
for (size_t i = 0; i < Count; i++)
Expand Down
9 changes: 8 additions & 1 deletion src/windows/WslcSDK/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
set(SOURCES wslcsdk.cpp)
set(SOURCES
ProgressCallback.cpp
TerminationCallback.cpp
wslcsdk.cpp
WslcsdkPrivate.cpp
)
set(HEADERS
ProgressCallback.h
TerminationCallback.h
wslcsdk.h
WslcsdkPrivate.h
)
Expand Down
74 changes: 74 additions & 0 deletions src/windows/WslcSDK/ProgressCallback.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*++

Copyright (c) Microsoft. All rights reserved.

Module Name:

ProgressCallback.cpp

Abstract:

Implementation of a type that implements IProgressCallback.

--*/
#include "precomp.h"
#include "ProgressCallback.h"

using namespace std::string_view_literals;

namespace {
WslcImageProgressStatus ConvertStatus(LPCSTR Status)
{
#define WSLC_STRING_TO_STATUS_MAPPING(_status_, _string_) \
if (_string_##sv == Status) \
{ \
return _status_; \
}

// TODO: Mapping engine strings to status values seems fragile.
// WSLA is intentionally avoiding this kind of thing for localization of engine strings, which amounts to the same
// thing. If we keep this, a test should be added to explicitly validate that each status is returned properly.
WSLC_STRING_TO_STATUS_MAPPING(WSLC_IMAGE_PROGRESS_STATUS_PULLING, "Pulling fs layer");
WSLC_STRING_TO_STATUS_MAPPING(WSLC_IMAGE_PROGRESS_STATUS_WAITING, "Waiting");
WSLC_STRING_TO_STATUS_MAPPING(WSLC_IMAGE_PROGRESS_STATUS_DOWNLOADING, "Downloading");
WSLC_STRING_TO_STATUS_MAPPING(WSLC_IMAGE_PROGRESS_STATUS_VERIFYING, "Verifying Checksum");
WSLC_STRING_TO_STATUS_MAPPING(WSLC_IMAGE_PROGRESS_STATUS_EXTRACTING, "Extracting");
WSLC_STRING_TO_STATUS_MAPPING(WSLC_IMAGE_PROGRESS_STATUS_COMPLETE, "Pull complete");
Comment thread
JohnMcPMS marked this conversation as resolved.

return WSLC_IMAGE_PROGRESS_STATUS_UNKNOWN;
}
} // namespace

ProgressCallback::ProgressCallback(WslcContainerImageProgressCallback callback, PVOID context) :
m_callback(callback), m_context(context)
{
}

HRESULT STDMETHODCALLTYPE ProgressCallback::OnProgress(LPCSTR Status, LPCSTR Id, ULONGLONG Current, ULONGLONG Total)
{
if (m_callback)
{
WslcImageProgressMessage message{};

message.id = Id;
message.status = ConvertStatus(Status);
message.detail.current = Current;
message.detail.total = Total;

return m_callback(&message, m_context);
}

return S_OK;
}

winrt::com_ptr<ProgressCallback> ProgressCallback::CreateIf(const WslcPullImageOptions* options)
{
if (options->progressCallback)
{
return winrt::make_self<ProgressCallback>(options->progressCallback, options->progressCallbackContext);
}
else
{
return nullptr;
}
}
32 changes: 32 additions & 0 deletions src/windows/WslcSDK/ProgressCallback.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*++

Copyright (c) Microsoft. All rights reserved.

Module Name:

ProgressCallback.h

Abstract:

Header for a type that implements IProgressCallback.

--*/
#pragma once
#include "wslaservice.h"
#include "wslcsdkprivate.h"
#include <winrt/base.h>

struct ProgressCallback : public winrt::implements<ProgressCallback, IProgressCallback>
{
ProgressCallback(WslcContainerImageProgressCallback callback, PVOID context);

// IProgressCallback
HRESULT STDMETHODCALLTYPE OnProgress(LPCSTR Status, LPCSTR Id, ULONGLONG Current, ULONGLONG Total) override;

// Creates a ProgressCallback if the options provides a callback.
static winrt::com_ptr<ProgressCallback> CreateIf(const WslcPullImageOptions* options);

private:
WslcContainerImageProgressCallback m_callback = nullptr;
PVOID m_context = nullptr;
};
58 changes: 58 additions & 0 deletions src/windows/WslcSDK/TerminationCallback.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*++

Copyright (c) Microsoft. All rights reserved.

Module Name:

TerminationCallback.cpp

Abstract:

Implementation of a type that implements ITerminationCallback.

--*/
#include "precomp.h"
#include "TerminationCallback.h"

namespace {
WslcSessionTerminationReason ConvertReason(WSLAVirtualMachineTerminationReason Reason)
{
switch (Reason)
{
case WSLAVirtualMachineTerminationReasonShutdown:
return WSLC_SESSION_TERMINATION_REASON_SHUTDOWN;
case WSLAVirtualMachineTerminationReasonCrashed:
return WSLC_SESSION_TERMINATION_REASON_CRASHED;
default:
return WSLC_SESSION_TERMINATION_REASON_UNKNOWN;
}
}
} // namespace

TerminationCallback::TerminationCallback(WslcSessionTerminationCallback callback, PVOID context) :
m_callback(callback), m_context(context)
{
}

// TODO: Details from the runtime are dropped; should the SDK callback function be updated to include the reasons string?
HRESULT STDMETHODCALLTYPE TerminationCallback::OnTermination(WSLAVirtualMachineTerminationReason Reason, LPCWSTR)
{
if (m_callback)
{
m_callback(ConvertReason(Reason), m_context);
}

return S_OK;
}

winrt::com_ptr<TerminationCallback> TerminationCallback::CreateIf(const WSLC_SESSION_OPTIONS_INTERNAL* options)
{
if (options->terminationCallback)
{
return winrt::make_self<TerminationCallback>(options->terminationCallback, options->terminationCallbackContext);
}
else
{
return nullptr;
}
}
32 changes: 32 additions & 0 deletions src/windows/WslcSDK/TerminationCallback.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*++

Copyright (c) Microsoft. All rights reserved.

Module Name:

TerminationCallback.h

Abstract:

Header for a type that implements ITerminationCallback.

--*/
#pragma once
#include "wslaservice.h"
#include "wslcsdkprivate.h"
#include <winrt/base.h>

struct TerminationCallback : public winrt::implements<TerminationCallback, ITerminationCallback>
{
TerminationCallback(WslcSessionTerminationCallback callback, PVOID context);

// ITerminationCallback
HRESULT STDMETHODCALLTYPE OnTermination(WSLAVirtualMachineTerminationReason Reason, LPCWSTR Details) override;

// Creates a TerminationCallback if the options provides a callback.
static winrt::com_ptr<TerminationCallback> CreateIf(const WSLC_SESSION_OPTIONS_INTERNAL* options);

private:
WslcSessionTerminationCallback m_callback = nullptr;
PVOID m_context = nullptr;
};
46 changes: 46 additions & 0 deletions src/windows/WslcSDK/WslcsdkPrivate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*++

Copyright (c) Microsoft. All rights reserved.

Module Name:

WslcSDKPrivate.cpp

Abstract:

This file contains the private WSL Container SDK implementations.

--*/
#include "precomp.h"

#include "wslcsdkprivate.h"

WSLC_SESSION_OPTIONS_INTERNAL* GetInternalType(WslcSessionSettings* settings)
{
return reinterpret_cast<WSLC_SESSION_OPTIONS_INTERNAL*>(settings);
}

WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL* GetInternalType(WslcProcessSettings* settings)
{
return reinterpret_cast<WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL*>(settings);
}

WSLC_CONTAINER_OPTIONS_INTERNAL* GetInternalType(WslcContainerSettings* settings)
{
return reinterpret_cast<WSLC_CONTAINER_OPTIONS_INTERNAL*>(settings);
}

WslcSessionImpl* GetInternalType(WslcSession handle)
{
return reinterpret_cast<WslcSessionImpl*>(handle);
}

WslcContainerImpl* GetInternalType(WslcContainer handle)
{
return reinterpret_cast<WslcContainerImpl*>(handle);
}

WslcProcessImpl* GetInternalType(WslcProcess handle)
{
return reinterpret_cast<WslcProcessImpl*>(handle);
}
45 changes: 41 additions & 4 deletions src/windows/WslcSDK/WslcsdkPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ typedef struct WSLC_SESSION_OPTIONS_INTERNAL
PCWSTR storagePath;

uint32_t cpuCount;
uint64_t memoryMb;
uint32_t memoryMb;
uint32_t timeoutMS;

WslcVhdRequirements vhdRequirements;
Expand All @@ -42,13 +42,17 @@ static_assert(
__alignof(WSLC_SESSION_OPTIONS_INTERNAL) == WSLC_SESSION_OPTIONS_ALIGNMENT,
"WSLC_SESSION_OPTIONS_INTERNAL alignment mismatch");

static_assert(std::is_trivial_v<WSLC_SESSION_OPTIONS_INTERNAL>, "WSLC_SESSION_OPTIONS_INTERNAL must be trivial");

WSLC_SESSION_OPTIONS_INTERNAL* GetInternalType(WslcSessionSettings* settings);

// PROCESS DEFINITIONS
typedef struct WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL
{
PCSTR executable; // path to executable inside container
PCSTR* commandLine;
PCSTR const* commandLine;
uint32_t commandLineCount;
PCSTR* environment;
PCSTR const* environment;
uint32_t environmentCount;
PCSTR currentDirectory;
} WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL;
Expand All @@ -60,6 +64,11 @@ static_assert(
__alignof(WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL) == WSLC_CONTAINER_PROCESS_OPTIONS_ALIGNMENT,
"WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL must be 8-byte aligned");

static_assert(
std::is_trivial_v<WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL>, "WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL must be trivial");

WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL* GetInternalType(WslcProcessSettings* settings);

// CONTAINER DEFINITIONS
typedef struct WSLC_CONTAINER_OPTIONS_INTERNAL
{
Expand All @@ -76,24 +85,52 @@ typedef struct WSLC_CONTAINER_OPTIONS_INTERNAL
WslcContainerFlags containerFlags;

} WSLC_CONTAINER_OPTIONS_INTERNAL;

static_assert(
sizeof(WSLC_CONTAINER_OPTIONS_INTERNAL) == WSLC_CONTAINER_OPTIONS_SIZE, "WSLC_CONTAINER_OPTIONS_INTERNAL must be 80 bytes");
static_assert(
__alignof(WSLC_CONTAINER_OPTIONS_INTERNAL) == WSLC_CONTAINER_OPTIONS_ALIGNMENT,
"WSLC_CONTAINER_OPTIONS_INTERNAL must be 8-byte aligned");

static_assert(std::is_trivial_v<WSLC_CONTAINER_OPTIONS_INTERNAL>, "WSLC_CONTAINER_OPTIONS_INTERNAL must be trivial");

WSLC_CONTAINER_OPTIONS_INTERNAL* GetInternalType(WslcContainerSettings* settings);

// Use to allocate the actual objects on the heap to keep it alive.
struct WslcSessionImpl
{
wil::com_ptr<IWSLASessionManager> sessionManager;
wil::com_ptr<IWSLASession> session;
wil::com_ptr<ITerminationCallback> terminationCallback;
};

WslcSessionImpl* GetInternalType(WslcSession handle);

struct WslcContainerImpl
{
wil::com_ptr<IWSLAContainer> container;
};

WslcContainerImpl* GetInternalType(WslcContainer handle);

struct WslcProcessImpl
{
wil::com_ptr<IWSLAProcess> process;
};

WslcProcessImpl* GetInternalType(WslcProcess handle);

// Converts to the internal type and throws an error on null input.
template <typename T>
auto CheckAndGetInternalType(T* value)
{
THROW_HR_IF_NULL(E_POINTER, value);
return GetInternalType(value);
}

// Converts to the internal type and throws an error on null input.
template <typename T>
auto CheckAndGetInternalTypeUniquePointer(T* value)
{
THROW_HR_IF_NULL(E_POINTER, value);
return std::unique_ptr<std::remove_pointer_t<decltype(GetInternalType(value))>>{GetInternalType(value)};
}
Loading