GuestFileImpl.cpp revision d8e12fa5dd1c35282b98cb165e42b6b395cf971b
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/* $Id$ */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/** @file
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * VirtualBox Main - Guest file handling.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/*
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Copyright (C) 2012-2013 Oracle Corporation
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *
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
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/*******************************************************************************
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync* Header Files *
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync*******************************************************************************/
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#include "GuestFileImpl.h"
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#include "GuestSessionImpl.h"
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#include "GuestCtrlImplPrivate.h"
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#include "ConsoleImpl.h"
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#include "Global.h"
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#include "AutoCaller.h"
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#include <iprt/file.h>
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#include <VBox/com/array.h>
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#ifdef LOG_GROUP
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync #undef LOG_GROUP
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#define LOG_GROUP LOG_GROUP_GUEST_CONTROL
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#include <VBox/log.h>
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync// constructor / destructor
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/////////////////////////////////////////////////////////////////////////////
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncDEFINE_EMPTY_CTOR_DTOR(GuestFile)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncHRESULT GuestFile::FinalConstruct(void)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("\n"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return BaseFinalConstruct();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncvoid GuestFile::FinalRelease(void)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFuncEnter();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uninit();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync BaseFinalRelease();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFuncLeave();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync// public initializer/uninitializer for internal purposes only
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/////////////////////////////////////////////////////////////////////////////
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
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 *
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.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::init(Console *pConsole, GuestSession *pSession, ULONG uFileID, const GuestFileOpenInfo &openInfo)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("pConsole=%p, pSession=%p, uFileID=%RU32, strPath=%s\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pConsole, pSession, uFileID, openInfo.mFileName.c_str()));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtrReturn(pConsole, VERR_INVALID_POINTER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtrReturn(pSession, VERR_INVALID_POINTER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Enclose the state transition NotReady->InInit->Ready. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoInitSpan autoInitSpan(this);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertReturn(autoInitSpan.isOk(), VERR_OBJECT_DESTROYED);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = bindToSession(pConsole, pSession, uFileID /* Object ID */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mID = 0;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mInitialSize = 0;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Confirm a successful initialization when it's the case. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync autoInitSpan.setSucceeded();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync autoInitSpan.setFailed();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/**
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Uninitializes the instance.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Called from FinalRelease().
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncvoid GuestFile::uninit(void)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("\n"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Enclose the state transition Ready->InUninit->NotReady. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoUninitSpan autoUninitSpan(this);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (autoUninitSpan.uninitDone())
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#ifdef VBOX_WITH_GUEST_CONTROL
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /*
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Cancel + remove all callbacks + waiters.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Note: Deleting them is the job of the caller!
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync callbackRemoveAll();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFuncLeave();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync// implementation of public getters/setters for attributes
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/////////////////////////////////////////////////////////////////////////////
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::COMGETTER(CreationMode)(ULONG *aCreationMode)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#ifndef VBOX_WITH_GUEST_CONTROL
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync ReturnComNotImplemented();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoCaller autoCaller(this);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync CheckComArgOutPointerValid(aCreationMode);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *aCreationMode = mData.mOpenInfo.mCreationMode;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return S_OK;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/** @todo For 4.3: Change ULONG* to BSTR* ?*/
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::COMGETTER(Disposition)(ULONG *aDisposition)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#ifndef VBOX_WITH_GUEST_CONTROL
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync ReturnComNotImplemented();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoCaller autoCaller(this);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync CheckComArgOutPointerValid(aDisposition);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *aDisposition = getDispositionFromString(mData.mOpenInfo.mDisposition);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return S_OK;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::COMGETTER(FileName)(BSTR *aFileName)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#ifndef VBOX_WITH_GUEST_CONTROL
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync ReturnComNotImplemented();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoCaller autoCaller(this);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync CheckComArgOutPointerValid(aFileName);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOpenInfo.mFileName.cloneTo(aFileName);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return S_OK;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::COMGETTER(InitialSize)(LONG64 *aInitialSize)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#ifndef VBOX_WITH_GUEST_CONTROL
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync ReturnComNotImplemented();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoCaller autoCaller(this);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync CheckComArgOutPointerValid(aInitialSize);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *aInitialSize = mData.mInitialSize;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return S_OK;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::COMGETTER(Offset)(LONG64 *aOffset)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#ifndef VBOX_WITH_GUEST_CONTROL
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync ReturnComNotImplemented();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoCaller autoCaller(this);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync CheckComArgOutPointerValid(aOffset);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *aOffset = mData.mOffCurrent;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return S_OK;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/** @todo For 4.3: Change ULONG* to BSTR* ?*/
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::COMGETTER(OpenMode)(ULONG *aOpenMode)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#ifndef VBOX_WITH_GUEST_CONTROL
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync ReturnComNotImplemented();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoCaller autoCaller(this);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync CheckComArgOutPointerValid(aOpenMode);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *aOpenMode = getOpenModeFromString(mData.mOpenInfo.mOpenMode);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return S_OK;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync// private methods
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/////////////////////////////////////////////////////////////////////////////
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#ifdef DEBUG
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("strName=%s, uContextID=%RU32, uFunction=%RU32, pSvcCb=%p\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOpenInfo.mFileName.c_str(), pCbCtx->uContextID, pCbCtx->uFunction, pSvcCb));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
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 GuestCtrlCallback *pCallback = NULL;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync GuestCtrlCallbacks::const_iterator it
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync = mData.mCallbacks.find(VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(pCbCtx->uContextID));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (it != mData.mCallbacks.end())
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pCallback = it->second;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtr(pCallback);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#ifdef DEBUG
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("pCallback=%p, CID=%RU32, Count=%RU32\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pCallback, pCbCtx->uContextID, VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(pCbCtx->uContextID)));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync switch (pCbCtx->uFunction)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case GUEST_DISCONNECTED:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = onGuestDisconnected(pCbCtx, pSvcCb, pCallback); /* Affects all callbacks. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case GUEST_FILE_NOTIFY:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = onFileNotify(pCbCtx, pSvcCb, pCallback);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync default:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Silently ignore not implemented functions. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = VERR_NOT_SUPPORTED;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#ifdef DEBUG
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowFuncLeaveRC(vrc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#endif
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::closeFile(int *pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("strFile=%s\n", mData.mOpenInfo.mFileName.c_str()));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync VBOXHGCMSVCPARM paParms[4];
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int i = 1; /* Context ID will be set in sendFileComannd(). */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(mData.mID /* Guest file ID */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_CLOSE, i, paParms, 30 * 1000 /* 30s timeout */,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync &guestRc, NULL /* ppCallback */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *pGuestRc = guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowFuncLeaveRC(vrc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/* static */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncuint32_t GuestFile::getDispositionFromString(const Utf8Str &strDisposition)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return 0; /** @todo Implement me! */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/* static */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncuint32_t GuestFile::getOpenModeFromString(const Utf8Str &strOpenMode)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uint32_t uOpenMode = 0;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync const char *pc = strOpenMode.c_str();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync while (*pc != '\0')
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync switch (*pc++)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case 'r':
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uOpenMode |= RTFILE_O_READ;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case 'w':
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uOpenMode |= RTFILE_O_WRITE;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync default:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Silently skip unknown values. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return uOpenMode;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/* static */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncUtf8Str GuestFile::guestErrorToString(int guestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Utf8Str strError;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /** @todo pData->u32Flags: int vs. uint32 -- IPRT errors are *negative* !!! */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync switch (guestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case VERR_INVALID_VM_HANDLE:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt(tr("VMM device is not available (is the VM running?)"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case VERR_HGCM_SERVICE_NOT_FOUND:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt(tr("The guest execution service is not available"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case VERR_TIMEOUT:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt(tr("The guest did not respond within time"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case VERR_CANCELLED:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt(tr("The session operation was canceled"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case VERR_MAX_PROCS_REACHED:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt(tr("Maximum number of concurrent guest files has been reached"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
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 break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case VERR_NOT_FOUND:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt(tr("The guest execution service is not ready (yet)"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync default:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync strError += Utf8StrFmt("%Rrc", guestRc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return strError;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::onFileNotify(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync GuestCtrlCallback *pCallback)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtrReturn(pCbCtx, VERR_INVALID_POINTER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtrReturn(pSvcCbData, VERR_INVALID_POINTER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* pCallback is optional. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pSvcCbData->mParms < 3)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return VERR_INVALID_PARAMETER;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = VINF_SUCCESS;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int idx = 0; /* Current parameter index. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync CALLBACKDATA_FILE_NOTIFY dataCb;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* pSvcCb->mpaParms[0] always contains the context ID. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.uType);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.rc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync switch (dataCb.uType)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case GUEST_FILE_NOTIFYTYPE_ERROR:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* No extra data. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case GUEST_FILE_NOTIFYTYPE_OPEN:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pSvcCbData->mParms == 4)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.open.uHandle);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertMsg(mData.mID == 0, ("File ID already set to %RU32\n", mData.mID));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mID = dataCb.u.open.uHandle;
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 }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = VERR_NOT_SUPPORTED;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case GUEST_FILE_NOTIFYTYPE_CLOSE:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* No extra data. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case GUEST_FILE_NOTIFYTYPE_READ:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pSvcCbData->mParms == 4)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getPointer(&dataCb.u.read.pvData,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync &dataCb.u.read.cbData);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOffCurrent += dataCb.u.read.cbData;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = VERR_NOT_SUPPORTED;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case GUEST_FILE_NOTIFYTYPE_WRITE:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pSvcCbData->mParms == 4)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getUInt32(&dataCb.u.write.cbWritten);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOffCurrent += dataCb.u.write.cbWritten;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = VERR_NOT_SUPPORTED;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case GUEST_FILE_NOTIFYTYPE_SEEK:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pSvcCbData->mParms == 4)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.seek.uOffActual);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOffCurrent = dataCb.u.seek.uOffActual;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = VERR_NOT_SUPPORTED;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync case GUEST_FILE_NOTIFYTYPE_TELL:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pSvcCbData->mParms == 4)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pSvcCbData->mpaParms[idx++].getUInt64(&dataCb.u.tell.uOffActual);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOffCurrent = dataCb.u.tell.uOffActual;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = VERR_NOT_SUPPORTED;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync default:
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = VERR_NOT_SUPPORTED;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync break;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("strName=%s, uType=%RU32, rc=%Rrc, pCallback=%p\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOpenInfo.mFileName.c_str(), dataCb.uType, dataCb.rc, pCallback));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int guestRc = (int)dataCb.rc; /* uint32_t vs. int. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Nothing to do here yet. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync else if (vrc == VERR_NOT_SUPPORTED)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Also let the callback know. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync guestRc = VERR_NOT_SUPPORTED;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Signal callback in every case (if available). */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pCallback)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int rc2 = pCallback->SetData(&dataCb, sizeof(dataCb));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = rc2;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync rc2 = pCallback->Signal(guestRc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = rc2;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowFuncLeaveRC(vrc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::onGuestDisconnected(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync GuestCtrlCallback *pCallback)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtrReturn(pCbCtx, VERR_INVALID_POINTER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtrReturn(pSvcCbData, VERR_INVALID_POINTER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* pCallback is optional. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("strFile=%s, pCallback=%p\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOpenInfo.mFileName.c_str(), pCallback));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* First, signal callback in every case. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pCallback)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pCallback->Signal();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /** @todo More on onGuestDisconnected? */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = VINF_SUCCESS;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowFuncLeaveRC(vrc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::openFile(int *pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
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
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync VBOXHGCMSVCPARM paParms[8];
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int i = 1; /* Context ID will be set in sendFileComannd(). */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setPointer((void*)mData.mOpenInfo.mFileName.c_str(),
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync (ULONG)mData.mOpenInfo.mFileName.length() + 1);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setPointer((void*)mData.mOpenInfo.mOpenMode.c_str(),
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync (ULONG)mData.mOpenInfo.mOpenMode.length() + 1);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setPointer((void*)mData.mOpenInfo.mDisposition.c_str(),
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync (ULONG)mData.mOpenInfo.mDisposition.length() + 1);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt32(mData.mOpenInfo.mCreationMode);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[i++].setUInt64(mData.mOpenInfo.mInitialOffset);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_OPEN, i, paParms, 30 * 1000 /* 30s timeout */,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pGuestRc, NULL /* ppCallback */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowFuncLeaveRC(vrc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::readData(uint32_t uSize, uint32_t uTimeoutMS, void *pvData, size_t cbData,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync size_t *pcbRead, int *pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("uSize=%RU32, uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uSize, uTimeoutMS, pvData, cbData));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync VBOXHGCMSVCPARM paParms[4];
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
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync GuestCtrlCallback *pCallback = NULL; int guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_READ, i, paParms, uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync &guestRc, &pCallback);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pCallback->GetDataSize() == sizeof(CALLBACKDATA_FILE_NOTIFY));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync PCALLBACKDATA_FILE_NOTIFY pData = (PCALLBACKDATA_FILE_NOTIFY)pCallback->GetDataRaw();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtr(pData);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pData->uType == GUEST_FILE_NOTIFYTYPE_READ);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync size_t cbRead = pData->u.read.cbData;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (cbRead)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(cbData >= cbRead);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync memcpy(pvData, pData->u.read.pvData, cbRead);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("cbRead=%RU32\n", cbRead));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pcbRead)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *pcbRead = cbRead;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync callbackDelete(pCallback);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *pGuestRc = guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowFuncLeaveRC(vrc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::readDataAt(uint64_t uOffset, uint32_t uSize, uint32_t uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync void *pvData, size_t cbData,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync size_t *pcbRead, int *pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("uOffset=%RU64, uSize=%RU32, uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uOffset, uSize, uTimeoutMS, pvData, cbData));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync VBOXHGCMSVCPARM paParms[4];
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
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync GuestCtrlCallback *pCallback = NULL; int guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_READ_AT, i, paParms, uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync &guestRc, &pCallback);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pCallback->GetDataSize() == sizeof(CALLBACKDATA_FILE_NOTIFY));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync PCALLBACKDATA_FILE_NOTIFY pData = (PCALLBACKDATA_FILE_NOTIFY)pCallback->GetDataRaw();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtr(pData);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pData->uType == GUEST_FILE_NOTIFYTYPE_READ);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync size_t cbRead = pData->u.read.cbData;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (cbRead)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(cbData >= cbRead);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync memcpy(pvData, pData->u.read.pvData, cbRead);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("cbRead=%RU32\n", cbRead));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pcbRead)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *pcbRead = cbRead;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync callbackDelete(pCallback);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *pGuestRc = guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowFuncLeaveRC(vrc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::seekAt(uint64_t uOffset, GUEST_FILE_SEEKTYPE eSeekType,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uint32_t uTimeoutMS, int *pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("uOffset=%RU64, uTimeoutMS=%RU32\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uOffset, uTimeoutMS));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync VBOXHGCMSVCPARM paParms[4];
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
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_SEEK, i, paParms, uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync &guestRc, NULL /* ppCallback */);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *pGuestRc = guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowFuncLeaveRC(vrc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/**
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 *
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.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::sendFileCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uint32_t uTimeoutMS, int *pGuestRc, GuestCtrlCallback **ppCallback)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertReturn(uParms, VERR_INVALID_PARAMETER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtrReturn(paParms, VERR_INVALID_POINTER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /** pGuestRc is optional. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /** ppCallback is optional. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("strFile=%s, uFunction=%RU32, uParms=%RU32\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync mData.mOpenInfo.mFileName.c_str(), uFunction, uParms));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtr(mData.mSession);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uint32_t uProtocol = mData.mSession->getProtocolVersion();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (uProtocol < 2)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return VERR_NOT_SUPPORTED;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = VINF_SUCCESS;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uint32_t uContextID = 0;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync GuestCtrlCallback *pCallback;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync try
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync pCallback = new GuestCtrlCallback();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync catch(std::bad_alloc &)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = VERR_NO_MEMORY;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Create callback and add it to the map. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = pCallback->Init(CALLBACKTYPE_FILE_NOTIFY);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = callbackAdd(pCallback, &uContextID);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Assign context ID. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync paParms[0].setUInt32(uContextID);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync GuestSession *pSession = mData.mSession;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtr(pSession);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync alock.release(); /* Drop the write lock again. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Note: Don't hold the write lock in here. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = sendCommand(uFunction, uParms, paParms);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /*
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Let's wait for the process being started.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync * Note: Be sure not keeping a AutoRead/WriteLock here.
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("Waiting for callback (%RU32ms) ...\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uTimeoutMS));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = pCallback->Wait(uTimeoutMS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc)) /* Wait was successful, check for supplied information. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int guestRc = pCallback->GetResultCode();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(guestRc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Nothing to do here yet. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = VERR_GSTCTL_GUEST_ERROR;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *pGuestRc = guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("Callback returned rc=%Rrc\n", guestRc));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync alock.acquire(); /* Get write lock again. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtr(pCallback);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int rc2 = callbackRemove(uContextID);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync vrc = rc2;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (ppCallback)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
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 *ppCallback = pCallback;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync delete pCallback;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowFuncLeaveRC(vrc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/* static */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncHRESULT GuestFile::setErrorExternal(VirtualBoxBase *pInterface, int guestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtr(pInterface);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertMsg(RT_FAILURE(guestRc), ("Guest rc does not indicate a failure when setting error\n"));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return pInterface->setError(VBOX_E_IPRT_ERROR, GuestFile::guestErrorToString(guestRc).c_str());
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::writeData(uint32_t uTimeoutMS, void *pvData, size_t cbData,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uint32_t *pcbWritten, int *pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertReturn(cbData, VERR_INVALID_PARAMETER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uTimeoutMS, pvData, cbData));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync VBOXHGCMSVCPARM paParms[4];
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 paParms[i++].setPointer(pvData, cbData);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync GuestCtrlCallback *pCallback = NULL; int guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_WRITE, i, paParms, uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync &guestRc, &pCallback);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pCallback->GetDataSize() == sizeof(CALLBACKDATA_FILE_NOTIFY));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync PCALLBACKDATA_FILE_NOTIFY pData = (PCALLBACKDATA_FILE_NOTIFY)pCallback->GetDataRaw();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtr(pData);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pData->uType == GUEST_FILE_NOTIFYTYPE_WRITE);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync size_t cbWritten = pData->u.write.cbWritten;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("cbWritten=%RU32\n", cbWritten));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pcbWritten)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *pcbWritten = cbWritten;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync callbackDelete(pCallback);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *pGuestRc = guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowFuncLeaveRC(vrc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncint GuestFile::writeDataAt(uint64_t uOffset, uint32_t uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync void *pvData, size_t cbData,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uint32_t *pcbWritten, int *pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertReturn(cbData, VERR_INVALID_PARAMETER);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("uOffset=%RU64, uTimeoutMS=%RU32, pvData=%p, cbData=%zu\n",
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync uOffset, uTimeoutMS, pvData, cbData));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync /* Prepare HGCM call. */
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync VBOXHGCMSVCPARM paParms[4];
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 paParms[i++].setPointer(pvData, cbData);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync GuestCtrlCallback *pCallback = NULL; int guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync int vrc = sendFileCommand(HOST_FILE_WRITE_AT, i, paParms, uTimeoutMS,
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync &guestRc, &pCallback);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (RT_SUCCESS(vrc))
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync {
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pCallback->GetDataSize() == sizeof(CALLBACKDATA_FILE_NOTIFY));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync PCALLBACKDATA_FILE_NOTIFY pData = (PCALLBACKDATA_FILE_NOTIFY)pCallback->GetDataRaw();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync AssertPtr(pData);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync Assert(pData->uType == GUEST_FILE_NOTIFYTYPE_WRITE);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync size_t cbWritten = pData->u.write.cbWritten;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFunc(("cbWritten=%RU32\n", cbWritten));
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pcbWritten)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *pcbWritten = cbWritten;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync }
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync callbackDelete(pCallback);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync if (pGuestRc)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync *pGuestRc = guestRc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowFuncLeaveRC(vrc);
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync return vrc;
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync}
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync// implementation of public methods
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync/////////////////////////////////////////////////////////////////////////////
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsyncSTDMETHODIMP GuestFile::Close(void)
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync{
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#ifndef VBOX_WITH_GUEST_CONTROL
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync ReturnComNotImplemented();
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync#else
1c2c968fd241148110002d75b2c0fdeddc211e14vboxsync LogFlowThisFuncEnter();
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
/* Close file on guest. */
int guestRc;
int rc = closeFile(&guestRc);
/* On failure don't return here, instead do all the cleanup
* work first and then return an error. */
AssertPtr(mData.mSession);
int rc2 = mData.mSession->fileRemoveFromList(this);
if (RT_SUCCESS(rc))
rc = rc2;
/*
* Release autocaller before calling uninit.
*/
autoCaller.release();
uninit();
LogFlowFuncLeaveRC(rc);
if (RT_FAILURE(rc))
{
if (rc == VERR_GSTCTL_GUEST_ERROR)
return GuestFile::setErrorExternal(this, guestRc);
return setError(VBOX_E_IPRT_ERROR,
tr("Closing guest file failed with %Rrc\n"), rc);
}
return S_OK;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestFile::QueryInfo(IFsObjInfo **aInfo)
{
#ifndef VBOX_WITH_GUEST_CONTROL
ReturnComNotImplemented();
#else
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
ReturnComNotImplemented();
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestFile::Read(ULONG aToRead, ULONG aTimeoutMS, ComSafeArrayOut(BYTE, aData))
{
#ifndef VBOX_WITH_GUEST_CONTROL
ReturnComNotImplemented();
#else
if (aToRead == 0)
return setError(E_INVALIDARG, tr("The size to read is zero"));
CheckComArgOutSafeArrayPointerValid(aData);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
com::SafeArray<BYTE> data((size_t)aToRead);
Assert(data.size() >= aToRead);
HRESULT hr = S_OK;
size_t cbRead; int guestRc;
int vrc = readData(aToRead, aTimeoutMS,
data.raw(), aToRead, &cbRead, &guestRc);
if (RT_SUCCESS(vrc))
{
if (data.size() != cbRead)
data.resize(cbRead);
data.detachTo(ComSafeArrayOutArg(aData));
}
else
{
switch (vrc)
{
case VERR_GSTCTL_GUEST_ERROR:
hr = GuestFile::setErrorExternal(this, guestRc);
break;
default:
hr = setError(VBOX_E_IPRT_ERROR,
tr("Reading from file \"%s\" failed: %Rrc"),
mData.mOpenInfo.mFileName.c_str(), vrc);
break;
}
}
LogFlowThisFunc(("rc=%Rrc, cbRead=%RU64\n", vrc, cbRead));
LogFlowFuncLeaveRC(vrc);
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestFile::ReadAt(LONG64 aOffset, ULONG aToRead, ULONG aTimeoutMS, ComSafeArrayOut(BYTE, aData))
{
#ifndef VBOX_WITH_GUEST_CONTROL
ReturnComNotImplemented();
#else
if (aToRead == 0)
return setError(E_INVALIDARG, tr("The size to read is zero"));
CheckComArgOutSafeArrayPointerValid(aData);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
com::SafeArray<BYTE> data((size_t)aToRead);
Assert(data.size() >= aToRead);
HRESULT hr = S_OK;
size_t cbRead; int guestRc;
int vrc = readDataAt(aOffset, aToRead, aTimeoutMS,
data.raw(), aToRead, &cbRead, &guestRc);
if (RT_SUCCESS(vrc))
{
if (data.size() != cbRead)
data.resize(cbRead);
data.detachTo(ComSafeArrayOutArg(aData));
}
else
{
switch (vrc)
{
case VERR_GSTCTL_GUEST_ERROR:
hr = GuestFile::setErrorExternal(this, guestRc);
break;
default:
hr = setError(VBOX_E_IPRT_ERROR,
tr("Reading from file \"%s\" (at offset %RU64) failed: %Rrc"),
mData.mOpenInfo.mFileName.c_str(), aOffset, vrc);
break;
}
}
LogFlowThisFunc(("rc=%Rrc, cbRead=%RU64\n", vrc, cbRead));
LogFlowFuncLeaveRC(vrc);
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestFile::Seek(LONG64 aOffset, FileSeekType_T aType)
{
#ifndef VBOX_WITH_GUEST_CONTROL
ReturnComNotImplemented();
#else
LogFlowThisFuncEnter();
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
HRESULT hr = S_OK;
GUEST_FILE_SEEKTYPE eSeekType;
switch (aType)
{
case FileSeekType_Set:
eSeekType = GUEST_FILE_SEEKTYPE_BEGIN;
break;
case FileSeekType_Current:
eSeekType = GUEST_FILE_SEEKTYPE_CURRENT;
break;
default:
return setError(E_INVALIDARG, tr("Invalid seek type specified"));
break;
}
int guestRc;
int vrc = seekAt(aOffset, eSeekType,
30 * 1000 /* 30s timeout */, &guestRc);
if (RT_FAILURE(vrc))
{
switch (vrc)
{
case VERR_GSTCTL_GUEST_ERROR:
hr = GuestFile::setErrorExternal(this, guestRc);
break;
default:
hr = setError(VBOX_E_IPRT_ERROR,
tr("Seeking file \"%s\" (to offset %RU64) failed: %Rrc"),
mData.mOpenInfo.mFileName.c_str(), aOffset, vrc);
break;
}
}
LogFlowFuncLeaveRC(vrc);
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestFile::SetACL(IN_BSTR aACL)
{
#ifndef VBOX_WITH_GUEST_CONTROL
ReturnComNotImplemented();
#else
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
ReturnComNotImplemented();
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestFile::Write(ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten)
{
#ifndef VBOX_WITH_GUEST_CONTROL
ReturnComNotImplemented();
#else
LogFlowThisFuncEnter();
CheckComArgOutPointerValid(aWritten);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
HRESULT hr = S_OK;
com::SafeArray<BYTE> data(ComSafeArrayInArg(aData)); int guestRc;
int vrc = writeData(aTimeoutMS, data.raw(), data.size(), (uint32_t*)aWritten, &guestRc);
if (RT_FAILURE(vrc))
{
switch (vrc)
{
case VERR_GSTCTL_GUEST_ERROR:
hr = GuestFile::setErrorExternal(this, guestRc);
break;
default:
hr = setError(VBOX_E_IPRT_ERROR,
tr("Writing to file \"%s\" failed: %Rrc"),
mData.mOpenInfo.mFileName.c_str(), vrc);
break;
}
}
LogFlowThisFunc(("rc=%Rrc, aWritten=%RU32\n", vrc, aWritten));
LogFlowFuncLeaveRC(vrc);
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}
STDMETHODIMP GuestFile::WriteAt(LONG64 aOffset, ComSafeArrayIn(BYTE, aData), ULONG aTimeoutMS, ULONG *aWritten)
{
#ifndef VBOX_WITH_GUEST_CONTROL
ReturnComNotImplemented();
#else
LogFlowThisFuncEnter();
CheckComArgOutPointerValid(aWritten);
AutoCaller autoCaller(this);
if (FAILED(autoCaller.rc())) return autoCaller.rc();
HRESULT hr = S_OK;
com::SafeArray<BYTE> data(ComSafeArrayInArg(aData)); int guestRc;
int vrc = writeData(aTimeoutMS, data.raw(), data.size(), (uint32_t*)aWritten, &guestRc);
if (RT_FAILURE(vrc))
{
switch (vrc)
{
case VERR_GSTCTL_GUEST_ERROR:
hr = GuestFile::setErrorExternal(this, guestRc);
break;
default:
hr = setError(VBOX_E_IPRT_ERROR,
tr("Writing to file \"%s\" (at offset %RU64) failed: %Rrc"),
mData.mOpenInfo.mFileName.c_str(), aOffset, vrc);
break;
}
}
LogFlowThisFunc(("rc=%Rrc, aWritten=%RU32\n", vrc, aWritten));
LogFlowFuncLeaveRC(vrc);
return hr;
#endif /* VBOX_WITH_GUEST_CONTROL */
}