GuestDirectoryImpl.cpp revision 510567648d46488f4166e5f69ffffe3eeeeec4d9
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync/* $Id$ */
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync/** @file
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync * VirtualBox Main - Guest directory handling.
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync */
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync/*
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync * Copyright (C) 2012-2013 Oracle Corporation
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync *
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync * available from http://www.virtualbox.org. This file is free software;
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync * you can redistribute it and/or modify it under the terms of the GNU
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync * General Public License (GPL) as published by the Free Software
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync */
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync/*******************************************************************************
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync* Header Files *
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync*******************************************************************************/
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync#include "GuestDirectoryImpl.h"
576099bc515c7c7349219499579f5729ffea3c35vboxsync#include "GuestSessionImpl.h"
576099bc515c7c7349219499579f5729ffea3c35vboxsync#include "GuestCtrlImplPrivate.h"
576099bc515c7c7349219499579f5729ffea3c35vboxsync
576099bc515c7c7349219499579f5729ffea3c35vboxsync#include "Global.h"
576099bc515c7c7349219499579f5729ffea3c35vboxsync#include "AutoCaller.h"
576099bc515c7c7349219499579f5729ffea3c35vboxsync
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync#include <VBox/com/array.h>
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync#ifdef LOG_GROUP
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync #undef LOG_GROUP
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync#endif
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync#define LOG_GROUP LOG_GROUP_GUEST_CONTROL
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync#include <VBox/log.h>
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync// constructor / destructor
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync/////////////////////////////////////////////////////////////////////////////
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsyncDEFINE_EMPTY_CTOR_DTOR(GuestDirectory)
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsyncHRESULT GuestDirectory::FinalConstruct(void)
352bb6b9d2fa1f7df7797f50c58e297ac37059a2vboxsync{
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync LogFlowThisFunc(("\n"));
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync return BaseFinalConstruct();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync}
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsyncvoid GuestDirectory::FinalRelease(void)
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync{
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync LogFlowThisFuncEnter();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync uninit();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync BaseFinalRelease();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync LogFlowThisFuncLeave();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync}
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync// public initializer/uninitializer for internal purposes only
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync/////////////////////////////////////////////////////////////////////////////
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsyncint GuestDirectory::init(GuestSession *aSession,
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync const Utf8Str &strPath, const Utf8Str &strFilter, uint32_t uFlags)
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync{
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync LogFlowThisFunc(("strPath=%s, strFilter=%s, uFlags=%x\n",
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync strPath.c_str(), strFilter.c_str(), uFlags));
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /* Enclose the state transition NotReady->InInit->Ready. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync AutoInitSpan autoInitSpan(this);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync AssertReturn(autoInitSpan.isOk(), E_FAIL);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync mData.mSession = aSession;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync mData.mName = strPath;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync mData.mFilter = strFilter;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync mData.mFlags = uFlags;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /* Start the directory process on the guest. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync GuestProcessStartupInfo procInfo;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync procInfo.mName = Utf8StrFmt(tr("Reading directory \"%s\"", strPath.c_str()));
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync procInfo.mCommand = Utf8Str(VBOXSERVICE_TOOL_LS);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync procInfo.mTimeoutMS = 5 * 60 * 1000; /* 5 minutes timeout. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync procInfo.mFlags = ProcessCreateFlag_WaitForStdOut;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /* We want the long output format which contains all the object details. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync procInfo.mArguments.push_back(Utf8Str("-l"));
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync#if 0 /* Flags are not supported yet. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (uFlags & DirectoryOpenFlag_NoSymlinks)
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync procInfo.mArguments.push_back(Utf8Str("--nosymlinks")); /** @todo What does GNU here? */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync#endif
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /** @todo Recursion support? */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync procInfo.mArguments.push_back(strPath); /* The directory we want to open. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /*
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync * Start the process asynchronously and keep it around so that we can use
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync * it later in subsequent read() calls.
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync * Note: No guest rc available because operation is asynchronous.
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync int rc = mData.mProcessTool.Init(mData.mSession, procInfo,
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync true /* Async */, NULL /* Guest rc */);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (RT_SUCCESS(rc))
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync {
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /* Confirm a successful initialization when it's the case. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync autoInitSpan.setSucceeded();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync return rc;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync }
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync autoInitSpan.setFailed();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync return rc;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync}
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync/**
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync * Uninitializes the instance.
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync * Called from FinalRelease().
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsyncvoid GuestDirectory::uninit(void)
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync{
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync LogFlowThisFunc(("\n"));
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /* Enclose the state transition Ready->InUninit->NotReady. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync AutoUninitSpan autoUninitSpan(this);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (autoUninitSpan.uninitDone())
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync return;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync LogFlowThisFuncLeave();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync}
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync// implementation of public getters/setters for attributes
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync/////////////////////////////////////////////////////////////////////////////
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsyncSTDMETHODIMP GuestDirectory::COMGETTER(DirectoryName)(BSTR *aName)
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync{
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync LogFlowThisFuncEnter();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync CheckComArgOutPointerValid(aName);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync AutoCaller autoCaller(this);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync mData.mName.cloneTo(aName);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync return S_OK;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync}
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsyncSTDMETHODIMP GuestDirectory::COMGETTER(Filter)(BSTR *aFilter)
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync{
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync LogFlowThisFuncEnter();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync CheckComArgOutPointerValid(aFilter);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync AutoCaller autoCaller(this);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync mData.mFilter.cloneTo(aFilter);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync return S_OK;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync}
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync// private methods
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync/////////////////////////////////////////////////////////////////////////////
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync// implementation of public methods
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync/////////////////////////////////////////////////////////////////////////////
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsyncSTDMETHODIMP GuestDirectory::Close(void)
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync{
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync#ifndef VBOX_WITH_GUEST_CONTROL
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync ReturnComNotImplemented();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync#else
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync LogFlowThisFuncEnter();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync AutoCaller autoCaller(this);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync AssertPtr(mData.mSession);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync int rc = mData.mSession->directoryRemoveFromList(this);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync AssertRC(rc);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync HRESULT hr = S_OK;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync int guestRc;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync rc = mData.mProcessTool.Terminate(30 * 1000, &guestRc);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (RT_FAILURE(rc))
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync {
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync switch (rc)
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync {
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync case VERR_GSTCTL_GUEST_ERROR:
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync hr = GuestProcess::setErrorExternal(this, guestRc);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync break;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync case VERR_NOT_SUPPORTED:
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /* Silently skip old Guest Additions which do not support killing the
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync * the guest directory handling process. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync break;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync default:
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync hr = setError(VBOX_E_IPRT_ERROR,
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync tr("Terminating open guest directory \"%s\" failed: %Rrc"),
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync mData.mName.c_str(), rc);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync break;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync }
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync }
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /*
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync * Release autocaller before calling uninit.
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync */
576099bc515c7c7349219499579f5729ffea3c35vboxsync autoCaller.release();
576099bc515c7c7349219499579f5729ffea3c35vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync uninit();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync LogFlowThisFunc(("Returning rc=%Rrc\n", rc));
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync return hr;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync}
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsyncSTDMETHODIMP GuestDirectory::Read(IFsObjInfo **aInfo)
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync{
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync#ifndef VBOX_WITH_GUEST_CONTROL
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync ReturnComNotImplemented();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync#else
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync LogFlowThisFuncEnter();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync AutoCaller autoCaller(this);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync GuestProcessStreamBlock curBlock;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync int guestRc;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync int rc = mData.mProcessTool.WaitEx(GUESTPROCESSTOOL_FLAG_STDOUT_BLOCK,
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync &curBlock, &guestRc);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /*
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync * Note: The guest process can still be around to serve the next
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync * upcoming stream block next time.
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if ( RT_SUCCESS(rc)
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync && !mData.mProcessTool.IsRunning())
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync {
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync rc = mData.mProcessTool.TerminatedOk(NULL /* Exit code */);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (rc == VERR_NOT_EQUAL)
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync rc = VERR_ACCESS_DENIED;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync }
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (RT_SUCCESS(rc))
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync {
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (curBlock.GetCount()) /* Did we get content? */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync {
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync GuestFsObjData objData;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync rc = objData.FromLs(curBlock);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (RT_FAILURE(rc))
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync rc = VERR_PATH_NOT_FOUND;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (RT_SUCCESS(rc))
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync {
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /* Create the object. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync ComObjPtr<GuestFsObjInfo> pFsObjInfo;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync HRESULT hr2 = pFsObjInfo.createObject();
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (FAILED(hr2))
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync rc = VERR_COM_UNEXPECTED;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (RT_SUCCESS(rc))
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync rc = pFsObjInfo->init(objData);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (RT_SUCCESS(rc))
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync {
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /* Return info object to the caller. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync hr2 = pFsObjInfo.queryInterfaceTo(aInfo);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (FAILED(hr2))
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync rc = VERR_COM_UNEXPECTED;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync }
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync }
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync }
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync else
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync {
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /* Nothing to read anymore. Tell the caller. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync rc = VERR_NO_MORE_FILES;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync }
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync }
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync HRESULT hr = S_OK;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync if (RT_FAILURE(rc)) /** @todo Add more errors here. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync {
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync switch (rc)
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync {
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync case VERR_GSTCTL_GUEST_ERROR:
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync hr = GuestProcess::setErrorExternal(this, guestRc);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync break;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync case VERR_ACCESS_DENIED:
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Unable to read / access denied"),
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync mData.mName.c_str());
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync break;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync case VERR_PATH_NOT_FOUND:
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Path not found"),
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync mData.mName.c_str());
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync break;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync case VERR_NO_MORE_FILES:
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync /* See SDK reference. */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync hr = setError(VBOX_E_OBJECT_NOT_FOUND, tr("No more entries for directory \"%s\""),
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync mData.mName.c_str());
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync break;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync default:
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync hr = setError(VBOX_E_IPRT_ERROR, tr("Error while reading directory \"%s\": %Rrc\n"),
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync mData.mName.c_str(), rc);
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync break;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync }
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync }
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync LogFlowThisFunc(("Returning rc=%Rrc\n", rc));
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync return hr;
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync}
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync
6da8aad9b9f0e2aa239259658e3d82073f5761e4vboxsync