master
h 685 lines 27.5 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 WslcSDK.h
8
9 Abstract:
10
11 This file contains the public WSL Container SDK api definitions.
12
13 PREVIEW NOTICE: This API is currently in preview and is subject to breaking
14 changes in future releases without prior notice. Do not rely on API stability
15 for production workloads. Features, function signatures, and behaviors may
16 change between releases during the preview period.
17
18 --*/
19 #pragma once
20 #include <winsock2.h>
21 #include <ws2tcpip.h>
22 #include <windows.h>
23 #include <stdint.h>
24 #include <specstrings.h>
25
26 EXTERN_C_START
27
28 // WSLC specific error codes
29 // Ensure wslc.idl and wslcsdk.idl are also updated.
30 #define WSLC_E_BASE (0x0600)
31 #define WSLC_E_IMAGE_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 1) /* 0x80040601 */
32 #define WSLC_E_CONTAINER_PREFIX_AMBIGUOUS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 2) /* 0x80040602 */
33 #define WSLC_E_CONTAINER_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 3) /* 0x80040603 */
34 #define WSLC_E_VOLUME_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 4) /* 0x80040604 */
35 #define WSLC_E_CONTAINER_NOT_RUNNING MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 5) /* 0x80040605 */
36 #define WSLC_E_CONTAINER_IS_RUNNING MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 6) /* 0x80040606 */
37 #define WSLC_E_SESSION_RESERVED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 7) /* 0x80040607 */
38 #define WSLC_E_INVALID_SESSION_NAME MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 8) /* 0x80040608 */
39 #define WSLC_E_NETWORK_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 9) /* 0x80040609 */
40 #define WSLC_E_WU_SEARCH_FAILED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 10) /* 0x8004060A */
41 #define WSLC_E_SDK_UPDATE_NEEDED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 11) /* 0x8004060B */
42 #define WSLC_E_CONTAINER_DISABLED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 12) /* 0x8004060C */
43 #define WSLC_E_REGISTRY_BLOCKED_BY_POLICY MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 13) /* 0x8004060D */
44 #define WSLC_E_VOLUME_NOT_AVAILABLE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 14) /* 0x8004060E */
45 #define WSLC_E_SESSION_NOT_FOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 15) /* 0x8004060F */
46 #define WSLC_E_VM_NOT_RUNNING MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 16) /* 0x80040610 */
47 #define WSLC_E_EVENTS_LOST MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 17) /* 0x80040611 */
48 #define WSLC_E_EVENT_STREAM_FINISHED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 18) /* 0x80040612 */
49 #define WSLC_E_CONTAINER_DELETED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, WSLC_E_BASE + 19) /* 0x80040613 */
50
51 // Session values
52 #define WSLC_SESSION_OPTIONS_SIZE 72
53 #define WSLC_SESSION_OPTIONS_ALIGNMENT 8
54
55 typedef struct WslcSessionSettings
56 {
57 __declspec(align(WSLC_SESSION_OPTIONS_ALIGNMENT)) BYTE _opaque[WSLC_SESSION_OPTIONS_SIZE];
58 } WslcSessionSettings;
59
60 DECLARE_HANDLE(WslcSession);
61
62 // Container values
63 #define WSLC_CONTAINER_OPTIONS_SIZE 104
64 #define WSLC_CONTAINER_OPTIONS_ALIGNMENT 8
65
66 typedef struct WslcContainerSettings
67 {
68 __declspec(align(WSLC_CONTAINER_OPTIONS_ALIGNMENT)) BYTE _opaque[WSLC_CONTAINER_OPTIONS_SIZE];
69 } WslcContainerSettings;
70
71 DECLARE_HANDLE(WslcContainer);
72
73 // Process values
74 #define WSLC_CONTAINER_PROCESS_OPTIONS_SIZE 72
75 #define WSLC_CONTAINER_PROCESS_OPTIONS_ALIGNMENT 8
76 typedef struct WslcProcessSettings
77 {
78 __declspec(align(WSLC_CONTAINER_PROCESS_OPTIONS_ALIGNMENT)) BYTE _opaque[WSLC_CONTAINER_PROCESS_OPTIONS_SIZE];
79 } WslcProcessSettings;
80
81 DECLARE_HANDLE(WslcProcess);
82
83 typedef enum WslcContainerNetworkingMode
84 {
85 WSLC_CONTAINER_NETWORKING_MODE_NONE = 0, // No networking / isolated
86 WSLC_CONTAINER_NETWORKING_MODE_BRIDGED = 1
87 } WslcContainerNetworkingMode;
88
89 typedef enum WslcVhdType
90 {
91 WSLC_VHD_TYPE_DYNAMIC = 0, // Expanding VHDX (default)
92 WSLC_VHD_TYPE_FIXED = 1 // Fixed-allocation VHDX (only honored by WslcCreateSessionVhdVolume)
93 } WslcVhdType;
94
95 typedef enum WslcVhdRequirementsFlags
96 {
97 WSLC_VHD_REQ_FLAG_NONE = 0x00000000,
98 // When set, WslcVhdRequirements::uid and gid are honored. When clear,
99 // those fields are ignored and the volume is left owned by root:root.
100 WSLC_VHD_REQ_FLAG_OWNER = 0x00000001,
101 } WslcVhdRequirementsFlags;
102
103 DEFINE_ENUM_FLAG_OPERATORS(WslcVhdRequirementsFlags);
104
105 typedef struct WslcVhdRequirements
106 {
107 // Ignored by WslcSetSessionSettingsVhd
108 _In_z_ PCSTR name;
109 _In_ uint64_t sizeBytes; // Desired size (for create/expand)
110 _In_ WslcVhdType type;
111 // The remaining fields are only honored by WslcCreateSessionVhdVolume.
112 // WslcSetSessionSettingsVhd rejects non-NONE flags with E_INVALIDARG.
113 _In_ WslcVhdRequirementsFlags flags;
114 _In_ uint32_t uid; // honored iff (flags & WSLC_VHD_REQ_FLAG_OWNER)
115 _In_ uint32_t gid; // honored iff (flags & WSLC_VHD_REQ_FLAG_OWNER)
116 } WslcVhdRequirements;
117
118 typedef enum WslcSessionFeatureFlags
119 {
120 WSLC_SESSION_FEATURE_FLAG_NONE = 0x00000000,
121 WSLC_SESSION_FEATURE_FLAG_ENABLE_GPU = 0x00000004
122 } WslcSessionFeatureFlags;
123
124 DEFINE_ENUM_FLAG_OPERATORS(WslcSessionFeatureFlags);
125
126 typedef enum WslcSessionTerminationReason
127 {
128 WSLC_SESSION_TERMINATION_REASON_UNKNOWN = 0,
129 WSLC_SESSION_TERMINATION_REASON_SHUTDOWN = 1,
130 WSLC_SESSION_TERMINATION_REASON_CRASHED = 2,
131 } WslcSessionTerminationReason;
132
133 typedef struct WslcSessionCrashDumpInfo
134 {
135 _Field_z_ PCWSTR dumpPath;
136 _Field_z_ PCSTR processName;
137 uint32_t pid;
138 uint32_t signal;
139 uint64_t timestamp;
140 } WslcSessionCrashDumpInfo;
141
142 typedef __callback void(CALLBACK* WslcSessionCrashDumpCallback)(_In_ const WslcSessionCrashDumpInfo* info, _In_opt_ PVOID context);
143
144 // Opaque handle returned by WslcRegisterSessionCrashDumpCallback. Holding it keeps the crash dump
145 // registration alive; pass it to WslcReleaseCrashDumpSubscription to unsubscribe.
146 DECLARE_HANDLE(WslcCrashDumpSubscription);
147
148 STDAPI WslcInitSessionSettings(_In_ PCWSTR name, _In_ PCWSTR storagePath, _Out_ WslcSessionSettings* sessionSettings);
149
150 STDAPI WslcCreateSession(_In_ WslcSessionSettings* sessionSettings, _Out_ WslcSession* session, _Outptr_opt_result_z_ PWSTR* errorMessage);
151
152 // OPTIONAL SESSION SETTINGS
153 STDAPI WslcSetSessionSettingsCpuCount(_In_ WslcSessionSettings* sessionSettings, _In_ uint32_t cpuCount);
154 STDAPI WslcSetSessionSettingsMemory(_In_ WslcSessionSettings* sessionSettings, _In_ uint32_t memoryMB);
155 STDAPI WslcSetSessionSettingsTimeout(_In_ WslcSessionSettings* sessionSettings, _In_ uint32_t timeoutMS);
156
157 STDAPI WslcSetSessionSettingsVhd(_In_ WslcSessionSettings* sessionSettings, _In_opt_ const WslcVhdRequirements* vhdRequirements);
158
159 STDAPI WslcSetSessionSettingsFeatureFlags(_In_ WslcSessionSettings* sessionSettings, _In_ WslcSessionFeatureFlags flags);
160
161 STDAPI WslcGetSessionTerminationEvent(_In_ WslcSession session, _Out_ HANDLE* terminationEvent);
162 STDAPI WslcGetSessionTerminationReason(_In_ WslcSession session, _Out_ WslcSessionTerminationReason* reason);
163
164 STDAPI WslcTerminateSession(_In_ WslcSession session);
165 STDAPI WslcReleaseSession(_In_ WslcSession session);
166
167 // Registers a callback invoked when a Linux process crash dump is written for the session.
168 // Works for any caller holding a live session. The returned subscription keeps the registration
169 // alive; release it with WslcReleaseCrashDumpSubscription to unsubscribe. Multiple subscriptions
170 // can be registered against the same session.
171 STDAPI WslcRegisterSessionCrashDumpCallback(
172 _In_ WslcSession session,
173 _In_ WslcSessionCrashDumpCallback crashDumpCallback,
174 _In_opt_ PVOID crashDumpContext,
175 _Out_ WslcCrashDumpSubscription* subscription,
176 _Outptr_opt_result_z_ PWSTR* errorMessage);
177
178 STDAPI WslcReleaseCrashDumpSubscription(_In_ WslcCrashDumpSubscription subscription);
179
180 // CONTAINER DEFINITIONS
181
182 typedef enum WslcPortProtocol
183 {
184 WSLC_PORT_PROTOCOL_TCP = 0,
185 WSLC_PORT_PROTOCOL_UDP = 1
186 } WslcPortProtocol;
187
188 typedef struct WslcContainerPortMapping
189 {
190 _In_ uint16_t windowsPort; // Port on Windows host
191 _In_ uint16_t containerPort; // Port inside container
192 _In_ WslcPortProtocol protocol; // TCP or UDP
193
194 // if you want to override the default binding address
195 _In_opt_ struct sockaddr_storage* windowsAddress; // accepts ipv4/6
196 } WslcContainerPortMapping;
197
198 typedef struct WslcContainerVolume
199 {
200 _In_z_ PCWSTR windowsPath;
201 _In_z_ PCSTR containerPath;
202 _In_ BOOL readOnly;
203 } WslcContainerVolume;
204
205 typedef struct WslcContainerNamedVolume
206 {
207 _In_z_ PCSTR name; // Name of the session volume (from WslcVhdRequirements.name)
208 _In_z_ PCSTR containerPath; // Absolute path inside the container
209 _In_ BOOL readOnly;
210 } WslcContainerNamedVolume;
211
212 typedef enum WslcContainerFlags
213 {
214 WSLC_CONTAINER_FLAG_NONE = 0x00000000,
215 WSLC_CONTAINER_FLAG_AUTO_REMOVE = 0x00000001,
216 WSLC_CONTAINER_FLAG_ENABLE_GPU = 0x00000002,
217 WSLC_CONTAINER_FLAG_PRIVILEGED = 0x00000004,
218
219 } WslcContainerFlags;
220
221 DEFINE_ENUM_FLAG_OPERATORS(WslcContainerFlags);
222
223 typedef enum WslcContainerStartFlags
224 {
225 WSLC_CONTAINER_START_FLAG_NONE = 0x00000000,
226 WSLC_CONTAINER_START_FLAG_ATTACH = 0x00000001,
227
228 } WslcContainerStartFlags;
229
230 DEFINE_ENUM_FLAG_OPERATORS(WslcContainerStartFlags);
231
232 STDAPI WslcInitContainerSettings(_In_ PCSTR imageName, _Out_ WslcContainerSettings* containerSettings);
233
234 STDAPI WslcCreateContainer(_In_ WslcSession session, _In_ const WslcContainerSettings* containerSettings, _Out_ WslcContainer* container, _Outptr_opt_result_z_ PWSTR* errorMessage);
235
236 // Opens an existing container by name, full ID, or partial ID prefix.
237 // The returned WslcContainer handle is owned by the caller; release it with WslcReleaseContainer.
238 // Returns WSLC_E_CONTAINER_NOT_FOUND if no matching container exists, or
239 // WSLC_E_CONTAINER_PREFIX_AMBIGUOUS if the given prefix matches more than one container.
240 STDAPI WslcOpenContainer(_In_ WslcSession session, _In_z_ PCSTR nameOrId, _Out_ WslcContainer* container, _Outptr_opt_result_z_ PWSTR* errorMessage);
241
242 STDAPI WslcStartContainer(_In_ WslcContainer container, _In_ WslcContainerStartFlags flags, _Outptr_opt_result_z_ PWSTR* errorMessage);
243
244 // OPTIONAL CONTAINER SETTINGS
245 STDAPI WslcSetContainerSettingsName(_In_ WslcContainerSettings* containerSettings, _In_ PCSTR name);
246
247 STDAPI WslcSetContainerSettingsInitProcess(_In_ WslcContainerSettings* containerSettings, _In_ WslcProcessSettings* initProcess);
248
249 STDAPI WslcSetContainerSettingsNetworkingMode(_In_ WslcContainerSettings* containerSettings, _In_ WslcContainerNetworkingMode networkingMode);
250
251 STDAPI WslcSetContainerSettingsHostName(_In_ WslcContainerSettings* containerSettings, _In_ PCSTR hostName);
252
253 STDAPI WslcSetContainerSettingsDomainName(_In_ WslcContainerSettings* containerSettings, _In_ PCSTR domainName);
254
255 STDAPI WslcSetContainerSettingsFlags(_In_ WslcContainerSettings* containerSettings, _In_ WslcContainerFlags flags);
256
257 STDAPI WslcSetContainerSettingsPortMappings(
258 _In_ WslcContainerSettings* containerSettings,
259 _In_reads_opt_(portMappingCount) const WslcContainerPortMapping* portMappings,
260 _In_ uint32_t portMappingCount);
261
262 // Add the container volumes to the volumes array
263 STDAPI WslcSetContainerSettingsVolumes(
264 _In_ WslcContainerSettings* containerSettings, _In_reads_opt_(volumeCount) const WslcContainerVolume* volumes, _In_ uint32_t volumeCount);
265
266 // Add named session volumes (created via WslcCreateSessionVhdVolume) to the container settings
267 STDAPI WslcSetContainerSettingsNamedVolumes(
268 _In_ WslcContainerSettings* containerSettings,
269 _In_reads_opt_(namedVolumeCount) const WslcContainerNamedVolume* namedVolumes,
270 _In_ uint32_t namedVolumeCount);
271
272 STDAPI WslcCreateContainerProcess(
273 _In_ WslcContainer container, _In_ WslcProcessSettings* newProcessSettings, _Out_ WslcProcess* newProcess, _Outptr_opt_result_z_ PWSTR* errorMessage);
274
275 STDAPI WslcReleaseContainer(_In_ WslcContainer container);
276
277 // GENERAL CONTAINER MANAGEMENT
278
279 #define WSLC_CONTAINER_ID_BUFFER_SIZE 65 // 64 hex chars + null terminator
280
281 STDAPI WslcGetContainerID(_In_ WslcContainer container, _Out_writes_(WSLC_CONTAINER_ID_BUFFER_SIZE) CHAR containerID[WSLC_CONTAINER_ID_BUFFER_SIZE]);
282
283 STDAPI WslcGetContainerInitProcess(_In_ WslcContainer container, _Out_ WslcProcess* initProcess);
284
285 // Retrieves the inspection data for a container.
286 //
287 // Parameters:
288 // container
289 // A valid WslcContainer handle representing the container to inspect.
290 //
291 // inspectData
292 // On success, receives a pointer to a null-terminated ANSI string
293 // containing the inspection data.
294 //
295 // The string is allocated using CoTaskMemAlloc. The caller takes
296 // ownership of the returned memory and must free it by calling
297 // CoTaskMemFree when it is no longer needed.
298 //
299 // Return Value:
300 // S_OK on success. Otherwise, an HRESULT error code indicating the failure.
301 STDAPI WslcInspectContainer(_In_ WslcContainer container, _Outptr_result_z_ PSTR* inspectData);
302
303 typedef enum WslcContainerState
304 {
305 WSLC_CONTAINER_STATE_INVALID = 0,
306 WSLC_CONTAINER_STATE_CREATED = 1,
307 WSLC_CONTAINER_STATE_RUNNING = 2,
308 WSLC_CONTAINER_STATE_EXITED = 3,
309 WSLC_CONTAINER_STATE_DELETED = 4,
310 } WslcContainerState;
311
312 STDAPI WslcGetContainerState(_In_ WslcContainer container, _Out_ WslcContainerState* state);
313
314 // Will define more signals as needed:
315 typedef enum WslcSignal
316 {
317 WSLC_SIGNAL_NONE = 0, // No signal; reserved for future use
318 WSLC_SIGNAL_SIGHUP = 1, // SIGHUP: reload / hangup
319 WSLC_SIGNAL_SIGINT = 2, // SIGINT: interrupt (Ctrl-C)
320 WSLC_SIGNAL_SIGQUIT = 3, // SIGQUIT: quit with core dump
321 WSLC_SIGNAL_SIGKILL = 9, // SIGKILL: immediate termination
322 WSLC_SIGNAL_SIGTERM = 15, // SIGTERM: graceful shutdown
323 } WslcSignal;
324
325 STDAPI WslcStopContainer(_In_ WslcContainer container, _In_ WslcSignal signal, _In_ uint32_t timeoutSeconds, _Outptr_opt_result_z_ PWSTR* errorMessage);
326
327 typedef enum WslcDeleteContainerFlags
328 {
329 WSLC_DELETE_CONTAINER_FLAG_NONE = 0,
330 WSLC_DELETE_CONTAINER_FLAG_FORCE = 0x01
331 } WslcDeleteContainerFlags;
332
333 DEFINE_ENUM_FLAG_OPERATORS(WslcDeleteContainerFlags);
334
335 STDAPI WslcDeleteContainer(_In_ WslcContainer container, _In_ WslcDeleteContainerFlags flags, _Outptr_opt_result_z_ PWSTR* errorMessage);
336
337 // PROCESS DEFINITIONS
338 STDAPI WslcInitProcessSettings(_Out_ WslcProcessSettings* processSettings);
339
340 // OPTIONAL PROCESS SETTINGS
341
342 STDAPI WslcSetProcessSettingsWorkingDirectory(_In_ WslcProcessSettings* processSettings, _In_ PCSTR workingDirectory);
343
344 STDAPI WslcSetProcessSettingsCmdLine(_In_ WslcProcessSettings* processSettings, _In_reads_(argc) PCSTR const* argv, size_t argc);
345
346 STDAPI WslcSetProcessSettingsEnvVariables(_In_ WslcProcessSettings* processSettings, _In_reads_(argc) PCSTR const* key_value, size_t argc);
347
348 typedef enum WslcProcessIOHandle
349 {
350 WSLC_PROCESS_IO_HANDLE_STDIN = 0,
351 WSLC_PROCESS_IO_HANDLE_STDOUT = 1,
352 WSLC_PROCESS_IO_HANDLE_STDERR = 2
353 } WslcProcessIOHandle;
354
355 // Callback invoked when stdout or stderr data is available from a running
356 // WSLC process.
357 //
358 // Parameters:
359 // ioHandle
360 // The WslcProcessIOHandle that the IO callback is for.
361 // Only STDOUT and STDERR will receive callbacks.
362 //
363 // data
364 // Pointer to a buffer containing the bytes read. The buffer is owned
365 // by WSLC and is valid only for the duration of the callback.
366 //
367 // The caller must not free, modify, or retain the pointer. If the
368 // caller needs to keep the data, it must copy the contents before
369 // returning from the callback.
370 //
371 // dataBytes
372 // Number of bytes available in the data buffer.
373 //
374 // context
375 // Caller-supplied context pointer that was provided when the callback
376 // was registered.
377 //
378 // Notes:
379 // - WSLC frees or reuses the buffer immediately after the callback returns.
380 // - The callback must return promptly; long-running operations may block
381 // WSLC's internal I/O processing.
382 // - The buffer is not null-terminated; it is a raw byte sequence.
383 //
384 typedef __callback void(CALLBACK* WslcStdIOCallback)(
385 WslcProcessIOHandle ioHandle, _In_reads_bytes_(dataBytes) const BYTE* data, _In_ uint32_t dataBytes, _In_opt_ PVOID context);
386
387 // Callback invoked when a WSLC process has exited AND any remaining IO has been flushed.
388 //
389 // Parameters:
390 // exitCode
391 // The exit code of the process.
392 //
393 // context
394 // Caller-supplied context pointer that was provided when the callback
395 // was registered.
396 //
397 // Notes:
398 // - Once this callback is invoked, any registered IO callbacks will no longer be called.
399 //
400 typedef __callback void(CALLBACK* WslcProcessExitCallback)(INT32 exitCode, _In_opt_ PVOID context);
401
402 // Using any callbacks will consume the IO handles, preventing acquisition through WslcGetProcessIOHandle.
403 // If using IO callbacks, also use the exit callback to prevent a race between process exit and IO buffer flushing.
404 typedef struct WslcProcessCallbacks
405 {
406 WslcStdIOCallback onStdOut;
407 WslcStdIOCallback onStdErr;
408 WslcProcessExitCallback onExit;
409 } WslcProcessCallbacks;
410
411 STDAPI WslcSetProcessSettingsCallbacks(_In_ WslcProcessSettings* processSettings, _In_ const WslcProcessCallbacks* callbacks, _In_opt_ PVOID context);
412
413 // Sets IO callbacks for the init process of a container.
414 // Must be called before WslcStartContainer (with WSLC_CONTAINER_START_FLAG_ATTACH).
415 // Has no effect on a container that is already running.
416 STDAPI WslcSetContainerInitProcessIOCallbacks(_In_ WslcContainer container, _In_ const WslcProcessCallbacks* callbacks, _In_opt_ PVOID context);
417
418 // PROCESS MANAGEMENT
419
420 STDAPI WslcGetProcessPid(_In_ WslcProcess process, _Out_ uint32_t* pid);
421
422 STDAPI WslcGetProcessExitEvent(_In_ WslcProcess process, _Out_ HANDLE* exitEvent);
423
424 typedef enum WslcProcessState
425 {
426 WSLC_PROCESS_STATE_UNKNOWN = 0,
427 WSLC_PROCESS_STATE_RUNNING = 1,
428 WSLC_PROCESS_STATE_EXITED = 2,
429 WSLC_PROCESS_STATE_SIGNALLED = 3
430 } WslcProcessState;
431
432 STDAPI WslcGetProcessState(_In_ WslcProcess process, _Out_ WslcProcessState* state);
433
434 STDAPI WslcGetProcessExitCode(_In_ WslcProcess process, _Out_ PINT32 exitCode);
435
436 STDAPI WslcSignalProcess(_In_ WslcProcess process, _In_ WslcSignal signal);
437
438 STDAPI WslcGetProcessIOHandle(_In_ WslcProcess process, _In_ WslcProcessIOHandle ioHandle, _Out_ HANDLE* handle);
439
440 STDAPI WslcReleaseProcess(_In_ WslcProcess process);
441
442 // IMAGE MANAGEMENT
443
444 // Container image
445 typedef struct WslcImageProgressDetail
446 {
447 _Out_ uint64_t currentBytes; // bytes downloaded so far
448 _Out_ uint64_t totalBytes; // total bytes expected
449 } WslcImageProgressDetail;
450
451 typedef enum WslcImageProgressStatus
452 {
453 WSLC_IMAGE_PROGRESS_STATUS_UNKNOWN = 0,
454 WSLC_IMAGE_PROGRESS_STATUS_PULLING = 1, // "Pulling fs layer"
455 WSLC_IMAGE_PROGRESS_STATUS_WAITING = 2, // "Waiting"
456 WSLC_IMAGE_PROGRESS_STATUS_DOWNLOADING = 3, // "Downloading"
457 WSLC_IMAGE_PROGRESS_STATUS_VERIFYING = 4, // "Verifying Checksum"
458 WSLC_IMAGE_PROGRESS_STATUS_EXTRACTING = 5, // "Extracting"
459 WSLC_IMAGE_PROGRESS_STATUS_COMPLETE = 6 // "Pull complete"
460 } WslcImageProgressStatus;
461
462 typedef struct WslcImageProgressMessage
463 {
464 _Out_ PCSTR id; // layer ID or digest
465 _Out_ WslcImageProgressStatus status; // "Downloading", "Extracting", etc.
466 _Out_ WslcImageProgressDetail detail;
467 } WslcImageProgressMessage;
468
469 // pointer-to-function typedef (unambiguous)
470 typedef HRESULT(CALLBACK* WslcContainerImageProgressCallback)(const WslcImageProgressMessage* progress, PVOID context);
471
472 // options struct typedef is a pointer type and _In_opt_ is valid
473 typedef struct WslcPullImageOptions
474 {
475 _In_z_ PCSTR uri;
476 WslcContainerImageProgressCallback progressCallback;
477 PVOID progressCallbackContext;
478 _In_opt_z_ PCSTR registryAuth;
479 } WslcPullImageOptions;
480
481 STDAPI WslcPullSessionImage(_In_ WslcSession session, _In_ const WslcPullImageOptions* options, _Outptr_opt_result_z_ PWSTR* errorMessage);
482
483 typedef struct WslcImportImageOptions
484 {
485 _In_opt_ WslcContainerImageProgressCallback progressCallback;
486 _In_opt_ PVOID progressCallbackContext;
487 } WslcImportImageOptions;
488
489 STDAPI WslcImportSessionImage(
490 _In_ WslcSession session,
491 _In_z_ PCSTR imageName,
492 _In_ HANDLE imageContent,
493 _In_ uint64_t imageContentBytes,
494 _In_opt_ const WslcImportImageOptions* options,
495 _Outptr_opt_result_z_ PWSTR* errorMessage);
496
497 STDAPI WslcImportSessionImageFromFile(
498 _In_ WslcSession session, _In_z_ PCSTR imageName, _In_z_ PCWSTR path, _In_opt_ const WslcImportImageOptions* options, _Outptr_opt_result_z_ PWSTR* errorMessage);
499
500 typedef struct WslcLoadImageOptions
501 {
502 _In_opt_ WslcContainerImageProgressCallback progressCallback;
503 _In_opt_ PVOID progressCallbackContext;
504 } WslcLoadImageOptions;
505
506 STDAPI WslcLoadSessionImage(
507 _In_ WslcSession session,
508 _In_ HANDLE imageContent,
509 _In_ uint64_t imageContentBytes,
510 _In_opt_ const WslcLoadImageOptions* options,
511 _Outptr_opt_result_z_ PWSTR* errorMessage);
512
513 STDAPI WslcLoadSessionImageFromFile(
514 _In_ WslcSession session, _In_z_ PCWSTR path, _In_opt_ const WslcLoadImageOptions* options, _Outptr_opt_result_z_ PWSTR* errorMessage);
515
516 #define WSLC_IMAGE_NAME_LENGTH 256 // 255 chars + null
517
518 typedef struct WslcImageInfo
519 {
520 // we should expose this
521 CHAR name[WSLC_IMAGE_NAME_LENGTH];
522 uint8_t sha256[32];
523 int64_t sizeBytes;
524 uint64_t createdUnixTime;
525 } WslcImageInfo;
526
527 STDAPI WslcDeleteSessionImage(_In_ WslcSession session, _In_z_ PCSTR nameOrID, _Outptr_opt_result_z_ PWSTR* errorMessage);
528
529 typedef struct WslcTagImageOptions
530 {
531 _In_z_ PCSTR image; // Source image name or ID.
532 _In_z_ PCSTR repo; // Target repository name.
533 _In_z_ PCSTR tag; // Target tag name.
534 } WslcTagImageOptions;
535
536 STDAPI WslcTagSessionImage(_In_ WslcSession session, _In_ const WslcTagImageOptions* options, _Outptr_opt_result_z_ PWSTR* errorMessage);
537
538 typedef struct WslcPushImageOptions
539 {
540 _In_z_ PCSTR image;
541 _In_z_ PCSTR registryAuth; // Base64-encoded X-Registry-Auth header value.
542 _In_opt_ WslcContainerImageProgressCallback progressCallback;
543 _In_opt_ PVOID progressCallbackContext;
544 } WslcPushImageOptions;
545
546 STDAPI WslcPushSessionImage(_In_ WslcSession session, _In_ const WslcPushImageOptions* options, _Outptr_opt_result_z_ PWSTR* errorMessage);
547
548 typedef enum WslcIdentityTokenType
549 {
550 WSLC_IDENTITY_TOKEN_TYPE_UNKNOWN = 0,
551 WSLC_IDENTITY_TOKEN_TYPE_TOKEN = 1,
552 WSLC_IDENTITY_TOKEN_TYPE_CREDENTIALS = 2,
553 } WslcIdentityTokenType;
554
555 // Authenticates with a container registry and returns an identity token suitable for use as
556 // the registryAuth value in WslcPullSessionImage and WslcPushSessionImage.
557 //
558 // Parameters:
559 // session
560 // A valid WslcSession handle.
561 //
562 // serverAddress
563 // The registry server address (e.g. "127.0.0.1:5000").
564 //
565 // username
566 // The username for authentication.
567 //
568 // password
569 // The password for authentication.
570 //
571 // identityToken
572 // On success, receives a pointer to a null-terminated ANSI string containing a
573 // base64-encoded JSON object that can be passed directly as the registryAuth value to
574 // WslcPullSessionImage or WslcPushSessionImage.
575 //
576 // The string is allocated using CoTaskMemAlloc. The caller takes ownership of the
577 // returned memory and must free it by calling CoTaskMemFree when it is no longer needed.
578 //
579 // tokenType
580 // Optional. On success, receives the type of credential embedded in identityToken:
581 // WSLC_IDENTITY_TOKEN_TYPE_TOKEN - the server returned an identity token;
582 // identityToken encodes {"identitytoken": ...}
583 // WSLC_IDENTITY_TOKEN_TYPE_CREDENTIALS - the server returned no token; the supplied
584 // username/password are embedded instead as
585 // {"username": ..., "password": ...}
586 // On failure, set to WSLC_IDENTITY_TOKEN_TYPE_UNKNOWN.
587 // May be null if the caller does not need the token type.
588 //
589 // errorMessage
590 // Optional. On failure, receives a human-readable error message. May be null.
591 //
592 // Return Value:
593 // S_OK on success. Otherwise, an HRESULT error code indicating the failure.
594 //
595 // Outcome table:
596 // Outcome | HRESULT | identityToken | tokenType
597 // ------------------------------|---------|--------------------------------------|----------
598 // Failure | FAILED | nullptr | UNKNOWN
599 // Success, server returns token | S_OK | base64({"identitytoken": "<token>"}) | TOKEN
600 // Success, no token returned | S_OK | base64({"username":..,"password":..})| CREDENTIALS
601 STDAPI WslcSessionAuthenticate(
602 _In_ WslcSession session,
603 _In_z_ PCSTR serverAddress,
604 _In_z_ PCSTR username,
605 _In_z_ PCSTR password,
606 _Outptr_result_z_ PSTR* identityToken,
607 _Out_opt_ WslcIdentityTokenType* tokenType,
608 _Outptr_opt_result_z_ PWSTR* errorMessage);
609
610 // Retrieves the list of container images
611 // Parameters:
612 // session
613 // A valid WslcSession handle.
614 //
615 // images
616 // On success, receives a pointer to a contiguous array of
617 // WslcImageInfo structures describing the images
618 //
619 // The array is allocated using CoTaskMemAlloc. The caller takes
620 // ownership of the memory and must free it by calling
621 // CoTaskMemFree when it is no longer needed.
622 //
623 // count
624 // On success, receives the number of elements in the images array.
625 // On failure, *count is set to 0.
626 //
627 // Return Value:
628 // S_OK on success. Otherwise, an HRESULT error code indicating the
629 // reason for failure.
630 //
631 // Notes:
632 // - The caller must pass non-null pointers for both 'images' and 'count'.
633 //
634
635 STDAPI WslcListSessionImages(_In_ WslcSession session, _Outptr_result_buffer_(*count) WslcImageInfo** images, _Out_ uint32_t* count);
636
637 // STORAGE
638
639 STDAPI WslcCreateSessionVhdVolume(_In_ WslcSession session, _In_ const WslcVhdRequirements* options, _Outptr_opt_result_z_ PWSTR* errorMessage);
640 STDAPI WslcDeleteSessionVhdVolume(_In_ WslcSession session, _In_z_ PCSTR name, _Outptr_opt_result_z_ PWSTR* errorMessage);
641
642 // INSTALL
643
644 typedef enum WslcComponentFlags
645 {
646 WSLC_COMPONENT_FLAG_NONE = 0,
647 // Services provided by the Virtual Machine Platform optional feature (other optional features may provide these services as
648 // well). Installing this component will require a reboot.
649 WSLC_COMPONENT_FLAG_VIRTUAL_MACHINE_PLATFORM = 1,
650 // The WSL runtime package, at an appropriate version to provide support for WSLC.
651 WSLC_COMPONENT_FLAG_WSL_PACKAGE = 2,
652 // Set if the WSLC SDK itself needs to be updated.
653 WSLC_COMPONENT_FLAG_SDK_NEEDS_UPDATE = 4,
654 } WslcComponentFlags;
655
656 DEFINE_ENUM_FLAG_OPERATORS(WslcComponentFlags);
657
658 STDAPI WslcGetMissingComponents(_Out_ WslcComponentFlags* missingComponents);
659
660 typedef struct WslcVersion
661 {
662 uint32_t major;
663 uint32_t minor;
664 uint32_t revision;
665 } WslcVersion;
666 STDAPI WslcGetVersion(_Out_writes_(1) WslcVersion* version);
667
668 typedef __callback void(CALLBACK* WslcInstallCallback)(
669 _In_ WslcComponentFlags component, _In_ uint32_t progressSteps, _In_ uint32_t totalSteps, _In_opt_ PVOID context);
670
671 typedef enum WslcInstallOptions
672 {
673 WSLC_INSTALL_OPTION_NONE = 0,
674 // Allows components to be reinstalled.
675 WSLC_INSTALL_OPTION_REPAIR = 1,
676 } WslcInstallOptions;
677
678 DEFINE_ENUM_FLAG_OPERATORS(WslcInstallOptions);
679
680 // Callbacks will only be made for components that are actively installed by this call.
681 // The list of required components can be acquired prior to this call with `WslcGetMissingComponents`.
682 STDAPI WslcInstallWithDependencies(
683 _In_ WslcComponentFlags components, _In_ WslcInstallOptions options, _In_opt_ WslcInstallCallback progressCallback, _In_opt_ PVOID context);
684
685 EXTERN_C_END