From 5ae346e36b4b8624fbedfa05d38ff72d84a43c4c Mon Sep 17 00:00:00 2001 From: Gijs Kruitbosch Date: Thu, 13 Apr 2017 15:45:54 +0100 Subject: [PATCH] Bug 1352348 - add a method to nsExternalHelperAppService that only fetches a string mimetype for an extension, r=bz,Paolo MozReview-Commit-ID: 3p1pakC9g45 --HG-- extra : rebase_source : b8b9eb417d2e70b57f3ecc5b872ad678afe946df --- .../exthandler/nsExternalHelperAppService.cpp | 16 +++- .../exthandler/nsExternalHelperAppService.h | 9 ++ .../exthandler/win/nsOSHelperAppService.cpp | 94 ++++++++++++------- .../exthandler/win/nsOSHelperAppService.h | 2 + 4 files changed, 83 insertions(+), 38 deletions(-) diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp index b5e4c42fb805..a1a603f8a612 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -2729,14 +2729,12 @@ nsExternalHelperAppService::GetTypeFromExtension(const nsACString& aFileExt, } // Ask OS. - bool found = false; - nsCOMPtr 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; } @@ -2935,3 +2933,11 @@ bool nsExternalHelperAppService::GetTypeFromExtras(const nsACString& aExtension, return false; } + +bool +nsExternalHelperAppService::GetMIMETypeFromOSForExtension(const nsACString& aExtension, nsACString& aMIMEType) +{ + bool found = false; + nsCOMPtr mimeInfo = GetMIMEInfoFromOS(EmptyCString(), aExtension, &found); + return found && mimeInfo && NS_SUCCEEDED(mimeInfo->GetMIMEType(aMIMEType)); +} diff --git a/uriloader/exthandler/nsExternalHelperAppService.h b/uriloader/exthandler/nsExternalHelperAppService.h index ae6d76af39dc..0645b24b01da 100644 --- a/uriloader/exthandler/nsExternalHelperAppService.h +++ b/uriloader/exthandler/nsExternalHelperAppService.h @@ -108,6 +108,15 @@ public: 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(); diff --git a/uriloader/exthandler/win/nsOSHelperAppService.cpp b/uriloader/exthandler/win/nsOSHelperAppService.cpp index 03c48cfacbe1..dedbeb795351 100644 --- a/uriloader/exthandler/win/nsOSHelperAppService.cpp +++ b/uriloader/exthandler/win/nsOSHelperAppService.cpp @@ -395,43 +395,25 @@ already_AddRefed nsOSHelperAppService::GetByExtension(const nsAFl 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 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 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 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); @@ -458,8 +440,17 @@ already_AddRefed nsOSHelperAppService::GetByExtension(const nsAFl } else { - found = NS_SUCCEEDED(regKey->ReadStringValue(EmptyString(), - appInfo)); + nsCOMPtr 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 @@ -597,3 +588,40 @@ nsOSHelperAppService::GetProtocolHandlerInfoFromOS(const nsACString &aScheme, 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 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; +} diff --git a/uriloader/exthandler/win/nsOSHelperAppService.h b/uriloader/exthandler/win/nsOSHelperAppService.h index c5e707256417..b00529433cc3 100644 --- a/uriloader/exthandler/win/nsOSHelperAppService.h +++ b/uriloader/exthandler/win/nsOSHelperAppService.h @@ -40,6 +40,8 @@ public: 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