Bug 1352348 - add a method to nsExternalHelperAppService that only fetches a string mimetype for an extension, r?bz,paolo
MozReview-Commit-ID: 3p1pakC9g45
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -2718,24 +2718,22 @@ nsExternalHelperAppService::GetTypeFromE
for (auto& entry : defaultMimeEntries) {
if (aFileExt.LowerCaseEqualsASCII(entry.mFileExtension)) {
aContentType = entry.mMimeType;
return NS_OK;
}
}
// Ask OS.
- bool found = false;
- nsCOMPtr<nsIMIMEInfo> mi = GetMIMEInfoFromOS(EmptyCString(), aFileExt, &found);
- if (mi && found) {
- return mi->GetMIMEType(aContentType);
+ if (GetMIMETypeFromOSForExtension(aFileExt, aContentType)) {
+ return NS_OK;
}
// Check extras array.
- found = GetTypeFromExtras(aFileExt, aContentType);
+ bool found = GetTypeFromExtras(aFileExt, aContentType);
if (found) {
return NS_OK;
}
// Try the plugins
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
if (pluginHost &&
pluginHost->HavePluginForExtension(aFileExt, aContentType)) {
@@ -2924,8 +2922,16 @@ bool nsExternalHelperAppService::GetType
++iter;
}
start = iter;
}
}
return false;
}
+
+bool
+nsExternalHelperAppService::GetMIMETypeFromOSForExtension(const nsACString& aExtension, nsACString& aMIMEType)
+{
+ bool found = false;
+ nsCOMPtr<nsIMIMEInfo> mimeInfo = GetMIMEInfoFromOS(EmptyCString(), aExtension, &found);
+ return found && mimeInfo && NS_SUCCEEDED(mimeInfo->GetMIMEType(aMIMEType));
+}
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -103,16 +103,25 @@ public:
* application path.
*/
virtual nsresult GetFileTokenForPath(const char16_t * platformAppPath,
nsIFile ** aFile);
virtual nsresult OSProtocolHandlerExists(const char *aScheme,
bool *aExists) = 0;
+ /**
+ * Given an extension, get a MIME type string. If not overridden by
+ * the OS-specific nsOSHelperAppService, will call into GetMIMEInfoFromOS
+ * with an empty mimetype.
+ * @return true if we successfully found a mimetype.
+ */
+ virtual bool GetMIMETypeFromOSForExtension(const nsACString& aExtension,
+ nsACString& aMIMEType);
+
protected:
virtual ~nsExternalHelperAppService();
/**
* Searches the "extra" array of MIMEInfo objects for an object
* with a specific type. If found, it will modify the passed-in
* MIMEInfo. Otherwise, it will return an error and the MIMEInfo
* will be untouched.
--- a/uriloader/exthandler/win/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/win/nsOSHelperAppService.cpp
@@ -390,53 +390,35 @@ nsOSHelperAppService::GetDefaultAppInfo(
return NS_OK;
}
already_AddRefed<nsMIMEInfoWin> nsOSHelperAppService::GetByExtension(const nsAFlatString& aFileExt, const char *aTypeHint)
{
if (aFileExt.IsEmpty())
return nullptr;
- // windows registry assumes your file extension is going to include the '.'.
- // so make sure it's there...
+ // Determine the mime type.
+ nsAutoCString typeToUse;
+ if (aTypeHint && *aTypeHint) {
+ typeToUse.Assign(aTypeHint);
+ } else if (!GetMIMETypeFromOSForExtension(NS_ConvertUTF16toUTF8(aFileExt), typeToUse)) {
+ return nullptr;
+ }
+
+ RefPtr<nsMIMEInfoWin> mimeInfo = new nsMIMEInfoWin(typeToUse);
+
+ // windows registry assumes your file extension is going to include the '.',
+ // but our APIs expect it to not be there, so make sure we normalize that bit.
nsAutoString fileExtToUse;
if (aFileExt.First() != char16_t('.'))
fileExtToUse = char16_t('.');
fileExtToUse.Append(aFileExt);
- // Try to get an entry from the windows registry.
- nsCOMPtr<nsIWindowsRegKey> regKey =
- do_CreateInstance("@mozilla.org/windows-registry-key;1");
- if (!regKey)
- return nullptr;
-
- nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
- fileExtToUse,
- nsIWindowsRegKey::ACCESS_QUERY_VALUE);
- if (NS_FAILED(rv))
- return nullptr;
-
- nsAutoCString typeToUse;
- if (aTypeHint && *aTypeHint) {
- typeToUse.Assign(aTypeHint);
- }
- else {
- nsAutoString temp;
- if (NS_FAILED(regKey->ReadStringValue(NS_LITERAL_STRING("Content Type"),
- temp)) || temp.IsEmpty()) {
- return nullptr;
- }
- // Content-Type is always in ASCII
- LossyAppendUTF16toASCII(temp, typeToUse);
- }
-
- RefPtr<nsMIMEInfoWin> mimeInfo = new nsMIMEInfoWin(typeToUse);
-
- // don't append the '.'
+ // don't append the '.' for our APIs.
mimeInfo->AppendExtension(NS_ConvertUTF16toUTF8(Substring(fileExtToUse, 1)));
mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
nsAutoString appInfo;
bool found;
// Retrieve the default application for this extension
if (mAppAssoc) {
@@ -453,18 +435,27 @@ already_AddRefed<nsMIMEInfoWin> nsOSHelp
CoTaskMemFree(pResult);
}
else {
found = false;
}
}
else
{
- found = NS_SUCCEEDED(regKey->ReadStringValue(EmptyString(),
- appInfo));
+ nsCOMPtr<nsIWindowsRegKey> regKey =
+ do_CreateInstance("@mozilla.org/windows-registry-key;1");
+ if (!regKey)
+ return nullptr;
+ nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
+ fileExtToUse,
+ nsIWindowsRegKey::ACCESS_QUERY_VALUE);
+ if (NS_SUCCEEDED(rv)) {
+ found = NS_SUCCEEDED(regKey->ReadStringValue(EmptyString(),
+ appInfo));
+ }
}
// Bug 358297 - ignore the default handler, force the user to choose app
if (appInfo.EqualsLiteral("XPSViewer.Document"))
found = false;
if (!found) {
return nullptr;
@@ -592,8 +583,45 @@ nsOSHelperAppService::GetProtocolHandler
nsAutoString desc;
GetApplicationDescription(aScheme, desc);
handlerInfo->SetDefaultDescription(desc);
return NS_OK;
}
+bool
+nsOSHelperAppService::GetMIMETypeFromOSForExtension(const nsACString& aExtension,
+ nsACString& aMIMEType)
+{
+ if (aExtension.IsEmpty())
+ return false;
+
+ // windows registry assumes your file extension is going to include the '.'.
+ // so make sure it's there...
+ nsAutoString fileExtToUse;
+ if (aExtension.First() != '.')
+ fileExtToUse = char16_t('.');
+
+ AppendUTF8toUTF16(aExtension, fileExtToUse);
+
+ // Try to get an entry from the windows registry.
+ nsCOMPtr<nsIWindowsRegKey> regKey =
+ do_CreateInstance("@mozilla.org/windows-registry-key;1");
+ if (!regKey)
+ return false;
+
+ nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
+ fileExtToUse,
+ nsIWindowsRegKey::ACCESS_QUERY_VALUE);
+ if (NS_FAILED(rv))
+ return false;
+
+ nsAutoString mimeType;
+ if (NS_FAILED(regKey->ReadStringValue(NS_LITERAL_STRING("Content Type"),
+ mimeType)) || mimeType.IsEmpty()) {
+ return false;
+ }
+ // Content-Type is always in ASCII
+ aMIMEType.Truncate();
+ LossyAppendUTF16toASCII(mimeType, aMIMEType);
+ return true;
+}
--- a/uriloader/exthandler/win/nsOSHelperAppService.h
+++ b/uriloader/exthandler/win/nsOSHelperAppService.h
@@ -35,16 +35,18 @@ public:
nsresult LoadUriInternal(nsIURI * aURL);
NS_IMETHOD GetApplicationDescription(const nsACString& aScheme, nsAString& _retval);
// method overrides for windows registry look up steps....
already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType, const nsACString& aFileExt, bool *aFound);
NS_IMETHOD GetProtocolHandlerInfoFromOS(const nsACString &aScheme,
bool *found,
nsIHandlerInfo **_retval);
+ virtual bool GetMIMETypeFromOSForExtension(const nsACString& aExtension,
+ nsACString& aMIMEType) override;
/** Get the string value of a registry value and store it in result.
* @return true on success, false on failure
*/
static bool GetValueString(HKEY hKey, const char16_t* pValueName, nsAString& result);
protected:
nsresult GetDefaultAppInfo(const nsAString& aTypeName, nsAString& aDefaultDescription, nsIFile** aDefaultApplication);