8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-31 06:43:02 +01:00
firebird-mirror/src/utilities/install/registry.cpp

253 lines
6.6 KiB
C++
Raw Normal View History

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
*/
#include "firebird.h"
2001-05-23 15:26:42 +02:00
#include "../jrd/ib_stdio.h"
#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
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
* Install Firebird in the registry.
2001-05-23 15:26:42 +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,
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;
}
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)
{
RegDeleteKey(hkey_rootnode, REG_KEY_ROOT_INSTANCES);
cleanup_key(hkey_rootnode, REG_KEY_ROOT_PRODUCT);
cleanup_key(hkey_rootnode, REG_KEY_ROOT_COMPANY);
}
return FB_FAILURE;
2001-05-23 15:26:42 +02:00
}
RegCloseKey(hkey_instances);
return FB_SUCCESS;
2001-05-23 15:26:42 +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
* Remove Firebird from the registry.
2001-05-23 15:26:42 +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)
{
2001-05-23 15:26:42 +02:00
if (silent_flag)
return FB_FAILURE;
2001-05-23 15:26:42 +02:00
return (*err_handler) (status, "RegOpenKeyEx", NULL);
}
// Remove the DEFAULT_INSTANCE value
if ((status = RegDeleteValue(hkey_instances, FB_DEFAULT_INSTANCE))
!= ERROR_SUCCESS)
{
RegCloseKey(hkey_instances);
2001-05-23 15:26:42 +02:00
if (silent_flag)
return FB_FAILURE;
return (*err_handler) (status, "RegDeleteValue", NULL);
2001-05-23 15:26:42 +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;
if (RegQueryInfoKey(hkey, NULL, 0, 0,
&subkeys_count, NULL, NULL,
&values_count, 0, 0, NULL, NULL) == ERROR_SUCCESS &&
subkeys_count == 0 && values_count == 0)
{
RegCloseKey(hkey);
RegDeleteKey(hkey_rootnode, key);
}
else
RegCloseKey(hkey);
}
return;
2001-05-23 15:26:42 +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
* 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);
if (status != ERROR_SUCCESS && status != ERROR_MORE_DATA) {
2001-05-23 15:26:42 +02:00
if (silent_flag)
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,
&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);
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)
return FB_FAILURE;
2001-05-23 15:26:42 +02:00
return (*err_handler) (status, p, NULL);
}
return FB_SUCCESS;
2001-05-23 15:26:42 +02:00
}
#endif