Пример #1
0
int GuestFile::i_writeDataAt(uint64_t uOffset, uint32_t uTimeoutMS,
                             void *pvData, uint32_t cbData, uint32_t *pcbWritten)
{
    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
    AssertReturn(cbData, VERR_INVALID_PARAMETER);

    LogFlowThisFunc(("uOffset=%RU64, uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n",
                     uOffset, uTimeoutMS, pvData, cbData));

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    int vrc;

    GuestWaitEvent *pEvent = NULL;
    GuestEventTypes eventTypes;
    try
    {
        eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged);
        eventTypes.push_back(VBoxEventType_OnGuestFileWrite);

        vrc = registerWaitEvent(eventTypes, &pEvent);
    }
    catch (std::bad_alloc)
    {
        vrc = VERR_NO_MEMORY;
    }

    if (RT_FAILURE(vrc))
        return vrc;

    /* Prepare HGCM call. */
    VBOXHGCMSVCPARM paParms[8];
    int i = 0;
    paParms[i++].setUInt32(pEvent->ContextID());
    paParms[i++].setUInt32(mData.mID /* File handle */);
    paParms[i++].setUInt64(uOffset /* Offset where to starting writing */);
    paParms[i++].setUInt32(cbData /* Size (in bytes) to write */);
    paParms[i++].setPointer(pvData, cbData);

    alock.release(); /* Drop write lock before sending. */

    vrc = sendCommand(HOST_FILE_WRITE_AT, i, paParms);
    if (RT_SUCCESS(vrc))
    {
        uint32_t cbWritten = 0;
        vrc = i_waitForWrite(pEvent, uTimeoutMS, &cbWritten);
        if (RT_SUCCESS(vrc))
        {
            LogFlowThisFunc(("cbWritten=%RU32\n", cbWritten));
            if (cbWritten)
                *pcbWritten = cbWritten;
        }
    }

    unregisterWaitEvent(pEvent);

    LogFlowFuncLeaveRC(vrc);
    return vrc;
}
Пример #2
0
int GuestFile::i_readData(uint32_t uSize, uint32_t uTimeoutMS,
                          void* pvData, uint32_t cbData, uint32_t* pcbRead)
{
    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
    AssertReturn(cbData, VERR_INVALID_PARAMETER);

    LogFlowThisFunc(("uSize=%RU32, uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n",
                     uSize, uTimeoutMS, pvData, cbData));

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    int vrc;

    GuestWaitEvent *pEvent = NULL;
    GuestEventTypes eventTypes;
    try
    {
        eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged);
        eventTypes.push_back(VBoxEventType_OnGuestFileRead);

        vrc = registerWaitEvent(eventTypes, &pEvent);
    }
    catch (std::bad_alloc)
    {
        vrc = VERR_NO_MEMORY;
    }

    if (RT_FAILURE(vrc))
        return vrc;

    /* Prepare HGCM call. */
    VBOXHGCMSVCPARM paParms[4];
    int i = 0;
    paParms[i++].setUInt32(pEvent->ContextID());
    paParms[i++].setUInt32(mData.mID /* File handle */);
    paParms[i++].setUInt32(uSize /* Size (in bytes) to read */);

    alock.release(); /* Drop write lock before sending. */

    vrc = sendCommand(HOST_FILE_READ, i, paParms);
    if (RT_SUCCESS(vrc))
    {
        uint32_t cbRead = 0;
        vrc = i_waitForRead(pEvent, uTimeoutMS, pvData, cbData, &cbRead);
        if (RT_SUCCESS(vrc))
        {
            LogFlowThisFunc(("cbRead=%RU32\n", cbRead));
            if (pcbRead)
                *pcbRead = cbRead;
        }
    }

    unregisterWaitEvent(pEvent);

    LogFlowFuncLeaveRC(vrc);
    return vrc;
}
Пример #3
0
int GuestFile::openFile(uint32_t uTimeoutMS, int *pGuestRc)
{
    LogFlowThisFuncEnter();

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    LogFlowThisFunc(("strFile=%s, strOpenMode=%s, strDisposition=%s, uCreationMode=%RU32, uOffset=%RU64\n",
                     mData.mOpenInfo.mFileName.c_str(), mData.mOpenInfo.mOpenMode.c_str(),
                     mData.mOpenInfo.mDisposition.c_str(), mData.mOpenInfo.mCreationMode, mData.mOpenInfo.mInitialOffset));
    int vrc;

    GuestWaitEvent *pEvent = NULL;
    GuestEventTypes eventTypes;
    try
    {
        eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged);

        vrc = registerWaitEvent(eventTypes, &pEvent);
    }
    catch (std::bad_alloc)
    {
        vrc = VERR_NO_MEMORY;
    }

    if (RT_FAILURE(vrc))
        return vrc;

    /* Prepare HGCM call. */
    VBOXHGCMSVCPARM paParms[8];
    int i = 0;
    paParms[i++].setUInt32(pEvent->ContextID());
    paParms[i++].setPointer((void*)mData.mOpenInfo.mFileName.c_str(),
                            (ULONG)mData.mOpenInfo.mFileName.length() + 1);
    paParms[i++].setPointer((void*)mData.mOpenInfo.mOpenMode.c_str(),
                            (ULONG)mData.mOpenInfo.mOpenMode.length() + 1);
    paParms[i++].setPointer((void*)mData.mOpenInfo.mDisposition.c_str(),
                            (ULONG)mData.mOpenInfo.mDisposition.length() + 1);
    paParms[i++].setPointer((void*)mData.mOpenInfo.mSharingMode.c_str(),
                            (ULONG)mData.mOpenInfo.mSharingMode.length() + 1);
    paParms[i++].setUInt32(mData.mOpenInfo.mCreationMode);
    paParms[i++].setUInt64(mData.mOpenInfo.mInitialOffset);

    alock.release(); /* Drop write lock before sending. */

    vrc = sendCommand(HOST_FILE_OPEN, i, paParms);
    if (RT_SUCCESS(vrc))
        vrc = waitForStatusChange(pEvent, uTimeoutMS,
                                  NULL /* FileStatus */, pGuestRc);

    unregisterWaitEvent(pEvent);

    LogFlowFuncLeaveRC(vrc);
    return vrc;
}
Пример #4
0
int GuestFile::i_openFile(uint32_t uTimeoutMS, int *pGuestRc)
{
    LogFlowThisFuncEnter();

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    LogFlowThisFunc(("strFile=%s, enmAccessMode=%d (%s) enmOpenAction=%d (%s) uCreationMode=%RU32, mfOpenEx=%RU32\n",
                     mData.mOpenInfo.mFileName.c_str(), mData.mOpenInfo.mAccessMode, mData.mOpenInfo.mpszAccessMode,
                     mData.mOpenInfo.mOpenAction, mData.mOpenInfo.mpszOpenAction, mData.mOpenInfo.mCreationMode,
                     mData.mOpenInfo.mfOpenEx));
    int vrc;

    GuestWaitEvent *pEvent = NULL;
    GuestEventTypes eventTypes;
    try
    {
        eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged);

        vrc = registerWaitEvent(eventTypes, &pEvent);
    }
    catch (std::bad_alloc)
    {
        vrc = VERR_NO_MEMORY;
    }

    if (RT_FAILURE(vrc))
        return vrc;

    /* Prepare HGCM call. */
    VBOXHGCMSVCPARM paParms[8];
    int i = 0;
    paParms[i++].setUInt32(pEvent->ContextID());
    paParms[i++].setPointer((void*)mData.mOpenInfo.mFileName.c_str(),
                            (ULONG)mData.mOpenInfo.mFileName.length() + 1);
    paParms[i++].setString(mData.mOpenInfo.mpszAccessMode);
    paParms[i++].setString(mData.mOpenInfo.mpszOpenAction);
    paParms[i++].setString(""); /** @todo sharing mode. */
    paParms[i++].setUInt32(mData.mOpenInfo.mCreationMode);
    paParms[i++].setUInt64(0 /* initial offset */);
    /** @todo Next protocol version: add flags, replace strings, remove initial offset. */

    alock.release(); /* Drop write lock before sending. */

    vrc = sendCommand(HOST_FILE_OPEN, i, paParms);
    if (RT_SUCCESS(vrc))
        vrc = i_waitForStatusChange(pEvent, uTimeoutMS,
                                    NULL /* FileStatus */, pGuestRc);

    unregisterWaitEvent(pEvent);

    LogFlowFuncLeaveRC(vrc);
    return vrc;
}
Пример #5
0
int GuestFile::i_seekAt(int64_t iOffset, GUEST_FILE_SEEKTYPE eSeekType,
                        uint32_t uTimeoutMS, uint64_t *puOffset)
{
    LogFlowThisFunc(("iOffset=%RI64, uTimeoutMS=%RU32\n",
                     iOffset, uTimeoutMS));

    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);

    int vrc;

    GuestWaitEvent *pEvent = NULL;
    GuestEventTypes eventTypes;
    try
    {
        eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged);
        eventTypes.push_back(VBoxEventType_OnGuestFileOffsetChanged);

        vrc = registerWaitEvent(eventTypes, &pEvent);
    }
    catch (std::bad_alloc)
    {
        vrc = VERR_NO_MEMORY;
    }

    if (RT_FAILURE(vrc))
        return vrc;

    /* Prepare HGCM call. */
    VBOXHGCMSVCPARM paParms[4];
    int i = 0;
    paParms[i++].setUInt32(pEvent->ContextID());
    paParms[i++].setUInt32(mData.mID /* File handle */);
    paParms[i++].setUInt32(eSeekType /* Seek method */);
    /** @todo uint64_t vs. int64_t! */
    paParms[i++].setUInt64((uint64_t)iOffset /* Offset (in bytes) to start reading */);

    alock.release(); /* Drop write lock before sending. */

    vrc = sendCommand(HOST_FILE_SEEK, i, paParms);
    if (RT_SUCCESS(vrc))
        vrc = i_waitForOffsetChange(pEvent, uTimeoutMS, puOffset);

    unregisterWaitEvent(pEvent);

    LogFlowFuncLeaveRC(vrc);
    return vrc;
}
Пример #6
0
int GuestBase::signalWaitEventInternalEx(PVBOXGUESTCTRLHOSTCBCTX pCbCtx,
                                         int rc, int guestRc,
                                         const GuestWaitEventPayload *pPayload)
{
    AssertPtrReturn(pCbCtx, VERR_INVALID_POINTER);
    /* pPayload is optional. */

    int rc2;
    GuestWaitEvents::iterator itEvent = mWaitEvents.find(pCbCtx->uContextID);
    if (itEvent != mWaitEvents.end())
    {
        LogFlowThisFunc(("Signalling event=%p (CID %RU32, rc=%Rrc, guestRc=%Rrc, pPayload=%p) ...\n",
                         itEvent->second, itEvent->first, rc, guestRc, pPayload));
        GuestWaitEvent *pEvent = itEvent->second;
        AssertPtr(pEvent);
        rc2 = pEvent->SignalInternal(rc, guestRc, pPayload);
    }
    else
        rc2 = VERR_NOT_FOUND;

    return rc2;
}
Пример #7
0
int GuestBase::cancelWaitEvents(void)
{
    LogFlowThisFuncEnter();

    int rc = RTCritSectEnter(&mWaitEventCritSect);
    if (RT_SUCCESS(rc))
    {
        GuestEventGroup::iterator itEventGroups = mWaitEventGroups.begin();
        while (itEventGroups != mWaitEventGroups.end())
        {
            GuestWaitEvents::iterator itEvents = itEventGroups->second.begin();
            while (itEvents != itEventGroups->second.end())
            {
                GuestWaitEvent *pEvent = itEvents->second;
                AssertPtr(pEvent);

                /*
                 * Just cancel the event, but don't remove it from the
                 * wait events map. Don't delete it though, this (hopefully)
                 * is done by the caller using unregisterWaitEvent().
                 */
                int rc2 = pEvent->Cancel();
                AssertRC(rc2);

                itEvents++;
            }

            itEventGroups++;
        }

        int rc2 = RTCritSectLeave(&mWaitEventCritSect);
        if (RT_SUCCESS(rc))
            rc = rc2;
    }

    LogFlowFuncLeaveRC(rc);
    return rc;
}
Пример #8
0
int GuestFile::i_closeFile(int *pGuestRc)
{
    LogFlowThisFunc(("strFile=%s\n", mData.mOpenInfo.mFileName.c_str()));

    int vrc;

    GuestWaitEvent *pEvent = NULL;
    GuestEventTypes eventTypes;
    try
    {
        eventTypes.push_back(VBoxEventType_OnGuestFileStateChanged);

        vrc = registerWaitEvent(eventTypes, &pEvent);
    }
    catch (std::bad_alloc)
    {
        vrc = VERR_NO_MEMORY;
    }

    if (RT_FAILURE(vrc))
        return vrc;

    /* Prepare HGCM call. */
    VBOXHGCMSVCPARM paParms[4];
    int i = 0;
    paParms[i++].setUInt32(pEvent->ContextID());
    paParms[i++].setUInt32(mData.mID /* Guest file ID */);

    vrc = sendCommand(HOST_FILE_CLOSE, i, paParms);
    if (RT_SUCCESS(vrc))
        vrc = i_waitForStatusChange(pEvent, 30 * 1000 /* Timeout in ms */,
                                    NULL /* FileStatus */, pGuestRc);
    unregisterWaitEvent(pEvent);

    LogFlowFuncLeaveRC(vrc);
    return vrc;
}