diff --git a/xpinstall/wizard/windows/nsinstall/nsinstall.cpp b/xpinstall/wizard/windows/nsinstall/nsinstall.cpp index 03df8e86da2c..cb058326d2e6 100644 --- a/xpinstall/wizard/windows/nsinstall/nsinstall.cpp +++ b/xpinstall/wizard/windows/nsinstall/nsinstall.cpp @@ -31,7 +31,6 @@ #define BAR_SPACING 0 #define BAR_WIDTH 6 #define MAX_BUF 4096 -#define WIZ_TEMP_DIR "ns_temp" /* Mode of Setup to run in */ #define NORMAL 0 @@ -50,6 +49,8 @@ char szCmdLineToSetup[MAX_BUF]; BOOL gbUncompressOnly; DWORD dwMode; HINSTANCE hInst; +char gszWizTempDir[20] = "ns_temp"; +BOOL gbAllowMultipleInstalls = FALSE; ///////////////////////////////////////////////////////////////////////////// // Global Declarations @@ -76,7 +77,7 @@ GetFullTempPathName(LPCTSTR lpszFileName, DWORD dwBufferLength, LPTSTR lpszBuffe dwLen = GetTempPath(dwBufferLength, lpszBuffer); if (lpszBuffer[dwLen - 1] != '\\') strcat(lpszBuffer, "\\"); - strcat(lpszBuffer, WIZ_TEMP_DIR); + strcat(lpszBuffer, gszWizTempDir); dwLen = lstrlen(lpszBuffer); if (lpszBuffer[dwLen - 1] != '\\') @@ -462,6 +463,10 @@ void ParseCommandLine(LPSTR lpszCmdLine) { gbUncompressOnly = TRUE; } + else if((lstrcmpi(szArgVBuf, "-mmi") == 0) || (lstrcmpi(szArgVBuf, "/mmi") == 0)) + { + gbAllowMultipleInstalls = TRUE; + } ++i; } @@ -860,11 +865,10 @@ RunInstaller() char szArcLstFile[MAX_BUF]; BOOL bRet; char szText[256]; - char szTempPath[4096]; + char szTempPath[MAX_BUF]; char szTmp[MAX_PATH]; char szFilename[MAX_BUF]; char szBuf[MAX_BUF]; - DWORD dwLen; if(gbUncompressOnly == TRUE) return(TRUE); @@ -877,12 +881,8 @@ RunInstaller() memset(&sti,0,sizeof(sti)); sti.cb = sizeof(STARTUPINFO); - dwLen = GetTempPath(4096, szTempPath); - if (szTempPath[dwLen - 1] != '\\') - strcat(szTempPath, "\\"); - strcat(szTempPath, WIZ_TEMP_DIR); - // Setup program is in the directory specified for temporary files + GetFullTempPathName("", MAX_BUF, szTempPath); GetFullTempPathName("Archive.lst", sizeof(szArcLstFile), szArcLstFile); GetFullTempPathName("SETUP.EXE", sizeof(szSetupFile), szSetupFile); GetFullTempPathName("uninstall.exe", sizeof(szUninstallFile), szUninstallFile); @@ -946,24 +946,44 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS hInst = hInstance; LoadString(hInst, IDS_TITLE, szTitle, MAX_BUF); - /* Allow only one instance of nsinstall to run. - * Detect a previous instance of nsinstall, bring it to the - * foreground, and quit current instance */ - if(FindWindow("NSExtracting", "Extracting...") != NULL) - return(1); + // Parse the command line + ParseCommandLine(lpCmdLine); + + /* Allow multiple installer instances with the + provision that each instance is guaranteed + to have its own unique setup directory + */ + if(FindWindow("NSExtracting", "Extracting...") != NULL || + (hwndFW = FindWindow(CLASS_NAME_SETUP_DLG, NULL)) != NULL) + { + if (gbAllowMultipleInstalls) + { + char szTempPath[MAX_BUF]; + GetFullTempPathName("", MAX_BUF, szTempPath); + DWORD dwLen = lstrlen(gszWizTempDir); - /* Allow only one instance of Setup to run. - * Detect a previous instance of Setup, and quit */ - if((hwndFW = FindWindow(CLASS_NAME_SETUP_DLG, NULL)) != NULL) + for(int i = 1; i <= 100 && (FileExists(szTempPath) != FALSE); i++) + { + itoa(i, (gszWizTempDir + dwLen), 10); + GetFullTempPathName("", MAX_BUF, szTempPath); + } + + if (FileExists(szTempPath) != FALSE) + { + MessageBox(NULL, "Cannot create temp directory", NULL, MB_OK | MB_ICONEXCLAMATION); + exit(1); + } + } + else + { + if (hwndFW!=NULL) { ShowWindow(hwndFW, SW_RESTORE); SetForegroundWindow(hwndFW); + } return(1); } - - - // Parse the command line - ParseCommandLine(lpCmdLine); + } // Figure out the total size of the resources EnumResourceNames(NULL, "FILE", (ENUMRESNAMEPROC)SizeOfResourcesProc, 0); diff --git a/xpinstall/wizard/windows/setup/extern.h b/xpinstall/wizard/windows/setup/extern.h index 6cd49447bb0c..bbd9c028696b 100644 --- a/xpinstall/wizard/windows/setup/extern.h +++ b/xpinstall/wizard/windows/setup/extern.h @@ -74,6 +74,7 @@ extern BOOL gbIgnoreRunAppX; extern BOOL gbIgnoreProgramFolderX; extern BOOL gbRestrictedAccess; extern BOOL gbDownloadTriggered; +extern BOOL gbAllowMultipleInstalls; extern setupGen sgProduct; extern diS diSetup; diff --git a/xpinstall/wizard/windows/setup/extra.c b/xpinstall/wizard/windows/setup/extra.c index 8a61f8c00043..fbf6937362af 100644 --- a/xpinstall/wizard/windows/setup/extra.c +++ b/xpinstall/wizard/windows/setup/extra.c @@ -648,6 +648,33 @@ HRESULT Initialize(HINSTANCE hInstance) AppendBackSlash(szTempDir, MAX_BUF); lstrcat(szTempDir, WIZ_TEMP_DIR); + /* if multiple installer instances are allowed; + each instance requires a unique temp directory + */ + if(gbAllowMultipleInstalls) + { + DWORD dwLen = lstrlen(szTempDir); + + if (strncmp(szSetupDir, szTempDir, dwLen) == 0) + { + lstrcpy(szTempDir, szSetupDir); + } + else + { + int i; + for(i = 1; i <= 100 && (FileExists(szTempDir) != FALSE); i++) + { + itoa(i, (szTempDir + dwLen), 10); + } + + if (FileExists(szTempDir) != FALSE) + { + MessageBox(hWndMain, "Cannot create temp directory", NULL, MB_OK | MB_ICONEXCLAMATION); + exit(1); + } + } + } + if(!FileExists(szTempDir)) { AppendBackSlash(szTempDir, MAX_BUF); @@ -4972,7 +4999,7 @@ void PrintUsage(void) * the Start Menu shortcut folder at the end of installation. */ - if(*sgProduct.szParentProcessFilename != '\0') + if(sgProduct.szParentProcessFilename && *sgProduct.szParentProcessFilename != '\0') lstrcpy(szProcessFilename, sgProduct.szParentProcessFilename); else { @@ -4981,10 +5008,12 @@ void PrintUsage(void) } GetPrivateProfileString("Strings", "UsageMsg Usage", "", szBuf, sizeof(szBuf), szFileIniConfig); + if (lstrlen(szBuf) > 0) + { wsprintf(szUsageMsg, szBuf, szProcessFilename, "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n"); - PrintError(szUsageMsg, ERROR_CODE_HIDE); } +} DWORD ParseCommandLine(LPSTR lpszCmdLine) { @@ -5063,6 +5092,10 @@ DWORD ParseCommandLine(LPSTR lpszCmdLine) GetArgV(lpszCmdLine, i, szArgVBuf, sizeof(szArgVBuf)); lstrcpy(sgProduct.szRegPath, szArgVBuf); } + else if(!lstrcmpi(szArgVBuf, "-mmi") || !lstrcmpi(szArgVBuf, "/mmi")) + { + gbAllowMultipleInstalls = TRUE; + } #ifdef XXX_DEBUG itoa(i, szBuf, 10); diff --git a/xpinstall/wizard/windows/setup/setup.c b/xpinstall/wizard/windows/setup/setup.c index a663bfeea1e2..a9d2b5851bb5 100644 --- a/xpinstall/wizard/windows/setup/setup.c +++ b/xpinstall/wizard/windows/setup/setup.c @@ -77,6 +77,7 @@ BOOL gbIgnoreRunAppX; BOOL gbIgnoreProgramFolderX; BOOL gbRestrictedAccess; BOOL gbDownloadTriggered; +BOOL gbAllowMultipleInstalls = FALSE; setupGen sgProduct; diS diSetup; @@ -127,11 +128,14 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmd if(!hPrevInstance) { + ParseCommandLine(lpszCmdLine); + + if((hwndFW = FindWindow(CLASS_NAME_SETUP_DLG, NULL)) != NULL && !gbAllowMultipleInstalls) + { /* Allow only one instance of setup to run. * Detect a previous instance of setup, bring it to the * foreground, and quit current instance */ - if((hwndFW = FindWindow(CLASS_NAME_SETUP_DLG, NULL)) != NULL) - { + ShowWindow(hwndFW, SW_RESTORE); SetForegroundWindow(hwndFW); iRv = WIZ_SETUP_ALREADY_RUNNING;