Esempio n. 1
0
int GuestBase::dispatchGeneric(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
{
    LogFlowFunc(("pCtxCb=%p, pSvcCb=%p\n", pCtxCb, pSvcCb));

    AssertPtrReturn(pCtxCb, VERR_INVALID_POINTER);
    AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);

    int vrc = VINF_SUCCESS;

    try
    {
        LogFlowFunc(("uFunc=%RU32, cParms=%RU32\n",
                     pCtxCb->uFunction, pSvcCb->mParms));

        switch (pCtxCb->uFunction)
        {
            case GUEST_MSG_PROGRESS_UPDATE:
                break;

            case GUEST_MSG_REPLY:
            {
                if (pSvcCb->mParms >= 3)
                {
                    int idx = 1; /* Current parameter index. */
                    CALLBACKDATA_MSG_REPLY dataCb;
                    /* pSvcCb->mpaParms[0] always contains the context ID. */
                    vrc = pSvcCb->mpaParms[idx++].getUInt32(&dataCb.uType);
                    AssertRCReturn(vrc, vrc);
                    vrc = pSvcCb->mpaParms[idx++].getUInt32(&dataCb.rc);
                    AssertRCReturn(vrc, vrc);
                    vrc = pSvcCb->mpaParms[idx++].getPointer(&dataCb.pvPayload, &dataCb.cbPayload);
                    AssertRCReturn(vrc, vrc);

                    GuestWaitEventPayload evPayload(dataCb.uType, dataCb.pvPayload, dataCb.cbPayload);
                    int rc2 = signalWaitEventInternal(pCtxCb, dataCb.rc, &evPayload);
                    AssertRC(rc2);
                }
                else
                    vrc = VERR_INVALID_PARAMETER;
                break;
            }

            default:
                vrc = VERR_NOT_SUPPORTED;
                break;
        }
    }
    catch (std::bad_alloc)
    {
        vrc = VERR_NO_MEMORY;
    }
    catch (int rc)
    {
        vrc = rc;
    }

    LogFlowFuncLeaveRC(vrc);
    return vrc;
}
Esempio n. 2
0
int GuestFile::i_onFileNotify(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData)
{
    AssertPtrReturn(pCbCtx, VERR_INVALID_POINTER);
    AssertPtrReturn(pSvcCbData, VERR_INVALID_POINTER);

    LogFlowThisFuncEnter();

    if (pSvcCbData->mParms < 3)
        return VERR_INVALID_PARAMETER;

    int vrc = VINF_SUCCESS;

    int idx = 1; /* Current parameter index. */
    CALLBACKDATA_FILE_NOTIFY dataCb;
    /* pSvcCb->mpaParms[0] always contains the context ID. */
    pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.uType);
    pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.rc);

    int guestRc = (int)dataCb.rc; /* uint32_t vs. int. */

    LogFlowFunc(("uType=%RU32, guestRc=%Rrc\n",
                 dataCb.uType, guestRc));

    if (RT_FAILURE(guestRc))
    {
        int rc2 = i_setFileStatus(FileStatus_Error, guestRc);
        AssertRC(rc2);

        rc2 = signalWaitEventInternal(pCbCtx,
                                      guestRc, NULL /* pPayload */);
        AssertRC(rc2);

        return VINF_SUCCESS; /* Report to the guest. */
    }

    switch (dataCb.uType)
    {
        case GUEST_FILE_NOTIFYTYPE_ERROR:
        {
            int rc2 = i_setFileStatus(FileStatus_Error, guestRc);
            AssertRC(rc2);

            break;
        }

        case GUEST_FILE_NOTIFYTYPE_OPEN:
        {
            if (pSvcCbData->mParms == 4)
            {
                pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.open.uHandle);

                AssertMsg(mData.mID == VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID),
                          ("File ID %RU32 does not match context ID %RU32\n", mData.mID,
                           VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID)));

                /* Set the process status. */
                int rc2 = i_setFileStatus(FileStatus_Open, guestRc);
                AssertRC(rc2);
            }
            else
                vrc = VERR_NOT_SUPPORTED;

            break;
        }

        case GUEST_FILE_NOTIFYTYPE_CLOSE:
        {
            int rc2 = i_setFileStatus(FileStatus_Closed, guestRc);
            AssertRC(rc2);

            break;
        }

        case GUEST_FILE_NOTIFYTYPE_READ:
        {
            if (pSvcCbData->mParms == 4)
            {
                pSvcCbData->mpaParms[idx++].getPointer(&dataCb.u.read.pvData,
                                                       &dataCb.u.read.cbData);
                uint32_t cbRead = dataCb.u.read.cbData;

                AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

                mData.mOffCurrent += cbRead;

                alock.release();

                com::SafeArray<BYTE> data((size_t)cbRead);
                data.initFrom((BYTE*)dataCb.u.read.pvData, cbRead);

                fireGuestFileReadEvent(mEventSource, mSession, this, mData.mOffCurrent,
                                       cbRead, ComSafeArrayAsInParam(data));
            }
            else
                vrc = VERR_NOT_SUPPORTED;
            break;
        }

        case GUEST_FILE_NOTIFYTYPE_WRITE:
        {
            if (pSvcCbData->mParms == 4)
            {
                pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.write.cbWritten);

                AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

                mData.mOffCurrent += dataCb.u.write.cbWritten;
                uint64_t uOffCurrent = mData.mOffCurrent;

                alock.release();

                fireGuestFileWriteEvent(mEventSource, mSession, this, uOffCurrent,
                                        dataCb.u.write.cbWritten);
            }
            else
                vrc = VERR_NOT_SUPPORTED;
            break;
        }

        case GUEST_FILE_NOTIFYTYPE_SEEK:
        {
            if (pSvcCbData->mParms == 4)
            {
                pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.seek.uOffActual);

                AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

                mData.mOffCurrent = dataCb.u.seek.uOffActual;

                alock.release();

                fireGuestFileOffsetChangedEvent(mEventSource, mSession, this,
                                                dataCb.u.seek.uOffActual, 0 /* Processed */);
            }
            else
                vrc = VERR_NOT_SUPPORTED;
            break;
        }

        case GUEST_FILE_NOTIFYTYPE_TELL:
        {
            if (pSvcCbData->mParms == 4)
            {
                pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.tell.uOffActual);

                AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

                mData.mOffCurrent = dataCb.u.tell.uOffActual;

                alock.release();

                fireGuestFileOffsetChangedEvent(mEventSource, mSession, this,
                                                dataCb.u.tell.uOffActual, 0 /* Processed */);
            }
            else
                vrc = VERR_NOT_SUPPORTED;
            break;
        }

        default:
            vrc = VERR_NOT_SUPPORTED;
            break;
    }

    if (RT_SUCCESS(vrc))
    {
        GuestWaitEventPayload payload(dataCb.uType, &dataCb, sizeof(dataCb));
        int rc2 = signalWaitEventInternal(pCbCtx, guestRc, &payload);
        AssertRC(rc2);
    }

    LogFlowThisFunc(("uType=%RU32, guestRc=%Rrc\n",
                     dataCb.uType, dataCb.rc));

    LogFlowFuncLeaveRC(vrc);
    return vrc;
}