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(&currentVersion, &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.