GuestDirectoryImpl.cpp revision d86beb7ea7f5fb6bf4a4e80c7b3fe0aeec98fa93
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * VirtualBox Main - Guest directory handling.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Copyright (C) 2012-2013 Oracle Corporation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Header Files *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
2f0d866e126dd288169fed591c259c1c6b4016e5vboxsync// constructor / destructor
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync/////////////////////////////////////////////////////////////////////////////
70aa086e9e9d2f85d2e997d0e69169018a001e54vboxsync// public initializer/uninitializer for internal purposes only
2634ec5cbf8f1fa0a968cd4664ead6df1fed730dvboxsync/////////////////////////////////////////////////////////////////////////////
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsyncint GuestDirectory::init(Console *pConsole, GuestSession *pSession,
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync ULONG uDirID, const GuestDirectoryOpenInfo &openInfo)
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync LogFlowThisFunc(("pConsole=%p, pSession=%p, uDirID=%RU32, strPath=%s, strFilter=%s, uFlags=%x\n",
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync pConsole, pSession, uDirID, openInfo.mPath.c_str(), openInfo.mFilter.c_str(),
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Enclose the state transition NotReady->InInit->Ready. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int vrc = bindToSession(pConsole, pSession, uDirID /* Object ID */);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Start the directory process on the guest. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync procInfo.mName = Utf8StrFmt(tr("Reading directory \"%s\"", openInfo.mPath.c_str()));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync procInfo.mTimeoutMS = 5 * 60 * 1000; /* 5 minutes timeout. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* We want the long output format which contains all the object details. */
b1c3cdef473df2fbc621d5da81acc82dbfb8a11avboxsync#if 0 /* Flags are not supported yet. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync procInfo.mArguments.push_back(Utf8Str("--nosymlinks")); /** @todo What does GNU here? */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** @todo Recursion support? */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync procInfo.mArguments.push_back(openInfo.mPath); /* The directory we want to open. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Start the process asynchronously and keep it around so that we can use
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * it later in subsequent read() calls.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Note: No guest rc available because operation is asynchronous.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Confirm a successful initialization when it's the case. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Uninitializes the instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Called from FinalRelease().
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Enclose the state transition Ready->InUninit->NotReady. */
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync// implementation of private wrapped getters/setters for attributes
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync/////////////////////////////////////////////////////////////////////////////
2afbe132eb7931e0125141eabe3a48e08f1ffab5vboxsyncHRESULT GuestDirectory::getDirectoryName(com::Utf8Str &aDirectoryName)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT GuestDirectory::getFilter(com::Utf8Str &aFilter)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync// private methods
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncint GuestDirectory::i_callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
541071eef3db0e3e0e5497bb4b692efee42b1ad0vboxsync LogFlowThisFunc(("strPath=%s, uContextID=%RU32, uFunction=%RU32, pSvcCb=%p\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync mData.mOpenInfo.mPath.c_str(), pCbCtx->uContextID, pCbCtx->uFunction, pSvcCb));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* pSvcCb->mpaParms[0] always contains the context ID. */
2634ec5cbf8f1fa0a968cd4664ead6df1fed730dvboxsync int guestRc = (int)dataCb.rc; /* uint32_t vs. int. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Nothing here yet, nothing to dispatch further. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Silently ignore not implemented functions. */
82e90599291da476b2de7c8db33cfb0f2cbac774vboxsync/* static */
82e90599291da476b2de7c8db33cfb0f2cbac774vboxsyncUtf8Str GuestDirectory::i_guestErrorToString(int guestRc)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** @todo pData->u32Flags: int vs. uint32 -- IPRT errors are *negative* !!! */
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync * Called by IGuestSession right before this directory gets
b40179b44fea65b72b2f226f62af1ed7bd3c48fcvboxsync * removed from the public directory list.
00599f6d39cc25ca39845c2433cd75de7b9f6971vboxsync/* static */
00599f6d39cc25ca39845c2433cd75de7b9f6971vboxsyncHRESULT GuestDirectory::i_setErrorExternal(VirtualBoxBase *pInterface, int guestRc)
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync AssertMsg(RT_FAILURE(guestRc), ("Guest rc does not indicate a failure when setting error\n"));
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync return pInterface->setError(VBOX_E_IPRT_ERROR, GuestDirectory::i_guestErrorToString(guestRc).c_str());
e50404712a2b5234c42bdf9740bddab5729ba188vboxsync// implementation of public methods
b978e5849454446957177fd47ee98609ab0457a6vboxsync/////////////////////////////////////////////////////////////////////////////
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1843553dbdf4e46417158b4c6348c503adf10740vboxsync int rc = mData.mProcessTool.i_terminate(30 * 1000, &guestRc);
1843553dbdf4e46417158b4c6348c503adf10740vboxsync hr = GuestProcess::i_setErrorExternal(this, guestRc);
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* Silently skip old Guest Additions which do not support killing the
9e4166cf5ed4940f506bc718ea6c89bf7ed252c8vboxsync * the guest directory handling process. */
ebbb1f6c7e8bae363a4efda4b35b58c8467d24bcvboxsync tr("Terminating open guest directory \"%s\" failed: %Rrc"),
806d0b554daa555364af5f87bc96eccbe760db7avboxsync int rc2 = mSession->i_directoryRemoveFromList(this);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
1843553dbdf4e46417158b4c6348c503adf10740vboxsyncHRESULT GuestDirectory::read(ComPtr<IFsObjInfo> &aObjInfo)
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
e52f819639386db020b2a635b47a415248c7fbf9vboxsync int rc = mData.mProcessTool.i_waitEx(GUESTPROCESSTOOL_FLAG_STDOUT_BLOCK,
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync * Note: The guest process can still be around to serve the next
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * upcoming stream block next time.
2634ec5cbf8f1fa0a968cd4664ead6df1fed730dvboxsync rc = mData.mProcessTool.i_terminatedOk(NULL /* Exit code */);
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync /* Create the object. */
2634ec5cbf8f1fa0a968cd4664ead6df1fed730dvboxsync /* Return info object to the caller. */
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsync hr2 = pFsObjInfo.queryInterfaceTo(aObjInfo.asOutParam());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Nothing to read anymore. Tell the caller. */
1999ae03c34840fa4d712fd2e020120b2cb7182avboxsync if (RT_FAILURE(rc)) /** @todo Add more errors here. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync hr = GuestProcess::i_setErrorExternal(this, guestRc);
13ba5527caaa9b8c4fee29f22e374fa67c4c6f72vboxsync hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Unable to read / access denied"),
22e281e75ed636601178296c6daebda8f1d17c59vboxsync hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Path not found"),
806d0b554daa555364af5f87bc96eccbe760db7avboxsync /* See SDK reference. */
806d0b554daa555364af5f87bc96eccbe760db7avboxsync hr = setError(VBOX_E_OBJECT_NOT_FOUND, tr("No more entries for directory \"%s\""),
e08de24d4792d31b7f2aac29db5cb8840d940009vboxsync hr = setError(VBOX_E_IPRT_ERROR, tr("Error while reading directory \"%s\": %Rrc\n"),
1986f56777969a25707ab214f8dd070804be666cvboxsync#endif /* VBOX_WITH_GUEST_CONTROL */