VirtualBox

source: vbox/trunk/src/VBox/Main/include/GuestProcessImpl.h@ 92404

Last change on this file since 92404 was 91312, checked in by vboxsync, 3 years ago

Main: bugref:1909: Prepared the API translation engine to using in ExtPacks and VBoxManage. Added using API translation engine in ExtPacks. Allowed VBox compilation with NLS enabled and GUI disabled. Allowed ExtPacks only compilation with NLS translation enabled.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 KB
Line 
1/* $Id: GuestProcessImpl.h 91312 2021-09-20 11:06:57Z vboxsync $ */
2/** @file
3 * VirtualBox Main - Guest process handling implementation.
4 */
5
6/*
7 * Copyright (C) 2012-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef MAIN_INCLUDED_GuestProcessImpl_h
19#define MAIN_INCLUDED_GuestProcessImpl_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include "GuestCtrlImplPrivate.h"
25#include "GuestProcessWrap.h"
26
27#include <iprt/cpp/utils.h>
28
29class Console;
30class GuestSession;
31class GuestProcessStartTask;
32
33/**
34 * Class for handling a guest process.
35 */
36class ATL_NO_VTABLE GuestProcess :
37 public GuestProcessWrap,
38 public GuestObject
39{
40public:
41 /** @name COM and internal init/term/mapping cruft.
42 * @{ */
43 DECLARE_COMMON_CLASS_METHODS(GuestProcess)
44
45 int init(Console *aConsole, GuestSession *aSession, ULONG aObjectID,
46 const GuestProcessStartupInfo &aProcInfo, const GuestEnvironment *pBaseEnv);
47 void uninit(void);
48 HRESULT FinalConstruct(void);
49 void FinalRelease(void);
50 /** @} */
51
52public:
53 /** @name Implemented virtual methods from GuestObject.
54 * @{ */
55 int i_callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
56 int i_onUnregister(void);
57 int i_onSessionStatusChange(GuestSessionStatus_T enmSessionStatus);
58 /** @} */
59
60public:
61 /** @name Public internal methods.
62 * @{ */
63 inline int i_checkPID(uint32_t uPID);
64 int i_readData(uint32_t uHandle, uint32_t uSize, uint32_t uTimeoutMS, void *pvData, size_t cbData, uint32_t *pcbRead, int *pGuestRc);
65 int i_startProcess(uint32_t cMsTimeout, int *pGuestRc);
66 int i_startProcessInner(uint32_t cMsTimeout, AutoWriteLock &rLock, GuestWaitEvent *pEvent, int *pGuestRc);
67 int i_startProcessAsync(void);
68 int i_terminateProcess(uint32_t uTimeoutMS, int *pGuestRc);
69 ProcessWaitResult_T i_waitFlagsToResult(uint32_t fWaitFlags);
70 int i_waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, ProcessWaitResult_T &waitResult, int *pGuestRc);
71 int i_waitForInputNotify(GuestWaitEvent *pEvent, uint32_t uHandle, uint32_t uTimeoutMS, ProcessInputStatus_T *pInputStatus, uint32_t *pcbProcessed);
72 int i_waitForOutput(GuestWaitEvent *pEvent, uint32_t uHandle, uint32_t uTimeoutMS, void* pvData, size_t cbData, uint32_t *pcbRead);
73 int i_waitForStatusChange(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, ProcessStatus_T *pProcessStatus, int *pGuestRc);
74 int i_writeData(uint32_t uHandle, uint32_t uFlags, void *pvData, size_t cbData, uint32_t uTimeoutMS, uint32_t *puWritten, int *pGuestRc);
75 /** @} */
76
77 /** @name Static internal methods.
78 * @{ */
79 static Utf8Str i_guestErrorToString(int rcGuest, const char *pcszWhat);
80 static bool i_isGuestError(int guestRc);
81 static ProcessWaitResult_T i_waitFlagsToResultEx(uint32_t fWaitFlags, ProcessStatus_T oldStatus, ProcessStatus_T newStatus, uint32_t uProcFlags, uint32_t uProtocol);
82#if 0 /* unused */
83 static bool i_waitResultImpliesEx(ProcessWaitResult_T waitResult, ProcessStatus_T procStatus, uint32_t uProtocol);
84#endif
85 /** @} */
86
87protected:
88 /** @name Protected internal methods.
89 * @{ */
90 inline bool i_isAlive(void);
91 inline bool i_hasEnded(void);
92 int i_onGuestDisconnected(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
93 int i_onProcessInputStatus(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
94 int i_onProcessNotifyIO(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
95 int i_onProcessStatusChange(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
96 int i_onProcessOutput(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
97 int i_prepareExecuteEnv(const char *pszEnv, void **ppvList, ULONG *pcbList, ULONG *pcEnvVars);
98 int i_setProcessStatus(ProcessStatus_T procStatus, int procRc);
99 static int i_startProcessThreadTask(GuestProcessStartTask *pTask);
100 /** @} */
101
102private:
103 /** Wrapped @name IProcess properties.
104 * @{ */
105 HRESULT getArguments(std::vector<com::Utf8Str> &aArguments);
106 HRESULT getEnvironment(std::vector<com::Utf8Str> &aEnvironment);
107 HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
108 HRESULT getExecutablePath(com::Utf8Str &aExecutablePath);
109 HRESULT getExitCode(LONG *aExitCode);
110 HRESULT getName(com::Utf8Str &aName);
111 HRESULT getPID(ULONG *aPID);
112 HRESULT getStatus(ProcessStatus_T *aStatus);
113 /** @} */
114
115 /** Wrapped @name IProcess methods.
116 * @{ */
117 HRESULT waitFor(ULONG aWaitFor,
118 ULONG aTimeoutMS,
119 ProcessWaitResult_T *aReason);
120 HRESULT waitForArray(const std::vector<ProcessWaitForFlag_T> &aWaitFor,
121 ULONG aTimeoutMS,
122 ProcessWaitResult_T *aReason);
123 HRESULT read(ULONG aHandle,
124 ULONG aToRead,
125 ULONG aTimeoutMS,
126 std::vector<BYTE> &aData);
127 HRESULT write(ULONG aHandle,
128 ULONG aFlags,
129 const std::vector<BYTE> &aData,
130 ULONG aTimeoutMS,
131 ULONG *aWritten);
132 HRESULT writeArray(ULONG aHandle,
133 const std::vector<ProcessInputFlag_T> &aFlags,
134 const std::vector<BYTE> &aData,
135 ULONG aTimeoutMS,
136 ULONG *aWritten);
137 HRESULT terminate(void);
138 /** @} */
139
140 /**
141 * This can safely be used without holding any locks.
142 * An AutoCaller suffices to prevent it being destroy while in use and
143 * internally there is a lock providing the necessary serialization.
144 */
145 const ComObjPtr<EventSource> mEventSource;
146
147 struct Data
148 {
149 /** The process startup information. */
150 GuestProcessStartupInfo mProcess;
151 /** Reference to the immutable session base environment. NULL if the
152 * environment feature isn't supported.
153 * @remarks If there is proof that the uninit order of GuestSession and
154 * this class is what GuestObjectBase claims, then this isn't
155 * strictly necessary. */
156 GuestEnvironment const *mpSessionBaseEnv;
157 /** Exit code if process has been terminated. */
158 LONG mExitCode;
159 /** PID reported from the guest.
160 * Note: This is *not* the internal object ID! */
161 ULONG mPID;
162 /** The current process status. */
163 ProcessStatus_T mStatus;
164 /** The last returned process status
165 * returned from the guest side. */
166 int mLastError;
167
168 Data(void) : mpSessionBaseEnv(NULL)
169 { }
170 ~Data(void)
171 {
172 if (mpSessionBaseEnv)
173 {
174 mpSessionBaseEnv->releaseConst();
175 mpSessionBaseEnv = NULL;
176 }
177 }
178 } mData;
179
180 friend class GuestProcessStartTask;
181};
182
183/**
184 * Guest process tool wait flags.
185 */
186/** No wait flags specified; wait until process terminates.
187 * The maximum waiting time is set in the process' startup
188 * info. */
189#define GUESTPROCESSTOOL_WAIT_FLAG_NONE 0
190/** Wait until next stream block from stdout has been
191 * read in completely, then return.
192 */
193#define GUESTPROCESSTOOL_WAIT_FLAG_STDOUT_BLOCK RT_BIT(0)
194
195/**
196 * Structure for keeping a VBoxService toolbox tool's error info around.
197 */
198struct GuestProcessToolErrorInfo
199{
200 /** Return code from the guest side for executing the process tool. */
201 int rcGuest;
202 /** The process tool's returned exit code. */
203 int32_t iExitCode;
204};
205
206/**
207 * Internal class for handling the BusyBox-like tools built into VBoxService
208 * on the guest side. It's also called the VBoxService Toolbox (tm).
209 *
210 * Those initially were necessary to guarantee execution of commands (like "ls", "cat")
211 * under the behalf of a certain guest user.
212 *
213 * This class essentially helps to wrap all the gory details like process creation,
214 * information extraction and maintaining the overall status.
215 */
216class GuestProcessTool
217{
218public:
219 DECLARE_TRANSLATE_METHODS(GuestProcessTool)
220
221 GuestProcessTool(void);
222
223 virtual ~GuestProcessTool(void);
224
225public:
226
227 int init(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, bool fAsync, int *pGuestRc);
228
229 void uninit(void);
230
231 int getCurrentBlock(uint32_t uHandle, GuestProcessStreamBlock &strmBlock);
232
233 int getRc(void) const;
234
235 GuestProcessStream &getStdOut(void) { return mStdOut; }
236
237 GuestProcessStream &getStdErr(void) { return mStdErr; }
238
239 int wait(uint32_t fToolWaitFlags, int *pGuestRc);
240
241 int waitEx(uint32_t fToolWaitFlags, GuestProcessStreamBlock *pStreamBlock, int *pGuestRc);
242
243 bool isRunning(void);
244
245 bool isTerminatedOk(void);
246
247 int getTerminationStatus(int32_t *piExitCode = NULL);
248
249 int terminate(uint32_t uTimeoutMS, int *pGuestRc);
250
251public:
252
253 /** Wrapped @name Static run methods.
254 * @{ */
255 static int run(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, int *pGuestRc);
256
257 static int runErrorInfo(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo, GuestProcessToolErrorInfo &errorInfo);
258
259 static int runEx(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo,
260 GuestCtrlStreamObjects *pStrmOutObjects, uint32_t cStrmOutObjects, int *pGuestRc);
261
262 static int runExErrorInfo(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo,
263 GuestCtrlStreamObjects *pStrmOutObjects, uint32_t cStrmOutObjects, GuestProcessToolErrorInfo &errorInfo);
264 /** @} */
265
266 /** Wrapped @name Static exit code conversion methods.
267 * @{ */
268 static int exitCodeToRc(const GuestProcessStartupInfo &startupInfo, int32_t iExitCode);
269
270 static int exitCodeToRc(const char *pszTool, int32_t iExitCode);
271 /** @} */
272
273 /** Wrapped @name Static guest error conversion methods.
274 * @{ */
275 static Utf8Str guestErrorToString(const char *pszTool, const GuestErrorInfo& guestErrorInfo);
276 /** @} */
277
278protected:
279
280 /** Pointer to session this toolbox object is bound to. */
281 ComObjPtr<GuestSession> pSession;
282 /** Pointer to process object this toolbox object is bound to. */
283 ComObjPtr<GuestProcess> pProcess;
284 /** The toolbox' startup info. */
285 GuestProcessStartupInfo mStartupInfo;
286 /** Stream object for handling the toolbox' stdout data. */
287 GuestProcessStream mStdOut;
288 /** Stream object for handling the toolbox' stderr data. */
289 GuestProcessStream mStdErr;
290};
291
292#endif /* !MAIN_INCLUDED_GuestProcessImpl_h */
293
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette