Fix xpfe winhooks static string abuse b=339810 r=CTho sr=jag
git-svn-id: svn://10.0.0.236/trunk@198932 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -49,7 +49,7 @@ MOZILLA_INTERNAL_API = 1
|
||||
|
||||
XPIDLSRCS = nsIWindowsHooks.idl
|
||||
|
||||
CPPSRCS = nsWindowsHooks.cpp
|
||||
CPPSRCS = nsWindowsHooks.cpp nsWindowsHooksUtil.cpp
|
||||
|
||||
REQUIRES = \
|
||||
xpcom \
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
#include "nsString.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsWindowsHooksUtil.cpp"
|
||||
#include "nsWindowsHooks.h"
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
@@ -84,39 +83,7 @@
|
||||
|
||||
#define RUNKEY "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
|
||||
|
||||
// Objects that describe the Windows registry entries that we need to tweak.
|
||||
static ProtocolRegistryEntry
|
||||
http( "http" ),
|
||||
https( "https" ),
|
||||
ftp( "ftp" ),
|
||||
chrome( "chrome" ),
|
||||
gopher( "gopher" );
|
||||
const char *jpgExts[] = { ".jpg", ".jpe", ".jpeg", ".jfif", ".pjpeg", ".pjp", 0 };
|
||||
const char *gifExts[] = { ".gif", 0 };
|
||||
const char *pngExts[] = { ".png", 0 };
|
||||
const char *mngExts[] = { ".mng", 0 };
|
||||
const char *xbmExts[] = { ".xbm", 0 };
|
||||
const char *bmpExts[] = { ".bmp", ".rle", ".dib", 0 };
|
||||
const char *icoExts[] = { ".ico", 0 };
|
||||
const char *xmlExts[] = { ".xml", 0 };
|
||||
const char *xhtmExts[] = { ".xht", ".xhtml", 0 };
|
||||
const char *xulExts[] = { ".xul", 0 };
|
||||
const char *htmExts[] = { ".htm", ".html", ".shtml", 0 };
|
||||
|
||||
static FileTypeRegistryEntry
|
||||
jpg( jpgExts, "MozillaJPEG", "JPEG Image", "jpegfile", "jpeg-file.ico"),
|
||||
gif( gifExts, "MozillaGIF", "GIF Image", "giffile", "gif-file.ico"),
|
||||
png( pngExts, "MozillaPNG", "PNG Image", "pngfile", "image-file.ico"),
|
||||
mng( mngExts, "MozillaMNG", "MNG Image", "", "image-file.ico"),
|
||||
xbm( xbmExts, "MozillaXBM", "XBM Image", "xbmfile", "image-file.ico"),
|
||||
bmp( bmpExts, "MozillaBMP", "BMP Image", "", "image-file.ico"),
|
||||
ico( icoExts, "MozillaICO", "Icon", "icofile", "%1"),
|
||||
xml( xmlExts, "MozillaXML", "XML Document", "xmlfile", "xml-file.ico"),
|
||||
xhtml( xhtmExts, "MozillaXHTML", "XHTML Document", "", "misc-file.ico"),
|
||||
xul( xulExts, "MozillaXUL", "Mozilla XUL Document", "", "xul-file.ico");
|
||||
|
||||
static EditableFileTypeRegistryEntry
|
||||
mozillaMarkup( htmExts, "MozillaHTML", "HTML Document", "htmlfile", "html-file.ico");
|
||||
static nsWindowsHooks *gWindowsHooks = nsnull;
|
||||
|
||||
// Implementation of the nsIWindowsHooksSettings interface.
|
||||
// Use standard implementation of nsISupports stuff.
|
||||
@@ -181,10 +148,43 @@ DEFINE_GETTER_AND_SETTER( HaveBeenSet, mHaveBeenSet )
|
||||
// Use standard implementation of nsISupports stuff.
|
||||
NS_IMPL_ISUPPORTS1( nsWindowsHooks, nsIWindowsHooks )
|
||||
|
||||
nsWindowsHooks::nsWindowsHooks() {
|
||||
static const char *jpgExts[] = { ".jpg", ".jpe", ".jpeg", ".jfif", ".pjpeg", ".pjp", 0 };
|
||||
static const char *gifExts[] = { ".gif", 0 };
|
||||
static const char *pngExts[] = { ".png", 0 };
|
||||
static const char *mngExts[] = { ".mng", 0 };
|
||||
static const char *xbmExts[] = { ".xbm", 0 };
|
||||
static const char *bmpExts[] = { ".bmp", ".rle", ".dib", 0 };
|
||||
static const char *icoExts[] = { ".ico", 0 };
|
||||
static const char *xmlExts[] = { ".xml", 0 };
|
||||
static const char *xhtmExts[] = { ".xht", ".xhtml", 0 };
|
||||
static const char *xulExts[] = { ".xul", 0 };
|
||||
static const char *htmExts[] = { ".htm", ".html", ".shtml", 0 };
|
||||
|
||||
nsWindowsHooks::nsWindowsHooks()
|
||||
: http( "http" ),
|
||||
https( "https" ),
|
||||
ftp( "ftp" ),
|
||||
chrome( "chrome" ),
|
||||
gopher( "gopher" ),
|
||||
|
||||
jpg( jpgExts, "MozillaJPEG", "JPEG Image", "jpegfile", "jpeg-file.ico"),
|
||||
gif( gifExts, "MozillaGIF", "GIF Image", "giffile", "gif-file.ico"),
|
||||
png( pngExts, "MozillaPNG", "PNG Image", "pngfile", "image-file.ico"),
|
||||
mng( mngExts, "MozillaMNG", "MNG Image", "", "image-file.ico"),
|
||||
xbm( xbmExts, "MozillaXBM", "XBM Image", "xbmfile", "image-file.ico"),
|
||||
bmp( bmpExts, "MozillaBMP", "BMP Image", "", "image-file.ico"),
|
||||
ico( icoExts, "MozillaICO", "Icon", "icofile", "%1"),
|
||||
xml( xmlExts, "MozillaXML", "XML Document", "xmlfile", "xml-file.ico"),
|
||||
xhtml( xhtmExts, "MozillaXHTML", "XHTML Document", "", "misc-file.ico"),
|
||||
xul( xulExts, "MozillaXUL", "Mozilla XUL Document", "", "xul-file.ico"),
|
||||
|
||||
mozillaMarkup( htmExts, "MozillaHTML", "HTML Document", "htmlfile", "html-file.ico")
|
||||
{
|
||||
gWindowsHooks = this;
|
||||
}
|
||||
|
||||
nsWindowsHooks::~nsWindowsHooks() {
|
||||
gWindowsHooks = nsnull;
|
||||
}
|
||||
|
||||
// Internal GetPreferences.
|
||||
@@ -305,37 +305,37 @@ nsWindowsHooksSettings::GetRegistryMatches( PRBool *_retval ) {
|
||||
NS_ENSURE_ARG( _retval );
|
||||
*_retval = PR_TRUE;
|
||||
// Test registry for all selected attributes.
|
||||
if ( misMatch( mHandleHTTP, http )
|
||||
if ( misMatch( mHandleHTTP, gWindowsHooks->http )
|
||||
||
|
||||
misMatch( mHandleHTTPS, https )
|
||||
misMatch( mHandleHTTPS, gWindowsHooks->https )
|
||||
||
|
||||
misMatch( mHandleFTP, ftp )
|
||||
misMatch( mHandleFTP, gWindowsHooks->ftp )
|
||||
||
|
||||
misMatch( mHandleCHROME, chrome )
|
||||
misMatch( mHandleCHROME, gWindowsHooks->chrome )
|
||||
||
|
||||
misMatch( mHandleGOPHER, gopher )
|
||||
misMatch( mHandleGOPHER, gWindowsHooks->gopher )
|
||||
||
|
||||
misMatch( mHandleHTML, mozillaMarkup )
|
||||
misMatch( mHandleHTML, gWindowsHooks->mozillaMarkup )
|
||||
||
|
||||
misMatch( mHandleJPEG, jpg )
|
||||
misMatch( mHandleJPEG, gWindowsHooks->jpg )
|
||||
||
|
||||
misMatch( mHandleGIF, gif )
|
||||
misMatch( mHandleGIF, gWindowsHooks->gif )
|
||||
||
|
||||
misMatch( mHandlePNG, png )
|
||||
misMatch( mHandlePNG, gWindowsHooks->png )
|
||||
||
|
||||
misMatch( mHandleMNG, mng )
|
||||
misMatch( mHandleMNG, gWindowsHooks->mng )
|
||||
||
|
||||
misMatch( mHandleXBM, xbm )
|
||||
misMatch( mHandleXBM, gWindowsHooks->xbm )
|
||||
||
|
||||
misMatch( mHandleBMP, bmp )
|
||||
misMatch( mHandleBMP, gWindowsHooks->bmp )
|
||||
||
|
||||
misMatch( mHandleICO, ico )
|
||||
misMatch( mHandleICO, gWindowsHooks->ico )
|
||||
||
|
||||
misMatch( mHandleXML, xml )
|
||||
misMatch( mHandleXML, gWindowsHooks->xml )
|
||||
||
|
||||
misMatch( mHandleXHTML, xhtml )
|
||||
misMatch( mHandleXHTML, gWindowsHooks->xhtml )
|
||||
||
|
||||
misMatch( mHandleXUL, xul ) ) {
|
||||
misMatch( mHandleXUL, gWindowsHooks->xul ) ) {
|
||||
// Registry is out of synch.
|
||||
*_retval = PR_FALSE;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsIWindowsHooks.h"
|
||||
#include "nsWindowsHooksUtil.h"
|
||||
|
||||
#ifndef MAX_BUF
|
||||
#define MAX_BUF 4096
|
||||
@@ -130,6 +131,14 @@ protected:
|
||||
char mShortcutName[MAX_BUF];
|
||||
char mShortcutBase[MAX_BUF];
|
||||
char mShortcutProg[MAX_BUF];
|
||||
}; // nsWindowsHooksSettings
|
||||
|
||||
// Objects that describe the Windows registry entries that we need to tweak.
|
||||
ProtocolRegistryEntry http, https, ftp, chrome, gopher;
|
||||
FileTypeRegistryEntry jpg, gif, png, mng, xbm, bmp, ico, xml, xhtml, xul;
|
||||
EditableFileTypeRegistryEntry mozillaMarkup;
|
||||
|
||||
// Give nsWindowsHooksSettings full access.
|
||||
friend class nsWindowsHooksSettings;
|
||||
}; // nsWindowsHooks
|
||||
|
||||
#endif // nswindowshooks_h____
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "nsDirectoryService.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
#include "nsWindowsHooksUtil.h"
|
||||
|
||||
#ifdef MOZ_XUL_APP
|
||||
#include "nsNativeAppSupportWin.h"
|
||||
@@ -56,50 +57,6 @@
|
||||
#define MOZ_HWND_BROADCAST_MSG_TIMEOUT 5000
|
||||
#define MOZ_CLIENT_BROWSER_KEY "Software\\Clients\\StartMenuInternet"
|
||||
|
||||
// Where Mozilla stores its own registry values.
|
||||
const char * const mozillaKeyName = "Software\\Mozilla\\Desktop";
|
||||
|
||||
static const char shortcutSuffix[] = " -url \"%1\"";
|
||||
static const char chromeSuffix[] = " -chrome \"%1\"";
|
||||
static const char iconSuffix[] = ",0";
|
||||
|
||||
// Returns the (fully-qualified) name of this executable.
|
||||
static nsCString thisApplication() {
|
||||
static nsCAutoString result;
|
||||
|
||||
if ( result.IsEmpty() ) {
|
||||
char buffer[MAX_PATH] = { 0 };
|
||||
DWORD len = ::GetModuleFileName( NULL, buffer, sizeof buffer );
|
||||
len = ::GetShortPathName( buffer, buffer, sizeof buffer );
|
||||
|
||||
result = buffer;
|
||||
ToUpperCase(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns the "short" name of this application (in upper case). This is for
|
||||
// use as a StartMenuInternet value.
|
||||
static nsCString shortAppName() {
|
||||
static nsCAutoString result;
|
||||
|
||||
if ( result.IsEmpty() ) {
|
||||
// Find last backslash in thisApplication().
|
||||
nsCAutoString thisApp( thisApplication() );
|
||||
PRInt32 n = thisApp.RFind( "\\" );
|
||||
if ( n != kNotFound ) {
|
||||
// Use what comes after the last backslash.
|
||||
result = (const char*)thisApp.get() + n + 1;
|
||||
} else {
|
||||
// Use entire string.
|
||||
result = thisApp;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRBool IsNT()
|
||||
{
|
||||
static PRBool sInitialized = PR_FALSE;
|
||||
@@ -118,186 +75,6 @@ static PRBool IsNT()
|
||||
return sIsNT;
|
||||
}
|
||||
|
||||
// RegistryEntry
|
||||
//
|
||||
// Generic registry entry (no saving of previous values). Each is comprised of:
|
||||
// o A base HKEY
|
||||
// o A subkey name.
|
||||
// o An optional value name (empty for the "default" value).
|
||||
// o The registry setting we'd like this entry to have when set.
|
||||
struct RegistryEntry {
|
||||
HKEY baseKey; // e.g., HKEY_CURRENT_USER
|
||||
PRBool isNull; // i.e., should use ::RegDeleteValue
|
||||
nsCString keyName; // Key name.
|
||||
nsCString valueName; // Value name (can be empty, which implies NULL).
|
||||
nsCString setting; // What we set it to (UTF-8). This had better be
|
||||
// nsString to avoid extra string copies, but
|
||||
// this code is not performance-critical.
|
||||
|
||||
RegistryEntry( HKEY baseKey, const char* keyName, const char* valueName, const char* setting )
|
||||
: baseKey( baseKey ), isNull( setting == 0 ), keyName( keyName ), valueName( valueName ), setting( setting ? setting : "" ) {
|
||||
}
|
||||
|
||||
PRBool isAlreadySet() const;
|
||||
nsresult set();
|
||||
nsresult reset();
|
||||
nsCString currentSetting( PRBool *currentUndefined = 0 ) const;
|
||||
|
||||
// Return value name in proper form for passing to ::Reg functions
|
||||
// (i.e., emptry string is converted to a NULL pointer).
|
||||
const char* valueNameArg() const {
|
||||
return valueName.IsEmpty() ? NULL : valueName.get();
|
||||
}
|
||||
|
||||
nsCString fullName() const;
|
||||
};
|
||||
|
||||
// BoolRegistryEntry
|
||||
//
|
||||
// These are used to store the "windows integration" preferences.
|
||||
// You can query the value via operator void* (i.e., if ( boolPref )... ).
|
||||
// These are stored under HKEY_LOCAL_MACHINE\Software\Mozilla\Desktop.
|
||||
// Set sets the stored value to "1". Reset deletes it (which implies 0).
|
||||
struct BoolRegistryEntry : public RegistryEntry {
|
||||
BoolRegistryEntry( const char *name )
|
||||
: RegistryEntry( HKEY_LOCAL_MACHINE, mozillaKeyName, name, "1" ) {
|
||||
}
|
||||
operator PRBool();
|
||||
};
|
||||
|
||||
// SavedRegistryEntry
|
||||
//
|
||||
// Like a plain RegistryEntry, but set/reset save/restore the
|
||||
// it had before we set it.
|
||||
struct SavedRegistryEntry : public RegistryEntry {
|
||||
SavedRegistryEntry( HKEY baseKey, const char *keyName, const char *valueName, const char *setting )
|
||||
: RegistryEntry( baseKey, keyName, valueName, setting ) {
|
||||
}
|
||||
nsresult set();
|
||||
nsresult reset();
|
||||
};
|
||||
|
||||
// ProtocolRegistryEntry
|
||||
//
|
||||
// For setting entries for a given Internet Shortcut protocol.
|
||||
// The key name is calculated as
|
||||
// HKEY_LOCAL_MACHINE\Software\Classes\protocol\shell\open\command.
|
||||
// The setting is this executable (with appropriate suffix).
|
||||
// Set/reset are trickier in this case.
|
||||
struct ProtocolRegistryEntry : public SavedRegistryEntry {
|
||||
nsCString protocol;
|
||||
ProtocolRegistryEntry( const char* protocol )
|
||||
: SavedRegistryEntry( HKEY_LOCAL_MACHINE, "", "", thisApplication().get() ),
|
||||
protocol( protocol ) {
|
||||
keyName = "Software\\Classes\\";
|
||||
keyName += protocol;
|
||||
keyName += "\\shell\\open\\command";
|
||||
|
||||
// Append appropriate suffix to setting.
|
||||
if ( this->protocol.Equals( "chrome" ) || this->protocol.Equals( "MozillaXUL" ) ) {
|
||||
// Use "-chrome" command line flag.
|
||||
setting += chromeSuffix;
|
||||
} else {
|
||||
// Use standard "-url" command line flag.
|
||||
setting += shortcutSuffix;
|
||||
}
|
||||
}
|
||||
nsresult set();
|
||||
nsresult reset();
|
||||
};
|
||||
|
||||
// ProtocolIconRegistryEntry
|
||||
//
|
||||
// For setting icon entries for a given Internet Shortcut protocol.
|
||||
// The key name is calculated as
|
||||
// HKEY_LOCAL_MACHINE\Software\Classes\protocol\DefaultIcon.
|
||||
// The setting is this executable (with appropriate suffix).
|
||||
struct ProtocolIconRegistryEntry : public SavedRegistryEntry {
|
||||
nsCString protocol;
|
||||
ProtocolIconRegistryEntry( const char* aprotocol )
|
||||
: SavedRegistryEntry( HKEY_LOCAL_MACHINE, "", "", thisApplication().get() ),
|
||||
protocol( aprotocol ) {
|
||||
keyName = NS_LITERAL_CSTRING("Software\\Classes\\") + protocol + NS_LITERAL_CSTRING("\\DefaultIcon");
|
||||
|
||||
// Append appropriate suffix to setting.
|
||||
setting += iconSuffix;
|
||||
}
|
||||
};
|
||||
|
||||
// DDERegistryEntry
|
||||
//
|
||||
// Like a protocol registry entry, but for the shell\open\ddeexec subkey.
|
||||
//
|
||||
// We need to remove this subkey entirely to ensure we work properly with
|
||||
// various programs on various platforms (see Bugzilla bugs 59078, 58770, etc.).
|
||||
//
|
||||
// We don't try to save everything, though. We do save the known useful info
|
||||
// under the ddeexec subkey:
|
||||
// ddeexec\@
|
||||
// ddeexec\NoActivateHandler
|
||||
// ddeexec\Application\@
|
||||
// ddeexec\Topic\@
|
||||
//
|
||||
// set/reset save/restore these values and remove/restore the ddeexec subkey
|
||||
struct DDERegistryEntry : public SavedRegistryEntry {
|
||||
DDERegistryEntry( const char *protocol )
|
||||
: SavedRegistryEntry( HKEY_LOCAL_MACHINE, "", "", 0 ),
|
||||
activate( HKEY_LOCAL_MACHINE, "", "NoActivateHandler", 0 ),
|
||||
app( HKEY_LOCAL_MACHINE, "", "", 0 ),
|
||||
topic( HKEY_LOCAL_MACHINE, "", "", 0 ) {
|
||||
// Derive keyName from protocol.
|
||||
keyName = "Software\\Classes\\";
|
||||
keyName += protocol;
|
||||
keyName += "\\shell\\open\\ddeexec";
|
||||
// Set subkey names.
|
||||
activate.keyName = keyName;
|
||||
app.keyName = keyName;
|
||||
app.keyName += "\\Application";
|
||||
topic.keyName = keyName;
|
||||
topic.keyName += "\\Topic";
|
||||
}
|
||||
nsresult set();
|
||||
nsresult reset();
|
||||
SavedRegistryEntry activate, app, topic;
|
||||
};
|
||||
|
||||
// FileTypeRegistryEntry
|
||||
//
|
||||
// For setting entries relating to a file extension (or extensions).
|
||||
// This object itself is for the "file type" associated with the extension.
|
||||
// Set/reset manage the mapping from extension to the file type, as well.
|
||||
// The description is taken from defDescKey if available. Otherwise desc
|
||||
// is used.
|
||||
struct FileTypeRegistryEntry : public ProtocolRegistryEntry {
|
||||
nsCString fileType;
|
||||
const char **ext;
|
||||
nsCString desc;
|
||||
nsCString defDescKey;
|
||||
nsCString iconFile;
|
||||
FileTypeRegistryEntry ( const char **ext, const char *fileType,
|
||||
const char *desc, const char *defDescKey, const char *iconFile )
|
||||
: ProtocolRegistryEntry( fileType ),
|
||||
fileType( fileType ),
|
||||
ext( ext ),
|
||||
desc( desc ),
|
||||
defDescKey(defDescKey),
|
||||
iconFile(iconFile) {
|
||||
}
|
||||
nsresult set();
|
||||
nsresult reset();
|
||||
};
|
||||
|
||||
// EditableFileTypeRegistryEntry
|
||||
//
|
||||
// Extends FileTypeRegistryEntry by setting an additional handler for an "edit" command.
|
||||
struct EditableFileTypeRegistryEntry : public FileTypeRegistryEntry {
|
||||
EditableFileTypeRegistryEntry( const char **ext, const char *fileType,
|
||||
const char *desc, const char *defDescKey, const char *iconFile )
|
||||
: FileTypeRegistryEntry( ext, fileType, desc, defDescKey, iconFile ) {
|
||||
}
|
||||
nsresult set();
|
||||
};
|
||||
|
||||
// Generate the "full" name of this registry entry.
|
||||
nsCString RegistryEntry::fullName() const {
|
||||
nsCString result;
|
||||
|
||||
264
mozilla/xpfe/components/winhooks/nsWindowsHooksUtil.h
Normal file
264
mozilla/xpfe/components/winhooks/nsWindowsHooksUtil.h
Normal file
@@ -0,0 +1,264 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bill Law <law@netscape.com>
|
||||
* Dean Tessman <dean_tessman@hotmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// Where Mozilla stores its own registry values.
|
||||
const char * const mozillaKeyName = "Software\\Mozilla\\Desktop";
|
||||
|
||||
static const char shortcutSuffix[] = " -url \"%1\"";
|
||||
static const char chromeSuffix[] = " -chrome \"%1\"";
|
||||
static const char iconSuffix[] = ",0";
|
||||
|
||||
// Returns the (fully-qualified) name of this executable.
|
||||
static nsCString thisApplication() {
|
||||
static nsCAutoString result;
|
||||
|
||||
if ( result.IsEmpty() ) {
|
||||
char buffer[MAX_PATH] = { 0 };
|
||||
DWORD len = ::GetModuleFileName( NULL, buffer, sizeof buffer );
|
||||
len = ::GetShortPathName( buffer, buffer, sizeof buffer );
|
||||
|
||||
result = buffer;
|
||||
ToUpperCase(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns the "short" name of this application (in upper case). This is for
|
||||
// use as a StartMenuInternet value.
|
||||
static nsCString shortAppName() {
|
||||
static nsCAutoString result;
|
||||
|
||||
if ( result.IsEmpty() ) {
|
||||
// Find last backslash in thisApplication().
|
||||
nsCAutoString thisApp( thisApplication() );
|
||||
PRInt32 n = thisApp.RFind( "\\" );
|
||||
if ( n != kNotFound ) {
|
||||
// Use what comes after the last backslash.
|
||||
result = (const char*)thisApp.get() + n + 1;
|
||||
} else {
|
||||
// Use entire string.
|
||||
result = thisApp;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// RegistryEntry
|
||||
//
|
||||
// Generic registry entry (no saving of previous values). Each is comprised of:
|
||||
// o A base HKEY
|
||||
// o A subkey name.
|
||||
// o An optional value name (empty for the "default" value).
|
||||
// o The registry setting we'd like this entry to have when set.
|
||||
struct RegistryEntry {
|
||||
HKEY baseKey; // e.g., HKEY_CURRENT_USER
|
||||
PRBool isNull; // i.e., should use ::RegDeleteValue
|
||||
nsCString keyName; // Key name.
|
||||
nsCString valueName; // Value name (can be empty, which implies NULL).
|
||||
nsCString setting; // What we set it to (UTF-8). This had better be
|
||||
// nsString to avoid extra string copies, but
|
||||
// this code is not performance-critical.
|
||||
|
||||
RegistryEntry( HKEY baseKey, const char* keyName, const char* valueName, const char* setting )
|
||||
: baseKey( baseKey ), isNull( setting == 0 ), keyName( keyName ), valueName( valueName ), setting( setting ? setting : "" ) {
|
||||
}
|
||||
|
||||
PRBool isAlreadySet() const;
|
||||
nsresult set();
|
||||
nsresult reset();
|
||||
nsCString currentSetting( PRBool *currentUndefined = 0 ) const;
|
||||
|
||||
// Return value name in proper form for passing to ::Reg functions
|
||||
// (i.e., emptry string is converted to a NULL pointer).
|
||||
const char* valueNameArg() const {
|
||||
return valueName.IsEmpty() ? NULL : valueName.get();
|
||||
}
|
||||
|
||||
nsCString fullName() const;
|
||||
};
|
||||
|
||||
// BoolRegistryEntry
|
||||
//
|
||||
// These are used to store the "windows integration" preferences.
|
||||
// You can query the value via operator void* (i.e., if ( boolPref )... ).
|
||||
// These are stored under HKEY_LOCAL_MACHINE\Software\Mozilla\Desktop.
|
||||
// Set sets the stored value to "1". Reset deletes it (which implies 0).
|
||||
struct BoolRegistryEntry : public RegistryEntry {
|
||||
BoolRegistryEntry( const char *name )
|
||||
: RegistryEntry( HKEY_LOCAL_MACHINE, mozillaKeyName, name, "1" ) {
|
||||
}
|
||||
operator PRBool();
|
||||
};
|
||||
|
||||
// SavedRegistryEntry
|
||||
//
|
||||
// Like a plain RegistryEntry, but set/reset save/restore the
|
||||
// it had before we set it.
|
||||
struct SavedRegistryEntry : public RegistryEntry {
|
||||
SavedRegistryEntry( HKEY baseKey, const char *keyName, const char *valueName, const char *setting )
|
||||
: RegistryEntry( baseKey, keyName, valueName, setting ) {
|
||||
}
|
||||
nsresult set();
|
||||
nsresult reset();
|
||||
};
|
||||
|
||||
// ProtocolRegistryEntry
|
||||
//
|
||||
// For setting entries for a given Internet Shortcut protocol.
|
||||
// The key name is calculated as
|
||||
// HKEY_LOCAL_MACHINE\Software\Classes\protocol\shell\open\command.
|
||||
// The setting is this executable (with appropriate suffix).
|
||||
// Set/reset are trickier in this case.
|
||||
struct ProtocolRegistryEntry : public SavedRegistryEntry {
|
||||
nsCString protocol;
|
||||
ProtocolRegistryEntry( const char* protocol )
|
||||
: SavedRegistryEntry( HKEY_LOCAL_MACHINE, "", "", thisApplication().get() ),
|
||||
protocol( protocol ) {
|
||||
keyName = "Software\\Classes\\";
|
||||
keyName += protocol;
|
||||
keyName += "\\shell\\open\\command";
|
||||
|
||||
// Append appropriate suffix to setting.
|
||||
if ( this->protocol.Equals( "chrome" ) || this->protocol.Equals( "MozillaXUL" ) ) {
|
||||
// Use "-chrome" command line flag.
|
||||
setting += chromeSuffix;
|
||||
} else {
|
||||
// Use standard "-url" command line flag.
|
||||
setting += shortcutSuffix;
|
||||
}
|
||||
}
|
||||
nsresult set();
|
||||
nsresult reset();
|
||||
};
|
||||
|
||||
// ProtocolIconRegistryEntry
|
||||
//
|
||||
// For setting icon entries for a given Internet Shortcut protocol.
|
||||
// The key name is calculated as
|
||||
// HKEY_LOCAL_MACHINE\Software\Classes\protocol\DefaultIcon.
|
||||
// The setting is this executable (with appropriate suffix).
|
||||
struct ProtocolIconRegistryEntry : public SavedRegistryEntry {
|
||||
nsCString protocol;
|
||||
ProtocolIconRegistryEntry( const char* aprotocol )
|
||||
: SavedRegistryEntry( HKEY_LOCAL_MACHINE, "", "", thisApplication().get() ),
|
||||
protocol( aprotocol ) {
|
||||
keyName = NS_LITERAL_CSTRING("Software\\Classes\\") + protocol + NS_LITERAL_CSTRING("\\DefaultIcon");
|
||||
|
||||
// Append appropriate suffix to setting.
|
||||
setting += iconSuffix;
|
||||
}
|
||||
};
|
||||
|
||||
// DDERegistryEntry
|
||||
//
|
||||
// Like a protocol registry entry, but for the shell\open\ddeexec subkey.
|
||||
//
|
||||
// We need to remove this subkey entirely to ensure we work properly with
|
||||
// various programs on various platforms (see Bugzilla bugs 59078, 58770, etc.).
|
||||
//
|
||||
// We don't try to save everything, though. We do save the known useful info
|
||||
// under the ddeexec subkey:
|
||||
// ddeexec\@
|
||||
// ddeexec\NoActivateHandler
|
||||
// ddeexec\Application\@
|
||||
// ddeexec\Topic\@
|
||||
//
|
||||
// set/reset save/restore these values and remove/restore the ddeexec subkey
|
||||
struct DDERegistryEntry : public SavedRegistryEntry {
|
||||
DDERegistryEntry( const char *protocol )
|
||||
: SavedRegistryEntry( HKEY_LOCAL_MACHINE, "", "", 0 ),
|
||||
activate( HKEY_LOCAL_MACHINE, "", "NoActivateHandler", 0 ),
|
||||
app( HKEY_LOCAL_MACHINE, "", "", 0 ),
|
||||
topic( HKEY_LOCAL_MACHINE, "", "", 0 ) {
|
||||
// Derive keyName from protocol.
|
||||
keyName = "Software\\Classes\\";
|
||||
keyName += protocol;
|
||||
keyName += "\\shell\\open\\ddeexec";
|
||||
// Set subkey names.
|
||||
activate.keyName = keyName;
|
||||
app.keyName = keyName;
|
||||
app.keyName += "\\Application";
|
||||
topic.keyName = keyName;
|
||||
topic.keyName += "\\Topic";
|
||||
}
|
||||
nsresult set();
|
||||
nsresult reset();
|
||||
SavedRegistryEntry activate, app, topic;
|
||||
};
|
||||
|
||||
// FileTypeRegistryEntry
|
||||
//
|
||||
// For setting entries relating to a file extension (or extensions).
|
||||
// This object itself is for the "file type" associated with the extension.
|
||||
// Set/reset manage the mapping from extension to the file type, as well.
|
||||
// The description is taken from defDescKey if available. Otherwise desc
|
||||
// is used.
|
||||
struct FileTypeRegistryEntry : public ProtocolRegistryEntry {
|
||||
nsCString fileType;
|
||||
const char **ext;
|
||||
nsCString desc;
|
||||
nsCString defDescKey;
|
||||
nsCString iconFile;
|
||||
FileTypeRegistryEntry ( const char **ext, const char *fileType,
|
||||
const char *desc, const char *defDescKey, const char *iconFile )
|
||||
: ProtocolRegistryEntry( fileType ),
|
||||
fileType( fileType ),
|
||||
ext( ext ),
|
||||
desc( desc ),
|
||||
defDescKey(defDescKey),
|
||||
iconFile(iconFile) {
|
||||
}
|
||||
nsresult set();
|
||||
nsresult reset();
|
||||
};
|
||||
|
||||
// EditableFileTypeRegistryEntry
|
||||
//
|
||||
// Extends FileTypeRegistryEntry by setting an additional handler for an "edit" command.
|
||||
struct EditableFileTypeRegistryEntry : public FileTypeRegistryEntry {
|
||||
EditableFileTypeRegistryEntry( const char **ext, const char *fileType,
|
||||
const char *desc, const char *defDescKey, const char *iconFile )
|
||||
: FileTypeRegistryEntry( ext, fileType, desc, defDescKey, iconFile ) {
|
||||
}
|
||||
nsresult set();
|
||||
};
|
||||
Reference in New Issue
Block a user