BOOL WinLaunchChild(const PRUnichar *exePath, int argc, char **argv, int needElevation) { PRUnichar** argvConverted = new PRUnichar*[argc]; if (!argvConverted) return FALSE; for (int i = 0; i < argc; ++i) { argvConverted[i] = AllocConvertUTF8toUTF16(argv[i]); if (!argvConverted[i]) { return FALSE; } } BOOL ok = WinLaunchChild(exePath, argc, argvConverted, needElevation); FreeAllocStrings(argc, argvConverted); return ok; }
static void LaunchApp(const NS_tchar *workingDir, int argc, NS_tchar **argv) { putenv("NO_EM_RESTART="); putenv("MOZ_LAUNCHED_CHILD=1"); // Run from the specified working directory (see bug 312360). NS_tchdir(workingDir); #if defined(USE_EXECV) execv(argv[0], argv); #elif defined(XP_MACOSX) LaunchChild(argc, argv); #elif defined(XP_WIN) WinLaunchChild(argv[0], argc, argv); #else # warning "Need implementaton of LaunchCallbackApp" #endif }
BOOL WinLaunchChild(const wchar_t *exePath, int argc, char **argv, HANDLE userToken, HANDLE *hProcess) { wchar_t** argvConverted = new wchar_t*[argc]; if (!argvConverted) return FALSE; for (int i = 0; i < argc; ++i) { argvConverted[i] = reinterpret_cast<wchar_t*>(AllocConvertUTF8toUTF16(argv[i])); if (!argvConverted[i]) { FreeAllocStrings(i, argvConverted); return FALSE; } } BOOL ok = WinLaunchChild(exePath, argc, argvConverted, userToken, hProcess); FreeAllocStrings(argc, argvConverted); return ok; }
static void ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsILocalFile *statusFile, nsIFile *appDir, int appArgc, char **appArgv) { nsresult rv; // Steps: // - mark update as 'applying' // - copy updater into update dir // - run updater w/ appDir as the current working dir nsCOMPtr<nsIFile> updater; if (!CopyUpdaterIntoUpdateDir(greDir, appDir, updateDir, updater)) { LOG(("failed copying updater\n")); return; } // We need to use the value returned from XRE_GetBinaryPath when attempting // to restart the running application. nsCOMPtr<nsILocalFile> appFile; #if defined(XP_MACOSX) // On OS X we need to pass the location of the xulrunner-stub executable // rather than xulrunner-bin. See bug 349737. GetXULRunnerStubPath(appArgv[0], getter_AddRefs(appFile)); #else XRE_GetBinaryPath(appArgv[0], getter_AddRefs(appFile)); #endif if (!appFile) return; #ifdef XP_WIN nsAutoString appFilePathW; rv = appFile->GetPath(appFilePathW); if (NS_FAILED(rv)) return; NS_ConvertUTF16toUTF8 appFilePath(appFilePathW); nsAutoString updaterPathW; rv = updater->GetPath(updaterPathW); if (NS_FAILED(rv)) return; NS_ConvertUTF16toUTF8 updaterPath(updaterPathW); #else nsCAutoString appFilePath; rv = appFile->GetNativePath(appFilePath); if (NS_FAILED(rv)) return; nsCAutoString updaterPath; rv = updater->GetNativePath(updaterPath); if (NS_FAILED(rv)) return; #endif // Get the directory to which the update will be applied. On Mac OSX we need // to apply the update to the Foo.app directory which is the parent of the // parent of the appDir. On other platforms we will just apply to the appDir. #if defined(XP_MACOSX) nsCAutoString applyToDir; { nsCOMPtr<nsIFile> parentDir1, parentDir2; rv = appDir->GetParent(getter_AddRefs(parentDir1)); if (NS_FAILED(rv)) return; rv = parentDir1->GetParent(getter_AddRefs(parentDir2)); if (NS_FAILED(rv)) return; rv = parentDir2->GetNativePath(applyToDir); } #elif defined(XP_WIN) nsAutoString applyToDir; rv = appDir->GetPath(applyToDir); #else nsCAutoString applyToDir; rv = appDir->GetNativePath(applyToDir); #endif if (NS_FAILED(rv)) return; #if defined(XP_WIN) nsAutoString updateDirPathW; rv = updateDir->GetPath(updateDirPathW); NS_ConvertUTF16toUTF8 updateDirPath(updateDirPathW); #else nsCAutoString updateDirPath; rv = updateDir->GetNativePath(updateDirPath); #endif if (NS_FAILED(rv)) return; // Get the current working directory. char workingDirPath[MAXPATHLEN]; rv = GetCurrentWorkingDir(workingDirPath, sizeof(workingDirPath)); if (NS_FAILED(rv)) return; if (!SetStatus(statusFile, "applying")) { LOG(("failed setting status to 'applying'\n")); return; } // Construct the PID argument for this process. If we are using execv, then // we pass "0" which is then ignored by the updater. #if defined(USE_EXECV) NS_NAMED_LITERAL_CSTRING(pid, "0"); #else nsCAutoString pid; pid.AppendInt((PRInt32) getpid()); #endif int argc = appArgc + 4; char **argv = new char*[argc + 1]; if (!argv) return; argv[0] = (char*) updaterPath.get(); argv[1] = (char*) updateDirPath.get(); argv[2] = (char*) pid.get(); if (appArgc) { argv[3] = workingDirPath; argv[4] = (char*) appFilePath.get(); for (int i = 1; i < appArgc; ++i) argv[4 + i] = appArgv[i]; argv[4 + appArgc] = nsnull; } else { argv[3] = nsnull; argc = 3; } LOG(("spawning updater process [%s]\n", updaterPath.get())); #if defined(USE_EXECV) chdir(applyToDir.get()); execv(updaterPath.get(), argv); #elif defined(XP_WIN) _wchdir(applyToDir.get()); if (!WinLaunchChild(updaterPathW.get(), appArgc + 4, argv)) return; _exit(0); #else PRStatus status; PRProcessAttr *attr; attr = PR_NewProcessAttr(); if (!attr) goto end; status = PR_ProcessAttrSetCurrentDirectory(attr, applyToDir.get()); if (status != PR_SUCCESS) goto end; #ifdef XP_MACOSX CommandLineServiceMac::SetupMacCommandLine(argc, argv, PR_TRUE); #endif PR_CreateProcessDetached(updaterPath.get(), argv, nsnull, attr); exit(0); end: PR_DestroyProcessAttr(attr); delete[] argv; #endif }