mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 04:03:47 +00:00
New files for windows desktop integration (not built yet)
This commit is contained in:
parent
be759e1524
commit
4f65713bc1
60
xpfe/components/winhooks/makefile.win
Normal file
60
xpfe/components/winhooks/makefile.win
Normal file
@ -0,0 +1,60 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Bill Law <law@netscape.com>
|
||||
|
||||
MODULE=winhooks
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
XPIDL_MODULE=winhooks
|
||||
|
||||
XPIDLSRCS=\
|
||||
.\nsIWindowsHooks.idl \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
DLLNAME = winhooks
|
||||
DLL1NAME = winhooks
|
||||
PDBFILE = $(DLLNAME).pdb
|
||||
MAPFILE = $(DLLNAME).map
|
||||
DLL =.\$(OBJDIR)\$(DLLNAME).dll
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
|
||||
LINCS = \
|
||||
$(NULL)
|
||||
|
||||
LLIBS = \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(NULL)
|
||||
|
||||
OBJS = \
|
||||
.\$(OBJDIR)\nsWindowsHooks.obj \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin\components
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\bin\components\$(DLLNAME).dll
|
||||
|
139
xpfe/components/winhooks/nsIWindowsHooks.idl
Normal file
139
xpfe/components/winhooks/nsIWindowsHooks.idl
Normal file
@ -0,0 +1,139 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bill Law <law@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
|
||||
/* These interface provides support for integrating Mozilla into Windows.
|
||||
* This integration consists primarily of setting Mozilla as the "default
|
||||
* browser." Or more precisely, setting Mozilla as the executable to
|
||||
* handle certain file types.
|
||||
*
|
||||
* There are two subtly different types of desktop objects that Mozilla
|
||||
* can be configured to "handle:"
|
||||
* o File types (based on file extension)
|
||||
* o Internet shortcuts (based on URL protocol).
|
||||
*
|
||||
* While these are different types of objects, the mechanism by which
|
||||
* applications are matched with them is essentially the same.
|
||||
*
|
||||
* In the case of files, there is one more level of indirection. File
|
||||
* extensions are assigned a "file type" via a Windows registry entry.
|
||||
* For example, given the file extension ".foo", the file type is
|
||||
* determined by examing the value stored in the "default" value stored
|
||||
* at the registry key HEKY_LOCAL_MACHINE\Software\Classes\.foo.
|
||||
*
|
||||
* Once you have the "file type" then you use that the same way you use
|
||||
* Internet Shortcut protocol names to determine which application to
|
||||
* launch. The application is specified by the default value stored in
|
||||
* the registry key
|
||||
* HKEY_LOCAL_MACHINE\Software\Classes\<X>\shell\open\command, where
|
||||
* <X> is the "file type" or protocol name.
|
||||
*
|
||||
* If there are additional keys under "shell" then these appear on the
|
||||
* context menu for files/shortcuts of this type. Typically, there are
|
||||
* entries for "print." But Mozilla does not currently support a command
|
||||
* line option to print so we don't offer that.
|
||||
*
|
||||
* Previously, Netscape Communicator made itself the handler of standard
|
||||
* web things by creating a new file type "NetscapeMarkup" and mapping
|
||||
* extensions to that (.htm, .html, .shtml, .xbm), or, by setting itself
|
||||
* up as the "handler" for the file types of other web things (.jpg, .gif)
|
||||
* and Internet Shortcut protocols (ftp, gopher, http, https, mailto, news,
|
||||
* snews).
|
||||
*
|
||||
* In order to better enable Mozilla to co-exist with other browsers
|
||||
* (including Communicator), it will create yet another new file type,
|
||||
* "MozillaMarkup," that will be used to make Mozilla the default handler
|
||||
* for certain file extensions. This will be done by remapping those
|
||||
* extensions to this new type.
|
||||
*
|
||||
* Mozilla will attempt to remember the original mapping and restore it
|
||||
* when the user decides to no longer have Mozilla be the default handler
|
||||
* for that extension.
|
||||
*
|
||||
* Mozilla will drop support for some items that are no longer germane:
|
||||
* the .shtml file extension and the gopher: protocol. We will also, perhaps
|
||||
* only temporarily, drop support for protocols that aren't accessible from
|
||||
* the command line: mailto:, news:, and snews:.
|
||||
*
|
||||
* We will be adding support for the chrome: protocol (using the "-chrome"
|
||||
* command line option) and for .png, .xul and .xml file extensions.
|
||||
*
|
||||
* Missing Features:
|
||||
*
|
||||
* Currently, there is no way to extend the set of file types or protocols
|
||||
* that Mozilla can be associated with (save manually tweaking the Windows
|
||||
* registry). This is likely to be a problem for branded Mozilla browsers
|
||||
* that might support specialized file types or protocols (e.g., .aim files).
|
||||
*
|
||||
* The plan is to extend this interface so that such file types and protocols
|
||||
* can be set up using the implementation of the interfaces defined here.
|
||||
*/
|
||||
|
||||
/* nsIWindowsHooksSettings
|
||||
*
|
||||
* This interface is used to get/set the user preferences relating to
|
||||
* "windows hooks" (aka "windows integration"). It is basically just
|
||||
* a conglomeration of a bunch of boolean attributes; it exists mainly
|
||||
* for historical reasons (it corresponds to the internal Prefs struct
|
||||
* that was in nsIDefaultBrowser.h in Mozilla Classic).
|
||||
*/
|
||||
[scriptable, uuid(4ce9aa90-0a6a-11d4-8076-00600811a9c3)]
|
||||
interface nsIWindowsHooksSettings : nsISupports {
|
||||
|
||||
// Internet shortcuts (based on "protocol").
|
||||
attribute boolean isHandlingHTTP;
|
||||
attribute boolean isHandlingHTTPS;
|
||||
attribute boolean isHandlingFTP;
|
||||
attribute boolean isHandlingCHROME;
|
||||
|
||||
// File handling (based on extension).
|
||||
attribute boolean isHandlingHTML;
|
||||
attribute boolean isHandlingJPEG;
|
||||
attribute boolean isHandlingGIF;
|
||||
attribute boolean isHandlingPNG;
|
||||
attribute boolean isHandlingXML;
|
||||
attribute boolean isHandlingXUL;
|
||||
|
||||
};
|
||||
|
||||
/* nsIWindowsHooks
|
||||
*
|
||||
* This interface describes the service that you can use to
|
||||
* get/set the various windows integration features specified
|
||||
* by the nsIWindowsHooksPrefs attributes.
|
||||
*/
|
||||
[scriptable, uuid(19c9fbb0-06a3-11d4-8076-00600811a9c3)]
|
||||
interface nsIWindowsHooks : nsISupports {
|
||||
|
||||
// Settings. Get/set this to query or modify them. The Windows
|
||||
// registry is updated when you set this attribute.
|
||||
attribute nsIWindowsHooksSettings settings;
|
||||
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_IWINDOWSHOOKS_PROGID "component://mozilla/winhooks"
|
||||
#define NS_IWINDOWSHOOKS_CLASSNAME "Mozilla Windows Integration Hooks"
|
||||
%}
|
382
xpfe/components/winhooks/nsWindowsHooks.cpp
Normal file
382
xpfe/components/winhooks/nsWindowsHooks.cpp
Normal file
@ -0,0 +1,382 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bill Law <law@netscape.com>
|
||||
*/
|
||||
#include "nsIWindowsHooks.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// Implementation utilities.
|
||||
#include "nsWindowsHooksUtil.cpp"
|
||||
|
||||
// Objects that describe the Windows registry entries that we need to tweak.
|
||||
static ProtocolRegistryEntry
|
||||
http( "http" ),
|
||||
https( "https" ),
|
||||
ftp( "ftp" ),
|
||||
chrome( "chrome" );
|
||||
|
||||
const char *jpgExts[] = { ".jpg", ".jpeg", 0 };
|
||||
const char *gifExts[] = { ".gif", 0 };
|
||||
const char *pngExts[] = { ".png", 0 };
|
||||
const char *xmlExts[] = { ".xml", 0 };
|
||||
const char *xulExts[] = { ".xul", 0 };
|
||||
const char *htmExts[] = { ".htm", ".html", 0 };
|
||||
|
||||
static FileTypeRegistryEntry
|
||||
jpg( jpgExts, "MozillaJPEG", "Mozilla JPEG Image File" ),
|
||||
gif( gifExts, "MozillaGIF", "Mozilla GIF Image File" ),
|
||||
png( pngExts, "MozillaPNG", "Mozilla Portable Network Graphic Image File" ),
|
||||
xml( xmlExts, "MozillaXML", "Mozilla Extensible Markup Language Document" ),
|
||||
xul( xulExts, "MozillaXUL", "Mozilla Extensible User-interface Language Document" );
|
||||
|
||||
static EditableFileTypeRegistryEntry
|
||||
mozillaMarkup( htmExts, "MozillaHTML", "Mozilla Hypertext Markup Language Document" );
|
||||
|
||||
|
||||
/* c09bc130-0a71-11d4-8076-00600811a9c3 */
|
||||
#define NS_IWINDOWSHOOKS_CID \
|
||||
{ 0xc09bc130, 0x0a71, 0x11d4, {0x80, 0x76, 0x00, 0x60, 0x08, 0x11, 0xa9, 0xc3} }
|
||||
|
||||
// Implementation of the nsIWindowsHooksSettings interface.
|
||||
class nsWindowsHooksSettings : public nsIWindowsHooksSettings {
|
||||
public:
|
||||
// ctor/dtor
|
||||
nsWindowsHooksSettings();
|
||||
virtual ~nsWindowsHooksSettings();
|
||||
|
||||
// Declare all interface methods we must implement.
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWINDOWSHOOKSSETTINGS
|
||||
|
||||
// Typedef for nsIWindowsHooksSettings getter/setter member functions.
|
||||
typedef nsresult (__stdcall nsIWindowsHooksSettings::*getter)( PRBool* );
|
||||
typedef nsresult (__stdcall nsIWindowsHooksSettings::*setter)( PRBool );
|
||||
|
||||
protected:
|
||||
// General purpose getter.
|
||||
NS_IMETHOD Get( PRBool *result, PRBool nsWindowsHooksSettings::*member );
|
||||
// General purpose setter.
|
||||
NS_IMETHOD Set( PRBool value, PRBool nsWindowsHooksSettings::*member );
|
||||
|
||||
private:
|
||||
// Internet shortcut protocols.
|
||||
struct {
|
||||
PRBool mHandleHTTP;
|
||||
PRBool mHandleHTTPS;
|
||||
PRBool mHandleFTP;
|
||||
PRBool mHandleCHROME;
|
||||
};
|
||||
// File types.
|
||||
struct {
|
||||
PRBool mHandleHTML;
|
||||
PRBool mHandleJPEG;
|
||||
PRBool mHandleGIF;
|
||||
PRBool mHandlePNG;
|
||||
PRBool mHandleXML;
|
||||
PRBool mHandleXUL;
|
||||
};
|
||||
friend class nsWindowsHooks;
|
||||
}; // nsWindowsHooksSettings
|
||||
|
||||
// Use standard implementation of nsISupports stuff.
|
||||
NS_IMPL_ISUPPORTS1( nsWindowsHooksSettings, nsIWindowsHooksSettings );
|
||||
|
||||
nsWindowsHooksSettings::nsWindowsHooksSettings() {
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsWindowsHooksSettings::~nsWindowsHooksSettings() {
|
||||
}
|
||||
|
||||
// Generic getter.
|
||||
NS_IMETHODIMP
|
||||
nsWindowsHooksSettings::Get( PRBool *result, PRBool nsWindowsHooksSettings::*member ) {
|
||||
NS_ENSURE_ARG( result );
|
||||
NS_ENSURE_ARG( member );
|
||||
*result = this->*member;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Generic setter.
|
||||
NS_IMETHODIMP
|
||||
nsWindowsHooksSettings::Set( PRBool value, PRBool nsWindowsHooksSettings::*member ) {
|
||||
NS_ENSURE_ARG( member );
|
||||
this->*member = value;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Macros to define specific getter/setter methods.
|
||||
#define DEFINE_GETTER_AND_SETTER( attr, member ) \
|
||||
NS_IMETHODIMP \
|
||||
nsWindowsHooksSettings::Get##attr ( PRBool *result ) { \
|
||||
return this->Get( result, &nsWindowsHooksSettings::member ); \
|
||||
} \
|
||||
NS_IMETHODIMP \
|
||||
nsWindowsHooksSettings::Set##attr ( PRBool value ) { \
|
||||
return this->Set( value, &nsWindowsHooksSettings::member ); \
|
||||
}
|
||||
|
||||
// Define all the getter/setter methods:
|
||||
DEFINE_GETTER_AND_SETTER( IsHandlingHTML, mHandleHTML )
|
||||
DEFINE_GETTER_AND_SETTER( IsHandlingJPEG, mHandleJPEG )
|
||||
DEFINE_GETTER_AND_SETTER( IsHandlingGIF, mHandleGIF )
|
||||
DEFINE_GETTER_AND_SETTER( IsHandlingPNG, mHandlePNG )
|
||||
DEFINE_GETTER_AND_SETTER( IsHandlingXML, mHandleXML )
|
||||
DEFINE_GETTER_AND_SETTER( IsHandlingXUL, mHandleXUL )
|
||||
DEFINE_GETTER_AND_SETTER( IsHandlingHTTP, mHandleHTTP )
|
||||
DEFINE_GETTER_AND_SETTER( IsHandlingHTTPS, mHandleHTTPS )
|
||||
DEFINE_GETTER_AND_SETTER( IsHandlingFTP, mHandleFTP )
|
||||
DEFINE_GETTER_AND_SETTER( IsHandlingCHROME, mHandleCHROME )
|
||||
|
||||
|
||||
// Implementation of the nsIWindowsHooks interface.
|
||||
class nsWindowsHooks : public nsIWindowsHooks {
|
||||
public:
|
||||
// ctor/dtor
|
||||
nsWindowsHooks();
|
||||
virtual ~nsWindowsHooks();
|
||||
|
||||
// Declare all interface methods we must implement.
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWINDOWSHOOKS
|
||||
|
||||
protected:
|
||||
// Internal flavor of GetPreferences.
|
||||
NS_IMETHOD GetSettings( nsWindowsHooksSettings ** );
|
||||
|
||||
// Set registry according to settings.
|
||||
NS_IMETHOD SetRegistry();
|
||||
|
||||
private:
|
||||
// Module stuff.
|
||||
static NS_METHOD CreateWindowsHooks( nsISupports *aOuter,
|
||||
REFNSIID aIID,
|
||||
void **aResult );
|
||||
static nsWindowsHooks *mInstance;
|
||||
|
||||
public:
|
||||
static nsModuleComponentInfo components[];
|
||||
}; // nsWindowsHooksSettings
|
||||
|
||||
// Use standard implementation of nsISupports stuff.
|
||||
NS_IMPL_ISUPPORTS1( nsWindowsHooks, nsIWindowsHooks );
|
||||
|
||||
nsWindowsHooks::nsWindowsHooks() {
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsWindowsHooks::~nsWindowsHooks() {
|
||||
}
|
||||
|
||||
// Internal GetPreferences.
|
||||
NS_IMETHODIMP
|
||||
nsWindowsHooks::GetSettings( nsWindowsHooksSettings **result ) {
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Validate input arg.
|
||||
NS_ENSURE_ARG( result );
|
||||
|
||||
// Allocate prefs object.
|
||||
nsWindowsHooksSettings *prefs = *result = new nsWindowsHooksSettings;
|
||||
NS_ENSURE_TRUE( prefs, NS_ERROR_OUT_OF_MEMORY );
|
||||
|
||||
// Got it, increment ref count.
|
||||
NS_ADDREF( prefs );
|
||||
|
||||
// Get each registry value and copy to prefs structure.
|
||||
prefs->mHandleHTTP = (void*)( BoolRegistryEntry( "isHandlingHTTP" ) ) ? PR_TRUE : PR_FALSE;
|
||||
prefs->mHandleHTTPS = (void*)( BoolRegistryEntry( "isHandlingHTTPS" ) ) ? PR_TRUE : PR_FALSE;
|
||||
prefs->mHandleFTP = (void*)( BoolRegistryEntry( "isHandlingFTP" ) ) ? PR_TRUE : PR_FALSE;
|
||||
prefs->mHandleCHROME = (void*)( BoolRegistryEntry( "isHandlingCHROME" ) ) ? PR_TRUE : PR_FALSE;
|
||||
prefs->mHandleHTML = (void*)( BoolRegistryEntry( "isHandlingHTML" ) ) ? PR_TRUE : PR_FALSE;
|
||||
prefs->mHandleJPEG = (void*)( BoolRegistryEntry( "isHandlingJPEG" ) ) ? PR_TRUE : PR_FALSE;
|
||||
prefs->mHandleGIF = (void*)( BoolRegistryEntry( "isHandlingGIF" ) ) ? PR_TRUE : PR_FALSE;
|
||||
prefs->mHandlePNG = (void*)( BoolRegistryEntry( "isHandlingPNG" ) ) ? PR_TRUE : PR_FALSE;
|
||||
prefs->mHandleXML = (void*)( BoolRegistryEntry( "isHandlingXML" ) ) ? PR_TRUE : PR_FALSE;
|
||||
prefs->mHandleXUL = (void*)( BoolRegistryEntry( "isHandlingXUL" ) ) ? PR_TRUE : PR_FALSE;
|
||||
|
||||
#ifdef DEBUG_law
|
||||
NS_WARN_IF_FALSE( NS_SUCCEEDED( rv ), "GetPreferences failed" );
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Public interface uses internal plus a QI to get to the proper result.
|
||||
NS_IMETHODIMP
|
||||
nsWindowsHooks::GetSettings( nsIWindowsHooksSettings **_retval ) {
|
||||
// Allocate prefs object.
|
||||
nsWindowsHooksSettings *prefs;
|
||||
nsresult rv = this->GetSettings( &prefs );
|
||||
|
||||
if ( NS_SUCCEEDED( rv ) ) {
|
||||
// QI to proper interface.
|
||||
rv = prefs->QueryInterface( NS_GET_IID( nsIWindowsHooksSettings ), (void**)_retval );
|
||||
// Release (to undo our Get...).
|
||||
NS_RELEASE( prefs );
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Utility to set PRBool registry value from getter method.
|
||||
nsresult putPRBoolIntoRegistry( const char* valueName,
|
||||
nsIWindowsHooksSettings *prefs,
|
||||
nsWindowsHooksSettings::getter memFun ) {
|
||||
// Use getter method to extract attribute from prefs.
|
||||
PRBool boolValue;
|
||||
(void)(prefs->*memFun)( &boolValue );
|
||||
// Convert to DWORD.
|
||||
DWORD dwordValue = boolValue;
|
||||
// Store into registry.
|
||||
BoolRegistryEntry pref( valueName );
|
||||
nsresult rv = boolValue ? pref.set() : pref.reset();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* void setPreferences (in nsIWindowsHooksSettings prefs); */
|
||||
NS_IMETHODIMP
|
||||
nsWindowsHooks::SetSettings(nsIWindowsHooksSettings *prefs) {
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
putPRBoolIntoRegistry( "isHandlingHTTP", prefs, &nsIWindowsHooksSettings::GetIsHandlingHTTP );
|
||||
putPRBoolIntoRegistry( "isHandlingHTTPS", prefs, &nsIWindowsHooksSettings::GetIsHandlingHTTPS );
|
||||
putPRBoolIntoRegistry( "isHandlingFTP", prefs, &nsIWindowsHooksSettings::GetIsHandlingFTP );
|
||||
putPRBoolIntoRegistry( "isHandlingCHROME", prefs, &nsIWindowsHooksSettings::GetIsHandlingCHROME );
|
||||
putPRBoolIntoRegistry( "isHandlingHTML", prefs, &nsIWindowsHooksSettings::GetIsHandlingHTML );
|
||||
putPRBoolIntoRegistry( "isHandlingJPEG", prefs, &nsIWindowsHooksSettings::GetIsHandlingJPEG );
|
||||
putPRBoolIntoRegistry( "isHandlingGIF", prefs, &nsIWindowsHooksSettings::GetIsHandlingGIF );
|
||||
putPRBoolIntoRegistry( "isHandlingPNG", prefs, &nsIWindowsHooksSettings::GetIsHandlingPNG );
|
||||
putPRBoolIntoRegistry( "isHandlingXML", prefs, &nsIWindowsHooksSettings::GetIsHandlingXML );
|
||||
putPRBoolIntoRegistry( "isHandlingXUL", prefs, &nsIWindowsHooksSettings::GetIsHandlingXUL );
|
||||
|
||||
rv = SetRegistry();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Get preferences and start handling everything selected.
|
||||
NS_IMETHODIMP
|
||||
nsWindowsHooks::SetRegistry() {
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Get raw prefs object.
|
||||
nsWindowsHooksSettings *prefs;
|
||||
rv = this->GetSettings( &prefs );
|
||||
|
||||
NS_ENSURE_TRUE( NS_SUCCEEDED( rv ), rv );
|
||||
|
||||
if ( prefs->mHandleHTML ) {
|
||||
(void) mozillaMarkup.set();
|
||||
} else {
|
||||
(void) mozillaMarkup.reset();
|
||||
}
|
||||
if ( prefs->mHandleJPEG ) {
|
||||
(void) jpg.set();
|
||||
} else {
|
||||
(void) jpg.reset();
|
||||
}
|
||||
if ( prefs->mHandleGIF ) {
|
||||
(void) gif.set();
|
||||
} else {
|
||||
(void) gif.reset();
|
||||
}
|
||||
if ( prefs->mHandlePNG ) {
|
||||
(void) png.set();
|
||||
} else {
|
||||
(void) png.reset();
|
||||
}
|
||||
if ( prefs->mHandleXML ) {
|
||||
(void) xml.set();
|
||||
} else {
|
||||
(void) xml.reset();
|
||||
}
|
||||
if ( prefs->mHandleXUL ) {
|
||||
(void) xul.set();
|
||||
} else {
|
||||
(void) xul.reset();
|
||||
}
|
||||
if ( prefs->mHandleHTTP ) {
|
||||
(void) http.set();
|
||||
} else {
|
||||
(void) http.reset();
|
||||
}
|
||||
if ( prefs->mHandleHTTPS ) {
|
||||
(void) https.set();
|
||||
} else {
|
||||
(void) https.reset();
|
||||
}
|
||||
if ( prefs->mHandleFTP ) {
|
||||
(void) ftp.set();
|
||||
} else {
|
||||
(void) ftp.reset();
|
||||
}
|
||||
if ( prefs->mHandleCHROME ) {
|
||||
(void) ftp.set();
|
||||
} else {
|
||||
(void) ftp.reset();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowsHooks::CreateWindowsHooks( nsISupports *aOuter,
|
||||
REFNSIID aIID,
|
||||
void **aResult ) {
|
||||
if ( !aResult ) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
if ( aOuter ) {
|
||||
*aResult = nsnull;
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
|
||||
if (mInstance == nsnull) {
|
||||
mInstance = new nsWindowsHooks();
|
||||
}
|
||||
|
||||
if ( mInstance == nsnull )
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = mInstance->QueryInterface( aIID, aResult );
|
||||
if ( NS_FAILED(rv) ) {
|
||||
*aResult = nsnull;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsWindowsHooks* nsWindowsHooks::mInstance = nsnull;
|
||||
|
||||
nsModuleComponentInfo nsWindowsHooks::components[] = {
|
||||
{ NS_IWINDOWSHOOKS_CLASSNAME,
|
||||
NS_IWINDOWSHOOKS_CID,
|
||||
NS_IWINDOWSHOOKS_PROGID,
|
||||
nsWindowsHooks::CreateWindowsHooks },
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE( "nsWindowsHooks", nsWindowsHooks::components )
|
||||
|
442
xpfe/components/winhooks/nsWindowsHooksUtil.cpp
Normal file
442
xpfe/components/winhooks/nsWindowsHooksUtil.cpp
Normal file
@ -0,0 +1,442 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bill Law <law@netscape.com>
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <string.h>
|
||||
#include "nsString.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\"";
|
||||
|
||||
// Returns the (fully-qualified) name of this executable.
|
||||
static nsCString thisApplication() {
|
||||
static nsCString result;
|
||||
|
||||
if ( result.IsEmpty() ) {
|
||||
char buffer[MAX_PATH] = { 0 };
|
||||
DWORD len = ::GetModuleFileName( NULL, buffer, sizeof buffer );
|
||||
len = ::GetShortPathName( buffer, buffer, sizeof buffer );
|
||||
|
||||
result = buffer;
|
||||
result.ToUpperCase();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns this
|
||||
|
||||
// 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
|
||||
nsCString keyName; // Key name.
|
||||
nsCString valueName; // Value name (can be empty, which implies NULL).
|
||||
nsCString setting; // What we set it to.
|
||||
|
||||
RegistryEntry( HKEY baseKey, const char* keyName, const char* valueName, const char* setting )
|
||||
: baseKey( baseKey ), keyName( keyName ), valueName( valueName ), setting( setting ) {
|
||||
}
|
||||
|
||||
PRBool isAlreadySet() const;
|
||||
nsresult set();
|
||||
nsresult reset();
|
||||
nsCString currentSetting() 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.GetBuffer();
|
||||
}
|
||||
|
||||
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 void*();
|
||||
};
|
||||
|
||||
// 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() ),
|
||||
protocol( protocol ) {
|
||||
keyName = "Software\\Classes\\";
|
||||
keyName += protocol;
|
||||
keyName += "\\shell\\open\\command";
|
||||
|
||||
// Append appropriate suffix to setting.
|
||||
if ( protocol == "chrome" ) {
|
||||
// Use "-chrome" command line flag.
|
||||
setting += chromeSuffix;
|
||||
} else {
|
||||
// Use standard "-url" command line flag.
|
||||
setting += shortcutSuffix;
|
||||
}
|
||||
}
|
||||
nsresult set();
|
||||
nsresult reset();
|
||||
};
|
||||
|
||||
// DDERegistryEntry
|
||||
//
|
||||
// Like a protocol registry entry, but for the shell\open\ddeexec subkey.
|
||||
// We don't need to do anything special for set/reset, either.
|
||||
struct DDERegistryEntry : public SavedRegistryEntry {
|
||||
DDERegistryEntry( const char *protocol )
|
||||
: SavedRegistryEntry( HKEY_LOCAL_MACHINE, "", "", thisApplication() ) {
|
||||
keyName = "Software\\Classes\\";
|
||||
keyName += protocol;
|
||||
keyName += "\\shell\\open\\ddeexec";
|
||||
}
|
||||
};
|
||||
|
||||
// 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.
|
||||
struct FileTypeRegistryEntry : public ProtocolRegistryEntry {
|
||||
nsCString fileType;
|
||||
const char **ext;
|
||||
nsCString desc;
|
||||
FileTypeRegistryEntry ( const char **ext, const char *fileType, const char *desc )
|
||||
: ProtocolRegistryEntry( fileType ),
|
||||
fileType( fileType ),
|
||||
ext( ext ),
|
||||
desc( desc ) {
|
||||
}
|
||||
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 )
|
||||
: FileTypeRegistryEntry( ext, fileType, desc ) {
|
||||
}
|
||||
nsresult set();
|
||||
};
|
||||
|
||||
// Generate the "full" name of this registry entry.
|
||||
nsCString RegistryEntry::fullName() const {
|
||||
nsCString result;
|
||||
if ( baseKey == HKEY_CURRENT_USER ) {
|
||||
result = "HKEY_CURRENT_USER\\";
|
||||
} else if ( baseKey == HKEY_LOCAL_MACHINE ) {
|
||||
result = "HKEY_LOCAL_MACHINE\\";
|
||||
} else {
|
||||
result = "\\";
|
||||
}
|
||||
result += keyName;
|
||||
if ( !valueName.IsEmpty() ) {
|
||||
result += "[";
|
||||
result += valueName;
|
||||
result += "]";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Tests whether registry entry already has desired setting.
|
||||
PRBool RegistryEntry::isAlreadySet() const {
|
||||
PRBool result = FALSE;
|
||||
|
||||
nsCString current = currentSetting();
|
||||
|
||||
result = ( current == setting );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Gives registry entry the desired setting.
|
||||
nsresult RegistryEntry::set() {
|
||||
#ifdef DEBUG_law
|
||||
printf( "Setting %s=%s\n", (const char*)fullName(), (const char*)setting );
|
||||
#endif
|
||||
nsresult result = NS_ERROR_FAILURE;
|
||||
|
||||
HKEY key;
|
||||
LONG rc = ::RegOpenKey( baseKey, keyName, &key );
|
||||
|
||||
// See if key doesn't exist yet...
|
||||
if ( rc == ERROR_FILE_NOT_FOUND ) {
|
||||
rc = ::RegCreateKey( baseKey, keyName, &key );
|
||||
}
|
||||
if ( rc == ERROR_SUCCESS ) {
|
||||
char buffer[4096] = { 0 };
|
||||
DWORD len = sizeof buffer;
|
||||
rc = ::RegQueryValueEx( key, valueNameArg(), NULL, NULL, (LPBYTE)buffer, &len );
|
||||
if ( strcmp( setting, buffer ) != 0 ) {
|
||||
rc = ::RegSetValueEx( key, valueNameArg(), NULL, REG_SZ, (LPBYTE)(const char*)setting, strlen(setting) );
|
||||
#ifdef DEBUG_law
|
||||
NS_WARN_IF_FALSE( rc == ERROR_SUCCESS, (const char*)fullName() );
|
||||
#endif
|
||||
if ( rc == ERROR_SUCCESS ) {
|
||||
result = NS_OK;
|
||||
}
|
||||
} else {
|
||||
// Already has desired setting.
|
||||
result = NS_OK;
|
||||
}
|
||||
::RegCloseKey( key );
|
||||
} else {
|
||||
#ifdef DEBUG_law
|
||||
NS_WARN_IF_FALSE( rc == ERROR_SUCCESS, (const char*)fullName() );
|
||||
#endif
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get current setting, set new one, then save the previous.
|
||||
nsresult SavedRegistryEntry::set() {
|
||||
nsresult rv = NS_OK;
|
||||
nsCString prev = currentSetting();
|
||||
// See if value is changing.
|
||||
if ( setting != prev ) {
|
||||
// Set new.
|
||||
rv = RegistryEntry::set();
|
||||
if ( NS_SUCCEEDED( rv ) ) {
|
||||
// Save old.
|
||||
RegistryEntry( HKEY_LOCAL_MACHINE, "Software\\Mozilla\\Desktop", fullName(), prev ).set();
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Set this entry and its corresponding DDE entry. The DDE entry
|
||||
// must be turned off to stop Windows from trying to use DDE.
|
||||
nsresult ProtocolRegistryEntry::set() {
|
||||
// Set this entry.
|
||||
nsresult rv = SavedRegistryEntry::set();
|
||||
|
||||
// Save and set corresponding DDE entry. This stops Windows from trying to use
|
||||
// DDE (and getting an error).
|
||||
nsCString ddeName = "Software\\Classes\\";
|
||||
ddeName += protocol;
|
||||
ddeName += "\\shell\\open\\ddeexec";
|
||||
SavedRegistryEntry( HKEY_LOCAL_MACHINE, ddeName, NULL, NULL ).set();
|
||||
|
||||
// Special case.
|
||||
if ( protocol = "http" ) {
|
||||
// We need to zap HKR\Software\Classes\http\shell\open\ddeexec\Application
|
||||
// because Communicator looks there to determine whether they're the
|
||||
// "default browser." If they are (the value there is "NSShell" or "Netscape")
|
||||
// then it will reset lots of registry entries, "stealing" them from us.
|
||||
SavedRegistryEntry special( HKEY_LOCAL_MACHINE, "Software\\Classes\\http\\shell\\open\\ddeexec\\Application", NULL, NULL );
|
||||
nsCString specialVal = special.currentSetting();
|
||||
if ( specialVal == "NSShell" || specialVal == "Netscape" ) {
|
||||
// Reset this so Communicator will at least prompt the user.
|
||||
special.set();
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Not being a "saved" entry, we can't restore, so just delete it.
|
||||
nsresult RegistryEntry::reset() {
|
||||
HKEY key;
|
||||
LONG rc = ::RegOpenKey( baseKey, keyName, &key );
|
||||
if ( rc == ERROR_SUCCESS ) {
|
||||
rc = ::RegDeleteValue( key, valueNameArg() );
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Resets registry entry to the saved value (if there is one). We first
|
||||
// ensure that we still "own" that entry (by comparing its value to what
|
||||
// we would set it to).
|
||||
nsresult SavedRegistryEntry::reset() {
|
||||
nsresult result = NS_OK;
|
||||
|
||||
// Get current setting for this key/value.
|
||||
nsCString current = currentSetting();
|
||||
|
||||
// Test if we "own" it.
|
||||
if ( current == setting ) {
|
||||
// Unset it, then. First get saved value it had previously.
|
||||
RegistryEntry saved = RegistryEntry( HKEY_LOCAL_MACHINE, mozillaKeyName, fullName(), "" );
|
||||
saved.setting = saved.currentSetting();
|
||||
if ( !saved.setting.IsEmpty() ) {
|
||||
// Set to previous value.
|
||||
setting = saved.setting;
|
||||
result = RegistryEntry::set();
|
||||
// Remove saved entry.
|
||||
saved.reset();
|
||||
} else {
|
||||
// Just delete this key/value.
|
||||
result = RegistryEntry::reset();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Restore this entry and corresponding DDE entry.
|
||||
nsresult ProtocolRegistryEntry::reset() {
|
||||
// Restore this entry.
|
||||
nsresult rv = SavedRegistryEntry::reset();
|
||||
|
||||
// Do same for corresponding DDE entry (which we had to zap to stop DDE).
|
||||
DDERegistryEntry( protocol ).reset();
|
||||
|
||||
// Special case.
|
||||
if ( protocol = "http" ) {
|
||||
// We had to zap HKR\Software\Classes\http\shell\open\ddeexec\Application
|
||||
// (see comment above under ProtocolRegistryEntry::set). Restore it here.
|
||||
SavedRegistryEntry( HKEY_LOCAL_MACHINE, "Software\\Classes\\http\\shell\\open\\ddeexec\\Application", NULL, NULL ).reset();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Return current setting for this registry entry.
|
||||
nsCString RegistryEntry::currentSetting() const {
|
||||
nsCString result;
|
||||
|
||||
HKEY key;
|
||||
LONG rc = ::RegOpenKey( baseKey, keyName, &key );
|
||||
if ( rc == ERROR_SUCCESS ) {
|
||||
char buffer[4096];
|
||||
DWORD len = sizeof buffer;
|
||||
rc = ::RegQueryValueEx( key, valueNameArg(), NULL, NULL, (LPBYTE)buffer, &len );
|
||||
if ( rc == ERROR_SUCCESS ) {
|
||||
result = buffer;
|
||||
}
|
||||
::RegCloseKey( key );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// For each file extension, map it to this entry's file type.
|
||||
// Set the file type so this application opens files of that type.
|
||||
nsresult FileTypeRegistryEntry::set() {
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Set file extensions.
|
||||
for ( int i = 0; NS_SUCCEEDED( rv ) && ext[i]; i++ ) {
|
||||
nsCString thisExt = "Software\\Classes\\";
|
||||
thisExt += ext[i];
|
||||
rv = SavedRegistryEntry( HKEY_LOCAL_MACHINE, thisExt, "", fileType ).set();
|
||||
}
|
||||
|
||||
// If OK, set file type opener.
|
||||
if ( NS_SUCCEEDED( rv ) ) {
|
||||
rv = ProtocolRegistryEntry::set();
|
||||
|
||||
// If we just created this file type entry, set description and default icon.
|
||||
if ( NS_SUCCEEDED( rv ) ) {
|
||||
nsCString descKey = "Software\\Classes\\";
|
||||
descKey += protocol;
|
||||
RegistryEntry descEntry( HKEY_LOCAL_MACHINE, descKey, NULL, desc );
|
||||
if ( descEntry.currentSetting().IsEmpty() ) {
|
||||
descEntry.set();
|
||||
}
|
||||
nsCString iconKey = "Software\\Classes\\";
|
||||
iconKey += protocol;
|
||||
iconKey += "\\DefaultIcon";
|
||||
RegistryEntry iconEntry( HKEY_LOCAL_MACHINE, iconKey, NULL, thisApplication()+",1" );
|
||||
if ( iconEntry.currentSetting().IsEmpty() ) {
|
||||
iconEntry.set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Basically, the inverse of set().
|
||||
// First, reset the opener for this entry's file type.
|
||||
// Then, reset the file type associated with each extension.
|
||||
nsresult FileTypeRegistryEntry::reset() {
|
||||
nsresult rv = ProtocolRegistryEntry::reset();
|
||||
|
||||
for ( int i = 0; ext[ i ]; i++ ) {
|
||||
nsCString thisExt = "Software\\Classes\\";
|
||||
thisExt += ext[i];
|
||||
(void)SavedRegistryEntry( HKEY_LOCAL_MACHINE, thisExt, "", fileType ).reset();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Do inherited set() and also set key for edit (with -edit option).
|
||||
//
|
||||
// Note: We make the rash assumption that we "own" this filetype (aka "protocol").
|
||||
// If we ever start commandeering some other file type then this may have to be
|
||||
// rethought. The solution is to override reset() and undo this (and make the
|
||||
// "edit" entry a SavedRegistryEntry).
|
||||
nsresult EditableFileTypeRegistryEntry::set() {
|
||||
nsresult rv = FileTypeRegistryEntry::set();
|
||||
if ( NS_SUCCEEDED( rv ) ) {
|
||||
nsCString editKey = "Software\\Classes\\";
|
||||
editKey += protocol;
|
||||
editKey += "\\shell\\edit\\command";
|
||||
nsCString editor = thisApplication();
|
||||
editor += " -edit \"%1\"";
|
||||
rv = RegistryEntry( HKEY_LOCAL_MACHINE, editKey, "", editor ).set();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Convert current registry setting to boolean.
|
||||
BoolRegistryEntry::operator void*() {
|
||||
return (void*)( currentSetting() == "1" ? PR_TRUE : PR_FALSE );
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user