VirtualBox

Changeset 42214 in vbox


Ignore:
Timestamp:
Jul 18, 2012 6:02:58 PM (13 years ago)
Author:
vboxsync
Message:

Guest Control 2.0: Update.

Location:
trunk/src/VBox/Main
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h

    r42194 r42214  
    3737
    3838
    39 /* Builds a context ID out of the session ID, process ID and an
    40  * increasing count. */
     39/** Maximum number of guest sessions a VM can have. */
     40#define VBOX_GUESTCTRL_MAX_SESSIONS     255
     41/** Maximum of guest processes a guest session can have. */
     42#define VBOX_GUESTCTRL_MAX_PROCESSES    255
     43/** Maximum of callback contexts a guest process can have. */
     44#define VBOX_GUESTCTRL_MAX_CONTEXTS     _64K - 1
     45
     46/** Builds a context ID out of the session ID, process ID and an
     47 *  increasing count. */
    4148#define VBOX_GUESTCTRL_CONTEXTID_MAKE(uSession, uProcess, uCount) \
    4249    (  (uint32_t)((uSession) &   0xff) << 24 \
     
    4451     | (uint32_t)((uCount)   & 0xffff)       \
    4552    )
     53/** Gets the session ID out of a context ID. */
     54#define VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID) \
     55    ((uContextID) >> 24)
     56/** Gets the process ID out of a context ID. */
     57#define VBOX_GUESTCTRL_CONTEXTID_GET_PROCESS(uContextID) \
     58    (((uContextID) >> 16) & 0xff)
     59/** Gets the conext count of a process out of a context ID. */
     60#define VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID) \
     61    ((uContextID) & 0xffff)
    4662
    4763
     
    6783public:
    6884
     85    int Cancel(void);
     86
     87    bool Canceled(void);
     88
    6989    int Init(eVBoxGuestCtrlCallbackType enmType);
    7090
     
    7393    eVBoxGuestCtrlCallbackType Type(void);
    7494
    75     int Wait(RTMSINTERVAL timeoutMS);
     95    int Wait(ULONG uTimeoutMS);
    7696
    7797protected:
     
    80100    eVBoxGuestCtrlCallbackType  mType;
    81101    /** Callback flags. */
    82     uint32_t                    mFlags;
     102    uint32_t                    uFlags;
     103    /** Was the callback canceled? */
     104    bool                        fCanceled;
    83105    /** Pointer to user-supplied data. */
    84106    void                       *pvData;
     
    86108    size_t                      cbData;
    87109    /** The event semaphore triggering the*/
    88     RTSEMEVENT                  mEventSem;
     110    RTSEMEVENT                  hEventSem;
    89111    /** Extended error information, if any. */
    90112    ErrorInfo                   mErrorInfo;
    91113};
    92 typedef std::map <uint32_t, GuestCtrlCallback> GuestCtrlCallbacks;
     114typedef std::map < uint32_t, GuestCtrlCallback* > GuestCtrlCallbacks;
    93115
    94116/**
     
    112134public:
    113135
    114     int BuildEnvironmentBlock(void **ppvEnv, uint32_t *pcbEnv, uint32_t *pcEnvVars);
     136    int BuildEnvironmentBlock(void **ppvEnv, size_t *pcbEnv, uint32_t *pcEnvVars);
    115137
    116138    void Clear(void);
     
    144166protected:
    145167
    146     int appendToEnvBlock(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnvVars);
     168    int appendToEnvBlock(const char *pszEnv, void **ppvList, size_t *pcbList, uint32_t *pcEnvVars);
    147169
    148170protected:
  • trunk/src/VBox/Main/include/GuestImpl.h

    r42160 r42214  
    205205    /** @name Public internal methods.
    206206     * @{ */
     207    int         dispatchToSession(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData);
    207208    Console    *getConsole(void) { return mParent; }
    208209    int         sessionClose(ComObjPtr<GuestSession> pSession);
  • trunk/src/VBox/Main/include/GuestProcessImpl.h

    r42162 r42214  
    4545    DECLARE_EMPTY_CTOR_DTOR(GuestProcess)
    4646
    47     int     init(Console *aConsole, GuestSession *aSession, uint32_t aProcessID, const GuestProcessInfo &aProcInfo);
     47    int     init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, const GuestProcessInfo &aProcInfo);
    4848    void    uninit(void);
    4949    HRESULT FinalConstruct(void);
     
    6969    /** @name Public internal methods.
    7070     * @{ */
    71     int callbackAdd(const GuestCtrlCallback& theCallback, uint32_t *puContextID);
    72     bool callbackExists(uint32_t uContextID);
     71    int callbackAdd(GuestCtrlCallback *pCallback, ULONG *puContextID);
     72    int callbackDispatcher(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData);
     73    bool callbackExists(ULONG uContextID);
    7374    bool isReady(void);
    74     int prepareExecuteEnv(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnvVars);
    75     int readData(ULONG aHandle, ULONG aSize, ULONG aTimeoutMS, ComSafeArrayOut(BYTE, aData));
     75    ULONG getPID(void) { return mData.mPID; }
     76    int onGuestDisconnected(void);
     77    int onProcessInputStatus(uint32_t uStatus, uint32_t uFlags, uint32_t cbDataProcessed);
     78    int onProcessStatusChange(uint32_t uStatus, uint32_t uFlags, uint32_t uPID);
     79    int onProcessOutput(uint32_t uHandle, uint32_t uFlags, void *pvData, uint32_t cbData);
     80    int prepareExecuteEnv(const char *pszEnv, void **ppvList, ULONG *pcbList, ULONG *pcEnvVars);
     81    int readData(ULONG uHandle, ULONG uSize, ULONG uTimeoutMS, BYTE *pbData, size_t cbData);
    7682    int startProcess(void);
    7783    static DECLCALLBACK(int) startProcessThread(RTTHREAD Thread, void *pvUser);
    7884    int terminateProcess(void);
    79     int waitFor(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitReason_T *aReason);
    80     int writeData(ULONG aHandle, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten);
     85    int waitFor(uint32_t fFlags, ULONG uTimeoutMS, ProcessWaitReason_T *penmReason);
     86    int writeData(ULONG uHandle, BYTE const *pbData, size_t cbData, ULONG uTimeoutMS, ULONG *puWritten);
    8187    /** @}  */
    8288
     
    99105        ULONG                    mPID;
    100106        /** Internal, host-side process ID. */
    101         uint32_t                 mProcessID;
     107        ULONG                 mProcessID;
    102108        /** The current process status. */
    103109        ProcessStatus_T          mStatus;
     
    105111        bool                     mStarted;
    106112        /** The next upcoming context ID. */
    107         uint32_t                 mNextContextID;
     113        ULONG                    mNextContextID;
     114        /** The waiting event. */
     115        RTSEMEVENT               mEvent;
    108116    } mData;
     117
     118    friend GuestSession; /* Let's be friends! */
    109119};
    110120
  • trunk/src/VBox/Main/include/GuestSessionImpl.h

    r42194 r42214  
    4848    DECLARE_EMPTY_CTOR_DTOR(GuestSession)
    4949
    50     int     init(Guest *aGuest, uint32_t aSessionID, Utf8Str aUser, Utf8Str aPassword, Utf8Str aDomain, Utf8Str aName);
     50    int     init(Guest *aGuest, ULONG aSessionID, Utf8Str aUser, Utf8Str aPassword, Utf8Str aDomain, Utf8Str aName);
    5151    void    uninit(void);
    5252    HRESULT FinalConstruct(void);
     
    113113    typedef std::vector <ComObjPtr<GuestDirectory> > SessionDirectories;
    114114    typedef std::vector <ComObjPtr<GuestFile> > SessionFiles;
    115     typedef std::map <uint32_t, ComObjPtr<GuestProcess> > SessionProcesses;
     115    /** Map of guest processes. The key specifies the internal process number.
     116     *  To retrieve the process' guest PID use the Id() method of the IProgress interface. */
     117    typedef std::map <ULONG, ComObjPtr<GuestProcess> > SessionProcesses;
    116118
    117119public:
     
    119121     * @{ */
    120122    int                     directoryClose(ComObjPtr<GuestDirectory> pDirectory);
     123    int                     dispatchToProcess(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData);
    121124    int                     fileClose(ComObjPtr<GuestFile> pFile);
    122125    const GuestCredentials &getCredentials(void);
     
    124127    int                     processClose(ComObjPtr<GuestProcess> pProcess);
    125128    int                     processCreateExInteral(GuestProcessInfo &aProcInfo, IGuestProcess **aProcess);
    126     inline bool             processExists(uint32_t uProcessID);
     129    inline bool             processExists(ULONG uProcessID, ComObjPtr<GuestProcess> *pProcess);
     130    inline int              processGetByPID(ULONG uPID, ComObjPtr<GuestProcess> *pProcess);
    127131    /** @}  */
    128132
  • trunk/src/VBox/Main/src-client/GuestCtrlImpl.cpp

    r42194 r42214  
    684684     * changes to the object state.
    685685     */
    686 #ifdef DEBUG_andy
    687     LogFlowFunc(("pvExtension=%p, u32Function=%d, pvParms=%p, cbParms=%d\n",
     686    LogFlowFunc(("pvExtension=%p, u32Function=%RU32, pvParms=%p, cbParms=%RU32\n",
    688687                 pvExtension, u32Function, pvParms, cbParms));
    689 #endif
    690688    ComObjPtr<Guest> pGuest = reinterpret_cast<Guest *>(pvExtension);
    691 
    692     int rc = VINF_SUCCESS;
     689    Assert(!pGuest.isNull());
     690
     691    /*
     692     * For guest control 2.0 using the legacy commands we need to do the following here:
     693     * - Get the callback header to access the context ID
     694     * - Get the context ID of the callback
     695     * - Extract the session ID out of the context ID
     696     * - Dispatch the whole stuff to the appropriate session (if still exists)
     697     */
     698
     699    PCALLBACKHEADER pHeader = (PCALLBACKHEADER)pvParms;
     700    AssertPtr(pHeader);
     701
     702    int rc = pGuest->dispatchToSession(pHeader->u32ContextID, u32Function, pvParms, cbParms);
     703
     704#ifdef VBOX_WITH_GUEST_CONTROL_LEGACY
     705    if (RT_SUCCESS(rc))
     706        return rc;
     707
     708    /* Legacy handling. */
    693709    switch (u32Function)
    694710    {
    695711        case GUEST_DISCONNECTED:
    696712        {
    697             //LogFlowFunc(("GUEST_DISCONNECTED\n"));
    698 
    699713            PCALLBACKDATACLIENTDISCONNECTED pCBData = reinterpret_cast<PCALLBACKDATACLIENTDISCONNECTED>(pvParms);
    700714            AssertPtr(pCBData);
     
    708722        case GUEST_EXEC_SEND_STATUS:
    709723        {
    710             //LogFlowFunc(("GUEST_EXEC_SEND_STATUS\n"));
    711 
    712724            PCALLBACKDATAEXECSTATUS pCBData = reinterpret_cast<PCALLBACKDATAEXECSTATUS>(pvParms);
    713725            AssertPtr(pCBData);
     
    721733        case GUEST_EXEC_SEND_OUTPUT:
    722734        {
    723             //LogFlowFunc(("GUEST_EXEC_SEND_OUTPUT\n"));
    724 
    725735            PCALLBACKDATAEXECOUT pCBData = reinterpret_cast<PCALLBACKDATAEXECOUT>(pvParms);
    726736            AssertPtr(pCBData);
     
    734744        case GUEST_EXEC_SEND_INPUT_STATUS:
    735745        {
    736             //LogFlowFunc(("GUEST_EXEC_SEND_INPUT_STATUS\n"));
    737 
    738746            PCALLBACKDATAEXECINSTATUS pCBData = reinterpret_cast<PCALLBACKDATAEXECINSTATUS>(pvParms);
    739747            AssertPtr(pCBData);
     
    746754
    747755        default:
    748             AssertMsgFailed(("Unknown guest control notification received, u32Function=%u\n", u32Function));
    749             rc = VERR_INVALID_PARAMETER;
     756            /* Silently ignore not implemented functions. */
     757            rc = VERR_NOT_IMPLEMENTED;
    750758            break;
    751759    }
     760#endif /* VBOX_WITH_GUEST_CONTROL_LEGACY */
    752761    return rc;
    753762}
     
    26642673/////////////////////////////////////////////////////////////////////////////
    26652674
     2675int Guest::dispatchToSession(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData)
     2676{
     2677    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
     2678    AssertReturn(cbData, VERR_INVALID_PARAMETER);
     2679
     2680    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     2681
     2682    GuestSessions::const_iterator itSession
     2683        = mData.mGuestSessions.find(VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID));
     2684    if (itSession != mData.mGuestSessions.end())
     2685    {
     2686        ComObjPtr<GuestSession> pSession(itSession->second);
     2687        Assert(!pSession.isNull());
     2688
     2689        alock.release();
     2690        return pSession->dispatchToProcess(uContextID, uFunction, pvData, cbData);
     2691    }
     2692    return VERR_NOT_FOUND;
     2693}
     2694
    26662695int Guest::sessionClose(ComObjPtr<GuestSession> pSession)
    26672696{
     
    27492778#else /* VBOX_WITH_GUEST_CONTROL */
    27502779
    2751     /* Do not allow anonymous sessions (with system rights). */
     2780    LogFlowFuncEnter();
     2781
     2782    /* Do not allow anonymous sessions (with system rights) with official API. */
    27522783    if (RT_UNLIKELY((aUser) == NULL || *(aUser) == '\0'))
    27532784        return setError(E_INVALIDARG, tr("No user name specified"));
    27542785    CheckComArgOutPointerValid(aGuestSession);
     2786    /* Rest is optional. */
    27552787
    27562788    AutoCaller autoCaller(this);
     
    27582790
    27592791    int rc = sessionCreate(aUser, aPassword, aDomain, aSessionName, aGuestSession);
    2760     return RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
     2792
     2793    /** @todo Do setError() here. */
     2794    HRESULT hr = RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
     2795    LogFlowFuncLeaveRC(hr);
     2796
     2797    return hr;
    27612798#endif /* VBOX_WITH_GUEST_CONTROL */
    27622799}
  • trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp

    r42194 r42214  
    2222#include "GuestCtrlImplPrivate.h"
    2323
     24#include <iprt/asm.h>
    2425#include <iprt/ctype.h>
    2526#ifdef DEBUG
     
    3435GuestCtrlCallback::GuestCtrlCallback(void)
    3536    : mType(VBOXGUESTCTRLCALLBACKTYPE_UNKNOWN),
     37      uFlags(0),
     38      fCanceled(false),
    3639      pvData(NULL),
    3740      cbData(0),
    38       mEventSem(NIL_RTSEMEVENT)
     41      hEventSem(NIL_RTSEMEVENT)
    3942{
    4043}
     
    4245GuestCtrlCallback::GuestCtrlCallback(eVBoxGuestCtrlCallbackType enmType)
    4346    : mType(VBOXGUESTCTRLCALLBACKTYPE_UNKNOWN),
     47      uFlags(0),
     48      fCanceled(false),
    4449      pvData(NULL),
    4550      cbData(0),
    46       mEventSem(NIL_RTSEMEVENT)
     51      hEventSem(NIL_RTSEMEVENT)
    4752{
    4853    int rc = Init(enmType);
     
    5358{
    5459    Destroy();
     60}
     61
     62int GuestCtrlCallback::Cancel(void)
     63{
     64    if (!ASMAtomicReadBool(&fCanceled))
     65    {
     66        int rc = RTSemEventSignal(hEventSem);
     67        if (RT_SUCCESS(rc))
     68            ASMAtomicXchgBool(&fCanceled, true);
     69    }
     70    return VINF_SUCCESS;
     71}
     72
     73bool GuestCtrlCallback::Canceled(void)
     74{
     75    return ASMAtomicReadBool(&fCanceled);
    5576}
    5677
     
    97118    if (RT_SUCCESS(rc))
    98119    {
    99         rc = RTSemEventCreate(&mEventSem);
     120        rc = RTSemEventCreate(&hEventSem);
    100121        if (RT_SUCCESS(rc))
    101122            mType  = enmType;
     
    114135    }
    115136    cbData = 0;
    116     if (mEventSem != NIL_RTSEMEVENT)
    117         RTSemEventDestroy(mEventSem);
     137    if (hEventSem != NIL_RTSEMEVENT)
     138        RTSemEventDestroy(hEventSem);
    118139}
    119140
     
    123144}
    124145
    125 int GuestCtrlCallback::Wait(RTMSINTERVAL timeoutMS)
    126 {
    127     Assert(mEventSem != NIL_RTSEMEVENT);
    128     return RTSemEventWait(mEventSem, timeoutMS);
     146int GuestCtrlCallback::Wait(ULONG uTimeoutMS)
     147{
     148    Assert(hEventSem != NIL_RTSEMEVENT);
     149
     150    RTMSINTERVAL msInterval = uTimeoutMS;
     151    if (!uTimeoutMS)
     152        msInterval = RT_INDEFINITE_WAIT;
     153    return RTSemEventWait(hEventSem, msInterval);
    129154}
    130155
    131156///////////////////////////////////////////////////////////////////////////////
    132157
    133 int GuestEnvironment::BuildEnvironmentBlock(void **ppvEnv, uint32_t *pcbEnv, uint32_t *pcEnvVars)
     158int GuestEnvironment::BuildEnvironmentBlock(void **ppvEnv, size_t *pcbEnv, uint32_t *pcEnvVars)
    134159{
    135160    AssertPtrReturn(ppvEnv, VERR_INVALID_POINTER);
    136161    /* Rest is optional. */
    137162
    138     uint32_t cbEnv = 0;
     163    size_t cbEnv = 0;
    139164    uint32_t cEnvVars = 0;
    140165
     
    338363 *                          stored in the environment block.
    339364 */
    340 int GuestEnvironment::appendToEnvBlock(const char *pszEnv, void **ppvList, uint32_t *pcbList, uint32_t *pcEnvVars)
     365int GuestEnvironment::appendToEnvBlock(const char *pszEnv, void **ppvList, size_t *pcbList, uint32_t *pcEnvVars)
    341366{
    342367    int rc = VINF_SUCCESS;
    343     uint32_t cchEnv = strlen(pszEnv); Assert(cchEnv >= 2);
     368    size_t cchEnv = strlen(pszEnv); Assert(cchEnv >= 2);
    344369    if (*ppvList)
    345370    {
    346         uint32_t cbNewLen = *pcbList + cchEnv + 1; /* Include zero termination. */
     371        size_t cbNewLen = *pcbList + cchEnv + 1; /* Include zero termination. */
    347372        char *pvTmp = (char *)RTMemRealloc(*ppvList, cbNewLen);
    348373        if (pvTmp == NULL)
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r42199 r42214  
    9191/////////////////////////////////////////////////////////////////////////////
    9292
    93 int GuestProcess::init(Console *aConsole, GuestSession *aSession, uint32_t aProcessID, const GuestProcessInfo &aProcInfo)
     93int GuestProcess::init(Console *aConsole, GuestSession *aSession, ULONG aProcessID, const GuestProcessInfo &aProcInfo)
    9494{
    9595    AssertPtrReturn(aSession, VERR_INVALID_POINTER);
     
    103103    mData.mConsole = aConsole;
    104104    mData.mParent = aSession;
     105    mData.mPID = 0; /* Will be assigned by the guest OS later. */
    105106    mData.mProcessID = aProcessID;
    106107    mData.mStatus = ProcessStatus_Starting;
     
    150151    ReturnComNotImplemented();
    151152#else
     153    LogFlowThisFuncEnter();
     154
    152155    AutoCaller autoCaller(this);
    153156    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     
    169172    collection.detachTo(ComSafeArrayOutArg(aArguments));
    170173
     174    LogFlowFuncLeaveRC(S_OK);
    171175    return S_OK;
    172176#endif /* VBOX_WITH_GUEST_CONTROL */
     
    178182    ReturnComNotImplemented();
    179183#else
     184    LogFlowThisFuncEnter();
     185
    180186    AutoCaller autoCaller(this);
    181187    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     
    193199    arguments.detachTo(ComSafeArrayOutArg(aEnvironment));
    194200
     201    LogFlowFuncLeaveRC(S_OK);
    195202    return S_OK;
    196203#endif /* VBOX_WITH_GUEST_CONTROL */
     
    202209    ReturnComNotImplemented();
    203210#else
     211    LogFlowThisFuncEnter();
     212
    204213    AutoCaller autoCaller(this);
    205214    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     
    209218    mData.mProcess.mCommand.cloneTo(aExecutablePath);
    210219
     220    LogFlowFuncLeaveRC(S_OK);
    211221    return S_OK;
    212222#endif /* VBOX_WITH_GUEST_CONTROL */
     
    218228    ReturnComNotImplemented();
    219229#else
     230    LogFlowThisFuncEnter();
     231
    220232    AutoCaller autoCaller(this);
    221233    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     
    225237    *aExitCode = mData.mExitCode;
    226238
     239    LogFlowFuncLeaveRC(S_OK);
    227240    return S_OK;
    228241#endif /* VBOX_WITH_GUEST_CONTROL */
     
    234247    ReturnComNotImplemented();
    235248#else
     249    LogFlowThisFuncEnter();
     250
    236251    AutoCaller autoCaller(this);
    237252    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     
    241256    *aPID = mData.mPID;
    242257
     258    LogFlowFuncLeaveRC(S_OK);
    243259    return S_OK;
    244260#endif /* VBOX_WITH_GUEST_CONTROL */
     
    250266    ReturnComNotImplemented();
    251267#else
     268    LogFlowThisFuncEnter();
     269
    252270    AutoCaller autoCaller(this);
    253271    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     
    257275    *aStatus = mData.mStatus;
    258276
     277    LogFlowFuncLeaveRC(S_OK);
    259278    return S_OK;
    260279#endif /* VBOX_WITH_GUEST_CONTROL */
     
    276295*/
    277296
    278 int GuestProcess::callbackAdd(const GuestCtrlCallback& theCallback, uint32_t *puContextID)
     297int GuestProcess::callbackAdd(GuestCtrlCallback *pCallback, ULONG *puContextID)
    279298{
    280299    const ComObjPtr<GuestSession> pSession(mData.mParent);
     
    286305    /* Create a new context ID and assign it. */
    287306    int rc = VERR_NOT_FOUND;
    288     uint32_t uNewContextID = 0;
    289     uint32_t uTries = 0;
     307    ULONG uNewContextID = 0;
     308    ULONG uTries = 0;
    290309    for (;;)
    291310    {
    292311        /* Create a new context ID ... */
    293312        uNewContextID = VBOX_GUESTCTRL_CONTEXTID_MAKE(uSessionID,
    294                                                       mData.mProcessID, ASMAtomicIncU32(&mData.mNextContextID));
     313                                                      mData.mProcessID, mData.mNextContextID++);
    295314        if (uNewContextID == UINT32_MAX)
    296             ASMAtomicUoWriteU32(&mData.mNextContextID, 0);
     315            mData.mNextContextID = 0;
    297316        /* Is the context ID already used?  Try next ID ... */
    298317        if (!callbackExists(uNewContextID))
     
    312331    {
    313332        /* Add callback with new context ID to our callback map. */
    314         mData.mCallbacks[uNewContextID] = theCallback;
     333        mData.mCallbacks[uNewContextID] = pCallback;
    315334        Assert(mData.mCallbacks.size());
    316335
     
    323342}
    324343
    325 bool GuestProcess::callbackExists(uint32_t uContextID)
     344int GuestProcess::callbackDispatcher(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData)
     345{
     346    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
     347    AssertReturn(cbData, VERR_INVALID_PARAMETER);
     348
     349    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     350
     351    GuestCtrlCallbacks::const_iterator it
     352        = mData.mCallbacks.find(VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID));
     353    if (it != mData.mCallbacks.end())
     354    {
     355        std::auto_ptr<GuestCtrlCallback> pCallback = it->second;
     356        AssertPtr(pCallback.get());
     357
     358        int rc;
     359
     360        switch (uFunction)
     361        {
     362            case GUEST_DISCONNECTED:
     363            {
     364                PCALLBACKDATACLIENTDISCONNECTED pCBData = reinterpret_cast<PCALLBACKDATACLIENTDISCONNECTED>(pvData);
     365                AssertPtr(pCBData);
     366                AssertReturn(sizeof(CALLBACKDATACLIENTDISCONNECTED) == cbData, VERR_INVALID_PARAMETER);
     367                AssertReturn(CALLBACKDATAMAGIC_CLIENT_DISCONNECTED == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
     368
     369                rc = onGuestDisconnected(); /* Affects all callbacks. */
     370                break;
     371            }
     372
     373            case GUEST_EXEC_SEND_STATUS:
     374            {
     375                PCALLBACKDATAEXECSTATUS pCBData = reinterpret_cast<PCALLBACKDATAEXECSTATUS>(pvData);
     376                AssertPtr(pCBData);
     377                AssertReturn(sizeof(CALLBACKDATAEXECSTATUS) == cbData, VERR_INVALID_PARAMETER);
     378                AssertReturn(CALLBACKDATAMAGIC_EXEC_STATUS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
     379
     380                rc = onProcessStatusChange(pCBData->u32Status, pCBData->u32Flags, pCBData->u32PID);
     381                break;
     382            }
     383
     384            case GUEST_EXEC_SEND_OUTPUT:
     385            {
     386                PCALLBACKDATAEXECOUT pCBData = reinterpret_cast<PCALLBACKDATAEXECOUT>(pvData);
     387                AssertPtr(pCBData);
     388                AssertReturn(sizeof(CALLBACKDATAEXECOUT) == cbData, VERR_INVALID_PARAMETER);
     389                AssertReturn(CALLBACKDATAMAGIC_EXEC_OUT == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
     390
     391                Assert(mData.mPID == pCBData->u32PID);
     392                rc = onProcessOutput(pCBData->u32HandleId, pCBData->u32Flags, pCBData->pvData, pCBData->cbData);
     393                break;
     394            }
     395
     396            case GUEST_EXEC_SEND_INPUT_STATUS:
     397            {
     398                PCALLBACKDATAEXECINSTATUS pCBData = reinterpret_cast<PCALLBACKDATAEXECINSTATUS>(pvData);
     399                AssertPtr(pCBData);
     400                AssertReturn(sizeof(CALLBACKDATAEXECINSTATUS) == cbData, VERR_INVALID_PARAMETER);
     401                AssertReturn(CALLBACKDATAMAGIC_EXEC_IN_STATUS == pCBData->hdr.u32Magic, VERR_INVALID_PARAMETER);
     402
     403                Assert(mData.mPID == pCBData->u32PID);
     404                rc = onProcessInputStatus(pCBData->u32Status, pCBData->u32Flags, pCBData->cbProcessed);
     405                break;
     406            }
     407
     408            default:
     409                /* Silently ignore not implemented functions. */
     410                rc = VERR_NOT_IMPLEMENTED;
     411                break;
     412        }
     413
     414        return rc;
     415    }
     416
     417    return VERR_NOT_FOUND;
     418}
     419
     420bool GuestProcess::callbackExists(ULONG uContextID)
    326421{
    327422    AssertReturn(uContextID, false);
     
    344439}
    345440
    346 int GuestProcess::readData(ULONG aHandle, ULONG aSize, ULONG aTimeoutMS, ComSafeArrayOut(BYTE, aData))
    347 {
    348     LogFlowFuncEnter();
     441int GuestProcess::onGuestDisconnected(void)
     442{
     443    LogFlowFunc(("uPID=%RU32", mData.mPID));
    349444
    350445    LogFlowFuncLeave();
     
    352447}
    353448
     449int GuestProcess::onProcessInputStatus(uint32_t uStatus, uint32_t uFlags, uint32_t cbDataProcessed)
     450{
     451    LogFlowFunc(("uPID=%RU32, uStatus=%RU32, uFlags=%RU32, cbDataProcessed=%RU32\n",
     452                 mData.mPID, uStatus, uFlags, cbDataProcessed));
     453
     454    LogFlowFuncLeave();
     455    return 0;
     456}
     457
     458int GuestProcess::onProcessStatusChange(uint32_t uStatus, uint32_t uFlags, uint32_t uPID)
     459{
     460    LogFlowFunc(("uPID=%RU32, uStatus=%RU32, uFlags=%RU32\n",
     461                 uPID, uStatus, uFlags));
     462
     463    LogFlowFuncLeave();
     464    return 0;
     465}
     466
     467int GuestProcess::onProcessOutput(uint32_t uHandle, uint32_t uFlags, void *pvData, uint32_t cbData)
     468{
     469    LogFlowFunc(("uPID=%RU32, uHandle=%RU32, uFlags=%RU32, pvData=%p, cbData=%RU32\n",
     470                 mData.mPID, uHandle, uFlags, pvData, cbData));
     471
     472    LogFlowFuncLeave();
     473    return 0;
     474}
     475
     476int GuestProcess::readData(ULONG uHandle, ULONG uSize, ULONG uTimeoutMS, BYTE *pbData, size_t cbData)
     477{
     478    LogFlowFunc(("uPID=%RU32, uHandle=%RU32, uSize=%RU32, uTimeoutMS=%RU32, pbData=%p, cbData=%z\n",
     479                 mData.mPID, uHandle, uSize, uTimeoutMS, pbData, cbData));
     480    AssertReturn(uSize, VERR_INVALID_PARAMETER);
     481    AssertPtrReturn(pbData, VERR_INVALID_POINTER);
     482    AssertReturn(cbData >= uSize, VERR_INVALID_PARAMETER);
     483
     484    LogFlowFuncLeave();
     485    return 0;
     486}
     487
    354488int GuestProcess::startProcess(void)
    355489{
    356     LogFlowFuncEnter();
     490    LogFlowFunc(("aCmd=%s, aTimeoutMS=%RU32, fFlags=%x\n",
     491                 mData.mProcess.mCommand.c_str(), mData.mProcess.mTimeoutMS, mData.mProcess.mFlags));
    357492
    358493    AssertReturn(!mData.mStarted, VERR_ALREADY_EXISTS);
    359494
    360495    int rc;
    361     uint32_t uContextID;
     496    ULONG uContextID;
     497    GuestCtrlCallback *pCallbackStart = (GuestCtrlCallback *)RTMemAlloc(sizeof(GuestCtrlCallback));
     498    if (!pCallbackStart)
     499        return VERR_NO_MEMORY;
    362500
    363501    {
     
    367505
    368506        /* Create callback and add it to the map. */
    369         GuestCtrlCallback callbackStart;
    370         rc = callbackStart.Init(VBOXGUESTCTRLCALLBACKTYPE_EXEC_START);
    371         if (RT_FAILURE(rc))
    372             return rc;
    373 
    374         rc = callbackAdd(callbackStart, &uContextID);
     507        rc = pCallbackStart->Init(VBOXGUESTCTRLCALLBACKTYPE_EXEC_START);
     508        if (RT_SUCCESS(rc))
     509            rc = callbackAdd(pCallbackStart, &uContextID);
     510    }
     511
     512    if (RT_SUCCESS(rc))
     513    {
    375514        Assert(uContextID);
    376     }
    377 
    378     if (RT_SUCCESS(rc))
    379     {
     515
    380516        ComObjPtr<GuestSession> pSession(mData.mParent);
    381517        Assert(!pSession.isNull());
     
    397533                rc = RTGetOptArgvToString(&pszArgs, papszArgv, RTGETOPTARGV_CNV_QUOTE_MS_CRT);
    398534        }
    399         uint32_t cbArgs = pszArgs ? strlen(pszArgs) + 1 : 0; /* Include terminating zero. */
     535        size_t cbArgs = pszArgs ? strlen(pszArgs) + 1 : 0; /* Include terminating zero. */
    400536
    401537        /* Prepare environment. */
    402538        void *pvEnv = NULL;
    403         uint32_t cbEnv = 0;
     539        size_t cbEnv = 0;
    404540        rc = mData.mProcess.mEnvironment.BuildEnvironmentBlock(&pvEnv, &cbEnv, NULL /* cEnv */);
    405541
     
    411547            paParms[i++].setUInt32(uContextID);
    412548            paParms[i++].setPointer((void*)mData.mProcess.mCommand.c_str(),
    413                                     (uint32_t)mData.mProcess.mCommand.length() + 1);
     549                                    (ULONG)mData.mProcess.mCommand.length() + 1);
    414550            paParms[i++].setUInt32(mData.mProcess.mFlags);
    415551            paParms[i++].setUInt32(mData.mProcess.mArguments.size());
     
    418554            paParms[i++].setUInt32(cbEnv);
    419555            paParms[i++].setPointer((void*)pvEnv, cbEnv);
    420             paParms[i++].setPointer((void*)sessionCreds.mUser.c_str(), (uint32_t)sessionCreds.mUser.length() + 1);
    421             paParms[i++].setPointer((void*)sessionCreds.mPassword.c_str(), (uint32_t)sessionCreds.mPassword.length() + 1);
     556            paParms[i++].setPointer((void*)sessionCreds.mUser.c_str(), (ULONG)sessionCreds.mUser.length() + 1);
     557            paParms[i++].setPointer((void*)sessionCreds.mPassword.c_str(), (ULONG)sessionCreds.mPassword.length() + 1);
    422558
    423559            /*
     
    454590        if (pszArgs)
    455591            RTStrFree(pszArgs);
     592
     593        if (RT_SUCCESS(rc))
     594        {
     595            /*
     596             * Let's wait for the process being started.
     597             * Note: Be sure not keeping a AutoRead/WriteLock here.
     598             */
     599            rc = pCallbackStart->Wait(mData.mProcess.mTimeoutMS);
     600        }
    456601    }
    457602
     
    464609    LogFlowFuncEnter();
    465610
    466     const ComObjPtr<GuestProcess> pProcess = static_cast<GuestProcess*>(pvUser);
     611    std::auto_ptr<GuestProcessStartTask> pTask(static_cast<GuestProcessStartTask*>(pvUser));
     612    AssertPtr(pTask.get());
     613
     614    const ComObjPtr<GuestProcess> pProcess(pTask->mProcess);
    467615    Assert(!pProcess.isNull());
    468616
     
    483631}
    484632
    485 int GuestProcess::waitFor(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitReason_T *aReason)
    486 {
    487     LogFlowFuncEnter();
     633int GuestProcess::waitFor(uint32_t fFlags, ULONG uTimeoutMS, ProcessWaitReason_T *penmReason)
     634{
     635    LogFlowFunc(("fFlags=%x, uTimeoutMS=%RU32, penmReason=%p\n",
     636                 fFlags, uTimeoutMS, penmReason));
    488637
    489638    LogFlowFuncLeave();
     
    491640}
    492641
    493 int GuestProcess::writeData(ULONG aHandle, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten)
    494 {
    495     LogFlowFuncEnter();
     642int GuestProcess::writeData(ULONG uHandle, const BYTE *pbData, size_t cbData, ULONG uTimeoutMS, ULONG *puWritten)
     643{
     644    LogFlowFunc(("uPID=%RU32, uHandle=%RU32, pbData=%p, cbData=%z, uTimeoutMS=%RU32, puWritten=%p\n",
     645                 mData.mPID, uHandle, pbData, cbData, uTimeoutMS, puWritten));
     646    AssertPtrReturn(pbData, VERR_INVALID_POINTER);
     647    AssertReturn(pbData, VERR_INVALID_PARAMETER);
     648    /* Rest is optional. */
    496649
    497650    LogFlowFuncLeave();
     
    507660    ReturnComNotImplemented();
    508661#else
    509 
    510     AutoCaller autoCaller(this);
    511     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    512 
    513     int rc = readData(aHandle, aSize, aTimeoutMS, ComSafeArrayOutArg(aData));
     662    LogFlowThisFuncEnter();
     663
     664    if (aSize == 0)
     665        return setError(E_INVALIDARG, tr("Invalid size to read specified"));
     666    CheckComArgOutSafeArrayPointerValid(aData);
     667
     668    AutoCaller autoCaller(this);
     669    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     670
     671    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     672
     673    com::SafeArray<BYTE> data(aSize);
     674    int rc = readData(aHandle, aSize, aTimeoutMS, data.raw(), aSize);
     675    if (RT_SUCCESS(rc))
     676        data.detachTo(ComSafeArrayOutArg(aData));
     677
    514678    /** @todo Do setError() here. */
    515     return RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
     679    HRESULT hr = RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
     680    LogFlowFuncLeaveRC(hr);
     681
     682    return hr;
    516683#endif /* VBOX_WITH_GUEST_CONTROL */
    517684}
     
    522689    ReturnComNotImplemented();
    523690#else
     691    LogFlowThisFuncEnter();
     692
    524693    AutoCaller autoCaller(this);
    525694    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     
    527696    int rc = terminateProcess();
    528697    /** @todo Do setError() here. */
    529     return RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
     698    HRESULT hr = RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
     699    LogFlowFuncLeaveRC(hr);
     700
     701    return hr;
    530702#endif /* VBOX_WITH_GUEST_CONTROL */
    531703}
     
    536708    ReturnComNotImplemented();
    537709#else
    538     AutoCaller autoCaller(this);
    539     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    540 
    541     int rc = waitFor(ComSafeArrayInArg(aFlags), aTimeoutMS, aReason);
     710    LogFlowThisFuncEnter();
     711
     712    CheckComArgOutPointerValid(aReason);
     713
     714    AutoCaller autoCaller(this);
     715    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     716
     717    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     718
     719    uint32_t fFlags = ProcessWaitForFlag_None;
     720    com::SafeArray<ProcessWaitForFlag_T> flags(ComSafeArrayInArg(aFlags));
     721    for (size_t i = 0; i < flags.size(); i++)
     722        fFlags |= flags[i];
     723
     724    int rc = waitFor(fFlags, aTimeoutMS, aReason);
    542725    /** @todo Do setError() here. */
    543     return RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
     726    HRESULT hr = RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
     727    LogFlowFuncLeaveRC(hr);
     728
     729    return hr;
    544730#endif /* VBOX_WITH_GUEST_CONTROL */
    545731}
     
    550736    ReturnComNotImplemented();
    551737#else
    552     AutoCaller autoCaller(this);
    553     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    554 
    555     int rc = writeData(aHandle, ComSafeArrayInArg(aData), aTimeoutMS, aWritten);
     738    LogFlowThisFuncEnter();
     739
     740    CheckComArgOutPointerValid(aWritten);
     741
     742    AutoCaller autoCaller(this);
     743    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     744
     745    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     746
     747    com::SafeArray<BYTE> data(aData);
     748    int rc = writeData(aHandle, data.raw(), data.size(), aTimeoutMS, aWritten);
    556749    /** @todo Do setError() here. */
    557     return RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
    558 #endif /* VBOX_WITH_GUEST_CONTROL */
    559 }
    560 
     750    HRESULT hr = RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
     751    LogFlowFuncLeaveRC(hr);
     752
     753    return hr;
     754#endif /* VBOX_WITH_GUEST_CONTROL */
     755}
     756
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r42194 r42214  
    5555/////////////////////////////////////////////////////////////////////////////
    5656
    57 int GuestSession::init(Guest *aGuest, uint32_t aSessionID,
     57int GuestSession::init(Guest *aGuest, ULONG aSessionID,
    5858                       Utf8Str aUser, Utf8Str aPassword, Utf8Str aDomain, Utf8Str aName)
    5959{
     
    347347    }
    348348
     349    return VERR_NOT_FOUND;
     350}
     351
     352int GuestSession::dispatchToProcess(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData)
     353{
     354    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
     355    AssertReturn(cbData, VERR_INVALID_PARAMETER);
     356
     357    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     358
     359    SessionProcesses::const_iterator itProc
     360        = mData.mProcesses.find(VBOX_GUESTCTRL_CONTEXTID_GET_PROCESS(uContextID));
     361    if (itProc != mData.mProcesses.end())
     362    {
     363        ComObjPtr<GuestProcess> pProcess(itProc->second);
     364        Assert(!pProcess.isNull());
     365
     366        alock.release();
     367        return pProcess->callbackDispatcher(uContextID, uFunction, pvData, cbData);
     368    }
    349369    return VERR_NOT_FOUND;
    350370}
     
    422442
    423443    /* Create a new (host-based) process ID and assign it. */
    424     uint32_t uNewProcessID = 0;
    425     uint32_t uTries = 0;
     444    ULONG uNewProcessID = 0;
     445    ULONG uTries = 0;
    426446
    427447    for (;;)
    428448    {
    429449        /* Is the context ID already used?  Try next ID ... */
    430         if (!processExists(uNewProcessID++))
     450        if (!processExists(uNewProcessID++, NULL /* pProgress */))
    431451        {
    432452            /* Callback with context ID was not found. This means
     
    467487}
    468488
    469 inline bool GuestSession::processExists(uint32_t uProcessID)
     489inline bool GuestSession::processExists(ULONG uProcessID, ComObjPtr<GuestProcess> *pProcess)
    470490{
    471491    AssertReturn(uProcessID, false);
    472492
    473     SessionProcesses::const_iterator itProcesses = mData.mProcesses.find(uProcessID);
    474     return (itProcesses == mData.mProcesses.end()) ? false : true;
     493    SessionProcesses::const_iterator it = mData.mProcesses.find(uProcessID);
     494    if (it != mData.mProcesses.end())
     495    {
     496        if (pProcess)
     497            *pProcess = it->second;
     498        return true;
     499    }
     500    return false;
     501}
     502
     503inline int GuestSession::processGetByPID(ULONG uPID, ComObjPtr<GuestProcess> *pProcess)
     504{
     505    AssertReturn(uPID, false);
     506    /* pProcess is optional. */
     507
     508    SessionProcesses::iterator it = mData.mProcesses.begin();
     509    for (; it != mData.mProcesses.end(); it++)
     510    {
     511        ComObjPtr<GuestProcess> pCurProc = it->second;
     512        AutoCaller procCaller(pCurProc);
     513        if (procCaller.rc())
     514            return VERR_COM_INVALID_OBJECT_STATE;
     515
     516        if (it->second->getPID() == uPID)
     517        {
     518            if (pProcess)
     519                *pProcess = pCurProc;
     520            return VINF_SUCCESS;
     521        }
     522    }
     523
     524    return VERR_NOT_FOUND;
    475525}
    476526
     
    897947    LogFlowThisFuncEnter();
    898948
    899     AutoCaller autoCaller(this);
    900     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    901 
     949    if (RT_UNLIKELY((aCommand) == NULL || *(aCommand) == '\0'))
     950        return setError(E_INVALIDARG, tr("No command to execute specified"));
    902951    CheckComArgOutPointerValid(aProcess);
     952
     953    AutoCaller autoCaller(this);
     954    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    903955
    904956    GuestProcessInfo procInfo;
     
    925977    if (RT_SUCCESS(rc))
    926978    {
    927 
    928979        com::SafeArray<ProcessCreateFlag_T> flags(ComSafeArrayInArg(aFlags));
    929980        for (size_t i = 0; i < flags.size(); i++)
     
    9531004    ReturnComNotImplemented();
    9541005#else
    955     LogFlowThisFuncEnter();
    956 
    957     AutoCaller autoCaller(this);
    958     if (FAILED(autoCaller.rc())) return autoCaller.rc();
    959 
    960     ReturnComNotImplemented();
     1006    LogFlowThisFunc(("aPID=%RU32\n", aPID));
     1007
     1008    CheckComArgOutPointerValid(aProcess);
     1009    if (aPID == 0)
     1010        return setError(E_INVALIDARG, tr("No valid process ID (PID) specified"));
     1011
     1012    AutoCaller autoCaller(this);
     1013    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     1014
     1015    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     1016
     1017    HRESULT hr = S_OK;
     1018
     1019    ComObjPtr<GuestProcess> pProcess;
     1020    int rc = processGetByPID(aPID, &pProcess);
     1021    if (RT_FAILURE(rc))
     1022        hr = setError(E_INVALIDARG, tr("No process with PID %RU32 found"), aPID);
     1023
     1024    /* This will set (*aProcess) to NULL if pProgress is NULL. */
     1025    HRESULT hr2 = pProcess.queryInterfaceTo(aProcess);
     1026    if (SUCCEEDED(hr))
     1027        hr = hr2;
     1028
     1029    LogFlowThisFunc(("aProcess=%p, hr=%Rrc\n", *aProcess, hr));
     1030    return hr;
    9611031#endif /* VBOX_WITH_GUEST_CONTROL */
    9621032}
     
    9721042    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    9731043
    974     ReturnComNotImplemented();
     1044    if (aTimeoutMS < 1000)
     1045        return setError(E_INVALIDARG, tr("Invalid timeout value specified"));
     1046
     1047    mData.mTimeout = aTimeoutMS;
     1048
     1049    LogFlowThisFunc(("aTimeoutMS=%RU32\n", mData.mTimeout));
     1050    return S_OK;
    9751051#endif /* VBOX_WITH_GUEST_CONTROL */
    9761052}
  • trunk/src/VBox/Main/testcase/Makefile.kmk

    r42160 r42214  
    2929        $(if $(VBOX_WITH_XPCOM),tstVBoxAPILinux,tstVBoxAPIWin) \
    3030        $(if $(VBOX_WITH_RESOURCE_USAGE_API),tstCollector,) \
    31         $(if $(VBOX_WITH_GUEST_CONTROL),tstGuestCtrlParseBuffer,)
     31        $(if $(VBOX_WITH_GUEST_CONTROL),tstGuestCtrlParseBuffer,) \
     32        $(if $(VBOX_WITH_GUEST_CONTROL),tstGuestCtrlContextID,)
    3233  PROGRAMS.linux += \
    3334        $(if $(VBOX_WITH_USB),tstUSBProxyLinux,)
     
    160161else
    161162 tstGuestCtrlParseBuffer_DEPS    = $(VBOX_PATH_SDK)/bindings/xpcom/include/VirtualBox_XPCOM.h
     163endif
     164
     165
     166#
     167# tstGuestCtrlContextID
     168#
     169tstGuestCtrlContextID_TEMPLATE = VBOXMAINCLIENTEXE
     170tstGuestCtrlContextID_DEFS    += VBOX_WITH_HGCM VBOX_WITH_GUEST_CONTROL
     171tstGuestCtrlContextID_SOURCES  = \
     172        tstGuestCtrlContextID.cpp \
     173        ../src-client/GuestCtrlPrivate.cpp
     174tstGuestCtrlContextID_INCS     = ../include
     175ifeq ($(KBUILD_TARGET),win) ## @todo just add this to the template.
     176 tstGuestCtrlContextID_DEPS    = $(VBOX_PATH_SDK)/bindings/mscom/include/VirtualBox.h
     177else
     178 tstGuestCtrlContextID_DEPS    = $(VBOX_PATH_SDK)/bindings/xpcom/include/VirtualBox_XPCOM.h
    162179endif
    163180
  • trunk/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp

    r42197 r42214  
    205205            if (iResult != aTestBlock[iTest].iResult)
    206206            {
    207                 RTTestFailed(hTest, "\tReturned %Rrc, expected %Rrc",
     207                RTTestFailed(hTest, "\tReturned %Rrc, expected %Rrc\n",
    208208                             iResult, aTestBlock[iTest].iResult);
    209209            }
    210210            else if (stream.GetOffset() != aTestBlock[iTest].uOffsetAfter)
    211211            {
    212                 RTTestFailed(hTest, "\tOffset %u wrong, expected %u",
     212                RTTestFailed(hTest, "\tOffset %u wrong, expected %u\n",
    213213                             stream.GetOffset(), aTestBlock[iTest].uOffsetAfter);
    214214            }
     
    223223                if (curBlock.GetCount() != aTestBlock[iTest].uMapElements)
    224224                {
    225                     RTTestFailed(hTest, "\tMap has %u elements, expected %u",
     225                    RTTestFailed(hTest, "\tMap has %u elements, expected %u\n",
    226226                                 curBlock.GetCount(), aTestBlock[iTest].uMapElements);
    227227                }
     
    275275            if (iResult != aTestStream[iTest].iResult)
    276276            {
    277                 RTTestFailed(hTest, "\tReturned %Rrc, expected %Rrc",
     277                RTTestFailed(hTest, "\tReturned %Rrc, expected %Rrc\n",
    278278                             iResult, aTestStream[iTest].iResult);
    279279            }
Note: See TracChangeset for help on using the changeset viewer.

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