Changeset 20081 in vbox
- Timestamp:
- May 27, 2009 12:55:11 PM (15 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 5 edited
- 2 copied
-
ApplianceImpl.cpp (modified) (27 diffs)
-
Makefile.kmk (modified) (1 diff)
-
VFSExplorerImpl.cpp (copied) (copied from trunk/src/VBox/Main/VFSExplorerImpl.cpp ) (15 diffs)
-
idl/VirtualBox.xidl (modified) (4 diffs)
-
include/ApplianceImpl.h (modified) (2 diffs)
-
include/VFSExplorerImpl.h (copied) (copied from trunk/src/VBox/Main/include/VFSExplorerImpl.h ) (2 diffs)
-
xpcom/server.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ApplianceImpl.cpp
r20045 r20081 21 21 */ 22 22 23 #include <VBox/param.h>24 23 #include <iprt/stream.h> 25 24 #include <iprt/path.h> 26 25 #include <iprt/dir.h> 27 26 #include <iprt/file.h> 27 #include <iprt/s3.h> 28 29 #include <VBox/param.h> 30 #include <VBox/version.h> 28 31 29 32 #include "ApplianceImpl.h" 33 #include "VFSExplorerImpl.h" 30 34 #include "VirtualBoxImpl.h" 31 35 #include "GuestOSTypeImpl.h" … … 460 464 * @return 461 465 */ 462 463 466 HRESULT Appliance::init(VirtualBox *aVirtualBox) 464 467 { … … 2501 2504 struct Appliance::TaskWriteOVF 2502 2505 { 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), 2507 2522 rc(S_OK) 2508 2523 {} 2509 2524 ~TaskWriteOVF() {} 2510 2525 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; 2513 2536 Appliance *pAppliance; 2514 enum { unspecified, OVF_0_9, OVF_1_0 }2515 enFormat;2516 2517 2537 ComObjPtr<Progress> progress; 2518 2538 HRESULT rc; 2519 2539 }; 2520 2540 2521 HRESULTAppliance::TaskWriteOVF::startThread()2541 int Appliance::TaskWriteOVF::startThread() 2522 2542 { 2523 2543 int vrc = RTThreadCreate(NULL, Appliance::taskThreadWriteOVF, this, 2524 2544 0, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0, 2525 2545 "Appliance::Task"); 2546 2526 2547 ComAssertMsgRCRet(vrc, 2527 ("Could not create taskThread ExportOVF (%Rrc)\n", vrc), E_FAIL);2548 ("Could not create taskThreadWriteOVF (%Rrc)\n", vrc), E_FAIL); 2528 2549 2529 2550 return S_OK; 2530 2551 } 2531 2552 2553 /* static */ 2554 int 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 2570 STDMETHODIMP 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 2532 2617 STDMETHODIMP Appliance::Write(IN_BSTR format, IN_BSTR path, IProgress **aProgress) 2533 2618 { … … 2537 2622 2538 2623 AutoCaller autoCaller(this); 2539 if (FAILED(rc = autoCaller.rc())) return rc;2624 CheckComRCReturnRC(autoCaller.rc()); 2540 2625 2541 2626 AutoWriteLock(this); 2542 2627 2543 2628 // 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)) 2546 2631 return setError(VBOX_E_FILE_ERROR, 2547 2632 tr("Appliance file must have .ovf extension")); 2548 2633 2549 2634 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); 2579 2646 2580 2647 if (SUCCEEDED(rc)) … … 2583 2650 2584 2651 return rc; 2652 } 2653 2654 void 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 2680 HRESULT 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 2733 DECLCALLBACK(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; 2585 2761 } 2586 2762 … … 2591 2767 */ 2592 2768 /* 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 2769 int Appliance::writeFS(TaskWriteOVF *pTask) 2770 { 2600 2771 LogFlowFuncEnter(); 2601 LogFlowFunc(("Appliance %p\n", pAppliance));2602 2603 AutoCaller autoCaller( pAppliance);2772 LogFlowFunc(("Appliance %p\n", this)); 2773 2774 AutoCaller autoCaller(this); 2604 2775 CheckComRCReturnRC(autoCaller.rc()); 2605 2776 2606 AutoWriteLock appLock( pAppliance);2777 AutoWriteLock appLock(this); 2607 2778 2608 2779 HRESULT rc = S_OK; 2609 2610 ComPtr<IVirtualBox> pVirtualBox(pAppliance->mVirtualBox);2611 2780 2612 2781 try … … 2615 2784 xml::ElementNode *pelmRoot = doc.createRootElement("Envelope"); 2616 2785 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"); 2618 2787 pelmRoot->setAttribute("xml:lang", "en-US"); 2619 2788 … … 2639 2808 </DiskSection> */ 2640 2809 xml::ElementNode *pelmDiskSection; 2641 if ( task->enFormat == TaskWriteOVF::OVF_0_9)2810 if (pTask->enFormat == TaskWriteOVF::OVF_0_9) 2642 2811 { 2643 2812 // <Section xsi:type="ovf:DiskSection_Type"> … … 2662 2831 </NetworkSection> */ 2663 2832 xml::ElementNode *pelmNetworkSection; 2664 if ( task->enFormat == TaskWriteOVF::OVF_0_9)2833 if (pTask->enFormat == TaskWriteOVF::OVF_0_9) 2665 2834 { 2666 2835 // <Section xsi:type="ovf:NetworkSection_Type"> … … 2684 2853 // one machine, it seems 2685 2854 xml::ElementNode *pelmToAddVirtualSystemsTo; 2686 if ( pAppliance->m->virtualSystemDescriptions.size() > 1)2855 if (m->virtualSystemDescriptions.size() > 1) 2687 2856 { 2688 if ( task->enFormat == TaskWriteOVF::OVF_0_9)2857 if (pTask->enFormat == TaskWriteOVF::OVF_0_9) 2689 2858 throw setError(VBOX_E_FILE_ERROR, 2690 2859 tr("Cannot export more than one virtual system with OVF 0.9, use OVF 1.0")); … … 2698 2867 list< ComObjPtr<VirtualSystemDescription> >::const_iterator it; 2699 2868 /* 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(); 2702 2871 ++it) 2703 2872 { … … 2705 2874 2706 2875 xml::ElementNode *pelmVirtualSystem; 2707 if ( task->enFormat == TaskWriteOVF::OVF_0_9)2876 if (pTask->enFormat == TaskWriteOVF::OVF_0_9) 2708 2877 { 2709 2878 // <Section xsi:type="ovf:NetworkSection_Type"> … … 2749 2918 </Section> */ 2750 2919 xml::ElementNode *pelmAnnotationSection; 2751 if ( task->enFormat == TaskWriteOVF::OVF_0_9)2920 if (pTask->enFormat == TaskWriteOVF::OVF_0_9) 2752 2921 { 2753 2922 // <Section ovf:required="false" xsi:type="ovf:ProductSection_Type"> … … 2781 2950 </Section> */ 2782 2951 xml::ElementNode *pelmAnnotationSection; 2783 if ( task->enFormat == TaskWriteOVF::OVF_0_9)2952 if (pTask->enFormat == TaskWriteOVF::OVF_0_9) 2784 2953 { 2785 2954 // <Section ovf:required="false" xsi:type="ovf:AnnotationSection_Type"> … … 2804 2973 </EulaSection> */ 2805 2974 xml::ElementNode *pelmEulaSection; 2806 if ( task->enFormat == TaskWriteOVF::OVF_0_9)2975 if (pTask->enFormat == TaskWriteOVF::OVF_0_9) 2807 2976 { 2808 2977 pelmEulaSection = pelmVirtualSystem->createChild("Section"); … … 2826 2995 </OperatingSystemSection> */ 2827 2996 xml::ElementNode *pelmOperatingSystemSection; 2828 if ( task->enFormat == TaskWriteOVF::OVF_0_9)2997 if (pTask->enFormat == TaskWriteOVF::OVF_0_9) 2829 2998 { 2830 2999 pelmOperatingSystemSection = pelmVirtualSystem->createChild("Section"); … … 2842 3011 // <VirtualHardwareSection ovf:id="hw1" ovf:transport="iso"> 2843 3012 xml::ElementNode *pelmVirtualHardwareSection; 2844 if ( task->enFormat == TaskWriteOVF::OVF_0_9)3013 if (pTask->enFormat == TaskWriteOVF::OVF_0_9) 2845 3014 { 2846 3015 // <Section xsi:type="ovf:VirtualHardwareSection_Type"> … … 2868 3037 // <vssd:VirtualSystemType>vmx-4</vssd:VirtualSystemType> 2869 3038 const char *pcszHardware = "virtualbox-2.2"; 2870 if ( task->enFormat == TaskWriteOVF::OVF_0_9)3039 if (pTask->enFormat == TaskWriteOVF::OVF_0_9) 2871 3040 // pretend to be vmware compatible then 2872 3041 pcszHardware = "vmx-6"; … … 3226 3395 // <rasd:InstanceID>1</rasd:InstanceID> 3227 3396 xml::ElementNode *pelmInstanceID; 3228 if ( task->enFormat == TaskWriteOVF::OVF_0_9)3397 if (pTask->enFormat == TaskWriteOVF::OVF_0_9) 3229 3398 pelmInstanceID = pItem->createChild("rasd:InstanceId"); 3230 3399 else … … 3302 3471 const Utf8Str &strTargetFileNameOnly = pDiskEntry->strOvf; 3303 3472 // 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); 3305 3474 strTargetFilePath.append("/"); 3306 3475 strTargetFilePath.append(strTargetFileNameOnly); … … 3312 3481 3313 3482 Log(("Finding source disk \"%ls\"\n", bstrSrcFilePath.raw())); 3314 rc = pVirtualBox->FindHardDisk(bstrSrcFilePath, pSourceDisk.asOutParam());3483 rc = mVirtualBox->FindHardDisk(bstrSrcFilePath, pSourceDisk.asOutParam()); 3315 3484 if (FAILED(rc)) throw rc; 3316 3485 … … 3320 3489 // create a new hard disk interface for the destination disk image 3321 3490 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()); 3323 3492 if (FAILED(rc)) throw rc; 3324 3493 … … 3332 3501 3333 3502 // 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()), 3336 3505 pDiskEntry->ulSizeMB); // operation's weight, as set up with the IProgress originally); 3337 3506 3338 3507 // 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); 3340 3509 } 3341 3510 catch (HRESULT rc3) … … 3344 3513 // it'll stick in the registry forever 3345 3514 pTargetDisk->Close(); 3346 throw rc3;3515 throw; 3347 3516 } 3348 3517 … … 3381 3550 // now go write the XML 3382 3551 xml::XmlFileWriter writer(doc); 3383 writer.write( pAppliance->m->strPath.c_str());3552 writer.write(m->strPath.c_str()); 3384 3553 } 3385 3554 catch(xml::Error &x) … … 3393 3562 } 3394 3563 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 */ 3581 int 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); 3399 3746 3400 3747 LogFlowFunc(("rc=%Rhrc\n", rc)); … … 3542 3889 bstrDescription, // CBSTR bstrFirstOperationDescription, 3543 3890 m->ulWeightPerOperation); // ULONG ulFirstOperationWeight, 3891 return rc; 3892 } 3893 3894 HRESULT 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, 3544 3950 return rc; 3545 3951 } -
trunk/src/VBox/Main/Makefile.kmk
r20045 r20081 285 285 VirtualBoxImplExtra.cpp \ 286 286 ApplianceImpl.cpp \ 287 VFSExplorerImpl.cpp \ 287 288 MachineImpl.cpp \ 288 289 SnapshotImpl.cpp \ -
trunk/src/VBox/Main/VFSExplorerImpl.cpp
r20044 r20081 46 46 struct DirEntry 47 47 { 48 DirEntry(Utf8Str aName, FileType_T aType)48 DirEntry(Utf8Str aName, VFSFileType_T aType) 49 49 : name(aName) 50 50 , type(aType) {} 51 51 52 52 Utf8Str name; 53 FileType_T type;53 VFSFileType_T type; 54 54 }; 55 55 … … 248 248 } 249 249 250 FileType_T VFSExplorer::RTToFileType(int aType) const251 { 252 FileType_T t;250 VFSFileType_T VFSExplorer::RTToVFSFileType(int aType) const 251 { 252 VFSFileType_T t; 253 253 switch(aType) 254 254 { 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; 264 264 } 265 265 return t; … … 286 286 int vrc = RTDirOpen(&pDir, pszPath); 287 287 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); 289 289 290 290 if(aTask->progress) … … 299 299 if (name != "." && 300 300 name != "..") 301 fileList.push_back(VFSExplorer::Data::DirEntry(name, RTTo FileType(entry.enmType)));301 fileList.push_back(VFSExplorer::Data::DirEntry(name, RTToVFSFileType(entry.enmType))); 302 302 } 303 303 } … … 360 360 int vrc = RTFileDelete(szPath); 361 361 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); 363 363 if(aTask->progress) 364 364 aTask->progress->setCurrentOperationProgress(fPercentStep * i); … … 398 398 int vrc = RTS3Create(&hS3, m->strUsername.c_str(), m->strPassword.c_str(), m->strHostname.c_str(), "virtualbox-agent/"VBOX_VERSION_STRING); 399 399 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); 401 401 402 402 RTS3SetProgressCallback(hS3, VFSExplorer::TaskVFSExplorer::uploadProgress, &aTask); … … 407 407 vrc = RTS3GetBuckets(hS3, &pBuckets); 408 408 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); 410 410 411 411 PCRTS3BUCKETENTRY pTmpBuckets = pBuckets; 412 412 while (pBuckets) 413 413 { 414 fileList.push_back(VFSExplorer::Data::DirEntry(pBuckets->pszName, FileType_Directory));414 fileList.push_back(VFSExplorer::Data::DirEntry(pBuckets->pszName, VFSFileType_Directory)); 415 415 pBuckets = pBuckets->pNext; 416 416 } … … 422 422 vrc = RTS3GetBucketKeys(hS3, m->strBucket, &pKeys); 423 423 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); 425 425 426 426 PCRTS3KEYENTRY pTmpKeys = pKeys; … … 428 428 { 429 429 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)); 431 431 pKeys = pKeys->pNext; 432 432 } … … 474 474 int vrc = RTS3Create(&hS3, m->strUsername.c_str(), m->strPassword.c_str(), m->strHostname.c_str(), "virtualbox-agent/"VBOX_VERSION_STRING); 475 475 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); 477 477 478 478 RTS3SetProgressCallback(hS3, VFSExplorer::TaskVFSExplorer::uploadProgress, &aTask); … … 486 486 vrc = RTS3DeleteKey(hS3, m->strBucket.c_str(), (*it).c_str()); 487 487 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); 489 489 if(aTask->progress) 490 490 aTask->progress->setCurrentOperationProgress(fPercentStep * i); … … 540 540 if (FAILED(rc)) throw rc; 541 541 542 /* Don't destruct on success */ 542 543 task.release(); 543 544 } … … 554 555 } 555 556 556 STDMETHODIMP VFSExplorer::EntryList(ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut( FileType_T, aTypes))557 STDMETHODIMP VFSExplorer::EntryList(ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(VFSFileType_T, aTypes)) 557 558 { 558 559 if (ComSafeArrayOutIsNull(aNames) || … … 566 567 567 568 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()); 569 570 570 571 std::list<VFSExplorer::Data::DirEntry>::const_iterator it; … … 657 658 if (FAILED(rc)) throw rc; 658 659 660 /* Don't destruct on success */ 659 661 task.release(); 660 662 } -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r20045 r20081 2890 2890 </method> 2891 2891 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 2892 3001 </interface> 2893 3002 … … 3043 3152 <interface 3044 3153 name="IAppliance" extends="$unknown" 3045 uuid=" 30bfa6b8-9eda-4b0a-b218-a86813248ccd"3154 uuid="07495095-d16c-4911-8964-5914341ced5d" 3046 3155 wsmap="managed" 3047 3156 > … … 3229 3338 </method> 3230 3339 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 3231 3352 <method name="write"> 3232 3353 <desc> … … 3253 3374 </param> 3254 3375 <param name="aProgress" type="IProgress" dir="return"> 3255 <desc></desc>3376 <desc>Progress object to track the operation completion.</desc> 3256 3377 </param> 3257 3378 </method> -
trunk/src/VBox/Main/include/ApplianceImpl.h
r20045 r20081 75 75 76 76 /* IAppliance methods */ 77 /* Import methods */ 77 78 STDMETHOD(Read)(IN_BSTR path); 78 79 STDMETHOD(Interpret)(void); 79 80 STDMETHOD(ImportMachines)(IProgress **aProgress); 81 /* Export methods */ 82 STDMETHOD(CreateVFSExplorer)(IN_BSTR aURI, IVFSExplorer **aExplorer); 80 83 STDMETHOD(Write)(IN_BSTR format, IN_BSTR path, IProgress **aProgress); 84 81 85 STDMETHOD(GetWarnings)(ComSafeArrayOut(BSTR, aWarnings)); 82 86 … … 99 103 HRESULT searchUniqueDiskImageFilePath(Utf8Str& aName) const; 100 104 HRESULT setUpProgress(ComObjPtr<Progress> &pProgress, const Bstr &bstrDescription); 105 HRESULT setUpProgressUpload(ComObjPtr<Progress> &pProgress, const Bstr &bstrDescription); 101 106 void waitForAsyncProgress(ComObjPtr<Progress> &pProgressThis, ComPtr<IProgress> &pProgressAsync); 102 107 void addWarning(const char* aWarning, ...); 103 108 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); 104 113 struct TaskImportMachines; /* Worker thread for import */ 105 114 static DECLCALLBACK(int) taskThreadImportMachines(RTTHREAD thread, void *pvUser); 106 115 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); 109 121 110 122 friend class Machine; -
trunk/src/VBox/Main/include/VFSExplorerImpl.h
r20044 r20081 68 68 STDMETHOD(Update)(IProgress **aProgress); 69 69 70 STDMETHOD(EntryList)(ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut( FileType_T, aTypes));70 STDMETHOD(EntryList)(ComSafeArrayOut(BSTR, aNames), ComSafeArrayOut(VFSFileType_T, aTypes)); 71 71 72 72 STDMETHOD(Exists)(ComSafeArrayIn(IN_BSTR, aNames), ComSafeArrayOut(BSTR, aExists)); … … 91 91 92 92 /* Private member methods */ 93 FileType_T RTToFileType(int aType) const;93 VFSFileType_T RTToVFSFileType(int aType) const; 94 94 95 95 HRESULT updateFS(TaskVFSExplorer *aTask); -
trunk/src/VBox/Main/xpcom/server.cpp
r20045 r20081 74 74 #include <VirtualBoxImpl.h> 75 75 #include <MachineImpl.h> 76 #include <VFSExplorerImpl.h> 76 77 #include <ApplianceImpl.h> 77 78 #include <SnapshotImpl.h> … … 110 111 NS_DECL_CLASSINFO(Machine) 111 112 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(Machine, IMachine) 113 114 NS_DECL_CLASSINFO(VFSExplorer) 115 NS_IMPL_THREADSAFE_ISUPPORTS1_CI(VFSExplorer, IVFSExplorer) 112 116 113 117 NS_DECL_CLASSINFO(Appliance)
Note:
See TracChangeset
for help on using the changeset viewer.

