VirtualBox

Changeset 42507 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Aug 1, 2012 12:40:05 PM (12 years ago)
Author:
vboxsync
Message:

Guest Control 2.0: Update.

Location:
trunk/src/VBox/Main
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r42461 r42507  
    99009900  <interface
    99019901    name="IProcess" extends="$unknown"
    9902     uuid="f55af4a1-e280-40ac-83e1-921c0abcaf18"
     9902    uuid="83275f41-01ee-4362-ac44-298191b5186c"
    99039903    wsmap="managed"
    99049904    >
     
    1003310033      <param name="handle" type="unsigned long" dir="in">
    1003410034        <desc>TODO</desc>
     10035      </param>
     10036      <param name="flags" type="unsigned long" dir="in">
     10037        <desc>
     10038          <link to="ProcessInputFlag"/> flags.
     10039        </desc>
     10040      </param>
     10041      <param name="data" type="octet" dir="in" safearray="yes">
     10042        <desc>TODO</desc>
     10043      </param>
     10044      <param name="timeoutMS" type="unsigned long" dir="in">
     10045        <desc>TODO</desc>
     10046      </param>
     10047      <param name="written" type="unsigned long" dir="return">
     10048        <desc>TODO</desc>
     10049      </param>
     10050    </method>
     10051   
     10052    <method name="WriteArray">
     10053      <desc>
     10054        TODO
     10055
     10056        <result name="VBOX_E_NOT_SUPPORTED">
     10057          TODO
     10058        </result>
     10059      </desc>
     10060      <param name="handle" type="unsigned long" dir="in">
     10061        <desc>TODO</desc>
     10062      </param>
     10063      <param name="flags" type="ProcessInputFlag" dir="in" safearray="yes">
     10064        <desc>
     10065          <link to="ProcessInputFlag"/> flags.
     10066        </desc>
    1003510067      </param>
    1003610068      <param name="data" type="octet" dir="in" safearray="yes">
  • trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h

    r42485 r42507  
    133133    void Destroy(void);
    134134
    135     int FillData(const void *pvToWrite, size_t cbToWrite);
    136 
    137135    int Init(eVBoxGuestCtrlCallbackType enmType);
    138136
    139137    eVBoxGuestCtrlCallbackType GetCallbackType(void) { return mType; }
    140138
     139    const void* GetDataRaw(void) const { return pvData; }
     140
     141    size_t GetDataSize(void) { return cbData; }
     142
    141143    const void* GetPayloadRaw(void) const { return pvPayload; }
    142144
    143145    size_t GetPayloadSize(void) { return cbPayload; }
     146
     147    int SetData(const void *pvCallback, size_t cbCallback);
     148
     149    int SetPayload(const void *pvToWrite, size_t cbToWrite);
    144150
    145151protected:
     
    156162     *  waiting (optional). */
    157163    void                       *pvPayload;
    158     /** Size of the payload. */
     164    /** Size of the payload (optional). */
    159165    size_t                      cbPayload;
    160166};
  • trunk/src/VBox/Main/include/GuestProcessImpl.h

    r42461 r42507  
    6565    STDMETHOD(WaitFor)(ULONG aWaitFlags, ULONG aTimeoutMS, ProcessWaitResult_T *aReason);
    6666    STDMETHOD(WaitForArray)(ComSafeArrayIn(ProcessWaitForFlag_T, aFlags), ULONG aTimeoutMS, ProcessWaitResult_T *aReason);
    67     STDMETHOD(Write)(ULONG aHandle, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten);
     67    STDMETHOD(Write)(ULONG aHandle, ULONG aFlags, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten);
     68    STDMETHOD(WriteArray)(ULONG aHandle, ComSafeArrayIn(ProcessInputFlag_T, aFlags), ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten);
    6869    /** @}  */
    6970
     
    7273     * @{ */
    7374    int callbackDispatcher(uint32_t uContextID, uint32_t uFunction, void *pvData, size_t cbData);
    74     inline bool callbackExists(ULONG uContextID);
     75    inline bool callbackExists(uint32_t uContextID);
    7576    void close(void);
    7677    bool isReady(void);
    7778    ULONG getPID(void) { return mData.mPID; }
    78     int readData(ULONG uHandle, ULONG uSize, ULONG uTimeoutMS, BYTE *pbData, size_t cbData, size_t *pcbRead);
     79    int readData(uint32_t uHandle, uint32_t uSize, uint32_t uTimeoutMS, void *pvData, size_t cbData, size_t *pcbRead);
    7980    int startProcess(void);
    8081    int startProcessAsync(void);
    8182    int terminateProcess(void);
    8283    int waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestProcessWaitResult &guestResult);
    83     int writeData(ULONG uHandle, BYTE const *pbData, size_t cbData, ULONG uTimeoutMS, ULONG *puWritten);
     84    int writeData(uint32_t uHandle, uint32_t uFlags, void *pvData, size_t cbData, uint32_t uTimeoutMS, uint32_t *puWritten);
    8485    /** @}  */
    8586
     
    8788    /** @name Protected internal methods.
    8889     * @{ */
    89     inline int callbackAdd(GuestCtrlCallback *pCallback, ULONG *puContextID);
    90     inline int callbackRemove(ULONG uContextID);
     90    inline int callbackAdd(GuestCtrlCallback *pCallback, uint32_t *puContextID);
     91    inline int callbackRemove(uint32_t uContextID);
    9192    inline bool isAlive(void);
    9293    int onGuestDisconnected(GuestCtrlCallback *pCallback, PCALLBACKDATACLIENTDISCONNECTED pData);
  • trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp

    r42485 r42507  
    196196    GuestCtrlEvent::Destroy();
    197197
     198    switch (mType)
     199    {
     200        case VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT:
     201        {
     202            PCALLBACKDATAEXECOUT pThis = (PCALLBACKDATAEXECOUT)pvData;
     203            AssertPtr(pThis);
     204            if (pThis->pvData)
     205                RTMemFree(pThis->pvData);
     206        }
     207
     208        default:
     209           break;
     210    }
     211
    198212    mType = VBOXGUESTCTRLCALLBACKTYPE_UNKNOWN;
    199213    if (pvData)
     
    212226}
    213227
    214 int GuestCtrlCallback::FillData(const void *pvToWrite, size_t cbToWrite)
     228int GuestCtrlCallback::SetData(const void *pvCallback, size_t cbCallback)
     229{
     230    if (!cbCallback)
     231        return VINF_SUCCESS;
     232    AssertPtr(pvCallback);
     233
     234    switch (mType)
     235    {
     236        case VBOXGUESTCTRLCALLBACKTYPE_EXEC_START:
     237        {
     238            PCALLBACKDATAEXECSTATUS pThis = (PCALLBACKDATAEXECSTATUS)pvData;
     239            PCALLBACKDATAEXECSTATUS pCB   = (PCALLBACKDATAEXECSTATUS)pvCallback;
     240            Assert(cbCallback == sizeof(CALLBACKDATAEXECSTATUS));
     241
     242            pThis->u32Flags  = pCB->u32Flags;
     243            pThis->u32PID    = pCB->u32PID;
     244            pThis->u32Status = pCB->u32Status;
     245            break;
     246        }
     247
     248        case VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT:
     249        {
     250            PCALLBACKDATAEXECOUT pThis = (PCALLBACKDATAEXECOUT)pvData;
     251            PCALLBACKDATAEXECOUT pCB   = (PCALLBACKDATAEXECOUT)pvCallback;
     252            Assert(cbCallback == sizeof(CALLBACKDATAEXECOUT));
     253
     254            pThis->cbData   = pCB->cbData;
     255            if (pThis->cbData)
     256            {
     257                pThis->pvData   = RTMemAlloc(pCB->cbData);
     258                AssertPtrReturn(pThis->pvData, VERR_NO_MEMORY);
     259                memcpy(pThis->pvData, pCB->pvData, pCB->cbData);
     260            }
     261            pThis->u32Flags = pCB->u32Flags;
     262            pThis->u32PID   = pCB->u32PID;
     263            break;
     264        }
     265
     266        case VBOXGUESTCTRLCALLBACKTYPE_EXEC_INPUT_STATUS:
     267        {
     268            PCALLBACKDATAEXECINSTATUS pThis = (PCALLBACKDATAEXECINSTATUS)pvData;
     269            PCALLBACKDATAEXECINSTATUS pCB   = (PCALLBACKDATAEXECINSTATUS)pvCallback;
     270            Assert(cbCallback == sizeof(CALLBACKDATAEXECINSTATUS));
     271
     272            pThis->cbProcessed = pCB->cbProcessed;
     273            pThis->u32Flags    = pCB->u32Flags;
     274            pThis->u32PID      = pCB->u32PID;
     275            pThis->u32Status   = pCB->u32Status;
     276        }
     277
     278        default:
     279            AssertMsgFailed(("Callback type not handled (%d)\n", mType));
     280            break;
     281    }
     282
     283    return VINF_SUCCESS;
     284}
     285
     286int GuestCtrlCallback::SetPayload(const void *pvToWrite, size_t cbToWrite)
    215287{
    216288    if (!cbToWrite)
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r42485 r42507  
    1717 */
    1818
     19/**
     20 * Locking rules:
     21 * - When the main dispatcher (callbackDispatcher) is called it takes the
     22 *   WriteLock while dispatching to the various on* methods.
     23 * - All other outer functions (accessible by Main) must not own a lock
     24 *   while waiting for a callback or for an event.
     25 * - Only keep Read/WriteLocks as short as possible and only when necessary.
     26 */
    1927
    2028/*******************************************************************************
     
    308316/////////////////////////////////////////////////////////////////////////////
    309317
    310 inline int GuestProcess::callbackAdd(GuestCtrlCallback *pCallback, ULONG *puContextID)
     318inline int GuestProcess::callbackAdd(GuestCtrlCallback *pCallback, uint32_t *puContextID)
    311319{
    312320    const ComObjPtr<GuestSession> pSession(mData.mParent);
     
    360368
    361369        LogFlowThisFunc(("Added new callback (Session: %RU32, Process: %RU32, Count=%RU32) CID=%RU32\n",
    362                      uSessionID, mData.mProcessID, uCount, uNewContextID));
     370                         uSessionID, mData.mProcessID, uCount, uNewContextID));
    363371    }
    364372
     
    370378#ifdef DEBUG
    371379    LogFlowThisFunc(("uPID=%RU32, uContextID=%RU32, uFunction=%RU32, pvData=%p, cbData=%RU32\n",
    372                  mData.mPID, uContextID, uFunction, pvData, cbData));
     380                     mData.mPID, uContextID, uFunction, pvData, cbData));
    373381#endif
    374382
     
    453461}
    454462
    455 inline bool GuestProcess::callbackExists(ULONG uContextID)
     463inline bool GuestProcess::callbackExists(uint32_t uContextID)
    456464{
    457465    GuestCtrlCallbacks::const_iterator it =
     
    460468}
    461469
    462 inline int GuestProcess::callbackRemove(ULONG uContextID)
     470inline int GuestProcess::callbackRemove(uint32_t uContextID)
    463471{
    464472    GuestCtrlCallbacks::iterator it =
     
    595603
    596604    LogFlowThisFunc(("uPID=%RU32, uStatus=%RU32, uFlags=%RU32, pCallback=%p, pData=%p\n",
    597                  pData->u32PID, pData->u32Status, pData->u32Flags, pCallback, pData));
     605                     pData->u32PID, pData->u32Status, pData->u32Flags, pCallback, pData));
    598606
    599607    int rc = VINF_SUCCESS;
     
    779787
    780788    LogFlowThisFunc(("uPID=%RU32, uHandle=%RU32, uFlags=%RU32, pvData=%p, cbData=%RU32, pCallback=%p, pData=%p\n",
    781                  mData.mPID, pData->u32HandleId, pData->u32Flags, pData->pvData, pData->cbData, pCallback, pData));
     789                     mData.mPID, pData->u32HandleId, pData->u32Flags, pData->pvData, pData->cbData, pCallback, pData));
    782790
    783791    /* Copy data into callback (if any). */
     
    787795    if (pCallback)
    788796    {
    789         if (pData->pvData && pData->cbData)
    790         {
    791             rc = pCallback->FillData(pData->pvData, pData->cbData);
    792             Assert(pCallback->GetPayloadSize() == pData->cbData);
    793         }
     797        rc = pCallback->SetData(pData, sizeof(CALLBACKDATAEXECOUT));
    794798
    795799        int rc2 = pCallback->Signal();
     
    831835}
    832836
    833 int GuestProcess::readData(ULONG uHandle, ULONG uSize, ULONG uTimeoutMS,
    834                            BYTE *pbData, size_t cbData, size_t *pcbRead)
    835 {
    836     LogFlowThisFunc(("uPID=%RU32, uHandle=%RU32, uSize=%RU32, uTimeoutMS=%RU32, pbData=%p, cbData=%RU32\n",
    837                  mData.mPID, uHandle, uSize, uTimeoutMS, pbData, cbData));
     837int GuestProcess::readData(uint32_t uHandle, uint32_t uSize, uint32_t uTimeoutMS,
     838                           void *pvData, size_t cbData, size_t *pcbRead)
     839{
     840    LogFlowThisFunc(("uPID=%RU32, uHandle=%RU32, uSize=%RU32, uTimeoutMS=%RU32, pvData=%p, cbData=%RU32\n",
     841                     mData.mPID, uHandle, uSize, uTimeoutMS, pvData, cbData));
    838842    AssertReturn(uSize, VERR_INVALID_PARAMETER);
    839     AssertPtrReturn(pbData, VERR_INVALID_POINTER);
     843    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
    840844    AssertReturn(cbData >= uSize, VERR_INVALID_PARAMETER);
    841845    /* pcbRead is optional. */
     
    846850        return VERR_NOT_AVAILABLE;
    847851
    848     ULONG uContextID = 0;
     852    uint32_t uContextID = 0;
    849853    GuestCtrlCallback *pCallbackRead = new GuestCtrlCallback();
    850854    if (!pCallbackRead)
     
    882886        {
    883887            rc = pCallbackRead->GetResultCode();
    884             LogFlowThisFunc(("Callback returned rc=%Rrc, cbData=%RU32\n", rc, pCallbackRead->GetPayloadSize()));
     888            LogFlowThisFunc(("Callback returned rc=%Rrc, cbData=%RU32\n", rc, pCallbackRead->GetDataSize()));
    885889
    886890            if (RT_SUCCESS(rc))
    887891            {
    888                 size_t cbDataCB = pCallbackRead->GetPayloadSize();
    889                 if (cbDataCB)
     892                Assert(pCallbackRead->GetDataSize() == sizeof(CALLBACKDATAEXECOUT));
     893                PCALLBACKDATAEXECOUT pData = (PCALLBACKDATAEXECOUT)pCallbackRead->GetDataRaw();
     894                AssertPtr(pData);
     895
     896                size_t cbRead = pData->cbData;
     897                if (cbRead)
    890898                {
    891                     Assert(cbData >= cbDataCB);
    892                     memcpy(pbData, pCallbackRead->GetPayloadRaw(), cbDataCB);
     899                    Assert(cbData >= cbRead);
     900                    memcpy(pvData, pData->pvData, cbRead);
    893901                }
    894902
     903                LogFlowThisFunc(("cbRead=%RU32\n", cbRead));
     904
    895905                if (pcbRead)
    896                     *pcbRead = cbDataCB;
     906                    *pcbRead = cbRead;
    897907            }
    898908        }
     
    944954}
    945955
     956/* Does not do locking; caller is responsible for that! */
    946957int GuestProcess::setErrorInternal(int rc, const Utf8Str &strMessage)
    947958{
     
    958969#endif
    959970
    960     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    961 
    962971    mData.mStatus = ProcessStatus_Error;
    963972    mData.mRC = rc;
     
    9991008
    10001009    int rc;
    1001     ULONG uContextID = 0;
     1010    uint32_t uContextID = 0;
    10021011    GuestCtrlCallback *pCallbackStart = new GuestCtrlCallback();
    10031012    if (!pCallbackStart)
     
    10131022    if (RT_SUCCESS(rc))
    10141023    {
    1015       //  AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
    1016 
    10171024        GuestSession *pSession = mData.mParent;
    10181025        AssertPtr(pSession);
     
    10701077                paParms[i++].setUInt32(mData.mProcess.mTimeoutMS);
    10711078
     1079            /* Note: Don't hold the write lock in here, because setErrorInternal */
    10721080            rc = sendCommand(HOST_EXEC_CMD, i, paParms);
    10731081        }
     
    10791087        uint32_t uTimeoutMS = mData.mProcess.mTimeoutMS;
    10801088
    1081         alock.release(); /* Drop the write lock again. */
     1089        /* Drop the write lock again before waiting. */
     1090        alock.release();
    10821091
    10831092        if (RT_SUCCESS(rc))
     
    11351144DECLCALLBACK(int) GuestProcess::startProcessThread(RTTHREAD Thread, void *pvUser)
    11361145{
    1137     LogFlowFuncEnter();
     1146    LogFlowFuncEnter(("pvUser=%p\n", pvUser));
    11381147
    11391148    std::auto_ptr<GuestProcessStartTask> pTask(static_cast<GuestProcessStartTask*>(pvUser));
     
    11531162
    11541163    LogFlowFuncLeaveRC(rc);
    1155     return VINF_SUCCESS;
     1164    return rc;
    11561165}
    11571166
     
    11741183
    11751184    LogFlowThisFunc(("fWaitFlags=%x, uTimeoutMS=%RU32, mStatus=%RU32, mWaitCount=%RU32, mWaitEvent=%p\n",
    1176                  fWaitFlags, uTimeoutMS, mData.mStatus, mData.mWaitCount, mData.mWaitEvent));
     1185                     fWaitFlags, uTimeoutMS, mData.mStatus, mData.mWaitCount, mData.mWaitEvent));
    11771186
    11781187    ProcessStatus_T curStatus;
     
    14451454}
    14461455
    1447 int GuestProcess::writeData(ULONG uHandle, const BYTE *pbData, size_t cbData, ULONG uTimeoutMS, ULONG *puWritten)
    1448 {
    1449     LogFlowThisFunc(("uPID=%RU32, uHandle=%RU32, pbData=%p, cbData=%RU32, uTimeoutMS=%RU32, puWritten=%p\n",
    1450                  mData.mPID, uHandle, pbData, cbData, uTimeoutMS, puWritten));
    1451     AssertPtrReturn(pbData, VERR_INVALID_POINTER);
    1452     AssertReturn(pbData, VERR_INVALID_PARAMETER);
     1456int GuestProcess::writeData(uint32_t uHandle, uint32_t uFlags,
     1457                            void *pvData, size_t cbData, uint32_t uTimeoutMS, uint32_t *puWritten)
     1458{
     1459    LogFlowThisFunc(("uPID=%RU32, uHandle=%RU32, pvData=%p, cbData=%RU32, uTimeoutMS=%RU32, puWritten=%p\n",
     1460                     mData.mPID, uHandle, pvData, cbData, uTimeoutMS, puWritten));
     1461    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
     1462    AssertReturn(cbData, VERR_INVALID_PARAMETER);
    14531463    /* Rest is optional. */
    14541464
    1455     LogFlowThisFuncLeave();
    1456     return 0;
     1465    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     1466
     1467    if (mData.mStatus != ProcessStatus_Started)
     1468        return VERR_NOT_AVAILABLE;
     1469
     1470    uint32_t uContextID = 0;
     1471    GuestCtrlCallback *pCallbackWrite = new GuestCtrlCallback();
     1472    if (!pCallbackWrite)
     1473        return VERR_NO_MEMORY;
     1474
     1475    /* Create callback and add it to the map. */
     1476    int rc = pCallbackWrite->Init(VBOXGUESTCTRLCALLBACKTYPE_EXEC_INPUT_STATUS);
     1477    if (RT_SUCCESS(rc))
     1478        rc = callbackAdd(pCallbackWrite, &uContextID);
     1479
     1480    alock.release(); /* Drop the write lock again. */
     1481
     1482    if (RT_SUCCESS(rc))
     1483    {
     1484        VBOXHGCMSVCPARM paParms[5];
     1485
     1486        int i = 0;
     1487        paParms[i++].setUInt32(uContextID);
     1488        paParms[i++].setUInt32(mData.mPID);
     1489        paParms[i++].setUInt32(uFlags);
     1490        paParms[i++].setPointer(pvData, cbData);
     1491        paParms[i++].setUInt32(cbData);
     1492
     1493        rc = sendCommand(HOST_EXEC_SET_INPUT, i, paParms);
     1494    }
     1495
     1496    if (RT_SUCCESS(rc))
     1497    {
     1498        /*
     1499         * Let's wait for the process being started.
     1500         * Note: Be sure not keeping a AutoRead/WriteLock here.
     1501         */
     1502        LogFlowThisFunc(("Waiting for callback (%RU32ms) ...\n", uTimeoutMS));
     1503        rc = pCallbackWrite->Wait(uTimeoutMS);
     1504        if (RT_SUCCESS(rc)) /* Wait was successful, check for supplied information. */
     1505        {
     1506            rc = pCallbackWrite->GetResultCode();
     1507            LogFlowThisFunc(("Callback returned rc=%Rrc, cbData=%RU32\n", rc, pCallbackWrite->GetDataSize()));
     1508
     1509            if (RT_SUCCESS(rc))
     1510            {
     1511                Assert(pCallbackWrite->GetDataSize() == sizeof(CALLBACKDATAEXECINSTATUS));
     1512                PCALLBACKDATAEXECINSTATUS pData = (PCALLBACKDATAEXECINSTATUS)pCallbackWrite->GetDataRaw();
     1513                AssertPtr(pData);
     1514
     1515                uint32_t cbWritten = 0;
     1516                switch (pData->u32Status)
     1517                {
     1518                    case INPUT_STS_WRITTEN:
     1519                        cbWritten = pData->cbProcessed;
     1520                        break;
     1521
     1522                    case INPUT_STS_ERROR:
     1523                        rc = pData->u32Flags; /** @todo Fix int vs. uint32_t! */
     1524                        break;
     1525
     1526                    case INPUT_STS_TERMINATED:
     1527                        rc = VERR_CANCELLED;
     1528                        break;
     1529
     1530                    case INPUT_STS_OVERFLOW:
     1531                        rc = VERR_BUFFER_OVERFLOW;
     1532                        break;
     1533
     1534                    default:
     1535                        /* Silently skip unknown errors. */
     1536                        break;
     1537                }
     1538
     1539                LogFlowThisFunc(("cbWritten=%RU32\n", cbWritten));
     1540
     1541                if (puWritten)
     1542                    *puWritten = cbWritten;
     1543            }
     1544        }
     1545        else
     1546            rc = VERR_TIMEOUT;
     1547    }
     1548
     1549    alock.acquire();
     1550
     1551    AssertPtr(pCallbackWrite);
     1552    int rc2 = callbackRemove(uContextID);
     1553    if (RT_SUCCESS(rc))
     1554        rc = rc2;
     1555
     1556    LogFlowFuncLeaveRC(rc);
     1557    return rc;
    14571558}
    14581559
     
    15791680}
    15801681
    1581 STDMETHODIMP GuestProcess::Write(ULONG aHandle, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten)
     1682STDMETHODIMP GuestProcess::Write(ULONG aHandle, ULONG aFlags,
     1683                                 ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten)
    15821684{
    15831685#ifndef VBOX_WITH_GUEST_CONTROL
     
    15941696
    15951697    com::SafeArray<BYTE> data(ComSafeArrayInArg(aData));
    1596     int rc = writeData(aHandle, data.raw(), data.size(), aTimeoutMS, aWritten);
     1698    int rc = writeData(aHandle, aFlags, data.raw(), data.size(), aTimeoutMS, (uint32_t*)aWritten);
    15971699    /** @todo Do setError() here. */
    15981700    HRESULT hr = RT_SUCCESS(rc) ? S_OK : VBOX_E_IPRT_ERROR;
     
    16031705}
    16041706
     1707STDMETHODIMP GuestProcess::WriteArray(ULONG aHandle, ComSafeArrayIn(ProcessInputFlag_T, aFlags),
     1708                                      ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten)
     1709{
     1710#ifndef VBOX_WITH_GUEST_CONTROL
     1711    ReturnComNotImplemented();
     1712#else
     1713    LogFlowThisFuncEnter();
     1714
     1715    CheckComArgOutPointerValid(aWritten);
     1716
     1717    AutoCaller autoCaller(this);
     1718    if (FAILED(autoCaller.rc())) return autoCaller.rc();
     1719
     1720    /*
     1721     * Note: Do not hold any locks here while writing!
     1722     */
     1723    ULONG fWrite = ProcessInputFlag_None;
     1724    com::SafeArray<ProcessInputFlag_T> flags(ComSafeArrayInArg(aFlags));
     1725    for (size_t i = 0; i < flags.size(); i++)
     1726        fWrite |= flags[i];
     1727
     1728    return Write(aHandle, fWrite, ComSafeArrayInArg(aData), aTimeoutMS, aWritten);
     1729#endif /* VBOX_WITH_GUEST_CONTROL */
     1730}
     1731
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