|
418 | 418 | WSLCSessionSettings runtimeSettings{}; |
419 | 419 | runtimeSettings.DisplayName = internalType->displayName; |
420 | 420 | runtimeSettings.StoragePath = internalType->storagePath; |
421 | | - // TODO: Is this the intended use for vhdRequirements.sizeInBytes? |
422 | 421 | runtimeSettings.MaximumStorageSizeMb = internalType->vhdRequirements.sizeInBytes / _1MB; |
423 | 422 | runtimeSettings.CpuCount = internalType->cpuCount; |
424 | 423 | runtimeSettings.MemoryMb = internalType->memoryMb; |
|
433 | 432 | runtimeSettings.FeatureFlags = ConvertFlags(internalType->featureFlags); |
434 | 433 | WI_SetFlag(runtimeSettings.FeatureFlags, WslcFeatureFlagsVirtioFs); |
435 | 434 |
|
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 | | - |
446 | 435 | if (SUCCEEDED(errorInfoWrapper.CaptureResult(sessionManager->CreateSession(&runtimeSettings, WSLCSessionFlagsNone, &result->session)))) |
447 | 436 | { |
448 | 437 | wsl::windows::common::security::ConfigureForCOMImpersonation(result->session.get()); |
@@ -481,23 +470,54 @@ try |
481 | 470 | } |
482 | 471 | CATCH_RETURN(); |
483 | 472 |
|
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) |
485 | 474 | try |
486 | 475 | { |
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)); |
491 | 508 | } |
492 | 509 | CATCH_RETURN(); |
493 | 510 |
|
494 | | -STDAPI WslcSetSessionSettingsVHD(_In_ WslcSessionSettings* sessionSettings, _In_ const WslcVhdRequirements* vhdRequirements) |
| 511 | +STDAPI WslcSetSessionSettingsVhd(_In_ WslcSessionSettings* sessionSettings, _In_opt_ const WslcVhdRequirements* vhdRequirements) |
495 | 512 | try |
496 | 513 | { |
497 | 514 | auto internalType = CheckAndGetInternalType(sessionSettings); |
498 | 515 |
|
499 | 516 | if (vhdRequirements) |
500 | 517 | { |
| 518 | + RETURN_HR_IF(E_INVALIDARG, vhdRequirements->sizeInBytes == 0); |
| 519 | + RETURN_HR_IF(E_NOTIMPL, vhdRequirements->type != WSLC_VHD_TYPE_DYNAMIC); |
| 520 | + |
501 | 521 | internalType->vhdRequirements = *vhdRequirements; |
502 | 522 | } |
503 | 523 | else |
|
622 | 642 | containerOptions.VolumesCount = static_cast<ULONG>(internalContainerSettings->volumesCount); |
623 | 643 | } |
624 | 644 |
|
| 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 | + |
625 | 662 | std::unique_ptr<WSLCPortMapping[]> convertedPorts; |
626 | 663 | std::vector<std::string> bindingAddressStrings; |
627 | 664 | if (internalContainerSettings->ports && internalContainerSettings->portsCount) |
|
847 | 884 | } |
848 | 885 | CATCH_RETURN(); |
849 | 886 |
|
| 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 | + |
850 | 908 | STDAPI WslcCreateContainerProcess( |
851 | 909 | _In_ WslcContainer container, _In_ WslcProcessSettings* newProcessSettings, _Out_ WslcProcess* newProcess, _Outptr_opt_result_z_ PWSTR* errorMessage) |
852 | 910 | try |
@@ -894,12 +952,21 @@ try |
894 | 952 | } |
895 | 953 | CATCH_RETURN(); |
896 | 954 |
|
897 | | -STDAPI WslcInspectContainer(_In_ WslcContainer container, _Outptr_result_z_ PCSTR* inspectData) |
| 955 | +STDAPI WslcInspectContainer(_In_ WslcContainer container, _Outptr_result_z_ PSTR* inspectData) |
898 | 956 | try |
899 | 957 | { |
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; |
903 | 970 | } |
904 | 971 | CATCH_RETURN(); |
905 | 972 |
|
|
0 commit comments