diff options
Diffstat (limited to 'uriloader/exthandler/win')
-rw-r--r-- | uriloader/exthandler/win/nsLocalHandlerAppWin.cpp | 119 | ||||
-rw-r--r-- | uriloader/exthandler/win/nsLocalHandlerAppWin.h | 34 | ||||
-rw-r--r-- | uriloader/exthandler/win/nsMIMEInfoWin.cpp | 31 | ||||
-rw-r--r-- | uriloader/exthandler/win/nsMIMEInfoWin.h | 3 |
4 files changed, 178 insertions, 9 deletions
diff --git a/uriloader/exthandler/win/nsLocalHandlerAppWin.cpp b/uriloader/exthandler/win/nsLocalHandlerAppWin.cpp new file mode 100644 index 0000000000..df5cfbee03 --- /dev/null +++ b/uriloader/exthandler/win/nsLocalHandlerAppWin.cpp @@ -0,0 +1,119 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsLocalHandlerAppWin.h" +#include "nsString.h" +#include "nsIWindowsRegKey.h" +#include "nsILocalFileWin.h" +#include "nsComponentManagerUtils.h" + +static nsresult GetPrettyNameFromFileDescription( + const nsCOMPtr<nsILocalFileWin>& executableOnWindows, + const nsString& assignedName, nsString& aName) { + nsresult result = NS_ERROR_FAILURE; + + if (executableOnWindows) { + result = executableOnWindows->GetVersionInfoField("FileDescription", aName); + + if (NS_FAILED(result) || aName.IsEmpty()) { + if (!assignedName.IsEmpty()) { + aName = assignedName; + } else { + result = executableOnWindows->GetLeafName(aName); + } + + if (!aName.IsEmpty()) { + result = NS_OK; + } else { + result = NS_ERROR_FAILURE; + } + } + } + + return result; +} + +static nsresult GetValueFromRegistry(nsString& aName, + const nsCOMPtr<nsIWindowsRegKey>& appKey, + const nsString& registryPath, + const nsString& valueName) { + nsresult rv = + appKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT, registryPath, + nsIWindowsRegKey::ACCESS_QUERY_VALUE); + + if (NS_SUCCEEDED(rv)) { + nsAutoString applicationName; + if (NS_SUCCEEDED(appKey->ReadStringValue(valueName, applicationName))) { + aName = applicationName; + return NS_OK; + } + } + + return NS_ERROR_FAILURE; +}; + +std::function<nsresult(nsString&)> +nsLocalHandlerAppWin::GetPrettyNameOnNonMainThreadCallback() { + // Make a copy of executable so that we don't have to worry about any other + // threads + nsCOMPtr<nsIFile> executable; + mExecutable->Clone(getter_AddRefs(executable)); + + // Get the windows interface to the file + nsCOMPtr<nsILocalFileWin> executableOnWindows(do_QueryInterface(executable)); + auto appIdOrName = mAppIdOrName; + auto assignedName = mName; + + std::function<nsresult(nsString&)> callback = + [assignedName, appIdOrName, + executableOnWindows = + std::move(executableOnWindows)](nsString& aName) -> nsresult { + // On all platforms, we want a human readable name for an application. + // For example: msedge -> Microsoft Edge Browser + // + // This is generated on mac directly in nsLocalHandlerAppMac::GetName. + // The auto-test coverage for GetName isn't thorough enough to be + // confident that changing GetName on Windows won't cause problems. + // + // Besides that, this is a potentially slow thing to execute, and making + // it asynchronous is preferable. There's a fallback to GetName() in the + // nsLocalHandlerApp::PrettyNameAsync to cover Mac and Linux. + + if (appIdOrName.IsEmpty()) { + return GetPrettyNameFromFileDescription(executableOnWindows, assignedName, + aName); + } + + nsCOMPtr<nsIWindowsRegKey> appKey = + do_CreateInstance("@mozilla.org/windows-registry-key;1"); + if (!appKey) { + return GetPrettyNameFromFileDescription(executableOnWindows, assignedName, + aName); + } + + // Check for ApplicationName first. Path: + // HKEY_CLASSES_ROOT\${APP_ID}\Application, Value entry: ApplicationName + nsresult rv = + GetValueFromRegistry(aName, appKey, appIdOrName + u"\\Application"_ns, + u"ApplicationName"_ns); + if (NS_SUCCEEDED(rv) && !aName.IsEmpty()) { + return rv; + } + + // Check for the default on the Applications entry next. + // Path: HKEY_CLASSES_ROOT\Applications\${APP_ID}, Value entry: "" + // (default) + rv = GetValueFromRegistry(aName, appKey, u"Applications\\"_ns + appIdOrName, + u""_ns); + if (NS_SUCCEEDED(rv) && !aName.IsEmpty()) { + return rv; + } + + // Fallthrough to getting the name from the file description + return GetPrettyNameFromFileDescription(executableOnWindows, assignedName, + aName); + }; + + return callback; +} diff --git a/uriloader/exthandler/win/nsLocalHandlerAppWin.h b/uriloader/exthandler/win/nsLocalHandlerAppWin.h new file mode 100644 index 0000000000..68deda05f4 --- /dev/null +++ b/uriloader/exthandler/win/nsLocalHandlerAppWin.h @@ -0,0 +1,34 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef NSLOCALHANDLERAPPWIN_H_ +#define NSLOCALHANDLERAPPWIN_H_ + +#include "nsLocalHandlerApp.h" +#include "nsString.h" + +class nsLocalHandlerAppWin : public nsLocalHandlerApp { + public: + nsLocalHandlerAppWin() {} + + nsLocalHandlerAppWin(const char16_t* aName, nsIFile* aExecutable) + : nsLocalHandlerApp(aName, aExecutable) {} + + nsLocalHandlerAppWin(const nsAString& aName, nsIFile* aExecutable) + : nsLocalHandlerApp(aName, aExecutable) {} + virtual ~nsLocalHandlerAppWin() {} + + void SetAppIdOrName(const nsString& appIdOrName) { + mAppIdOrName = appIdOrName; + } + + protected: + std::function<nsresult(nsString&)> GetPrettyNameOnNonMainThreadCallback() + override; + + private: + nsString mAppIdOrName; +}; + +#endif /*NSLOCALHANDLERAPPMAC_H_*/ diff --git a/uriloader/exthandler/win/nsMIMEInfoWin.cpp b/uriloader/exthandler/win/nsMIMEInfoWin.cpp index 758b2018a7..24044c5f25 100644 --- a/uriloader/exthandler/win/nsMIMEInfoWin.cpp +++ b/uriloader/exthandler/win/nsMIMEInfoWin.cpp @@ -9,6 +9,7 @@ #include "nsCOMArray.h" #include "nsLocalFile.h" #include "nsMIMEInfoWin.h" +#include "nsLocalHandlerAppWin.h" #include "nsIMIMEService.h" #include "nsNetUtil.h" #include <windows.h> @@ -221,6 +222,16 @@ nsMIMEInfoWin::GetHasDefaultHandler(bool* _retval) { return NS_OK; } +NS_IMETHODIMP nsMIMEInfoWin::GetDefaultExecutable(nsIFile** aExecutable) { + nsCOMPtr<nsIFile> defaultApp = GetDefaultApplication(); + if (defaultApp) { + defaultApp.forget(aExecutable); + return NS_OK; + } + + return NS_ERROR_FAILURE; +} + NS_IMETHODIMP nsMIMEInfoWin::GetEnumerator(nsISimpleEnumerator** _retval) { nsCOMArray<nsIVariant> properties; @@ -554,6 +565,7 @@ bool nsMIMEInfoWin::GetProgIDVerbCommandHandler(const nsAString& appProgIDName, // entries to lower case and stores them in the trackList array. void nsMIMEInfoWin::ProcessPath(nsCOMPtr<nsIMutableArray>& appList, nsTArray<nsString>& trackList, + const nsAutoString& appIdOrName, const nsAString& appFilesystemCommand) { nsAutoString lower(appFilesystemCommand); ToLowerCase(lower); @@ -569,6 +581,9 @@ void nsMIMEInfoWin::ProcessPath(nsCOMPtr<nsIMutableArray>& appList, nsCOMPtr<nsILocalHandlerApp> aApp; if (!GetLocalHandlerApp(appFilesystemCommand, aApp)) return; + // Track the app id so that the pretty name can be determined later + (static_cast<nsLocalHandlerAppWin*>(aApp.get()))->SetAppIdOrName(appIdOrName); + // Save in our main tracking arrays appList->AppendElement(aApp); trackList.AppendElement(lower); @@ -673,7 +688,7 @@ nsMIMEInfoWin::GetPossibleLocalHandlers(nsIArray** _retval) { if (GetProgIDVerbCommandHandler(appProgId, appFilesystemCommand, false) && !IsPathInList(appFilesystemCommand, trackList)) { - ProcessPath(appList, trackList, appFilesystemCommand); + ProcessPath(appList, trackList, appProgId, appFilesystemCommand); } } } @@ -701,7 +716,7 @@ nsMIMEInfoWin::GetPossibleLocalHandlers(nsIArray** _retval) { false) || IsPathInList(appFilesystemCommand, trackList)) continue; - ProcessPath(appList, trackList, appFilesystemCommand); + ProcessPath(appList, trackList, appName, appFilesystemCommand); } } regKey->Close(); @@ -729,7 +744,7 @@ nsMIMEInfoWin::GetPossibleLocalHandlers(nsIArray** _retval) { false) || IsPathInList(appFilesystemCommand, trackList)) continue; - ProcessPath(appList, trackList, appFilesystemCommand); + ProcessPath(appList, trackList, appProgId, appFilesystemCommand); } } regKey->Close(); @@ -762,7 +777,7 @@ nsMIMEInfoWin::GetPossibleLocalHandlers(nsIArray** _retval) { false) || IsPathInList(appFilesystemCommand, trackList)) continue; - ProcessPath(appList, trackList, appFilesystemCommand); + ProcessPath(appList, trackList, appValue, appFilesystemCommand); } } } @@ -791,7 +806,7 @@ nsMIMEInfoWin::GetPossibleLocalHandlers(nsIArray** _retval) { false) || IsPathInList(appFilesystemCommand, trackList)) continue; - ProcessPath(appList, trackList, appFilesystemCommand); + ProcessPath(appList, trackList, appProgId, appFilesystemCommand); } } regKey->Close(); @@ -829,7 +844,7 @@ nsMIMEInfoWin::GetPossibleLocalHandlers(nsIArray** _retval) { false) || IsPathInList(appFilesystemCommand, trackList)) continue; - ProcessPath(appList, trackList, appFilesystemCommand); + ProcessPath(appList, trackList, appName, appFilesystemCommand); } } } @@ -857,7 +872,7 @@ nsMIMEInfoWin::GetPossibleLocalHandlers(nsIArray** _retval) { if (!GetAppsVerbCommandHandler(appName, appFilesystemCommand, false) || IsPathInList(appFilesystemCommand, trackList)) continue; - ProcessPath(appList, trackList, appFilesystemCommand); + ProcessPath(appList, trackList, appName, appFilesystemCommand); } } regKey->Close(); @@ -882,7 +897,7 @@ nsMIMEInfoWin::GetPossibleLocalHandlers(nsIArray** _retval) { if (!GetAppsVerbCommandHandler(appName, appFilesystemCommand, false) || IsPathInList(appFilesystemCommand, trackList)) continue; - ProcessPath(appList, trackList, appFilesystemCommand); + ProcessPath(appList, trackList, appName, appFilesystemCommand); } } } diff --git a/uriloader/exthandler/win/nsMIMEInfoWin.h b/uriloader/exthandler/win/nsMIMEInfoWin.h index fa972b23a9..a7bc40c696 100644 --- a/uriloader/exthandler/win/nsMIMEInfoWin.h +++ b/uriloader/exthandler/win/nsMIMEInfoWin.h @@ -22,6 +22,7 @@ class nsMIMEInfoWin : public nsMIMEInfoBase, public nsIPropertyBag { NS_IMETHOD LaunchWithFile(nsIFile* aFile) override; NS_IMETHOD GetHasDefaultHandler(bool* _retval) override; + NS_IMETHOD GetDefaultExecutable(nsIFile** aExecutable) override; NS_IMETHOD GetPossibleLocalHandlers(nsIArray** _retval) override; NS_IMETHOD IsCurrentAppOSDefault(bool* _retval) override; @@ -68,7 +69,7 @@ class nsMIMEInfoWin : public nsMIMEInfoBase, public nsIPropertyBag { // Helper routine used in tracking app lists void ProcessPath(nsCOMPtr<nsIMutableArray>& appList, - nsTArray<nsString>& trackList, + nsTArray<nsString>& trackList, const nsAutoString& appId, const nsAString& appFilesystemCommand); // Helper routine to call mozilla::ShellExecuteByExplorer |