2001-05-23 15:26:42 +02:00
|
|
|
/*
|
|
|
|
* PROGRAM: Windows NT registry installation program
|
2003-10-20 12:35:38 +02:00
|
|
|
* MODULE: registry.cpp
|
2001-05-23 15:26:42 +02:00
|
|
|
* DESCRIPTION: Registry update routines
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Interbase Public
|
|
|
|
* License Version 1.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.Inprise.com/IPL.html
|
|
|
|
*
|
|
|
|
* 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 was created by Inprise Corporation
|
|
|
|
* and its predecessors. Portions created by Inprise Corporation are
|
|
|
|
* Copyright (C) Inprise Corporation.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
2002-06-29 10:49:39 +02:00
|
|
|
*
|
|
|
|
* 01-Feb-2002 Paul Reeves: Removed hard-coded registry path
|
|
|
|
*
|
2001-05-23 15:26:42 +02:00
|
|
|
*/
|
|
|
|
|
2001-07-30 01:43:24 +02:00
|
|
|
#include "firebird.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../jrd/ib_stdio.h"
|
2001-07-30 01:43:24 +02:00
|
|
|
#include "../jrd/isc_proto.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <windows.h>
|
|
|
|
#include "../jrd/common.h"
|
|
|
|
#include "../jrd/license.h"
|
2003-07-15 04:43:36 +02:00
|
|
|
#include "../utilities/install/install_nt.h"
|
|
|
|
#include "../utilities/install/regis_proto.h"
|
|
|
|
#include "../utilities/install/registry.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-20 12:35:38 +02:00
|
|
|
static void cleanup_key(HKEY, TEXT*);
|
2003-11-06 18:57:22 +01:00
|
|
|
#ifdef THIS_CODE_IS_TEMPORARILY_NOT_USED_ANYMORE
|
2003-10-20 12:35:38 +02:00
|
|
|
static USHORT remove_subkeys(HKEY, bool, USHORT(*)(SLONG, TEXT*, HKEY));
|
2003-11-06 18:57:22 +01:00
|
|
|
#endif
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-08 11:42:23 +02:00
|
|
|
USHORT REGISTRY_install(HKEY hkey_rootnode,
|
2003-10-20 12:35:38 +02:00
|
|
|
TEXT* directory, USHORT(*err_handler)(SLONG, TEXT*, HKEY))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* R E G I S T R Y _ i n s t a l l
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2003-10-12 13:48:33 +02:00
|
|
|
* Install Firebird in the registry.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2003-10-08 11:42:23 +02:00
|
|
|
HKEY hkey_instances;
|
2001-05-23 15:26:42 +02:00
|
|
|
DWORD disp;
|
2003-10-20 12:35:38 +02:00
|
|
|
TEXT path_name[MAXPATHLEN];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-20 12:35:38 +02:00
|
|
|
SLONG status = RegCreateKeyEx(hkey_rootnode,
|
2003-10-08 11:42:23 +02:00
|
|
|
REG_KEY_ROOT_INSTANCES,
|
|
|
|
0,
|
|
|
|
"",
|
|
|
|
REG_OPTION_NON_VOLATILE,
|
|
|
|
KEY_WRITE,
|
2003-10-20 12:35:38 +02:00
|
|
|
NULL, &hkey_instances, &disp);
|
|
|
|
if (status != ERROR_SUCCESS) {
|
2001-05-23 15:26:42 +02:00
|
|
|
return (*err_handler) (status, "RegCreateKeyEx", NULL);
|
|
|
|
}
|
|
|
|
|
2003-10-20 12:35:38 +02:00
|
|
|
TEXT* p;
|
|
|
|
USHORT len = GetFullPathName(directory, sizeof(path_name), path_name, &p);
|
2001-05-23 15:26:42 +02:00
|
|
|
if (len && path_name[len - 1] != '/' && path_name[len - 1] != '\\') {
|
|
|
|
path_name[len++] = '\\';
|
|
|
|
path_name[len] = 0;
|
|
|
|
}
|
|
|
|
|
2003-10-08 11:42:23 +02:00
|
|
|
if ((status = RegSetValueEx(hkey_instances, FB_DEFAULT_INSTANCE, 0,
|
|
|
|
REG_SZ, reinterpret_cast<UCHAR*>(path_name),
|
|
|
|
(DWORD) (len + 1))) != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
(*err_handler) (status, "RegSetValueEx", hkey_instances);
|
|
|
|
|
|
|
|
// Removes the "Instances" key if we just created it.
|
|
|
|
// Else, keep it, because we don't want to trash other instances.
|
2001-05-23 15:26:42 +02:00
|
|
|
if (disp == REG_CREATED_NEW_KEY)
|
2003-10-12 13:48:33 +02:00
|
|
|
{
|
2003-10-08 11:42:23 +02:00
|
|
|
RegDeleteKey(hkey_rootnode, REG_KEY_ROOT_INSTANCES);
|
2003-10-12 13:48:33 +02:00
|
|
|
cleanup_key(hkey_rootnode, REG_KEY_ROOT_PRODUCT);
|
|
|
|
cleanup_key(hkey_rootnode, REG_KEY_ROOT_COMPANY);
|
|
|
|
}
|
2003-10-08 11:42:23 +02:00
|
|
|
|
2002-11-14 09:33:08 +01:00
|
|
|
return FB_FAILURE;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-10-08 11:42:23 +02:00
|
|
|
RegCloseKey(hkey_instances);
|
2002-11-14 09:33:08 +01:00
|
|
|
return FB_SUCCESS;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-10-08 11:42:23 +02:00
|
|
|
USHORT REGISTRY_remove(HKEY hkey_rootnode,
|
2003-10-20 12:35:38 +02:00
|
|
|
bool silent_flag, USHORT(*err_handler)(SLONG, TEXT*, HKEY))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* R E G I S T R Y _ r e m o v e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2003-10-12 13:48:33 +02:00
|
|
|
* Remove Firebird from the registry.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2003-10-08 11:42:23 +02:00
|
|
|
HKEY hkey_instances;
|
|
|
|
|
2003-10-20 12:35:38 +02:00
|
|
|
SLONG status = RegOpenKeyEx(hkey_rootnode, REG_KEY_ROOT_INSTANCES, 0,
|
|
|
|
KEY_READ | KEY_WRITE, &hkey_instances);
|
|
|
|
if (status != ERROR_SUCCESS)
|
2003-10-08 11:42:23 +02:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
if (silent_flag)
|
2002-11-14 09:33:08 +01:00
|
|
|
return FB_FAILURE;
|
2001-05-23 15:26:42 +02:00
|
|
|
return (*err_handler) (status, "RegOpenKeyEx", NULL);
|
|
|
|
}
|
|
|
|
|
2003-10-12 13:48:33 +02:00
|
|
|
// Remove the DEFAULT_INSTANCE value
|
2003-10-08 11:42:23 +02:00
|
|
|
if ((status = RegDeleteValue(hkey_instances, FB_DEFAULT_INSTANCE))
|
2003-10-12 13:48:33 +02:00
|
|
|
!= ERROR_SUCCESS)
|
2003-10-08 11:42:23 +02:00
|
|
|
{
|
|
|
|
RegCloseKey(hkey_instances);
|
2001-05-23 15:26:42 +02:00
|
|
|
if (silent_flag)
|
2002-11-14 09:33:08 +01:00
|
|
|
return FB_FAILURE;
|
2003-10-08 11:42:23 +02:00
|
|
|
return (*err_handler) (status, "RegDeleteValue", NULL);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-10-12 13:48:33 +02:00
|
|
|
RegCloseKey(hkey_instances);
|
|
|
|
cleanup_key(hkey_rootnode, REG_KEY_ROOT_INSTANCES);
|
|
|
|
cleanup_key(hkey_rootnode, REG_KEY_ROOT_PRODUCT);
|
|
|
|
cleanup_key(hkey_rootnode, REG_KEY_ROOT_COMPANY);
|
|
|
|
|
|
|
|
return FB_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cleanup_key(HKEY hkey_rootnode, TEXT * key)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* c l e a n u p _ k e y
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Remove a key, if found unused (no subkeys and no values).
|
|
|
|
* This function is silent.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
HKEY hkey;
|
|
|
|
|
|
|
|
if (RegOpenKeyEx(hkey_rootnode, key, 0,
|
|
|
|
KEY_READ | KEY_WRITE, &hkey) == ERROR_SUCCESS)
|
|
|
|
{
|
2003-10-20 12:35:38 +02:00
|
|
|
DWORD subkeys_count, values_count;
|
2003-10-12 13:48:33 +02:00
|
|
|
if (RegQueryInfoKey(hkey, NULL, 0, 0,
|
2003-10-08 11:42:23 +02:00
|
|
|
&subkeys_count, NULL, NULL,
|
|
|
|
&values_count, 0, 0, NULL, NULL) == ERROR_SUCCESS &&
|
|
|
|
subkeys_count == 0 && values_count == 0)
|
2003-10-12 13:48:33 +02:00
|
|
|
{
|
|
|
|
RegCloseKey(hkey);
|
|
|
|
RegDeleteKey(hkey_rootnode, key);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
RegCloseKey(hkey);
|
2003-10-08 11:42:23 +02:00
|
|
|
}
|
2003-10-12 13:48:33 +02:00
|
|
|
return;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-10-08 11:42:23 +02:00
|
|
|
#ifdef THIS_CODE_IS_TEMPORARILY_NOT_USED_ANYMORE
|
|
|
|
// I keep it here for possible re-use after FB 1.5 release. OM, sept 30, 2003.
|
2001-05-23 15:26:42 +02:00
|
|
|
static USHORT remove_subkeys(
|
|
|
|
HKEY hkey,
|
2003-10-20 12:35:38 +02:00
|
|
|
bool silent_flag, USHORT(*err_handler)(SLONG, TEXT*, HKEY))
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* r e m o v e _ s u b k e y s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
2003-10-12 13:48:33 +02:00
|
|
|
* Remove all sub-keys of an Firebird key from the registry.
|
2001-05-23 15:26:42 +02:00
|
|
|
*
|
|
|
|
**************************************/
|
2003-10-20 12:35:38 +02:00
|
|
|
TEXT buffer[MAXPATHLEN], *p;
|
|
|
|
DWORD n_sub_keys, max_sub_key;
|
2001-05-23 15:26:42 +02:00
|
|
|
FILETIME last_write_time;
|
|
|
|
|
2003-10-20 12:35:38 +02:00
|
|
|
DWORD buf_len = sizeof(buffer);
|
|
|
|
DWORD status = RegQueryInfoKey(hkey,
|
2001-05-23 15:26:42 +02:00
|
|
|
buffer, &buf_len,
|
|
|
|
NULL,
|
|
|
|
&n_sub_keys,
|
|
|
|
&max_sub_key,
|
|
|
|
&i, &i, &i, &i, &i, &last_write_time);
|
2002-11-14 09:33:08 +01:00
|
|
|
if (status != ERROR_SUCCESS && status != ERROR_MORE_DATA) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (silent_flag)
|
2002-11-14 09:33:08 +01:00
|
|
|
return FB_FAILURE;
|
2001-05-23 15:26:42 +02:00
|
|
|
return (*err_handler) (status, "RegQueryInfoKey", NULL);
|
|
|
|
}
|
|
|
|
|
2003-10-20 12:35:38 +02:00
|
|
|
TEXT* sub_key = (++max_sub_key > sizeof(buffer)) ?
|
|
|
|
(TEXT*) malloc((SLONG) max_sub_key) : buffer;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-10-20 12:35:38 +02:00
|
|
|
TEXT* p = NULL;
|
|
|
|
for (DWORD i = 0; i < n_sub_keys; i++) {
|
|
|
|
DWORD sub_key_len = max_sub_key;
|
2001-05-23 15:26:42 +02:00
|
|
|
if ((status = RegEnumKeyEx(hkey, i, sub_key, &sub_key_len,
|
|
|
|
NULL, NULL, NULL,
|
2002-11-14 09:33:08 +01:00
|
|
|
&last_write_time)) != ERROR_SUCCESS) {
|
2001-05-23 15:26:42 +02:00
|
|
|
p = "RegEnumKeyEx";
|
|
|
|
break;
|
|
|
|
}
|
2003-10-20 12:35:38 +02:00
|
|
|
|
|
|
|
HKEY hkey_sub;
|
2001-05-23 15:26:42 +02:00
|
|
|
if ((status = RegOpenKeyEx(hkey, sub_key,
|
|
|
|
0,
|
|
|
|
KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE |
|
2003-10-20 12:35:38 +02:00
|
|
|
KEY_WRITE, &hkey_sub)) != ERROR_SUCCESS)
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
p = "RegOpenKeyEx";
|
|
|
|
break;
|
|
|
|
}
|
2003-10-20 12:35:38 +02:00
|
|
|
const USHORT ret = remove_subkeys(hkey_sub, silent_flag, err_handler);
|
2001-05-23 15:26:42 +02:00
|
|
|
RegCloseKey(hkey_sub);
|
2002-11-14 09:33:08 +01:00
|
|
|
if (ret == FB_FAILURE)
|
|
|
|
return FB_FAILURE;
|
|
|
|
if ((status = RegDeleteKey(hkey, sub_key)) != ERROR_SUCCESS) {
|
2001-05-23 15:26:42 +02:00
|
|
|
p = "RegDeleteKey";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buffer != sub_key)
|
|
|
|
free(sub_key);
|
|
|
|
|
|
|
|
if (p) {
|
|
|
|
if (silent_flag)
|
2002-11-14 09:33:08 +01:00
|
|
|
return FB_FAILURE;
|
2001-05-23 15:26:42 +02:00
|
|
|
return (*err_handler) (status, p, NULL);
|
|
|
|
}
|
|
|
|
|
2002-11-14 09:33:08 +01:00
|
|
|
return FB_SUCCESS;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
2003-10-08 11:42:23 +02:00
|
|
|
#endif
|