VFSExplorerImpl.cpp revision dc09cb937d0a66e030b4d7bef88dec429f41e060
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * IVFSExplorer COM class implementations.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Copyright (C) 2009 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
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
d31ded334a29f575e23dc889b603b1a586759348vboxsync////////////////////////////////////////////////////////////////////////////////
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync// VFSExplorer definitions
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync////////////////////////////////////////////////////////////////////////////////
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* opaque private instance data of VFSExplorer class */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * VFSExplorer COM initializer.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT VFSExplorer::init(VFSType_T aType, Utf8Str aFilePath, Utf8Str aHostname, Utf8Str aUsername, Utf8Str aPassword, VirtualBox *aVirtualBox)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Enclose the state transition NotReady->InInit->Ready */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Weak reference to a VirtualBox object */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* initialize data */
22e281e75ed636601178296c6daebda8f1d17c59vboxsync m->strBucket = aFilePath.substr(1, bpos - 1); /* The bucket without any slashes */
22e281e75ed636601178296c6daebda8f1d17c59vboxsync aFilePath = aFilePath.substr(bpos); /* The rest of the file path */
22e281e75ed636601178296c6daebda8f1d17c59vboxsync /* Confirm a successful initialization */
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * VFSExplorer COM uninitializer.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * Public method implementation.
22e281e75ed636601178296c6daebda8f1d17c59vboxsyncSTDMETHODIMP VFSExplorer::COMGETTER(Path)(BSTR *aPath)
d1cbbd799d8912978f5146960b6780f387bb414bvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncSTDMETHODIMP VFSExplorer::COMGETTER(Type)(VFSType_T *aType)
b1c3cdef473df2fbc621d5da81acc82dbfb8a11avboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
3ecf9412133496b2aeb090cfd33a286404ec59fbvboxsync TaskVFSExplorer(TaskType aTaskType, VFSExplorer *aThat, Progress *aProgress)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync static int taskThread(RTTHREAD aThread, void *pvUser);
750d4d0506a38b2e80c997075d40aad474e675fbvboxsync static int uploadProgress(unsigned uPercent, void *pvUser);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* task data */
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync int vrc = RTThreadCreate(NULL, VFSExplorer::TaskVFSExplorer::taskThread, this,
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync "Explorer::Task");
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync ("Could not create taskThreadVFS (%Rrc)\n", vrc), E_FAIL);
576d4214137bce409cdcf01e8df4a0bca5e0b2d1vboxsync/* static */
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsyncDECLCALLBACK(int) VFSExplorer::TaskVFSExplorer::taskThread(RTTHREAD /* aThread */, void *pvUser)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync std::auto_ptr<TaskVFSExplorer> task(static_cast<TaskVFSExplorer*>(pvUser));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else if (pVFSExplorer->m->storageType == VFSType_S3)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync else if (pVFSExplorer->m->storageType == VFSType_S3)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* static */
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsyncint VFSExplorer::TaskVFSExplorer::uploadProgress(unsigned uPercent, void *pvUser)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VFSExplorer::TaskVFSExplorer* pTask = *(VFSExplorer::TaskVFSExplorer**)pvUser;
b978e5849454446957177fd47ee98609ab0457a6vboxsync pTask->progress->SetCurrentOperationProgress(uPercent);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncVFSFileType_T VFSExplorer::RTToVFSFileType(int aType) const
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case RTDIRENTRYTYPE_UNKNOWN: t = VFSFileType_Unknown; break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case RTDIRENTRYTYPE_FIFO: t = VFSFileType_Fifo; break;
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync case RTDIRENTRYTYPE_DEV_CHAR: t = VFSFileType_DevChar; break;
6ae4b1c72625a8e5c369effea7f018b578d733c4vboxsync case RTDIRENTRYTYPE_DIRECTORY: t = VFSFileType_Directory; break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case RTDIRENTRYTYPE_DEV_BLOCK: t = VFSFileType_DevBlock; break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case RTDIRENTRYTYPE_FILE: t = VFSFileType_File; break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case RTDIRENTRYTYPE_SYMLINK: t = VFSFileType_SymLink; break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case RTDIRENTRYTYPE_SOCKET: t = VFSFileType_Socket; break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case RTDIRENTRYTYPE_WHITEOUT: t = VFSFileType_WhiteOut; break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncHRESULT VFSExplorer::updateFS(TaskVFSExplorer *aTask)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
00599f6d39cc25ca39845c2433cd75de7b9f6971vboxsync throw setError(VBOX_E_FILE_ERROR, tr ("Can't open directory '%s' (%Rrc)"), pszPath, vrc);
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync fileList.push_back(VFSExplorer::Data::DirEntry(name, RTToVFSFileType(entry.enmType)));
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* Clean up */
6ae4b1c72625a8e5c369effea7f018b578d733c4vboxsync /* Assign the result on success (this clears the old list) */
ebbb1f6c7e8bae363a4efda4b35b58c8467d24bcvboxsync m->entryList.assign(fileList.begin(), fileList.end());
1843553dbdf4e46417158b4c6348c503adf10740vboxsyncHRESULT VFSExplorer::deleteFS(TaskVFSExplorer *aTask)
1843553dbdf4e46417158b4c6348c503adf10740vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
1843553dbdf4e46417158b4c6348c503adf10740vboxsync float fPercentStep = 100.0f / aTask->filenames.size();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync memcpy(szPath, m->strPath.c_str(), strlen(m->strPath.c_str()) + 1);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync RTPathAppend(szPath, sizeof(szPath), (*it).c_str());
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync throw setError(VBOX_E_FILE_ERROR, tr ("Can't delete file '%s' (%Rrc)"), szPath, vrc);
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync aTask->progress->SetCurrentOperationProgress((ULONG)(fPercentStep * i));
2d53f6e472561965d363674e17f48d3bdffc24d3vboxsyncHRESULT VFSExplorer::updateS3(TaskVFSExplorer *aTask)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int vrc = RTS3Create(&hS3, m->strUsername.c_str(), m->strPassword.c_str(), m->strHostname.c_str(), "virtualbox-agent/"VBOX_VERSION_STRING);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync throw setError(E_FAIL, tr ("Can't open S3 storage service (%Rrc)"), vrc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTS3SetProgressCallback(hS3, VFSExplorer::TaskVFSExplorer::uploadProgress, &aTask);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync /* Do we need the list of buckets or keys? */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync throw setError(E_FAIL, tr ("Can't get buckets (%Rrc)"), vrc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fileList.push_back(VFSExplorer::Data::DirEntry(pBuckets->pszName, VFSFileType_Directory));
806d0b554daa555364af5f87bc96eccbe760db7avboxsync vrc = RTS3GetBucketKeys(hS3, m->strBucket.c_str(), &pKeys);
806d0b554daa555364af5f87bc96eccbe760db7avboxsync throw setError(E_FAIL, tr ("Can't get keys for bucket (%Rrc)"), vrc);
806d0b554daa555364af5f87bc96eccbe760db7avboxsync fileList.push_back(VFSExplorer::Data::DirEntry(pKeys->pszName, VFSFileType_File));
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync /* Assign the result on success (this clears the old list) */
806d0b554daa555364af5f87bc96eccbe760db7avboxsync m->entryList.assign(fileList.begin(), fileList.end());
806d0b554daa555364af5f87bc96eccbe760db7avboxsyncHRESULT VFSExplorer::deleteS3(TaskVFSExplorer *aTask)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
7e960d3a0a8a3a84d7aba2cca45d72b1c31cc97bvboxsync float fPercentStep = 100.0f / aTask->filenames.size();
22e281e75ed636601178296c6daebda8f1d17c59vboxsync int vrc = RTS3Create(&hS3, m->strUsername.c_str(), m->strPassword.c_str(), m->strHostname.c_str(), "virtualbox-agent/"VBOX_VERSION_STRING);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync throw setError(E_FAIL, tr ("Can't open S3 storage service (%Rrc)"), vrc);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RTS3SetProgressCallback(hS3, VFSExplorer::TaskVFSExplorer::uploadProgress, &aTask);
13ba5527caaa9b8c4fee29f22e374fa67c4c6f72vboxsync vrc = RTS3DeleteKey(hS3, m->strBucket.c_str(), (*it).c_str());
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync throw setError(VBOX_E_FILE_ERROR, tr ("Can't delete file '%s' (%Rrc)"), (*it).c_str(), vrc);
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync aTask->progress->SetCurrentOperationProgress((ULONG)(fPercentStep * i));
6ae4b1c72625a8e5c369effea7f018b578d733c4vboxsyncSTDMETHODIMP VFSExplorer::Update(IProgress **aProgress)
9e4166cf5ed4940f506bc718ea6c89bf7ed252c8vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
22e281e75ed636601178296c6daebda8f1d17c59vboxsync Bstr progressDesc = BstrFmt(tr("Update directory info for '%s'"),
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync /* Create the progress object */
79b24ef0ab7cd4a03a3571b3954c52ab8b573137vboxsync rc = progress->init(mVirtualBox, static_cast<IVFSExplorer*>(this),
13ba5527caaa9b8c4fee29f22e374fa67c4c6f72vboxsync /* Initialize our worker task */
3dde2f85d4cf477621a3128887a2c08a8bca7c01vboxsync std::auto_ptr<TaskVFSExplorer> task(new TaskVFSExplorer(TaskVFSExplorer::Update, this, progress));
7bae75e0b207aa4d4cad2a951271ad1a0e8ab9fdvboxsync /* Don't destruct on success */
b978e5849454446957177fd47ee98609ab0457a6vboxsync /* Return progress to the caller */
6f0193f5a9287559d34a75f438c2682d8fb08038vboxsyncSTDMETHODIMP VFSExplorer::Cd(IN_BSTR aDir, IProgress **aProgress)
f827fea1108b8f8a1a5f63318f6ec3cf4a9e7010vboxsyncSTDMETHODIMP VFSExplorer::CdUp(IProgress **aProgress)
f9147fe1eaa4e35287f8f39282c7f92f0d7de0b7vboxsyncSTDMETHODIMP VFSExplorer::EntryList(ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(VFSFileType_T, aTypes))
6f0193f5a9287559d34a75f438c2682d8fb08038vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
6f0193f5a9287559d34a75f438c2682d8fb08038vboxsync com::SafeArray<BSTR> sfaNames((ULONG)m->entryList.size());
6ae4b1c72625a8e5c369effea7f018b578d733c4vboxsync com::SafeArray<ULONG> sfaTypes((VFSFileType_T)m->entryList.size());
6f0193f5a9287559d34a75f438c2682d8fb08038vboxsync std::list<VFSExplorer::Data::DirEntry>::const_iterator it;
13ba5527caaa9b8c4fee29f22e374fa67c4c6f72vboxsyncSTDMETHODIMP VFSExplorer::Exists(ComSafeArrayIn(IN_BSTR, aNames), ComSafeArrayOut(BSTR, aExists))
6f0193f5a9287559d34a75f438c2682d8fb08038vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
6f0193f5a9287559d34a75f438c2682d8fb08038vboxsync com::SafeArray<IN_BSTR> sfaNames(ComSafeArrayInArg(aNames));
6f0193f5a9287559d34a75f438c2682d8fb08038vboxsync std::list<VFSExplorer::Data::DirEntry>::const_iterator it;
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync if (entry.name == RTPathFilename(Utf8Str(sfaNames[a]).c_str()))
9e4166cf5ed4940f506bc718ea6c89bf7ed252c8vboxsyncSTDMETHODIMP VFSExplorer::Remove(ComSafeArrayIn(IN_BSTR, aNames), IProgress **aProgress)
13ba5527caaa9b8c4fee29f22e374fa67c4c6f72vboxsync if (FAILED(autoCaller.rc())) return autoCaller.rc();
8e8844a522f5d335f177a0313b03067d79cce201vboxsync com::SafeArray<IN_BSTR> sfaNames(ComSafeArrayInArg(aNames));
65b61798a61dd4c32cce448db1dac70bba8d5cf5vboxsync /* Create the progress object */
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsync rc = progress->init(mVirtualBox, static_cast<IVFSExplorer*>(this),
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsync /* Initialize our worker task */
46df4404c8dbbf3672e7aae8cd0b2770356e5b73vboxsync std::auto_ptr<TaskVFSExplorer> task(new TaskVFSExplorer(TaskVFSExplorer::Delete, this, progress));
ce2d2eef2525963979102e63c2419d1c69d767ccvboxsync /* Add all filenames to delete as task data */
ce2d2eef2525963979102e63c2419d1c69d767ccvboxsync /* Don't destruct on success */
ce2d2eef2525963979102e63c2419d1c69d767ccvboxsync /* Return progress to the caller */