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:
cbiesinger%web.de 2003-11-14 20:48:52 +00:00
Родитель 0b06306238
Коммит a00520fd2c
2 изменённых файлов: 99 добавлений и 45 удалений

Просмотреть файл

@ -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__