VirtualBox

Changeset 20081 in vbox


Ignore:
Timestamp:
May 27, 2009 12:55:11 PM (15 years ago)
Author:
vboxsync
Message:

Main: initial code for upload to cloud (second try)

Location:
trunk/src/VBox/Main
Files:
5 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ApplianceImpl.cpp

    r20045 r20081  
    2121 */
    2222
    23 #include <VBox/param.h>
    2423#include <iprt/stream.h>
    2524#include <iprt/path.h>
    2625#include <iprt/dir.h>
    2726#include <iprt/file.h>
     27#include <iprt/s3.h>
     28
     29#include <VBox/param.h>
     30#include <VBox/version.h>
    2831
    2932#include "ApplianceImpl.h"
     33#include "VFSExplorerImpl.h"
    3034#include "VirtualBoxImpl.h"
    3135#include "GuestOSTypeImpl.h"
     
    460464 * @return
    461465 */
    462 
    463466HRESULT Appliance::init(VirtualBox *aVirtualBox)
    464467{
     
    25012504struct Appliance::TaskWriteOVF
    25022505{
    2503     TaskWriteOVF(Appliance *aThat, Progress *aProgress)
    2504         : pAppliance(aThat),
    2505           enFormat(unspecified),
    2506           progress(aProgress),
     2506    enum OVFFormat
     2507    {
     2508        unspecified,
     2509        OVF_0_9,
     2510        OVF_1_0
     2511    };
     2512    enum TaskType
     2513    {
     2514        Write
     2515    };
     2516
     2517    TaskWriteOVF(OVFFormat aFormat, Appliance *aThat)
     2518        : taskType(Write),
     2519          storageType(VFSType_File),
     2520          enFormat(aFormat),
     2521          pAppliance(aThat),
    25072522          rc(S_OK)
    25082523    {}
    25092524    ~TaskWriteOVF() {}
    25102525
    2511     HRESULT startThread();
    2512 
     2526    int startThread();
     2527    static int uploadProgress(unsigned uPercent, void *pvUser);
     2528
     2529    TaskType taskType;
     2530    VFSType_T storageType;
     2531    Utf8Str filepath;
     2532    Utf8Str hostname;
     2533    Utf8Str username;
     2534    Utf8Str password;
     2535    OVFFormat enFormat;
    25132536    Appliance *pAppliance;
    2514     enum { unspecified, OVF_0_9, OVF_1_0 }
    2515         enFormat;
    2516 
    25172537    ComObjPtr<Progress> progress;
    25182538    HRESULT rc;
    25192539};
    25202540
    2521 HRESULT Appliance::TaskWriteOVF::startThread()
     2541int Appliance::TaskWriteOVF::startThread()
    25222542{
    25232543    int vrc = RTThreadCreate(NULL, Appliance::taskThreadWriteOVF, this,
    25242544                             0, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0,
    25252545                             "Appliance::Task");
     2546
    25262547    ComAssertMsgRCRet(vrc,
    2527                       ("Could not create taskThreadExportOVF (%Rrc)\n", vrc), E_FAIL);
     2548                      ("Could not create taskThreadWriteOVF (%Rrc)\n", vrc), E_FAIL);
    25282549
    25292550    return S_OK;
    25302551}
    25312552
     2553/* static */
     2554int Appliance::TaskWriteOVF::uploadProgress(unsigned uPercent, void *pvUser)
     2555{
     2556    Appliance::TaskWriteOVF* pTask = *(Appliance::TaskWriteOVF**)pvUser;
     2557
     2558    if (pTask &&
     2559        !pTask->progress.isNull())
     2560    {
     2561        BOOL fCanceled;
     2562        pTask->progress->COMGETTER(Canceled)(&fCanceled);
     2563        if (fCanceled)
     2564            return -1;
     2565        pTask->progress->setCurrentOperationProgress(uPercent);
     2566    }
     2567    return VINF_SUCCESS;
     2568}
     2569
     2570STDMETHODIMP Appliance::CreateVFSExplorer(IN_BSTR aURI, IVFSExplorer **aExplorer)
     2571{
     2572    HRESULT rc = S_OK;
     2573
     2574    CheckComArgOutPointerValid(aExplorer);
     2575
     2576    AutoCaller autoCaller(this);
     2577    CheckComRCReturnRC(autoCaller.rc());
     2578
     2579    AutoReadLock(this);
     2580
     2581    Utf8Str uri(aURI);
     2582    /* Check which kind of export the user has requested */
     2583    VFSType_T type = VFSType_File;
     2584    Utf8Str strProtocol = "";
     2585    /* Check the URI for the target format */
     2586    if (uri.startsWith("SunCloud://", Utf8Str::CaseInsensitive)) /* Sun Cloud service */
     2587    {
     2588        type = VFSType_S3;
     2589        strProtocol = "SunCloud://";
     2590    }
     2591    else if (uri.startsWith("S3://", Utf8Str::CaseInsensitive)) /* S3 service */
     2592    {
     2593        type = VFSType_S3;
     2594        strProtocol = "S3://";
     2595    }
     2596    else if (uri.startsWith("webdav://", Utf8Str::CaseInsensitive)) /* webdav service */
     2597        throw E_NOTIMPL;
     2598
     2599    Utf8Str strFilepath;
     2600    Utf8Str strHostname;
     2601    Utf8Str strUsername;
     2602    Utf8Str strPassword;
     2603    parseURI(uri, strProtocol, strFilepath, strHostname, strUsername, strPassword);
     2604
     2605    ComObjPtr<VFSExplorer> explorer;
     2606    explorer.createObject();
     2607
     2608    rc = explorer->init(type, strFilepath, strHostname, strUsername, strPassword, mVirtualBox);
     2609
     2610    if (SUCCEEDED(rc))
     2611        /* Return explorer to the caller */
     2612        explorer.queryInterfaceTo(aExplorer);
     2613
     2614    return rc;
     2615}
     2616
    25322617STDMETHODIMP Appliance::Write(IN_BSTR format, IN_BSTR path, IProgress **aProgress)
    25332618{
     
    25372622
    25382623    AutoCaller autoCaller(this);
    2539     if (FAILED(rc = autoCaller.rc())) return rc;
     2624    CheckComRCReturnRC(autoCaller.rc());
    25402625
    25412626    AutoWriteLock(this);
    25422627
    25432628    // see if we can handle this file; for now we insist it has an ".ovf" extension
    2544     m->strPath = path;
    2545     if (!m->strPath.endsWith(".ovf", Utf8Str::CaseInsensitive))
     2629    Utf8Str strPath = path;
     2630    if (!strPath.endsWith(".ovf", Utf8Str::CaseInsensitive))
    25462631        return setError(VBOX_E_FILE_ERROR,
    25472632                        tr("Appliance file must have .ovf extension"));
    25482633
    25492634    ComObjPtr<Progress> progress;
    2550     try
    2551     {
    2552         Bstr progressDesc = BstrFmt(tr("Export appliance '%s'"),
    2553                                     m->strPath.raw());
    2554         rc = setUpProgress(progress, progressDesc);
    2555         if (FAILED(rc)) throw rc;
    2556 
    2557         /* Initialize our worker task */
    2558         std::auto_ptr<TaskWriteOVF> task(new TaskWriteOVF(this, progress));
    2559         //AssertComRCThrowRC (task->autoCaller.rc());
    2560 
    2561         Utf8Str strFormat(format);
    2562         if (strFormat == "ovf-0.9")
    2563             task->enFormat = TaskWriteOVF::OVF_0_9;
    2564         else if (strFormat == "ovf-1.0")
    2565             task->enFormat = TaskWriteOVF::OVF_1_0;
    2566         else
    2567             return setError(VBOX_E_FILE_ERROR,
    2568                             tr("Invalid format \"%s\" specified"), strFormat.c_str());
    2569 
    2570         rc = task->startThread();
    2571         CheckComRCThrowRC(rc);
    2572 
    2573         task.release();
    2574     }
    2575     catch (HRESULT aRC)
    2576     {
    2577         rc = aRC;
    2578     }
     2635    Utf8Str strFormat(format);
     2636    TaskWriteOVF::OVFFormat ovfF;
     2637    if (strFormat == "ovf-0.9")
     2638        ovfF = TaskWriteOVF::OVF_0_9;
     2639    else if (strFormat == "ovf-1.0")
     2640        ovfF = TaskWriteOVF::OVF_1_0;
     2641    else
     2642        return setError(VBOX_E_FILE_ERROR,
     2643                        tr("Invalid format \"%s\" specified"), strFormat.c_str());
     2644
     2645    rc = writeImpl(ovfF, strPath, progress);
    25792646
    25802647    if (SUCCEEDED(rc))
     
    25832650
    25842651    return rc;
     2652}
     2653
     2654void Appliance::parseURI(Utf8Str strUri, const Utf8Str &strProtocol, Utf8Str &strFilepath, Utf8Str &strHostname, Utf8Str &strUsername, Utf8Str &strPassword)
     2655{
     2656    /* Remove the protocol */
     2657    if (strUri.startsWith(strProtocol, Utf8Str::CaseInsensitive))
     2658        strUri = strUri.substr(strProtocol.length());
     2659    size_t uppos = strUri.find("@");
     2660    if (uppos != Utf8Str::npos)
     2661    {
     2662        strUsername = strUri.substr(0, uppos);
     2663        strUri = strUri.substr(uppos + 1);
     2664        size_t upos = strUsername.find(":");
     2665        if (upos != Utf8Str::npos)
     2666        {
     2667            strPassword = strUsername.substr(upos + 1);
     2668            strUsername = strUsername.substr(0, upos);
     2669        }
     2670    }
     2671    size_t hpos = strUri.find("/");
     2672    if (hpos != Utf8Str::npos)
     2673    {
     2674        strHostname = strUri.substr(0, hpos);
     2675        strUri = strUri.substr(hpos);
     2676    }
     2677    strFilepath = strUri;
     2678}
     2679
     2680HRESULT Appliance::writeImpl(int aFormat, Utf8Str aPath, ComObjPtr<Progress> &aProgress)
     2681{
     2682    HRESULT rc = S_OK;
     2683    try
     2684    {
     2685        m->strPath = aPath;
     2686
     2687        /* Initialize our worker task */
     2688        std::auto_ptr<TaskWriteOVF> task(new TaskWriteOVF((TaskWriteOVF::OVFFormat)aFormat, this));
     2689
     2690        /* Check which kind of export the user has requested */
     2691        Utf8Str strProtocol = "";
     2692        /* Check the URI for the target format */
     2693        if (m->strPath.startsWith("SunCloud://", Utf8Str::CaseInsensitive)) /* Sun Cloud service */
     2694        {
     2695            task->storageType = VFSType_S3;
     2696            strProtocol = "SunCloud://";
     2697        }
     2698        else if (m->strPath.startsWith("S3://", Utf8Str::CaseInsensitive)) /* S3 service */
     2699        {
     2700            task->storageType = VFSType_S3;
     2701            strProtocol = "S3://";
     2702        }
     2703        else if (m->strPath.startsWith("webdav://", Utf8Str::CaseInsensitive)) /* webdav service */
     2704            throw E_NOTIMPL;
     2705
     2706        parseURI(m->strPath, strProtocol, task->filepath, task->hostname, task->username, task->password);
     2707        Bstr progressDesc = BstrFmt(tr("Export appliance '%s'"),
     2708                                    task->filepath.c_str());
     2709
     2710        /* todo: This progress init stuff should be done a little bit more generic */
     2711        if (task->storageType == VFSType_S3)
     2712            rc = setUpProgressUpload(aProgress, progressDesc);
     2713        else
     2714            rc = setUpProgress(aProgress, progressDesc);
     2715        if (FAILED(rc)) throw rc;
     2716
     2717        task->progress = aProgress;
     2718
     2719        rc = task->startThread();
     2720        CheckComRCThrowRC(rc);
     2721
     2722        /* Don't destruct on success */
     2723        task.release();
     2724    }
     2725    catch (HRESULT aRC)
     2726    {
     2727        rc = aRC;
     2728    }
     2729
     2730    return rc;
     2731}
     2732
     2733DECLCALLBACK(int) Appliance::taskThreadWriteOVF(RTTHREAD /* aThread */, void *pvUser)
     2734{
     2735    std::auto_ptr<TaskWriteOVF> task(static_cast<TaskWriteOVF*>(pvUser));
     2736    AssertReturn(task.get(), VERR_GENERAL_FAILURE);
     2737
     2738    Appliance *pAppliance = task->pAppliance;
     2739
     2740    LogFlowFuncEnter();
     2741    LogFlowFunc(("Appliance %p\n", pAppliance));
     2742
     2743    HRESULT rc = S_OK;
     2744
     2745    switch(task->taskType)
     2746    {
     2747        case TaskWriteOVF::Write:
     2748        {
     2749            if (task->storageType == VFSType_File)
     2750                rc = pAppliance->writeFS(task.get());
     2751            else if (task->storageType == VFSType_S3)
     2752                rc = pAppliance->writeS3(task.get());
     2753            break;
     2754        }
     2755    }
     2756
     2757    LogFlowFunc(("rc=%Rhrc\n", rc));
     2758    LogFlowFuncLeave();
     2759
     2760    return VINF_SUCCESS;
    25852761}
    25862762
     
    25912767 */
    25922768/* static */
    2593 DECLCALLBACK(int) Appliance::taskThreadWriteOVF(RTTHREAD /* aThread */, void *pvUser)
    2594 {
    2595     std::auto_ptr<TaskWriteOVF> task(static_cast<TaskWriteOVF*>(pvUser));
    2596     AssertReturn(task.get(), VERR_GENERAL_FAILURE);
    2597 
    2598     Appliance *pAppliance = task->pAppliance;
    2599 
     2769int Appliance::writeFS(TaskWriteOVF *pTask)
     2770{
    26002771    LogFlowFuncEnter();
    2601     LogFlowFunc(("Appliance %p\n", pAppliance));
    2602 
    2603     AutoCaller autoCaller(pAppliance);
     2772    LogFlowFunc(("Appliance %p\n", this));
     2773
     2774    AutoCaller autoCaller(this);
    26042775    CheckComRCReturnRC(autoCaller.rc());
    26052776
    2606     AutoWriteLock appLock(pAppliance);
     2777    AutoWriteLock appLock(this);
    26072778
    26082779    HRESULT rc = S_OK;
    2609 
    2610     ComPtr<IVirtualBox> pVirtualBox(pAppliance->mVirtualBox);
    26112780
    26122781    try
     
    26152784        xml::ElementNode *pelmRoot = doc.createRootElement("Envelope");
    26162785
    2617         pelmRoot->setAttribute("ovf:version", (task->enFormat == TaskWriteOVF::OVF_1_0) ? "1.0" : "0.9");
     2786        pelmRoot->setAttribute("ovf:version", (pTask->enFormat == TaskWriteOVF::OVF_1_0) ? "1.0" : "0.9");
    26182787        pelmRoot->setAttribute("xml:lang", "en-US");
    26192788
     
    26392808            </DiskSection> */
    26402809        xml::ElementNode *pelmDiskSection;
    2641         if (task->enFormat == TaskWriteOVF::OVF_0_9)
     2810        if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
    26422811        {
    26432812            // <Section xsi:type="ovf:DiskSection_Type">
     
    26622831            </NetworkSection> */
    26632832        xml::ElementNode *pelmNetworkSection;
    2664         if (task->enFormat == TaskWriteOVF::OVF_0_9)
     2833        if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
    26652834        {
    26662835            // <Section xsi:type="ovf:NetworkSection_Type">
     
    26842853        // one machine, it seems
    26852854        xml::ElementNode *pelmToAddVirtualSystemsTo;
    2686         if (pAppliance->m->virtualSystemDescriptions.size() > 1)
     2855        if (m->virtualSystemDescriptions.size() > 1)
    26872856        {
    2688             if (task->enFormat == TaskWriteOVF::OVF_0_9)
     2857            if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
    26892858                throw setError(VBOX_E_FILE_ERROR,
    26902859                               tr("Cannot export more than one virtual system with OVF 0.9, use OVF 1.0"));
     
    26982867        list< ComObjPtr<VirtualSystemDescription> >::const_iterator it;
    26992868        /* Iterate through all virtual systems of that appliance */
    2700         for (it = pAppliance->m->virtualSystemDescriptions.begin();
    2701              it != pAppliance->m->virtualSystemDescriptions.end();
     2869        for (it = m->virtualSystemDescriptions.begin();
     2870             it != m->virtualSystemDescriptions.end();
    27022871             ++it)
    27032872        {
     
    27052874
    27062875            xml::ElementNode *pelmVirtualSystem;
    2707             if (task->enFormat == TaskWriteOVF::OVF_0_9)
     2876            if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
    27082877            {
    27092878                // <Section xsi:type="ovf:NetworkSection_Type">
     
    27492918                </Section> */
    27502919                xml::ElementNode *pelmAnnotationSection;
    2751                 if (task->enFormat == TaskWriteOVF::OVF_0_9)
     2920                if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
    27522921                {
    27532922                    // <Section ovf:required="false" xsi:type="ovf:ProductSection_Type">
     
    27812950                    </Section> */
    27822951                xml::ElementNode *pelmAnnotationSection;
    2783                 if (task->enFormat == TaskWriteOVF::OVF_0_9)
     2952                if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
    27842953                {
    27852954                    // <Section ovf:required="false" xsi:type="ovf:AnnotationSection_Type">
     
    28042973                   </EulaSection> */
    28052974                xml::ElementNode *pelmEulaSection;
    2806                 if (task->enFormat == TaskWriteOVF::OVF_0_9)
     2975                if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
    28072976                {
    28082977                    pelmEulaSection = pelmVirtualSystem->createChild("Section");
     
    28262995                </OperatingSystemSection> */
    28272996            xml::ElementNode *pelmOperatingSystemSection;
    2828             if (task->enFormat == TaskWriteOVF::OVF_0_9)
     2997            if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
    28292998            {
    28302999                pelmOperatingSystemSection = pelmVirtualSystem->createChild("Section");
     
    28423011            // <VirtualHardwareSection ovf:id="hw1" ovf:transport="iso">
    28433012            xml::ElementNode *pelmVirtualHardwareSection;
    2844             if (task->enFormat == TaskWriteOVF::OVF_0_9)
     3013            if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
    28453014            {
    28463015                // <Section xsi:type="ovf:VirtualHardwareSection_Type">
     
    28683037            // <vssd:VirtualSystemType>vmx-4</vssd:VirtualSystemType>
    28693038            const char *pcszHardware = "virtualbox-2.2";
    2870             if (task->enFormat == TaskWriteOVF::OVF_0_9)
     3039            if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
    28713040                // pretend to be vmware compatible then
    28723041                pcszHardware = "vmx-6";
     
    32263395                        // <rasd:InstanceID>1</rasd:InstanceID>
    32273396                        xml::ElementNode *pelmInstanceID;
    3228                         if (task->enFormat == TaskWriteOVF::OVF_0_9)
     3397                        if (pTask->enFormat == TaskWriteOVF::OVF_0_9)
    32293398                            pelmInstanceID = pItem->createChild("rasd:InstanceId");
    32303399                        else
     
    33023471            const Utf8Str &strTargetFileNameOnly = pDiskEntry->strOvf;
    33033472            // target path needs to be composed from where the output OVF is
    3304             Utf8Str strTargetFilePath = stripFilename(pAppliance->m->strPath);
     3473            Utf8Str strTargetFilePath = stripFilename(m->strPath);
    33053474            strTargetFilePath.append("/");
    33063475            strTargetFilePath.append(strTargetFileNameOnly);
     
    33123481
    33133482            Log(("Finding source disk \"%ls\"\n", bstrSrcFilePath.raw()));
    3314             rc = pVirtualBox->FindHardDisk(bstrSrcFilePath, pSourceDisk.asOutParam());
     3483            rc = mVirtualBox->FindHardDisk(bstrSrcFilePath, pSourceDisk.asOutParam());
    33153484            if (FAILED(rc)) throw rc;
    33163485
     
    33203489            // create a new hard disk interface for the destination disk image
    33213490            Log(("Creating target disk \"%s\"\n", strTargetFilePath.raw()));
    3322             rc = pVirtualBox->CreateHardDisk(bstrSrcFormat, Bstr(strTargetFilePath), pTargetDisk.asOutParam());
     3491            rc = mVirtualBox->CreateHardDisk(bstrSrcFormat, Bstr(strTargetFilePath), pTargetDisk.asOutParam());
    33233492            if (FAILED(rc)) throw rc;
    33243493
     
    33323501
    33333502                // advance to the next operation
    3334                 if (!task->progress.isNull())
    3335                     task->progress->setNextOperation(BstrFmt(tr("Exporting virtual disk image '%s'"), strSrcFilePath.c_str()),
     3503                if (!pTask->progress.isNull())
     3504                    pTask->progress->setNextOperation(BstrFmt(tr("Exporting virtual disk image '%s'"), strSrcFilePath.c_str()),
    33363505                                                     pDiskEntry->ulSizeMB);     // operation's weight, as set up with the IProgress originally);
    33373506
    33383507                // now wait for the background disk operation to complete; this throws HRESULTs on error
    3339                 pAppliance->waitForAsyncProgress(task->progress, pProgress2);
     3508                waitForAsyncProgress(pTask->progress, pProgress2);
    33403509            }
    33413510            catch (HRESULT rc3)
     
    33443513                // it'll stick in the registry forever
    33453514                pTargetDisk->Close();
    3346                 throw rc3;
     3515                throw;
    33473516            }
    33483517
     
    33813550        // now go write the XML
    33823551        xml::XmlFileWriter writer(doc);
    3383         writer.write(pAppliance->m->strPath.c_str());
     3552        writer.write(m->strPath.c_str());
    33843553    }
    33853554    catch(xml::Error &x)
     
    33933562    }
    33943563
    3395     task->rc = rc;
    3396 
    3397     if (!task->progress.isNull())
    3398         task->progress->notifyComplete(rc);
     3564    pTask->rc = rc;
     3565
     3566    if (!pTask->progress.isNull())
     3567        pTask->progress->notifyComplete(rc);
     3568
     3569    LogFlowFunc(("rc=%Rhrc\n", rc));
     3570    LogFlowFuncLeave();
     3571
     3572    return VINF_SUCCESS;
     3573}
     3574
     3575/**
     3576 * Worker thread implementation for Upload() (ovf uploader).
     3577 * @param aThread
     3578 * @param pvUser
     3579 */
     3580/* static */
     3581int Appliance::writeS3(TaskWriteOVF *pTask)
     3582{
     3583    LogFlowFuncEnter();
     3584    LogFlowFunc(("Appliance %p\n", this));
     3585
     3586    AutoCaller autoCaller(this);
     3587    CheckComRCReturnRC(autoCaller.rc());
     3588
     3589    HRESULT rc = S_OK;
     3590
     3591    AutoWriteLock appLock(this);
     3592
     3593    /* Buckets are S3 specific. So parse the bucket out of the file path */
     3594    Utf8Str tmpPath = pTask->filepath;
     3595    if (!tmpPath.startsWith("/"))
     3596        return setError(E_INVALIDARG,
     3597                        tr("The path '%s' must start with /"), tmpPath.c_str());
     3598    Utf8Str bucket;
     3599    size_t bpos = tmpPath.find("/", 1);
     3600    if (bpos != Utf8Str::npos)
     3601    {
     3602        bucket = tmpPath.substr(1, bpos - 1); /* The bucket without any slashes */
     3603        tmpPath = tmpPath.substr(bpos); /* The rest of the file path */
     3604    }
     3605    /* If there is no bucket name provided reject the upload */
     3606    if (bucket.isEmpty())
     3607        return setError(E_INVALIDARG,
     3608                        tr("You doesn't provide a bucket name in the URI"), tmpPath.c_str());
     3609
     3610    int vrc = VINF_SUCCESS;
     3611    RTS3 hS3 = NULL;
     3612    char szOSTmpDir[RTPATH_MAX];
     3613    RTPathTemp(szOSTmpDir, sizeof(szOSTmpDir));
     3614    /* The template for the temporary directory created below */
     3615    char *pszTmpDir;
     3616    RTStrAPrintf(&pszTmpDir, "%s"RTPATH_SLASH_STR"vbox-ovf-XXXXXX", szOSTmpDir);
     3617    list< pair<Utf8Str, ULONG> > filesList;
     3618
     3619    // todo:
     3620    // - getting the tmp directory (especially on win)
     3621    // - usable error codes
     3622    // - seems snapshot filenames are problematic {uuid}.vdi
     3623    try
     3624    {
     3625        /* We need a temporary directory which we can put the OVF file & all
     3626         * disk images in */
     3627        vrc = RTDirCreateTemp(pszTmpDir);
     3628        if (RT_FAILURE(rc))
     3629            throw setError(VBOX_E_FILE_ERROR,
     3630                           tr("Cannot create temporary directory '%s'"), pszTmpDir);
     3631
     3632        /* The temporary name of the target OVF file */
     3633        Utf8StrFmt strTmpOvf("%s/%s", pszTmpDir, RTPathFilename(tmpPath));
     3634
     3635        /* Prepare the temporary writing of the OVF */
     3636        ComObjPtr<Progress> progress;
     3637        rc = writeImpl(pTask->enFormat, strTmpOvf.c_str(), progress);
     3638        if (FAILED(rc)) throw rc;
     3639
     3640        /* Unlock the appliance for the writing thread */
     3641        appLock.unlock();
     3642        /* Wait until the writing is done, but report the progress back to the
     3643           caller */
     3644        ComPtr<IProgress> progressInt(progress);
     3645        waitForAsyncProgress(pTask->progress, progressInt); /* Any errors will be thrown */
     3646
     3647        /* Again lock the appliance for the next steps */
     3648        appLock.lock();
     3649
     3650        vrc = RTPathExists(strTmpOvf.c_str()); /* Paranoid check */
     3651        if(RT_FAILURE(vrc))
     3652            throw setError(VBOX_E_FILE_ERROR,
     3653                           tr("Cannot find source file '%s'"), strTmpOvf.c_str());
     3654        /* Add the OVF file */
     3655        filesList.push_back(pair<Utf8Str, ULONG>(strTmpOvf, m->ulWeightPerOperation)); /* Use 1% of the total for the OVF file upload */
     3656
     3657        /* Now add every disks of every virtual system */
     3658        list< ComObjPtr<VirtualSystemDescription> >::const_iterator it;
     3659        for (it = m->virtualSystemDescriptions.begin();
     3660             it != m->virtualSystemDescriptions.end();
     3661             ++it)
     3662        {
     3663            ComObjPtr<VirtualSystemDescription> vsdescThis = (*it);
     3664            std::list<VirtualSystemDescriptionEntry*> avsdeHDs = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskImage);
     3665            std::list<VirtualSystemDescriptionEntry*>::const_iterator itH;
     3666            for (itH = avsdeHDs.begin();
     3667                 itH != avsdeHDs.end();
     3668                 ++itH)
     3669            {
     3670                const Utf8Str &strTargetFileNameOnly = (*itH)->strOvf;
     3671                /* Target path needs to be composed from where the output OVF is */
     3672                Utf8Str strTargetFilePath = stripFilename(m->strPath);
     3673                strTargetFilePath.append("/");
     3674                strTargetFilePath.append(strTargetFileNameOnly);
     3675                vrc = RTPathExists(strTargetFilePath.c_str()); /* Paranoid check */
     3676                if(RT_FAILURE(vrc))
     3677                    throw setError(VBOX_E_FILE_ERROR,
     3678                                   tr("Cannot find source file '%s'"), strTargetFilePath.c_str());
     3679                filesList.push_back(pair<Utf8Str, ULONG>(strTargetFilePath, (*itH)->ulSizeMB));
     3680            }
     3681        }
     3682        /* Next we have to upload the OVF & all disk images */
     3683        vrc = RTS3Create(&hS3, pTask->username.c_str(), pTask->password.c_str(), pTask->hostname.c_str(), "virtualbox-agent/"VBOX_VERSION_STRING);
     3684        if(RT_FAILURE(vrc))
     3685            throw setError(VBOX_E_IPRT_ERROR,
     3686                           tr("Cannot create S3 service handler"));
     3687        RTS3SetProgressCallback(hS3, pTask->uploadProgress, &pTask);
     3688
     3689        /* Upload all files */
     3690        for (list< pair<Utf8Str, ULONG> >::const_iterator it1 = filesList.begin(); it1 != filesList.end(); ++it1)
     3691        {
     3692            const pair<Utf8Str, ULONG> &s = (*it1);
     3693            char *pszFilename = RTPathFilename(s.first.c_str());
     3694            /* Advance to the next operation */
     3695            if (!pTask->progress.isNull())
     3696                pTask->progress->setNextOperation(BstrFmt(tr("Uploading file '%s'"), pszFilename), s.second);
     3697            vrc = RTS3PutKey(hS3, bucket.c_str(), pszFilename, s.first.c_str());
     3698            if (RT_FAILURE(vrc))
     3699            {
     3700                if(vrc == VERR_S3_CANCELED)
     3701                    break;
     3702                else if(vrc == VERR_S3_ACCESS_DENIED)
     3703                    throw setError(E_ACCESSDENIED,
     3704                                   tr("Cannot upload file '%s' to S3 storage server (Access denied)"), pszFilename);
     3705                else if(vrc == VERR_S3_NOT_FOUND)
     3706                    throw setError(VBOX_E_FILE_ERROR,
     3707                                   tr("Cannot upload file '%s' to S3 storage server (File not found)"), pszFilename);
     3708                else
     3709                    throw setError(VBOX_E_IPRT_ERROR,
     3710                                   tr("Cannot upload file '%s' to S3 storage server (%Rrc)"), pszFilename, vrc);
     3711            }
     3712        }
     3713
     3714    }
     3715    catch(HRESULT aRC)
     3716    {
     3717        rc = aRC;
     3718    }
     3719    /* Cleanup */
     3720    if (hS3)
     3721        RTS3Destroy(hS3);
     3722    /* Delete all files which where temporary created */
     3723    for (list< pair<Utf8Str, ULONG> >::const_iterator it1 = filesList.begin(); it1 != filesList.end(); ++it1)
     3724    {
     3725        const pair<Utf8Str, ULONG> &s = (*it1);
     3726        vrc = RTFileDelete(s.first.c_str());
     3727        if(RT_FAILURE(vrc))
     3728            rc = setError(VBOX_E_FILE_ERROR,
     3729                          tr("Cannot delete file '%s' (%Rrc)"), s.first.c_str(), vrc);
     3730    }
     3731    /* Delete the temporary directory */
     3732    if (RTPathExists(pszTmpDir))
     3733    {
     3734        vrc = RTDirRemove(pszTmpDir);
     3735        if(RT_FAILURE(vrc))
     3736            rc = setError(VBOX_E_FILE_ERROR,
     3737                          tr("Cannot delete temporary directory '%s' (%Rrc)"), pszTmpDir, vrc);
     3738    }
     3739    if (pszTmpDir)
     3740        RTStrFree(pszTmpDir);
     3741
     3742    pTask->rc = rc;
     3743
     3744    if (!pTask->progress.isNull())
     3745        pTask->progress->notifyComplete(rc);
    33993746
    34003747    LogFlowFunc(("rc=%Rhrc\n", rc));
     
    35423889                         bstrDescription, // CBSTR bstrFirstOperationDescription,
    35433890                         m->ulWeightPerOperation); // ULONG ulFirstOperationWeight,
     3891    return rc;
     3892}
     3893
     3894HRESULT Appliance::setUpProgressUpload(ComObjPtr<Progress> &pProgress, const Bstr &bstrDescription)
     3895{
     3896    HRESULT rc;
     3897
     3898    /* Create the progress object */
     3899    pProgress.createObject();
     3900
     3901    // weigh the disk images according to their sizes
     3902    uint32_t ulTotalMB = 0;
     3903    uint32_t cDisks = 0;
     3904    list< ComObjPtr<VirtualSystemDescription> >::const_iterator it;
     3905    for (it = m->virtualSystemDescriptions.begin();
     3906         it != m->virtualSystemDescriptions.end();
     3907         ++it)
     3908    {
     3909        ComObjPtr<VirtualSystemDescription> vsdescThis = (*it);
     3910        /* One for every hard disk of the Virtual System */
     3911        std::list<VirtualSystemDescriptionEntry*> avsdeHDs = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskImage);
     3912        std::list<VirtualSystemDescriptionEntry*>::const_iterator itH;
     3913        for (itH = avsdeHDs.begin();
     3914             itH != avsdeHDs.end();
     3915             ++itH)
     3916        {
     3917            const VirtualSystemDescriptionEntry *pHD = *itH;
     3918            ulTotalMB += pHD->ulSizeMB;
     3919            ++cDisks;
     3920        }
     3921    }
     3922
     3923    ULONG cOperations = 1 + 1 + cDisks;     // one op per disk plus 1 for the OVF & 1 plus to the temporary creation */
     3924
     3925    ULONG ulTotalOperationsWeight;
     3926    if (ulTotalMB)
     3927    {
     3928        m->ulWeightPerOperation = (ULONG)((double)ulTotalMB * 1  / 100);    // use 1% of the progress for OVF file upload (we didn't know the size at this point)
     3929        ulTotalOperationsWeight = ulTotalMB + m->ulWeightPerOperation;
     3930    }
     3931    else
     3932    {
     3933        // no disks to export:
     3934        ulTotalOperationsWeight = 1;
     3935        m->ulWeightPerOperation = 1;
     3936    }
     3937    ULONG ulOVFCreationWeight = ((double)ulTotalOperationsWeight * 50.0 / 100.0); /* Use 50% for the creation of the OVF & the disks */
     3938    ulTotalOperationsWeight += ulOVFCreationWeight;
     3939
     3940    Log(("Setting up progress object: ulTotalMB = %d, cDisks = %d, => cOperations = %d, ulTotalOperationsWeight = %d, m->ulWeightPerOperation = %d\n",
     3941         ulTotalMB, cDisks, cOperations, ulTotalOperationsWeight, m->ulWeightPerOperation));
     3942
     3943    rc = pProgress->init(mVirtualBox, static_cast<IAppliance*>(this),
     3944                         bstrDescription,
     3945                         TRUE /* aCancelable */,
     3946                         cOperations, // ULONG cOperations,
     3947                         ulTotalOperationsWeight, // ULONG ulTotalOperationsWeight,
     3948                         bstrDescription, // CBSTR bstrFirstOperationDescription,
     3949                         ulOVFCreationWeight); // ULONG ulFirstOperationWeight,
    35443950    return rc;
    35453951}
  • trunk/src/VBox/Main/Makefile.kmk

    r20045 r20081  
    285285        VirtualBoxImplExtra.cpp \
    286286        ApplianceImpl.cpp \
     287        VFSExplorerImpl.cpp \
    287288        MachineImpl.cpp \
    288289        SnapshotImpl.cpp \
  • trunk/src/VBox/Main/VFSExplorerImpl.cpp

    r20044 r20081  
    4646    struct DirEntry
    4747    {
    48         DirEntry(Utf8Str aName, FileType_T aType)
     48        DirEntry(Utf8Str aName, VFSFileType_T aType)
    4949          : name(aName)
    5050          , type(aType) {}
    5151
    5252        Utf8Str name;
    53         FileType_T type;
     53        VFSFileType_T type;
    5454    };
    5555
     
    248248}
    249249
    250 FileType_T VFSExplorer::RTToFileType(int aType) const
    251 {
    252     FileType_T t;
     250VFSFileType_T VFSExplorer::RTToVFSFileType(int aType) const
     251{
     252    VFSFileType_T t;
    253253    switch(aType)
    254254    {
    255         case RTDIRENTRYTYPE_UNKNOWN: t = FileType_Unknown; break;
    256         case RTDIRENTRYTYPE_FIFO: t = FileType_Fifo; break;
    257         case RTDIRENTRYTYPE_DEV_CHAR: t = FileType_DevChar; break;
    258         case RTDIRENTRYTYPE_DIRECTORY: t = FileType_Directory; break;
    259         case RTDIRENTRYTYPE_DEV_BLOCK: t = FileType_DevBlock; break;
    260         case RTDIRENTRYTYPE_FILE: t = FileType_File; break;
    261         case RTDIRENTRYTYPE_SYMLINK: t = FileType_SymLink; break;
    262         case RTDIRENTRYTYPE_SOCKET: t = FileType_Socket; break;
    263         case RTDIRENTRYTYPE_WHITEOUT: t = FileType_WhiteOut; break;
     255        case RTDIRENTRYTYPE_UNKNOWN: t = VFSFileType_Unknown; break;
     256        case RTDIRENTRYTYPE_FIFO: t = VFSFileType_Fifo; break;
     257        case RTDIRENTRYTYPE_DEV_CHAR: t = VFSFileType_DevChar; break;
     258        case RTDIRENTRYTYPE_DIRECTORY: t = VFSFileType_Directory; break;
     259        case RTDIRENTRYTYPE_DEV_BLOCK: t = VFSFileType_DevBlock; break;
     260        case RTDIRENTRYTYPE_FILE: t = VFSFileType_File; break;
     261        case RTDIRENTRYTYPE_SYMLINK: t = VFSFileType_SymLink; break;
     262        case RTDIRENTRYTYPE_SOCKET: t = VFSFileType_Socket; break;
     263        case RTDIRENTRYTYPE_WHITEOUT: t = VFSFileType_WhiteOut; break;
    264264    }
    265265    return t;
     
    286286        int vrc = RTDirOpen(&pDir, pszPath);
    287287        if (RT_FAILURE(vrc))
    288             throw setError(VBOX_E_FILE_ERROR, tr ("Can't open directory '%s'", pszPath));
     288            throw setError(VBOX_E_FILE_ERROR, tr ("Can't open directory '%s' (%Rrc)"), pszPath, vrc);
    289289
    290290        if(aTask->progress)
     
    299299                if (name != "." &&
    300300                    name != "..")
    301                     fileList.push_back(VFSExplorer::Data::DirEntry(name, RTToFileType(entry.enmType)));
     301                    fileList.push_back(VFSExplorer::Data::DirEntry(name, RTToVFSFileType(entry.enmType)));
    302302            }
    303303        }
     
    360360            int vrc = RTFileDelete(szPath);
    361361            if (RT_FAILURE(vrc))
    362                 throw setError(VBOX_E_FILE_ERROR, tr ("Can't delete file '%s'", szPath));
     362                throw setError(VBOX_E_FILE_ERROR, tr ("Can't delete file '%s' (%Rrc)"), szPath, vrc);
    363363            if(aTask->progress)
    364364                aTask->progress->setCurrentOperationProgress(fPercentStep * i);
     
    398398        int vrc = RTS3Create(&hS3, m->strUsername.c_str(), m->strPassword.c_str(), m->strHostname.c_str(), "virtualbox-agent/"VBOX_VERSION_STRING);
    399399        if (RT_FAILURE(vrc))
    400             throw setError(E_FAIL, tr ("Can't open S3 storage service"));
     400            throw setError(E_FAIL, tr ("Can't open S3 storage service (%Rrc)"), vrc);
    401401
    402402        RTS3SetProgressCallback(hS3, VFSExplorer::TaskVFSExplorer::uploadProgress, &aTask);
     
    407407            vrc = RTS3GetBuckets(hS3, &pBuckets);
    408408            if (RT_FAILURE(vrc))
    409                 throw setError(E_FAIL, tr ("Can't get buckets"));
     409                throw setError(E_FAIL, tr ("Can't get buckets (%Rrc)"), vrc);
    410410
    411411            PCRTS3BUCKETENTRY pTmpBuckets = pBuckets;
    412412            while (pBuckets)
    413413            {
    414                 fileList.push_back(VFSExplorer::Data::DirEntry(pBuckets->pszName, FileType_Directory));
     414                fileList.push_back(VFSExplorer::Data::DirEntry(pBuckets->pszName, VFSFileType_Directory));
    415415                pBuckets = pBuckets->pNext;
    416416            }
     
    422422            vrc = RTS3GetBucketKeys(hS3, m->strBucket, &pKeys);
    423423            if (RT_FAILURE(vrc))
    424                 throw setError(E_FAIL, tr ("Can't get keys for bucket"));
     424                throw setError(E_FAIL, tr ("Can't get keys for bucket (%Rrc)"), vrc);
    425425
    426426            PCRTS3KEYENTRY pTmpKeys = pKeys;
     
    428428            {
    429429                Utf8Str name(pKeys->pszName);
    430                 fileList.push_back(VFSExplorer::Data::DirEntry(pKeys->pszName, FileType_File));
     430                fileList.push_back(VFSExplorer::Data::DirEntry(pKeys->pszName, VFSFileType_File));
    431431                pKeys = pKeys->pNext;
    432432            }
     
    474474        int vrc = RTS3Create(&hS3, m->strUsername.c_str(), m->strPassword.c_str(), m->strHostname.c_str(), "virtualbox-agent/"VBOX_VERSION_STRING);
    475475        if (RT_FAILURE(vrc))
    476             throw setError(E_FAIL, tr ("Can't open S3 storage service"));
     476            throw setError(E_FAIL, tr ("Can't open S3 storage service (%Rrc)"), vrc);
    477477
    478478        RTS3SetProgressCallback(hS3, VFSExplorer::TaskVFSExplorer::uploadProgress, &aTask);
     
    486486            vrc = RTS3DeleteKey(hS3, m->strBucket.c_str(), (*it).c_str());
    487487            if (RT_FAILURE(vrc))
    488                 throw setError(VBOX_E_FILE_ERROR, tr ("Can't delete file '%s'", (*it).c_str()));
     488                throw setError(VBOX_E_FILE_ERROR, tr ("Can't delete file '%s' (%Rrc)"), (*it).c_str(), vrc);
    489489            if(aTask->progress)
    490490                aTask->progress->setCurrentOperationProgress(fPercentStep * i);
     
    540540        if (FAILED(rc)) throw rc;
    541541
     542        /* Don't destruct on success */
    542543        task.release();
    543544    }
     
    554555}
    555556
    556 STDMETHODIMP VFSExplorer::EntryList(ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(FileType_T, aTypes))
     557STDMETHODIMP VFSExplorer::EntryList(ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(VFSFileType_T, aTypes))
    557558{
    558559    if (ComSafeArrayOutIsNull(aNames) ||
     
    566567
    567568    com::SafeArray<BSTR> sfaNames((ULONG)m->entryList.size());
    568     com::SafeArray<ULONG> sfaTypes((FileType_T)m->entryList.size());
     569    com::SafeArray<ULONG> sfaTypes((VFSFileType_T)m->entryList.size());
    569570
    570571    std::list<VFSExplorer::Data::DirEntry>::const_iterator it;
     
    657658        if (FAILED(rc)) throw rc;
    658659
     660        /* Don't destruct on success */
    659661        task.release();
    660662    }
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r20045 r20081  
    28902890    </method>
    28912891
     2892  </interface>
     2893
     2894  <!--
     2895  // IVFSExplorer
     2896  /////////////////////////////////////////////////////////////////////////
     2897  -->
     2898
     2899  <enum
     2900    name="VFSType"
     2901    uuid="813999ba-b949-48a8-9230-aadc6285e2f2"
     2902  >
     2903    <desc>
     2904      Supported virtual file systems of VFSExplorer.
     2905    </desc>
     2906
     2907    <const name="File" value="1" />
     2908    <const name="Cloud" value="2" />
     2909    <const name="S3" value="3" />
     2910    <const name="WebDav" value="4" />
     2911  </enum>
     2912
     2913  <enum
     2914    name="VFSFileType"
     2915    uuid="714333cd-44e2-415f-a245-d378fa9b1242"
     2916  >
     2917    <desc>
     2918      File types known by VFSExplorer.
     2919    </desc>
     2920
     2921    <const name="Unknown" value="1" />
     2922    <const name="Fifo" value="2" />
     2923    <const name="DevChar" value="3" />
     2924    <const name="Directory" value="4" />
     2925    <const name="DevBlock" value="5" />
     2926    <const name="File" value="6" />
     2927    <const name="SymLink" value="7" />
     2928    <const name="Socket" value="8" />
     2929    <const name="WhiteOut" value="9" />
     2930  </enum>
     2931
     2932  <interface
     2933     name="IVFSExplorer" extends="$unknown"
     2934     uuid="fd7da337-80ef-4a5c-9122-918435e33003"
     2935     wsmap="managed"
     2936     >
     2937    <desc>
     2938      The VFSExplorer interface unify the access to different file system
     2939      types. This includes local file systems as well remote file systems like
     2940      the S3 one. For a list of supported types see <link to="VFSType" />.
     2941    </desc>
     2942
     2943    <attribute name="path" type="wstring" readonly="yes">
     2944      <desc>Return the current path in the virtual file system.</desc>
     2945    </attribute>
     2946
     2947    <attribute name="type" type="VFSType" readonly="yes">
     2948      <desc>Return the file system type which is currently in use.</desc>
     2949    </attribute>
     2950
     2951    <method name="update">
     2952      <desc>This method updates the internal list of files/directories from the
     2953      current directory level. Use <link to="entryList" /> to get the full list
     2954      after a call to this method.</desc>
     2955
     2956      <param name="aProgress" type="IProgress" dir="return">
     2957        <desc>Progress object to track the operation completion.</desc>
     2958      </param>
     2959    </method>
     2960
     2961    <method name="entryList">
     2962      <desc>Fetch the list of files/directories after a call to <link
     2963      to="update" />. The user is responcible for keeping this internal list up
     2964      do date.</desc>
     2965
     2966      <param name="aNames" type="wstring" safearray="yes" dir="out">
     2967        <desc>The list of names for the entries.</desc>
     2968      </param>
     2969
     2970      <param name="aTypes" type="unsigned long" safearray="yes" dir="out">
     2971        <desc>The list of types for the entries.</desc>
     2972      </param>
     2973    </method>
     2974
     2975    <method name="exists">
     2976        <desc>Check if the given file list exists in the current directory
     2977        level.</desc>
     2978
     2979      <param name="aNames" type="wstring" safearray="yes" dir="in">
     2980        <desc>The names to check.</desc>
     2981      </param>
     2982
     2983      <param name="aExists" type="wstring" safearray="yes" dir="return">
     2984        <desc>The names which exists.</desc>
     2985      </param>
     2986    </method>
     2987
     2988    <method name="remove">
     2989        <desc>Remove the given file names from the current directory
     2990        level.</desc>
     2991
     2992      <param name="aNames" type="wstring" safearray="yes" dir="in">
     2993        <desc>The names to remove.</desc>
     2994      </param>
     2995
     2996      <param name="aProgress" type="IProgress" dir="return">
     2997        <desc>Progress object to track the operation completion.</desc>
     2998      </param>
     2999    </method>
     3000   
    28923001  </interface>
    28933002
     
    30433152  <interface
    30443153     name="IAppliance" extends="$unknown"
    3045      uuid="30bfa6b8-9eda-4b0a-b218-a86813248ccd"
     3154     uuid="07495095-d16c-4911-8964-5914341ced5d"
    30463155     wsmap="managed"
    30473156     >
     
    32293338    </method>
    32303339
     3340    <method name="createVFSExplorer">
     3341      <desc>Returns a <link to="IVFSExplorer" /> object for the given URI.</desc>
     3342
     3343      <param name="aUri" type="wstring" dir="in">
     3344        <desc>The URI describing the file system to use.</desc>
     3345      </param>
     3346
     3347      <param name="aExplorer" type="IVFSExplorer" dir="return">
     3348        <desc></desc>
     3349      </param>
     3350    </method>
     3351
    32313352    <method name="write">
    32323353      <desc>
     
    32533374      </param>
    32543375      <param name="aProgress" type="IProgress" dir="return">
    3255           <desc></desc>
     3376        <desc>Progress object to track the operation completion.</desc>
    32563377      </param>
    32573378    </method>
  • trunk/src/VBox/Main/include/ApplianceImpl.h

    r20045 r20081  
    7575
    7676    /* IAppliance methods */
     77    /* Import methods */
    7778    STDMETHOD(Read)(IN_BSTR path);
    7879    STDMETHOD(Interpret)(void);
    7980    STDMETHOD(ImportMachines)(IProgress **aProgress);
     81    /* Export methods */
     82    STDMETHOD(CreateVFSExplorer)(IN_BSTR aURI, IVFSExplorer **aExplorer);
    8083    STDMETHOD(Write)(IN_BSTR format, IN_BSTR path, IProgress **aProgress);
     84
    8185    STDMETHOD(GetWarnings)(ComSafeArrayOut(BSTR, aWarnings));
    8286
     
    99103    HRESULT searchUniqueDiskImageFilePath(Utf8Str& aName) const;
    100104    HRESULT setUpProgress(ComObjPtr<Progress> &pProgress, const Bstr &bstrDescription);
     105    HRESULT setUpProgressUpload(ComObjPtr<Progress> &pProgress, const Bstr &bstrDescription);
    101106    void waitForAsyncProgress(ComObjPtr<Progress> &pProgressThis, ComPtr<IProgress> &pProgressAsync);
    102107    void addWarning(const char* aWarning, ...);
    103108
     109    void parseURI(Utf8Str strUri, const Utf8Str &strProtocol, Utf8Str &strFilepath, Utf8Str &strHostname, Utf8Str &strUsername, Utf8Str &strPassword);
     110    HRESULT writeImpl(int aFormat, Utf8Str aPath, ComObjPtr<Progress> &aProgress);
     111
     112    char * mkTemp(char *pszTemplate);
    104113    struct TaskImportMachines;  /* Worker thread for import */
    105114    static DECLCALLBACK(int) taskThreadImportMachines(RTTHREAD thread, void *pvUser);
    106115
    107     struct TaskWriteOVF;       /* Worker thread for export */
    108     static DECLCALLBACK(int) taskThreadWriteOVF(RTTHREAD thread, void *pvUser);
     116    struct TaskWriteOVF;        /* Worker threads for export */
     117    static DECLCALLBACK(int) taskThreadWriteOVF(RTTHREAD aThread, void *pvUser);
     118
     119    int writeFS(TaskWriteOVF *pTask);
     120    int writeS3(TaskWriteOVF *pTask);
    109121
    110122    friend class Machine;
  • trunk/src/VBox/Main/include/VFSExplorerImpl.h

    r20044 r20081  
    6868    STDMETHOD(Update)(IProgress **aProgress);
    6969
    70     STDMETHOD(EntryList)(ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(FileType_T, aTypes));
     70    STDMETHOD(EntryList)(ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(VFSFileType_T, aTypes));
    7171
    7272    STDMETHOD(Exists)(ComSafeArrayIn(IN_BSTR, aNames), ComSafeArrayOut(BSTR, aExists));
     
    9191
    9292    /* Private member methods */
    93     FileType_T RTToFileType(int aType) const;
     93    VFSFileType_T RTToVFSFileType(int aType) const;
    9494
    9595    HRESULT updateFS(TaskVFSExplorer *aTask);
  • trunk/src/VBox/Main/xpcom/server.cpp

    r20045 r20081  
    7474#include <VirtualBoxImpl.h>
    7575#include <MachineImpl.h>
     76#include <VFSExplorerImpl.h>
    7677#include <ApplianceImpl.h>
    7778#include <SnapshotImpl.h>
     
    110111NS_DECL_CLASSINFO(Machine)
    111112NS_IMPL_THREADSAFE_ISUPPORTS1_CI(Machine, IMachine)
     113
     114NS_DECL_CLASSINFO(VFSExplorer)
     115NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VFSExplorer, IVFSExplorer)
    112116
    113117NS_DECL_CLASSINFO(Appliance)
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette