- Timestamp:
- Dec 14, 2010 4:21:38 PM (14 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageMisc.cpp
r34971 r35100 819 819 if (!strcmp(a->argv[0], "install")) 820 820 { 821 if (a->argc != 2) 822 return errorSyntax(USAGE_EXTPACK, "Incorrect number of parameters for \"extpack install\""); 821 const char *pszName = NULL; 822 bool fReplace = false; 823 824 static const RTGETOPTDEF s_aInstallOptions[] = 825 { 826 { "--replace", 'r', RTGETOPT_REQ_NOTHING }, 827 }; 828 829 RTGetOptInit(&GetState, a->argc, a->argv, s_aInstallOptions, RT_ELEMENTS(s_aInstallOptions), 1, 0 /*fFlags*/); 830 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 831 { 832 switch (ch) 833 { 834 case 'f': 835 fReplace = true; 836 break; 837 838 case VINF_GETOPT_NOT_OPTION: 839 if (pszName) 840 return errorSyntax(USAGE_EXTPACK, "Too many extension pack names given to \"extpack uninstall\""); 841 pszName = ValueUnion.psz; 842 break; 843 844 default: 845 return errorGetOpt(USAGE_EXTPACK, ch, &ValueUnion); 846 } 847 } 848 if (!pszName) 849 return errorSyntax(USAGE_EXTPACK, "No extension pack name was given to \"extpack install\""); 823 850 824 851 char szPath[RTPATH_MAX]; … … 832 859 CHECK_ERROR2_RET(ptrExtPackMgr, OpenExtPackFile(bstrTarball.raw(), ptrExtPackFile.asOutParam()), RTEXITCODE_FAILURE); 833 860 CHECK_ERROR2_RET(ptrExtPackFile, COMGETTER(Name)(bstrName.asOutParam()), RTEXITCODE_FAILURE); 834 CHECK_ERROR2_RET(ptrExtPackFile, Install( ), RTEXITCODE_FAILURE);861 CHECK_ERROR2_RET(ptrExtPackFile, Install(fReplace), RTEXITCODE_FAILURE); 835 862 RTPrintf("Successfully installed \"%lS\".\n", bstrName.raw()); 836 863 } … … 845 872 }; 846 873 847 RTGetOptInit(&GetState, a->argc, a->argv, s_aUninstallOptions, RT_ELEMENTS(s_aUninstallOptions), 848 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 874 RTGetOptInit(&GetState, a->argc, a->argv, s_aUninstallOptions, RT_ELEMENTS(s_aUninstallOptions), 1, 0); 849 875 while ((ch = RTGetOpt(&GetState, &ValueUnion))) 850 876 { -
trunk/src/VBox/Frontends/VirtualBox/src/settings/global/UIGlobalSettingsExtension.cpp
r35094 r35100 144 144 */ 145 145 CExtPack extPackCur = manager.Find(strPackName); 146 bool f UninstallIt = extPackCur.isOk();147 if (f UninstallIt)146 bool fReplaceIt = extPackCur.isOk(); 147 if (fReplaceIt) 148 148 { 149 149 QString strPackVersionCur = QString("%1r%2").arg(extPackCur.GetVersion()).arg(extPackCur.GetRevision()); … … 172 172 173 173 /* 174 * Perform uninstallation of any previouspackage.174 * Install the selected package. 175 175 * 176 176 * Set the package name return value before doing this as the caller should 177 177 * do a refresh even on failure. 178 178 */ 179 if (pstrExtPackName) 180 *pstrExtPackName = strPackName; 181 if (fUninstallIt) 182 { 183 /** @todo Refuse this if any VMs are running. */ 184 manager.Uninstall(strPackName, false /*aForcedRemoval*/); 185 if (!extPackFile.isOk()) 186 { 187 vboxProblem().cannotUninstallExtPack(strFilePath, manager, pParent); 188 return; 189 } 190 } 191 192 /* 193 * Install the selected package. 194 */ 195 extPackFile.Install(); 179 extPackFile.Install(fReplaceIt); 196 180 if (extPackFile.isOk()) 197 181 vboxProblem().notifyAboutExtPackInstalled(strPackName, pParent); 198 182 else 199 183 vboxProblem().cannotInstallExtPack(strFilePath, extPackFile, pParent); 184 185 if (pstrExtPackName) 186 *pstrExtPackName = strPackName; 200 187 } 201 188 -
trunk/src/VBox/Main/ExtPackManagerImpl.cpp
r35013 r35100 580 580 } 581 581 582 STDMETHODIMP ExtPackFile::Install( void)582 STDMETHODIMP ExtPackFile::Install(BOOL a_fReplace) 583 583 { 584 584 AutoCaller autoCaller(this); … … 587 587 { 588 588 if (m->fUsable) 589 hrc = m->ptrExtPackMgr->doInstall(this );589 hrc = m->ptrExtPackMgr->doInstall(this, RT_BOOL(a_fReplace)); 590 590 else 591 591 hrc = setError(E_FAIL, "%s", m->strWhyUnusable.c_str()); … … 1062 1062 if (m->fUsable) 1063 1063 { 1064 /** @todo not important, so it can wait. */ 1064 if (m->hMainMod == NIL_RTLDRMOD) 1065 probeAndLoad(); 1066 else if ( !objinfoIsEqual(&ObjInfoDesc, &m->ObjInfoDesc) 1067 || !objinfoIsEqual(&ObjInfoMainMod, &m->ObjInfoMainMod) 1068 || !objinfoIsEqual(&ObjInfoExtPack, &m->ObjInfoExtPack) ) 1069 { 1070 /** @todo not important, so it can wait. */ 1071 } 1065 1072 } 1066 1073 /* … … 1918 1925 */ 1919 1926 ExtPack *pExtPack; 1920 hrc = refreshExtPack(strName.c_str(), false /*a_fUn suableIsError*/, &pExtPack);1927 hrc = refreshExtPack(strName.c_str(), false /*a_fUnusableIsError*/, &pExtPack); 1921 1928 if (SUCCEEDED(hrc)) 1922 1929 { … … 1949 1956 if (SUCCEEDED(hrc)) 1950 1957 { 1951 hrc = refreshExtPack(strName.c_str(), false /*a_fUn suableIsError*/, &pExtPack);1958 hrc = refreshExtPack(strName.c_str(), false /*a_fUnusableIsError*/, &pExtPack); 1952 1959 if (SUCCEEDED(hrc)) 1953 1960 { … … 1963 1970 { 1964 1971 ErrorInfoKeeper Eik; 1965 refreshExtPack(strName.c_str(), false /*a_fUn suableIsError*/, NULL);1972 refreshExtPack(strName.c_str(), false /*a_fUnusableIsError*/, NULL); 1966 1973 } 1967 1974 } … … 2291 2298 * 2292 2299 * @param a_pszName The extension to update.. 2293 * @param a_fUn suableIsError If @c true, report an unusable extension pack2300 * @param a_fUnusableIsError If @c true, report an unusable extension pack 2294 2301 * as an error. 2295 2302 * @param a_ppExtPack Where to store the pointer to the extension … … 2300 2307 * @remarks Only called in VBoxSVC. 2301 2308 */ 2302 HRESULT ExtPackManager::refreshExtPack(const char *a_pszName, bool a_fUn suableIsError, ExtPack **a_ppExtPack)2309 HRESULT ExtPackManager::refreshExtPack(const char *a_pszName, bool a_fUnusableIsError, ExtPack **a_ppExtPack) 2303 2310 { 2304 2311 Assert(m->pVirtualBox != NULL); /* Only called from VBoxSVC. */ … … 2397 2404 if ( SUCCEEDED(hrc) 2398 2405 && pExtPack 2399 && a_fUn suableIsError2406 && a_fUnusableIsError 2400 2407 && !pExtPack->m->fUsable) 2401 2408 hrc = setError(E_FAIL, "%s", pExtPack->m->strWhyUnusable.c_str()); … … 2412 2419 * @param a_pExtPackFile The extension pack file, caller checks that it's 2413 2420 * usable. 2414 */ 2415 HRESULT ExtPackManager::doInstall(ExtPackFile *a_pExtPackFile) 2421 * @param a_fReplace Whether to replace any existing extpack or just 2422 * fail. 2423 */ 2424 HRESULT ExtPackManager::doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace) 2416 2425 { 2417 2426 AssertReturn(m->enmContext == VBOXEXTPACKCTX_PER_USER_DAEMON, E_UNEXPECTED); … … 2430 2439 */ 2431 2440 ExtPack *pExtPack; 2432 hrc = refreshExtPack(pStrName->c_str(), false /*a_fUnsuableIsError*/, &pExtPack); 2433 if (SUCCEEDED(hrc) && !pExtPack) 2441 hrc = refreshExtPack(pStrName->c_str(), false /*a_fUnusableIsError*/, &pExtPack); 2442 if (SUCCEEDED(hrc)) 2443 { 2444 if (pExtPack && a_fReplace) 2445 hrc = pExtPack->callUninstallHookAndClose(m->pVirtualBox, false /*a_ForcedRemoval*/); 2446 else if (pExtPack) 2447 hrc = setError(E_FAIL, 2448 tr("Extension pack '%s' is already installed." 2449 " In case of a reinstallation, please uninstall it first"), 2450 pStrName->c_str()); 2451 } 2452 if (SUCCEEDED(hrc)) 2434 2453 { 2435 2454 /* … … 2438 2457 * even on failure, to be on the safe side). 2439 2458 */ 2440 /** @todo add a hash (SHA-256) of the tarball or maybe just the manifest. */2459 /** @todo add a hash (SHA-256) of the tarball or maybe just the manifest. */ 2441 2460 hrc = runSetUidToRootHelper("install", 2442 2461 "--base-dir", m->strBaseDir.c_str(), … … 2444 2463 "--name", pStrName->c_str(), 2445 2464 "--tarball", pStrTarball->c_str(), 2465 pExtPack ? "--replace" : (const char *)NULL, 2446 2466 (const char *)NULL); 2447 2467 if (SUCCEEDED(hrc)) 2448 2468 { 2449 hrc = refreshExtPack(pStrName->c_str(), true /*a_fUn suableIsError*/, &pExtPack);2469 hrc = refreshExtPack(pStrName->c_str(), true /*a_fUnusableIsError*/, &pExtPack); 2450 2470 if (SUCCEEDED(hrc)) 2451 2471 { … … 2457 2477 { 2458 2478 ErrorInfoKeeper Eik; 2459 refreshExtPack(pStrName->c_str(), false /*a_fUn suableIsError*/, NULL);2479 refreshExtPack(pStrName->c_str(), false /*a_fUnusableIsError*/, NULL); 2460 2480 } 2461 2481 } 2462 else if (SUCCEEDED(hrc))2463 hrc = setError(E_FAIL,2464 tr("Extension pack '%s' is already installed."2465 " In case of a reinstallation, please uninstall it first"),2466 pStrName->c_str());2467 2482 2468 2483 /* -
trunk/src/VBox/Main/VBoxExtPackHelperApp.cpp
r35017 r35100 195 195 fTemporary ? "temporary " : "", rc, pszDir); 196 196 return RTEXITCODE_SUCCESS; 197 } 198 199 200 /** 201 * Common uninstall worker used by both uninstall and install --replace. 202 * 203 * @returns success or failure, message displayed on failure. 204 * @param pszExtPackDir The extension pack directory name. 205 */ 206 static RTEXITCODE CommonUninstallWorker(const char *pszExtPackDir) 207 { 208 /* Rename the extension pack directory before deleting it to prevent new 209 VM processes from picking it up. */ 210 char szExtPackUnInstDir[RTPATH_MAX]; 211 int rc = RTStrCopy(szExtPackUnInstDir, sizeof(szExtPackUnInstDir), pszExtPackDir); 212 if (RT_SUCCESS(rc)) 213 rc = RTStrCat(szExtPackUnInstDir, sizeof(szExtPackUnInstDir), "-_-uninst"); 214 if (RT_FAILURE(rc)) 215 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to construct temporary extension pack path: %Rrc", rc); 216 217 rc = RTDirRename(pszExtPackDir, szExtPackUnInstDir, RTPATHRENAME_FLAGS_NO_REPLACE); 218 if (RT_FAILURE(rc)) 219 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to rename the extension pack directory: %Rrc", rc); 220 221 /* Recursively delete the directory content. */ 222 return RemoveExtPackDir(szExtPackUnInstDir, false /*fTemporary*/); 197 223 } 198 224 … … 565 591 * @param pszName The extension pack name. 566 592 * @param pszMangledName The mangled extension pack name. 593 * @param fReplace Whether to replace any existing ext pack. 567 594 */ 568 595 static RTEXITCODE DoInstall2(const char *pszBaseDir, const char *pszCertDir, const char *pszTarball, 569 596 RTFILE hTarballFile, RTFILE hTarballFileOpt, 570 const char *pszName, const char *pszMangledName )597 const char *pszName, const char *pszMangledName, bool fReplace) 571 598 { 572 599 /* … … 612 639 613 640 /* 614 * Check that they don't exist at this point in time .615 */ 616 rc = RTPathQueryInfoEx(szFinalPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, 641 * Check that they don't exist at this point in time, unless fReplace=true. 642 */ 643 rc = RTPathQueryInfoEx(szFinalPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 617 644 if (RT_SUCCESS(rc) && RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode)) 618 return RTMsgErrorExit(RTEXITCODE_FAILURE, "The extension pack is already installed. You must uninstall the old one first."); 619 if (RT_SUCCESS(rc)) 645 { 646 if (!fReplace) 647 return RTMsgErrorExit(RTEXITCODE_FAILURE, 648 "The extension pack is already installed. You must uninstall the old one first."); 649 } 650 else if (RT_SUCCESS(rc)) 620 651 return RTMsgErrorExit(RTEXITCODE_FAILURE, 621 652 "Found non-directory file system object where the extension pack would be installed ('%s')", 622 653 szFinalPath); 623 if (rc != VERR_FILE_NOT_FOUND && rc != VERR_PATH_NOT_FOUND)654 else if (rc != VERR_FILE_NOT_FOUND && rc != VERR_PATH_NOT_FOUND) 624 655 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unexpected RTPathQueryInfoEx status code %Rrc for '%s'", rc, szFinalPath); 625 656 626 rc = RTPathQueryInfoEx(szTmpPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, 657 rc = RTPathQueryInfoEx(szTmpPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 627 658 if (rc != VERR_FILE_NOT_FOUND && rc != VERR_PATH_NOT_FOUND) 628 659 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Unexpected RTPathQueryInfoEx status code %Rrc for '%s'", rc, szFinalPath); … … 650 681 { 651 682 rc = RTDirRename(szTmpPath, szFinalPath, RTPATHRENAME_FLAGS_NO_REPLACE); 683 if ( RT_FAILURE(rc) 684 && fReplace 685 && RTDirExists(szFinalPath)) 686 { 687 /* Automatic uninstall if --replace was given. */ 688 rcExit = CommonUninstallWorker(szFinalPath); 689 if (rcExit == RTEXITCODE_SUCCESS) 690 rc = RTDirRename(szTmpPath, szFinalPath, RTPATHRENAME_FLAGS_NO_REPLACE); 691 } 652 692 if (RT_SUCCESS(rc)) 653 693 RTMsgInfo("Successfully installed '%s' (%s)", pszName, pszTarball); 654 else 694 else if (rcExit == RTEXITCODE_SUCCESS) 655 695 rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, 656 696 "Failed to rename the temporary directory to the final one: %Rrc ('%s' -> '%s')", … … 688 728 static const RTGETOPTDEF s_aOptions[] = 689 729 { 690 { "--base-dir", 'b', RTGETOPT_REQ_STRING }, 691 { "--cert-dir", 'c', RTGETOPT_REQ_STRING }, 692 { "--name", 'n', RTGETOPT_REQ_STRING }, 693 { "--tarball", 't', RTGETOPT_REQ_STRING }, 694 { "--tarball-fd", 'd', RTGETOPT_REQ_UINT64 } 730 { "--base-dir", 'b', RTGETOPT_REQ_STRING }, 731 { "--cert-dir", 'c', RTGETOPT_REQ_STRING }, 732 { "--name", 'n', RTGETOPT_REQ_STRING }, 733 { "--tarball", 't', RTGETOPT_REQ_STRING }, 734 { "--tarball-fd", 'd', RTGETOPT_REQ_UINT64 }, 735 { "--replace", 'r', RTGETOPT_REQ_NOTHING } 695 736 }; 696 737 RTGETOPTSTATE GetState; … … 704 745 const char *pszTarball = NULL; 705 746 RTFILE hTarballFileOpt = NIL_RTFILE; 747 bool fReplace = false; 706 748 RTGETOPTUNION ValueUnion; 707 749 int ch; … … 753 795 } 754 796 797 case 'r': 798 fReplace = true; 799 break; 800 755 801 case 'h': 756 802 case 'V': … … 783 829 { 784 830 rcExit = DoInstall2(pszBaseDir, pszCertDir, pszTarball, hTarballFile, hTarballFileOpt, 785 pszName, pstrMangledName->c_str() );831 pszName, pstrMangledName->c_str(), fReplace); 786 832 RTFileClose(hTarballFile); 787 833 } … … 880 926 } 881 927 882 /* Rename the extension pack directory before deleting it to prevent new 883 VM processes from picking it up. */ 884 char szExtPackUnInstDir[RTPATH_MAX]; 885 rc = RTPathJoin(szExtPackUnInstDir, sizeof(szExtPackUnInstDir), pszBaseDir, strMangledName.c_str()); 886 if (RT_SUCCESS(rc)) 887 rc = RTStrCat(szExtPackUnInstDir, sizeof(szExtPackUnInstDir), "-_-uninst"); 888 if (RT_FAILURE(rc)) 889 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to construct temporary extension pack path: %Rrc", rc); 890 891 rc = RTDirRename(szExtPackDir, szExtPackUnInstDir, RTPATHRENAME_FLAGS_NO_REPLACE); 892 if (RT_FAILURE(rc)) 893 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to rename the extension pack directory: %Rrc", rc); 894 895 /* Recursively delete the directory content. */ 896 RTEXITCODE rcExit = RemoveExtPackDir(szExtPackUnInstDir, false /*fTemporary*/); 928 RTEXITCODE rcExit = CommonUninstallWorker(szExtPackDir); 897 929 if (rcExit == RTEXITCODE_SUCCESS) 898 930 RTMsgInfo("Successfully removed extension pack '%s'\n", pszName); -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r35088 r35100 14476 14476 <interface 14477 14477 name="IExtPackFile" extends="IExtPackBase" 14478 uuid=" e57e5ab7-e0e8-4a55-9241-afa7ad219911"14478 uuid="64b65bda-eedf-442c-9fd2-d179a021031a" 14479 14479 wsmap="suppress" 14480 14480 > … … 14495 14495 Install the extension pack. 14496 14496 </desc> 14497 <param name="replace" type="boolean" dir="in"> 14498 <desc> 14499 Set this to automatically uninstall any existing extension pack with 14500 the same name as the one being installed. 14501 </desc> 14502 </param> 14497 14503 </method> 14498 14504 </interface> -
trunk/src/VBox/Main/include/ExtPackManagerImpl.h
r34907 r35100 70 70 * @{ */ 71 71 STDMETHOD(COMGETTER(FilePath))(BSTR *a_pbstrPath); 72 STDMETHOD(Install)( void);72 STDMETHOD(Install)(BOOL a_fReplace); 73 73 /** @} */ 74 74 … … 219 219 /** @name Internal interfaces used by other Main classes. 220 220 * @{ */ 221 HRESULT doInstall(ExtPackFile *a_pExtPackFile );221 HRESULT doInstall(ExtPackFile *a_pExtPackFile, bool a_fReplace); 222 222 void callAllVirtualBoxReadyHooks(void); 223 223 void callAllConsoleReadyHooks(IConsole *a_pConsole);
Note:
See TracChangeset
for help on using the changeset viewer.