/*
* $Id$
* IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
*
* http://izpack.org/
* http://izpack.codehaus.org/
*
* Copyright 2005 Klaus Bartz
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.izforge.izpack.util.os;
import com.coi.tools.os.win.MSWinConstants;
import com.coi.tools.os.win.NativeLibException;
import com.coi.tools.os.win.RegDataContainer;
import com.izforge.izpack.installer.AutomatedInstallData;
import com.izforge.izpack.installer.ResourceManager;
import com.izforge.izpack.util.Debug;
import com.izforge.izpack.util.OSClassHelper;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This class represents a registry handler in a operating system independent way. OS specific
* subclasses are used to implement the necessary mapping from this generic API to the classes that
* reflect the system dependent AIP.
*
* @author Klaus Bartz
*/
public class RegistryHandler extends OSClassHelper implements MSWinConstants
{
public static final String UNINSTALL_ROOT = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
public static final Map<String, Integer> ROOT_KEY_MAP = new HashMap<String, Integer>();
protected String uninstallName = null;
private static final String UNINSTALLER_ICON = "UninstallerIcon";
private static RegistryHandler defaultHandler = null;
static
{
ROOT_KEY_MAP.put("HKCR", HKEY_CLASSES_ROOT);
ROOT_KEY_MAP.put("HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT);
ROOT_KEY_MAP.put("HKCU", HKEY_CURRENT_USER);
ROOT_KEY_MAP.put("HKEY_CURRENT_USER", HKEY_CURRENT_USER);
ROOT_KEY_MAP.put("HKLM", HKEY_LOCAL_MACHINE);
ROOT_KEY_MAP.put("HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE);
ROOT_KEY_MAP.put("HKU", HKEY_USERS);
ROOT_KEY_MAP.put("HKEY_USERS", HKEY_USERS);
ROOT_KEY_MAP.put("HKPD", HKEY_PERFORMANCE_DATA);
ROOT_KEY_MAP.put("HKEY_PERFORMANCE_DATA", HKEY_PERFORMANCE_DATA);
ROOT_KEY_MAP.put("HKCC", HKEY_CURRENT_CONFIG);
ROOT_KEY_MAP.put("HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG);
ROOT_KEY_MAP.put("HKDDS", HKEY_DYN_DATA);
ROOT_KEY_MAP.put("HKEY_DYN_DATA", HKEY_DYN_DATA);
}
/**
* Default constructor.
*/
public RegistryHandler()
{
super();
}
/**
* Creates an registry handler which uses an oblect of the given class as worker.
*
* @param className full qualified class name of the class which should be used as worker
*/
public RegistryHandler(String className)
{
super(className);
setDefault();
}
/**
* Set this object as default handler if it is not done earlier.
*/
private synchronized void setDefault()
{
if (defaultHandler == null)
{
defaultHandler = this;
}
}
/**
* Sets the given contents to the given registry value. If a sub key or the registry value does
* not exist, it will be created. The return value is a String array which contains the names of
* the keys and values which are created. REG_SZ is used as registry value type.
*
* @param key the registry key which should be used or created
* @param value the registry value into which the contents should be set
* @param contents the contents for the value
* @throws NativeLibException
*/
public void setValue(String key, String value, String contents) throws NativeLibException
{
}
public void setValue(String key, String value, String[] contents) throws NativeLibException
{
}
/**
* Sets the given contents to the given registry value. If a sub key or the registry value does
* not exist, it will be created. The return value is a String array which contains the names of
* the keys and values which are created. REG_BINARY is used as registry value type.
*
* @param key the registry key which should be used or created
* @param value the registry value into which the contents should be set
* @param contents the contents for the value
* @throws NativeLibException
*/
public void setValue(String key, String value, byte[] contents) throws NativeLibException
{
}
/**
* Sets the given contents to the given registry value. If a sub key or the registry value does
* not exist, it will be created. The return value is a String array which contains the names of
* the keys and values which are created. REG_DWORD is used as registry value type.
*
* @param key the registry key which should be used or created
* @param value the registry value into which the contents should be set
* @param contents the contents for the value
* @throws NativeLibException
*/
public void setValue(String key, String value, long contents) throws NativeLibException
{
}
/**
* Returns the contents of the key/value pair if value exist, else the given default value.
*
* @param key the registry key which should be used
* @param value the registry value from which the contents should be requested
* @param defaultVal value to be used if no value exist in the registry
* @return requested value if exist, else the default value
* @throws NativeLibException
*/
public RegDataContainer getValue(String key, String value, RegDataContainer defaultVal) throws NativeLibException
{
return (null);
}
/**
* Returns whether a key exist or not.
*
* @param key key to be evaluated
* @return whether a key exist or not
* @throws NativeLibException
*/
public boolean keyExist(String key) throws NativeLibException
{
return (false);
}
/**
* Returns whether a the given value under the given key exist or not.
*
* @param key key to be used as path for the value
* @param value value name to be evaluated
* @return whether a the given value under the given key exist or not
* @throws NativeLibException
*/
public boolean valueExist(String key, String value) throws NativeLibException
{
return (false);
}
/**
* Returns all keys which are defined under the given key.
*
* @param key key to be used as path for the sub keys
* @return all keys which are defined under the given key
* @throws NativeLibException
*/
public String[] getSubkeys(String key) throws NativeLibException
{
return (null);
}
/**
* Returns all value names which are defined under the given key.
*
* @param key key to be used as path for the value names
* @return all value names which are defined under the given key
* @throws NativeLibException
*/
public String[] getValueNames(String key) throws NativeLibException
{
return (null);
}
/**
* Returns the contents of the key/value pair if value exist, else an exception is raised.
*
* @param key the registry key which should be used
* @param value the registry value from which the contents should be requested
* @return requested value if exist, else an exception
* @throws NativeLibException
*/
public RegDataContainer getValue(String key, String value) throws NativeLibException
{
return (null);
}
/**
* Creates the given key in the registry.
*
* @param key key to be created
* @throws NativeLibException
*/
public void createKey(String key) throws NativeLibException
{
}
/**
* Deletes the given key if exist, else throws an exception.
*
* @param key key to be deleted
* @throws NativeLibException
*/
public void deleteKey(String key) throws NativeLibException
{
}
/**
* Deletes a key under the current root if it is empty, else do nothing.
*
* @param key key to be deleted
* @throws NativeLibException
*/
public void deleteKeyIfEmpty(String key) throws NativeLibException
{
}
/**
* Deletes a value.
*
* @param key key of the value which should be deleted
* @param value value name to be deleted
* @throws NativeLibException
*/
public void deleteValue(String key, String value) throws NativeLibException
{
}
/**
* Sets the root for the next registry access.
*
* @param i an integer which refers to a HKEY
* @throws NativeLibException
*/
public void setRoot(int i) throws NativeLibException
{
}
/**
* Return the root as integer (HKEY_xxx).
*
* @return the root as integer
* @throws NativeLibException
*/
public int getRoot() throws NativeLibException
{
return (0);
}
/**
* Sets up whether or not previous contents of registry values will
* be logged by the 'setValue()' method. When registry values are
* overwritten by repeated installations, the desired behavior can
* be to have the registry value removed rather than rewound to the
* last-set contents (acheived via 'false'). If this method is not
* called then the flag wll default to 'true'.
*
* @param flagVal true to have the previous contents of registry
* values logged by the 'setValue()' method.
*/
public void setLogPrevSetValueFlag(boolean flagVal)
{
}
/**
* Determines whether or not previous contents of registry values
* will be logged by the 'setValue()' method.
*
* @return true if the previous contents of registry values will be
* logged by the 'setValue()' method.
*/
public boolean getLogPrevSetValueFlag()
{
return (true);
}
/**
* Activates logging of registry changes.
*
* @throws NativeLibException
*/
public void activateLogging() throws NativeLibException
{
}
/**
* Suspends logging of registry changes.
*
* @throws NativeLibException
*/
public void suspendLogging() throws NativeLibException
{
}
/**
* Resets logging of registry changes.
*
* @throws NativeLibException
*/
public void resetLogging() throws NativeLibException
{
}
public List<Object> getLoggingInfo() throws NativeLibException
{
return (null);
}
public void setLoggingInfo(List info) throws NativeLibException
{
}
public void addLoggingInfo(List info) throws NativeLibException
{
}
public void rewind() throws NativeLibException
{
}
public String getUninstallName()
{
if (uninstallName != null)
{
return (uninstallName);
}
if (installdata == null)
{
return (null);
}
return (installdata.getVariable("APP_NAME") + " " + installdata.getVariable("APP_VER"));
}
public boolean isProductRegistered() throws NativeLibException
{
String uninstallName = getUninstallName();
if (uninstallName == null)
{
return (false);
}
String keyName = UNINSTALL_ROOT + uninstallName;
int oldVal = getRoot();
setRoot(HKEY_LOCAL_MACHINE);
boolean retval = keyExist(keyName);
setRoot(HKEY_CURRENT_USER);
retval = retval || keyExist(keyName);
setRoot(oldVal);
return (retval);
}
public void setUninstallName(String name)
{
uninstallName = name;
}
public void registerUninstallKey() throws NativeLibException
{
String uninstallName = getUninstallName();
if (uninstallName == null)
{
return;
}
String keyName = UNINSTALL_ROOT + uninstallName;
String cmd = "\"" + installdata.getVariable("JAVA_HOME") + "\\bin\\javaw.exe\" -jar \""
+ installdata.getVariable("INSTALL_PATH") + "\\uninstaller\\uninstaller.jar\"";
String appVersion = installdata.getVariable("APP_VER");
String appUrl = installdata.getVariable("APP_URL");
int oldVal = getRoot();
try
{
setRoot(HKEY_LOCAL_MACHINE);
setValue(keyName, "DisplayName", uninstallName);
}
catch (NativeLibException exception)
{ // Users without administrative rights should be able to install the app for themselves
Debug.trace("Failed to register uninstaller in HKEY_LOCAL_MACHINE hive, trying HKEY_CURRENT_USER: " + exception.getMessage());
setRoot(HKEY_CURRENT_USER);
setValue(keyName, "DisplayName", uninstallName);
}
setValue(keyName, "UninstallString", cmd);
setValue(keyName, "DisplayVersion", appVersion);
if (appUrl != null && appUrl.length() > 0)
{
setValue(keyName, "HelpLink", appUrl);
}
// Try to write the uninstaller icon out.
try
{
InputStream input = ResourceManager.getInstance().getInputStream(UNINSTALLER_ICON);
String iconPath = installdata.getVariable("INSTALL_PATH") + File.separator
+ "Uninstaller" + File.separator + "UninstallerIcon.ico";
FileOutputStream out = new FileOutputStream(iconPath);
byte[] buffer = new byte[5120];
long bytesCopied = 0;
int bytesInBuffer;
while ((bytesInBuffer = input.read(buffer)) != -1)
{
out.write(buffer, 0, bytesInBuffer);
bytesCopied += bytesInBuffer;
}
input.close();
out.close();
setValue(keyName, "DisplayIcon", iconPath);
}
catch (Exception exception)
{ // May be no icon resource defined; ignore it
Debug.trace(exception);
}
setRoot(oldVal);
}
/**
* @param idata
*/
public boolean verify(AutomatedInstallData idata) throws Exception
{
super.verify(idata);
return (true);
}
/**
* Returns whether an action with this handler should be performed or not.
*
* @return always true
*/
public boolean doPerform()
{
return true;
}
/**
* Returns the default handler which is the first created registry handler.
*
* @return Returns the default handler.
*/
public RegistryHandler getDefaultHandler()
{
return defaultHandler;
}
}