зеркало из https://github.com/mozilla/pjs.git
194439 nsOSHelperAppService on windows doesn't support non-ASCII default description.
fix this by using *W versions of registry functions when running on an nt-based windows. r=ere sr=bzbarsky
This commit is contained in:
Родитель
0b06306238
Коммит
a00520fd2c
|
@ -31,6 +31,7 @@
|
|||
#include "nsIProcess.h"
|
||||
#include "plstr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
|
||||
// we need windows.h to read out registry information...
|
||||
#include <windows.h>
|
||||
|
@ -42,11 +43,26 @@
|
|||
|
||||
// helper methods: forward declarations...
|
||||
static BYTE * GetValueBytes( HKEY hKey, const char *pValueName, DWORD *pLen=0);
|
||||
nsresult GetExtensionFrom4xRegistryInfo(const char * aMimeType, nsCString& aFileExtension);
|
||||
nsresult GetExtensionFromWindowsMimeDatabase(const char * aMimeType, nsCString& aFileExtension);
|
||||
static nsresult GetExtensionFrom4xRegistryInfo(const char * aMimeType, nsCString& aFileExtension);
|
||||
static nsresult GetExtensionFromWindowsMimeDatabase(const char * aMimeType, nsCString& aFileExtension);
|
||||
|
||||
// static member
|
||||
PRBool nsOSHelperAppService::mIsNT = PR_FALSE;
|
||||
|
||||
nsOSHelperAppService::nsOSHelperAppService() : nsExternalHelperAppService()
|
||||
{}
|
||||
{
|
||||
OSVERSIONINFO osversion;
|
||||
::ZeroMemory(&osversion, sizeof(OSVERSIONINFO));
|
||||
osversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
|
||||
if (!GetVersionEx(&osversion)) {
|
||||
// If the call failed, better be safe and assume *W functions don't work
|
||||
mIsNT = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
mIsNT = (osversion.dwPlatformId == VER_PLATFORM_WIN32_NT);
|
||||
}
|
||||
}
|
||||
|
||||
nsOSHelperAppService::~nsOSHelperAppService()
|
||||
{}
|
||||
|
@ -99,7 +115,7 @@ NS_IMETHODIMP nsOSHelperAppService::LaunchAppWithTempFile(nsIMIMEInfo * aMIMEInf
|
|||
|
||||
// The windows registry provides a mime database key which lists a set of mime types and corresponding "Extension" values.
|
||||
// we can use this to look up our mime type to see if there is a preferred extension for the mime type.
|
||||
nsresult GetExtensionFromWindowsMimeDatabase(const char * aMimeType, nsCString& aFileExtension)
|
||||
static nsresult GetExtensionFromWindowsMimeDatabase(const char * aMimeType, nsCString& aFileExtension)
|
||||
{
|
||||
HKEY hKey;
|
||||
nsCAutoString mimeDatabaseKey ("MIME\\Database\\Content Type\\");
|
||||
|
@ -127,7 +143,7 @@ nsresult GetExtensionFromWindowsMimeDatabase(const char * aMimeType, nsCString&
|
|||
// helper apps based on extension. Right now, we really don't have a good place to go for
|
||||
// trying to figure out the extension for a particular mime type....One short term hack is to look
|
||||
// this information in 4.x (it's stored in the windows regsitry).
|
||||
nsresult GetExtensionFrom4xRegistryInfo(const char * aMimeType, nsCString& aFileExtension)
|
||||
static nsresult GetExtensionFrom4xRegistryInfo(const char * aMimeType, nsCString& aFileExtension)
|
||||
{
|
||||
nsCAutoString command ("Software\\Netscape\\Netscape Navigator\\Suffixes");
|
||||
nsresult rv = NS_OK;
|
||||
|
@ -169,8 +185,8 @@ static BYTE * GetValueBytes( HKEY hKey, const char *pValueName, DWORD *pLen)
|
|||
if (err == ERROR_SUCCESS) {
|
||||
pBytes = new BYTE[bufSz];
|
||||
err = ::RegQueryValueEx( hKey, pValueName, NULL, NULL, pBytes, &bufSz);
|
||||
delete [] pBytes;
|
||||
if (err != ERROR_SUCCESS) {
|
||||
delete [] pBytes;
|
||||
pBytes = NULL;
|
||||
} else {
|
||||
// Return length if caller wanted it.
|
||||
|
@ -183,6 +199,39 @@ static BYTE * GetValueBytes( HKEY hKey, const char *pValueName, DWORD *pLen)
|
|||
return( pBytes);
|
||||
}
|
||||
|
||||
/* static */
|
||||
PRBool nsOSHelperAppService::GetValueString(HKEY hKey, PRUnichar* pValueName, nsAString& result)
|
||||
{
|
||||
if (!mIsNT) {
|
||||
char* pBytes = (char*)GetValueBytes(hKey, NS_LossyConvertUTF16toASCII(pValueName).get());
|
||||
if (pBytes) {
|
||||
nsresult rv = NS_CopyNativeToUnicode(nsDependentCString(pBytes), result);
|
||||
delete[] pBytes;
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
DWORD bufSz;
|
||||
LONG err = ::RegQueryValueExW( hKey, pValueName, NULL, NULL, NULL, &bufSz);
|
||||
if (err == ERROR_SUCCESS) {
|
||||
PRUnichar* pBytes = new PRUnichar[bufSz];
|
||||
if (!pBytes)
|
||||
return PR_FALSE;
|
||||
|
||||
err = ::RegQueryValueExW( hKey, pValueName, NULL, NULL, (BYTE*)pBytes, &bufSz);
|
||||
delete [] pBytes;
|
||||
if (err != ERROR_SUCCESS) {
|
||||
return PR_FALSE;
|
||||
} else {
|
||||
result.Assign(pBytes);
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsOSHelperAppService::ExternalProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists)
|
||||
{
|
||||
// look up the protocol scheme in the windows registry....if we find a match then we have a handler for it...
|
||||
|
@ -258,40 +307,38 @@ nsresult nsOSHelperAppService::GetFileTokenForPath(const PRUnichar * platformApp
|
|||
// to be prompted.
|
||||
//
|
||||
// This function sets only the Description attribute of the input nsIMIMEInfo.
|
||||
static nsresult GetMIMEInfoFromRegistry( LPBYTE fileType, nsIMIMEInfo *pInfo )
|
||||
/* static */
|
||||
nsresult nsOSHelperAppService::GetMIMEInfoFromRegistry( const nsAFlatString& fileType, nsIMIMEInfo *pInfo )
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NS_ENSURE_ARG( fileType );
|
||||
NS_ENSURE_ARG( pInfo );
|
||||
|
||||
// Get registry key for the pointed-to "file type."
|
||||
HKEY fileTypeKey = 0;
|
||||
LONG rc = ::RegOpenKeyEx( HKEY_CLASSES_ROOT, (const char *)fileType, 0, KEY_QUERY_VALUE, &fileTypeKey );
|
||||
if ( rc == ERROR_SUCCESS )
|
||||
{
|
||||
// OK, the default value here is the description of the type.
|
||||
DWORD lenDesc = 0;
|
||||
LPBYTE pDesc = GetValueBytes( fileTypeKey, "", &lenDesc );
|
||||
if ( pDesc )
|
||||
{
|
||||
PRUnichar *pUniDesc = new PRUnichar[lenDesc+1];
|
||||
if (pUniDesc) {
|
||||
int len = MultiByteToWideChar(CP_ACP, 0, (const char *)pDesc, -1, pUniDesc, lenDesc);
|
||||
pUniDesc[len] = 0;
|
||||
pInfo->SetDescription( pUniDesc );
|
||||
delete [] pUniDesc;
|
||||
}
|
||||
delete [] pDesc;
|
||||
}
|
||||
::RegCloseKey(fileTypeKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = NS_ERROR_FAILURE;
|
||||
LONG rc;
|
||||
if (mIsNT) {
|
||||
rc = ::RegOpenKeyExW( HKEY_CLASSES_ROOT, fileType.get(), 0, KEY_QUERY_VALUE, &fileTypeKey );
|
||||
}
|
||||
else {
|
||||
nsCAutoString ansiKey;
|
||||
rv = NS_CopyUnicodeToNative(fileType, ansiKey);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return rv;
|
||||
rc = ::RegOpenKeyEx( HKEY_CLASSES_ROOT, ansiKey.get(), 0, KEY_QUERY_VALUE, &fileTypeKey );
|
||||
}
|
||||
if ( rc != ERROR_SUCCESS )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// OK, the default value here is the description of the type.
|
||||
nsAutoString description;
|
||||
PRBool found = GetValueString(fileTypeKey, NULL, description);
|
||||
if (found)
|
||||
pInfo->SetDescription(description.get());
|
||||
::RegCloseKey(fileTypeKey);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -315,7 +362,7 @@ static PRBool typeFromExtEquals(const char *aExt, const char *aType)
|
|||
LONG err = ::RegOpenKeyEx( HKEY_CLASSES_ROOT, fileExtToUse.get(), 0, KEY_QUERY_VALUE, &hKey);
|
||||
if (err == ERROR_SUCCESS)
|
||||
{
|
||||
LPBYTE pBytes = GetValueBytes( hKey, "Content Type");
|
||||
LPBYTE pBytes = GetValueBytes(hKey, "Content Type");
|
||||
if (pBytes)
|
||||
{
|
||||
eq = strcmp((const char *)pBytes, aType) == 0;
|
||||
|
@ -354,41 +401,39 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetByExtension(const char *a
|
|||
typeToUse.Assign((const char*)pBytes);
|
||||
delete [] pBytes;
|
||||
}
|
||||
LPBYTE pFileDescription = GetValueBytes(hKey, "");
|
||||
nsAutoString description;
|
||||
PRBool found = GetValueString(hKey, NULL, description);
|
||||
|
||||
nsIMIMEInfo* mimeInfo = nsnull;
|
||||
CallCreateInstance(NS_MIMEINFO_CONTRACTID, &mimeInfo);
|
||||
if (mimeInfo && !typeToUse.IsEmpty())
|
||||
if (mimeInfo)
|
||||
{
|
||||
mimeInfo->SetMIMEType(typeToUse.get());
|
||||
if (!typeToUse.IsEmpty())
|
||||
mimeInfo->SetMIMEType(typeToUse.get());
|
||||
// don't append the '.'
|
||||
mimeInfo->AppendExtension(fileExtToUse.get() + 1);
|
||||
|
||||
mimeInfo->SetPreferredAction(nsIMIMEInfo::useSystemDefault);
|
||||
|
||||
nsAutoString description;
|
||||
description.AssignWithConversion((char *) pFileDescription);
|
||||
|
||||
PRInt32 pos = description.FindChar('.');
|
||||
nsAutoString visibleDesc(description);
|
||||
PRInt32 pos = visibleDesc.FindChar('.');
|
||||
if (pos > 0)
|
||||
description.Truncate(pos);
|
||||
visibleDesc.Truncate(pos);
|
||||
// the format of the description usually looks like appname.version.something.
|
||||
// for now, let's try to make it pretty and just show you the appname.
|
||||
|
||||
mimeInfo->SetDefaultDescription(description.get());
|
||||
mimeInfo->SetDefaultDescription(visibleDesc.get());
|
||||
|
||||
// Get other nsIMIMEInfo fields from registry, if possible.
|
||||
if ( pFileDescription )
|
||||
if ( found )
|
||||
{
|
||||
GetMIMEInfoFromRegistry( pFileDescription, mimeInfo );
|
||||
GetMIMEInfoFromRegistry( description, mimeInfo );
|
||||
}
|
||||
}
|
||||
else {
|
||||
NS_IF_RELEASE(mimeInfo); // we failed to really find an entry in the registry
|
||||
}
|
||||
|
||||
delete [] pFileDescription;
|
||||
|
||||
// close the key
|
||||
::RegCloseKey(hKey);
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "nsExternalHelperAppService.h"
|
||||
#include "nsCExternalHandlerService.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include <windows.h>
|
||||
|
||||
class nsOSHelperAppService : public nsExternalHelperAppService
|
||||
{
|
||||
|
@ -57,6 +58,14 @@ protected:
|
|||
// Lookup a mime info by extension, using an optional type hint
|
||||
already_AddRefed<nsIMIMEInfo> GetByExtension(const char *aFileExt, const char *aTypeHint = nsnull);
|
||||
nsresult FindOSMimeInfoForType(const char * aMimeContentType, nsIURI * aURI, char ** aFileExtension, nsIMIMEInfo ** aMIMEInfo);
|
||||
|
||||
/** Whether we're running on an OS that supports the *W registry functions */
|
||||
static PRBool mIsNT;
|
||||
/** Get the string value of a registry value and store it in result.
|
||||
* @return PR_TRUE on success, PR_FALSE on failure
|
||||
*/
|
||||
static PRBool GetValueString(HKEY hKey, PRUnichar* pValueName, nsAString& result);
|
||||
static nsresult GetMIMEInfoFromRegistry(const nsAFlatString& fileType, nsIMIMEInfo *pInfo);
|
||||
};
|
||||
|
||||
#endif // nsOSHelperAppService_h__
|
||||
|
|
Загрузка…
Ссылка в новой задаче