GuestFileImpl.cpp revision d8e12fa5dd1c35282b98cb165e42b6b395cf971b
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * VirtualBox Main - Guest file handling.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Copyright (C) 2012-2013 Oracle Corporation
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * available from http://www.virtualbox.org. This file is free software;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * you can redistribute it and/or modify it under the terms of the GNU
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * General Public License (GPL) as published by the Free Software
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/*******************************************************************************
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync* Header Files *
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync*******************************************************************************/
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync// constructor / destructor
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/////////////////////////////////////////////////////////////////////////////
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync// public initializer/uninitializer for internal purposes only
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/////////////////////////////////////////////////////////////////////////////
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Initializes a file object but does *not* open the file on the guest
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * yet. This is done in the dedidcated openFile call.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @return IPRT status code.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pConsole Pointer to console object.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pSession Pointer to session object.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param uFileID Host-based file ID (part of the context ID).
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param openInfo File opening information.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::init(Console *pConsole, GuestSession *pSession, ULONG uFileID, const GuestFileOpenInfo &openInfo)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("pConsole=%p, pSession=%p, uFileID=%RU32, strPath=%s\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pConsole, pSession, uFileID, openInfo.mFileName.c_str()));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Enclose the state transition NotReady->InInit->Ready. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertReturn(autoInitSpan.isOk(), VERR_OBJECT_DESTROYED);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = bindToSession(pConsole, pSession, uFileID /* Object ID */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Confirm a successful initialization when it's the case. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Uninitializes the instance.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Called from FinalRelease().
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Enclose the state transition Ready->InUninit->NotReady. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Cancel + remove all callbacks + waiters.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Note: Deleting them is the job of the caller!
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync// implementation of public getters/setters for attributes
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/////////////////////////////////////////////////////////////////////////////
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::COMGETTER(CreationMode)(ULONG *aCreationMode)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/** @todo For 4.3: Change ULONG* to BSTR* ?*/
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::COMGETTER(Disposition)(ULONG *aDisposition)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *aDisposition = getDispositionFromString(mData.mOpenInfo.mDisposition);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::COMGETTER(FileName)(BSTR *aFileName)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::COMGETTER(InitialSize)(LONG64 *aInitialSize)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::COMGETTER(Offset)(LONG64 *aOffset)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/** @todo For 4.3: Change ULONG* to BSTR* ?*/
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::COMGETTER(OpenMode)(ULONG *aOpenMode)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *aOpenMode = getOpenModeFromString(mData.mOpenInfo.mOpenMode);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync// private methods
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/////////////////////////////////////////////////////////////////////////////
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("strName=%s, uContextID=%RU32, uFunction=%RU32, pSvcCb=%p\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOpenInfo.mFileName.c_str(), pCbCtx->uContextID, pCbCtx->uFunction, pSvcCb));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Get the optional callback associated to this context ID.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * The callback may not be around anymore if just kept locally by the caller when
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * doing the actual HGCM sending stuff. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync = mData.mCallbacks.find(VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(pCbCtx->uContextID));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("pCallback=%p, CID=%RU32, Count=%RU32\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pCallback, pCbCtx->uContextID, VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(pCbCtx->uContextID)));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = onGuestDisconnected(pCbCtx, pSvcCb, pCallback); /* Affects all callbacks. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Silently ignore not implemented functions. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("strFile=%s\n", mData.mOpenInfo.mFileName.c_str()));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int i = 1; /* Context ID will be set in sendFileComannd(). */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(mData.mID /* Guest file ID */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_CLOSE, i, paParms, 30 * 1000 /* 30s timeout */,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/* static */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncuint32_t GuestFile::getDispositionFromString(const Utf8Str &strDisposition)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return 0; /** @todo Implement me! */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/* static */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncuint32_t GuestFile::getOpenModeFromString(const Utf8Str &strOpenMode)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync switch (*pc++)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Silently skip unknown values. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/* static */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /** @todo pData->u32Flags: int vs. uint32 -- IPRT errors are *negative* !!! */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt(tr("VMM device is not available (is the VM running?)"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt(tr("The guest execution service is not available"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt(tr("The guest did not respond within time"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt(tr("The session operation was canceled"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt(tr("Maximum number of concurrent guest files has been reached"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case VERR_NOT_EQUAL: /** @todo Imprecise to the user; can mean anything and all. */
46fd1b35e55cbd736b7abe0d856a940f0336eb81vboxsync strError += Utf8StrFmt(tr("Unable to retrieve requested information"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt(tr("The guest execution service is not ready (yet)"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::onFileNotify(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* pCallback is optional. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* pSvcCb->mpaParms[0] always contains the context ID. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.uType);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* No extra data. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.open.uHandle);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertMsg(mData.mID == 0, ("File ID already set to %RU32\n", mData.mID));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertMsg(mData.mID == VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID),
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync ("File ID %RU32 does not match context ID %RU32\n", mData.mID,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pCbCtx->uContextID)));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* No extra data. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getPointer(&dataCb.u.read.pvData,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.write.cbWritten);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.seek.uOffActual);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.tell.uOffActual);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("strName=%s, uType=%RU32, rc=%Rrc, pCallback=%p\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOpenInfo.mFileName.c_str(), dataCb.uType, dataCb.rc, pCallback));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int guestRc = (int)dataCb.rc; /* uint32_t vs. int. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Nothing to do here yet. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Also let the callback know. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Signal callback in every case (if available). */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int rc2 = pCallback->SetData(&dataCb, sizeof(dataCb));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::onGuestDisconnected(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* pCallback is optional. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* First, signal callback in every case. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /** @todo More on onGuestDisconnected? */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("strFile=%s, strOpenMode=%s, strDisposition=%s, uCreationMode=%RU32\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOpenInfo.mFileName.c_str(), mData.mOpenInfo.mOpenMode.c_str(),
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOpenInfo.mDisposition.c_str(), mData.mOpenInfo.mCreationMode));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int i = 1; /* Context ID will be set in sendFileComannd(). */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setPointer((void*)mData.mOpenInfo.mFileName.c_str(),
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setPointer((void*)mData.mOpenInfo.mOpenMode.c_str(),
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setPointer((void*)mData.mOpenInfo.mDisposition.c_str(),
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(mData.mOpenInfo.mCreationMode);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt64(mData.mOpenInfo.mInitialOffset);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_OPEN, i, paParms, 30 * 1000 /* 30s timeout */,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::readData(uint32_t uSize, uint32_t uTimeoutMS, void *pvData, size_t cbData,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("uSize=%RU32, uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int i = 1; /* Context ID will be set in sendFileComannd(). */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(mData.mID /* File handle */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(uSize /* Size (in bytes) to read */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_READ, i, paParms, uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pCallback->GetDataSize() == sizeof(CALLBACKDATA_FILE_NOTIFY));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync PCALLBACKDATA_FILE_NOTIFY pData = (PCALLBACKDATA_FILE_NOTIFY)pCallback->GetDataRaw();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pData->uType == GUEST_FILE_NOTIFYTYPE_READ);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::readDataAt(uint64_t uOffset, uint32_t uSize, uint32_t uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("uOffset=%RU64, uSize=%RU32, uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int i = 1; /* Context ID will be set in sendFileComannd(). */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(mData.mID /* File handle */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt64(uOffset /* Offset (in bytes) to start reading */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(uSize /* Size (in bytes) to read */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_READ_AT, i, paParms, uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pCallback->GetDataSize() == sizeof(CALLBACKDATA_FILE_NOTIFY));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync PCALLBACKDATA_FILE_NOTIFY pData = (PCALLBACKDATA_FILE_NOTIFY)pCallback->GetDataRaw();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pData->uType == GUEST_FILE_NOTIFYTYPE_READ);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::seekAt(uint64_t uOffset, GUEST_FILE_SEEKTYPE eSeekType,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("uOffset=%RU64, uTimeoutMS=%RU32\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int i = 1; /* Context ID will be set in sendFileComannd(). */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(mData.mID /* File handle */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(eSeekType /* Seek method */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt64(uOffset /* Offset (in bytes) to start reading */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_SEEK, i, paParms, uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Handles the common parts of sending a file command to the guest.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * If ppCallback is returned it must be removed via callbackRemove()
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * by the caller in any case.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @return IPRT status code.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param uFunction HGCM function of command to send.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param uParms Number of HGCM parameters to send.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * At least one parameter must be present.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param paParms Array of HGCM parameters to send.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Index [0] must not be used and will be
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * filled out by the function.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param uTimeoutMS Timeout (in ms).
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param pGuestRc Guest result. Optional.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * @param ppCallback Pointer which will receive the callback for
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * further processing by the caller. Must
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * be deleted with callbackDelete() when done. Optional.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::sendFileCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uint32_t uTimeoutMS, int *pGuestRc, GuestCtrlCallback **ppCallback)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /** pGuestRc is optional. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /** ppCallback is optional. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("strFile=%s, uFunction=%RU32, uParms=%RU32\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOpenInfo.mFileName.c_str(), uFunction, uParms));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uint32_t uProtocol = mData.mSession->getProtocolVersion();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Create callback and add it to the map. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Assign context ID. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Note: Don't hold the write lock in here. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Let's wait for the process being started.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Note: Be sure not keeping a AutoRead/WriteLock here.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("Waiting for callback (%RU32ms) ...\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc)) /* Wait was successful, check for supplied information. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Nothing to do here yet. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("Callback returned rc=%Rrc\n", guestRc));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Return callback to the caller which then will be
21fe567f85453e9865063d3d51464d189de5a867vboxsync * responsible for removing it. Don't forget to lock write
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * access before using this callback then! */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/* static */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncHRESULT GuestFile::setErrorExternal(VirtualBoxBase *pInterface, int guestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertMsg(RT_FAILURE(guestRc), ("Guest rc does not indicate a failure when setting error\n"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return pInterface->setError(VBOX_E_IPRT_ERROR, GuestFile::guestErrorToString(guestRc).c_str());
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::writeData(uint32_t uTimeoutMS, void *pvData, size_t cbData,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int i = 1; /* Context ID will be set in sendFileComannd(). */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(mData.mID /* File handle */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(cbData /* Size (in bytes) to write */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_WRITE, i, paParms, uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pCallback->GetDataSize() == sizeof(CALLBACKDATA_FILE_NOTIFY));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync PCALLBACKDATA_FILE_NOTIFY pData = (PCALLBACKDATA_FILE_NOTIFY)pCallback->GetDataRaw();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pData->uType == GUEST_FILE_NOTIFYTYPE_WRITE);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::writeDataAt(uint64_t uOffset, uint32_t uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("uOffset=%RU64, uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int i = 1; /* Context ID will be set in sendFileComannd(). */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(mData.mID /* File handle */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt64(uOffset /* Offset where to starting writing */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(cbData /* Size (in bytes) to write */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_WRITE_AT, i, paParms, uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pCallback->GetDataSize() == sizeof(CALLBACKDATA_FILE_NOTIFY));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync PCALLBACKDATA_FILE_NOTIFY pData = (PCALLBACKDATA_FILE_NOTIFY)pCallback->GetDataRaw();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pData->uType == GUEST_FILE_NOTIFYTYPE_WRITE);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync// implementation of public methods
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/////////////////////////////////////////////////////////////////////////////
int guestRc;
uninit();
return S_OK;
#ifndef VBOX_WITH_GUEST_CONTROL
#ifndef VBOX_WITH_GUEST_CONTROL
if (aToRead == 0)
switch (vrc)
case VERR_GSTCTL_GUEST_ERROR:
return hr;
STDMETHODIMP GuestFile::ReadAt(LONG64 aOffset, ULONG aToRead, ULONG aTimeoutMS, ComSafeArrayOut(BYTE, aData))
#ifndef VBOX_WITH_GUEST_CONTROL
if (aToRead == 0)
switch (vrc)
case VERR_GSTCTL_GUEST_ERROR:
return hr;
#ifndef VBOX_WITH_GUEST_CONTROL
switch (aType)
case FileSeekType_Set:
case FileSeekType_Current:
int guestRc;
switch (vrc)
case VERR_GSTCTL_GUEST_ERROR:
return hr;
#ifndef VBOX_WITH_GUEST_CONTROL
#ifndef VBOX_WITH_GUEST_CONTROL
switch (vrc)
case VERR_GSTCTL_GUEST_ERROR:
return hr;
STDMETHODIMP GuestFile::WriteAt(LONG64 aOffset, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten)
#ifndef VBOX_WITH_GUEST_CONTROL
switch (vrc)
case VERR_GSTCTL_GUEST_ERROR:
return hr;