@@ -594,24 +594,105 @@ CATCH_RETURN();
594594STDAPI WslcStartContainer (_In_ WslcContainer container, _In_ WslcContainerStartFlags flags, _Outptr_opt_result_z_ PWSTR* errorMessage)
595595try
596596{
597+ RETURN_HR_IF_NULL (E_POINTER, container);
598+ *container = nullptr ;
597599 ErrorInfoWrapper errorInfoWrapper{errorMessage};
598- auto internalType = CheckAndGetInternalType (container);
599- RETURN_HR_IF_NULL (HRESULT_FROM_WIN32 (ERROR_INVALID_STATE), internalType->container );
600+ auto internalSession = CheckAndGetInternalType (session);
601+ RETURN_HR_IF_NULL (HRESULT_FROM_WIN32 (ERROR_INVALID_STATE), internalSession->session );
602+ auto internalContainerSettings = CheckAndGetInternalType (containerSettings);
603+
604+ auto result = std::make_unique<WslcContainerImpl>();
605+
606+ WSLCContainerOptions containerOptions{};
607+ containerOptions.Image = internalContainerSettings->image ;
608+ containerOptions.Name = internalContainerSettings->runtimeName ;
609+ containerOptions.HostName = internalContainerSettings->HostName ;
610+ containerOptions.DomainName = internalContainerSettings->DomainName ;
611+ containerOptions.Flags = ConvertFlags (internalContainerSettings->containerFlags );
612+
613+ CopyProcessSettingsToRuntime (containerOptions.InitProcessOptions , internalContainerSettings->initProcessOptions );
614+
615+ std::unique_ptr<WSLCVolume[]> convertedVolumes;
616+ if (internalContainerSettings->volumes && internalContainerSettings->volumesCount )
617+ {
618+ convertedVolumes = std::make_unique<WSLCVolume[]>(internalContainerSettings->volumesCount );
619+ for (uint32_t i = 0 ; i < internalContainerSettings->volumesCount ; ++i)
620+ {
621+ const WslcContainerVolume& internalVolume = internalContainerSettings->volumes [i];
622+ WSLCVolume& convertedVolume = convertedVolumes[i];
623+
624+ convertedVolume.HostPath = internalVolume.windowsPath ;
625+ convertedVolume.ContainerPath = internalVolume.containerPath ;
626+ convertedVolume.ReadOnly = internalVolume.readOnly ;
627+ }
628+ containerOptions.Volumes = convertedVolumes.get ();
629+ containerOptions.VolumesCount = static_cast <ULONG>(internalContainerSettings->volumesCount );
630+ }
631+
632+ std::unique_ptr<WSLCPortMapping[]> convertedPorts;
633+ std::vector<std::string> bindingAddressStrings;
634+ if (internalContainerSettings->ports && internalContainerSettings->portsCount )
635+ {
636+ convertedPorts = std::make_unique<WSLCPortMapping[]>(internalContainerSettings->portsCount );
637+ bindingAddressStrings.resize (internalContainerSettings->portsCount );
638+ for (uint32_t i = 0 ; i < internalContainerSettings->portsCount ; ++i)
639+ {
640+ const WslcContainerPortMapping& internalPort = internalContainerSettings->ports [i];
641+ WSLCPortMapping& convertedPort = convertedPorts[i];
642+
643+ convertedPort.HostPort = internalPort.windowsPort ;
644+ convertedPort.ContainerPort = internalPort.containerPort ;
645+
646+ // TODO: Consider using standard protocol numbers instead of our own enum.
647+ convertedPort.Protocol = internalPort.protocol == WSLC_PORT_PROTOCOL_TCP ? IPPROTO_TCP : IPPROTO_UDP;
648+
649+ if (internalPort.windowsAddress != nullptr )
650+ {
651+ char addrBuf[INET6_ADDRSTRLEN]{};
652+ if (internalPort.windowsAddress ->ss_family == AF_INET)
653+ {
654+ const auto * addr4 = reinterpret_cast <const sockaddr_in*>(internalPort.windowsAddress );
655+ THROW_HR_IF_NULL (E_UNEXPECTED, inet_ntop (AF_INET, &addr4->sin_addr , addrBuf, sizeof (addrBuf)));
656+ convertedPort.Family = AF_INET;
657+ }
658+ else
659+ {
660+ const auto * addr6 = reinterpret_cast <const sockaddr_in6*>(internalPort.windowsAddress );
661+ THROW_HR_IF_NULL (E_UNEXPECTED, inet_ntop (AF_INET6, &addr6->sin6_addr , addrBuf, sizeof (addrBuf)));
662+ convertedPort.Family = AF_INET6;
663+ }
664+ bindingAddressStrings[i] = addrBuf;
665+ convertedPort.BindingAddress = bindingAddressStrings[i].c_str ();
666+ }
667+ else
668+ {
669+ convertedPort.Family = AF_INET;
670+ convertedPort.BindingAddress = " 127.0.0.1" ;
671+ }
672+ }
673+ containerOptions.Ports = convertedPorts.get ();
674+ containerOptions.PortsCount = static_cast <ULONG>(internalContainerSettings->portsCount );
675+ }
600676
601- bool hasIOCallback = IOCallback::HasIOCallback (internalType->ioCallbackOptions );
602- // If callbacks were provided, ATTACH must be used.
603- // TODO: Consider if we should just override flags when callbacks were provided instead.
604- RETURN_HR_IF (E_INVALIDARG, WI_IsFlagClear (flags, WSLC_CONTAINER_START_FLAG_ATTACH) && hasIOCallback);
677+ containerOptions.ContainerNetwork .ContainerNetworkType = internalContainerSettings->networking ;
678+
679+ // TODO: No user access
680+ // containerOptions.Entrypoint;
681+ // containerOptions.Labels;
682+ // containerOptions.LabelsCount;
683+ // containerOptions.StopSignal;
684+ // containerOptions.ShmSize;
605685
606- if (SUCCEEDED (errorInfoWrapper.CaptureResult (internalType-> container -> Start ( ConvertFlags (flags), nullptr ))))
686+ if (SUCCEEDED (errorInfoWrapper.CaptureResult (internalSession-> session -> CreateContainer (&containerOptions, &result-> container ))))
607687 {
608- if (hasIOCallback)
688+ wsl::windows::common::security::ConfigureForCOMImpersonation (result->container .get ());
689+
690+ if (IOCallback::HasIOCallback (internalContainerSettings->initProcessOptions ))
609691 {
610- wil::com_ptr<IWSLCProcess> process;
611- RETURN_IF_FAILED (internalType->container ->GetInitProcess (&process));
612- wsl::windows::common::security::ConfigureForCOMImpersonation (process.get ());
613- internalType->ioCallbacks = std::make_shared<IOCallback>(process.get (), internalType->ioCallbackOptions );
692+ result->ioCallbackOptions = internalContainerSettings->initProcessOptions ->ioCallbacks ;
614693 }
694+
695+ *container = reinterpret_cast <WslcContainer>(result.release ());
615696 }
616697
617698 return errorInfoWrapper;
693774
694775 for (uint32_t i = 0 ; i < portMappingCount; ++i)
695776 {
696- RETURN_HR_IF (E_NOTIMPL, portMappings[i].windowsAddress != nullptr );
777+ if (portMappings[i].windowsAddress != nullptr )
778+ {
779+ const auto family = portMappings[i].windowsAddress ->ss_family ;
780+ RETURN_HR_IF (E_INVALIDARG, family != AF_INET && family != AF_INET6);
781+ }
697782 RETURN_HR_IF (E_NOTIMPL, portMappings[i].protocol != 0 );
698783 }
699784
0 commit comments