Skip to content

Commit 7f1eca4

Browse files
authored
Merge branch 'feature/wsl-for-apps' into richfr/portmapping
2 parents 7ca8e51 + f0b9455 commit 7f1eca4

5 files changed

Lines changed: 273 additions & 58 deletions

File tree

src/windows/WslcSDK/WslcsdkPrivate.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ typedef struct WslcContainerProcessOptionsInternal
6464

6565
static_assert(
6666
sizeof(WslcContainerProcessOptionsInternal) == WSLC_CONTAINER_PROCESS_OPTIONS_SIZE,
67-
"WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL must be 72 bytes");
67+
"WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL size mismatch");
6868
static_assert(
6969
__alignof(WslcContainerProcessOptionsInternal) == WSLC_CONTAINER_PROCESS_OPTIONS_ALIGNMENT,
70-
"WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL must be 8-byte aligned");
70+
"WSLC_CONTAINER_PROCESS_OPTIONS_INTERNAL alignment mismatch");
7171

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

@@ -84,17 +84,19 @@ typedef struct WslcContainerOptionsInternal
8484
uint32_t portsCount;
8585
const WslcContainerVolume* volumes;
8686
uint32_t volumesCount;
87+
const WslcContainerNamedVolume* namedVolumes;
88+
uint32_t namedVolumesCount;
8789
const WslcContainerProcessOptionsInternal* initProcessOptions;
8890
WSLCContainerNetworkType networking;
8991
WslcContainerFlags containerFlags;
9092

9193
} WslcContainerOptionsInternal;
9294

9395
static_assert(
94-
sizeof(WslcContainerOptionsInternal) == WSLC_CONTAINER_OPTIONS_SIZE, "WSLC_CONTAINER_OPTIONS_INTERNAL must be 80 bytes");
96+
sizeof(WslcContainerOptionsInternal) == WSLC_CONTAINER_OPTIONS_SIZE, "WSLC_CONTAINER_OPTIONS_INTERNAL size mismatch");
9597
static_assert(
9698
__alignof(WslcContainerOptionsInternal) == WSLC_CONTAINER_OPTIONS_ALIGNMENT,
97-
"WSLC_CONTAINER_OPTIONS_INTERNAL must be 8-byte aligned");
99+
"WSLC_CONTAINER_OPTIONS_INTERNAL alignment mismatch");
98100

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

src/windows/WslcSDK/wslcsdk.cpp

Lines changed: 88 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,6 @@ try
418418
WSLCSessionSettings runtimeSettings{};
419419
runtimeSettings.DisplayName = internalType->displayName;
420420
runtimeSettings.StoragePath = internalType->storagePath;
421-
// TODO: Is this the intended use for vhdRequirements.sizeInBytes?
422421
runtimeSettings.MaximumStorageSizeMb = internalType->vhdRequirements.sizeInBytes / _1MB;
423422
runtimeSettings.CpuCount = internalType->cpuCount;
424423
runtimeSettings.MemoryMb = internalType->memoryMb;
@@ -433,16 +432,6 @@ try
433432
runtimeSettings.FeatureFlags = ConvertFlags(internalType->featureFlags);
434433
WI_SetFlag(runtimeSettings.FeatureFlags, WslcFeatureFlagsVirtioFs);
435434

436-
// TODO: Debug message output? No user control? Expects a handle value as a ULONG (to write debug info to?)
437-
// runtimeSettings.DmesgOutput;
438-
439-
// TODO: VHD overrides; I'm not sure if we intend these to be provided.
440-
// runtimeSettings.RootVhdOverride = internalType->vhdRequirements.path;
441-
// TODO: I don't think that this VHD type override can be reused from the VHD requirements type
442-
// Tracking the code suggests that this is the `filesystemtype` to the linux `mount` function.
443-
// Not clear how to map dynamic and fixed to values like `ext4` and `tmpfs`.
444-
// runtimeSettings.RootVhdTypeOverride = ConvertType(internalType->vhdRequirements.type);
445-
446435
if (SUCCEEDED(errorInfoWrapper.CaptureResult(sessionManager->CreateSession(&runtimeSettings, WSLCSessionFlagsNone, &result->session))))
447436
{
448437
wsl::windows::common::security::ConfigureForCOMImpersonation(result->session.get());
@@ -481,23 +470,54 @@ try
481470
}
482471
CATCH_RETURN();
483472

484-
STDAPI WslcCreateSessionVhd(_In_ WslcSession session, _In_ const WslcVhdRequirements* options, _Outptr_opt_result_z_ PWSTR* errorMessage)
473+
STDAPI WslcCreateSessionVhdVolume(_In_ WslcSession session, _In_ const WslcVhdRequirements* options, _Outptr_opt_result_z_ PWSTR* errorMessage)
485474
try
486475
{
487-
UNREFERENCED_PARAMETER(session);
488-
UNREFERENCED_PARAMETER(options);
489-
UNREFERENCED_PARAMETER(errorMessage);
490-
return E_NOTIMPL;
476+
ErrorInfoWrapper errorInfoWrapper{errorMessage};
477+
478+
auto internalType = CheckAndGetInternalType(session);
479+
RETURN_HR_IF_NULL(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), internalType->session);
480+
RETURN_HR_IF_NULL(E_POINTER, options);
481+
482+
RETURN_HR_IF_NULL(E_INVALIDARG, options->name);
483+
RETURN_HR_IF(E_INVALIDARG, options->sizeInBytes == 0);
484+
RETURN_HR_IF(E_NOTIMPL, options->type != WSLC_VHD_TYPE_DYNAMIC);
485+
486+
WSLCVolumeOptions volumeOptions{};
487+
volumeOptions.Name = options->name;
488+
// Only supported value currently
489+
volumeOptions.Type = "vhd";
490+
491+
auto dynamicOptions = std::format(R"({{ "SizeBytes": "{}" }})", options->sizeInBytes);
492+
volumeOptions.Options = dynamicOptions.c_str();
493+
494+
return errorInfoWrapper.CaptureResult(internalType->session->CreateVolume(&volumeOptions));
495+
}
496+
CATCH_RETURN();
497+
498+
STDAPI WslcDeleteSessionVhdVolume(_In_ WslcSession session, _In_z_ PCSTR name, _Outptr_opt_result_z_ PWSTR* errorMessage)
499+
try
500+
{
501+
ErrorInfoWrapper errorInfoWrapper{errorMessage};
502+
503+
auto internalType = CheckAndGetInternalType(session);
504+
RETURN_HR_IF_NULL(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), internalType->session);
505+
RETURN_HR_IF_NULL(E_POINTER, name);
506+
507+
return errorInfoWrapper.CaptureResult(internalType->session->DeleteVolume(name));
491508
}
492509
CATCH_RETURN();
493510

494-
STDAPI WslcSetSessionSettingsVHD(_In_ WslcSessionSettings* sessionSettings, _In_ const WslcVhdRequirements* vhdRequirements)
511+
STDAPI WslcSetSessionSettingsVhd(_In_ WslcSessionSettings* sessionSettings, _In_opt_ const WslcVhdRequirements* vhdRequirements)
495512
try
496513
{
497514
auto internalType = CheckAndGetInternalType(sessionSettings);
498515

499516
if (vhdRequirements)
500517
{
518+
RETURN_HR_IF(E_INVALIDARG, vhdRequirements->sizeInBytes == 0);
519+
RETURN_HR_IF(E_NOTIMPL, vhdRequirements->type != WSLC_VHD_TYPE_DYNAMIC);
520+
501521
internalType->vhdRequirements = *vhdRequirements;
502522
}
503523
else
@@ -622,6 +642,23 @@ try
622642
containerOptions.VolumesCount = static_cast<ULONG>(internalContainerSettings->volumesCount);
623643
}
624644

645+
std::unique_ptr<WSLCNamedVolume[]> convertedNamedVolumes;
646+
if (internalContainerSettings->namedVolumes && internalContainerSettings->namedVolumesCount)
647+
{
648+
convertedNamedVolumes = std::make_unique<WSLCNamedVolume[]>(internalContainerSettings->namedVolumesCount);
649+
for (uint32_t i = 0; i < internalContainerSettings->namedVolumesCount; ++i)
650+
{
651+
const WslcContainerNamedVolume& internalVolume = internalContainerSettings->namedVolumes[i];
652+
WSLCNamedVolume& convertedVolume = convertedNamedVolumes[i];
653+
654+
convertedVolume.Name = internalVolume.name;
655+
convertedVolume.ContainerPath = internalVolume.containerPath;
656+
convertedVolume.ReadOnly = internalVolume.readOnly;
657+
}
658+
containerOptions.NamedVolumes = convertedNamedVolumes.get();
659+
containerOptions.NamedVolumesCount = static_cast<ULONG>(internalContainerSettings->namedVolumesCount);
660+
}
661+
625662
std::unique_ptr<WSLCPortMapping[]> convertedPorts;
626663
std::vector<std::string> bindingAddressStrings;
627664
if (internalContainerSettings->ports && internalContainerSettings->portsCount)
@@ -847,6 +884,27 @@ try
847884
}
848885
CATCH_RETURN();
849886

887+
STDAPI WslcSetContainerSettingsNamedVolumes(
888+
_In_ WslcContainerSettings* containerSettings, _In_reads_opt_(namedVolumeCount) const WslcContainerNamedVolume* namedVolumes, _In_ uint32_t namedVolumeCount)
889+
try
890+
{
891+
auto internalType = CheckAndGetInternalType(containerSettings);
892+
RETURN_HR_IF(E_INVALIDARG, (namedVolumes == nullptr && namedVolumeCount != 0) || (namedVolumes != nullptr && namedVolumeCount == 0));
893+
894+
for (uint32_t i = 0; i < namedVolumeCount; ++i)
895+
{
896+
RETURN_HR_IF_NULL(E_INVALIDARG, namedVolumes[i].name);
897+
RETURN_HR_IF_NULL(E_INVALIDARG, namedVolumes[i].containerPath);
898+
EnsureAbsolutePath(namedVolumes[i].containerPath, true);
899+
}
900+
901+
internalType->namedVolumes = namedVolumes;
902+
internalType->namedVolumesCount = namedVolumeCount;
903+
904+
return S_OK;
905+
}
906+
CATCH_RETURN();
907+
850908
STDAPI WslcCreateContainerProcess(
851909
_In_ WslcContainer container, _In_ WslcProcessSettings* newProcessSettings, _Out_ WslcProcess* newProcess, _Outptr_opt_result_z_ PWSTR* errorMessage)
852910
try
@@ -894,12 +952,21 @@ try
894952
}
895953
CATCH_RETURN();
896954

897-
STDAPI WslcInspectContainer(_In_ WslcContainer container, _Outptr_result_z_ PCSTR* inspectData)
955+
STDAPI WslcInspectContainer(_In_ WslcContainer container, _Outptr_result_z_ PSTR* inspectData)
898956
try
899957
{
900-
UNREFERENCED_PARAMETER(container);
901-
UNREFERENCED_PARAMETER(inspectData);
902-
return E_NOTIMPL;
958+
auto internalType = CheckAndGetInternalType(container);
959+
RETURN_HR_IF_NULL(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), internalType->container);
960+
RETURN_HR_IF_NULL(E_POINTER, inspectData);
961+
962+
*inspectData = nullptr;
963+
964+
wil::unique_cotaskmem_ansistring result;
965+
RETURN_IF_FAILED(internalType->container->Inspect(&result));
966+
967+
*inspectData = result.release();
968+
969+
return S_OK;
903970
}
904971
CATCH_RETURN();
905972

src/windows/WslcSDK/wslcsdk.def

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ WslcSetSessionSettingsTerminationCallback
1818
WslcSetSessionSettingsCpuCount
1919
WslcSetSessionSettingsMemory
2020
WslcSetSessionSettingsTimeout
21-
WslcSetSessionSettingsVHD
21+
WslcSetSessionSettingsVhd
2222

2323
WslcTerminateSession
2424
WslcPullSessionImage
@@ -28,13 +28,15 @@ WslcLoadSessionImage
2828
WslcLoadSessionImageFromFile
2929
WslcDeleteSessionImage
3030
WslcListSessionImages
31-
WslcCreateSessionVhd
31+
WslcCreateSessionVhdVolume
32+
WslcDeleteSessionVhdVolume
3233

3334
WslcSetContainerSettingsDomainName
3435
WslcSetContainerSettingsName
3536
WslcSetContainerSettingsNetworkingMode
3637
WslcSetContainerSettingsHostName
3738
WslcSetContainerSettingsVolumes
39+
WslcSetContainerSettingsNamedVolumes
3840
WslcSetContainerSettingsInitProcess
3941
WslcSetContainerSettingsFlags
4042
WslcSetContainerSettingsPortMappings

src/windows/WslcSDK/wslcsdk.h

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Module Name:
2121
EXTERN_C_START
2222

2323
// Session values
24-
#define WSLC_SESSION_OPTIONS_SIZE 72
24+
#define WSLC_SESSION_OPTIONS_SIZE 80
2525
#define WSLC_SESSION_OPTIONS_ALIGNMENT 8
2626

2727
typedef struct WslcSessionSettings
@@ -32,7 +32,7 @@ typedef struct WslcSessionSettings
3232
DECLARE_HANDLE(WslcSession);
3333

3434
// Container values
35-
#define WSLC_CONTAINER_OPTIONS_SIZE 80
35+
#define WSLC_CONTAINER_OPTIONS_SIZE 96
3636
#define WSLC_CONTAINER_OPTIONS_ALIGNMENT 8
3737

3838
typedef struct WslcContainerSettings
@@ -66,6 +66,8 @@ typedef enum WslcVhdType
6666

6767
typedef struct WslcVhdRequirements
6868
{
69+
// Ignored by WslcSetSessionSettingsVHD
70+
_In_z_ PCSTR name;
6971
_In_ uint64_t sizeInBytes; // Desired size (for create/expand)
7072
_In_ WslcVhdType type;
7173
} WslcVhdRequirements;
@@ -96,7 +98,7 @@ STDAPI WslcSetSessionSettingsCpuCount(_In_ WslcSessionSettings* sessionSettings,
9698
STDAPI WslcSetSessionSettingsMemory(_In_ WslcSessionSettings* sessionSettings, _In_ uint32_t memoryMb);
9799
STDAPI WslcSetSessionSettingsTimeout(_In_ WslcSessionSettings* sessionSettings, _In_ uint32_t timeoutMS);
98100

99-
STDAPI WslcSetSessionSettingsVHD(_In_ WslcSessionSettings* sessionSettings, _In_ const WslcVhdRequirements* vhdRequirements);
101+
STDAPI WslcSetSessionSettingsVhd(_In_ WslcSessionSettings* sessionSettings, _In_opt_ const WslcVhdRequirements* vhdRequirements);
100102

101103
STDAPI WslcSetSessionSettingsFeatureFlags(_In_ WslcSessionSettings* sessionSettings, _In_ WslcSessionFeatureFlags flags);
102104

@@ -132,6 +134,13 @@ typedef struct WslcContainerVolume
132134
_In_ BOOL readOnly;
133135
} WslcContainerVolume;
134136

137+
typedef struct WslcContainerNamedVolume
138+
{
139+
_In_z_ PCSTR name; // Name of the session volume (from WslcVhdRequirements.name)
140+
_In_z_ PCSTR containerPath; // Absolute path inside the container
141+
_In_ BOOL readOnly;
142+
} WslcContainerNamedVolume;
143+
135144
typedef enum WslcContainerFlags
136145
{
137146
WSLC_CONTAINER_FLAG_NONE = 0x00000000,
@@ -180,6 +189,12 @@ STDAPI WslcSetContainerSettingsPortMappings(
180189
STDAPI WslcSetContainerSettingsVolumes(
181190
_In_ WslcContainerSettings* containerSettings, _In_reads_opt_(volumeCount) const WslcContainerVolume* volumes, _In_ uint32_t volumeCount);
182191

192+
// Add named session volumes (created via WslcCreateSessionVhdVolume) to the container settings
193+
STDAPI WslcSetContainerSettingsNamedVolumes(
194+
_In_ WslcContainerSettings* containerSettings,
195+
_In_reads_opt_(namedVolumeCount) const WslcContainerNamedVolume* namedVolumes,
196+
_In_ uint32_t namedVolumeCount);
197+
183198
STDAPI WslcCreateContainerProcess(
184199
_In_ WslcContainer container, _In_ WslcProcessSettings* newProcessSettings, _Out_ WslcProcess* newProcess, _Outptr_opt_result_z_ PWSTR* errorMessage);
185200

@@ -209,11 +224,7 @@ STDAPI WslcGetContainerInitProcess(_In_ WslcContainer container, _Out_ WslcProce
209224
//
210225
// Return Value:
211226
// S_OK on success. Otherwise, an HRESULT error code indicating the failure.
212-
//
213-
// Notes:
214-
// - The caller must pass a non-null pointer to a PCSTR variable.
215-
// - The returned string is immutable and must not be modified by the caller.
216-
STDAPI WslcInspectContainer(_In_ WslcContainer container, _Outptr_result_z_ PCSTR* inspectData);
227+
STDAPI WslcInspectContainer(_In_ WslcContainer container, _Outptr_result_z_ PSTR* inspectData);
217228

218229
typedef enum WslcContainerState
219230
{
@@ -470,7 +481,8 @@ STDAPI WslcListSessionImages(_In_ WslcSession session, _Outptr_result_buffer_(*c
470481

471482
// STORAGE
472483

473-
STDAPI WslcCreateSessionVhd(_In_ WslcSession session, _In_ const WslcVhdRequirements* options, _Outptr_opt_result_z_ PWSTR* errorMessage);
484+
STDAPI WslcCreateSessionVhdVolume(_In_ WslcSession session, _In_ const WslcVhdRequirements* options, _Outptr_opt_result_z_ PWSTR* errorMessage);
485+
STDAPI WslcDeleteSessionVhdVolume(_In_ WslcSession session, _In_z_ PCSTR name, _Outptr_opt_result_z_ PWSTR* errorMessage);
474486

475487
// INSTALL
476488

0 commit comments

Comments
 (0)