| 1 | /*++ |
| 2 | |
| 3 | Copyright (c) Microsoft. All rights reserved. |
| 4 | |
| 5 | Module Name: |
| 6 | |
| 7 | Process.h |
| 8 | |
| 9 | Abstract: |
| 10 | |
| 11 | This file contains the definition of the WinRT wrapper for the WSLC SDK Process class. |
| 12 | --*/ |
| 13 | |
| 14 | #pragma once |
| 15 | #include "Microsoft.WSL.Containers.Process.g.h" |
| 16 | #include "Helpers.h" |
| 17 | |
| 18 | namespace winrt::Microsoft::WSL::Containers::implementation { |
| 19 | |
| 20 | struct Process : ProcessT<Process> |
| 21 | { |
| 22 | Process() = default; |
| 23 | Process(winrt::Microsoft::WSL::Containers::ProcessSettings const& settings); // For the init process |
| 24 | Process(winrt::Microsoft::WSL::Containers::Container const& container, winrt::Microsoft::WSL::Containers::ProcessSettings const& settings); |
| 25 | // Package-internal: creates a Process with a fixed output mode but no ProcessSettings struct. |
| 26 | // Used for containers opened via OpenContainer (SetInitProcessOutputMode and InitProcess lazy-fetch paths). |
| 27 | explicit Process(winrt::Microsoft::WSL::Containers::ProcessOutputMode outputMode); |
| 28 | |
| 29 | void Start(); |
| 30 | uint32_t Pid(); |
| 31 | winrt::Microsoft::WSL::Containers::ProcessState State(); |
| 32 | int32_t ExitCode(); |
| 33 | void Signal(winrt::Microsoft::WSL::Containers::Signal const& signal); |
| 34 | winrt::Windows::Storage::Streams::IInputStream GetOutputStream(winrt::Microsoft::WSL::Containers::ProcessOutputHandle const& outputHandle); |
| 35 | winrt::Windows::Storage::Streams::IOutputStream GetInputStream(); |
| 36 | winrt::event_token OutputReceived(winrt::Microsoft::WSL::Containers::ProcessOutputHandler const& handler); |
| 37 | void OutputReceived(winrt::event_token const& token) noexcept; |
| 38 | winrt::event_token ErrorReceived(winrt::Microsoft::WSL::Containers::ProcessOutputHandler const& handler); |
| 39 | void ErrorReceived(winrt::event_token const& token) noexcept; |
| 40 | winrt::event_token Exited(winrt::Microsoft::WSL::Containers::ProcessExitHandler const& handler); |
| 41 | void Exited(winrt::event_token const& token) noexcept; |
| 42 | |
| 43 | void Close(); |
| 44 | static void final_release(std::unique_ptr<Process> self); |
| 45 | |
| 46 | WslcProcess ToHandle(); |
| 47 | ProcessOutputMode OutputMode(); |
| 48 | void AttachHandle(WslcProcess handle); |
| 49 | // Returns the WslcProcessCallbacks struct pointing to the static callbacks with 'this' as context. |
| 50 | // Only meaningful when OutputMode is Event; the callbacks fire into m_outputReceivedEvent etc. |
| 51 | WslcProcessCallbacks GetEventCallbacks() const noexcept; |
| 52 | |
| 53 | private: |
| 54 | void EnsureStarted() const; |
| 55 | void EnsureNotStarted() const; |
| 56 | void EnsureCanStart() const; |
| 57 | |
| 58 | void ApplyCallbacksToSettings(); |
| 59 | void StartWaitingForExit(); |
| 60 | winrt::Windows::Foundation::IAsyncAction StartWaitingForExitAsync(); |
| 61 | |
| 62 | static void CALLBACK OutputCallback( |
| 63 | WslcProcessIOHandle ioHandle, _In_reads_bytes_(dataBytes) const BYTE* data, _In_ uint32_t dataBytes, _In_opt_ PVOID context) noexcept; |
| 64 | static void CALLBACK ExitCallback(INT32 exitCode, _In_opt_ PVOID context) noexcept; |
| 65 | |
| 66 | // Only kept until Start() is called |
| 67 | winrt::Microsoft::WSL::Containers::Container m_container{nullptr}; |
| 68 | winrt::Microsoft::WSL::Containers::ProcessSettings m_settings{nullptr}; |
| 69 | |
| 70 | winrt::Microsoft::WSL::Containers::ProcessOutputMode m_outputMode{winrt::Microsoft::WSL::Containers::ProcessOutputMode::Discard}; |
| 71 | |
| 72 | winrt::Windows::Foundation::IAsyncAction m_waitForExitAction{nullptr}; |
| 73 | |
| 74 | // For output mode Event |
| 75 | winrt::event<winrt::Microsoft::WSL::Containers::ProcessOutputHandler> m_outputReceivedEvent; |
| 76 | winrt::event<winrt::Microsoft::WSL::Containers::ProcessOutputHandler> m_errorReceivedEvent; |
| 77 | winrt::event<winrt::Microsoft::WSL::Containers::ProcessExitHandler> m_exitedEvent; |
| 78 | |
| 79 | // Releasing the process handle will disconnect the callbacks. |
| 80 | // Keep this at the end so that it is released first, ensuring the events aren't destroyed while they may still be signaled. |
| 81 | wil::unique_any<WslcProcess, decltype(&WslcReleaseProcess), &WslcReleaseProcess> m_process{nullptr}; |
| 82 | }; |
| 83 | |
| 84 | } // namespace winrt::Microsoft::WSL::Containers::implementation |
| 85 | |
| 86 | DEFINE_TYPE_HELPERS(Process); |