NS_METHOD nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile **aLocalFile) { if (NS_WARN_IF(!aLocalFile)) return NS_ERROR_INVALID_ARG; nsresult rv; if (!mMozBinDirectory) { // Get the mozilla bin directory // 1. Check the directory service first for NS_XPCOM_CURRENT_PROCESS_DIR // This will be set if a directory was passed to NS_InitXPCOM // 2. If that doesn't work, set it to be the current process directory nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); if (NS_FAILED(rv)) return rv; rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory)); if (NS_FAILED(rv)) { rv = directoryService->Get(NS_OS_CURRENT_PROCESS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(mMozBinDirectory)); if (NS_FAILED(rv)) return rv; } } nsCOMPtr<nsIFile> aFile; rv = mMozBinDirectory->Clone(getter_AddRefs(aFile)); if (NS_FAILED(rv)) return rv; NS_IF_ADDREF(*aLocalFile = aFile); return NS_OK; }
// A helper function for AutoObjectMapperFaultyLib::Map. Finds out // where the installation's lib directory is, since we'll have to look // in there to get hold of libmozglue.so. Returned C string is heap // allocated and the caller must deallocate it. static char* get_installation_lib_dir() { nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID)); if (!directoryService) { return nullptr; } nsCOMPtr<nsIFile> greDir; nsresult rv = directoryService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile), getter_AddRefs(greDir)); if (NS_FAILED(rv)) return nullptr; nsCString path; rv = greDir->GetNativePath(path); if (NS_FAILED(rv)) { return nullptr; } return strdup(path.get()); }
bool PluginHangUIParent::Init(const nsString& aPluginName) { if (mHangUIProcessHandle) { return false; } nsresult rv; rv = mMiniShm.Init(this, ::IsDebuggerPresent() ? INFINITE : kTimeout); NS_ENSURE_SUCCESS(rv, false); nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID)); if (!directoryService) { return false; } nsCOMPtr<nsIFile> greDir; rv = directoryService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile), getter_AddRefs(greDir)); if (NS_FAILED(rv)) { return false; } nsAutoString path; greDir->GetPath(path); FilePath exePath(path.get()); exePath = exePath.AppendASCII(MOZ_HANGUI_PROCESS_NAME); CommandLine commandLine(exePath.value()); nsXPIDLString localizedStr; const PRUnichar* formatParams[] = { aPluginName.get() }; rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES, "PluginHangUIMessage", formatParams, localizedStr); if (NS_FAILED(rv)) { return false; } commandLine.AppendLooseValue(localizedStr.get()); const char* keys[] = { "PluginHangUITitle", "PluginHangUIWaitButton", "PluginHangUIStopButton", "DontAskAgain" }; for (unsigned int i = 0; i < ArrayLength(keys); ++i) { rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES, keys[i], localizedStr); if (NS_FAILED(rv)) { return false; } commandLine.AppendLooseValue(localizedStr.get()); } rv = GetHangUIOwnerWindowHandle(mMainWindowHandle); if (NS_FAILED(rv)) { return false; } nsAutoString hwndStr; hwndStr.AppendPrintf("%p", mMainWindowHandle); commandLine.AppendLooseValue(hwndStr.get()); ScopedHandle procHandle(::OpenProcess(SYNCHRONIZE, TRUE, GetCurrentProcessId())); if (!procHandle.IsValid()) { return false; } nsAutoString procHandleStr; procHandleStr.AppendPrintf("%p", procHandle.Get()); commandLine.AppendLooseValue(procHandleStr.get()); std::wstring ipcCookie; rv = mMiniShm.GetCookie(ipcCookie); if (NS_FAILED(rv)) { return false; } commandLine.AppendLooseValue(ipcCookie); mShowEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); ScopedHandle showEvent(::CreateEvent(NULL, FALSE, FALSE, NULL)); if (!showEvent.IsValid()) { return false; } mShowEvent = showEvent.Get(); STARTUPINFO startupInfo = { sizeof(STARTUPINFO) }; PROCESS_INFORMATION processInfo = { NULL }; BOOL isProcessCreated = ::CreateProcess(exePath.value().c_str(), const_cast<wchar_t*>(commandLine.command_line_string().c_str()), nullptr, nullptr, TRUE, DETACHED_PROCESS, nullptr, nullptr, &startupInfo, &processInfo); if (isProcessCreated) { ::CloseHandle(processInfo.hThread); mHangUIProcessHandle = processInfo.hProcess; ::RegisterWaitForSingleObject(&mRegWait, processInfo.hProcess, &SOnHangUIProcessExit, this, INFINITE, WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE); ::WaitForSingleObject(mShowEvent, kTimeout); } mShowEvent = NULL; return !(!isProcessCreated); }
NS_IMETHODIMP sbLocalDatabaseLibraryLoader::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData) { nsresult rv; if (strcmp(aTopic, NS_FINAL_UI_STARTUP_CATEGORY) == 0) { if (m_DetectedCorruptLibrary) { /* check to see if the prefs file is writable, to recover from people * running the app with sudo :( */ nsCOMPtr<nsIProperties> dirService = do_GetService("@mozilla.org/file/directory_service;1", &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIFile> prefFile; rv = dirService->Get("PrefF", NS_GET_IID(nsIFile), getter_AddRefs(prefFile)); NS_ENSURE_SUCCESS(rv, rv); PRBool prefExists; /* if the pref file is missing we go through the normal first-run process * and therefore don't need to care about this */ PRBool prefWritable = PR_TRUE; rv = prefFile->Exists(&prefExists); if (NS_SUCCEEDED(rv) && prefExists) { rv = prefFile->IsWritable(&prefWritable); NS_ENSURE_SUCCESS(rv, rv); } if (prefWritable) { rv = PromptToDeleteLibraries(); NS_ENSURE_SUCCESS(rv, rv); } else { // database file is not writable, just bail rv = PromptInaccessibleLibraries(); NS_ENSURE_SUCCESS(rv, rv); } } } else if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { // By now, databases should all be closed so it is safe to delete // the db directory. if (m_DeleteLibrariesAtShutdown) { // get profile directory nsCOMPtr<nsIProperties> directoryService( do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIFile> siteDBDir; rv = directoryService->Get("ProfD", NS_GET_IID(nsIFile), getter_AddRefs(siteDBDir)); NS_ENSURE_SUCCESS(rv, rv); // append the database dir name siteDBDir->Append(NS_LITERAL_STRING("db")); // Delete all the databases but the metrics DB. (which hopefully // is not corrupt) nsCOMPtr<nsISimpleEnumerator> dirEnumerator; rv = siteDBDir->GetDirectoryEntries(getter_AddRefs(dirEnumerator)); NS_ENSURE_SUCCESS(rv, rv); nsString metricsdb = NS_LITERAL_STRING("metrics.db"); PRBool hasMore; dirEnumerator->HasMoreElements(&hasMore); while (hasMore && NS_SUCCEEDED(rv)) { nsCOMPtr<nsISupports> aSupport; rv = dirEnumerator->GetNext(getter_AddRefs(aSupport)); if (NS_FAILED(rv)) break; nsCOMPtr<nsIFile> curFile(do_QueryInterface(aSupport, &rv)); if (NS_FAILED(rv)) break; nsString leafName; rv = curFile->GetLeafName(leafName); if (NS_FAILED(rv)) break; if (leafName.Compare(metricsdb) != 0) { rv = curFile->Remove(false); NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Unable to delete file"); } dirEnumerator->HasMoreElements(&hasMore); } // We want to prompt the user to rescan on restart. nsCAutoString scancompleteBranch("songbird.firstrun.scancomplete"); sbLocalDatabaseLibraryLoader::RemovePrefBranch(scancompleteBranch); // And delete all the library prefs, so they get recreated on // startup. (It would be nice to not need to do this, so that // users could delete their db directory by hand and restart, but // bad things happen due to prefs and it's not worth putting time // into.) nsCAutoString prefBranch(PREFBRANCH_LOADER); sbLocalDatabaseLibraryLoader::RemovePrefBranch(prefBranch); } } return NS_OK; }
bool PluginHangUIParent::Init(const nsString& aPluginName) { if (mHangUIProcessHandle) { return false; } nsresult rv; rv = mMiniShm.Init(this, ::IsDebuggerPresent() ? INFINITE : mIPCTimeoutMs); NS_ENSURE_SUCCESS(rv, false); nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID)); if (!directoryService) { return false; } nsCOMPtr<nsIFile> greDir; rv = directoryService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile), getter_AddRefs(greDir)); if (NS_FAILED(rv)) { return false; } nsAutoString path; greDir->GetPath(path); FilePath exePath(path.get()); exePath = exePath.AppendASCII(MOZ_HANGUI_PROCESS_NAME); CommandLine commandLine(exePath.value()); nsXPIDLString localizedStr; const PRUnichar* formatParams[] = { aPluginName.get() }; rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES, "PluginHangUIMessage", formatParams, localizedStr); if (NS_FAILED(rv)) { return false; } commandLine.AppendLooseValue(localizedStr.get()); const char* keys[] = { "PluginHangUITitle", "PluginHangUIWaitButton", "PluginHangUIStopButton", "DontAskAgain" }; for (unsigned int i = 0; i < ArrayLength(keys); ++i) { rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES, keys[i], localizedStr); if (NS_FAILED(rv)) { return false; } commandLine.AppendLooseValue(localizedStr.get()); } rv = GetHangUIOwnerWindowHandle(mMainWindowHandle); if (NS_FAILED(rv)) { return false; } nsAutoString hwndStr; hwndStr.AppendPrintf("%p", mMainWindowHandle); commandLine.AppendLooseValue(hwndStr.get()); ScopedHandle procHandle(::OpenProcess(SYNCHRONIZE, TRUE, GetCurrentProcessId())); if (!procHandle.IsValid()) { return false; } nsAutoString procHandleStr; procHandleStr.AppendPrintf("%p", procHandle.Get()); commandLine.AppendLooseValue(procHandleStr.get()); // On Win7+, pass the application user model to the child, so it can // register with it. This insures windows created by the Hang UI // properly group with the parent app on the Win7 taskbar. nsCOMPtr<nsIWinTaskbar> taskbarInfo = do_GetService(NS_TASKBAR_CONTRACTID); if (taskbarInfo) { bool isSupported = false; taskbarInfo->GetAvailable(&isSupported); nsAutoString appId; if (isSupported && NS_SUCCEEDED(taskbarInfo->GetDefaultGroupId(appId))) { commandLine.AppendLooseValue(appId.get()); } else { commandLine.AppendLooseValue(L"-"); } } else { commandLine.AppendLooseValue(L"-"); } nsAutoString ipcTimeoutStr; ipcTimeoutStr.AppendInt(mIPCTimeoutMs); commandLine.AppendLooseValue(ipcTimeoutStr.get()); std::wstring ipcCookie; rv = mMiniShm.GetCookie(ipcCookie); if (NS_FAILED(rv)) { return false; } commandLine.AppendLooseValue(ipcCookie); ScopedHandle showEvent(::CreateEvent(nullptr, FALSE, FALSE, nullptr)); if (!showEvent.IsValid()) { return false; } mShowEvent = showEvent.Get(); MutexAutoLock lock(mMutex); STARTUPINFO startupInfo = { sizeof(STARTUPINFO) }; PROCESS_INFORMATION processInfo = { nullptr }; BOOL isProcessCreated = ::CreateProcess(exePath.value().c_str(), const_cast<wchar_t*>(commandLine.command_line_string().c_str()), nullptr, nullptr, TRUE, DETACHED_PROCESS, nullptr, nullptr, &startupInfo, &processInfo); if (isProcessCreated) { ::CloseHandle(processInfo.hThread); mHangUIProcessHandle = processInfo.hProcess; ::RegisterWaitForSingleObject(&mRegWait, processInfo.hProcess, &SOnHangUIProcessExit, this, INFINITE, WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE); ::WaitForSingleObject(mShowEvent, ::IsDebuggerPresent() ? INFINITE : mIPCTimeoutMs); // Setting this to true even if we time out on mShowEvent. This timeout // typically occurs when the machine is thrashing so badly that // plugin-hang-ui.exe is taking a while to start. If we didn't set // this to true, Firefox would keep spawning additional plugin-hang-ui // processes, which is not what we want. mIsShowing = true; } mShowEvent = nullptr; return !(!isProcessCreated); }
/* nsIFile getFile (in string prop, out bool\/* PRBool *\/ persistent); */ NS_IMETHODIMP LocationProvider::GetFile(const char *prop, bool/* PRBool */ *persistent, nsIFile **_retval) { nsCOMPtr<nsILocalFile> localFile; nsresult rv = NS_ERROR_FAILURE; *_retval = nsnull; *persistent = PR_TRUE; if (strcmp(prop, NS_GRE_DIR) == 0) rv = GetAvailableRuntime (getter_AddRefs(localFile)); else if (strcmp(prop, NS_APP_DEFAULTS_50_DIR) == 0) { rv = GetAvailableRuntime (getter_AddRefs(localFile)); if (NS_SUCCEEDED(rv)) rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); } else if (strcmp(prop, NS_APP_PREF_DEFAULTS_50_DIR) == 0) { rv = GetAvailableRuntime (getter_AddRefs(localFile)); if (NS_SUCCEEDED(rv)) { rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); if (NS_SUCCEEDED(rv)) rv = localFile->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME); } } else if (strcmp(prop, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR) == 0 || strcmp(prop, NS_APP_PROFILE_DEFAULTS_50_DIR) == 0) { rv = GetAvailableRuntime (getter_AddRefs(localFile)); if (NS_SUCCEEDED(rv)) { rv = localFile->AppendRelativeNativePath(DEFAULTS_DIR_NAME); if (NS_SUCCEEDED(rv)) rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME); } } else if (strcmp(prop, NS_APP_USER_PROFILE_50_DIR) == 0 || strcmp(prop, NS_APP_PREFS_50_DIR) == 0) { nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); if (NS_FAILED(rv)) return rv; rv = directoryService->Get(NS_APP_USER_PROFILES_ROOT_DIR, NS_GET_IID(nsIFile), getter_AddRefs(localFile)); // nsEmbedCString file(widget->startDir); // rv = NS_NewNativeLocalFile(file, PR_TRUE, getter_AddRefs(localFile)); // if (NS_SUCCEEDED(rv)) { // rv = localFile->AppendRelativeNativePath(PROFILE_ROOT_DIR_NAME); // if (NS_SUCCEEDED(rv)) // rv = localFile->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME); // } } else if (strcmp(prop, NS_APP_RES_DIR) == 0) { rv = GetAvailableRuntime (getter_AddRefs(localFile)); if (NS_SUCCEEDED(rv)) rv = localFile->AppendRelativeNativePath(RES_DIR_NAME); } else if (strcmp(prop, NS_APP_CHROME_DIR) == 0) { rv = GetAvailableRuntime (getter_AddRefs(localFile)); if (NS_SUCCEEDED(rv)) rv = localFile->AppendRelativeNativePath(CHROME_DIR_NAME); } //else if (strcmp(prop, NS_APP_PLUGINS_DIR) == 0) //{ // rv = GetAvailableRuntime (getter_AddRefs(localFile)); // if (NS_SUCCEEDED(rv)) // rv = localFile->AppendRelativeNativePath(PLUGINS_DIR_NAME); //} //else if (strcmp(prop, NS_APP_SEARCH_DIR) == 0) //{ // rv = GetAvailableRuntime (getter_AddRefs(localFile)); // if (NS_SUCCEEDED(rv)) // rv = localFile->AppendRelativeNativePath(SEARCH_DIR_NAME); //} else if (strcmp(prop, NS_GRE_COMPONENT_DIR) == 0 || strcmp(prop, NS_XPCOM_COMPONENT_DIR) == 0) { rv = GetAvailableRuntime (getter_AddRefs(localFile)); if (NS_SUCCEEDED(rv)) rv = localFile->AppendRelativeNativePath(COMPONENTS_DIR_NAME); } else if (strcmp (prop, NS_XPCOM_COMPONENT_REGISTRY_FILE) == 0) { nsEmbedCString file(widget->dataDir); rv = NS_NewNativeLocalFile(file, PR_TRUE, getter_AddRefs(localFile)); if (NS_SUCCEEDED(rv)) { bool/* PRBool */ exists; rv = localFile->AppendNative(COMPONENT_DIRECTORY); if (NS_FAILED(rv)) return rv; rv = localFile->Exists (&exists); if (NS_FAILED(rv)) return rv; if (!exists) rv = localFile->Create(nsIFile::DIRECTORY_TYPE, 0700); if (NS_FAILED(rv)) return rv; rv = localFile->AppendNative(COMPONENT_REGISTRY_NAME); } } else if (strcmp(prop, NS_XPCOM_XPTI_REGISTRY_FILE) == 0) { nsEmbedCString file(widget->dataDir); rv = NS_NewNativeLocalFile(file, PR_TRUE, getter_AddRefs(localFile)); if (NS_SUCCEEDED(rv)) { bool/* PRBool */ exists; rv = localFile->AppendNative(COMPONENT_DIRECTORY); if (NS_FAILED(rv)) return rv; rv = localFile->Exists (&exists); if (NS_FAILED(rv)) return rv; if (!exists) rv = localFile->Create(nsIFile::DIRECTORY_TYPE, 0700); if (NS_FAILED(rv)) return rv; rv = localFile->AppendNative(XPTI_REGISTRY_NAME); } } if (localFile && NS_SUCCEEDED(rv)) return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval); return rv; }
NS_IMETHODIMP nsPrefBranch::GetComplexValue(const char *aPrefName, const nsIID & aType, void * *_retval) { nsresult rv; nsXPIDLCString utf8String; // we have to do this one first because it's different than all the rest if (aType.Equals(NS_GET_IID(nsIPrefLocalizedString))) { nsCOMPtr<nsIPrefLocalizedString> theString(do_CreateInstance(NS_PREFLOCALIZEDSTRING_CONTRACTID, &rv)); if (NS_SUCCEEDED(rv)) { const char *pref; PRBool bNeedDefault = PR_FALSE; rv = getValidatedPrefName(aPrefName, &pref); if (NS_FAILED(rv)) return rv; if (mIsDefault) { bNeedDefault = PR_TRUE; } else { // if there is no user (or locked) value if (!PREF_HasUserPref(pref) && !PREF_PrefIsLocked(pref)) { bNeedDefault = PR_TRUE; } } // if we need to fetch the default value, do that instead, otherwise use the // value we pulled in at the top of this function if (bNeedDefault) { nsXPIDLString utf16String; rv = GetDefaultFromPropertiesFile(pref, getter_Copies(utf16String)); if (NS_SUCCEEDED(rv)) { rv = theString->SetData(utf16String.get()); } } else { rv = GetCharPref(aPrefName, getter_Copies(utf8String)); if (NS_SUCCEEDED(rv)) { rv = theString->SetData(NS_ConvertUTF8toUCS2(utf8String).get()); } } if (NS_SUCCEEDED(rv)) { nsIPrefLocalizedString *temp = theString; NS_ADDREF(temp); *_retval = (void *)temp; } } return rv; } // if we can't get the pref, there's no point in being here rv = GetCharPref(aPrefName, getter_Copies(utf8String)); if (NS_FAILED(rv)) { return rv; } if (aType.Equals(NS_GET_IID(nsILocalFile))) { nsCOMPtr<nsILocalFile> file(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv)); if (NS_SUCCEEDED(rv)) { rv = file->SetPersistentDescriptor(utf8String); if (NS_SUCCEEDED(rv)) { nsILocalFile *temp = file; NS_ADDREF(temp); *_retval = (void *)temp; return NS_OK; } } return rv; } if (aType.Equals(NS_GET_IID(nsIRelativeFilePref))) { nsACString::const_iterator keyBegin, strEnd; utf8String.BeginReading(keyBegin); utf8String.EndReading(strEnd); // The pref has the format: [fromKey]a/b/c if (*keyBegin++ != '[') return NS_ERROR_FAILURE; nsACString::const_iterator keyEnd(keyBegin); if (!FindCharInReadable(']', keyEnd, strEnd)) return NS_ERROR_FAILURE; nsCAutoString key(Substring(keyBegin, keyEnd)); nsCOMPtr<nsILocalFile> fromFile; nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv)); if (NS_FAILED(rv)) return rv; rv = directoryService->Get(key.get(), NS_GET_IID(nsILocalFile), getter_AddRefs(fromFile)); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsILocalFile> theFile; rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(theFile)); if (NS_FAILED(rv)) return rv; rv = theFile->SetRelativeDescriptor(fromFile, Substring(++keyEnd, strEnd)); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIRelativeFilePref> relativePref; rv = NS_NewRelativeFilePref(theFile, key, getter_AddRefs(relativePref)); if (NS_FAILED(rv)) return rv; *_retval = relativePref; NS_ADDREF(NS_STATIC_CAST(nsIRelativeFilePref*, *_retval)); return NS_OK; }