GuestDirectoryImpl.cpp revision 9d60b6be8b3cd7d8bb393ae591e846f44c3df3b2
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * VirtualBox Main - Guest directory handling.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * Copyright (C) 2012-2013 Oracle Corporation
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * available from http://www.virtualbox.org. This file is free software;
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * you can redistribute it and/or modify it under the terms of the GNU
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * General Public License (GPL) as published by the Free Software
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync/*******************************************************************************
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync* Header Files *
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync*******************************************************************************/
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync// constructor / destructor
71c8a528203c289a8585ce10ac6bafc4274058c6vboxsync/////////////////////////////////////////////////////////////////////////////
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync// public initializer/uninitializer for internal purposes only
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync/////////////////////////////////////////////////////////////////////////////
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsyncint GuestDirectory::init(Console *pConsole, GuestSession *pSession,
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync ULONG uDirID, const GuestDirectoryOpenInfo &openInfo)
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync LogFlowThisFunc(("pConsole=%p, pSession=%p, uDirID=%RU32, strPath=%s, strFilter=%s, uFlags=%x\n",
c33fc49611f2444dade533488bf431e29eb88bcdvboxsync pConsole, pSession, uDirID, openInfo.mPath.c_str(), openInfo.mFilter.c_str(),
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync /* Enclose the state transition NotReady->InInit->Ready. */
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync int vrc = bindToSession(pConsole, pSession, uDirID /* Object ID */);
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync /* Start the directory process on the guest. */
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync procInfo.mName = Utf8StrFmt(tr("Reading directory \"%s\""), openInfo.mPath.c_str());
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync procInfo.mTimeoutMS = 5 * 60 * 1000; /* 5 minutes timeout. */
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync /* We want the long output format which contains all the object details. */
2a5e5a032e6f23f8937718e4ee4d6979188bdd19vboxsync#if 0 /* Flags are not supported yet. */
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync procInfo.mArguments.push_back(Utf8Str("--nosymlinks")); /** @todo What does GNU here? */
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsync /** @todo Recursion support? */
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync procInfo.mArguments.push_back(openInfo.mPath); /* The directory we want to open. */
b604fbf16eda38d14b4999c245f032bfaa5aa85avboxsync * Start the process asynchronously and keep it around so that we can use
13d1fd6f43e9a245a4f2b4fc6845bdaa5d0f4134vboxsync * it later in subsequent read() calls.
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync * Note: No guest rc available because operation is asynchronous.
cebc93936b5bb4d867e1c086dd1b206db33c31dcvboxsync /* Confirm a successful initialization when it's the case. */
cebc93936b5bb4d867e1c086dd1b206db33c31dcvboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync * Uninitializes the instance.
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync * Called from FinalRelease().
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync /* Enclose the state transition Ready->InUninit->NotReady. */
3933885bc0c2c93436d858a14564c6179ec72872vboxsync// implementation of private wrapped getters/setters for attributes
3933885bc0c2c93436d858a14564c6179ec72872vboxsync/////////////////////////////////////////////////////////////////////////////
3933885bc0c2c93436d858a14564c6179ec72872vboxsyncHRESULT GuestDirectory::getDirectoryName(com::Utf8Str &aDirectoryName)
3933885bc0c2c93436d858a14564c6179ec72872vboxsyncHRESULT GuestDirectory::getFilter(com::Utf8Str &aFilter)
a9315925c69e4c3bb342bb317ca5b6d29e1ee467vboxsync// private methods
a9315925c69e4c3bb342bb317ca5b6d29e1ee467vboxsync/////////////////////////////////////////////////////////////////////////////
4090390866c02d5d0ad061151cdb298b9a173e86vboxsyncint GuestDirectory::i_callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
40dce69ff1c2949a489337922f30f1021d62d864vboxsync LogFlowThisFunc(("strPath=%s, uContextID=%RU32, uFunction=%RU32, pSvcCb=%p\n",
40dce69ff1c2949a489337922f30f1021d62d864vboxsync mData.mOpenInfo.mPath.c_str(), pCbCtx->uContextID, pCbCtx->uFunction, pSvcCb));
7708252d252a55417a6a817041e4356797e34255vboxsync /* pSvcCb->mpaParms[0] always contains the context ID. */
7708252d252a55417a6a817041e4356797e34255vboxsync int guestRc = (int)dataCb.rc; /* uint32_t vs. int. */
3f00104a87d8a725dfa0348b69cbdac901062a4avboxsync /* Nothing here yet, nothing to dispatch further. */
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync /* Silently ignore not implemented functions. */
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync/* static */
8fdb854581fe3cb394d84835dc09b02e6e18d4edvboxsyncUtf8Str GuestDirectory::i_guestErrorToString(int guestRc)
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync /** @todo pData->u32Flags: int vs. uint32 -- IPRT errors are *negative* !!! */
9353e321b583ed6f2b42414257a5212885575b5cvboxsync * Called by IGuestSession right before this directory gets
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync * removed from the public directory list.
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync/* static */
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsyncHRESULT GuestDirectory::i_setErrorExternal(VirtualBoxBase *pInterface, int guestRc)
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync AssertMsg(RT_FAILURE(guestRc), ("Guest rc does not indicate a failure when setting error\n"));
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync return pInterface->setError(VBOX_E_IPRT_ERROR, GuestDirectory::i_guestErrorToString(guestRc).c_str());
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync// implementation of public methods
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync/////////////////////////////////////////////////////////////////////////////
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync int rc = mData.mProcessTool.i_terminate(30 * 1000, &guestRc);
cebc93936b5bb4d867e1c086dd1b206db33c31dcvboxsync hr = GuestProcess::i_setErrorExternal(this, guestRc);
cebc93936b5bb4d867e1c086dd1b206db33c31dcvboxsync /* Silently skip old Guest Additions which do not support killing the
cebc93936b5bb4d867e1c086dd1b206db33c31dcvboxsync * the guest directory handling process. */
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync tr("Terminating open guest directory \"%s\" failed: %Rrc"),
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync int rc2 = mSession->i_directoryRemoveFromList(this);
3933885bc0c2c93436d858a14564c6179ec72872vboxsync#endif /* VBOX_WITH_GUEST_CONTROL */
060f7ec6ae5c99df18341ef2e1f3e91f4b0c89f1vboxsyncHRESULT GuestDirectory::read(ComPtr<IFsObjInfo> &aObjInfo)
3933885bc0c2c93436d858a14564c6179ec72872vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
261b44f7fa60a1d4bb4102142d3aa44188908484vboxsync int rc = mData.mProcessTool.i_waitEx(GUESTPROCESSTOOL_FLAG_STDOUT_BLOCK,
f106b549ead77cab51ff1e2c116060aaabb90d5evboxsync * Note: The guest process can still be around to serve the next
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync * upcoming stream block next time.
a9315925c69e4c3bb342bb317ca5b6d29e1ee467vboxsync rc = mData.mProcessTool.i_terminatedOk(NULL /* Exit code */);
3f00104a87d8a725dfa0348b69cbdac901062a4avboxsync /* Create the object. */
a1b4fb3917412d2632d358ff8989f1ec971f2d5bvboxsync /* Return info object to the caller. */
5a41049c24bcf93e3dc63c76bee23db645867e0cvboxsync hr2 = pFsObjInfo.queryInterfaceTo(aObjInfo.asOutParam());
147e101bcd061b5e085e4a2c0cc9fc35546ff1aavboxsync /* Nothing to read anymore. Tell the caller. */
a1b4fb3917412d2632d358ff8989f1ec971f2d5bvboxsync if (RT_FAILURE(rc)) /** @todo Add more errors here. */
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsync hr = GuestProcess::i_setErrorExternal(this, guestRc);
aa0553becec2abc2e781f839ba1d399c31c2c07fvboxsync hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Unable to read / access denied"),
a1b4fb3917412d2632d358ff8989f1ec971f2d5bvboxsync hr = setError(VBOX_E_IPRT_ERROR, tr("Reading directory \"%s\" failed: Path not found"),
a1b4fb3917412d2632d358ff8989f1ec971f2d5bvboxsync /* See SDK reference. */
3933885bc0c2c93436d858a14564c6179ec72872vboxsync hr = setError(VBOX_E_OBJECT_NOT_FOUND, tr("No more entries for directory \"%s\""),
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsync hr = setError(VBOX_E_IPRT_ERROR, tr("Error while reading directory \"%s\": %Rrc\n"),
1147e980f6ab0b7ff1d08c13ad1c03eea30d102dvboxsync#endif /* VBOX_WITH_GUEST_CONTROL */