Move the SDK API to its own IDL file (#40784)
* Save state * Save state * Save state * Cleanup * Cleanup * Cleanup * Merge * Format * Apply PR feedback --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Blue committed
Jun 17, 2026 at 14:55 UTC
8bc3684ec9460f452750454ac4e430f3376474b5
28 files changed
+1661
-315
msipackage/package.wix.in
+56
@@ -378,6 +378,62 @@
378
</RegistryKey>
379
</RegistryKey>
380
381
+ <!-- IWSLCCompatCrashDumpCallback-->
382
+ <RegistryKey Root="HKCR" Key="Interface\{EAA15E20-7FCC-485B-B798-ED4095DBACA5}">
383
+ <RegistryValue Value="IWSLCCompatCrashDumpCallback" Type="string" />
384
+ <RegistryKey Key="ProxyStubClsid32">
385
+ <RegistryValue Value="{4EA0C6DD-E9FF-48E7-994E-13A31D10DC60}" Type="string" />
386
+ </RegistryKey>
387
+ </RegistryKey>
388
+
389
+ <!-- IWSLCCompatProgressCallback-->
390
+ <RegistryKey Root="HKCR" Key="Interface\{06154F2A-ACA7-461E-94FC-92781BA1F6F6}">
391
+ <RegistryValue Value="IWSLCCompatProgressCallback" Type="string" />
392
+ <RegistryKey Key="ProxyStubClsid32">
393
+ <RegistryValue Value="{4EA0C6DD-E9FF-48E7-994E-13A31D10DC60}" Type="string" />
394
+ </RegistryKey>
395
+ </RegistryKey>
396
+
397
+ <!-- IWSLCCompatWarningCallback-->
398
+ <RegistryKey Root="HKCR" Key="Interface\{290C58A1-328C-4E90-B09B-0A9D32C40074}">
399
+ <RegistryValue Value="IWSLCCompatWarningCallback" Type="string" />
400
+ <RegistryKey Key="ProxyStubClsid32">
401
+ <RegistryValue Value="{4EA0C6DD-E9FF-48E7-994E-13A31D10DC60}" Type="string" />
402
+ </RegistryKey>
403
+ </RegistryKey>
404
+
405
+ <!-- IWSLCCompatProcess-->
406
+ <RegistryKey Root="HKCR" Key="Interface\{AC69DD0D-6616-4C4F-91F2-C39D6034EA82}">
407
+ <RegistryValue Value="IWSLCCompatProcess" Type="string" />
408
+ <RegistryKey Key="ProxyStubClsid32">
409
+ <RegistryValue Value="{4EA0C6DD-E9FF-48E7-994E-13A31D10DC60}" Type="string" />
410
+ </RegistryKey>
411
+ </RegistryKey>
412
+
413
+ <!-- IWSLCCompatContainer-->
414
+ <RegistryKey Root="HKCR" Key="Interface\{8C3C91FA-D550-41B9-AD9D-23DCBF96F549}">
415
+ <RegistryValue Value="IWSLCCompatContainer" Type="string" />
416
+ <RegistryKey Key="ProxyStubClsid32">
417
+ <RegistryValue Value="{4EA0C6DD-E9FF-48E7-994E-13A31D10DC60}" Type="string" />
418
+ </RegistryKey>
419
+ </RegistryKey>
420
+
421
+ <!-- IWSLCCompatSession-->
422
+ <RegistryKey Root="HKCR" Key="Interface\{DD7B2EF9-AA01-4F21-8A3A-29D394CBB579}">
423
+ <RegistryValue Value="IWSLCCompatSession" Type="string" />
424
+ <RegistryKey Key="ProxyStubClsid32">
425
+ <RegistryValue Value="{4EA0C6DD-E9FF-48E7-994E-13A31D10DC60}" Type="string" />
426
+ </RegistryKey>
427
+ </RegistryKey>
428
+
429
+ <!-- IWSLCCompatSessionManager-->
430
+ <RegistryKey Root="HKCR" Key="Interface\{279F2047-DA35-45A3-B671-AFD2302D5D16}">
431
+ <RegistryValue Value="IWSLCCompatSessionManager" Type="string" />
432
+ <RegistryKey Key="ProxyStubClsid32">
433
+ <RegistryValue Value="{4EA0C6DD-E9FF-48E7-994E-13A31D10DC60}" Type="string" />
434
+ </RegistryKey>
435
+ </RegistryKey>
436
+
437
<File Id="wslcsession.exe" Source="${BIN}/wslcsession.exe" />
438
</Component>
439
<Component Id="wslg" Guid="F0C8D6BA-1502-41E7-BF72-D93DFA134731" UninstallWhenSuperseded="yes" DisableRegistryReflection="yes" Bitness="always64">
src/windows/WslcSDK/CrashDumpCallback.cpp
+1
-1
@@ -8,7 +8,7 @@ Module Name:
8
9
Abstract:
10
11
- Implementation of a type that implements ICrashDumpCallback.
11
+ Implementation of a type that implements IWSLCCompatCrashDumpCallback.
12
13
--*/
14
#include "precomp.h"
src/windows/WslcSDK/CrashDumpCallback.h
+5
-5
@@ -8,21 +8,21 @@ Module Name:
8
9
Abstract:
10
11
- Header for a type that implements ICrashDumpCallback. Bridges the COM
12
- ICrashDumpCallback interface back to the C-style SDK callback registered
11
+ Header for a type that implements IWSLCCompatCrashDumpCallback. Bridges the COM
12
+ IWSLCCompatCrashDumpCallback interface back to the C-style SDK callback registered
13
via WslcRegisterSessionCrashDumpCallback.
14
15
--*/
16
#pragma once
17
-#include "wslc.h"
17
+#include "WSLCCompat.h"
18
#include "wslcsdkprivate.h"
19
#include <winrt/base.h>
20
21
-struct CrashDumpCallback : public winrt::implements<CrashDumpCallback, ICrashDumpCallback>
21
+struct CrashDumpCallback : public winrt::implements<CrashDumpCallback, IWSLCCompatCrashDumpCallback>
22
{
23
CrashDumpCallback(WslcSessionCrashDumpCallback callback, PVOID context);
24
25
- // ICrashDumpCallback
25
+ // IWSLCCompatCrashDumpCallback
26
HRESULT STDMETHODCALLTYPE OnCrashDump(_In_ LPCWSTR DumpPath, _In_opt_ LPCSTR ProcessName, _In_ ULONGLONG Pid, _In_ ULONG Signal, _In_ ULONGLONG Timestamp) override;
27
28
private:
src/windows/WslcSDK/IOCallback.cpp
+5
-4
@@ -14,7 +14,7 @@ Abstract:
14
#include "precomp.h"
15
#include "WslcsdkPrivate.h"
16
17
-IOCallback::IOCallback(IWSLCProcess* process, const WslcContainerProcessIOCallbackOptions& options) :
17
+IOCallback::IOCallback(IWSLCCompatProcess* process, const WslcContainerProcessIOCallbackOptions& options) :
18
m_process(process), m_callbackOptions(std::make_unique<WslcContainerProcessIOCallbackOptions>(options))
19
{
20
using namespace wsl::windows::common::io;
@@ -119,11 +119,12 @@ bool IOCallback::HasIOCallback(const WslcContainerProcessIOCallbackOptions& opti
119
return options.onStdOut || options.onStdErr || options.onExit;
120
}
121
122
-wil::unique_handle IOCallback::GetIOHandle(IWSLCProcess* process, WslcProcessIOHandle ioHandle)
122
+wil::unique_handle IOCallback::GetIOHandle(IWSLCCompatProcess* process, WslcProcessIOHandle ioHandle)
123
{
124
- wsl::windows::common::wslutil::COMOutputHandle handle;
124
+ WSLCCompatHandle handle{};
125
126
THROW_IF_FAILED(process->GetStdHandle(static_cast<WSLCFD>(static_cast<std::underlying_type_t<WslcProcessIOHandle>>(ioHandle)), &handle));
127
128
- return handle.Release();
128
+ // The handle value is the same regardless of the union member that was populated.
129
+ return wil::unique_handle{handle.Handle.File};
130
}
src/windows/WslcSDK/IOCallback.h
+4
-4
@@ -12,7 +12,7 @@ Abstract:
12
13
--*/
14
#pragma once
15
-#include "wslc.h"
15
+#include "WSLCCompat.h"
16
#include "relay.hpp"
17
#include <thread>
18
@@ -21,7 +21,7 @@ struct WslcContainerProcessOptionsInternal;
21
22
struct IOCallback
23
{
24
- IOCallback(IWSLCProcess* process, const WslcContainerProcessIOCallbackOptions& options);
24
+ IOCallback(IWSLCCompatProcess* process, const WslcContainerProcessIOCallbackOptions& options);
25
~IOCallback();
26
27
void Cancel();
@@ -32,10 +32,10 @@ struct IOCallback
32
static bool HasIOCallback(const WslcContainerProcessOptionsInternal* options);
33
static bool HasIOCallback(const WslcContainerProcessIOCallbackOptions& options);
34
35
- static wil::unique_handle GetIOHandle(IWSLCProcess* process, WslcProcessIOHandle ioHandle);
35
+ static wil::unique_handle GetIOHandle(IWSLCCompatProcess* process, WslcProcessIOHandle ioHandle);
36
37
private:
38
- wil::com_ptr<IWSLCProcess> m_process;
38
+ wil::com_ptr<IWSLCCompatProcess> m_process;
39
std::unique_ptr<WslcContainerProcessIOCallbackOptions> m_callbackOptions;
40
std::thread m_thread;
41
wsl::windows::common::io::MultiHandleWait m_io;
src/windows/WslcSDK/ProgressCallback.cpp
+1
-1
@@ -8,7 +8,7 @@ Module Name:
8
9
Abstract:
10
11
- Implementation of a type that implements IProgressCallback.
11
+ Implementation of a type that implements IWSLCCompatProgressCallback.
12
13
--*/
14
#include "precomp.h"
src/windows/WslcSDK/ProgressCallback.h
+4
-4
@@ -8,19 +8,19 @@ Module Name:
8
9
Abstract:
10
11
- Header for a type that implements IProgressCallback.
11
+ Header for a type that implements IWSLCCompatProgressCallback.
12
13
--*/
14
#pragma once
15
-#include "wslc.h"
15
+#include "WSLCCompat.h"
16
#include "wslcsdkprivate.h"
17
#include <winrt/base.h>
18
19
-struct ProgressCallback : public winrt::implements<ProgressCallback, IProgressCallback>
19
+struct ProgressCallback : public winrt::implements<ProgressCallback, IWSLCCompatProgressCallback>
20
{
21
ProgressCallback(WslcContainerImageProgressCallback callback, PVOID context);
22
23
- // IProgressCallback
23
+ // IWSLCCompatProgressCallback
24
HRESULT STDMETHODCALLTYPE OnProgress(LPCSTR Status, LPCSTR Id, ULONGLONG Current, ULONGLONG Total) override;
25
26
// Creates a ProgressCallback if the options provides a callback.
src/windows/WslcSDK/WslcsdkPrivate.h
+5
-5
@@ -14,7 +14,7 @@ Abstract:
14
#pragma once
15
#include <windows.h>
16
#include "wslcsdk.h"
17
-#include "wslc.h"
17
+#include "WSLCCompat.h"
18
#include "IOCallback.h"
19
#include <stdint.h>
20
#include <wil/com.h> // COM helpers
@@ -104,7 +104,7 @@ const WslcContainerOptionsInternal* GetInternalType(const WslcContainerSettings*
104
// Use to allocate the actual objects on the heap to keep it alive.
105
struct WslcSessionImpl
106
{
107
- wil::com_ptr<IWSLCSession> session;
107
+ wil::com_ptr<IWSLCCompatSession> session;
108
};
109
110
WslcSessionImpl* GetInternalType(WslcSession handle);
@@ -113,7 +113,7 @@ WslcSessionImpl* GetInternalType(WslcSession handle);
113
// subscription whose release unregisters the callback.
114
struct WslcCrashDumpSubscriptionImpl
115
{
116
- wil::com_ptr<ICrashDumpCallback> callback;
116
+ wil::com_ptr<IWSLCCompatCrashDumpCallback> callback;
117
wil::com_ptr<IUnknown> subscription;
118
};
119
@@ -121,7 +121,7 @@ WslcCrashDumpSubscriptionImpl* GetInternalType(WslcCrashDumpSubscription handle)
121
122
struct WslcContainerImpl
123
{
124
- wil::com_ptr<IWSLCContainer> container;
124
+ wil::com_ptr<IWSLCCompatContainer> container;
125
WslcContainerProcessIOCallbackOptions ioCallbackOptions{};
126
std::atomic<std::shared_ptr<IOCallback>> ioCallbacks;
127
};
@@ -130,7 +130,7 @@ WslcContainerImpl* GetInternalType(WslcContainer handle);
130
131
struct WslcProcessImpl
132
{
133
- wil::com_ptr<IWSLCProcess> process;
133
+ wil::com_ptr<IWSLCCompatProcess> process;
134
std::shared_ptr<IOCallback> ioCallbacks;
135
};
136
src/windows/WslcSDK/wslcsdk.cpp
+42
-37
@@ -21,6 +21,7 @@ Abstract:
21
#include "Localization.h"
22
#include "WslInstall.h"
23
#include "wslutil.h"
24
+#include "APICompat.h"
25
#include "WindowsUpdateIntegration.h"
26
27
using namespace std::string_view_literals;
@@ -207,7 +208,7 @@ static HRESULT InetNtopToHresult(int af, const void* src, char* dst, size_t dstC
208
return S_OK;
209
}
210
210
-bool CopyProcessSettingsToRuntime(WSLCProcessOptions& runtimeOptions, const WslcContainerProcessOptionsInternal* initProcessOptions)
211
+bool CopyProcessSettingsToRuntime(WSLCCompatProcessOptions& runtimeOptions, const WslcContainerProcessOptionsInternal* initProcessOptions)
212
{
213
if (initProcessOptions)
214
{
@@ -305,13 +306,13 @@ WslRuntimeState CheckWslRuntimeState()
306
return DoesWslRuntimeVersionSupportWslc(version) ? WslRuntimeState::InstalledWithWslcSupport : WslRuntimeState::InstalledWithoutWslcSupport;
307
}
308
308
-std::pair<wil::com_ptr<IWSLCSessionManager>, HRESULT> CreateSessionManagerRaw()
309
+std::pair<wil::com_ptr<IWSLCCompatSessionManager>, HRESULT> CreateSessionManagerRaw()
310
{
310
- wil::com_ptr<IWSLCSessionManager> result;
311
+ wil::com_ptr<IWSLCCompatSessionManager> result;
312
HRESULT hr = CoCreateInstance(__uuidof(WSLCSessionManager), nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&result));
313
if (SUCCEEDED(hr))
314
{
314
- const WSLCVersion clientVersion{WSL_PACKAGE_VERSION_MAJOR, WSL_PACKAGE_VERSION_MINOR, WSL_PACKAGE_VERSION_REVISION};
315
+ const WSLCCompatVersion clientVersion{WSL_PACKAGE_VERSION_MAJOR, WSL_PACKAGE_VERSION_MINOR, WSL_PACKAGE_VERSION_REVISION};
316
BOOL isSupported = FALSE;
317
THROW_IF_FAILED(result->IsClientVersionSupported(&clientVersion, &isSupported));
318
@@ -331,7 +332,7 @@ std::pair<wil::com_ptr<IWSLCSessionManager>, HRESULT> CreateSessionManagerRaw()
332
return {result, hr};
333
}
334
334
-wil::com_ptr<IWSLCSessionManager> CreateSessionManager()
335
+wil::com_ptr<IWSLCCompatSessionManager> CreateSessionManager()
336
{
337
auto [result, hr] = CreateSessionManagerRaw();
338
@@ -423,10 +424,10 @@ try
424
ErrorInfoWrapper errorInfoWrapper{errorMessage};
425
auto internalType = CheckAndGetInternalType(sessionSettings);
426
426
- wil::com_ptr<IWSLCSessionManager> sessionManager = CreateSessionManager();
427
+ wil::com_ptr<IWSLCCompatSessionManager> sessionManager = CreateSessionManager();
428
429
auto result = std::make_unique<WslcSessionImpl>();
429
- WSLCSessionSettings runtimeSettings{};
430
+ WSLCCompatSessionSettings runtimeSettings{};
431
runtimeSettings.DisplayName = internalType->displayName;
432
runtimeSettings.StoragePath = internalType->storagePath;
433
runtimeSettings.MaximumStorageSizeMb = internalType->vhdRequirements.sizeBytes / _1MB;
@@ -499,7 +500,7 @@ try
500
std::string uidStr;
501
std::string gidStr;
502
502
- std::vector<WSLCDriverOption> driverOpts;
503
+ std::vector<WSLCCompatDriverOption> driverOpts;
504
driverOpts.push_back({"SizeBytes", sizeStr.c_str()});
505
506
if (options->type == WSLC_VHD_TYPE_FIXED)
@@ -519,13 +520,13 @@ try
520
driverOpts.push_back({"Gid", gidStr.c_str()});
521
}
522
522
- WSLCVolumeOptions volumeOptions{};
523
+ WSLCCompatVolumeOptions volumeOptions{};
524
volumeOptions.Name = options->name;
525
volumeOptions.Driver = "vhd";
526
volumeOptions.DriverOpts = driverOpts.data();
527
volumeOptions.DriverOptsCount = static_cast<ULONG>(driverOpts.size());
528
528
- WSLCVolumeInformation volumeInfo{};
529
+ WSLCCompatVolumeInformation volumeInfo{};
530
return errorInfoWrapper.CaptureResult(internalType->session->CreateVolume(&volumeOptions, &volumeInfo));
531
}
532
CATCH_RETURN();
@@ -770,8 +771,8 @@ try
771
772
auto result = std::make_unique<WslcContainerImpl>();
773
773
- WSLCContainerOptions containerOptions{};
774
- std::unique_ptr<WSLCPortMapping[]> convertedPorts; // this must stay in same scope as containerOptions since containerOptions.Ports is getting a raw pointer to the array owned by convertedPorts.
774
+ WSLCCompatContainerOptions containerOptions{};
775
+ std::unique_ptr<WSLCCompatPortMapping[]> convertedPorts; // this must stay in same scope as containerOptions since containerOptions.Ports is getting a raw pointer to the array owned by convertedPorts.
776
777
containerOptions.Image = internalContainerSettings->image;
778
containerOptions.Name = internalContainerSettings->runtimeName;
@@ -781,14 +782,14 @@ try
782
783
CopyProcessSettingsToRuntime(containerOptions.InitProcessOptions, internalContainerSettings->initProcessOptions);
784
784
- std::unique_ptr<WSLCVolume[]> convertedVolumes;
785
+ std::unique_ptr<WSLCCompatVolume[]> convertedVolumes;
786
if (internalContainerSettings->volumes && internalContainerSettings->volumesCount)
787
{
787
- convertedVolumes = std::make_unique<WSLCVolume[]>(internalContainerSettings->volumesCount);
788
+ convertedVolumes = std::make_unique<WSLCCompatVolume[]>(internalContainerSettings->volumesCount);
789
for (uint32_t i = 0; i < internalContainerSettings->volumesCount; ++i)
790
{
791
const WslcContainerVolume& internalVolume = internalContainerSettings->volumes[i];
791
- WSLCVolume& convertedVolume = convertedVolumes[i];
792
+ WSLCCompatVolume& convertedVolume = convertedVolumes[i];
793
794
convertedVolume.HostPath = internalVolume.windowsPath;
795
convertedVolume.ContainerPath = internalVolume.containerPath;
@@ -798,14 +799,14 @@ try
799
containerOptions.VolumesCount = static_cast<ULONG>(internalContainerSettings->volumesCount);
800
}
801
801
- std::unique_ptr<WSLCNamedVolume[]> convertedNamedVolumes;
802
+ std::unique_ptr<WSLCCompatNamedVolume[]> convertedNamedVolumes;
803
if (internalContainerSettings->namedVolumes && internalContainerSettings->namedVolumesCount)
804
{
804
- convertedNamedVolumes = std::make_unique<WSLCNamedVolume[]>(internalContainerSettings->namedVolumesCount);
805
+ convertedNamedVolumes = std::make_unique<WSLCCompatNamedVolume[]>(internalContainerSettings->namedVolumesCount);
806
for (uint32_t i = 0; i < internalContainerSettings->namedVolumesCount; ++i)
807
{
808
const WslcContainerNamedVolume& internalVolume = internalContainerSettings->namedVolumes[i];
808
- WSLCNamedVolume& convertedVolume = convertedNamedVolumes[i];
809
+ WSLCCompatNamedVolume& convertedVolume = convertedNamedVolumes[i];
810
811
convertedVolume.Name = internalVolume.name;
812
convertedVolume.ContainerPath = internalVolume.containerPath;
@@ -817,11 +818,11 @@ try
818
819
if (internalContainerSettings->ports && internalContainerSettings->portsCount)
820
{
820
- convertedPorts = std::make_unique<WSLCPortMapping[]>(internalContainerSettings->portsCount);
821
+ convertedPorts = std::make_unique<WSLCCompatPortMapping[]>(internalContainerSettings->portsCount);
822
for (uint32_t i = 0; i < internalContainerSettings->portsCount; ++i)
823
{
824
const WslcContainerPortMapping& internalPort = internalContainerSettings->ports[i];
824
- WSLCPortMapping& convertedPort = convertedPorts[i];
825
+ WSLCCompatPortMapping& convertedPort = convertedPorts[i];
826
827
convertedPort.HostPort = internalPort.windowsPort;
828
convertedPort.ContainerPort = internalPort.containerPort;
@@ -918,11 +919,11 @@ try
919
// TODO: Consider if we should just override flags when callbacks were provided instead.
920
RETURN_HR_IF(E_INVALIDARG, WI_IsFlagClear(flags, WSLC_CONTAINER_START_FLAG_ATTACH) && hasIOCallback);
921
921
- if (SUCCEEDED(errorInfoWrapper.CaptureResult(internalType->container->Start(ConvertFlags(flags), nullptr, nullptr))))
922
+ if (SUCCEEDED(errorInfoWrapper.CaptureResult(internalType->container->Start(ConvertFlags(flags)))))
923
{
924
if (hasIOCallback)
925
{
925
- wil::com_ptr<IWSLCProcess> process;
926
+ wil::com_ptr<IWSLCCompatProcess> process;
927
RETURN_IF_FAILED(internalType->container->GetInitProcess(&process));
928
wsl::windows::common::security::ConfigureForCOMImpersonation(process.get());
929
internalType->ioCallbacks = std::make_shared<IOCallback>(process.get(), internalType->ioCallbackOptions);
@@ -1079,11 +1080,11 @@ try
1080
auto internalProcessSettings = CheckAndGetInternalType(newProcessSettings);
1081
RETURN_HR_IF(E_INVALIDARG, internalProcessSettings->commandLine == nullptr || internalProcessSettings->commandLineCount == 0);
1082
1082
- WSLCProcessOptions runtimeOptions{};
1083
+ WSLCCompatProcessOptions runtimeOptions{};
1084
CopyProcessSettingsToRuntime(runtimeOptions, internalProcessSettings);
1085
1086
auto result = std::make_unique<WslcProcessImpl>();
1086
- if (SUCCEEDED(errorInfoWrapper.CaptureResult(internalContainer->container->Exec(&runtimeOptions, nullptr, &result->process))))
1087
+ if (SUCCEEDED(errorInfoWrapper.CaptureResult(internalContainer->container->Exec(&runtimeOptions, &result->process))))
1088
{
1089
wsl::windows::common::security::ConfigureForCOMImpersonation(result->process.get());
1090
@@ -1104,7 +1105,7 @@ CATCH_RETURN();
1105
STDAPI WslcGetContainerID(WslcContainer container, CHAR containerID[WSLC_CONTAINER_ID_BUFFER_SIZE])
1106
try
1107
{
1107
- static_assert(WSLC_CONTAINER_ID_BUFFER_SIZE == sizeof(WSLCContainerId), "Container ID lengths differ.");
1108
+ static_assert(WSLC_CONTAINER_ID_BUFFER_SIZE == sizeof(WSLCCompatContainerId), "Container ID lengths differ.");
1109
1110
auto internalType = CheckAndGetInternalType(container);
1111
RETURN_HR_IF_NULL(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), internalType->container);
@@ -1400,7 +1401,11 @@ static HRESULT WslcImportSessionImageImpl(
1401
auto progressCallback = ProgressCallback::CreateIf(options);
1402
1403
return errorInfoWrapper.CaptureResult(internalSession->session->ImportImage(
1403
- ToCOMInputHandle(imageFile.Handle()), imageName, progressCallback.get(), imageFile.Length(), nullptr));
1404
+ wsl::windows::common::apicompat::Convert(ToCOMInputHandle(imageFile.Handle())),
1405
+ imageName,
1406
+ progressCallback.get(),
1407
+ imageFile.Length(),
1408
+ nullptr));
1409
}
1410
1411
STDAPI WslcImportSessionImage(
@@ -1437,8 +1442,8 @@ static HRESULT WslcLoadSessionImageImpl(
1442
{
1443
auto progressCallback = ProgressCallback::CreateIf(options);
1444
1440
- return errorInfoWrapper.CaptureResult(
1441
- internalSession->session->LoadImage(ToCOMInputHandle(imageFile.Handle()), progressCallback.get(), imageFile.Length(), nullptr));
1445
+ return errorInfoWrapper.CaptureResult(internalSession->session->LoadImage(
1446
+ wsl::windows::common::apicompat::Convert(ToCOMInputHandle(imageFile.Handle())), progressCallback.get(), imageFile.Length(), nullptr));
1447
}
1448
1449
STDAPI WslcLoadSessionImage(
@@ -1474,11 +1479,11 @@ try
1479
RETURN_HR_IF_NULL(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), internalType->session);
1480
RETURN_HR_IF_NULL(E_POINTER, nameOrID);
1481
1477
- WSLCDeleteImageOptions options{};
1482
+ WSLCCompatDeleteImageOptions options{};
1483
options.Image = nameOrID;
1484
// TODO: Flags? (Force and NoPrune)
1485
1481
- wil::unique_cotaskmem_array_ptr<WSLCDeletedImageInformation> deletedImageInformation;
1486
+ wil::unique_cotaskmem_array_ptr<WSLCCompatDeletedImageInformation> deletedImageInformation;
1487
1488
return errorInfoWrapper.CaptureResult(
1489
internalType->session->DeleteImage(&options, &deletedImageInformation, deletedImageInformation.size_address<ULONG>()));
@@ -1496,7 +1501,7 @@ try
1501
RETURN_HR_IF_NULL(E_INVALIDARG, options->repo);
1502
RETURN_HR_IF_NULL(E_INVALIDARG, options->tag);
1503
1499
- WSLCTagImageOptions runtimeOptions{};
1504
+ WSLCCompatTagImageOptions runtimeOptions{};
1505
runtimeOptions.Image = options->image;
1506
runtimeOptions.Repo = options->repo;
1507
runtimeOptions.Tag = options->tag;
@@ -1556,7 +1561,7 @@ STDAPI WslcListSessionImages(_In_ WslcSession session, _Outptr_result_buffer_(*c
1561
try
1562
{
1563
static_assert(
1559
- sizeof(decltype(WslcImageInfo::name)) == sizeof(decltype(WSLCImageInformation::Image)), "Image name size mismatch.");
1564
+ sizeof(decltype(WslcImageInfo::name)) == sizeof(decltype(WSLCCompatImageInformation::Image)), "Image name size mismatch.");
1565
1566
RETURN_HR_IF_NULL(E_POINTER, images);
1567
*images = nullptr;
@@ -1567,7 +1572,7 @@ try
1572
1573
// TODO: Many filtering options are available via WSLC_LIST_IMAGES_OPTIONS
1574
1570
- wil::unique_cotaskmem_array_ptr<WSLCImageInformation> imageInformation;
1575
+ wil::unique_cotaskmem_array_ptr<WSLCCompatImageInformation> imageInformation;
1576
1577
RETURN_IF_FAILED(internalType->session->ListImages(nullptr, &imageInformation, imageInformation.size_address<ULONG>()));
1578
@@ -1578,14 +1583,14 @@ try
1583
for (size_t i = 0; i < imageInformation.size(); ++i)
1584
{
1585
WslcImageInfo& currentResult = result[i];
1581
- WSLCImageInformation& currentImage = imageInformation[i];
1586
+ WSLCCompatImageInformation& currentImage = imageInformation[i];
1587
1588
static_assert(std::is_trivial_v<WslcImageInfo>, "WslcImageInfo must be trivial.");
1589
currentResult = {};
1590
1591
THROW_HR_IF(
1592
E_UNEXPECTED,
1588
- memcpy_s(currentResult.name, sizeof(decltype(WslcImageInfo::name)), currentImage.Image, sizeof(decltype(WSLCImageInformation::Image))) !=
1593
+ memcpy_s(currentResult.name, sizeof(decltype(WslcImageInfo::name)), currentImage.Image, sizeof(decltype(WSLCCompatImageInformation::Image))) !=
1594
0);
1595
ConvertSHA256Hash(currentImage.Hash, currentResult.sha256);
1596
currentResult.sizeBytes = currentImage.Size;
@@ -1643,9 +1648,9 @@ try
1648
static_assert(std::is_trivial_v<WslcVersion>, "WslcVersion must be trivial");
1649
*version = {};
1650
1646
- wil::com_ptr<IWSLCSessionManager> sessionManager = CreateSessionManager();
1651
+ wil::com_ptr<IWSLCCompatSessionManager> sessionManager = CreateSessionManager();
1652
1648
- WSLCVersion runtimeVersion{};
1653
+ WSLCCompatVersion runtimeVersion{};
1654
RETURN_IF_FAILED(sessionManager->GetVersion(&runtimeVersion));
1655
1656
version->major = runtimeVersion.Major;
src/windows/common/APICompat.cpp
new
+423
@@ -0,0 +1,423 @@
1
+// Copyright (C) Microsoft Corporation. All rights reserved.
2
+
3
+#include "precomp.h"
4
+#include "APICompat.h"
5
+#include <wrl/implements.h>
6
+
7
+namespace wsl::windows::common::apicompat {
8
+
9
+namespace {
10
+
11
+ template <size_t Size>
12
+ void CopyString(char (&Destination)[Size], const char* Source)
13
+ {
14
+ THROW_HR_IF(E_UNEXPECTED, strcpy_s(Destination, Source) != 0);
15
+ }
16
+
17
+ template <typename TOut, typename TIn>
18
+ std::vector<TOut> ConvertArray(const TIn* Items, ULONG Count)
19
+ {
20
+ std::vector<TOut> result;
21
+ if (Items == nullptr || Count == 0)
22
+ {
23
+ return result;
24
+ }
25
+
26
+ result.reserve(Count);
27
+ for (ULONG index = 0; index < Count; index++)
28
+ {
29
+ result.push_back(Convert(Items[index]));
30
+ }
31
+
32
+ return result;
33
+ }
34
+
35
+ class CrashDumpCallbackAdapter
36
+ : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, ICrashDumpCallback>
37
+ {
38
+ public:
39
+ CrashDumpCallbackAdapter(IWSLCCompatCrashDumpCallback* Inner) : m_inner(Inner)
40
+ {
41
+ }
42
+
43
+ IFACEMETHOD(OnCrashDump)(LPCWSTR DumpPath, LPCSTR ProcessName, ULONGLONG Pid, ULONG Signal, ULONGLONG Timestamp) override
44
+ {
45
+ return m_inner->OnCrashDump(DumpPath, ProcessName, Pid, Signal, Timestamp);
46
+ }
47
+
48
+ private:
49
+ Microsoft::WRL::ComPtr<IWSLCCompatCrashDumpCallback> m_inner;
50
+ };
51
+
52
+ class ProgressCallbackAdapter
53
+ : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IProgressCallback>
54
+ {
55
+ public:
56
+ ProgressCallbackAdapter(IWSLCCompatProgressCallback* Inner) : m_inner(Inner)
57
+ {
58
+ }
59
+
60
+ IFACEMETHOD(OnProgress)(LPCSTR Status, LPCSTR Id, ULONGLONG Current, ULONGLONG Total) override
61
+ {
62
+ return m_inner->OnProgress(Status, Id, Current, Total);
63
+ }
64
+
65
+ private:
66
+ Microsoft::WRL::ComPtr<IWSLCCompatProgressCallback> m_inner;
67
+ };
68
+
69
+ class WarningCallbackAdapter
70
+ : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWarningCallback>
71
+ {
72
+ public:
73
+ WarningCallbackAdapter(IWSLCCompatWarningCallback* Inner) : m_inner(Inner)
74
+ {
75
+ }
76
+
77
+ IFACEMETHOD(OnWarning)(LPCWSTR Message) override
78
+ {
79
+ return m_inner->OnWarning(Message);
80
+ }
81
+
82
+ private:
83
+ Microsoft::WRL::ComPtr<IWSLCCompatWarningCallback> m_inner;
84
+ };
85
+
86
+} // namespace
87
+
88
+//
89
+// Scalar / non-owning struct conversions.
90
+//
91
+
92
+WSLCVersion Convert(const WSLCCompatVersion& Version)
93
+{
94
+ WSLCVersion result{};
95
+ result.Major = Version.Major;
96
+ result.Minor = Version.Minor;
97
+ result.Revision = Version.Revision;
98
+ return result;
99
+}
100
+
101
+WSLCCompatVersion Convert(const WSLCVersion& Version)
102
+{
103
+ WSLCCompatVersion result{};
104
+ result.Major = Version.Major;
105
+ result.Minor = Version.Minor;
106
+ result.Revision = Version.Revision;
107
+ return result;
108
+}
109
+
110
+WSLCHandle Convert(const WSLCCompatHandle& Handle)
111
+{
112
+ WSLCHandle result{};
113
+ result.Type = Handle.Type;
114
+ switch (Handle.Type)
115
+ {
116
+ case WSLCHandleTypeFile:
117
+ result.Handle.File = Handle.Handle.File;
118
+ break;
119
+ case WSLCHandleTypePipe:
120
+ result.Handle.Pipe = Handle.Handle.Pipe;
121
+ break;
122
+ case WSLCHandleTypeSocket:
123
+ result.Handle.Socket = Handle.Handle.Socket;
124
+ break;
125
+ case WSLCHandleTypeUnknown:
126
+ break;
127
+ }
128
+
129
+ return result;
130
+}
131
+
132
+WSLCCompatHandle Convert(const WSLCHandle& Handle)
133
+{
134
+ WSLCCompatHandle result{};
135
+ result.Type = Handle.Type;
136
+ switch (Handle.Type)
137
+ {
138
+ case WSLCHandleTypeFile:
139
+ result.Handle.File = Handle.Handle.File;
140
+ break;
141
+ case WSLCHandleTypePipe:
142
+ result.Handle.Pipe = Handle.Handle.Pipe;
143
+ break;
144
+ case WSLCHandleTypeSocket:
145
+ result.Handle.Socket = Handle.Handle.Socket;
146
+ break;
147
+ case WSLCHandleTypeUnknown:
148
+ break;
149
+ }
150
+
151
+ return result;
152
+}
153
+
154
+WSLCStringArray Convert(const WSLCCompatStringArray& Array)
155
+{
156
+ WSLCStringArray result{};
157
+ result.Values = Array.Values;
158
+ result.Count = Array.Count;
159
+ return result;
160
+}
161
+
162
+WSLCProcessOptions Convert(const WSLCCompatProcessOptions& Options)
163
+{
164
+ WSLCProcessOptions result{};
165
+ result.CurrentDirectory = Options.CurrentDirectory;
166
+ result.User = Options.User;
167
+ result.CommandLine = Convert(Options.CommandLine);
168
+ result.Environment = Convert(Options.Environment);
169
+ result.Flags = Options.Flags;
170
+ return result;
171
+}
172
+
173
+KeyValuePair Convert(const WSLCCompatKeyValuePair& Pair)
174
+{
175
+ KeyValuePair result{};
176
+ result.Key = Pair.Key;
177
+ result.Value = Pair.Value;
178
+ return result;
179
+}
180
+
181
+WSLCVolume Convert(const WSLCCompatVolume& Volume)
182
+{
183
+ WSLCVolume result{};
184
+ result.HostPath = Volume.HostPath;
185
+ result.ContainerPath = Volume.ContainerPath;
186
+ result.ReadOnly = Volume.ReadOnly;
187
+ return result;
188
+}
189
+
190
+WSLCNamedVolume Convert(const WSLCCompatNamedVolume& Volume)
191
+{
192
+ WSLCNamedVolume result{};
193
+ result.Name = Volume.Name;
194
+ result.ContainerPath = Volume.ContainerPath;
195
+ result.ReadOnly = Volume.ReadOnly;
196
+ return result;
197
+}
198
+
199
+WSLCPortMapping Convert(const WSLCCompatPortMapping& Port)
200
+{
201
+ WSLCPortMapping result{};
202
+ result.HostPort = Port.HostPort;
203
+ result.ContainerPort = Port.ContainerPort;
204
+ result.Family = Port.Family;
205
+ result.Protocol = Port.Protocol;
206
+ CopyString(result.BindingAddress, Port.BindingAddress);
207
+ return result;
208
+}
209
+
210
+WSLCTmpfsMount Convert(const WSLCCompatTmpfsMount& Mount)
211
+{
212
+ WSLCTmpfsMount result{};
213
+ result.Destination = Mount.Destination;
214
+ result.Options = Mount.Options;
215
+ return result;
216
+}
217
+
218
+WSLCUlimit Convert(const WSLCCompatUlimit& Ulimit)
219
+{
220
+ WSLCUlimit result{};
221
+ result.Name = Ulimit.Name;
222
+ result.Soft = Ulimit.Soft;
223
+ result.Hard = Ulimit.Hard;
224
+ return result;
225
+}
226
+
227
+WSLCDeleteImageOptions Convert(const WSLCCompatDeleteImageOptions& Options)
228
+{
229
+ WSLCDeleteImageOptions result{};
230
+ result.Image = Options.Image;
231
+ result.Flags = Options.Flags;
232
+ return result;
233
+}
234
+
235
+WSLCTagImageOptions Convert(const WSLCCompatTagImageOptions& Options)
236
+{
237
+ WSLCTagImageOptions result{};
238
+ result.Image = Options.Image;
239
+ result.Repo = Options.Repo;
240
+ result.Tag = Options.Tag;
241
+ return result;
242
+}
243
+
244
+WSLCCompatImageInformation Convert(const WSLCImageInformation& Image)
245
+{
246
+ WSLCCompatImageInformation result{};
247
+ CopyString(result.Image, Image.Image);
248
+ CopyString(result.Hash, Image.Hash);
249
+ CopyString(result.Digest, Image.Digest);
250
+ result.Size = Image.Size;
251
+ result.Created = Image.Created;
252
+ CopyString(result.ParentId, Image.ParentId);
253
+ return result;
254
+}
255
+
256
+WSLCCompatDeletedImageInformation Convert(const WSLCDeletedImageInformation& Image)
257
+{
258
+ WSLCCompatDeletedImageInformation result{};
259
+ CopyString(result.Image, Image.Image);
260
+ result.Type = Image.Type;
261
+ return result;
262
+}
263
+
264
+WSLCCompatVolumeInformation Convert(const WSLCVolumeInformation& Volume)
265
+{
266
+ WSLCCompatVolumeInformation result{};
267
+ CopyString(result.Name, Volume.Name);
268
+ CopyString(result.Driver, Volume.Driver);
269
+ return result;
270
+}
271
+
272
+//
273
+// Composite struct conversions.
274
+//
275
+
276
+ContainerOptionsConversion::ContainerOptionsConversion(const WSLCCompatContainerOptions& Options)
277
+{
278
+ m_value.Image = Options.Image;
279
+ m_value.Name = Options.Name;
280
+ m_value.Entrypoint = Convert(Options.Entrypoint);
281
+ m_value.InitProcessOptions = Convert(Options.InitProcessOptions);
282
+
283
+ m_volumes = ConvertArray<WSLCVolume>(Options.Volumes, Options.VolumesCount);
284
+ m_value.Volumes = m_volumes.empty() ? nullptr : m_volumes.data();
285
+ m_value.VolumesCount = Options.VolumesCount;
286
+
287
+ m_ports = ConvertArray<WSLCPortMapping>(Options.Ports, Options.PortsCount);
288
+ m_value.Ports = m_ports.empty() ? nullptr : m_ports.data();
289
+ m_value.PortsCount = Options.PortsCount;
290
+
291
+ m_labels = ConvertArray<WSLCLabel>(Options.Labels, Options.LabelsCount);
292
+ m_value.Labels = m_labels.empty() ? nullptr : m_labels.data();
293
+ m_value.LabelsCount = Options.LabelsCount;
294
+
295
+ m_value.Flags = Options.Flags;
296
+ m_value.StopSignal = Options.StopSignal;
297
+ m_value.HostName = Options.HostName;
298
+ m_value.DomainName = Options.DomainName;
299
+
300
+ m_value.DnsServers = Convert(Options.DnsServers);
301
+ m_value.DnsSearchDomains = Convert(Options.DnsSearchDomains);
302
+ m_value.DnsOptions = Convert(Options.DnsOptions);
303
+
304
+ m_value.ShmSize = Options.ShmSize;
305
+
306
+ // Container network (nested arrays whose elements have their own arrays).
307
+ m_value.ContainerNetwork.NetworkMode = Options.ContainerNetwork.NetworkMode;
308
+ const ULONG networksCount = Options.ContainerNetwork.NetworksCount;
309
+ THROW_HR_IF(E_INVALIDARG, networksCount > 0 && Options.ContainerNetwork.Networks == nullptr);
310
+
311
+ m_networks.reserve(networksCount);
312
+ m_networkSettings.reserve(networksCount);
313
+ for (ULONG index = 0; index < networksCount; index++)
314
+ {
315
+ const auto& network = Options.ContainerNetwork.Networks[index];
316
+ THROW_HR_IF(E_INVALIDARG, network.SettingsCount > 0 && network.Settings == nullptr);
317
+
318
+ m_networkSettings.push_back(ConvertArray<KeyValuePair>(network.Settings, network.SettingsCount));
319
+
320
+ WSLCNetworkConnection connection{};
321
+ connection.NetworkName = network.NetworkName;
322
+ connection.Settings = m_networkSettings.back().empty() ? nullptr : m_networkSettings.back().data();
323
+ connection.SettingsCount = network.SettingsCount;
324
+ m_networks.push_back(connection);
325
+ }
326
+
327
+ m_value.ContainerNetwork.Networks = m_networks.empty() ? nullptr : m_networks.data();
328
+ m_value.ContainerNetwork.NetworksCount = networksCount;
329
+
330
+ m_tmpfs = ConvertArray<WSLCTmpfsMount>(Options.Tmpfs, Options.TmpfsCount);
331
+ m_value.Tmpfs = m_tmpfs.empty() ? nullptr : m_tmpfs.data();
332
+ m_value.TmpfsCount = Options.TmpfsCount;
333
+
334
+ m_namedVolumes = ConvertArray<WSLCNamedVolume>(Options.NamedVolumes, Options.NamedVolumesCount);
335
+ m_value.NamedVolumes = m_namedVolumes.empty() ? nullptr : m_namedVolumes.data();
336
+ m_value.NamedVolumesCount = Options.NamedVolumesCount;
337
+
338
+ m_value.MemoryBytes = Options.MemoryBytes;
339
+ m_value.NanoCpus = Options.NanoCpus;
340
+
341
+ m_ulimits = ConvertArray<WSLCUlimit>(Options.Ulimits, Options.UlimitsCount);
342
+ m_value.Ulimits = m_ulimits.empty() ? nullptr : m_ulimits.data();
343
+ m_value.UlimitsCount = Options.UlimitsCount;
344
+}
345
+
346
+ListImagesOptionsConversion::ListImagesOptionsConversion(const WSLCCompatListImagesOptions& Options)
347
+{
348
+ m_value.Flags = Options.Flags;
349
+
350
+ m_filters = ConvertArray<WSLCFilter>(Options.Filters, Options.FiltersCount);
351
+ m_value.Filters = m_filters.empty() ? nullptr : m_filters.data();
352
+ m_value.FiltersCount = Options.FiltersCount;
353
+}
354
+
355
+VolumeOptionsConversion::VolumeOptionsConversion(const WSLCCompatVolumeOptions& Options)
356
+{
357
+ m_value.Name = Options.Name;
358
+ m_value.Driver = Options.Driver;
359
+
360
+ m_driverOpts = ConvertArray<WSLCDriverOption>(Options.DriverOpts, Options.DriverOptsCount);
361
+ m_value.DriverOpts = m_driverOpts.empty() ? nullptr : m_driverOpts.data();
362
+ m_value.DriverOptsCount = Options.DriverOptsCount;
363
+
364
+ m_labels = ConvertArray<WSLCLabel>(Options.Labels, Options.LabelsCount);
365
+ m_value.Labels = m_labels.empty() ? nullptr : m_labels.data();
366
+ m_value.LabelsCount = Options.LabelsCount;
367
+}
368
+
369
+SessionSettingsConversion::SessionSettingsConversion(const WSLCCompatSessionSettings& Settings)
370
+{
371
+ m_value.DisplayName = Settings.DisplayName;
372
+ m_value.StoragePath = Settings.StoragePath;
373
+ m_value.MaximumStorageSizeMb = Settings.MaximumStorageSizeMb;
374
+ m_value.CpuCount = Settings.CpuCount;
375
+ m_value.MemoryMb = Settings.MemoryMb;
376
+ m_value.BootTimeoutMs = Settings.BootTimeoutMs;
377
+ m_value.NetworkingMode = Settings.NetworkingMode;
378
+
379
+ m_value.FeatureFlags = Settings.FeatureFlags;
380
+ m_value.DmesgOutput = Convert(Settings.DmesgOutput);
381
+ m_value.StorageFlags = Settings.StorageFlags;
382
+ m_value.RootVhdOverride = Settings.RootVhdOverride;
383
+ m_value.RootVhdTypeOverride = Settings.RootVhdTypeOverride;
384
+}
385
+
386
+//
387
+// Callback conversions.
388
+//
389
+
390
+Microsoft::WRL::ComPtr<ICrashDumpCallback> Convert(IWSLCCompatCrashDumpCallback* Callback)
391
+{
392
+ Microsoft::WRL::ComPtr<ICrashDumpCallback> result;
393
+ if (Callback != nullptr)
394
+ {
395
+ result = Microsoft::WRL::Make<CrashDumpCallbackAdapter>(Callback);
396
+ }
397
+
398
+ return result;
399
+}
400
+
401
+Microsoft::WRL::ComPtr<IProgressCallback> Convert(IWSLCCompatProgressCallback* Callback)
402
+{
403
+ Microsoft::WRL::ComPtr<IProgressCallback> result;
404
+ if (Callback != nullptr)
405
+ {
406
+ result = Microsoft::WRL::Make<ProgressCallbackAdapter>(Callback);
407
+ }
408
+
409
+ return result;
410
+}
411
+
412
+Microsoft::WRL::ComPtr<IWarningCallback> Convert(IWSLCCompatWarningCallback* Callback)
413
+{
414
+ Microsoft::WRL::ComPtr<IWarningCallback> result;
415
+ if (Callback != nullptr)
416
+ {
417
+ result = Microsoft::WRL::Make<WarningCallbackAdapter>(Callback);
418
+ }
419
+
420
+ return result;
421
+}
422
+
423
+} // namespace wsl::windows::common::apicompat
src/windows/common/APICompat.h
new
+163
@@ -0,0 +1,163 @@
1
+/*++
2
+
3
+Copyright (c) Microsoft. All rights reserved.
4
+
5
+Module Name:
6
+
7
+ APICompat.h
8
+
9
+Abstract:
10
+
11
+ API compatibility layer between the wslc.idl and wslccompat.idl.
12
+
13
+--*/
14
+
15
+#pragma once
16
+
17
+#include <vector>
18
+#include <wrl/client.h>
19
+#include "wslc.h"
20
+#include "WSLCCompat.h"
21
+
22
+namespace wsl::windows::common::apicompat {
23
+
24
+//
25
+// Struct conversions.
26
+//
27
+// Enums and flags are shared between wslc.idl and WSLCCompat.idl (see WSLCShared.idl),
28
+// so they require no conversion.
29
+//
30
+
31
+// Forward (WSLCCompat -> wslc.idl).
32
+WSLCVersion Convert(const WSLCCompatVersion& Version);
33
+WSLCHandle Convert(const WSLCCompatHandle& Handle);
34
+WSLCStringArray Convert(const WSLCCompatStringArray& Array);
35
+WSLCProcessOptions Convert(const WSLCCompatProcessOptions& Options);
36
+KeyValuePair Convert(const WSLCCompatKeyValuePair& Pair);
37
+WSLCVolume Convert(const WSLCCompatVolume& Volume);
38
+WSLCNamedVolume Convert(const WSLCCompatNamedVolume& Volume);
39
+WSLCPortMapping Convert(const WSLCCompatPortMapping& Port);
40
+WSLCTmpfsMount Convert(const WSLCCompatTmpfsMount& Mount);
41
+WSLCUlimit Convert(const WSLCCompatUlimit& Ulimit);
42
+WSLCDeleteImageOptions Convert(const WSLCCompatDeleteImageOptions& Options);
43
+WSLCTagImageOptions Convert(const WSLCCompatTagImageOptions& Options);
44
+
45
+// Reverse (wslc.idl -> WSLCCompat).
46
+WSLCCompatVersion Convert(const WSLCVersion& Version);
47
+WSLCCompatHandle Convert(const WSLCHandle& Handle);
48
+WSLCCompatImageInformation Convert(const WSLCImageInformation& Image);
49
+WSLCCompatDeletedImageInformation Convert(const WSLCDeletedImageInformation& Image);
50
+WSLCCompatVolumeInformation Convert(const WSLCVolumeInformation& Volume);
51
+
52
+//
53
+// Composite struct conversions.
54
+//
55
+
56
+class ContainerOptionsConversion
57
+{
58
+public:
59
+ NON_COPYABLE(ContainerOptionsConversion);
60
+ DEFAULT_MOVABLE(ContainerOptionsConversion);
61
+
62
+ explicit ContainerOptionsConversion(const WSLCCompatContainerOptions& Options);
63
+
64
+ const WSLCContainerOptions* Get() const noexcept
65
+ {
66
+ return &m_value;
67
+ }
68
+
69
+private:
70
+ WSLCContainerOptions m_value{};
71
+ std::vector<WSLCVolume> m_volumes;
72
+ std::vector<WSLCPortMapping> m_ports;
73
+ std::vector<WSLCLabel> m_labels;
74
+ std::vector<WSLCTmpfsMount> m_tmpfs;
75
+ std::vector<WSLCNamedVolume> m_namedVolumes;
76
+ std::vector<WSLCUlimit> m_ulimits;
77
+ std::vector<WSLCNetworkConnection> m_networks;
78
+ std::vector<std::vector<KeyValuePair>> m_networkSettings;
79
+};
80
+
81
+class ListImagesOptionsConversion
82
+{
83
+public:
84
+ NON_COPYABLE(ListImagesOptionsConversion);
85
+ DEFAULT_MOVABLE(ListImagesOptionsConversion);
86
+
87
+ explicit ListImagesOptionsConversion(const WSLCCompatListImagesOptions& Options);
88
+
89
+ const WSLCListImagesOptions* Get() const noexcept
90
+ {
91
+ return &m_value;
92
+ }
93
+
94
+private:
95
+ WSLCListImagesOptions m_value{};
96
+ std::vector<WSLCFilter> m_filters;
97
+};
98
+
99
+class VolumeOptionsConversion
100
+{
101
+public:
102
+ NON_COPYABLE(VolumeOptionsConversion);
103
+ DEFAULT_MOVABLE(VolumeOptionsConversion);
104
+
105
+ explicit VolumeOptionsConversion(const WSLCCompatVolumeOptions& Options);
106
+
107
+ const WSLCVolumeOptions* Get() const noexcept
108
+ {
109
+ return &m_value;
110
+ }
111
+
112
+private:
113
+ WSLCVolumeOptions m_value{};
114
+ std::vector<WSLCDriverOption> m_driverOpts;
115
+ std::vector<WSLCLabel> m_labels;
116
+};
117
+
118
+class SessionSettingsConversion
119
+{
120
+public:
121
+ NON_COPYABLE(SessionSettingsConversion);
122
+ DEFAULT_MOVABLE(SessionSettingsConversion);
123
+
124
+ explicit SessionSettingsConversion(const WSLCCompatSessionSettings& Settings);
125
+
126
+ const WSLCSessionSettings* Get() const noexcept
127
+ {
128
+ return &m_value;
129
+ }
130
+
131
+private:
132
+ WSLCSessionSettings m_value{};
133
+};
134
+
135
+inline ContainerOptionsConversion Convert(const WSLCCompatContainerOptions& Options)
136
+{
137
+ return ContainerOptionsConversion(Options);
138
+}
139
+
140
+inline ListImagesOptionsConversion Convert(const WSLCCompatListImagesOptions& Options)
141
+{
142
+ return ListImagesOptionsConversion(Options);
143
+}
144
+
145
+inline VolumeOptionsConversion Convert(const WSLCCompatVolumeOptions& Options)
146
+{
147
+ return VolumeOptionsConversion(Options);
148
+}
149
+
150
+inline SessionSettingsConversion Convert(const WSLCCompatSessionSettings& Settings)
151
+{
152
+ return SessionSettingsConversion(Settings);
153
+}
154
+
155
+//
156
+// Callback conversions.
157
+//
158
+
159
+Microsoft::WRL::ComPtr<ICrashDumpCallback> Convert(IWSLCCompatCrashDumpCallback* Callback);
160
+Microsoft::WRL::ComPtr<IProgressCallback> Convert(IWSLCCompatProgressCallback* Callback);
161
+Microsoft::WRL::ComPtr<IWarningCallback> Convert(IWSLCCompatWarningCallback* Callback);
162
+
163
+} // namespace wsl::windows::common::apicompat
src/windows/common/CMakeLists.txt
+2
@@ -1,4 +1,5 @@
1
set(SOURCES
2
+ APICompat.cpp
3
ConsoleProgressBar.cpp
4
ConsoleProgressIndicator.cpp
5
ConsoleState.cpp
@@ -58,6 +59,7 @@ set(SOURCES
59
60
set(HEADERS
61
../../../generated/Localization.h
62
+ APICompat.h
63
../inc/docker_schema.h
64
../inc/wslc_schema.h
65
../inc/lxssbusclient.h
src/windows/service/exe/WSLCSessionManager.cpp
+42
-1
@@ -37,6 +37,7 @@ Abstract:
37
#include "helpers.hpp"
38
#include "wslutil.h"
39
#include "filesystem.hpp"
40
+#include "APICompat.h"
41
42
extern wsl::windows::service::PluginManager g_pluginManager;
43
@@ -47,6 +48,7 @@ using wsl::windows::service::wslc::WSLCPluginNotifier;
48
using wsl::windows::service::wslc::WSLCSessionManagerImpl;
49
using wsl::windows::service::wslc::WSLCVirtualMachineFactory;
50
namespace wslutil = wsl::windows::common::wslutil;
51
+namespace apicompat = wsl::windows::common::apicompat;
52
namespace settings = wsl::windows::wslc::settings;
53
54
namespace {
@@ -541,7 +543,7 @@ try
543
}
544
CATCH_RETURN();
545
544
-HRESULT WSLCSessionManager::IsClientVersionSupported(_In_ const WSLCVersion* ClientVersion, _Out_ BOOL* IsSupported)
546
+HRESULT WSLCSessionManager::IsClientVersionSupported(_In_ const WSLCCompatVersion* ClientVersion, _Out_ BOOL* IsSupported)
547
try
548
{
549
RETURN_HR_IF(E_POINTER, ClientVersion == nullptr || IsSupported == nullptr);
@@ -601,6 +603,45 @@ HRESULT WSLCSessionManager::OpenSessionByName(_In_ LPCWSTR DisplayName, _Out_ IW
603
return CallImpl(&WSLCSessionManagerImpl::OpenSessionByName, DisplayName, Session);
604
}
605
606
+HRESULT WSLCSessionManager::GetVersion(_Out_ WSLCCompatVersion* Version)
607
+try
608
+{
609
+ RETURN_HR_IF_NULL(E_POINTER, Version);
610
+
611
+ WSLCVersion version{};
612
+ RETURN_IF_FAILED(GetVersion(&version));
613
+
614
+ *Version = apicompat::Convert(version);
615
+ return S_OK;
616
+}
617
+CATCH_RETURN();
618
+
619
+HRESULT WSLCSessionManager::CreateSession(
620
+ const WSLCCompatSessionSettings* Settings, WSLCSessionFlags Flags, IWSLCCompatWarningCallback* WarningCallback, IWSLCCompatSession** Session)
621
+try
622
+{
623
+ RETURN_HR_IF_NULL(E_POINTER, Session);
624
+ *Session = nullptr;
625
+
626
+ const auto warning = apicompat::Convert(WarningCallback);
627
+
628
+ Microsoft::WRL::ComPtr<IWSLCSession> session;
629
+ if (Settings == nullptr)
630
+ {
631
+ RETURN_IF_FAILED(CreateSession(static_cast<const WSLCSessionSettings*>(nullptr), Flags, warning.Get(), &session));
632
+ }
633
+ else
634
+ {
635
+ const auto settings = apicompat::Convert(*Settings);
636
+ RETURN_IF_FAILED(CreateSession(settings.Get(), Flags, warning.Get(), &session));
637
+ }
638
+
639
+ RETURN_HR_IF_NULL(E_UNEXPECTED, session);
640
+
641
+ return session.CopyTo(Session);
642
+}
643
+CATCH_RETURN();
644
+
645
namespace wsl::windows::service::wslc {
646
647
WSLCSessionManagerImpl* WSLCSessionManagerImpl::Instance() noexcept
src/windows/service/exe/WSLCSessionManager.h
+8
-2
@@ -32,6 +32,7 @@ Abstract:
32
33
#pragma once
34
#include "wslc.h"
35
+#include "WSLCCompat.h"
36
#include "COMImplClass.h"
37
#include "wslutil.h"
38
#include <atomic>
@@ -187,7 +188,7 @@ private:
188
} // namespace wsl::windows::service::wslc
189
190
class DECLSPEC_UUID("a9b7a1b9-0671-405c-95f1-e0612cb4ce8f") WSLCSessionManager
190
- : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWSLCSessionManager, IFastRundown>,
191
+ : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWSLCSessionManager, IWSLCCompatSessionManager, IFastRundown>,
192
public wsl::windows::service::wslc::COMImplClass<wsl::windows::service::wslc::WSLCSessionManagerImpl>
193
{
194
public:
@@ -197,11 +198,16 @@ public:
198
WSLCSessionManager(wsl::windows::service::wslc::WSLCSessionManagerImpl* Impl);
199
200
IFACEMETHOD(GetVersion)(_Out_ WSLCVersion* Version) override;
200
- IFACEMETHOD(IsClientVersionSupported)(_In_ const WSLCVersion* ClientVersion, _Out_ BOOL* IsSupported) override;
201
IFACEMETHOD(CreateSession)(
202
const WSLCSessionSettings* WslcSessionSettings, WSLCSessionFlags Flags, IWarningCallback* WarningCallback, IWSLCSession** WslcSession) override;
203
IFACEMETHOD(EnterSession)(_In_ LPCWSTR DisplayName, _In_ LPCWSTR StoragePath, IWarningCallback* WarningCallback, IWSLCSession** WslcSession) override;
204
IFACEMETHOD(ListSessions)(_Out_ WSLCSessionListEntry** Sessions, _Out_ ULONG* SessionsCount) override;
205
IFACEMETHOD(OpenSession)(_In_ ULONG Id, _Out_ IWSLCSession** Session) override;
206
IFACEMETHOD(OpenSessionByName)(_In_ LPCWSTR DisplayName, _Out_ IWSLCSession** Session) override;
207
+
208
+ // IWSLCCompatSessionManager.
209
+ IFACEMETHOD(GetVersion)(_Out_ WSLCCompatVersion* Version) override;
210
+ IFACEMETHOD(IsClientVersionSupported)(_In_ const WSLCCompatVersion* ClientVersion, _Out_ BOOL* IsSupported) override;
211
+ IFACEMETHOD(CreateSession)(
212
+ const WSLCCompatSessionSettings* Settings, WSLCSessionFlags Flags, IWSLCCompatWarningCallback* WarningCallback, IWSLCCompatSession** Session) override;
213
};
src/windows/service/inc/CMakeLists.txt
+1
-1
@@ -1,3 +1,3 @@
1
-add_idl(wslserviceidl "wslservice.idl;wslc.idl" "windowsdefs.idl")
1
+add_idl(wslserviceidl "wslservice.idl;wslc.idl;WSLCCompat.idl" "windowsdefs.idl;WSLCShared.idl")
2
3
set_target_properties(wslserviceidl PROPERTIES FOLDER windows)
src/windows/service/inc/WSLCCompat.idl
new
+363
@@ -0,0 +1,363 @@
1
+/*++
2
+
3
+Copyright (c) Microsoft Corporation. All rights reserved.
4
+
5
+Module Name:
6
+
7
+ WSLCCompat.idl
8
+
9
+Abstract:
10
+
11
+ This file contains the WSLC SDK-facing COM object definitions.
12
+ Changes in this file must maintain backwards compatibility
13
+
14
+--*/
15
+
16
+import "unknwn.idl";
17
+import "wtypes.idl";
18
+
19
+// Enums and flags shared with the service API (wslc.idl).
20
+import "WSLCShared.idl";
21
+
22
+cpp_quote("#ifdef __cplusplus")
23
+cpp_quote("class DECLSPEC_UUID(\"a9b7a1b9-0671-405c-95f1-e0612cb4ce8f\") WSLCCompatSessionManager;")
24
+cpp_quote("class DECLSPEC_UUID(\"9fcd2067-9fc6-4efa-9eb0-698169ebf7d3\") WSLCCompatSessionManagerFactory;")
25
+cpp_quote("#endif")
26
+
27
+#define WSLCCompat_MAX_IMAGE_NAME_LENGTH 255
28
+#define WSLCCompat_MAX_VOLUME_NAME_LENGTH 255
29
+#define WSLCCompat_MAX_VOLUME_DRIVER_LENGTH 255
30
+#define WSLCCompat_CONTAINER_ID_LENGTH 64
31
+#define WSLCCompat_MAX_BINDING_ADDRESS_LENGTH 45
32
+
33
+typedef
34
+struct _WSLCCompatVersion {
35
+ ULONG Major;
36
+ ULONG Minor;
37
+ ULONG Revision;
38
+} WSLCCompatVersion;
39
+
40
+[
41
+ uuid(EAA15E20-7FCC-485B-B798-ED4095DBACA5),
42
+ pointer_default(unique),
43
+ object
44
+]
45
+interface IWSLCCompatCrashDumpCallback : IUnknown
46
+{
47
+ HRESULT OnCrashDump(
48
+ [in, string] LPCWSTR DumpPath,
49
+ [in, unique, string] LPCSTR ProcessName,
50
+ [in] ULONGLONG Pid,
51
+ [in] ULONG Signal,
52
+ [in] ULONGLONG Timestamp);
53
+};
54
+
55
+[
56
+ uuid(06154F2A-ACA7-461E-94FC-92781BA1F6F6),
57
+ pointer_default(unique),
58
+ object
59
+]
60
+interface IWSLCCompatProgressCallback : IUnknown
61
+{
62
+ HRESULT OnProgress(LPCSTR Status, LPCSTR Id, ULONGLONG Current, ULONGLONG Total);
63
+};
64
+
65
+[
66
+ uuid(290C58A1-328C-4E90-B09B-0A9D32C40074),
67
+ pointer_default(unique),
68
+ object
69
+]
70
+interface IWSLCCompatWarningCallback : IUnknown
71
+{
72
+ HRESULT OnWarning([in, string] LPCWSTR Message);
73
+};
74
+
75
+typedef struct _WSLCCompatImageInformation
76
+{
77
+ char Image[WSLCCompat_MAX_IMAGE_NAME_LENGTH + 1];
78
+ char Hash[256];
79
+ char Digest[256];
80
+ LONGLONG Size; // Matches Docker's int64 image size
81
+ LONGLONG Created; // Unix timestamp
82
+ char ParentId[256];
83
+} WSLCCompatImageInformation;
84
+
85
+typedef struct _WSLCCompatKeyValuePair
86
+{
87
+ [string] LPCSTR Key;
88
+ [string] LPCSTR Value;
89
+} WSLCCompatKeyValuePair;
90
+
91
+typedef WSLCCompatKeyValuePair WSLCCompatLabel;
92
+typedef WSLCCompatKeyValuePair WSLCCompatDriverOption;
93
+typedef WSLCCompatKeyValuePair WSLCCompatFilter;
94
+
95
+typedef struct _WSLCCompatListImagesOptions
96
+{
97
+ DWORD Flags; // WSLCListImagesFlags (can combine with bitwise OR)
98
+ [unique, size_is(FiltersCount)] const WSLCCompatFilter* Filters;
99
+ ULONG FiltersCount;
100
+} WSLCCompatListImagesOptions;
101
+
102
+typedef struct _WSLCCompatStringArray
103
+{
104
+ [unique, size_is(Count)] LPCSTR const* Values;
105
+ ULONG Count;
106
+} WSLCCompatStringArray;
107
+
108
+typedef struct _WSLCCompatProcessOptions
109
+{
110
+ [unique] LPCSTR CurrentDirectory;
111
+ [unique] LPCSTR User;
112
+ WSLCCompatStringArray CommandLine;
113
+ WSLCCompatStringArray Environment;
114
+ WSLCProcessFlags Flags;
115
+} WSLCCompatProcessOptions;
116
+
117
+typedef struct _WSLCCompatNamedVolume
118
+{
119
+ LPCSTR Name;
120
+ LPCSTR ContainerPath;
121
+ BOOL ReadOnly;
122
+} WSLCCompatNamedVolume;
123
+
124
+typedef struct _WSLCCompatVolume
125
+{
126
+ LPCWSTR HostPath;
127
+ LPCSTR ContainerPath;
128
+ BOOL ReadOnly;
129
+} WSLCCompatVolume;
130
+
131
+typedef struct _WSLCCompatPortMapping
132
+{
133
+ USHORT HostPort;
134
+ USHORT ContainerPort;
135
+ int Family;
136
+ int Protocol;
137
+ char BindingAddress[WSLCCompat_MAX_BINDING_ADDRESS_LENGTH + 1];
138
+} WSLCCompatPortMapping;
139
+
140
+typedef struct _WSLCCompatTmpfsMount
141
+{
142
+ LPCSTR Destination;
143
+ [unique] LPCSTR Options;
144
+} WSLCCompatTmpfsMount;
145
+
146
+typedef struct _WSLCCompatUlimit
147
+{
148
+ [string] LPCSTR Name;
149
+ LONGLONG Soft;
150
+ LONGLONG Hard;
151
+} WSLCCompatUlimit;
152
+
153
+typedef struct _WSLCCompatNetworkConnection
154
+{
155
+ [string] LPCSTR NetworkName;
156
+ [unique, size_is(SettingsCount)] const WSLCCompatKeyValuePair* Settings;
157
+ ULONG SettingsCount;
158
+} WSLCCompatNetworkConnection;
159
+
160
+typedef struct _WSLCCompatContainerNetwork
161
+{
162
+ [unique, string] LPCSTR NetworkMode;
163
+
164
+ [unique, size_is(NetworksCount)] const WSLCCompatNetworkConnection* Networks;
165
+ ULONG NetworksCount;
166
+} WSLCCompatContainerNetwork;
167
+
168
+typedef struct _WSLCCompatContainerOptions
169
+{
170
+ LPCSTR Image;
171
+ [unique] LPCSTR Name;
172
+ WSLCCompatStringArray Entrypoint;
173
+ WSLCCompatProcessOptions InitProcessOptions;
174
+ [unique, size_is(VolumesCount)] WSLCCompatVolume* Volumes;
175
+ ULONG VolumesCount;
176
+ [unique, size_is(PortsCount)] WSLCCompatPortMapping* Ports;
177
+ ULONG PortsCount;
178
+ [unique, size_is(LabelsCount)] const WSLCCompatLabel* Labels;
179
+ ULONG LabelsCount;
180
+ WSLCContainerFlags Flags;
181
+ WSLCSignal StopSignal;
182
+ [unique] LPCSTR HostName;
183
+ [unique] LPCSTR DomainName;
184
+
185
+ WSLCCompatStringArray DnsServers;
186
+ WSLCCompatStringArray DnsSearchDomains;
187
+ WSLCCompatStringArray DnsOptions;
188
+
189
+ LONGLONG ShmSize;
190
+ WSLCCompatContainerNetwork ContainerNetwork;
191
+ [unique, size_is(TmpfsCount)] const WSLCCompatTmpfsMount* Tmpfs;
192
+ ULONG TmpfsCount;
193
+
194
+ [unique, size_is(NamedVolumesCount)] WSLCCompatNamedVolume* NamedVolumes;
195
+ ULONG NamedVolumesCount;
196
+
197
+ LONGLONG MemoryBytes;
198
+ LONGLONG NanoCpus;
199
+ [unique, size_is(UlimitsCount)] const WSLCCompatUlimit* Ulimits;
200
+ ULONG UlimitsCount;
201
+} WSLCCompatContainerOptions;
202
+
203
+typedef char WSLCCompatContainerId[WSLCCompat_CONTAINER_ID_LENGTH + 1];
204
+
205
+typedef [system_handle(sh_file)] HANDLE WSLCCompatFileHandle;
206
+typedef [system_handle(sh_pipe)] HANDLE WSLCCompatPipeHandle;
207
+typedef [system_handle(sh_socket)] HANDLE WSLCCompatSocketHandle;
208
+
209
+typedef struct _WSLCCompatHandle
210
+{
211
+ WSLCHandleType Type;
212
+
213
+ [switch_type(WSLCHandleType), switch_is(Type)]
214
+ union
215
+ {
216
+ [case(WSLCHandleTypeFile)]
217
+ WSLCCompatFileHandle File;
218
+ [case(WSLCHandleTypePipe)]
219
+ WSLCCompatPipeHandle Pipe;
220
+ [case(WSLCHandleTypeSocket)]
221
+ WSLCCompatSocketHandle Socket;
222
+ [default];
223
+ } Handle;
224
+} WSLCCompatHandle;
225
+
226
+[
227
+ uuid(AC69DD0D-6616-4C4F-91F2-C39D6034EA82),
228
+ pointer_default(unique),
229
+ object
230
+]
231
+interface IWSLCCompatProcess : IUnknown
232
+{
233
+ HRESULT Signal([in] int Signal);
234
+ HRESULT GetExitEvent([out, system_handle(sh_event)] HANDLE* EventHandle);
235
+ HRESULT GetStdHandle([in] WSLCFD Fd, [out] WSLCCompatHandle* Handle);
236
+ HRESULT GetPid([out] int* Pid);
237
+ HRESULT GetState([out] WSLCProcessState* State, [out] int* Code);
238
+}
239
+
240
+typedef struct _WSLCCompatSessionSettings {
241
+ LPCWSTR DisplayName;
242
+ LPCWSTR StoragePath;
243
+ ULONGLONG MaximumStorageSizeMb;
244
+ ULONG CpuCount;
245
+ ULONG MemoryMb;
246
+ ULONG BootTimeoutMs;
247
+ WSLCNetworkingMode NetworkingMode;
248
+ WSLCFeatureFlags FeatureFlags;
249
+ WSLCCompatHandle DmesgOutput;
250
+ WSLCSessionStorageFlags StorageFlags;
251
+
252
+ // Below options are used for debugging purposes only.
253
+ [unique] LPCWSTR RootVhdOverride;
254
+ [unique] LPCSTR RootVhdTypeOverride;
255
+} WSLCCompatSessionSettings;
256
+
257
+[
258
+ uuid(8C3C91FA-D550-41B9-AD9D-23DCBF96F549),
259
+ pointer_default(unique),
260
+ object
261
+]
262
+interface IWSLCCompatContainer : IUnknown
263
+{
264
+ HRESULT Stop([in] WSLCSignal Signal, [in] LONG TimeoutSeconds);
265
+ HRESULT Start([in] WSLCContainerStartFlags Flags);
266
+ HRESULT Delete([in] WSLCDeleteFlags Flags);
267
+ HRESULT GetState([out] WSLCContainerState* State);
268
+ HRESULT GetInitProcess([out] IWSLCCompatProcess** Process);
269
+ HRESULT Exec([in, ref] const WSLCCompatProcessOptions* Options, [out] IWSLCCompatProcess** Process);
270
+ HRESULT Inspect([out] LPSTR* Output);
271
+ HRESULT GetId([out, string] WSLCCompatContainerId Id);
272
+}
273
+
274
+typedef struct _WSLCCompatDeletedImageInformation
275
+{
276
+ char Image[WSLCCompat_MAX_IMAGE_NAME_LENGTH + 1];
277
+ WSLCDeletedImageType Type;
278
+} WSLCCompatDeletedImageInformation;
279
+
280
+typedef struct _WSLCCompatDeleteImageOptions
281
+{
282
+ LPCSTR Image; // Image can be ID or Repo:Tag.
283
+ DWORD Flags; // WSLCDeleteImageFlags
284
+} WSLCCompatDeleteImageOptions;
285
+
286
+typedef struct _WSLCCompatTagImageOptions
287
+{
288
+ LPCSTR Image; // Source image name or ID.
289
+ LPCSTR Repo; // Target repository name.
290
+ LPCSTR Tag; // Target tag name.
291
+} WSLCCompatTagImageOptions;
292
+
293
+typedef struct _WSLCCompatVolumeOptions
294
+{
295
+ [unique] LPCSTR Name;
296
+ [unique] LPCSTR Driver;
297
+ [unique, size_is(DriverOptsCount)] const WSLCCompatDriverOption* DriverOpts;
298
+ ULONG DriverOptsCount;
299
+ [unique, size_is(LabelsCount)] const WSLCCompatLabel* Labels;
300
+ ULONG LabelsCount;
301
+} WSLCCompatVolumeOptions;
302
+
303
+typedef char WSLCCompatVolumeName[WSLCCompat_MAX_VOLUME_NAME_LENGTH + 1];
304
+
305
+typedef struct _WSLCCompatVolumeInformation
306
+{
307
+ WSLCCompatVolumeName Name;
308
+ char Driver[WSLCCompat_MAX_VOLUME_DRIVER_LENGTH + 1];
309
+} WSLCCompatVolumeInformation;
310
+
311
+[
312
+ uuid(DD7B2EF9-AA01-4F21-8A3A-29D394CBB579),
313
+ pointer_default(unique),
314
+ object
315
+]
316
+interface IWSLCCompatSession : IUnknown
317
+{
318
+ // Image management.
319
+ HRESULT PullImage([in] LPCSTR Image, [in, unique] LPCSTR RegistryAuthenticationInformation, [in, unique] IWSLCCompatProgressCallback* ProgressCallback, [in, unique] IWSLCCompatWarningCallback* WarningCallback);
320
+ HRESULT LoadImage([in] WSLCCompatHandle ImageHandle, [in, unique] IWSLCCompatProgressCallback* ProgressCallback, [in] ULONGLONG ContentLength, [in, unique] IWSLCCompatWarningCallback* WarningCallback);
321
+ HRESULT ImportImage([in] WSLCCompatHandle ImageHandle, [in] LPCSTR ImageName, [in, unique] IWSLCCompatProgressCallback* ProgressCallback, [in] ULONGLONG ContentLength, [in, unique] IWSLCCompatWarningCallback* WarningCallback);
322
+ HRESULT ListImages([in, unique] const WSLCCompatListImagesOptions* Options, [out, size_is(, *Count)] WSLCCompatImageInformation** Images, [out] ULONG* Count);
323
+ HRESULT DeleteImage([in] const WSLCCompatDeleteImageOptions* Options, [out, size_is(, *Count)] WSLCCompatDeletedImageInformation** DeletedImages, [out] ULONG* Count);
324
+ HRESULT TagImage([in] const WSLCCompatTagImageOptions* Options);
325
+
326
+ // Container management.
327
+ HRESULT CreateContainer([in] const WSLCCompatContainerOptions* Options, [in, unique] IWSLCCompatWarningCallback* WarningCallback, [out] IWSLCCompatContainer** Container);
328
+
329
+ // Terminate the VM and containers.
330
+ HRESULT Terminate();
331
+
332
+ // Returns a one-off event that is signaled when the session terminates, whether due to an
333
+ // explicit Terminate() call or an unexpected VM exit. The returned handle is owned by the
334
+ // caller and remains valid (and observes the signaled state) even after the session is released.
335
+ HRESULT GetTerminationEvent([out, system_handle(sh_event)] HANDLE* Event);
336
+
337
+ // Returns the cached termination reason and details. These are only available after the
338
+ // termination event has been signaled; before that the call fails.
339
+ HRESULT GetTerminationReason([out] WSLCVirtualMachineTerminationReason* Reason, [out] LPWSTR* Details);
340
+
341
+ // Volume management.
342
+ HRESULT CreateVolume([in] const WSLCCompatVolumeOptions* Options, [out] WSLCCompatVolumeInformation* VolumeInfo);
343
+ HRESULT DeleteVolume([in] LPCSTR Name);
344
+
345
+ HRESULT Authenticate([in] LPCSTR ServerAddress, [in] LPCSTR Username, [in] LPCSTR Password, [out] LPSTR* IdentityToken);
346
+ HRESULT PushImage([in] LPCSTR Image, [in] LPCSTR RegistryAuthenticationInformation, [in, unique] IWSLCCompatProgressCallback* ProgressCallback, [in, unique] IWSLCCompatWarningCallback* WarningCallback);
347
+
348
+ HRESULT RegisterCrashDumpCallback([in] IWSLCCompatCrashDumpCallback* Callback, [out] IUnknown** Subscription);
349
+}
350
+
351
+[
352
+ uuid(279F2047-DA35-45A3-B671-AFD2302D5D16),
353
+ pointer_default(unique),
354
+ object
355
+]
356
+interface IWSLCCompatSessionManager : IUnknown
357
+{
358
+ HRESULT GetVersion([out] WSLCCompatVersion* Version);
359
+ HRESULT IsClientVersionSupported([in] const WSLCCompatVersion* ClientVersion, [out] BOOL* IsSupported);
360
+
361
+ // Session management.
362
+ HRESULT CreateSession([in, unique] const WSLCCompatSessionSettings* Settings, WSLCSessionFlags Flags, [in, unique] IWSLCCompatWarningCallback* WarningCallback, [out] IWSLCCompatSession** Session);
363
+}
src/windows/service/inc/WSLCShared.idl
new
+248
@@ -0,0 +1,248 @@
1
+/*++
2
+
3
+Copyright (c) Microsoft Corporation. All rights reserved.
4
+
5
+Module Name:
6
+
7
+ WSLCShared.idl
8
+
9
+Abstract:
10
+
11
+ This file contains the enum and flag definitions shared between the WSLC
12
+ service API (wslc.idl) and the WSLC SDK-facing API (WSLCCompat.idl).
13
+ Backwards compatibility must be maintained when changes made to this file
14
+
15
+--*/
16
+
17
+import "wtypes.idl";
18
+
19
+typedef enum _WSLCVirtualMachineTerminationReason
20
+{
21
+ WSLCVirtualMachineTerminationReasonUnknown,
22
+ WSLCVirtualMachineTerminationReasonShutdown,
23
+ WSLCVirtualMachineTerminationReasonCrashed,
24
+} WSLCVirtualMachineTerminationReason;
25
+
26
+typedef enum _WSLCFD
27
+{
28
+ WSLCFDStdin = 0,
29
+ WSLCFDStdout = 1,
30
+ WSLCFDStderr = 2,
31
+ WSLCFDTty = 3,
32
+} WSLCFD;
33
+
34
+typedef enum _WSLCSignal
35
+{
36
+ WSLCSignalNone = 0,
37
+ WSLCSignalSIGHUP = 1,
38
+ WSLCSignalSIGINT = 2,
39
+ WSLCSignalSIGQUIT = 3,
40
+ WSLCSignalSIGILL = 4,
41
+ WSLCSignalSIGTRAP = 5,
42
+ WSLCSignalSIGABRT = 6,
43
+ WSLCSignalSIGIOT = 6, // SIGABRT and SIGIOT are equivalent.
44
+ WSLCSignalSIGBUS = 7,
45
+ WSLCSignalSIGFPE = 8,
46
+ WSLCSignalSIGKILL = 9,
47
+ WSLCSignalSIGUSR1 = 10,
48
+ WSLCSignalSIGSEGV = 11,
49
+ WSLCSignalSIGUSR2 = 12,
50
+ WSLCSignalSIGPIPE = 13,
51
+ WSLCSignalSIGALRM = 14,
52
+ WSLCSignalSIGTERM = 15,
53
+ WSLCSignalSIGTKFLT = 16,
54
+ WSLCSignalSIGCHLD = 17,
55
+ WSLCSignalSIGCONT = 18,
56
+ WSLCSignalSIGSTOP = 19,
57
+ WSLCSignalSIGTSTP = 20,
58
+ WSLCSignalSIGTTIN = 21,
59
+ WSLCSignalSIGTTOU = 22,
60
+ WSLCSignalSIGURG = 23,
61
+ WSLCSignalSIGXCPU = 24,
62
+ WSLCSignalSIGXFSZ = 25,
63
+ WSLCSignalSIGVTALRM = 26,
64
+ WSLCSignalSIGPROF = 27,
65
+ WSLCSignalSIGWINCH = 28,
66
+ WSLCSignalSIGIO = 29,
67
+ WSLCSignalSIGPOLL = 29, // SIGIO and SIGPOLL are equivalent.
68
+ WSLCSignalSIGPWR = 30,
69
+ WSLCSignalSIGSYS = 31
70
+} WSLCSignal;
71
+
72
+typedef enum _WSLCListImagesFlags
73
+{
74
+ WSLCListImagesFlagsNone = 0,
75
+ WSLCListImagesFlagsAll = 1, // Show all images (default hides intermediate images)
76
+ WSLCListImagesFlagsDigests = 2, // Include digest information
77
+} WSLCListImagesFlags;
78
+
79
+cpp_quote("#define WSLCListImagesFlagsValid (WSLCListImagesFlagsAll | WSLCListImagesFlagsDigests)")
80
+
81
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCListImagesFlags);")
82
+
83
+typedef enum _WSLCProcessFlags
84
+{
85
+ WSLCProcessFlagsNone = 0,
86
+ WSLCProcessFlagsStdin = 1,
87
+ WSLCProcessFlagsTty = 2
88
+} WSLCProcessFlags;
89
+
90
+cpp_quote("#define WSLCProcessFlagsValid (WSLCProcessFlagsStdin | WSLCProcessFlagsTty)")
91
+
92
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCProcessFlags);")
93
+
94
+typedef enum _WSLCContainerFlags
95
+{
96
+ WSLCContainerFlagsNone = 0,
97
+ WSLCContainerFlagsRm = 1, // Delete the container when it exits.
98
+ WSLCContainerFlagsGpu = 2, // Enable GPU access.
99
+ WSLCContainerFlagsInit = 4, // Run the container under an init process.
100
+ WSLCContainerFlagsPublishAll = 8, // Publish all exposed ports.
101
+} WSLCContainerFlags;
102
+
103
+cpp_quote("#define WSLCContainerFlagsValid (WSLCContainerFlagsRm | WSLCContainerFlagsGpu | WSLCContainerFlagsInit | WSLCContainerFlagsPublishAll)")
104
+
105
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCContainerFlags);")
106
+
107
+typedef enum _WSLCContainerStartFlags
108
+{
109
+ WSLCContainerStartFlagsNone = 0,
110
+ WSLCContainerStartFlagsAttach = 1, // Attach stdio handles on start.
111
+} WSLCContainerStartFlags;
112
+
113
+cpp_quote("#define WSLCContainerStartFlagsValid (WSLCContainerStartFlagsAttach)")
114
+
115
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCContainerStartFlags);")
116
+
117
+typedef enum _WSLCContainerState
118
+{
119
+ WslcContainerStateInvalid = 0,
120
+ WslcContainerStateCreated = 1,
121
+ WslcContainerStateRunning = 2,
122
+ WslcContainerStateExited = 3,
123
+ WslcContainerStateDeleted = 4,
124
+} WSLCContainerState;
125
+
126
+typedef enum _WSLCHandleType
127
+{
128
+ WSLCHandleTypeUnknown = 0,
129
+ WSLCHandleTypeFile = 1,
130
+ WSLCHandleTypePipe = 2,
131
+ WSLCHandleTypeSocket = 3
132
+} WSLCHandleType;
133
+
134
+typedef enum _WSLCProcessState
135
+{
136
+ WslcProcessStateUnknown = 0,
137
+ WslcProcessStateRunning = 1,
138
+ WslcProcessStateExited = 2,
139
+ WslcProcessStateSignalled = 3
140
+} WSLCProcessState;
141
+
142
+typedef enum _WSLCNetworkingMode
143
+{
144
+ WSLCNetworkingModeNone,
145
+ WSLCNetworkingModeNAT,
146
+ WSLCNetworkingModeVirtioProxy
147
+} WSLCNetworkingMode;
148
+
149
+typedef enum _WSLCFeatureFlags
150
+{
151
+ WslcFeatureFlagsNone = 0,
152
+ WslcFeatureFlagsDnsTunneling = 1,
153
+ WslcFeatureFlagsEarlyBootDmesg = 2,
154
+ WslcFeatureFlagsGPU = 4,
155
+ WslcFeatureFlagsVirtioFs = 8,
156
+ WslcFeatureFlagsDebug = 16,
157
+} WSLCFeatureFlags;
158
+
159
+cpp_quote("#define WSLCFeatureFlagsValid (WslcFeatureFlagsDnsTunneling | WslcFeatureFlagsEarlyBootDmesg | WslcFeatureFlagsGPU | WslcFeatureFlagsVirtioFs | WslcFeatureFlagsDebug)")
160
+
161
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCFeatureFlags);")
162
+
163
+typedef enum _WSLCSessionStorageFlags
164
+{
165
+ WSLCSessionStorageFlagsNone = 0,
166
+ WSLCSessionStorageFlagsNoCreate = 1, // Open an existing storage path, but don't create a new one.
167
+ WSLCSessionStorageFlagsValid = WSLCSessionStorageFlagsNoCreate
168
+} WSLCSessionStorageFlags;
169
+
170
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCSessionStorageFlags);")
171
+
172
+typedef enum _WSLCLogsFlags
173
+{
174
+ WSLCLogsFlagsNone = 0,
175
+ WSLCLogsFlagsFollow = 1,
176
+ WSLCLogsFlagsTimestamps = 2,
177
+} WSLCLogsFlags;
178
+
179
+cpp_quote("#define WSLCLogsFlagsValid (WSLCLogsFlagsFollow | WSLCLogsFlagsTimestamps)")
180
+
181
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCLogsFlags);")
182
+
183
+typedef enum _WSLCDeleteFlags
184
+{
185
+ WSLCDeleteFlagsNone = 0,
186
+ WSLCDeleteFlagsForce = 1,
187
+ WSLCDeleteFlagsDeleteVolumes = 2,
188
+ // TODO: Flags to remove bridge links, etc.
189
+} WSLCDeleteFlags;
190
+
191
+cpp_quote("#define WSLCDeleteFlagsValid (WSLCDeleteFlagsForce | WSLCDeleteFlagsDeleteVolumes)")
192
+
193
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCDeleteFlags);")
194
+
195
+typedef enum _WSLCDeletedImageType
196
+{
197
+ WSLCDeletedImageTypeDeleted = 0,
198
+ WSLCDeletedImageTypeUntagged = 1
199
+} WSLCDeletedImageType;
200
+
201
+typedef enum _WSLCDeleteImageFlags
202
+{
203
+ WSLCDeleteImageFlagsNone = 0,
204
+ WSLCDeleteImageFlagsForce = 1,
205
+ WSLCDeleteImageFlagsNoPrune = 2,
206
+} WSLCDeleteImageFlags;
207
+
208
+cpp_quote("#define WSLCDeleteImageFlagsValid (WSLCDeleteImageFlagsForce | WSLCDeleteImageFlagsNoPrune)")
209
+
210
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCDeleteImageFlags);")
211
+
212
+typedef enum _WSLCBuildImageFlags
213
+{
214
+ WSLCBuildImageFlagsNone = 0,
215
+ WSLCBuildImageFlagsVerbose = 1, // Show all build progress including internal steps.
216
+ WSLCBuildImageFlagsNoCache = 2, // Do not use cache when building the image.
217
+ WSLCBuildImageFlagsPull = 4, // Always attempt to pull a newer version of the image.
218
+} WSLCBuildImageFlags;
219
+
220
+cpp_quote("#define WSLCBuildImageFlagsValid (WSLCBuildImageFlagsVerbose | WSLCBuildImageFlagsNoCache | WSLCBuildImageFlagsPull)")
221
+
222
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCBuildImageFlags);")
223
+
224
+typedef enum _WSLCListContainersFlags
225
+{
226
+ WSLCListContainersFlagsNone = 0,
227
+ WSLCListContainersFlagsAll = 1,
228
+} WSLCListContainersFlags;
229
+
230
+cpp_quote("#define WSLCListContainersFlagsValid (WSLCListContainersFlagsAll)")
231
+
232
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCListContainersFlags);")
233
+
234
+typedef enum _WSLCSessionState
235
+{
236
+ WSLCSessionStateRunning = 0,
237
+ WSLCSessionStateTerminated = 1
238
+} WSLCSessionState;
239
+
240
+typedef enum _WSLCSessionFlags
241
+{
242
+ WSLCSessionFlagsNone = 0,
243
+ WSLCSessionFlagsPersistent = 1, // Session remains active after its COM reference is released.
244
+ WSLCSessionFlagsOpenExisting = 2, // Open an existing session if the name is in use.
245
+} WSLCSessionFlags;
246
+
247
+cpp_quote("#define WSLCSessionFlagsValid (WSLCSessionFlagsPersistent | WSLCSessionFlagsOpenExisting)")
248
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCSessionFlags);")
src/windows/service/inc/wslc.idl
+6
-235
@@ -9,15 +9,20 @@ Module Name:
9
Abstract:
10
11
This file contains the WSLC-related COM object definitions.
12
+ // N.B. ABI breaking changes in this file are OK, since both client & server always ship together.
13
+ // The WSLC SDK must not use this file, and instead use WSLCCompat.idl
14
15
--*/
16
17
import "unknwn.idl";
18
import "wtypes.idl";
19
20
+// Enums and flags shared with the SDK-facing API (WSLCCompat.idl).
21
+import "WSLCShared.idl";
22
+
23
cpp_quote("#ifdef __cplusplus")
24
cpp_quote("class DECLSPEC_UUID(\"a9b7a1b9-0671-405c-95f1-e0612cb4ce8f\") WSLCSessionManager;")
20
-cpp_quote("class DECLSPEC_UUID(\"9FCD2067-9FC6-4EFA-9EB0-698169EBF7D3\") WSLCSessionFactory;")
25
+cpp_quote("class DECLSPEC_UUID(\"9fcd2067-9fc6-4efa-9eb0-698169ebf7d3\") WSLCSessionFactory;")
26
cpp_quote("#endif")
27
28
#define WSLC_MAX_CONTAINER_NAME_LENGTH 255
@@ -46,59 +51,6 @@ struct _WSLCVersion {
51
ULONG Revision;
52
} WSLCVersion;
53
49
-typedef enum _WSLCVirtualMachineTerminationReason
50
-{
51
- WSLCVirtualMachineTerminationReasonUnknown,
52
- WSLCVirtualMachineTerminationReasonShutdown,
53
- WSLCVirtualMachineTerminationReasonCrashed,
54
-} WSLCVirtualMachineTerminationReason;
55
-
56
-typedef enum _WSLCFD
57
-{
58
- WSLCFDStdin = 0,
59
- WSLCFDStdout = 1,
60
- WSLCFDStderr = 2,
61
- WSLCFDTty = 3,
62
-} WSLCFD;
63
-
64
-typedef enum _WSLCSignal
65
-{
66
- WSLCSignalNone = 0,
67
- WSLCSignalSIGHUP = 1,
68
- WSLCSignalSIGINT = 2,
69
- WSLCSignalSIGQUIT = 3,
70
- WSLCSignalSIGILL = 4,
71
- WSLCSignalSIGTRAP = 5,
72
- WSLCSignalSIGABRT = 6,
73
- WSLCSignalSIGIOT = 6, // SIGABRT and SIGIOT are equivalent.
74
- WSLCSignalSIGBUS = 7,
75
- WSLCSignalSIGFPE = 8,
76
- WSLCSignalSIGKILL = 9,
77
- WSLCSignalSIGUSR1 = 10,
78
- WSLCSignalSIGSEGV = 11,
79
- WSLCSignalSIGUSR2 = 12,
80
- WSLCSignalSIGPIPE = 13,
81
- WSLCSignalSIGALRM = 14,
82
- WSLCSignalSIGTERM = 15,
83
- WSLCSignalSIGTKFLT = 16,
84
- WSLCSignalSIGCHLD = 17,
85
- WSLCSignalSIGCONT = 18,
86
- WSLCSignalSIGSTOP = 19,
87
- WSLCSignalSIGTSTP = 20,
88
- WSLCSignalSIGTTIN = 21,
89
- WSLCSignalSIGTTOU = 22,
90
- WSLCSignalSIGURG = 23,
91
- WSLCSignalSIGXCPU = 24,
92
- WSLCSignalSIGXFSZ = 25,
93
- WSLCSignalSIGVTALRM = 26,
94
- WSLCSignalSIGPROF = 27,
95
- WSLCSignalSIGWINCH = 28,
96
- WSLCSignalSIGIO = 29,
97
- WSLCSignalSIGPOLL = 29, // SIGIO and SIGPOLL are equivalent.
98
- WSLCSignalSIGPWR = 30,
99
- WSLCSignalSIGSYS = 31
100
-} WSLCSignal;
101
-
54
[
55
uuid(8C5A7B14-9D26-4FAE-AB31-7E5BC23F4801),
56
pointer_default(unique),
@@ -165,17 +117,6 @@ typedef struct _WSLCImageInformation
117
char ParentId[256];
118
} WSLCImageInformation;
119
168
-typedef enum _WSLCListImagesFlags
169
-{
170
- WSLCListImagesFlagsNone = 0,
171
- WSLCListImagesFlagsAll = 1, // Show all images (default hides intermediate images)
172
- WSLCListImagesFlagsDigests = 2, // Include digest information
173
-} WSLCListImagesFlags;
174
-
175
-cpp_quote("#define WSLCListImagesFlagsValid (WSLCListImagesFlagsAll | WSLCListImagesFlagsDigests)")
176
-
177
-cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCListImagesFlags);")
178
-
120
typedef struct _KeyValuePairInformation
121
{
122
[string] LPSTR Key;
@@ -202,17 +143,6 @@ typedef struct _WSLCListImagesOptions
143
ULONG FiltersCount;
144
} WSLCListImagesOptions;
145
205
-typedef enum _WSLCProcessFlags
206
-{
207
- WSLCProcessFlagsNone = 0,
208
- WSLCProcessFlagsStdin = 1,
209
- WSLCProcessFlagsTty = 2
210
-} WSLCProcessFlags;
211
-
212
-cpp_quote("#define WSLCProcessFlagsValid (WSLCProcessFlagsStdin | WSLCProcessFlagsTty)")
213
-
214
-cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCProcessFlags);")
215
-
146
typedef struct _WSLCStringArray
147
{
148
[unique, size_is(Count)] LPCSTR const* Values;
@@ -298,30 +228,6 @@ typedef struct _WSLCContainerNetwork
228
ULONG SettingsCount;
229
} WSLCContainerNetwork;
230
301
-typedef enum _WSLCContainerFlags
302
-{
303
- WSLCContainerFlagsNone = 0,
304
- WSLCContainerFlagsRm = 1, // Delete the container when it exits.
305
- WSLCContainerFlagsGpu = 2, // Enable GPU access.
306
- WSLCContainerFlagsInit = 4, // Run the container under an init process.
307
- WSLCContainerFlagsPublishAll = 8, // Publish all exposed ports.
308
-} WSLCContainerFlags;
309
-
310
-cpp_quote("#define WSLCContainerFlagsValid (WSLCContainerFlagsRm | WSLCContainerFlagsGpu | WSLCContainerFlagsInit | WSLCContainerFlagsPublishAll)")
311
-
312
-cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCContainerFlags);")
313
-
314
-
315
-typedef enum _WSLCContainerStartFlags
316
-{
317
- WSLCContainerStartFlagsNone = 0,
318
- WSLCContainerStartFlagsAttach = 1, // Attach stdio handles on start.
319
-} WSLCContainerStartFlags;
320
-
321
-cpp_quote("#define WSLCContainerStartFlagsValid (WSLCContainerStartFlagsAttach)")
322
-
323
-cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCContainerStartFlags);")
324
-
231
typedef struct _WSLCContainerOptions
232
{
233
LPCSTR Image;
@@ -358,15 +264,6 @@ typedef struct _WSLCContainerOptions
264
ULONG UlimitsCount;
265
} WSLCContainerOptions;
266
361
-typedef enum _WSLCContainerState
362
-{
363
- WslcContainerStateInvalid = 0,
364
- WslcContainerStateCreated = 1,
365
- WslcContainerStateRunning = 2,
366
- WslcContainerStateExited = 3,
367
- WslcContainerStateDeleted = 4,
368
-} WSLCContainerState;
369
-
267
typedef char WSLCContainerId[WSLC_CONTAINER_ID_LENGTH + 1] ;
268
269
typedef struct _WSLCContainerEntry
@@ -389,14 +286,6 @@ typedef [system_handle(sh_file)] HANDLE FILE_HANDLE;
286
typedef [system_handle(sh_pipe)] HANDLE PIPE_HANDLE;
287
typedef [system_handle(sh_socket)] HANDLE SOCKET_HANDLE;
288
392
-typedef enum _WSLCHandleType
393
-{
394
- WSLCHandleTypeUnknown = 0,
395
- WSLCHandleTypeFile = 1,
396
- WSLCHandleTypePipe = 2,
397
- WSLCHandleTypeSocket = 3
398
-} WSLCHandleType;
399
-
289
typedef struct _WSLCHandle
290
{
291
WSLCHandleType Type;
@@ -414,14 +303,6 @@ typedef struct _WSLCHandle
303
} Handle;
304
} WSLCHandle;
305
417
-typedef enum _WSLCProcessState
418
-{
419
- WslcProcessStateUnknown = 0,
420
- WslcProcessStateRunning = 1,
421
- WslcProcessStateExited = 2,
422
- WslcProcessStateSignalled = 3
423
-} WSLCProcessState;
424
-
306
[
307
uuid(1AD163CD-393D-4B33-83A2-8A3F3F23E608),
308
pointer_default(unique),
@@ -440,27 +321,6 @@ interface IWSLCProcess : IUnknown
321
// Note: the SDK can offer a convenience Wait() method, but that doesn't need to be part of the service API.
322
}
323
443
-typedef enum _WSLCNetworkingMode
444
-{
445
- WSLCNetworkingModeNone,
446
- WSLCNetworkingModeNAT,
447
- WSLCNetworkingModeVirtioProxy
448
-} WSLCNetworkingMode;
449
-
450
-typedef enum _WSLCFeatureFlags
451
-{
452
- WslcFeatureFlagsNone = 0,
453
- WslcFeatureFlagsDnsTunneling = 1,
454
- WslcFeatureFlagsEarlyBootDmesg = 2,
455
- WslcFeatureFlagsGPU = 4,
456
- WslcFeatureFlagsVirtioFs = 8,
457
- WslcFeatureFlagsDebug = 16,
458
-} WSLCFeatureFlags;
459
-
460
-cpp_quote("#define WSLCFeatureFlagsValid (WslcFeatureFlagsDnsTunneling | WslcFeatureFlagsEarlyBootDmesg | WslcFeatureFlagsGPU | WslcFeatureFlagsVirtioFs | WslcFeatureFlagsDebug)")
461
-
462
-cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCFeatureFlags);")
463
-
324
//
325
// Values discovered from the guest kernel after the VM has booted, forwarded
326
// from wslcsession via IWSLCVirtualMachine::ApplyGuestCapabilities. Add new
@@ -552,15 +412,6 @@ interface IWSLCVirtualMachineFactory : IUnknown
412
HRESULT CreateVirtualMachine([out] IWSLCVirtualMachine** Vm);
413
}
414
555
-typedef enum _WSLCSessionStorageFlags
556
-{
557
- WSLCSessionStorageFlagsNone = 0,
558
- WSLCSessionStorageFlagsNoCreate = 1, // Open an existing storage path, but don't create a new one.
559
- WSLCSessionStorageFlagsValid = WSLCSessionStorageFlagsNoCreate
560
-} WSLCSessionStorageFlags;
561
-
562
-cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCSessionStorageFlags);")
563
-
415
// Settings for IWSLCSessionManager::CreateSession - full session configuration
416
typedef struct _WSLCSessionSettings {
417
LPCWSTR DisplayName;
@@ -579,29 +430,6 @@ typedef struct _WSLCSessionSettings {
430
[unique] LPCSTR RootVhdTypeOverride;
431
} WSLCSessionSettings;
432
582
-typedef enum _WSLCLogsFlags
583
-{
584
- WSLCLogsFlagsNone = 0,
585
- WSLCLogsFlagsFollow = 1,
586
- WSLCLogsFlagsTimestamps = 2,
587
-} WSLCLogsFlags;
588
-
589
-cpp_quote("#define WSLCLogsFlagsValid (WSLCLogsFlagsFollow | WSLCLogsFlagsTimestamps)")
590
-
591
-cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCLogsFlags);")
592
-
593
-typedef enum _WSLCDeleteFlags
594
-{
595
- WSLCDeleteFlagsNone = 0,
596
- WSLCDeleteFlagsForce = 1,
597
- WSLCDeleteFlagsDeleteVolumes = 2,
598
- // TODO: Flags to remove bridge links, etc.
599
-} WSLCDeleteFlags;
600
-
601
-cpp_quote("#define WSLCDeleteFlagsValid (WSLCDeleteFlagsForce | WSLCDeleteFlagsDeleteVolumes)")
602
-
603
-cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCDeleteFlags);")
604
-
433
434
[
435
uuid(7577FE8D-DE85-471E-B870-11669986F332),
@@ -629,29 +457,12 @@ interface IWSLCContainer : IUnknown
457
HRESULT DisconnectFromNetwork([in] LPCSTR NetworkName);
458
}
459
632
-typedef enum _WSLCDeletedImageType
633
-{
634
- WSLCDeletedImageTypeDeleted = 0,
635
- WSLCDeletedImageTypeUntagged = 1
636
-} WSLCDeletedImageType;
637
-
460
typedef struct _WSLCDeletedImageInformation
461
{
462
char Image[WSLC_MAX_IMAGE_NAME_LENGTH + 1];
463
WSLCDeletedImageType Type;
464
} WSLCDeletedImageInformation;
465
644
-typedef enum _WSLCDeleteImageFlags
645
-{
646
- WSLCDeleteImageFlagsNone = 0,
647
- WSLCDeleteImageFlagsForce = 1,
648
- WSLCDeleteImageFlagsNoPrune = 2,
649
-} WSLCDeleteImageFlags;
650
-
651
-cpp_quote("#define WSLCDeleteImageFlagsValid (WSLCDeleteImageFlagsForce | WSLCDeleteImageFlagsNoPrune)")
652
-
653
-cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCDeleteImageFlags);")
654
-
466
typedef struct _WSLCDeleteImageOptions
467
{
468
LPCSTR Image; // Image can be ID or Repo:Tag.
@@ -659,18 +470,6 @@ typedef struct _WSLCDeleteImageOptions
470
// TODO: Platforms: a json array of OCI platform strings.
471
} WSLCDeleteImageOptions;
472
662
-typedef enum _WSLCBuildImageFlags
663
-{
664
- WSLCBuildImageFlagsNone = 0,
665
- WSLCBuildImageFlagsVerbose = 1, // Show all build progress including internal steps.
666
- WSLCBuildImageFlagsNoCache = 2, // Do not use cache when building the image.
667
- WSLCBuildImageFlagsPull = 4, // Always attempt to pull a newer version of the image.
668
-} WSLCBuildImageFlags;
669
-
670
-cpp_quote("#define WSLCBuildImageFlagsValid (WSLCBuildImageFlagsVerbose | WSLCBuildImageFlagsNoCache | WSLCBuildImageFlagsPull)")
671
-
672
-cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCBuildImageFlags);")
673
-
473
typedef struct _WSLCBuildImageOptions
474
{
475
LPCWSTR ContextPath;
@@ -732,16 +531,6 @@ typedef struct _WSLCPruneContainersResults
531
ULONGLONG SpaceReclaimed;
532
} WSLCPruneContainersResults;
533
735
-typedef enum _WSLCListContainersFlags
736
-{
737
- WSLCListContainersFlagsNone = 0,
738
- WSLCListContainersFlagsAll = 1,
739
-} WSLCListContainersFlags;
740
-
741
-cpp_quote("#define WSLCListContainersFlagsValid (WSLCListContainersFlagsAll)")
742
-
743
-cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCListContainersFlags);")
744
-
534
typedef struct _WSLCListContainersOptions
535
{
536
DWORD Flags; // WSLCListContainersFlags
@@ -751,12 +540,6 @@ typedef struct _WSLCListContainersOptions
540
ULONG FiltersCount;
541
} WSLCListContainersOptions;
542
754
-typedef enum _WSLCSessionState
755
-{
756
- WSLCSessionStateRunning = 0,
757
- WSLCSessionStateTerminated = 1
758
-} WSLCSessionState;
759
-
543
// Settings for IWSLCSession::Initialize - passed from service to per-user process
544
typedef struct _WSLCSessionInitSettings
545
{
@@ -911,16 +694,6 @@ typedef struct _WSLCSessionListEntry
694
wchar_t Sid[256 + 1]; // MAX_SID_SIZE = 256
695
} WSLCSessionListEntry;
696
914
-typedef enum _WSLCSessionFlags
915
-{
916
- WSLCSessionFlagsNone = 0,
917
- WSLCSessionFlagsPersistent = 1, // Session remains active after its COM reference is released.
918
- WSLCSessionFlagsOpenExisting = 2, // Open an existing session if the name is in use.
919
-} WSLCSessionFlags;
920
-
921
-cpp_quote("#define WSLCSessionFlagsValid (WSLCSessionFlagsPersistent | WSLCSessionFlagsOpenExisting)")
922
-cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCSessionFlags);")
923
-
697
[
698
uuid(82A7ABC8-6B50-43FC-AB96-15FBBE7E8760),
699
pointer_default(unique),
@@ -929,8 +702,6 @@ cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(WSLCSessionFlags);")
702
interface IWSLCSessionManager : IUnknown
703
{
704
HRESULT GetVersion([out] WSLCVersion* Version);
932
- HRESULT IsClientVersionSupported([in] const WSLCVersion* ClientVersion, [out] BOOL* IsSupported);
933
-
705
// Session management.
706
HRESULT CreateSession([in, unique] const WSLCSessionSettings* Settings, WSLCSessionFlags Flags, [in, unique] IWarningCallback* WarningCallback, [out] IWSLCSession** Session);
707
HRESULT EnterSession([in, ref] LPCWSTR DisplayName, [in, ref] LPCWSTR StoragePath, [in, unique] IWarningCallback* WarningCallback, [out] IWSLCSession** Session);
src/windows/service/stub/CMakeLists.txt
+2
@@ -3,6 +3,8 @@ set(SOURCES
3
${CMAKE_CURRENT_BINARY_DIR}/../inc/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}/wslservice_p_${TARGET_PLATFORM}.c
4
${CMAKE_CURRENT_BINARY_DIR}/../inc/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}/wslc_i_${TARGET_PLATFORM}.c
5
${CMAKE_CURRENT_BINARY_DIR}/../inc/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}/wslc_p_${TARGET_PLATFORM}.c
6
+ ${CMAKE_CURRENT_BINARY_DIR}/../inc/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}/WSLCCompat_i_${TARGET_PLATFORM}.c
7
+ ${CMAKE_CURRENT_BINARY_DIR}/../inc/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}/WSLCCompat_p_${TARGET_PLATFORM}.c
8
${CMAKE_CURRENT_BINARY_DIR}/../inc/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}/dlldata_${TARGET_PLATFORM}.c
9
${CMAKE_CURRENT_LIST_DIR}/WslServiceProxyStub.def
10
${CMAKE_CURRENT_LIST_DIR}/WslServiceProxyStub.rc)
src/windows/wslcsession/WSLCContainer.cpp
+40
-1
@@ -23,6 +23,9 @@ Abstract:
23
#include "WSLCProcess.h"
24
#include "WSLCProcessIO.h"
25
#include "WSLCVolumes.h"
26
+#include "APICompat.h"
27
+
28
+namespace apicompat = wsl::windows::common::apicompat;
29
30
using wsl::windows::common::COMServiceExecutionContext;
31
using wsl::windows::common::docker_schema::ErrorResponse;
@@ -2537,5 +2540,41 @@ CATCH_RETURN();
2540
2541
HRESULT WSLCContainer::InterfaceSupportsErrorInfo(REFIID riid)
2542
{
2540
- return riid == __uuidof(IWSLCContainer) ? S_OK : S_FALSE;
2543
+ return riid == __uuidof(IWSLCContainer) || riid == __uuidof(IWSLCCompatContainer) ? S_OK : S_FALSE;
2544
+}
2545
+
2546
+HRESULT WSLCContainer::Start(WSLCContainerStartFlags Flags)
2547
+{
2548
+ return Start(Flags, nullptr, nullptr);
2549
+}
2550
+
2551
+HRESULT WSLCContainer::GetInitProcess(IWSLCCompatProcess** Process)
2552
+try
2553
+{
2554
+ RETURN_HR_IF_NULL(E_POINTER, Process);
2555
+ *Process = nullptr;
2556
+
2557
+ Microsoft::WRL::ComPtr<IWSLCProcess> process;
2558
+ RETURN_IF_FAILED(GetInitProcess(&process));
2559
+ RETURN_HR_IF_NULL(E_UNEXPECTED, process);
2560
+
2561
+ return process.CopyTo(Process);
2562
+}
2563
+CATCH_RETURN();
2564
+
2565
+HRESULT WSLCContainer::Exec(const WSLCCompatProcessOptions* Options, IWSLCCompatProcess** Process)
2566
+try
2567
+{
2568
+ RETURN_HR_IF_NULL(E_POINTER, Options);
2569
+ RETURN_HR_IF_NULL(E_POINTER, Process);
2570
+ *Process = nullptr;
2571
+
2572
+ const auto options = apicompat::Convert(*Options);
2573
+
2574
+ Microsoft::WRL::ComPtr<IWSLCProcess> process;
2575
+ RETURN_IF_FAILED(Exec(&options, nullptr, &process));
2576
+ RETURN_HR_IF_NULL(E_UNEXPECTED, process);
2577
+
2578
+ return process.CopyTo(Process);
2579
}
2580
+CATCH_RETURN();
src/windows/wslcsession/WSLCContainer.h
+7
-1
@@ -22,6 +22,7 @@ Abstract:
22
#include "IORelay.h"
23
#include "COMImplClass.h"
24
#include "wslc_schema.h"
25
+#include "WSLCCompat.h"
26
#include "WSLCContainerMetadata.h"
27
#include "WSLCNetworkMetadata.h"
28
#include "WSLCVhdVolume.h"
@@ -222,7 +223,7 @@ private:
223
};
224
225
class DECLSPEC_UUID("B1F1C4E3-C225-4CAE-AD8A-34C004DE1AE4") WSLCContainer
225
- : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWSLCContainer, IFastRundown, ISupportErrorInfo>,
226
+ : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWSLCContainer, IWSLCCompatContainer, IFastRundown, ISupportErrorInfo>,
227
public COMImplClass<WSLCContainerImpl>
228
{
229
@@ -247,6 +248,11 @@ public:
248
IFACEMETHOD(ConnectToNetwork)(_In_ const WSLCNetworkConnectionOptions* Options) override;
249
IFACEMETHOD(DisconnectFromNetwork)(_In_ LPCSTR NetworkName) override;
250
251
+ // IWSLCCompatContainer.
252
+ IFACEMETHOD(Start)(_In_ WSLCContainerStartFlags Flags) override;
253
+ IFACEMETHOD(GetInitProcess)(_Out_ IWSLCCompatProcess** Process) override;
254
+ IFACEMETHOD(Exec)(_In_ const WSLCCompatProcessOptions* Options, _Out_ IWSLCCompatProcess** Process) override;
255
+
256
IFACEMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
257
258
// Cache read-only properties so they remain accessible after the impl is disconnected.
src/windows/wslcsession/WSLCProcess.cpp
+15
@@ -15,8 +15,10 @@ Abstract:
15
#include "precomp.h"
16
#include "WSLCProcess.h"
17
#include "WSLCVirtualMachine.h"
18
+#include "APICompat.h"
19
20
using wsl::windows::service::wslc::WSLCProcess;
21
+namespace apicompat = wsl::windows::common::apicompat;
22
23
WSLCProcess::WSLCProcess(std::shared_ptr<WSLCProcessControl> Control, std::unique_ptr<WSLCProcessIO>&& Io, WSLCProcessFlags Flags) :
24
m_control(std::move(Control)), m_io(std::move(Io)), m_flags(Flags)
@@ -122,4 +124,17 @@ try
124
m_control->ResizeTty(Rows, Columns);
125
return S_OK;
126
}
127
+CATCH_RETURN();
128
+
129
+HRESULT WSLCProcess::GetStdHandle(WSLCFD Fd, WSLCCompatHandle* Handle)
130
+try
131
+{
132
+ RETURN_HR_IF_NULL(E_POINTER, Handle);
133
+
134
+ WSLCHandle handle{};
135
+ RETURN_IF_FAILED(GetStdHandle(Fd, &handle));
136
+
137
+ *Handle = apicompat::Convert(handle);
138
+ return S_OK;
139
+}
140
CATCH_RETURN();
\ No newline at end of file
src/windows/wslcsession/WSLCProcess.h
+5
-1
@@ -14,6 +14,7 @@ Abstract:
14
#pragma once
15
16
#include "wslc.h"
17
+#include "WSLCCompat.h"
18
#include "WSLCProcessControl.h"
19
#include "WSLCProcessIO.h"
20
@@ -22,7 +23,7 @@ namespace wsl::windows::service::wslc {
23
class WSLCVirtualMachine;
24
25
class DECLSPEC_UUID("AFBEA6D6-D8A4-4F81-8FED-F947EB74B33B") WSLCProcess
25
- : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWSLCProcess, IFastRundown>
26
+ : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWSLCProcess, IWSLCCompatProcess, IFastRundown>
27
{
28
public:
29
WSLCProcess(std::shared_ptr<WSLCProcessControl> Control, std::unique_ptr<WSLCProcessIO>&& Io, WSLCProcessFlags Flags);
@@ -37,6 +38,9 @@ public:
38
IFACEMETHOD(GetState)(_Out_ WSLCProcessState* State, _Out_ int* Code) override;
39
IFACEMETHOD(ResizeTty)(_In_ ULONG Rows, _In_ ULONG Columns) override;
40
41
+ // IWSLCCompatProcess - converts the WSLCCompat types to the wslc.idl types and forwards to the methods above.
42
+ IFACEMETHOD(GetStdHandle)(_In_ WSLCFD Fd, _Out_ WSLCCompatHandle* Handle) override;
43
+
44
wil::unique_handle GetStdHandle(int Index);
45
HANDLE GetExitEvent();
46
int GetPid() const;
src/windows/wslcsession/WSLCSession.cpp
+165
-1
@@ -22,6 +22,7 @@ Abstract:
22
#include "WindowsCertStore.h"
23
#include "WslCoreFilesystem.h"
24
#include "wslpolicies.h"
25
+#include "APICompat.h"
26
27
using namespace wsl::windows::common;
28
using io::MultiHandleWait;
@@ -2991,7 +2992,170 @@ CATCH_RETURN();
2992
2993
HRESULT WSLCSession::InterfaceSupportsErrorInfo(REFIID riid)
2994
{
2994
- return riid == __uuidof(IWSLCSession) ? S_OK : S_FALSE;
2995
+ return riid == __uuidof(IWSLCSession) || riid == __uuidof(IWSLCCompatSession) ? S_OK : S_FALSE;
2996
+}
2997
+
2998
+HRESULT WSLCSession::PullImage(LPCSTR Image, LPCSTR RegistryAuthenticationInformation, IWSLCCompatProgressCallback* ProgressCallback, IWSLCCompatWarningCallback* WarningCallback)
2999
+{
3000
+ const auto progress = apicompat::Convert(ProgressCallback);
3001
+ const auto warning = apicompat::Convert(WarningCallback);
3002
+
3003
+ return PullImage(Image, RegistryAuthenticationInformation, progress.Get(), warning.Get());
3004
+}
3005
+
3006
+HRESULT WSLCSession::LoadImage(WSLCCompatHandle ImageHandle, IWSLCCompatProgressCallback* ProgressCallback, ULONGLONG ContentLength, IWSLCCompatWarningCallback* WarningCallback)
3007
+{
3008
+ const auto handle = apicompat::Convert(ImageHandle);
3009
+ const auto progress = apicompat::Convert(ProgressCallback);
3010
+ const auto warning = apicompat::Convert(WarningCallback);
3011
+
3012
+ return LoadImage(handle, progress.Get(), ContentLength, warning.Get());
3013
+}
3014
+
3015
+HRESULT WSLCSession::ImportImage(
3016
+ WSLCCompatHandle ImageHandle, LPCSTR ImageName, IWSLCCompatProgressCallback* ProgressCallback, ULONGLONG ContentLength, IWSLCCompatWarningCallback* WarningCallback)
3017
+{
3018
+ const auto handle = apicompat::Convert(ImageHandle);
3019
+ const auto progress = apicompat::Convert(ProgressCallback);
3020
+ const auto warning = apicompat::Convert(WarningCallback);
3021
+
3022
+ return ImportImage(handle, ImageName, progress.Get(), ContentLength, warning.Get());
3023
+}
3024
+
3025
+HRESULT WSLCSession::ListImages(const WSLCCompatListImagesOptions* Options, WSLCCompatImageInformation** Images, ULONG* Count)
3026
+try
3027
+{
3028
+ RETURN_HR_IF_NULL(E_POINTER, Images);
3029
+ RETURN_HR_IF_NULL(E_POINTER, Count);
3030
+
3031
+ *Images = nullptr;
3032
+ *Count = 0;
3033
+
3034
+ wil::unique_cotaskmem_array_ptr<WSLCImageInformation> imagesImpl;
3035
+
3036
+ if (Options == nullptr)
3037
+ {
3038
+ RETURN_IF_FAILED(ListImages(static_cast<const WSLCListImagesOptions*>(nullptr), &imagesImpl, imagesImpl.size_address<ULONG>()));
3039
+ }
3040
+ else
3041
+ {
3042
+ const auto options = apicompat::Convert(*Options);
3043
+ RETURN_IF_FAILED(ListImages(options.Get(), &imagesImpl, imagesImpl.size_address<ULONG>()));
3044
+ }
3045
+
3046
+ if (imagesImpl.size() > 0)
3047
+ {
3048
+ auto converted = wil::make_unique_cotaskmem_nothrow<WSLCCompatImageInformation[]>(imagesImpl.size());
3049
+ RETURN_IF_NULL_ALLOC(converted);
3050
+
3051
+ for (size_t index = 0; index < imagesImpl.size(); index++)
3052
+ {
3053
+ converted[index] = apicompat::Convert(imagesImpl[index]);
3054
+ }
3055
+
3056
+ *Images = converted.release();
3057
+ }
3058
+
3059
+ *Count = static_cast<ULONG>(imagesImpl.size());
3060
+ return S_OK;
3061
+}
3062
+CATCH_RETURN();
3063
+
3064
+HRESULT WSLCSession::DeleteImage(const WSLCCompatDeleteImageOptions* Options, WSLCCompatDeletedImageInformation** DeletedImages, ULONG* Count)
3065
+try
3066
+{
3067
+ RETURN_HR_IF_NULL(E_POINTER, Options);
3068
+ RETURN_HR_IF_NULL(E_POINTER, DeletedImages);
3069
+ RETURN_HR_IF_NULL(E_POINTER, Count);
3070
+
3071
+ *DeletedImages = nullptr;
3072
+ *Count = 0;
3073
+
3074
+ const auto options = apicompat::Convert(*Options);
3075
+
3076
+ wil::unique_cotaskmem_array_ptr<WSLCDeletedImageInformation> imagesImpl;
3077
+
3078
+ RETURN_IF_FAILED(DeleteImage(&options, &imagesImpl, imagesImpl.size_address<ULONG>()));
3079
+
3080
+ if (imagesImpl.size() > 0)
3081
+ {
3082
+ auto converted = wil::make_unique_cotaskmem_nothrow<WSLCCompatDeletedImageInformation[]>(imagesImpl.size());
3083
+ RETURN_IF_NULL_ALLOC(converted);
3084
+
3085
+ for (size_t index = 0; index < imagesImpl.size(); index++)
3086
+ {
3087
+ converted[index] = apicompat::Convert(imagesImpl[index]);
3088
+ }
3089
+
3090
+ *DeletedImages = converted.release();
3091
+ }
3092
+
3093
+ *Count = static_cast<ULONG>(imagesImpl.size());
3094
+ return S_OK;
3095
+}
3096
+CATCH_RETURN();
3097
+
3098
+HRESULT WSLCSession::TagImage(const WSLCCompatTagImageOptions* Options)
3099
+try
3100
+{
3101
+ RETURN_HR_IF_NULL(E_POINTER, Options);
3102
+
3103
+ const auto options = apicompat::Convert(*Options);
3104
+ return TagImage(&options);
3105
+}
3106
+CATCH_RETURN();
3107
+
3108
+HRESULT WSLCSession::PushImage(LPCSTR Image, LPCSTR RegistryAuthenticationInformation, IWSLCCompatProgressCallback* ProgressCallback, IWSLCCompatWarningCallback* WarningCallback)
3109
+{
3110
+ const auto progress = apicompat::Convert(ProgressCallback);
3111
+ const auto warning = apicompat::Convert(WarningCallback);
3112
+
3113
+ return PushImage(Image, RegistryAuthenticationInformation, progress.Get(), warning.Get());
3114
+}
3115
+
3116
+HRESULT WSLCSession::CreateContainer(const WSLCCompatContainerOptions* Options, IWSLCCompatWarningCallback* WarningCallback, IWSLCCompatContainer** Container)
3117
+try
3118
+{
3119
+ RETURN_HR_IF_NULL(E_POINTER, Options);
3120
+ RETURN_HR_IF_NULL(E_POINTER, Container);
3121
+ *Container = nullptr;
3122
+
3123
+ const auto warning = apicompat::Convert(WarningCallback);
3124
+ const auto options = apicompat::Convert(*Options);
3125
+
3126
+ Microsoft::WRL::ComPtr<IWSLCContainer> container;
3127
+ RETURN_IF_FAILED(CreateContainer(options.Get(), warning.Get(), &container));
3128
+ RETURN_HR_IF_NULL(E_UNEXPECTED, container);
3129
+
3130
+ return container.CopyTo(Container);
3131
+}
3132
+CATCH_RETURN();
3133
+
3134
+HRESULT WSLCSession::CreateVolume(const WSLCCompatVolumeOptions* Options, WSLCCompatVolumeInformation* VolumeInfo)
3135
+try
3136
+{
3137
+ RETURN_HR_IF_NULL(E_POINTER, Options);
3138
+
3139
+ const auto options = apicompat::Convert(*Options);
3140
+
3141
+ WSLCVolumeInformation info{};
3142
+ WSLCVolumeInformation* internalInfo = (VolumeInfo != nullptr) ? &info : nullptr;
3143
+ RETURN_IF_FAILED(CreateVolume(options.Get(), internalInfo));
3144
+
3145
+ if (VolumeInfo != nullptr)
3146
+ {
3147
+ *VolumeInfo = apicompat::Convert(info);
3148
+ }
3149
+
3150
+ return S_OK;
3151
+}
3152
+CATCH_RETURN();
3153
+
3154
+HRESULT WSLCSession::RegisterCrashDumpCallback(IWSLCCompatCrashDumpCallback* Callback, IUnknown** Subscription)
3155
+{
3156
+ const auto callback = apicompat::Convert(Callback);
3157
+
3158
+ return RegisterCrashDumpCallback(callback.Get(), Subscription);
3159
}
3160
3161
MultiHandleWait WSLCSession::CreateIOContext(HANDLE CancelHandle)
src/windows/wslcsession/WSLCSession.h
+36
-1
@@ -15,6 +15,7 @@ Abstract:
15
#pragma once
16
17
#include "wslc.h"
18
+#include "WSLCCompat.h"
19
#include "WSLCVirtualMachine.h"
20
#include "WSLCContainer.h"
21
#include "WSLCVolumes.h"
@@ -73,7 +74,7 @@ private:
74
// The SYSTEM service creates the VM and passes IWSLCVirtualMachine to Initialize().
75
//
76
class DECLSPEC_UUID("4877FEFC-4977-4929-A958-9F36AA1892A4") WSLCSession
76
- : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>, IWSLCSession, IFastRundown, ISupportErrorInfo>
77
+ : public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>, IWSLCSession, IWSLCCompatSession, IFastRundown, ISupportErrorInfo>
78
{
79
public:
80
WSLCSession() = default;
@@ -198,6 +199,40 @@ public:
199
IFACEMETHOD(MapVmPort)(_In_ int Family, _In_ unsigned short WindowsPort, _In_ unsigned short LinuxPort) override;
200
IFACEMETHOD(UnmapVmPort)(_In_ int Family, _In_ unsigned short WindowsPort, _In_ unsigned short LinuxPort) override;
201
202
+ // IWSLCCompatSession - converts the WSLCCompat types to the wslc.idl types and forwards to the methods above.
203
+ // Methods that have an identical signature in both interfaces (Terminate, DeleteVolume, Authenticate,
204
+ // GetTerminationReason) are served by the single existing override and require no additional code here.
205
+ IFACEMETHOD(PullImage)(
206
+ _In_ LPCSTR Image,
207
+ _In_opt_ LPCSTR RegistryAuthenticationInformation,
208
+ _In_opt_ IWSLCCompatProgressCallback* ProgressCallback,
209
+ _In_opt_ IWSLCCompatWarningCallback* WarningCallback) override;
210
+ IFACEMETHOD(LoadImage)(
211
+ _In_ WSLCCompatHandle ImageHandle,
212
+ _In_opt_ IWSLCCompatProgressCallback* ProgressCallback,
213
+ _In_ ULONGLONG ContentLength,
214
+ _In_opt_ IWSLCCompatWarningCallback* WarningCallback) override;
215
+ IFACEMETHOD(ImportImage)(
216
+ _In_ WSLCCompatHandle ImageHandle,
217
+ _In_ LPCSTR ImageName,
218
+ _In_opt_ IWSLCCompatProgressCallback* ProgressCallback,
219
+ _In_ ULONGLONG ContentLength,
220
+ _In_opt_ IWSLCCompatWarningCallback* WarningCallback) override;
221
+ IFACEMETHOD(ListImages)(_In_opt_ const WSLCCompatListImagesOptions* Options, _Out_ WSLCCompatImageInformation** Images, _Out_ ULONG* Count) override;
222
+ IFACEMETHOD(DeleteImage)(_In_ const WSLCCompatDeleteImageOptions* Options, _Out_ WSLCCompatDeletedImageInformation** DeletedImages, _Out_ ULONG* Count) override;
223
+ IFACEMETHOD(TagImage)(_In_ const WSLCCompatTagImageOptions* Options) override;
224
+ IFACEMETHOD(PushImage)(
225
+ _In_ LPCSTR Image,
226
+ _In_ LPCSTR RegistryAuthenticationInformation,
227
+ _In_opt_ IWSLCCompatProgressCallback* ProgressCallback,
228
+ _In_opt_ IWSLCCompatWarningCallback* WarningCallback) override;
229
+ IFACEMETHOD(CreateContainer)(
230
+ _In_ const WSLCCompatContainerOptions* Options,
231
+ _In_opt_ IWSLCCompatWarningCallback* WarningCallback,
232
+ _Out_ IWSLCCompatContainer** Container) override;
233
+ IFACEMETHOD(CreateVolume)(_In_ const WSLCCompatVolumeOptions* Options, _Out_ WSLCCompatVolumeInformation* VolumeInfo) override;
234
+ IFACEMETHOD(RegisterCrashDumpCallback)(_In_ IWSLCCompatCrashDumpCallback* Callback, _Out_ IUnknown** Subscription) override;
235
+
236
common::io::MultiHandleWait CreateIOContext(HANDLE CancelHandle = nullptr);
237
238
UserHandle OpenUserHandle(WSLCHandle Handle);
test/windows/WSLCTests.cpp
+5
-4
@@ -15,6 +15,7 @@ Abstract:
15
#include "precomp.h"
16
#include "Common.h"
17
#include "wslc.h"
18
+#include "wslccompat.h"
19
#include "WSLCProcessLauncher.h"
20
#include "WSLCContainerLauncher.h"
21
#include "WslCoreFilesystem.h"
@@ -235,23 +236,23 @@ class WSLCTests
236
237
WSLC_TEST_METHOD(IsClientVersionSupported)
238
{
238
- wil::com_ptr<IWSLCSessionManager> sessionManager;
239
+ wil::com_ptr<IWSLCCompatSessionManager> sessionManager;
240
VERIFY_SUCCEEDED(CoCreateInstance(__uuidof(WSLCSessionManager), nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&sessionManager)));
241
242
BOOL isSupported = FALSE;
243
244
// The current version should always be supported.
244
- const WSLCVersion currentVersion{WSL_PACKAGE_VERSION_MAJOR, WSL_PACKAGE_VERSION_MINOR, WSL_PACKAGE_VERSION_REVISION};
245
+ const WSLCCompatVersion currentVersion{WSL_PACKAGE_VERSION_MAJOR, WSL_PACKAGE_VERSION_MINOR, WSL_PACKAGE_VERSION_REVISION};
246
VERIFY_SUCCEEDED(sessionManager->IsClientVersionSupported(¤tVersion, &isSupported));
247
VERIFY_IS_TRUE(isSupported);
248
249
// A very old version should not be supported.
249
- const WSLCVersion oldVersion{1, 0, 0};
250
+ const WSLCCompatVersion oldVersion{1, 0, 0};
251
VERIFY_SUCCEEDED(sessionManager->IsClientVersionSupported(&oldVersion, &isSupported));
252
VERIFY_IS_FALSE(isSupported);
253
254
// A very high version should be supported.
254
- const WSLCVersion futureVersion{99, 0, 0};
255
+ const WSLCCompatVersion futureVersion{99, 0, 0};
256
VERIFY_SUCCEEDED(sessionManager->IsClientVersionSupported(&futureVersion, &isSupported));
257
VERIFY_IS_TRUE(isSupported);
258
}
test/windows/WslcSdkTests.cpp
+4
-4
@@ -356,10 +356,10 @@ class WslcSdkTests
356
UniqueCrashDumpSubscription subscription;
357
VERIFY_SUCCEEDED(WslcRegisterSessionCrashDumpCallback(session.get(), callback, &promise, &subscription, nullptr));
358
359
- auto& comSession = *reinterpret_cast<WslcSessionImpl*>(session.get())->session;
359
+ auto comSession = reinterpret_cast<WslcSessionImpl*>(session.get())->session.query<IWSLCSession>();
360
361
wsl::windows::common::WSLCProcessLauncher launcher{"/bin/sh", {"/bin/sh", "-c", "kill -SEGV $$"}};
362
- auto process = launcher.Launch(comSession);
362
+ auto process = launcher.Launch(*comSession);
363
auto result = process.WaitAndCaptureOutput();
364
VERIFY_ARE_EQUAL(result.Code, 128 + WSLCSignalSIGSEGV);
365
@@ -2220,8 +2220,8 @@ class WslcSdkTests
2220
const std::string& username = {}, const std::string& password = {}, uint16_t port = 5000)
2221
{
2222
// Get the IWSLCSession COM object from the SDK session handle and delegate to the shared helper.
2223
- auto& session = *reinterpret_cast<WslcSessionImpl*>(m_defaultSession)->session;
2224
- return WSLCE2ETests::StartLocalRegistry(session, username, password, port);
2223
+ auto session = reinterpret_cast<WslcSessionImpl*>(m_defaultSession)->session.query<IWSLCSession>();
2224
+ return WSLCE2ETests::StartLocalRegistry(*session, username, password, port);
2225
}
2226
2227
// Tags and pushes an image to a local registry via the SDK APIs.
test/windows/WslcSdkWinRTTests.cpp
+3
-2
@@ -173,8 +173,9 @@ class WslcSdkWinRtTests
173
const std::string& username = {}, const std::string& password = {}, uint16_t port = 5000)
174
{
175
// Get the IWSLCSession COM object from the SDK session handle and delegate to the shared helper.
176
- auto& comSession = *reinterpret_cast<WslcSessionImpl*>(WSLCSDK::implementation::GetHandle(m_defaultSession))->session;
177
- return WSLCE2ETests::StartLocalRegistry(comSession, username, password, port);
176
+ auto comSession =
177
+ reinterpret_cast<WslcSessionImpl*>(WSLCSDK::implementation::GetHandle(m_defaultSession))->session.query<IWSLCSession>();
178
+ return WSLCE2ETests::StartLocalRegistry(*comSession, username, password, port);
179
}
180
181
// Tags and pushes an image to a local registry via the SDK APIs.