diff --git a/mozilla/docshell/resources/locale/en-US/appstrings.properties b/mozilla/docshell/resources/locale/en-US/appstrings.properties index 13fbc662ee1..32f80484f10 100644 --- a/mozilla/docshell/resources/locale/en-US/appstrings.properties +++ b/mozilla/docshell/resources/locale/en-US/appstrings.properties @@ -52,6 +52,8 @@ deniedPortAccess=Access to the port number given has been disabled for security proxyResolveFailure=The proxy server you have configured could not be found. Please check your proxy settings and try again. proxyConnectFailure=The connection was refused when attempting to contact the proxy server you have configured. Please check your proxy settings and try again. externalProtocolTitle=External Protocol Request -externalProtocolPrompt=An external application must be launched to handle %1$S: links. Requested link:\n\n\n%2$S\n\n\nIf you were not expecting this request it may be an attempt to exploit a weakness in that other program. Cancel this request unless you are sure it is not malicious.\n +externalProtocolPrompt=An external application must be launched to handle %1$S: links. Requested link:\n\n\n%2$S\nApplication: %3$S\n\n\nIf you were not expecting this request it may be an attempt to exploit a weakness in that other program. Cancel this request unless you are sure it is not malicious.\n +#LOCALIZATION NOTE (externalProtocolUnknown): The following string is shown if the application name can't be determined +externalProtocolUnknown= externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application diff --git a/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp b/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp index f8929a3c95b..35cc0825cb6 100644 --- a/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/mozilla/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -1067,6 +1067,12 @@ NS_IMETHODIMP nsExternalHelperAppService::LoadUrl(nsIURI * aURL) return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP nsExternalHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval) +{ + // this method should only be implemented by each OS specific implementation of this service. + return NS_ERROR_NOT_IMPLEMENTED; +} + ////////////////////////////////////////////////////////////////////////////////////////////////////// // Methods related to deleting temporary files on exit diff --git a/mozilla/uriloader/exthandler/nsExternalProtocolHandler.cpp b/mozilla/uriloader/exthandler/nsExternalProtocolHandler.cpp index bb76d5a6085..7194a559eba 100644 --- a/mozilla/uriloader/exthandler/nsExternalProtocolHandler.cpp +++ b/mozilla/uriloader/exthandler/nsExternalProtocolHandler.cpp @@ -190,6 +190,11 @@ PRBool nsExtProtocolChannel::PromptForScheme(nsIURI* aURI) return PR_FALSE; } + nsXPIDLString desc; + nsCOMPtr extProtService (do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID)); + if (extProtService) + extProtService->GetApplicationDescription(scheme, desc); + nsCOMPtr appstrings; rv = sbSvc->CreateBundle("chrome://global/locale/appstrings.properties", getter_AddRefs(appstrings)); @@ -213,15 +218,21 @@ PRBool nsExtProtocolChannel::PromptForScheme(nsIURI* aURI) appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolLaunchBtn").get(), getter_Copies(launchBtn)); + if (desc.IsEmpty()) + appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolUnknown").get(), + getter_Copies(desc)); + + nsXPIDLString message; - const PRUnichar* msgArgs[] = { utf16scheme.get(), uri.get() }; + const PRUnichar* msgArgs[] = { utf16scheme.get(), uri.get(), desc.get() }; appstrings->FormatStringFromName(NS_LITERAL_STRING("externalProtocolPrompt").get(), msgArgs, NS_ARRAY_LENGTH(msgArgs), getter_Copies(message)); if (utf16scheme.IsEmpty() || uri.IsEmpty() || title.IsEmpty() || - checkMsg.IsEmpty() || launchBtn.IsEmpty() || message.IsEmpty()) + checkMsg.IsEmpty() || launchBtn.IsEmpty() || message.IsEmpty() || + desc.IsEmpty()) return PR_FALSE; // all pieces assembled, now we can pose the dialog diff --git a/mozilla/uriloader/exthandler/nsIExternalProtocolService.idl b/mozilla/uriloader/exthandler/nsIExternalProtocolService.idl index 39f7a1b1973..fabacaa6880 100644 --- a/mozilla/uriloader/exthandler/nsIExternalProtocolService.idl +++ b/mozilla/uriloader/exthandler/nsIExternalProtocolService.idl @@ -50,7 +50,7 @@ interface nsIFile; * handler for a given protocol scheme. And you can ask it to load * the url using the default handler. */ -[scriptable, uuid(100FD4B3-4557-11d4-98D0-001083010E9B)] +[scriptable, uuid(4F38DF07-0B21-4d40-BED0-08E33EB566FB)] interface nsIExternalProtocolService : nsISupports { /** @@ -76,5 +76,19 @@ interface nsIExternalProtocolService : nsISupports * Used to load a url via an external protocol handler (if one exists) * @param aURL The url to load */ - void loadUrl (in nsIURI aURL); + void loadUrl (in nsIURI aURL); + + /** + * Gets a human-readable description for the application responsible for + * handling a specific protocol. + * + * @param aScheme The scheme to look up. For example, "mms". + * + * @throw NS_ERROR_NOT_IMPLEMENTED + * If getting descriptions for protocol helpers is not supported + * @throw NS_ERROR_NOT_AVAILABLE + * If no protocol helper exists for this scheme, or if it is not + * possible to get a description for it. + */ + AString getApplicationDescription(in AUTF8String aScheme); }; diff --git a/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp b/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp index 89b90bc8f4c..fdf6c736b3a 100644 --- a/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp +++ b/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.cpp @@ -184,30 +184,50 @@ nsGNOMERegistry::Startup() // crash on exit. } -/* static */ PRBool -nsGNOMERegistry::HandlerExists(const char *aProtocolScheme) +/** + * Finds the application for a given protocol. + * + * @param aProtocolScheme + * Protocol to look up. For example, "ghelp" or "mailto". + * + * @return UTF-8 string identifying the application. Must be freed with + * g_free. + * NULL on error. + */ +static gchar* getAppForScheme(const nsACString& aProtocolScheme) { if (!gconfLib) - return PR_FALSE; + return nsnull; GConfClient *client = _gconf_client_get_default(); NS_ASSERTION(client, "no gconf client"); nsCAutoString gconfPath(NS_LITERAL_CSTRING("/desktop/gnome/url-handlers/") + - nsDependentCString(aProtocolScheme) + + aProtocolScheme + NS_LITERAL_CSTRING("/command")); gchar *app = _gconf_client_get_string(client, gconfPath.get(), NULL); g_object_unref(G_OBJECT(client)); + return app; +} + +/* static */ PRBool +nsGNOMERegistry::HandlerExists(const char *aProtocolScheme) +{ + gchar *app = getAppForScheme(nsDependentCString(aProtocolScheme)); + if (app) { g_free(app); + GConfClient *client = _gconf_client_get_default(); nsCAutoString enabledPath(NS_LITERAL_CSTRING("/desktop/gnome/url-handlers/") + nsDependentCString(aProtocolScheme) + NS_LITERAL_CSTRING("/enabled")); gboolean isEnabled = _gconf_client_get_bool(client, enabledPath.get(), NULL); + g_object_unref(G_OBJECT(client)); + return isEnabled ? PR_TRUE : PR_FALSE; } @@ -231,6 +251,19 @@ nsGNOMERegistry::LoadURL(nsIURI *aURL) return NS_ERROR_FAILURE; } +/* static */ void +nsGNOMERegistry::GetAppDescForScheme(const nsACString& aScheme, + nsAString& aDesc) +{ + char *app = getAppForScheme(aScheme); + + if (app) { + CopyUTF8toUTF16(app, aDesc); + g_free(app); + } +} + + /* static */ already_AddRefed nsGNOMERegistry::GetFromExtension(const char *aFileExt) { diff --git a/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.h b/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.h index b485f1e3812..cf2bdc11064 100644 --- a/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.h +++ b/mozilla/uriloader/exthandler/unix/nsGNOMERegistry.h @@ -49,6 +49,9 @@ class nsGNOMERegistry static nsresult LoadURL(nsIURI *aURL); + static void GetAppDescForScheme(const nsACString& aScheme, + nsAString& aDesc); + static already_AddRefed GetFromExtension(const char *aFileExt); static already_AddRefed GetFromType(const char *aMIMEType); diff --git a/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp b/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp index d6bc9ecafa7..3a8aa518c6f 100644 --- a/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp +++ b/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.cpp @@ -1298,6 +1298,22 @@ NS_IMETHODIMP nsOSHelperAppService::LoadUrl(nsIURI * aURI) #endif } +NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval) +{ + nsCOMPtr appFile; + nsresult rv = GetHandlerAppFromPrefs(PromiseFlatCString(aScheme).get(), + getter_AddRefs(appFile)); + if (NS_SUCCEEDED(rv)) + return appFile->GetLeafName(_retval); + +#ifdef MOZ_WIDGET_GTK2 + nsGNOMERegistry::GetAppDescForScheme(aScheme, _retval); + return _retval.IsEmpty() ? NS_ERROR_NOT_AVAILABLE : NS_OK; +#else + return NS_ERROR_NOT_AVAILABLE; +#endif +} + nsresult nsOSHelperAppService::GetFileTokenForPath(const PRUnichar * platformAppPath, nsIFile ** aFile) { LOG(("-- nsOSHelperAppService::GetFileTokenForPath: '%s'\n", diff --git a/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.h b/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.h index 5b0bc13e693..5f7aa6a5773 100644 --- a/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.h +++ b/mozilla/uriloader/exthandler/unix/nsOSHelperAppService.h @@ -65,6 +65,7 @@ public: // override nsIExternalProtocolService methods NS_IMETHOD ExternalProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists); NS_IMETHOD LoadUrl(nsIURI * aURL); + NS_IMETHOD GetApplicationDescription(const nsACString& aScheme, nsAString& _retval); // GetFileTokenForPath must be implemented by each platform. // platformAppPath --> a platform specific path to an application that we got out of the diff --git a/mozilla/uriloader/exthandler/win/nsOSHelperAppService.cpp b/mozilla/uriloader/exthandler/win/nsOSHelperAppService.cpp index b806dc03fbb..bbfbba1b2f4 100644 --- a/mozilla/uriloader/exthandler/win/nsOSHelperAppService.cpp +++ b/mozilla/uriloader/exthandler/win/nsOSHelperAppService.cpp @@ -256,6 +256,20 @@ NS_IMETHODIMP nsOSHelperAppService::LoadUrl(nsIURI * aURL) return rv; } +NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval) +{ + nsCAutoString cmdString(aScheme); + cmdString.AppendLiteral("\\shell\\open\\command"); + HKEY cmd; + LONG rc = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, cmdString.get(), 0, KEY_QUERY_VALUE, &cmd); + if (rc != ERROR_SUCCESS) + return NS_ERROR_NOT_AVAILABLE; + + PRBool found = GetValueString(cmd, NULL, _retval); + ::RegCloseKey(cmd); + return found ? NS_OK : NS_ERROR_NOT_AVAILABLE; +} + // GetMIMEInfoFromRegistry: This function obtains the values of some of the nsIMIMEInfo // attributes for the mimeType/extension associated with the input registry key. The default // entry for that key is the name of a registry key under HKEY_CLASSES_ROOT. The default diff --git a/mozilla/uriloader/exthandler/win/nsOSHelperAppService.h b/mozilla/uriloader/exthandler/win/nsOSHelperAppService.h index ad4eb1f5d4b..6eecb08a98f 100644 --- a/mozilla/uriloader/exthandler/win/nsOSHelperAppService.h +++ b/mozilla/uriloader/exthandler/win/nsOSHelperAppService.h @@ -60,6 +60,7 @@ public: // override nsIExternalProtocolService methods NS_IMETHOD ExternalProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists); NS_IMETHOD LoadUrl(nsIURI * aURL); + NS_IMETHOD GetApplicationDescription(const nsACString& aScheme, nsAString& _retval); // method overrides for windows registry look up steps.... already_AddRefed GetMIMEInfoFromOS(const nsACString& aMIMEType, const nsACString& aFileExt, PRBool *aFound);