master
h 166 lines 5.2 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 LxssCreateProcess.h
8
9 Abstract:
10
11 This file contains process creation function declarations.
12
13 --*/
14
15 #pragma once
16
17 #include "SocketChannel.h"
18 #include "WslPluginApi.h"
19
20 // Macro to test if Windows interop is enabled.
21 #define LXSS_INTEROP_FLAGS (LXSS_DISTRO_FLAGS_ENABLE_DRIVE_MOUNTING | LXSS_DISTRO_FLAGS_ENABLE_INTEROP)
22
23 #define LXSS_INTEROP_ENABLED(_flags) (((_flags) & LXSS_INTEROP_FLAGS) == LXSS_INTEROP_FLAGS)
24
25 using CreateLxProcessConsoleData = struct
26 {
27 wil::unique_handle ConsoleHandle;
28 wil::unique_handle ClientProcess;
29 };
30
31 using CreateLxProcessContext = struct
32 {
33 ULONG Flags;
34 std::vector<std::string> DefaultEnvironment;
35 wil::unique_handle UserToken;
36 bool Elevated;
37 };
38
39 using CreateLxProcessData = struct
40 {
41 std::string Filename;
42 std::vector<std::string> CommandLine;
43 std::vector<std::string> Environment;
44 std::vector<std::string> NtEnvironment;
45 CREATE_PROCESS_SHELL_OPTIONS ShellOptions;
46 std::string NtPath;
47 std::string CurrentWorkingDirectory;
48 std::string Username;
49 };
50
51 class LxssCreateProcess
52 {
53 public:
54 /// <summary>
55 /// Allocates and initializes a create process message.
56 /// </summary>
57 static std::vector<gsl::byte> CreateMessage(_In_ LX_MESSAGE_TYPE MessageType, _In_ const CreateLxProcessData& CreateProcessData, _In_ ULONG DefaultUid);
58
59 /// <summary>
60 /// Parses create process arguments.
61 /// </summary>
62 static CreateLxProcessData ParseArguments(
63 _In_opt_ LPCSTR Filename,
64 _In_ ULONG CommandLineCount,
65 _In_reads_opt_(CommandLineCount) LPCSTR* CommandLine,
66 _In_opt_ LPCWSTR CurrentWorkingDirectory,
67 _In_opt_ LPCWSTR NtPath,
68 _In_reads_opt_(NtEnvironmentLength) PWCHAR NtEnvironment,
69 _In_ ULONG NtEnvironmentLength,
70 _In_opt_ LPCWSTR Username,
71 _In_ const std::vector<std::string>& DefaultEnvironment,
72 _In_ ULONG Flags);
73
74 static inline wil::unique_socket CreateLinuxProcess(
75 _In_ LPCSTR Path, _In_ LPCSTR* Arguments, const GUID& RuntimeId, wsl::shared::SocketChannel& channel, HANDLE terminatingEvent, DWORD Timeout)
76 {
77 std::vector<char> ArgumentsData;
78 for (const auto* e = Arguments; *e != nullptr; e++)
79 {
80 ArgumentsData.insert(ArgumentsData.end(), *e, *e + strlen(*e) + 1);
81 }
82
83 ArgumentsData.emplace_back('\0');
84
85 wsl::shared::MessageWriter<CREATE_PROCESS_MESSAGE> message(LxInitCreateProcess);
86 message.WriteString(message->PathIndex, Path);
87 gsl::copy(as_bytes(gsl::span(ArgumentsData)), message.InsertBuffer(message->CommandLineIndex, ArgumentsData.size()));
88 auto transaction = channel.StartTransaction(Timeout);
89 transaction.Send<CREATE_PROCESS_MESSAGE>(message.Span());
90
91 auto readResult = [&]() {
92 const auto& message = transaction.Receive<RESULT_MESSAGE<int32_t>>();
93 return message.Result;
94 };
95
96 auto processSocket = wsl::windows::common::hvsocket::Connect(RuntimeId, readResult(), terminatingEvent);
97 const auto execResult = readResult();
98 THROW_HR_IF_MSG(E_FAIL, execResult != 0, "Failed to execute '%hs', error=%d", Path, execResult);
99
100 return processSocket;
101 }
102 };
103
104 typedef struct _LXSS_DISTRO_CONFIGURATION
105 {
106 GUID DistroId;
107 DWORD State;
108 std::wstring Name;
109 DWORD Version;
110 std::filesystem::path BasePath;
111 std::wstring PackageFamilyName;
112 std::filesystem::path VhdFilePath;
113 ULONG Flags;
114 std::wstring Flavor;
115 std::wstring OsVersion;
116 std::optional<std::wstring> ShortcutPath;
117 bool RunOOBE;
118 } LXSS_DISTRO_CONFIGURATION, *PLXSS_DISTRO_CONFIGURATION;
119
120 class LxssRunningInstance
121 {
122 public:
123 LxssRunningInstance(int IdleTimeout) : m_idleTimeout(IdleTimeout)
124 {
125 }
126
127 LxssRunningInstance(const LxssRunningInstance&) = delete;
128 LxssRunningInstance(LxssRunningInstance&&) = delete;
129 void operator=(const LxssRunningInstance&) = delete;
130 void operator=(LxssRunningInstance&&) = delete;
131
132 virtual void CreateLxProcess(
133 _In_ const CreateLxProcessData& CreateProcessData,
134 _In_ const CreateLxProcessContext& CreateProcessContext,
135 _In_ const CreateLxProcessConsoleData& ConsoleData,
136 _In_ SHORT Columns,
137 _In_ SHORT Rows,
138 _In_ PLXSS_STD_HANDLES StdHandles,
139 _Out_ GUID* InstanceId,
140 _Out_ HANDLE* ProcessHandle,
141 _Out_ HANDLE* ServerHandle,
142 _Out_ HANDLE* StandardIn,
143 _Out_ HANDLE* StandardOut,
144 _Out_ HANDLE* StandardErr,
145 _Out_ HANDLE* CommunicationChannel,
146 _Out_ HANDLE* InteropSocket) = 0;
147
148 virtual GUID GetDistributionId() const = 0;
149 virtual std::shared_ptr<LxssPort> GetInitPort() = 0;
150 virtual ULONG64 GetLifetimeManagerId() const = 0;
151 virtual ULONG GetClientId() const = 0;
152 virtual void Initialize() = 0;
153 virtual bool RequestStop(_In_ bool Force) = 0;
154 virtual void Stop() = 0;
155 virtual void RegisterPlan9ConnectionTarget(_In_ HANDLE userToken) = 0;
156 virtual void UpdateTimezone() = 0;
157 virtual const WSLDistributionInformation* DistributionInformation() const noexcept = 0;
158
159 int GetIdleTimeout() const noexcept
160 {
161 return m_idleTimeout;
162 };
163
164 private:
165 int m_idleTimeout;
166 };