summaryrefslogtreecommitdiffstats
path: root/uriloader/exthandler/win
diff options
context:
space:
mode:
Diffstat (limited to 'uriloader/exthandler/win')
-rw-r--r--uriloader/exthandler/win/nsLocalHandlerAppWin.cpp119
-rw-r--r--uriloader/exthandler/win/nsLocalHandlerAppWin.h34
-rw-r--r--uriloader/exthandler/win/nsMIMEInfoWin.cpp31
-rw-r--r--uriloader/exthandler/win/nsMIMEInfoWin.h3
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