Changeset 59319 in vbox
- Timestamp:
- Jan 12, 2016 4:26:05 PM (9 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 2 edited
-
include/ExtPackManagerImpl.h (modified) (3 diffs)
-
src-all/ExtPackManagerImpl.cpp (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/ExtPackManagerImpl.h
r58985 r59319 193 193 * @{ */ 194 194 #if !defined(VBOX_COM_INPROC) 195 static DECLCALLBACK(int) i_doInstallThreadProc(RTTHREAD hThread, void *pvJob);196 195 HRESULT i_doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace, Utf8Str const *a_pstrDisplayInfo); 197 static DECLCALLBACK(int) i_doUninstallThreadProc(RTTHREAD hThread, void *pvJob);198 196 HRESULT i_doUninstall(const Utf8Str *a_pstrName, bool a_fForcedRemoval, const Utf8Str *a_pstrDisplayInfo); 199 197 #endif … … 213 211 214 212 private: 215 bool isThereAnyRunningVM() const;216 213 // wrapped IExtPackManager properties 217 214 HRESULT getInstalledExtPacks(std::vector<ComPtr<IExtPack> > &aInstalledExtPacks); … … 232 229 BOOL *aUsable); 233 230 231 bool i_areThereAnyRunningVMs(void) const; 234 232 HRESULT i_runSetUidToRootHelper(Utf8Str const *a_pstrDisplayInfo, const char *a_pszCommand, ...); 235 233 ExtPack *i_findExtPack(const char *a_pszName); -
trunk/src/VBox/Main/src-all/ExtPackManagerImpl.cpp
r58989 r59319 172 172 173 173 #if !defined(VBOX_COM_INPROC) 174 174 175 /** 175 176 * Extension pack installation job. … … 177 178 class ExtPackInstallTask : public ThreadTask 178 179 { 179 180 180 public: 181 explicit ExtPackInstallTask() 182 { 183 m_strTaskName = "ExtPackInst"; 184 } 185 186 ~ExtPackInstallTask(){}; 181 explicit ExtPackInstallTask() : ThreadTask("ExtPackInst") { } 182 ~ExtPackInstallTask() { } 187 183 188 184 void handler() 189 185 { 190 int vrc = ExtPackManager::i_doInstallThreadProc(NULL, this); 191 } 192 193 HRESULT Init(const ComPtr<ExtPackFile>& extPackFile, 194 bool f, 195 const Utf8Str& dispInfo, 196 const ComPtr<ExtPackManager>& extPackMgr) 197 { 198 HRESULT hrc = S_OK; 199 200 ptrExtPackFile = extPackFile; 201 fReplace = f; 202 strDisplayInfo = dispInfo; 203 ptrExtPackMgr = extPackMgr; 204 205 hrc = ptrProgress.createObject(); 186 HRESULT hrc = ptrExtPackMgr->i_doInstall(ptrExtPackFile, fReplace, &strDisplayInfo); 187 ptrProgress->i_notifyComplete(hrc); 188 } 189 190 HRESULT Init(const ComPtr<ExtPackFile> &a_strExtPackFile, bool a_fReplace, 191 const Utf8Str &strDispInfo, const ComPtr<ExtPackManager> &a_ptrExtPackMgr) 192 { 193 ptrExtPackFile = a_strExtPackFile; 194 fReplace = a_fReplace; 195 strDisplayInfo = strDispInfo; 196 ptrExtPackMgr = a_ptrExtPackMgr; 197 198 HRESULT hrc = ptrProgress.createObject(); 206 199 if (SUCCEEDED(hrc)) 207 200 { 208 201 Bstr bstrDescription("Installing extension pack"); 209 hrc = ptrProgress->init( 210 #ifndef VBOX_COM_INPROC 211 ptrExtPackFile->m->pVirtualBox, 212 #endif 202 hrc = ptrProgress->init(ptrExtPackFile->m->pVirtualBox, 213 203 static_cast<IExtPackFile *>(ptrExtPackFile), 214 204 bstrDescription.raw(), … … 219 209 } 220 210 221 const ComPtr<Progress>& GetProgressObject() const {return ptrProgress;} 222 const ComPtr<ExtPackFile>& GetExtPackFileObject() const {return ptrExtPackFile;} 223 const ComPtr<ExtPackManager>& GetExtPackManagerObject() const {return ptrExtPackMgr;} 224 bool IsReplaced() const {return fReplace;} 225 const Utf8Str& GetDisplayInfo(){return strDisplayInfo;} 226 211 /** Smart pointer to the progress object for this job. */ 212 ComObjPtr<Progress> ptrProgress; 227 213 private: 228 214 /** Smart pointer to the extension pack file. */ … … 234 220 /** Smart pointer to the extension manager. */ 235 221 ComPtr<ExtPackManager> ptrExtPackMgr; 236 /** Smart pointer to the progress object for this job. */237 ComObjPtr<Progress> ptrProgress;238 222 }; 239 /** Pointer to an extension pack installation job. */240 //typedef EXTPACKINSTALLJOB *PEXTPACKINSTALLJOB;241 223 242 224 /** … … 246 228 { 247 229 public: 248 explicit ExtPackUninstallTask() 249 { 250 m_strTaskName = "ExtPackUninst"; 251 } 252 253 ~ExtPackUninstallTask(){} 230 explicit ExtPackUninstallTask() : ThreadTask("ExtPackUninst") { } 231 ~ExtPackUninstallTask() { } 254 232 255 233 void handler() 256 234 { 257 int vrc = ExtPackManager::i_doUninstallThreadProc(NULL, this);258 }259 260 HRESULT Init(const ComPtr<ExtPackManager>& extPackMgr, const Utf8Str& name, bool f, const Utf8Str& dispInfo) 261 {262 HRESULT hrc = S_OK;263 264 ptrExtPackMgr = extPackMgr;265 strName = name;266 fForcedRemoval = f;267 strDisplayInfo = dispInfo;268 269 hrc = ptrProgress.createObject();235 HRESULT hrc = ptrExtPackMgr->i_doUninstall(&strName, fForcedRemoval, &strDisplayInfo); 236 ptrProgress->i_notifyComplete(hrc); 237 } 238 239 HRESULT Init(const ComPtr<ExtPackManager> &a_ptrExtPackMgr, const Utf8Str &a_strName, 240 bool a_fForcedRemoval, const Utf8Str &a_strDisplayInfo) 241 { 242 ptrExtPackMgr = a_ptrExtPackMgr; 243 strName = a_strName; 244 fForcedRemoval = a_fForcedRemoval; 245 strDisplayInfo = a_strDisplayInfo; 246 247 HRESULT hrc = ptrProgress.createObject(); 270 248 if (SUCCEEDED(hrc)) 271 249 { 272 250 Bstr bstrDescription("Uninstalling extension pack"); 273 hrc = ptrProgress->init( 274 #ifndef VBOX_COM_INPROC 275 ptrExtPackMgr->m->pVirtualBox, 276 #endif 251 hrc = ptrProgress->init(ptrExtPackMgr->m->pVirtualBox, 277 252 static_cast<IExtPackManager *>(ptrExtPackMgr), 278 253 bstrDescription.raw(), … … 283 258 } 284 259 285 const ComPtr<Progress>& GetProgressObject() const {return ptrProgress;} 286 const ComPtr<ExtPackManager>& GetExtPackManagerObject() const {return ptrExtPackMgr;} 287 const Utf8Str& GetName() const {return strName;} 288 bool IsForcedRemoval() const {return fForcedRemoval;} 289 const Utf8Str& GetDisplayInfo(){return strDisplayInfo;} 290 260 /** Smart pointer to the progress object for this job. */ 261 ComObjPtr<Progress> ptrProgress; 291 262 private: 292 263 /** Smart pointer to the extension manager. */ … … 298 269 /** The display info argument. */ 299 270 Utf8Str strDisplayInfo; 300 /** Smart pointer to the progress object for this job. */301 ComObjPtr<Progress> ptrProgress;302 303 271 }; 304 /** Pointer to an extension pack uninstallation job. */305 272 306 273 DEFINE_EMPTY_CTOR_DTOR(ExtPackFile) … … 682 649 HRESULT ExtPackFile::install(BOOL aReplace, const com::Utf8Str &aDisplayInfo, ComPtr<IProgress> &aProgress) 683 650 { 684 HRESULT hrc = S_OK; 685 651 HRESULT hrc; 686 652 if (m->fUsable) 687 653 { 688 ExtPackInstallTask* pTask = NULL; 689 ComPtr<Progress> ptrProgress; 654 ExtPackInstallTask *pTask = NULL; 690 655 try 691 656 { 692 657 pTask = new ExtPackInstallTask(); 693 694 658 hrc = pTask->Init(this, aReplace != FALSE, aDisplayInfo, m->ptrExtPackMgr); 695 696 if (FAILED(hrc))697 {698 delete pTask;699 hrc = setError(VBOX_E_IPRT_ERROR,700 tr("Looks like creating a progress object for ExtraPackInstallTask object failed"));701 throw hrc;702 }703 704 ptrProgress = pTask->GetProgressObject();705 hrc = pTask->createThread(NULL, RTTHREADTYPE_DEFAULT);706 707 659 if (SUCCEEDED(hrc)) 708 660 { 709 hrc = ptrProgress.queryInterfaceTo(aProgress.asOutParam()); 661 ComPtr<Progress> ptrProgress = pTask->ptrProgress; 662 hrc = pTask->createThread(NULL, RTTHREADTYPE_DEFAULT); 663 pTask = NULL; /* The _completely_ _undocumented_ createThread method always consumes pTask. */ 664 if (SUCCEEDED(hrc)) 665 hrc = ptrProgress.queryInterfaceTo(aProgress.asOutParam()); 666 else 667 hrc = setError(VBOX_E_IPRT_ERROR, 668 tr("Starting thread for an extension pack installation failed with %Rrc"), hrc); 710 669 } 711 670 else 712 671 hrc = setError(VBOX_E_IPRT_ERROR, 713 tr(" Starting thread for an extension pack installation failed with %Rrc"), hrc);714 } 715 catch (std::bad_alloc &)672 tr("Looks like creating a progress object for ExtraPackInstallTask object failed")); 673 } 674 catch (std::bad_alloc &) 716 675 { 717 676 hrc = E_OUTOFMEMORY; 718 677 } 719 catch (HRESULT eHR)678 catch (HRESULT hrcXcpt) 720 679 { 721 680 LogFlowThisFunc(("Exception was caught in the function ExtPackFile::install() \n")); 722 } 723 681 hrc = hrcXcpt; 682 } 683 if (pTask) 684 delete pTask; 724 685 } 725 686 else … … 728 689 } 729 690 730 #endif 691 #endif /* !VBOX_COM_INPROC */ 731 692 732 693 … … 2112 2073 const com::Utf8Str &aDisplayInfo, ComPtr<IProgress> &aProgress) 2113 2074 { 2114 HRESULT hrc = S_OK;2115 2116 2075 Assert(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON); 2117 2076 2118 2077 #if !defined(VBOX_COM_INPROC) 2119 2078 2120 ExtPackUninstallTask* pTask = NULL;2121 ComPtr<Progress> ptrProgress;2079 HRESULT hrc; 2080 ExtPackUninstallTask *pTask = NULL; 2122 2081 try 2123 2082 { 2124 2083 pTask = new ExtPackUninstallTask(); 2125 2126 2084 hrc = pTask->Init(this, aName, aForcedRemoval != FALSE, aDisplayInfo); 2127 2128 if (FAILED(hrc)) 2129 { 2130 delete pTask; 2085 if (SUCCEEDED(hrc)) 2086 { 2087 ComPtr<Progress> ptrProgress = pTask->ptrProgress; 2088 hrc = pTask->createThread(NULL, RTTHREADTYPE_DEFAULT); 2089 pTask = NULL; /* always consumed by createThread */ 2090 if (SUCCEEDED(hrc)) 2091 hrc = ptrProgress.queryInterfaceTo(aProgress.asOutParam()); 2092 else 2093 hrc = setError(VBOX_E_IPRT_ERROR, 2094 tr("Starting thread for an extension pack uninstallation failed with %Rrc"), hrc); 2095 } 2096 else 2131 2097 hrc = setError(VBOX_E_IPRT_ERROR, 2132 2098 tr("Looks like creating a progress object for ExtraPackUninstallTask object failed")); 2133 throw hrc; 2134 } 2135 2136 ptrProgress = pTask->GetProgressObject(); 2137 hrc = pTask->createThread(NULL, RTTHREADTYPE_DEFAULT); 2138 2139 if (SUCCEEDED(hrc)) 2140 { 2141 hrc = ptrProgress.queryInterfaceTo(aProgress.asOutParam()); 2142 } 2143 else 2144 hrc = setError(VBOX_E_IPRT_ERROR, 2145 tr("Starting thread for an extension pack uninstallation failed with %Rrc"), hrc); 2146 } 2147 catch(std::bad_alloc &) 2099 } 2100 catch (std::bad_alloc &) 2148 2101 { 2149 2102 hrc = E_OUTOFMEMORY; 2150 2103 } 2151 catch(HRESULT eHR) 2152 { 2153 LogFlowThisFunc(("Exception was caught in the function ExtPackManager::uninstall() \n")); 2154 } 2155 2104 catch (HRESULT hrcXcpt) 2105 { 2106 LogFlowThisFunc(("Exception was caught in the function ExtPackManager::uninstall()\n")); 2107 hrc = hrcXcpt; 2108 } 2109 if (pTask) 2110 delete pTask; 2156 2111 return hrc; 2157 2112 #else … … 2612 2567 } 2613 2568 2614 bool ExtPackManager::isThereAnyRunningVM() const 2615 { 2616 Assert(m->pVirtualBox); /* Only called from VBoxSVC */ 2569 /** 2570 * Checks if there are any running VMs. 2571 * 2572 * This is called when uninstalling or replacing an extension pack. 2573 * 2574 * @returns true / false 2575 */ 2576 bool ExtPackManager::i_areThereAnyRunningVMs(void) const 2577 { 2578 Assert(m->pVirtualBox != NULL); /* Only called from VBoxSVC. */ 2617 2579 2618 2580 /* 2619 * Get the list of all _running_ VMs 2620 */ 2621 bool fRunning = false; 2622 com::SafeIfaceArray<IMachine> machines; 2623 com::SafeArray<MachineState_T> states; 2624 int rc = m->pVirtualBox->COMGETTER(Machines)(ComSafeArrayAsOutParam(machines)); 2625 if (SUCCEEDED(rc)) 2626 rc = m->pVirtualBox->GetMachineStates(ComSafeArrayAsInParam(machines), ComSafeArrayAsOutParam(states)); 2627 if (SUCCEEDED(rc)) 2628 { 2629 for (size_t i = 0; i < machines.size(); ++i) 2630 { 2631 if (machines[i]) 2632 { 2633 MachineState_T machineState = states[i]; 2634 switch (machineState) 2635 { 2636 case MachineState_Running: 2637 case MachineState_Teleporting: 2638 case MachineState_LiveSnapshotting: 2639 case MachineState_Paused: 2640 case MachineState_TeleportingPausedVM: 2641 fRunning = true; 2642 break; 2643 } 2644 } 2645 if (fRunning) 2646 break; 2647 } 2648 } 2649 return fRunning; 2650 } 2651 2652 /** 2653 * Thread wrapper around doInstall. 2654 * 2655 * @returns VINF_SUCCESS (ignored) 2656 * @param hThread The thread handle (ignored). 2657 * @param pvJob The job structure. 2658 */ 2659 /*static*/ DECLCALLBACK(int) ExtPackManager::i_doInstallThreadProc(RTTHREAD hThread, void *pvJob) 2660 { 2661 ExtPackInstallTask* pTask = (ExtPackInstallTask*)pvJob; 2662 HRESULT hrc = pTask->GetExtPackManagerObject()->i_doInstall(pTask->GetExtPackFileObject(), 2663 pTask->IsReplaced(), 2664 &pTask->GetDisplayInfo()); 2665 pTask->GetProgressObject()->i_notifyComplete(hrc); 2666 2667 NOREF(hThread); 2668 return VINF_SUCCESS; 2581 * Get list of machines and their states. 2582 */ 2583 com::SafeIfaceArray<IMachine> SaMachines; 2584 HRESULT hrc = m->pVirtualBox->COMGETTER(Machines)(ComSafeArrayAsOutParam(SaMachines)); 2585 if (SUCCEEDED(hrc)) 2586 { 2587 com::SafeArray<MachineState_T> SaStates; 2588 hrc = m->pVirtualBox->GetMachineStates(ComSafeArrayAsInParam(SaMachines), ComSafeArrayAsOutParam(SaStates)); 2589 if (SUCCEEDED(hrc)) 2590 { 2591 /* 2592 * Scan the two parallel arrays for machines in the running state. 2593 */ 2594 Assert(SaStates.size() == SaMachines.size()); 2595 for (size_t i = 0; i < SaMachines.size(); ++i) 2596 if (SaMachines[i] && Global::IsOnline(SaStates[i])) 2597 return true; 2598 } 2599 } 2600 return false; 2669 2601 } 2670 2602 … … 2695 2627 { 2696 2628 AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS); 2629 2630 /* 2631 * Refresh the data we have on the extension pack as it 2632 * may be made stale by direct meddling or some other user. 2633 */ 2697 2634 ExtPack *pExtPack; 2698 2699 bool fRunning = isThereAnyRunningVM(); 2700 if (fRunning) 2701 { 2702 LogRel(("Install extension pack '%s' failed because at least one VM is still running.", pStrName->c_str())); 2703 hrc = setError(E_FAIL, tr("Install extension pack '%s' failed because at least one VM is still running"), 2704 pStrName->c_str()); 2705 } 2706 else 2707 { 2708 /* 2709 * Refresh the data we have on the extension pack as it 2710 * may be made stale by direct meddling or some other user. 2711 */ 2712 hrc = i_refreshExtPack(pStrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack); 2713 } 2714 2635 hrc = i_refreshExtPack(pStrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack); 2715 2636 if (SUCCEEDED(hrc)) 2716 2637 { 2717 2638 if (pExtPack && a_fReplace) 2718 hrc = pExtPack->i_callUninstallHookAndClose(m->pVirtualBox, false /*a_ForcedRemoval*/); 2639 { 2640 if (!i_areThereAnyRunningVMs()) 2641 hrc = pExtPack->i_callUninstallHookAndClose(m->pVirtualBox, false /*a_ForcedRemoval*/); 2642 else 2643 { 2644 LogRel(("Install extension pack '%s' failed because at least one VM is still running.", pStrName->c_str())); 2645 hrc = setError(E_FAIL, tr("Install extension pack '%s' failed because at least one VM is still running"), 2646 pStrName->c_str()); 2647 } 2648 } 2719 2649 else if (pExtPack) 2720 2650 hrc = setError(E_FAIL, … … 2794 2724 2795 2725 /** 2796 * Thread wrapper around doUninstall.2797 *2798 * @returns VINF_SUCCESS (ignored)2799 * @param hThread The thread handle (ignored).2800 * @param pvJob The job structure.2801 */2802 /*static*/ DECLCALLBACK(int) ExtPackManager::i_doUninstallThreadProc(RTTHREAD hThread, void *pvJob)2803 {2804 ExtPackUninstallTask* pTask = (ExtPackUninstallTask*)pvJob;2805 HRESULT hrc = pTask->GetExtPackManagerObject()->i_doUninstall(&pTask->GetName(),2806 pTask->IsForcedRemoval(),2807 &pTask->GetDisplayInfo());2808 pTask->GetProgressObject()->i_notifyComplete(hrc);2809 2810 NOREF(hThread);2811 return VINF_SUCCESS;2812 }2813 2814 /**2815 2726 * Worker for IExtPackManager::Uninstall. 2816 2727 * … … 2834 2745 { 2835 2746 AutoWriteLock autoLock(this COMMA_LOCKVAL_SRC_POS); 2836 ExtPack *pExtPack; 2837 2838 bool fRunning = isThereAnyRunningVM(); 2839 if (fRunning) 2840 { 2841 LogRel(("Uninstall extension pack '%s' failed because at least one VM is still running.", a_pstrName->c_str())); 2842 hrc = setError(E_FAIL, tr("Uninstall extension pack '%s' failed because at least one VM is still running"), 2843 a_pstrName->c_str()); 2844 } 2845 else 2747 if (a_fForcedRemoval || !i_areThereAnyRunningVMs()) 2846 2748 { 2847 2749 /* … … 2849 2751 * stale by direct meddling or some other user. 2850 2752 */ 2753 ExtPack *pExtPack; 2851 2754 hrc = i_refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack); 2852 } 2853 2854 if (SUCCEEDED(hrc)) 2855 { 2856 if (!pExtPack) 2755 if (SUCCEEDED(hrc)) 2857 2756 { 2858 LogRel(("ExtPackManager: Extension pack '%s' is not installed, so nothing to uninstall.\n", a_pstrName->c_str())); 2859 hrc = S_OK; /* nothing to uninstall */ 2860 } 2861 else 2862 { 2863 /* 2864 * Call the uninstall hook and unload the main dll. 2865 */ 2866 hrc = pExtPack->i_callUninstallHookAndClose(m->pVirtualBox, a_fForcedRemoval); 2867 if (SUCCEEDED(hrc)) 2757 if (!pExtPack) 2758 { 2759 LogRel(("ExtPackManager: Extension pack '%s' is not installed, so nothing to uninstall.\n", a_pstrName->c_str())); 2760 hrc = S_OK; /* nothing to uninstall */ 2761 } 2762 else 2868 2763 { 2869 2764 /* 2870 * Run the set-uid-to-root binary that performs the 2871 * uninstallation. Then refresh the object. 2872 * 2873 * This refresh is theorically subject to races, but it's of 2874 * the don't-do-that variety. 2765 * Call the uninstall hook and unload the main dll. 2875 2766 */ 2876 const char *pszForcedOpt = a_fForcedRemoval ? "--forced" : NULL; 2877 hrc = i_runSetUidToRootHelper(a_pstrDisplayInfo, 2878 "uninstall", 2879 "--base-dir", m->strBaseDir.c_str(), 2880 "--name", a_pstrName->c_str(), 2881 pszForcedOpt, /* Last as it may be NULL. */ 2882 (const char *)NULL); 2767 hrc = pExtPack->i_callUninstallHookAndClose(m->pVirtualBox, a_fForcedRemoval); 2883 2768 if (SUCCEEDED(hrc)) 2884 2769 { 2885 hrc = i_refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack); 2770 /* 2771 * Run the set-uid-to-root binary that performs the 2772 * uninstallation. Then refresh the object. 2773 * 2774 * This refresh is theorically subject to races, but it's of 2775 * the don't-do-that variety. 2776 */ 2777 const char *pszForcedOpt = a_fForcedRemoval ? "--forced" : NULL; 2778 hrc = i_runSetUidToRootHelper(a_pstrDisplayInfo, 2779 "uninstall", 2780 "--base-dir", m->strBaseDir.c_str(), 2781 "--name", a_pstrName->c_str(), 2782 pszForcedOpt, /* Last as it may be NULL. */ 2783 (const char *)NULL); 2886 2784 if (SUCCEEDED(hrc)) 2887 2785 { 2888 if (!pExtPack) 2889 LogRel(("ExtPackManager: Successfully uninstalled extension pack '%s'.\n", a_pstrName->c_str())); 2890 else 2891 hrc = setError(E_FAIL, 2892 tr("Uninstall extension pack '%s' failed under mysterious circumstances"), 2893 a_pstrName->c_str()); 2786 hrc = i_refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack); 2787 if (SUCCEEDED(hrc)) 2788 { 2789 if (!pExtPack) 2790 LogRel(("ExtPackManager: Successfully uninstalled extension pack '%s'.\n", a_pstrName->c_str())); 2791 else 2792 hrc = setError(E_FAIL, 2793 tr("Uninstall extension pack '%s' failed under mysterious circumstances"), 2794 a_pstrName->c_str()); 2795 } 2894 2796 } 2895 }2896 else2897 {2898 ErrorInfoKeeper Eik;2899 i_refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, NULL);2797 else 2798 { 2799 ErrorInfoKeeper Eik; 2800 i_refreshExtPack(a_pstrName->c_str(), false /*a_fUnusableIsError*/, NULL); 2801 } 2900 2802 } 2901 2803 } 2902 2804 } 2805 } 2806 else 2807 { 2808 LogRel(("Uninstall extension pack '%s' failed because at least one VM is still running.", a_pstrName->c_str())); 2809 hrc = setError(E_FAIL, tr("Uninstall extension pack '%s' failed because at least one VM is still running"), 2810 a_pstrName->c_str()); 2903 2811 } 2904 2812
Note:
See TracChangeset
for help on using the changeset viewer.

