Changeset 18248 in vbox for trunk/src/VBox/Main
- Timestamp:
- Mar 25, 2009 12:46:46 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 44988
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ApplianceImpl.cpp
r18220 r18248 214 214 { 215 215 list<VirtualSystemDescriptionEntry> llDescriptions; 216 };217 218 ////////////////////////////////////////////////////////////////////////////////219 //220 // Threads221 //222 ////////////////////////////////////////////////////////////////////////////////223 224 struct Appliance::TaskImportMachines225 {226 TaskImportMachines(Appliance *aThat, Progress *aProgress)227 : pAppliance(aThat)228 , progress(aProgress)229 , rc(S_OK)230 {}231 ~TaskImportMachines() {}232 233 HRESULT startThread();234 235 Appliance *pAppliance;236 ComObjPtr<Progress> progress;237 HRESULT rc;238 };239 240 struct Appliance::TaskWriteOVF241 {242 TaskWriteOVF(Appliance *aThat, Progress *aProgress)243 : pAppliance(aThat)244 , progress(aProgress)245 , rc(S_OK)246 {}247 ~TaskWriteOVF() {}248 249 HRESULT startThread();250 251 Appliance *pAppliance;252 ComObjPtr<Progress> progress;253 HRESULT rc;254 216 }; 255 217 … … 395 357 396 358 return rc; 397 }398 399 ////////////////////////////////////////////////////////////////////////////////400 //401 // Appliance::task methods402 //403 ////////////////////////////////////////////////////////////////////////////////404 405 HRESULT Appliance::TaskImportMachines::startThread()406 {407 int vrc = RTThreadCreate(NULL, Appliance::taskThreadImportMachines, this,408 0, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0,409 "Appliance::Task");410 ComAssertMsgRCRet(vrc,411 ("Could not create taskThreadImportMachines (%Rrc)\n", vrc), E_FAIL);412 413 return S_OK;414 }415 416 HRESULT Appliance::TaskWriteOVF::startThread()417 {418 int vrc = RTThreadCreate(NULL, Appliance::taskThreadWriteOVF, this,419 0, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0,420 "Appliance::Task");421 ComAssertMsgRCRet(vrc,422 ("Could not create taskThreadExportOVF (%Rrc)\n", vrc), E_FAIL);423 424 return S_OK;425 359 } 426 360 … … 1638 1572 } 1639 1573 1574 struct Appliance::TaskImportMachines 1575 { 1576 TaskImportMachines(Appliance *aThat, Progress *aProgress) 1577 : pAppliance(aThat) 1578 , progress(aProgress) 1579 , rc(S_OK) 1580 {} 1581 ~TaskImportMachines() {} 1582 1583 HRESULT startThread(); 1584 1585 Appliance *pAppliance; 1586 ComObjPtr<Progress> progress; 1587 HRESULT rc; 1588 }; 1589 1590 HRESULT Appliance::TaskImportMachines::startThread() 1591 { 1592 int vrc = RTThreadCreate(NULL, Appliance::taskThreadImportMachines, this, 1593 0, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0, 1594 "Appliance::Task"); 1595 ComAssertMsgRCRet(vrc, 1596 ("Could not create taskThreadImportMachines (%Rrc)\n", vrc), E_FAIL); 1597 1598 return S_OK; 1599 } 1600 1640 1601 /** 1641 1602 * Public method implementation. … … 1688 1649 1689 1650 return rc; 1690 }1691 1692 STDMETHODIMP Appliance::Write(IN_BSTR path, IProgress **aProgress)1693 {1694 HRESULT rc = S_OK;1695 1696 CheckComArgOutPointerValid(aProgress);1697 1698 AutoCaller autoCaller(this);1699 if (FAILED(rc = autoCaller.rc())) return rc;1700 1701 AutoWriteLock(this);1702 1703 // see if we can handle this file; for now we insist it has an ".ovf" extension1704 m->strPath = path;1705 if (!m->strPath.endsWith(".ovf", Utf8Str::CaseInsensitive))1706 return setError(VBOX_E_FILE_ERROR,1707 tr("Appliance file must have .ovf extension"));1708 1709 ComObjPtr<Progress> progress;1710 try1711 {1712 uint32_t opCount = calcMaxProgress();1713 Bstr progressDesc = BstrFmt(tr("Write appliance '%s'"),1714 m->strPath.raw());1715 /* Create the progress object */1716 progress.createObject();1717 rc = progress->init(mVirtualBox, static_cast<IAppliance*>(this),1718 progressDesc,1719 FALSE /* aCancelable */,1720 opCount,1721 progressDesc);1722 CheckComRCThrowRC(rc);1723 1724 /* Initialize our worker task */1725 std::auto_ptr<TaskWriteOVF> task(new TaskWriteOVF(this, progress));1726 //AssertComRCThrowRC (task->autoCaller.rc());1727 1728 rc = task->startThread();1729 CheckComRCThrowRC(rc);1730 1731 task.release();1732 }1733 catch (HRESULT aRC)1734 {1735 rc = aRC;1736 }1737 1738 if (SUCCEEDED(rc))1739 /* Return progress to the caller */1740 progress.queryInterfaceTo(aProgress);1741 1742 return rc;1743 }1744 1745 /**1746 * Public method implementation.1747 * @return1748 */1749 STDMETHODIMP Appliance::GetWarnings(ComSafeArrayOut(BSTR, aWarnings))1750 {1751 if (ComSafeArrayOutIsNull(aWarnings))1752 return E_POINTER;1753 1754 AutoCaller autoCaller(this);1755 CheckComRCReturnRC(autoCaller.rc());1756 1757 AutoReadLock alock(this);1758 1759 com::SafeArray<BSTR> sfaWarnings(m->llWarnings.size());1760 1761 list<Utf8Str>::const_iterator it;1762 size_t i = 0;1763 for (it = m->llWarnings.begin();1764 it != m->llWarnings.end();1765 ++it, ++i)1766 {1767 Bstr bstr = *it;1768 bstr.cloneTo(&sfaWarnings[i]);1769 }1770 1771 sfaWarnings.detachTo(ComSafeArrayOutArg(aWarnings));1772 1773 return S_OK;1774 }1775 1776 HRESULT Appliance::searchUniqueVMName(Utf8Str& aName) const1777 {1778 IMachine *machine = NULL;1779 char *tmpName = RTStrDup(aName.c_str());1780 int i = 1;1781 /* @todo: Maybe too cost-intensive; try to find a lighter way */1782 while (mVirtualBox->FindMachine(Bstr(tmpName), &machine) != VBOX_E_OBJECT_NOT_FOUND)1783 {1784 RTStrFree(tmpName);1785 RTStrAPrintf(&tmpName, "%s_%d", aName.c_str(), i);1786 ++i;1787 }1788 aName = tmpName;1789 RTStrFree(tmpName);1790 1791 return S_OK;1792 }1793 1794 HRESULT Appliance::searchUniqueDiskImageFilePath(Utf8Str& aName) const1795 {1796 IHardDisk *harddisk = NULL;1797 char *tmpName = RTStrDup(aName.c_str());1798 int i = 1;1799 /* Check if the file exists or if a file with this path is registered1800 * already */1801 /* @todo: Maybe too cost-intensive; try to find a lighter way */1802 while (RTPathExists(tmpName) ||1803 mVirtualBox->FindHardDisk(Bstr(tmpName), &harddisk) != VBOX_E_OBJECT_NOT_FOUND)1804 {1805 RTStrFree(tmpName);1806 char *tmpDir = RTStrDup(aName.c_str());1807 RTPathStripFilename(tmpDir);;1808 char *tmpFile = RTStrDup(RTPathFilename(aName.c_str()));1809 RTPathStripExt(tmpFile);1810 const char *tmpExt = RTPathExt(aName.c_str());1811 RTStrAPrintf(&tmpName, "%s%c%s_%d%s", tmpDir, RTPATH_DELIMITER, tmpFile, i, tmpExt);1812 RTStrFree(tmpFile);1813 RTStrFree(tmpDir);1814 ++i;1815 }1816 aName = tmpName;1817 RTStrFree(tmpName);1818 1819 return S_OK;1820 }1821 1822 /**1823 * Calculates the maximum progress value for importMachines() and write().1824 * @return1825 */1826 uint32_t Appliance::calcMaxProgress()1827 {1828 /* Figure out how many sub operation the import will need */1829 /* One for the appliance */1830 uint32_t opCount = 1;1831 list< ComObjPtr<VirtualSystemDescription> >::const_iterator it;1832 for (it = m->virtualSystemDescriptions.begin();1833 it != m->virtualSystemDescriptions.end();1834 ++it)1835 {1836 /* One for every Virtual System */1837 ++opCount;1838 ComObjPtr<VirtualSystemDescription> vsdescThis = (*it);1839 /* One for every hard disk of the Virtual System */1840 std::list<VirtualSystemDescriptionEntry*> avsdeHDs = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskImage);1841 opCount += (uint32_t)avsdeHDs.size();1842 }1843 1844 return opCount;1845 }1846 1847 void Appliance::addWarning(const char* aWarning, ...)1848 {1849 va_list args;1850 va_start(args, aWarning);1851 Utf8StrFmtVA str(aWarning, args);1852 va_end(args);1853 m->llWarnings.push_back(str);1854 1651 } 1855 1652 … … 2554 2351 } 2555 2352 2353 struct Appliance::TaskWriteOVF 2354 { 2355 TaskWriteOVF(Appliance *aThat, Progress *aProgress) 2356 : pAppliance(aThat) 2357 , progress(aProgress) 2358 , rc(S_OK) 2359 {} 2360 ~TaskWriteOVF() {} 2361 2362 HRESULT startThread(); 2363 2364 Appliance *pAppliance; 2365 ComObjPtr<Progress> progress; 2366 HRESULT rc; 2367 }; 2368 2369 HRESULT Appliance::TaskWriteOVF::startThread() 2370 { 2371 int vrc = RTThreadCreate(NULL, Appliance::taskThreadWriteOVF, this, 2372 0, RTTHREADTYPE_MAIN_HEAVY_WORKER, 0, 2373 "Appliance::Task"); 2374 ComAssertMsgRCRet(vrc, 2375 ("Could not create taskThreadExportOVF (%Rrc)\n", vrc), E_FAIL); 2376 2377 return S_OK; 2378 } 2379 2380 STDMETHODIMP Appliance::Write(IN_BSTR path, IProgress **aProgress) 2381 { 2382 HRESULT rc = S_OK; 2383 2384 CheckComArgOutPointerValid(aProgress); 2385 2386 AutoCaller autoCaller(this); 2387 if (FAILED(rc = autoCaller.rc())) return rc; 2388 2389 AutoWriteLock(this); 2390 2391 // see if we can handle this file; for now we insist it has an ".ovf" extension 2392 m->strPath = path; 2393 if (!m->strPath.endsWith(".ovf", Utf8Str::CaseInsensitive)) 2394 return setError(VBOX_E_FILE_ERROR, 2395 tr("Appliance file must have .ovf extension")); 2396 2397 ComObjPtr<Progress> progress; 2398 try 2399 { 2400 uint32_t opCount = calcMaxProgress(); 2401 Bstr progressDesc = BstrFmt(tr("Write appliance '%s'"), 2402 m->strPath.raw()); 2403 /* Create the progress object */ 2404 progress.createObject(); 2405 rc = progress->init(mVirtualBox, static_cast<IAppliance*>(this), 2406 progressDesc, 2407 FALSE /* aCancelable */, 2408 opCount, 2409 progressDesc); 2410 CheckComRCThrowRC(rc); 2411 2412 /* Initialize our worker task */ 2413 std::auto_ptr<TaskWriteOVF> task(new TaskWriteOVF(this, progress)); 2414 //AssertComRCThrowRC (task->autoCaller.rc()); 2415 2416 rc = task->startThread(); 2417 CheckComRCThrowRC(rc); 2418 2419 task.release(); 2420 } 2421 catch (HRESULT aRC) 2422 { 2423 rc = aRC; 2424 } 2425 2426 if (SUCCEEDED(rc)) 2427 /* Return progress to the caller */ 2428 progress.queryInterfaceTo(aProgress); 2429 2430 return rc; 2431 } 2432 2556 2433 /** 2557 2434 * Worker thread implementation for Write() (ovf writer). … … 3251 3128 } 3252 3129 3130 /** 3131 * Public method implementation. 3132 * @return 3133 */ 3134 STDMETHODIMP Appliance::GetWarnings(ComSafeArrayOut(BSTR, aWarnings)) 3135 { 3136 if (ComSafeArrayOutIsNull(aWarnings)) 3137 return E_POINTER; 3138 3139 AutoCaller autoCaller(this); 3140 CheckComRCReturnRC(autoCaller.rc()); 3141 3142 AutoReadLock alock(this); 3143 3144 com::SafeArray<BSTR> sfaWarnings(m->llWarnings.size()); 3145 3146 list<Utf8Str>::const_iterator it; 3147 size_t i = 0; 3148 for (it = m->llWarnings.begin(); 3149 it != m->llWarnings.end(); 3150 ++it, ++i) 3151 { 3152 Bstr bstr = *it; 3153 bstr.cloneTo(&sfaWarnings[i]); 3154 } 3155 3156 sfaWarnings.detachTo(ComSafeArrayOutArg(aWarnings)); 3157 3158 return S_OK; 3159 } 3160 3161 HRESULT Appliance::searchUniqueVMName(Utf8Str& aName) const 3162 { 3163 IMachine *machine = NULL; 3164 char *tmpName = RTStrDup(aName.c_str()); 3165 int i = 1; 3166 /* @todo: Maybe too cost-intensive; try to find a lighter way */ 3167 while (mVirtualBox->FindMachine(Bstr(tmpName), &machine) != VBOX_E_OBJECT_NOT_FOUND) 3168 { 3169 RTStrFree(tmpName); 3170 RTStrAPrintf(&tmpName, "%s_%d", aName.c_str(), i); 3171 ++i; 3172 } 3173 aName = tmpName; 3174 RTStrFree(tmpName); 3175 3176 return S_OK; 3177 } 3178 3179 HRESULT Appliance::searchUniqueDiskImageFilePath(Utf8Str& aName) const 3180 { 3181 IHardDisk *harddisk = NULL; 3182 char *tmpName = RTStrDup(aName.c_str()); 3183 int i = 1; 3184 /* Check if the file exists or if a file with this path is registered 3185 * already */ 3186 /* @todo: Maybe too cost-intensive; try to find a lighter way */ 3187 while (RTPathExists(tmpName) || 3188 mVirtualBox->FindHardDisk(Bstr(tmpName), &harddisk) != VBOX_E_OBJECT_NOT_FOUND) 3189 { 3190 RTStrFree(tmpName); 3191 char *tmpDir = RTStrDup(aName.c_str()); 3192 RTPathStripFilename(tmpDir);; 3193 char *tmpFile = RTStrDup(RTPathFilename(aName.c_str())); 3194 RTPathStripExt(tmpFile); 3195 const char *tmpExt = RTPathExt(aName.c_str()); 3196 RTStrAPrintf(&tmpName, "%s%c%s_%d%s", tmpDir, RTPATH_DELIMITER, tmpFile, i, tmpExt); 3197 RTStrFree(tmpFile); 3198 RTStrFree(tmpDir); 3199 ++i; 3200 } 3201 aName = tmpName; 3202 RTStrFree(tmpName); 3203 3204 return S_OK; 3205 } 3206 3207 /** 3208 * Calculates the maximum progress value for importMachines() and write(). 3209 * @return 3210 */ 3211 uint32_t Appliance::calcMaxProgress() 3212 { 3213 /* Figure out how many sub operation the import will need */ 3214 /* One for the appliance */ 3215 uint32_t opCount = 1; 3216 list< ComObjPtr<VirtualSystemDescription> >::const_iterator it; 3217 for (it = m->virtualSystemDescriptions.begin(); 3218 it != m->virtualSystemDescriptions.end(); 3219 ++it) 3220 { 3221 /* One for every Virtual System */ 3222 ++opCount; 3223 ComObjPtr<VirtualSystemDescription> vsdescThis = (*it); 3224 /* One for every hard disk of the Virtual System */ 3225 std::list<VirtualSystemDescriptionEntry*> avsdeHDs = vsdescThis->findByType(VirtualSystemDescriptionType_HardDiskImage); 3226 opCount += (uint32_t)avsdeHDs.size(); 3227 } 3228 3229 return opCount; 3230 } 3231 3232 void Appliance::addWarning(const char* aWarning, ...) 3233 { 3234 va_list args; 3235 va_start(args, aWarning); 3236 Utf8StrFmtVA str(aWarning, args); 3237 va_end(args); 3238 m->llWarnings.push_back(str); 3239 } 3240 3253 3241 //////////////////////////////////////////////////////////////////////////////// 3254 3242 //
Note:
See TracChangeset
for help on using the changeset viewer.