mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-10-06 03:20:10 +02:00
919 lines
23 KiB
C++
919 lines
23 KiB
C++
|
/* -*- 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):
|
||
|
*
|
||
|
* 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 "nsWinReg.h"
|
||
|
#include "nsWinRegItem.h"
|
||
|
#include "nsNativeCharsetUtils.h"
|
||
|
#include <windows.h>
|
||
|
|
||
|
|
||
|
/* Public Methods */
|
||
|
|
||
|
MOZ_DECL_CTOR_COUNTER(nsWinReg)
|
||
|
|
||
|
nsWinReg::nsWinReg(nsInstall* suObj)
|
||
|
{
|
||
|
MOZ_COUNT_CTOR(nsWinReg);
|
||
|
|
||
|
mInstallObject = suObj;
|
||
|
mRootKey = (PRInt32)HKEY_CLASSES_ROOT;
|
||
|
}
|
||
|
|
||
|
nsWinReg::~nsWinReg()
|
||
|
{
|
||
|
MOZ_COUNT_DTOR(nsWinReg);
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::SetRootKey(PRInt32 key)
|
||
|
{
|
||
|
mRootKey = key;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::CreateKey(const nsAString& subkey, const nsAString& classname, PRInt32* aReturn)
|
||
|
{
|
||
|
nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_CREATE, subkey, classname, NS_LITERAL_STRING("null"), aReturn);
|
||
|
|
||
|
if(wi == nsnull)
|
||
|
{
|
||
|
*aReturn = nsInstall::OUT_OF_MEMORY;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
if(*aReturn != nsInstall::SUCCESS)
|
||
|
{
|
||
|
if(wi)
|
||
|
{
|
||
|
delete wi;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(mInstallObject)
|
||
|
*aReturn = mInstallObject->ScheduleForInstall(wi);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::DeleteKey(const nsAString& subkey, PRInt32* aReturn)
|
||
|
{
|
||
|
nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_DELETE, subkey, NS_LITERAL_STRING("null"), NS_LITERAL_STRING("null"), aReturn);
|
||
|
|
||
|
if(wi == nsnull)
|
||
|
{
|
||
|
*aReturn = nsInstall::OUT_OF_MEMORY;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
if(*aReturn != nsInstall::SUCCESS)
|
||
|
{
|
||
|
if(wi)
|
||
|
{
|
||
|
delete wi;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(mInstallObject)
|
||
|
*aReturn = mInstallObject->ScheduleForInstall(wi);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::DeleteValue(const nsAString& subkey, const nsAString& valname, PRInt32* aReturn)
|
||
|
{
|
||
|
nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_DELETE_VAL, subkey, valname, NS_LITERAL_STRING("null"), aReturn);
|
||
|
|
||
|
if(wi == nsnull)
|
||
|
{
|
||
|
*aReturn = nsInstall::OUT_OF_MEMORY;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
if(*aReturn != nsInstall::SUCCESS)
|
||
|
{
|
||
|
if(wi)
|
||
|
{
|
||
|
delete wi;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(mInstallObject)
|
||
|
*aReturn = mInstallObject->ScheduleForInstall(wi);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::SetValueString(const nsAString& subkey, const nsAString& valname, const nsAString& value, PRInt32* aReturn)
|
||
|
{
|
||
|
nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_SET_VAL_STRING, subkey, valname, value, aReturn);
|
||
|
|
||
|
if(wi == nsnull)
|
||
|
{
|
||
|
*aReturn = nsInstall::OUT_OF_MEMORY;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
if(*aReturn != nsInstall::SUCCESS)
|
||
|
{
|
||
|
if(wi)
|
||
|
{
|
||
|
delete wi;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(mInstallObject)
|
||
|
*aReturn = mInstallObject->ScheduleForInstall(wi);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::GetValueString(const nsString& subkey, const nsString& valname, nsString* aReturn)
|
||
|
{
|
||
|
return NativeGetValueString(subkey, valname, aReturn);
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::EnumValueNames(const nsString& aSubkey, PRInt32 aIndex, nsString &aReturn)
|
||
|
{
|
||
|
char namebuf[MAX_BUF];
|
||
|
HKEY root;
|
||
|
HKEY newkey;
|
||
|
LONG result;
|
||
|
DWORD namesize = sizeof(namebuf);
|
||
|
PRInt32 rv = nsInstall::UNEXPECTED_ERROR;
|
||
|
|
||
|
nsCAutoString subkey;
|
||
|
if ( NS_FAILED ( NS_CopyUnicodeToNative(aSubkey, subkey) ) )
|
||
|
return nsInstall::UNEXPECTED_ERROR;
|
||
|
|
||
|
root = (HKEY) mRootKey;
|
||
|
result = RegOpenKeyEx( root, subkey.get(), 0, KEY_READ, &newkey );
|
||
|
|
||
|
if ( ERROR_SUCCESS == result ) {
|
||
|
result = RegEnumValue( newkey, aIndex, namebuf, &namesize, nsnull, 0, 0, 0 );
|
||
|
RegCloseKey( newkey );
|
||
|
|
||
|
if ( ERROR_SUCCESS == result ) {
|
||
|
nsCAutoString cstrName(namebuf);
|
||
|
nsAutoString name;
|
||
|
if(NS_SUCCEEDED(NS_CopyNativeToUnicode(cstrName, name)))
|
||
|
{
|
||
|
aReturn.Assign(name);
|
||
|
rv = nsInstall::SUCCESS;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return rv;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::EnumKeys(const nsString& aSubkey, PRInt32 aIndex, nsString &aReturn)
|
||
|
{
|
||
|
char keybuf[MAX_BUF];
|
||
|
HKEY root;
|
||
|
HKEY newkey;
|
||
|
LONG result;
|
||
|
DWORD type = REG_SZ;
|
||
|
PRInt32 rv = nsInstall::UNEXPECTED_ERROR;
|
||
|
|
||
|
nsCAutoString subkey;
|
||
|
if ( NS_FAILED(NS_CopyUnicodeToNative(aSubkey, subkey) ) )
|
||
|
return nsInstall::UNEXPECTED_ERROR;
|
||
|
|
||
|
root = (HKEY) mRootKey;
|
||
|
result = RegOpenKeyEx( root, subkey.get(), 0, KEY_READ, &newkey );
|
||
|
|
||
|
if ( ERROR_SUCCESS == result ) {
|
||
|
result = RegEnumKey( newkey, aIndex, keybuf, sizeof keybuf );
|
||
|
RegCloseKey( newkey );
|
||
|
|
||
|
if ( ERROR_SUCCESS == result ) {
|
||
|
nsCAutoString cstrKey(keybuf);
|
||
|
nsAutoString key;
|
||
|
if (NS_SUCCEEDED(NS_CopyNativeToUnicode(cstrKey, key) ) )
|
||
|
{
|
||
|
aReturn.Assign(key);
|
||
|
rv = nsInstall::SUCCESS;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return rv;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::SetValueNumber(const nsString& subkey, const nsString& valname, PRInt32 value, PRInt32* aReturn)
|
||
|
{
|
||
|
nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_SET_VAL_NUMBER, subkey, valname, value, aReturn);
|
||
|
|
||
|
if(wi == nsnull)
|
||
|
{
|
||
|
*aReturn = nsInstall::OUT_OF_MEMORY;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
if(*aReturn != nsInstall::SUCCESS)
|
||
|
{
|
||
|
if(wi)
|
||
|
{
|
||
|
delete wi;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(mInstallObject)
|
||
|
*aReturn = mInstallObject->ScheduleForInstall(wi);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::GetValueNumber(const nsString& subkey, const nsString& valname, PRInt32* aReturn)
|
||
|
{
|
||
|
return NativeGetValueNumber(subkey, valname, aReturn);
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::SetValue(const nsString& subkey, const nsString& valname, nsWinRegValue* value, PRInt32* aReturn)
|
||
|
{
|
||
|
// fix: need to figure out what to do with nsWinRegValue class.
|
||
|
//
|
||
|
// nsWinRegItem* wi = new nsWinRegItem(this, mRootKey, NS_WIN_REG_SET_VAL, subkey, valname, (nsWinRegValue*)value, aReturn);
|
||
|
//
|
||
|
// if(wi == nsnull)
|
||
|
// {
|
||
|
// return NS_OK;
|
||
|
// }
|
||
|
// mInstallObject->ScheduleForInstall(wi);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::GetValue(const nsString& subkey, const nsString& valname, nsWinRegValue** aReturn)
|
||
|
{
|
||
|
// fix:
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
nsInstall* nsWinReg::InstallObject()
|
||
|
{
|
||
|
return mInstallObject;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::KeyExists(const nsString& subkey,
|
||
|
PRBool* aReturn)
|
||
|
{
|
||
|
*aReturn = NativeKeyExists(subkey);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::ValueExists(const nsString& subkey,
|
||
|
const nsString& valname,
|
||
|
PRBool* aReturn)
|
||
|
{
|
||
|
*aReturn = NativeValueExists(subkey, valname);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::IsKeyWritable(const nsString& subkey,
|
||
|
PRBool* aReturn)
|
||
|
{
|
||
|
*aReturn = NativeIsKeyWritable(subkey);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::PrepareCreateKey(PRInt32 root,
|
||
|
const nsString& subkey,
|
||
|
PRInt32* aReturn)
|
||
|
{
|
||
|
SetRootKey(root);
|
||
|
if(NativeIsKeyWritable(subkey))
|
||
|
*aReturn = nsInstall::SUCCESS;
|
||
|
else
|
||
|
*aReturn = nsInstall::KEY_ACCESS_DENIED;
|
||
|
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::PrepareDeleteKey(PRInt32 root,
|
||
|
const nsString& subkey,
|
||
|
PRInt32* aReturn)
|
||
|
{
|
||
|
SetRootKey(root);
|
||
|
if(NativeKeyExists(subkey))
|
||
|
{
|
||
|
if(NativeIsKeyWritable(subkey))
|
||
|
*aReturn = nsInstall::SUCCESS;
|
||
|
else
|
||
|
*aReturn = nsInstall::KEY_ACCESS_DENIED;
|
||
|
}
|
||
|
else
|
||
|
*aReturn = nsInstall::KEY_DOES_NOT_EXIST;
|
||
|
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::PrepareDeleteValue(PRInt32 root,
|
||
|
const nsString& subkey,
|
||
|
const nsString& valname,
|
||
|
PRInt32* aReturn)
|
||
|
{
|
||
|
SetRootKey(root);
|
||
|
if(NativeValueExists(subkey, valname))
|
||
|
{
|
||
|
if(NativeIsKeyWritable(subkey))
|
||
|
*aReturn = nsInstall::SUCCESS;
|
||
|
else
|
||
|
*aReturn = nsInstall::KEY_ACCESS_DENIED;
|
||
|
}
|
||
|
else
|
||
|
*aReturn = nsInstall::VALUE_DOES_NOT_EXIST;
|
||
|
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::PrepareSetValueString(PRInt32 root,
|
||
|
const nsString& subkey,
|
||
|
PRInt32* aReturn)
|
||
|
{
|
||
|
SetRootKey(root);
|
||
|
if(NativeIsKeyWritable(subkey))
|
||
|
*aReturn = nsInstall::SUCCESS;
|
||
|
else
|
||
|
*aReturn = nsInstall::KEY_ACCESS_DENIED;
|
||
|
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::PrepareSetValueNumber(PRInt32 root,
|
||
|
const nsString& subkey,
|
||
|
PRInt32* aReturn)
|
||
|
{
|
||
|
SetRootKey(root);
|
||
|
if(NativeIsKeyWritable(subkey))
|
||
|
*aReturn = nsInstall::SUCCESS;
|
||
|
else
|
||
|
*aReturn = nsInstall::KEY_ACCESS_DENIED;
|
||
|
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::PrepareSetValue(PRInt32 root,
|
||
|
const nsString& subkey,
|
||
|
PRInt32* aReturn)
|
||
|
{
|
||
|
SetRootKey(root);
|
||
|
if(NativeIsKeyWritable(subkey))
|
||
|
*aReturn = nsInstall::SUCCESS;
|
||
|
else
|
||
|
*aReturn = nsInstall::KEY_ACCESS_DENIED;
|
||
|
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::FinalCreateKey(PRInt32 root, const nsString& subkey, const nsString& classname, PRInt32* aReturn)
|
||
|
{
|
||
|
SetRootKey(root);
|
||
|
*aReturn = NativeCreateKey(subkey, classname);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::FinalDeleteKey(PRInt32 root, const nsString& subkey, PRInt32* aReturn)
|
||
|
{
|
||
|
SetRootKey(root);
|
||
|
if ( PR_TRUE == NativeKeyExists(subkey) )
|
||
|
*aReturn = NativeDeleteKey(subkey);
|
||
|
else {
|
||
|
NS_WARNING("Trying to delete a key that doesn't exist anymore. Possible causes include calling deleteKey for the same key multiple times, or key+subkey are not unique");
|
||
|
*aReturn = ERROR_SUCCESS;
|
||
|
}
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::FinalDeleteValue(PRInt32 root, const nsString& subkey, const nsString& valname, PRInt32* aReturn)
|
||
|
{
|
||
|
SetRootKey(root);
|
||
|
*aReturn = NativeDeleteValue(subkey, valname);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::FinalSetValueString(PRInt32 root, const nsString& subkey, const nsString& valname, const nsString& value, PRInt32* aReturn)
|
||
|
{
|
||
|
SetRootKey(root);
|
||
|
*aReturn = NativeSetValueString(subkey, valname, value);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::FinalSetValueNumber(PRInt32 root, const nsString& subkey, const nsString& valname, PRInt32 value, PRInt32* aReturn)
|
||
|
{
|
||
|
SetRootKey(root);
|
||
|
*aReturn = NativeSetValueNumber(subkey, valname, value);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::FinalSetValue(PRInt32 root, const nsString& subkey, const nsString& valname, nsWinRegValue* value, PRInt32* aReturn)
|
||
|
{
|
||
|
SetRootKey(root);
|
||
|
*aReturn = NativeSetValue(subkey, valname, value);
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Private Methods */
|
||
|
|
||
|
PRBool
|
||
|
nsWinReg::NativeKeyExists(const nsString& aSubkey)
|
||
|
{
|
||
|
HKEY root, newkey;
|
||
|
LONG result;
|
||
|
PRBool keyExists = PR_FALSE;
|
||
|
|
||
|
#ifdef WIN32
|
||
|
nsCAutoString subkey;
|
||
|
|
||
|
if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) )
|
||
|
return PR_FALSE;
|
||
|
|
||
|
root = (HKEY)mRootKey;
|
||
|
result = RegOpenKeyEx(root, subkey.get(), 0, KEY_READ, &newkey);
|
||
|
switch(result)
|
||
|
{
|
||
|
case ERROR_SUCCESS:
|
||
|
RegCloseKey(newkey);
|
||
|
keyExists = PR_TRUE;
|
||
|
break;
|
||
|
|
||
|
case ERROR_FILE_NOT_FOUND:
|
||
|
case ERROR_ACCESS_DENIED:
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return keyExists;
|
||
|
}
|
||
|
|
||
|
PRBool
|
||
|
nsWinReg::NativeValueExists(const nsString& aSubkey, const nsString& aValname)
|
||
|
{
|
||
|
HKEY root;
|
||
|
HKEY newkey;
|
||
|
LONG result;
|
||
|
PRBool valueExists = PR_FALSE;
|
||
|
DWORD length = _MAXKEYVALUE_;
|
||
|
unsigned char valbuf[_MAXKEYVALUE_];
|
||
|
|
||
|
#ifdef WIN32
|
||
|
nsCAutoString subkey;
|
||
|
nsCAutoString valname;
|
||
|
|
||
|
if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
|
||
|
NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
|
||
|
return PR_FALSE;
|
||
|
|
||
|
root = (HKEY) mRootKey;
|
||
|
result = RegOpenKeyEx(root, subkey.get(), 0, KEY_READ, &newkey);
|
||
|
switch(result)
|
||
|
{
|
||
|
case ERROR_SUCCESS:
|
||
|
result = RegQueryValueEx(newkey,
|
||
|
valname.get(),
|
||
|
0,
|
||
|
NULL,
|
||
|
valbuf,
|
||
|
&length);
|
||
|
switch(result)
|
||
|
{
|
||
|
case ERROR_SUCCESS:
|
||
|
valueExists = PR_TRUE;
|
||
|
break;
|
||
|
|
||
|
case ERROR_FILE_NOT_FOUND:
|
||
|
case ERROR_ACCESS_DENIED:
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
RegCloseKey(newkey);
|
||
|
break;
|
||
|
|
||
|
case ERROR_FILE_NOT_FOUND:
|
||
|
case ERROR_ACCESS_DENIED:
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return valueExists;
|
||
|
}
|
||
|
|
||
|
PRBool
|
||
|
nsWinReg::NativeIsKeyWritable(const nsString& aSubkey)
|
||
|
{
|
||
|
HKEY root;
|
||
|
HKEY newkey;
|
||
|
LONG result;
|
||
|
nsString subkeyParent = aSubkey;
|
||
|
PRInt32 index;
|
||
|
PRInt32 rv = PR_FALSE;
|
||
|
|
||
|
#ifdef WIN32
|
||
|
/* In order to check to see if a key is writable (user has write access
|
||
|
* to the key), we need to open the key with KEY_WRITE access. In order
|
||
|
* to open a key, the key must first exist. If the key passed does not
|
||
|
* exist, we need to search for one of its parent key that _does_ exist.
|
||
|
* This do{} loop will search for an existing parent key. */
|
||
|
do
|
||
|
{
|
||
|
rv = NativeKeyExists(subkeyParent);
|
||
|
if(!rv)
|
||
|
{
|
||
|
index = subkeyParent.RFindChar('\\', -1, -1);
|
||
|
if(index > 0)
|
||
|
/* delete everything from the '\\' found to the end of the string */
|
||
|
subkeyParent.SetLength(index);
|
||
|
else
|
||
|
/* key does not exist and no parent key found */
|
||
|
break;
|
||
|
}
|
||
|
}while(!rv);
|
||
|
|
||
|
if(rv)
|
||
|
{
|
||
|
nsCAutoString subkey;
|
||
|
|
||
|
if ( NS_FAILED( NS_CopyUnicodeToNative(subkeyParent, subkey) ) )
|
||
|
result = nsInstall::UNEXPECTED_ERROR;
|
||
|
else
|
||
|
{
|
||
|
rv = PR_FALSE;
|
||
|
root = (HKEY)mRootKey;
|
||
|
result = RegOpenKeyEx(root, subkey.get(), 0, KEY_WRITE, &newkey);
|
||
|
switch(result)
|
||
|
{
|
||
|
case ERROR_SUCCESS:
|
||
|
RegCloseKey(newkey);
|
||
|
rv = PR_TRUE;
|
||
|
break;
|
||
|
|
||
|
case ERROR_FILE_NOT_FOUND:
|
||
|
case ERROR_ACCESS_DENIED:
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
return rv;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::NativeCreateKey(const nsString& aSubkey, const nsString& aClassname)
|
||
|
{
|
||
|
HKEY root, newkey;
|
||
|
LONG result;
|
||
|
ULONG disposition;
|
||
|
|
||
|
#ifdef WIN32
|
||
|
nsCAutoString subkey;
|
||
|
nsCAutoString classname;
|
||
|
|
||
|
if (NS_FAILED(NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
|
||
|
NS_FAILED(NS_CopyUnicodeToNative(aClassname, classname) ) )
|
||
|
return nsInstall::UNEXPECTED_ERROR;
|
||
|
|
||
|
root = (HKEY)mRootKey;
|
||
|
result = RegCreateKeyEx(root, subkey.get(), 0, NS_CONST_CAST(char*, classname.get()),
|
||
|
REG_OPTION_NON_VOLATILE, KEY_WRITE, nsnull, &newkey, &disposition);
|
||
|
|
||
|
if(ERROR_SUCCESS == result)
|
||
|
{
|
||
|
RegCloseKey( newkey );
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::NativeDeleteKey(const nsString& aSubkey)
|
||
|
{
|
||
|
HKEY root;
|
||
|
LONG result;
|
||
|
|
||
|
#ifdef WIN32
|
||
|
nsCAutoString subkey;
|
||
|
|
||
|
if (NS_FAILED(NS_CopyUnicodeToNative(aSubkey, subkey) ) )
|
||
|
return nsInstall::UNEXPECTED_ERROR;
|
||
|
|
||
|
root = (HKEY) mRootKey;
|
||
|
result = RegDeleteKey( root, subkey.get() );
|
||
|
#endif
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::NativeDeleteValue(const nsString& aSubkey, const nsString& aValname)
|
||
|
{
|
||
|
#if defined (WIN32) || defined (XP_OS2)
|
||
|
HKEY root, newkey;
|
||
|
LONG result;
|
||
|
nsCAutoString subkey;
|
||
|
nsCAutoString valname;
|
||
|
|
||
|
if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
|
||
|
NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
|
||
|
return nsInstall::UNEXPECTED_ERROR;
|
||
|
root = (HKEY) mRootKey;
|
||
|
result = RegOpenKeyEx( root, subkey.get(), 0, KEY_WRITE, &newkey);
|
||
|
|
||
|
if ( ERROR_SUCCESS == result )
|
||
|
{
|
||
|
result = RegDeleteValue( newkey, valname.get() );
|
||
|
RegCloseKey( newkey );
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
#else
|
||
|
return ERROR_INVALID_PARAMETER;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::NativeSetValueString(const nsString& aSubkey, const nsString& aValname, const nsString& aValue)
|
||
|
{
|
||
|
HKEY root;
|
||
|
HKEY newkey;
|
||
|
LONG result;
|
||
|
DWORD length;
|
||
|
|
||
|
nsCAutoString subkey;
|
||
|
nsCAutoString valname;
|
||
|
nsCAutoString value;
|
||
|
|
||
|
if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
|
||
|
NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) ||
|
||
|
NS_FAILED( NS_CopyUnicodeToNative(aValue, value) ) )
|
||
|
return nsInstall::UNEXPECTED_ERROR;
|
||
|
|
||
|
length = value.Length();
|
||
|
|
||
|
root = (HKEY) mRootKey;
|
||
|
result = RegOpenKeyEx( root, subkey.get(), 0, KEY_WRITE, &newkey);
|
||
|
|
||
|
if(ERROR_SUCCESS == result)
|
||
|
{
|
||
|
result = RegSetValueEx( newkey, valname.get(), 0, REG_SZ, (unsigned char*)value.get(), length );
|
||
|
RegCloseKey( newkey );
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
#define STRBUFLEN 255
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::NativeGetValueString(const nsString& aSubkey, const nsString& aValname, nsString* aReturn)
|
||
|
{
|
||
|
unsigned char valbuf[_MAXKEYVALUE_];
|
||
|
HKEY root;
|
||
|
HKEY newkey;
|
||
|
LONG result;
|
||
|
DWORD type = REG_SZ;
|
||
|
DWORD length = sizeof(valbuf);
|
||
|
nsCAutoString subkey;
|
||
|
nsCAutoString valname;
|
||
|
|
||
|
if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
|
||
|
NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
|
||
|
return nsInstall::UNEXPECTED_ERROR;
|
||
|
|
||
|
root = (HKEY) mRootKey;
|
||
|
result = RegOpenKeyEx( root, subkey.get(), 0, KEY_READ, &newkey );
|
||
|
|
||
|
if ( ERROR_SUCCESS == result ) {
|
||
|
result = RegQueryValueEx( newkey, valname.get(), nsnull, &type, valbuf, &length );
|
||
|
|
||
|
RegCloseKey( newkey );
|
||
|
|
||
|
if( result == ERROR_SUCCESS && type == REG_SZ)
|
||
|
{
|
||
|
// this cast is ok until mozilla is compiled in UNICODE, then this
|
||
|
// will break.
|
||
|
nsAutoString value;
|
||
|
if (NS_SUCCEEDED( NS_CopyNativeToUnicode(nsDependentCString(NS_REINTERPRET_CAST(const char *, valbuf)), value) ) )
|
||
|
aReturn->Assign(value);
|
||
|
else
|
||
|
result = nsInstall::UNEXPECTED_ERROR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(ERROR_ACCESS_DENIED == result)
|
||
|
result = nsInstall::ACCESS_DENIED;
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::NativeSetValueNumber(const nsString& aSubkey, const nsString& aValname, PRInt32 aValue)
|
||
|
{
|
||
|
HKEY root;
|
||
|
HKEY newkey;
|
||
|
LONG result;
|
||
|
nsCAutoString subkey;
|
||
|
nsCAutoString valname;
|
||
|
|
||
|
if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
|
||
|
NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
|
||
|
return nsInstall::UNEXPECTED_ERROR;
|
||
|
|
||
|
root = (HKEY) mRootKey;
|
||
|
result = RegOpenKeyEx( root, subkey.get(), 0, KEY_WRITE, &newkey);
|
||
|
|
||
|
if(ERROR_SUCCESS == result)
|
||
|
{
|
||
|
result = RegSetValueEx( newkey, valname.get(), 0, REG_DWORD, (LPBYTE)&aValue, sizeof(PRInt32));
|
||
|
RegCloseKey( newkey );
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::NativeGetValueNumber(const nsString& aSubkey, const nsString& aValname, PRInt32* aReturn)
|
||
|
|
||
|
{
|
||
|
PRInt32 valbuf;
|
||
|
PRInt32 valbuflen;
|
||
|
HKEY root;
|
||
|
HKEY newkey;
|
||
|
LONG result;
|
||
|
DWORD type = REG_DWORD;
|
||
|
DWORD length = _MAXKEYVALUE_;
|
||
|
nsCAutoString subkey;
|
||
|
nsCAutoString valname;
|
||
|
|
||
|
if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
|
||
|
NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
|
||
|
return nsInstall::UNEXPECTED_ERROR;
|
||
|
|
||
|
valbuflen = sizeof(PRInt32);
|
||
|
root = (HKEY) mRootKey;
|
||
|
result = RegOpenKeyEx( root, subkey.get(), 0, KEY_READ, &newkey );
|
||
|
|
||
|
if ( ERROR_SUCCESS == result ) {
|
||
|
result = RegQueryValueEx( newkey, valname.get(), nsnull, &type, (LPBYTE)&valbuf, (LPDWORD)&valbuflen);
|
||
|
|
||
|
RegCloseKey( newkey );
|
||
|
|
||
|
if(type == REG_DWORD)
|
||
|
*aReturn = valbuf;
|
||
|
}
|
||
|
|
||
|
if(ERROR_ACCESS_DENIED == result)
|
||
|
return nsInstall::ACCESS_DENIED;
|
||
|
else if (result != ERROR_SUCCESS)
|
||
|
return nsInstall::UNEXPECTED_ERROR;
|
||
|
|
||
|
return nsInstall::SUCCESS;
|
||
|
}
|
||
|
|
||
|
PRInt32
|
||
|
nsWinReg::NativeSetValue(const nsString& aSubkey, const nsString& aValname, nsWinRegValue* aValue)
|
||
|
{
|
||
|
#if defined (WIN32) || defined (XP_OS2)
|
||
|
HKEY root;
|
||
|
HKEY newkey;
|
||
|
LONG result;
|
||
|
DWORD length;
|
||
|
DWORD type;
|
||
|
unsigned char* data;
|
||
|
nsCAutoString subkey;
|
||
|
nsCAutoString valname;
|
||
|
|
||
|
if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
|
||
|
NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
|
||
|
return nsnull;
|
||
|
|
||
|
root = (HKEY) mRootKey;
|
||
|
result = RegOpenKeyEx( root, subkey.get(), 0, KEY_WRITE, &newkey );
|
||
|
|
||
|
if(ERROR_SUCCESS == result)
|
||
|
{
|
||
|
type = (DWORD)aValue->type;
|
||
|
data = (unsigned char*)aValue->data;
|
||
|
length = (DWORD)aValue->data_length;
|
||
|
|
||
|
result = RegSetValueEx( newkey, valname.get(), 0, type, data, length);
|
||
|
RegCloseKey( newkey );
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
#else
|
||
|
return ERROR_INVALID_PARAMETER;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
nsWinRegValue*
|
||
|
nsWinReg::NativeGetValue(const nsString& aSubkey, const nsString& aValname)
|
||
|
{
|
||
|
#if defined (WIN32) || defined (XP_OS2)
|
||
|
unsigned char valbuf[STRBUFLEN];
|
||
|
HKEY root;
|
||
|
HKEY newkey;
|
||
|
LONG result;
|
||
|
DWORD length=STRBUFLEN;
|
||
|
DWORD type;
|
||
|
nsString* data;
|
||
|
nsWinRegValue* value = nsnull;
|
||
|
nsCAutoString subkey;
|
||
|
nsCAutoString valname;
|
||
|
|
||
|
if ( NS_FAILED( NS_CopyUnicodeToNative(aSubkey, subkey) ) ||
|
||
|
NS_FAILED( NS_CopyUnicodeToNative(aValname, valname) ) )
|
||
|
return nsnull;
|
||
|
|
||
|
root = (HKEY) mRootKey;
|
||
|
result = RegOpenKeyEx( root, subkey.get(), 0, KEY_READ, &newkey );
|
||
|
|
||
|
if(ERROR_SUCCESS == result)
|
||
|
{
|
||
|
result = RegQueryValueEx( newkey, valname.get(), nsnull, &type, valbuf, &length );
|
||
|
|
||
|
if ( ERROR_SUCCESS == result ) {
|
||
|
data = new nsString;
|
||
|
data->AssignWithConversion((char *)valbuf);
|
||
|
length = data->Length();
|
||
|
value = new nsWinRegValue(type, (void*)data, length);
|
||
|
}
|
||
|
|
||
|
RegCloseKey( newkey );
|
||
|
}
|
||
|
|
||
|
return value;
|
||
|
#else
|
||
|
return nsnull;
|
||
|
#endif
|
||
|
}
|
||
|
|