Skip to content
Open
34 changes: 34 additions & 0 deletions localization/strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -3110,4 +3110,38 @@ On first run, creates the file with all settings commented out at their defaults
<value>Warning: Settings file at {} is empty or has invalid structure. Expected a YAML mapping.</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="MessageWslcFailedToRecoverContainer" xml:space="preserve">
<value>Failed to recover container '{}'</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="MessageWslcFailedToRecoverNetwork" xml:space="preserve">
<value>Failed to recover network '{}'</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="MessageWslcFailedToRecoverVolume" xml:space="preserve">
<value>Failed to recover volume '{}'</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="MessageWslcSwapInitFailed" xml:space="preserve">
<value>Failed to initialize swap</value>
</data>
<data name="MessageWslcContainerTimestampRecoveryFailed" xml:space="preserve">
<value>Failed to restore timestamp for container '{}'</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="MessageWslcImportProgressParseFailed" xml:space="preserve">
<value>Failed to parse image import progress</value>
</data>
<data name="MessageWslcVolumeUnmountFailed" xml:space="preserve">
<value>Failed to unmount volume '{}': {}</value>
<comment>{FixedPlaceholder="{}"}{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
Comment thread
yao-msft marked this conversation as resolved.
</data>
<data name="MessageWslcContainerStopAfterPluginRejectionFailed" xml:space="preserve">
<value>Failed to stop container '{}' after plugin rejection</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="MessageWslcVolumeReleaseFailed" xml:space="preserve">
<value>Failed to release host resources for volume '{}'</value>
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
</root>
8 changes: 8 additions & 0 deletions msipackage/package.wix.in
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,14 @@
</RegistryKey>
</RegistryKey>

<!-- IWarningCallback-->
<RegistryKey Root="HKCR" Key="Interface\{8153ED5D-8ABB-408B-ADBE-C0F3B13E07C3}">
<RegistryValue Value="IWarningCallback" Type="string" />
<RegistryKey Key="ProxyStubClsid32">
<RegistryValue Value="{4EA0C6DD-E9FF-48E7-994E-13A31D10DC60}" Type="string" />
</RegistryKey>
</RegistryKey>

<!-- IWSLCSession-->
<RegistryKey Root="HKCR" Key="Interface\{EF0661E4-6364-40EA-B433-E2FDF11F3519}">
<RegistryValue Value="IWSLCSession" Type="string" />
Expand Down
16 changes: 9 additions & 7 deletions src/windows/WslcSDK/wslcsdk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,8 @@ try
WI_SetFlag(runtimeSettings.FeatureFlags, WslcFeatureFlagsVirtioFs);
WI_SetFlag(runtimeSettings.FeatureFlags, WslcFeatureFlagsDnsTunneling);

if (SUCCEEDED(errorInfoWrapper.CaptureResult(sessionManager->CreateSession(&runtimeSettings, WSLCSessionFlagsNone, &result->session))))
if (SUCCEEDED(errorInfoWrapper.CaptureResult(
sessionManager->CreateSession(&runtimeSettings, WSLCSessionFlagsNone, nullptr, &result->session))))
{
wsl::windows::common::security::ConfigureForCOMImpersonation(result->session.get());
*session = reinterpret_cast<WslcSession>(result.release());
Expand Down Expand Up @@ -780,7 +781,7 @@ try
// containerOptions.StopSignal;
// containerOptions.ShmSize;

if (SUCCEEDED(errorInfoWrapper.CaptureResult(internalSession->session->CreateContainer(&containerOptions, &result->container))))
if (SUCCEEDED(errorInfoWrapper.CaptureResult(internalSession->session->CreateContainer(&containerOptions, nullptr, &result->container))))
{
wsl::windows::common::security::ConfigureForCOMImpersonation(result->container.get());

Expand Down Expand Up @@ -808,7 +809,7 @@ try
// TODO: Consider if we should just override flags when callbacks were provided instead.
RETURN_HR_IF(E_INVALIDARG, WI_IsFlagClear(flags, WSLC_CONTAINER_START_FLAG_ATTACH) && hasIOCallback);

if (SUCCEEDED(errorInfoWrapper.CaptureResult(internalType->container->Start(ConvertFlags(flags), nullptr))))
if (SUCCEEDED(errorInfoWrapper.CaptureResult(internalType->container->Start(ConvertFlags(flags), nullptr, nullptr))))
{
if (hasIOCallback)
{
Expand Down Expand Up @@ -1280,7 +1281,7 @@ try

auto progressCallback = ProgressCallback::CreateIf(options);

return errorInfoWrapper.CaptureResult(internalType->session->PullImage(options->uri, options->registryAuth, progressCallback.get()));
return errorInfoWrapper.CaptureResult(internalType->session->PullImage(options->uri, options->registryAuth, progressCallback.get(), nullptr));
}
CATCH_RETURN();

Expand All @@ -1290,7 +1291,7 @@ static HRESULT WslcImportSessionImageImpl(
auto progressCallback = ProgressCallback::CreateIf(options);

return errorInfoWrapper.CaptureResult(internalSession->session->ImportImage(
ToCOMInputHandle(imageFile.Handle()), imageName, progressCallback.get(), imageFile.Length()));
ToCOMInputHandle(imageFile.Handle()), imageName, progressCallback.get(), imageFile.Length(), nullptr));
}

STDAPI WslcImportSessionImage(
Expand Down Expand Up @@ -1328,7 +1329,7 @@ static HRESULT WslcLoadSessionImageImpl(
auto progressCallback = ProgressCallback::CreateIf(options);

return errorInfoWrapper.CaptureResult(
internalSession->session->LoadImage(ToCOMInputHandle(imageFile.Handle()), progressCallback.get(), imageFile.Length()));
internalSession->session->LoadImage(ToCOMInputHandle(imageFile.Handle()), progressCallback.get(), imageFile.Length(), nullptr));
}

STDAPI WslcLoadSessionImage(
Expand Down Expand Up @@ -1407,7 +1408,8 @@ try

auto progressCallback = ProgressCallback::CreateIf(options);

return errorInfoWrapper.CaptureResult(internalType->session->PushImage(options->image, options->registryAuth, progressCallback.get()));
return errorInfoWrapper.CaptureResult(
internalType->session->PushImage(options->image, options->registryAuth, progressCallback.get(), nullptr));
}
CATCH_RETURN();

Expand Down
19 changes: 10 additions & 9 deletions src/windows/common/WSLCContainerLauncher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,20 +255,21 @@ void wsl::windows::common::WSLCContainerLauncher::AddAdditionalNetwork(const std
m_additionalNetworks.push_back(Name);
}

std::pair<HRESULT, std::optional<RunningWSLCContainer>> WSLCContainerLauncher::LaunchNoThrow(IWSLCSession& Session, WSLCContainerStartFlags Flags)
std::pair<HRESULT, std::optional<RunningWSLCContainer>> WSLCContainerLauncher::LaunchNoThrow(
IWSLCSession& Session, WSLCContainerStartFlags Flags, IWarningCallback* WarningCallback)
{
auto [result, container] = CreateNoThrow(Session);
auto [result, container] = CreateNoThrow(Session, WarningCallback);
if (FAILED(result))
{
return std::make_pair(result, std::optional<RunningWSLCContainer>{});
}

result = container.value().Get().Start(Flags, nullptr);
result = container.value().Get().Start(Flags, nullptr, WarningCallback);

return std::make_pair(result, std::move(container));
}

std::pair<HRESULT, std::optional<RunningWSLCContainer>> WSLCContainerLauncher::CreateNoThrow(IWSLCSession& Session)
std::pair<HRESULT, std::optional<RunningWSLCContainer>> WSLCContainerLauncher::CreateNoThrow(IWSLCSession& Session, IWarningCallback* WarningCallback)
{
WSLCContainerOptions options{};
options.Image = m_image.c_str();
Expand Down Expand Up @@ -382,7 +383,7 @@ std::pair<HRESULT, std::optional<RunningWSLCContainer>> WSLCContainerLauncher::C

// TODO: Support volumes, ports, flags, container networking mode, etc.
wil::com_ptr<IWSLCContainer> container;
auto result = Session.CreateContainer(&options, &container);
auto result = Session.CreateContainer(&options, WarningCallback, &container);
if (FAILED(result))
{
return std::pair<HRESULT, std::optional<RunningWSLCContainer>>(result, std::optional<RunningWSLCContainer>{});
Expand All @@ -391,17 +392,17 @@ std::pair<HRESULT, std::optional<RunningWSLCContainer>> WSLCContainerLauncher::C
return std::make_pair(S_OK, std::move(RunningWSLCContainer{std::move(container), m_flags}));
}

RunningWSLCContainer WSLCContainerLauncher::Create(IWSLCSession& Session)
RunningWSLCContainer WSLCContainerLauncher::Create(IWSLCSession& Session, IWarningCallback* WarningCallback)
{
auto [result, container] = CreateNoThrow(Session);
auto [result, container] = CreateNoThrow(Session, WarningCallback);
THROW_IF_FAILED(result);

return std::move(container.value());
}

RunningWSLCContainer WSLCContainerLauncher::Launch(IWSLCSession& Session, WSLCContainerStartFlags Flags)
RunningWSLCContainer WSLCContainerLauncher::Launch(IWSLCSession& Session, WSLCContainerStartFlags Flags, IWarningCallback* WarningCallback)
{
auto [result, container] = LaunchNoThrow(Session, Flags);
auto [result, container] = LaunchNoThrow(Session, Flags, WarningCallback);
THROW_IF_FAILED(result);

return std::move(container.value());
Expand Down
9 changes: 5 additions & 4 deletions src/windows/common/WSLCContainerLauncher.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,12 @@ class WSLCContainerLauncher : private WSLCProcessLauncher
void AddTmpfs(const std::string& ContainerPath, const std::string& Options);
void AddAdditionalNetwork(const std::string& Name);

std::pair<HRESULT, std::optional<RunningWSLCContainer>> CreateNoThrow(IWSLCSession& Session);
RunningWSLCContainer Create(IWSLCSession& Session);
std::pair<HRESULT, std::optional<RunningWSLCContainer>> CreateNoThrow(IWSLCSession& Session, IWarningCallback* WarningCallback = nullptr);
RunningWSLCContainer Create(IWSLCSession& Session, IWarningCallback* WarningCallback = nullptr);

RunningWSLCContainer Launch(IWSLCSession& Session, WSLCContainerStartFlags Flags = WSLCContainerStartFlagsAttach);
std::pair<HRESULT, std::optional<RunningWSLCContainer>> LaunchNoThrow(IWSLCSession& Session, WSLCContainerStartFlags Flags = WSLCContainerStartFlagsAttach);
RunningWSLCContainer Launch(IWSLCSession& Session, WSLCContainerStartFlags Flags = WSLCContainerStartFlagsAttach, IWarningCallback* WarningCallback = nullptr);
std::pair<HRESULT, std::optional<RunningWSLCContainer>> LaunchNoThrow(
IWSLCSession& Session, WSLCContainerStartFlags Flags = WSLCContainerStartFlagsAttach, IWarningCallback* WarningCallback = nullptr);

void SetName(std::string&& Name);
void SetEntrypoint(std::vector<std::string>&& entrypoint);
Expand Down
3 changes: 2 additions & 1 deletion src/windows/inc/docker_schema.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ struct ErrorResponse
struct ImageLoadResult
{
std::optional<std::string> stream;
std::optional<std::string> status;
std::optional<ErrorResponse> errorDetail;

NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ImageLoadResult, stream, errorDetail);
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(ImageLoadResult, stream, status, errorDetail);
};

struct EmptyRequest
Expand Down
21 changes: 12 additions & 9 deletions src/windows/service/exe/WSLCSessionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ try
}
CATCH_LOG()

void WSLCSessionManagerImpl::CreateSession(const WSLCSessionSettings* Settings, WSLCSessionFlags Flags, IWSLCSession** WslcSession)
void WSLCSessionManagerImpl::CreateSession(
_In_ const WSLCSessionSettings* Settings, _In_ WSLCSessionFlags Flags, _In_opt_ IWarningCallback* WarningCallback, _Out_ IWSLCSession** WslcSession)
{
auto tokenInfo = GetCallingProcessTokenInfo();
const auto callerToken = wsl::windows::common::security::GetUserToken(TokenImpersonation);
Expand Down Expand Up @@ -269,10 +270,10 @@ void WSLCSessionManagerImpl::CreateSession(const WSLCSessionSettings* Settings,
auto factory = wslutil::CreateComServerAsUser<IWSLCSessionFactory>(__uuidof(WSLCSessionFactory), userToken.get());
AddSessionProcessToJobObject(factory.get());

auto sessionSettings = CreateSessionSettings(sessionId, creatorPid, Settings, resolvedDisplayName.c_str());
const auto sessionSettings = CreateSessionSettings(sessionId, creatorPid, Settings, resolvedDisplayName.c_str());
wil::com_ptr<IWSLCSession> session;
wil::com_ptr<IWSLCSessionReference> serviceRef;
THROW_IF_FAILED(factory->CreateSession(&sessionSettings, vm.Get(), notifier.Get(), &session, &serviceRef));
THROW_IF_FAILED(factory->CreateSession(&sessionSettings, vm.Get(), notifier.Get(), WarningCallback, &session, &serviceRef));

// Track the session via its service ref, along with metadata and security info.
m_sessions.push_back(SessionEntry{
Expand Down Expand Up @@ -402,14 +403,15 @@ void WSLCSessionManagerImpl::ListSessions(_Out_ WSLCSessionListEntry** Sessions,
*SessionsCount = static_cast<ULONG>(sessionInfo.size());
}

void WSLCSessionManagerImpl::EnterSession(_In_ LPCWSTR DisplayName, _In_ LPCWSTR StoragePath, IWSLCSession** WslcSession)
void WSLCSessionManagerImpl::EnterSession(
_In_ LPCWSTR DisplayName, _In_ LPCWSTR StoragePath, _In_opt_ IWarningCallback* WarningCallback, _Out_ IWSLCSession** WslcSession)
{
THROW_HR_IF(E_POINTER, DisplayName == nullptr || StoragePath == nullptr);
THROW_HR_IF(E_INVALIDARG, DisplayName[0] == L'\0' || StoragePath[0] == L'\0');

const auto callerToken = wsl::windows::common::security::GetUserToken(TokenImpersonation);
auto sessionSettings = SessionSettings::Custom(callerToken.get(), DisplayName, StoragePath, WSLCSessionStorageFlagsNoCreate);
CreateSession(&sessionSettings.Settings, WSLCSessionFlagsNone, WslcSession);
CreateSession(&sessionSettings.Settings, WSLCSessionFlagsNone, WarningCallback, WslcSession);
}

WSLCSessionInitSettings WSLCSessionManagerImpl::CreateSessionSettings(
Expand Down Expand Up @@ -551,20 +553,21 @@ try
}
CATCH_RETURN();

HRESULT WSLCSessionManager::CreateSession(const WSLCSessionSettings* WslcSessionSettings, WSLCSessionFlags Flags, IWSLCSession** WslcSession)
HRESULT WSLCSessionManager::CreateSession(
const WSLCSessionSettings* WslcSessionSettings, WSLCSessionFlags Flags, IWarningCallback* WarningCallback, IWSLCSession** WslcSession)
try
{
COMServiceExecutionContext context;

return CallImpl(&WSLCSessionManagerImpl::CreateSession, WslcSessionSettings, Flags, WslcSession);
return CallImpl(&WSLCSessionManagerImpl::CreateSession, WslcSessionSettings, Flags, WarningCallback, WslcSession);
}
CATCH_RETURN();

HRESULT WSLCSessionManager::EnterSession(_In_ LPCWSTR DisplayName, _In_ LPCWSTR StoragePath, IWSLCSession** WslcSession)
HRESULT WSLCSessionManager::EnterSession(_In_ LPCWSTR DisplayName, _In_ LPCWSTR StoragePath, IWarningCallback* WarningCallback, IWSLCSession** WslcSession)
{
COMServiceExecutionContext context;

return CallImpl(&WSLCSessionManagerImpl::EnterSession, DisplayName, StoragePath, WslcSession);
return CallImpl(&WSLCSessionManagerImpl::EnterSession, DisplayName, StoragePath, WarningCallback, WslcSession);
}

HRESULT WSLCSessionManager::ListSessions(_Out_ WSLCSessionListEntry** Sessions, _Out_ ULONG* SessionsCount)
Expand Down
13 changes: 9 additions & 4 deletions src/windows/service/exe/WSLCSessionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,12 @@ class WSLCSessionManagerImpl
WSLCSessionManagerImpl();
~WSLCSessionManagerImpl();

void CreateSession(const WSLCSessionSettings* WslcSessionSettings, WSLCSessionFlags Flags, IWSLCSession** WslcSession);
void EnterSession(_In_ LPCWSTR DisplayName, _In_ LPCWSTR StoragePath, IWSLCSession** WslcSession);
void CreateSession(
_In_ const WSLCSessionSettings* WslcSessionSettings,
_In_ WSLCSessionFlags Flags,
_In_opt_ IWarningCallback* WarningCallback,
_Out_ IWSLCSession** WslcSession);
void EnterSession(_In_ LPCWSTR DisplayName, _In_ LPCWSTR StoragePath, _In_opt_ IWarningCallback* WarningCallback, _Out_ IWSLCSession** WslcSession);
void ListSessions(_Out_ WSLCSessionListEntry** Sessions, _Out_ ULONG* SessionsCount);
void OpenSession(_In_ ULONG Id, _Out_ IWSLCSession** Session);
void OpenSessionByName(_In_ LPCWSTR DisplayName, _Out_ IWSLCSession** Session);
Expand Down Expand Up @@ -198,8 +202,9 @@ class DECLSPEC_UUID("a9b7a1b9-0671-405c-95f1-e0612cb4ce8f") WSLCSessionManager

IFACEMETHOD(GetVersion)(_Out_ WSLCVersion* Version) override;
IFACEMETHOD(IsClientVersionSupported)(_In_ const WSLCVersion* ClientVersion, _Out_ BOOL* IsSupported) override;
IFACEMETHOD(CreateSession)(const WSLCSessionSettings* WslcSessionSettings, WSLCSessionFlags Flags, IWSLCSession** WslcSession) override;
IFACEMETHOD(EnterSession)(_In_ LPCWSTR DisplayName, _In_ LPCWSTR StoragePath, IWSLCSession** WslcSession) override;
IFACEMETHOD(CreateSession)(
const WSLCSessionSettings* WslcSessionSettings, WSLCSessionFlags Flags, IWarningCallback* WarningCallback, IWSLCSession** WslcSession) override;
IFACEMETHOD(EnterSession)(_In_ LPCWSTR DisplayName, _In_ LPCWSTR StoragePath, IWarningCallback* WarningCallback, IWSLCSession** WslcSession) override;
IFACEMETHOD(ListSessions)(_Out_ WSLCSessionListEntry** Sessions, _Out_ ULONG* SessionsCount) override;
IFACEMETHOD(OpenSession)(_In_ ULONG Id, _Out_ IWSLCSession** Session) override;
IFACEMETHOD(OpenSessionByName)(_In_ LPCWSTR DisplayName, _Out_ IWSLCSession** Session) override;
Expand Down
Loading