GuestProcessImpl.h revision ed9d3db07648c7e3a979105c15ad752ee9ea18de
6eb6d0439d67fd4833f1d058b63bc9a56277b0b2vboxsync
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync/* $Id$ */
6eb6d0439d67fd4833f1d058b63bc9a56277b0b2vboxsync/** @file
6eb6d0439d67fd4833f1d058b63bc9a56277b0b2vboxsync * VirtualBox Main - XXX.
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync */
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync
6eb6d0439d67fd4833f1d058b63bc9a56277b0b2vboxsync/*
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync * Copyright (C) 2012 Oracle Corporation
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync *
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync * available from http://www.virtualbox.org. This file is free software;
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync * you can redistribute it and/or modify it under the terms of the GNU
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync * General Public License (GPL) as published by the Free Software
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync */
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync#ifndef ____H_GUESTPROCESSIMPL
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync#define ____H_GUESTPROCESSIMPL
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync#include "VirtualBoxBase.h"
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync#include "GuestCtrlImplPrivate.h"
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync
667f741ffdced56a2059511ce99372ebdd62a115vboxsyncclass Console;
667f741ffdced56a2059511ce99372ebdd62a115vboxsyncclass GuestSession;
667f741ffdced56a2059511ce99372ebdd62a115vboxsync
667f741ffdced56a2059511ce99372ebdd62a115vboxsync/**
667f741ffdced56a2059511ce99372ebdd62a115vboxsync * TODO
667f741ffdced56a2059511ce99372ebdd62a115vboxsync */
667f741ffdced56a2059511ce99372ebdd62a115vboxsyncclass ATL_NO_VTABLE GuestProcess :
667f741ffdced56a2059511ce99372ebdd62a115vboxsync public VirtualBoxBase,
667f741ffdced56a2059511ce99372ebdd62a115vboxsync VBOX_SCRIPTABLE_IMPL(IGuestProcess)
667f741ffdced56a2059511ce99372ebdd62a115vboxsync{
667f741ffdced56a2059511ce99372ebdd62a115vboxsyncpublic:
667f741ffdced56a2059511ce99372ebdd62a115vboxsync /** @name COM and internal init/term/mapping cruft.
667f741ffdced56a2059511ce99372ebdd62a115vboxsync * @{ */
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT(GuestProcess, IGuestProcess)
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync DECLARE_NOT_AGGREGATABLE(GuestProcess)
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync DECLARE_PROTECT_FINAL_CONSTRUCT()
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync BEGIN_COM_MAP(GuestProcess)
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync VBOX_DEFAULT_INTERFACE_ENTRIES(IGuestProcess)
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync COM_INTERFACE_ENTRY(IProcess)
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync END_COM_MAP()
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync DECLARE_EMPTY_CTOR_DTOR(GuestProcess)
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync int init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, const GuestProcessInfo &aProcInfo);
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync void uninit(void);
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync HRESULT FinalConstruct(void);
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync void FinalRelease(void);
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync /** @} */
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync /** @name IProcess interface.
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync * @{ */
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync STDMETHOD(COMGETTER(Arguments))(ComSafeArrayOut(BSTR, aArguments));
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync STDMETHOD(COMGETTER(Environment))(ComSafeArrayOut(BSTR, aEnvironment));
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync STDMETHOD(COMGETTER(ExecutablePath))(BSTR *aExecutablePath);
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync STDMETHOD(COMGETTER(ExitCode))(LONG *aExitCode);
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync STDMETHOD(COMGETTER(Pid))(ULONG *aPID);
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync STDMETHOD(COMGETTER(Status))(ProcessStatus_T *aStatus);
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync
18470279db8a9fdd714617adbe1aa8b63cc80aeevboxsync STDMETHOD(Read)(ULONG aHandle, ULONG aSize, ULONG aTimeoutMS, ComSafeArrayOut(BYTE, aData));
STDMETHOD(Terminate)(void);
STDMETHOD(WaitFor)(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitResult_T *aReason);
STDMETHOD(Write)(ULONG aHandle, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten);
/** @} */
public:
/** @name Public internal methods.
* @{ */
int callbackDispatcher(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData);
inline bool callbackExists(ULONG uContextID);
void close(void);
bool isReady(void);
ULONG getPID(void) { return mData.mPID; }
int readData(ULONG uHandle, ULONG uSize, ULONG uTimeoutMS, BYTE *pbData, size_t cbData);
int startProcess(void);
int startProcessAsync(void);
int terminateProcess(void);
int waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestProcessWaitResult &guestResult);
HRESULT waitResultToErrorEx(const GuestProcessWaitResult &waitResult, bool fLog);
int writeData(ULONG uHandle, BYTE const *pbData, size_t cbData, ULONG uTimeoutMS, ULONG *puWritten);
/** @} */
protected:
/** @name Protected internal methods.
* @{ */
inline int callbackAdd(GuestCtrlCallback *pCallback, ULONG *puContextID);
inline int callbackRemove(ULONG uContextID);
int onGuestDisconnected(GuestCtrlCallback *pCallback, PCALLBACKDATACLIENTDISCONNECTED pData);
int onProcessInputStatus(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECINSTATUS pData);
int onProcessStatusChange(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECSTATUS pData);
int onProcessOutput(GuestCtrlCallback *pCallback, PCALLBACKDATAEXECOUT pData);
int prepareExecuteEnv(const char *pszEnv, void **ppvList, ULONG *pcbList, ULONG *pcEnvVars);
int sendCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms);
int signalWaiters(ProcessWaitResult enmWaitResult, int rc = VINF_SUCCESS);
static DECLCALLBACK(int) startProcessThread(RTTHREAD Thread, void *pvUser);
/** @} */
private:
struct Data
{
/** Pointer to parent session. */
GuestSession *mParent;
/** Pointer to the console object. Needed
* for HGCM (VMMDev) communication. */
Console *mConsole;
/** All related callbacks to this process. */
GuestCtrlCallbacks mCallbacks;
/** The process start information. */
GuestProcessInfo mProcess;
/** Exit code if process has been terminated. */
LONG mExitCode;
/** PID reported from the guest. */
ULONG mPID;
/** Internal, host-side process ID. */
ULONG mProcessID;
/** The current process status. */
ProcessStatus_T mStatus;
/** Flag indicating whether the process has been started
* so that it can't be started a second time. */
bool mStarted;
/** The next upcoming context ID. */
ULONG mNextContextID;
/** How many waiters? At the moment there can only
* be one. */
uint32_t mWaitCount;
/** The actual process event for doing the waits.
* At the moment we only support one wait a time. */
GuestProcessEvent *mWaitEvent;
} mData;
};
#endif /* !____H_GUESTPROCESSIMPL */