| 1 | /*++ |
| 2 | |
| 3 | Copyright (c) Microsoft. All rights reserved. |
| 4 | |
| 5 | Module Name: |
| 6 | |
| 7 | WSLCProcess.cpp |
| 8 | |
| 9 | Abstract: |
| 10 | |
| 11 | Contains the implementation of WSLCProcess. |
| 12 | |
| 13 | --*/ |
| 14 | |
| 15 | #include "precomp.h" |
| 16 | #include "WSLCProcess.h" |
| 17 | #include "WSLCVirtualMachine.h" |
| 18 | #include "APICompat.h" |
| 19 | |
| 20 | using wsl::windows::service::wslc::WSLCProcess; |
| 21 | namespace apicompat = wsl::windows::common::apicompat; |
| 22 | |
| 23 | WSLCProcess::WSLCProcess(std::shared_ptr<WSLCProcessControl> Control, std::unique_ptr<WSLCProcessIO>&& Io, WSLCProcessFlags Flags) : |
| 24 | m_control(std::move(Control)), m_io(std::move(Io)), m_flags(Flags) |
| 25 | { |
| 26 | } |
| 27 | |
| 28 | HRESULT WSLCProcess::Signal(int Signal) |
| 29 | try |
| 30 | { |
| 31 | m_control->Signal(Signal); |
| 32 | return S_OK; |
| 33 | } |
| 34 | CATCH_RETURN(); |
| 35 | |
| 36 | HRESULT WSLCProcess::GetExitEvent(HANDLE* Event) |
| 37 | try |
| 38 | { |
| 39 | RETURN_HR_IF_NULL(E_POINTER, Event); |
| 40 | |
| 41 | *Event = wsl::windows::common::wslutil::DuplicateHandle(m_control->GetExitEvent().get(), SYNCHRONIZE, FALSE); |
| 42 | return S_OK; |
| 43 | } |
| 44 | CATCH_RETURN(); |
| 45 | |
| 46 | HRESULT WSLCProcess::GetStdHandle(WSLCFD Fd, WSLCHandle* Handle) |
| 47 | try |
| 48 | { |
| 49 | RETURN_HR_IF_NULL(E_POINTER, Handle); |
| 50 | RETURN_HR_IF_MSG(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), !m_io, "Process IO not attached"); |
| 51 | |
| 52 | auto typedHandle = m_io->OpenFd(Fd); |
| 53 | |
| 54 | RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), !typedHandle.is_valid()); |
| 55 | |
| 56 | DWORD Access = SYNCHRONIZE; |
| 57 | |
| 58 | WI_SetFlagIf(Access, GENERIC_WRITE, Fd == WSLCFDTty || Fd == WSLCFDStdin); |
| 59 | WI_SetFlagIf(Access, GENERIC_READ, Fd == WSLCFDStdout || Fd == WSLCFDStderr || Fd == WSLCFDTty); |
| 60 | |
| 61 | *Handle = common::wslutil::ToCOMOutputHandle(typedHandle.get(), Access, typedHandle.Type); |
| 62 | |
| 63 | WSL_LOG( |
| 64 | "GetStdHandle", |
| 65 | TraceLoggingValue(static_cast<int>(Fd), "fd"), |
| 66 | TraceLoggingValue(typedHandle.get(), "handle"), |
| 67 | TraceLoggingValue(static_cast<int>(Handle->Type), "type")); |
| 68 | |
| 69 | return S_OK; |
| 70 | } |
| 71 | CATCH_RETURN(); |
| 72 | |
| 73 | HRESULT WSLCProcess::GetFlags(WSLCProcessFlags* Flags) |
| 74 | try |
| 75 | { |
| 76 | RETURN_HR_IF_NULL(E_POINTER, Flags); |
| 77 | |
| 78 | *Flags = m_flags; |
| 79 | return S_OK; |
| 80 | } |
| 81 | CATCH_RETURN(); |
| 82 | |
| 83 | wsl::windows::common::io::HandleWrapper WSLCProcess::GetStdHandle(int Index) |
| 84 | { |
| 85 | THROW_WIN32_IF(ERROR_INVALID_STATE, !m_io); |
| 86 | |
| 87 | return std::move(m_io->OpenFd(Index).Handle); |
| 88 | } |
| 89 | |
| 90 | HANDLE WSLCProcess::GetExitEvent() |
| 91 | { |
| 92 | return m_control->GetExitEvent().get(); |
| 93 | } |
| 94 | |
| 95 | HRESULT WSLCProcess::GetPid(int* Pid) |
| 96 | try |
| 97 | { |
| 98 | RETURN_HR_IF_NULL(E_POINTER, Pid); |
| 99 | |
| 100 | *Pid = m_control->GetPid(); |
| 101 | return S_OK; |
| 102 | } |
| 103 | CATCH_RETURN(); |
| 104 | |
| 105 | int WSLCProcess::GetPid() const |
| 106 | { |
| 107 | return m_control->GetPid(); |
| 108 | } |
| 109 | |
| 110 | HRESULT WSLCProcess::GetState(WSLCProcessState* State, int* Code) |
| 111 | try |
| 112 | { |
| 113 | RETURN_HR_IF_NULL(E_POINTER, State); |
| 114 | RETURN_HR_IF_NULL(E_POINTER, Code); |
| 115 | |
| 116 | std::tie(*State, *Code) = m_control->GetState(); |
| 117 | return S_OK; |
| 118 | } |
| 119 | CATCH_RETURN(); |
| 120 | |
| 121 | HRESULT WSLCProcess::ResizeTty(ULONG Rows, ULONG Columns) |
| 122 | try |
| 123 | { |
| 124 | m_control->ResizeTty(Rows, Columns); |
| 125 | return S_OK; |
| 126 | } |
| 127 | CATCH_RETURN(); |
| 128 | |
| 129 | HRESULT WSLCProcess::GetStdHandle(WSLCFD Fd, WSLCCompatHandle* Handle) |
| 130 | try |
| 131 | { |
| 132 | RETURN_HR_IF_NULL(E_POINTER, Handle); |
| 133 | |
| 134 | WSLCHandle handle{}; |
| 135 | RETURN_IF_FAILED(GetStdHandle(Fd, &handle)); |
| 136 | |
| 137 | *Handle = apicompat::Convert(handle); |
| 138 | return S_OK; |
| 139 | } |
| 140 | CATCH_RETURN(); |