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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }