1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-04 17:47:26 +03:00

* refactored registry operations some. subkey lists and

registry values are now passed around in containers
  (REGSUBKEY_CTR & REGVAL_CTR) which each possess a TALLOC_CTX.

* removed subkey_specific_fn() from REGISTRY_OPS.  Is implemented
  in the form of a wrapper

* temporarily broke the printing registry ops.

* implemented inheritence for the data_p of nodes in a SORTED_TREE

* All REGISTRY_KEY instances now store a valid REGISTRY_HOOK since
  the default REGOSTRY_OPS structure is stored in the root of the
  cache_tree.

* Probably some other change I forgot....  T
This commit is contained in:
Gerald Carter -
parent e3f7d6c03f
commit e7b55e8f01
7 changed files with 491 additions and 243 deletions

View File

@ -66,7 +66,7 @@
#define KEY_HKLM "HKLM"
#define KEY_HKU "HKU"
#define KEY_PRINTING "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print"
#define KEY_TREE_ROOT ""
/* Registry data types */
@ -89,7 +89,7 @@
/* structure to contain registry values */
typedef struct _RegistryValue {
typedef struct {
fstring valuename;
uint16 type;
uint32 size; /* in bytes */
@ -100,22 +100,37 @@ typedef struct _RegistryValue {
} data;
} REGISTRY_VALUE;
/* container for regostry values */
typedef struct {
TALLOC_CTX *ctx;
uint32 num_values;
REGISTRY_VALUE **values;
} REGVAL_CTR;
/* container for registry subkey names */
typedef struct {
TALLOC_CTX *ctx;
uint32 num_subkeys;
char **subkeys;
} REGSUBKEY_CTR;
/*
* container for function pointers to enumeration routines
* for vitural registry view
*/
typedef struct _reg_ops {
typedef struct {
/* functions for enumerating subkeys and values */
int (*subkey_fn)( char *key, char **subkeys );
int (*subkey_specific_fn)( char *key, char** subkey, uint32 indx );
int (*value_fn) ( char *key, REGISTRY_VALUE **val );
BOOL (*store_subkeys_fn)( char *key, char **subkeys, uint32 num_subkeys );
BOOL (*store_values_fn)( char *key, REGISTRY_VALUE **val, uint32 num_values );
int (*subkey_fn)( char *key, REGSUBKEY_CTR *subkeys);
int (*value_fn) ( char *key, REGVAL_CTR *val );
BOOL (*store_subkeys_fn)( char *key, REGSUBKEY_CTR *subkeys );
BOOL (*store_values_fn)( char *key, REGVAL_CTR *val );
} REGISTRY_OPS;
typedef struct _reg_hook {
typedef struct {
char *keyname; /* full path to name of key */
REGISTRY_OPS *ops; /* registry function hooks */
} REGISTRY_HOOK;

View File

@ -26,7 +26,8 @@
for comparision of two children
*************************************************************************/
SORTED_TREE* sorted_tree_init( int (cmp_fn)(void*, void*),
SORTED_TREE* sorted_tree_init( void *data_p,
int (cmp_fn)(void*, void*),
void (free_fn)(void*) )
{
SORTED_TREE *tree = NULL;
@ -45,6 +46,7 @@ SORTED_TREE* sorted_tree_init( int (cmp_fn)(void*, void*),
}
ZERO_STRUCTP( tree->root );
tree->root->data_p = data_p;
return tree;
}
@ -94,7 +96,6 @@ void sorted_tree_destroy( SORTED_TREE *tree )
static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key )
{
TREE_NODE *infant = NULL;
TREE_NODE *child, *crib;
TREE_NODE **siblings;
int i, result;
@ -116,7 +117,7 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key )
/* first child */
if ( node->num_children == 1 ) {
DEBUG(11,("sorted_tree_birth_child: First child of node [%s]! [%s]\n",
DEBUG(10,("sorted_tree_birth_child: First child of node [%s]! [%s]\n",
node->key ? node->key : "NULL", infant->key ));
node->children[0] = infant;
}
@ -133,23 +134,28 @@ static TREE_NODE* sorted_tree_birth_child( TREE_NODE *node, char* key )
for ( i = node->num_children-1; i>=1; i-- )
{
crib = node->children[i];
child = node->children[i-1];
DEBUG(10,("sorted_tree_birth_child: Looking for crib; infant -> [%s], child -> [%s]\n",
infant->key, child->key));
infant->key, node->children[i-1]->key));
/* the strings should never match assuming that we
have called sorted_tree_find_child() first */
result = StrCaseCmp( infant->key, child->key );
result = StrCaseCmp( infant->key, node->children[i-1]->key );
if ( result > 0 ) {
crib = infant;
node->children[i] = infant;
break;
}
crib = child;
/* bump everything towards the end on slot */
node->children[i] = node->children[i-1];
}
/* if we haven't found the correct clot yet, the child
will be first in the list */
if ( i == 0 )
node->children[0] = infant;
}
return infant;
@ -376,6 +382,9 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key )
str = keystr;
current = tree->root;
if ( tree->root->data_p )
result = tree->root->data_p;
do
{
/* break off the remaining part of the path */
@ -384,7 +393,7 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key )
if ( str )
*str = '\0';
DEBUG(10,("sorted_tree_find: [loop] key => [%s]\n", base));
DEBUG(11,("sorted_tree_find: [loop] key => [%s]\n", base));
/* iterate to the next child */
@ -399,10 +408,18 @@ void* sorted_tree_find( SORTED_TREE *tree, char *key )
str = base;
}
/*
* the idea is that the data_p for a parent should
* be inherited by all children, but allow it to be
* overridden farther down
*/
if ( current && current->data_p )
result = current->data_p;
} while ( base && current );
if ( current )
result = current->data_p;
/* result should be the data_p from the lowest match node in the tree */
SAFE_FREE( keystr );

View File

@ -26,6 +26,8 @@
#define DBGC_CLASS DBGC_RPC_SRV
static SORTED_TREE *cache_tree;
extern REGISTRY_OPS regdb_ops; /* these are the default */
static REGISTRY_HOOK default_hook = { KEY_TREE_ROOT, &regdb_ops };
/**********************************************************************
Initialize the cache tree
@ -33,7 +35,7 @@ static SORTED_TREE *cache_tree;
BOOL reghook_cache_init( void )
{
cache_tree = sorted_tree_init( NULL, NULL );
cache_tree = sorted_tree_init( &default_hook, NULL, NULL );
return ( cache_tree == NULL );
}

View File

@ -34,73 +34,72 @@ static TDB_CONTEXT *tdb_reg;
static BOOL init_registry_data( void )
{
pstring keyname;
char *subkeys[3];
pstring keyname;
REGSUBKEY_CTR subkeys;
ZERO_STRUCTP( &subkeys );
regsubkey_ctr_init( &subkeys );
/* HKEY_LOCAL_MACHINE */
pstrcpy( keyname, KEY_HKLM );
subkeys[0] = "SYSTEM";
if ( !regdb_store_reg_keys( keyname, subkeys, 1 ))
regsubkey_ctr_addkey( &subkeys, "SYSTEM" );
if ( !regdb_store_reg_keys( keyname, &subkeys ))
return False;
regsubkey_ctr_destroy( &subkeys );
pstrcpy( keyname, KEY_HKLM );
pstrcat( keyname, "/SYSTEM" );
subkeys[0] = "CurrentControlSet";
if ( !regdb_store_reg_keys( keyname, subkeys, 1 ))
regsubkey_ctr_addkey( &subkeys, "CurrentControlSet" );
if ( !regdb_store_reg_keys( keyname, &subkeys ))
return False;
regsubkey_ctr_destroy( &subkeys );
pstrcpy( keyname, KEY_HKLM );
pstrcat( keyname, "/SYSTEM/CurrentControlSet" );
subkeys[0] = "Control";
subkeys[1] = "services";
if ( !regdb_store_reg_keys( keyname, subkeys, 2 ))
regsubkey_ctr_addkey( &subkeys, "Control" );
regsubkey_ctr_addkey( &subkeys, "services" );
if ( !regdb_store_reg_keys( keyname, &subkeys ))
return False;
regsubkey_ctr_destroy( &subkeys );
pstrcpy( keyname, KEY_HKLM );
pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control" );
subkeys[0] = "Print";
subkeys[1] = "ProduceOptions";
if ( !regdb_store_reg_keys( keyname, subkeys, 2 ))
regsubkey_ctr_addkey( &subkeys, "Print" );
regsubkey_ctr_addkey( &subkeys, "ProductOptions" );
if ( !regdb_store_reg_keys( keyname, &subkeys ))
return False;
#if 0 /* JERRY */
pstrcpy( keyname, KEY_HKLM );
pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control/Print" );
subkeys[0] = "Environments";
subkeys[1] = "Forms";
subkeys[2] = "Printers";
if ( !regdb_store_reg_keys( keyname, subkeys, 0 ))
return False;
#endif
regsubkey_ctr_destroy( &subkeys );
pstrcpy( keyname, KEY_HKLM );
pstrcat( keyname, "/SYSTEM/CurrentControlSet/Control/ProductOptions" );
if ( !regdb_store_reg_keys( keyname, subkeys, 0 ))
if ( !regdb_store_reg_keys( keyname, &subkeys ))
return False;
pstrcpy( keyname, KEY_HKLM );
pstrcat( keyname, "/SYSTEM/CurrentControlSet/services" );
subkeys[0] = "Netlogon";
if ( !regdb_store_reg_keys( keyname, subkeys, 1 ))
regsubkey_ctr_addkey( &subkeys, "Netlogon" );
if ( !regdb_store_reg_keys( keyname, &subkeys ))
return False;
regsubkey_ctr_destroy( &subkeys );
pstrcpy( keyname, KEY_HKLM );
pstrcat( keyname, "/SYSTEM/CurrentControlSet/services/Netlogon" );
subkeys[0] = "parameters";
if ( !regdb_store_reg_keys( keyname, subkeys, 1 ))
regsubkey_ctr_addkey( &subkeys, "parameters" );
if ( !regdb_store_reg_keys( keyname, &subkeys ))
return False;
regsubkey_ctr_destroy( &subkeys );
pstrcpy( keyname, KEY_HKLM );
pstrcat( keyname, "/SYSTEM/CurrentControlSet/services/Netlogon/parameters" );
if ( !regdb_store_reg_keys( keyname, subkeys, 0 ))
if ( !regdb_store_reg_keys( keyname, &subkeys ))
return False;
/* HKEY_USER */
pstrcpy( keyname, KEY_HKU );
if ( !regdb_store_reg_keys( keyname, subkeys, 0 ) )
if ( !regdb_store_reg_keys( keyname, &subkeys ) )
return False;
return True;
@ -157,13 +156,14 @@ BOOL init_registry_db( void )
\'s are converted to /'s.
***********************************************************************/
BOOL regdb_store_reg_keys( char *keyname, char **subkeys, uint32 num_subkeys )
BOOL regdb_store_reg_keys( char *keyname, REGSUBKEY_CTR *ctr )
{
TDB_DATA kbuf, dbuf;
char *buffer, *tmpbuf;
int i = 0;
uint32 len, buflen;
BOOL ret = True;
uint32 num_subkeys = regsubkey_ctr_numkeys( ctr );
if ( !keyname )
return False;
@ -176,23 +176,23 @@ BOOL regdb_store_reg_keys( char *keyname, char **subkeys, uint32 num_subkeys )
/* store the number of subkeys */
len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys);
len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys );
/* pack all the strings */
for (i=0; i<num_subkeys; i++) {
len += tdb_pack(buffer+len, buflen-len, "f", subkeys[i]);
len += tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
if ( len > buflen ) {
/* allocate some extra space */
if ((tmpbuf = Realloc( buffer, len*2 )) == NULL) {
DEBUG(0,("store_reg_keys: Failed to realloc memory of size [%d]\n", len*2));
DEBUG(0,("regdb_store_reg_keys: Failed to realloc memory of size [%d]\n", len*2));
ret = False;
goto done;
}
buffer = tmpbuf;
buflen = len*2;
len = tdb_pack(buffer+len, buflen-len, "f", subkeys[i]);
len = tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
}
}
@ -218,7 +218,7 @@ done:
of null terminated character strings
***********************************************************************/
int regdb_fetch_reg_keys( char* key, char **subkeys )
int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr )
{
pstring path;
uint32 num_items;
@ -226,7 +226,7 @@ int regdb_fetch_reg_keys( char* key, char **subkeys )
char *buf;
uint32 buflen, len;
int i;
char *s;
fstring subkeyname;
pstrcpy( path, key );
@ -240,63 +240,21 @@ int regdb_fetch_reg_keys( char* key, char **subkeys )
buflen = dbuf.dsize;
if ( !buf ) {
DEBUG(5,("fetch_reg_keys: Failed to fetch any subkeys for [%s]\n", key));
DEBUG(5,("regdb_fetch_reg_keys: Failed to fetch any subkeys for [%s]\n", key));
return 0;
}
len = tdb_unpack( buf, buflen, "d", &num_items);
if (num_items) {
if ( (*subkeys = (char*)malloc(sizeof(fstring)*num_items)) == NULL ) {
DEBUG(0,("fetch_reg_keys: Failed to malloc memory for subkey array containing [%d] items!\n",
num_items));
num_items = -1;
goto done;
}
}
s = *subkeys;
for (i=0; i<num_items; i++) {
len += tdb_unpack( buf+len, buflen-len, "f", s );
s += strlen(s) + 1;
len += tdb_unpack( buf+len, buflen-len, "f", subkeyname );
regsubkey_ctr_addkey( ctr, subkeyname );
}
done:
SAFE_FREE(dbuf.dptr);
return num_items;
}
/***********************************************************************
retreive a specific subkey specified by index. The subkey parameter
is assumed to be an fstring.
***********************************************************************/
BOOL regdb_fetch_reg_keys_specific( char* key, char** subkey, uint32 key_index )
{
int num_subkeys, i;
char *subkeys = NULL;
char *s;
num_subkeys = regdb_fetch_reg_keys( key, &subkeys );
if ( num_subkeys == -1 )
return False;
s = subkeys;
for ( i=0; i<num_subkeys; i++ ) {
/* copy the key if the index matches */
if ( i == key_index ) {
*subkey = strdup( s );
break;
}
/* go onto the next string */
s += strlen(s) + 1;
}
SAFE_FREE(subkeys);
return True;
}
/***********************************************************************
Retrieve an array of strings containing subkeys. Memory should be
@ -304,8 +262,31 @@ BOOL regdb_fetch_reg_keys_specific( char* key, char** subkey, uint32 key_index )
of null terminated character strings
***********************************************************************/
int regdb_fetch_reg_values( char* key, REGISTRY_VALUE **val )
int regdb_fetch_reg_values( char* key, REGVAL_CTR *val )
{
return 0;
}
/***********************************************************************
Stub function since we do not currently support storing registry
values in the registry.tdb
***********************************************************************/
BOOL regdb_store_reg_values( char *key, REGVAL_CTR *val )
{
return False;
}
/*
* Table of function pointers for default access
*/
REGISTRY_OPS regdb_ops = {
regdb_fetch_reg_keys,
regdb_fetch_reg_values,
regdb_store_reg_keys,
regdb_store_reg_values
};

View File

@ -26,12 +26,14 @@
#define DBGC_CLASS DBGC_RPC_SRV
extern REGISTRY_OPS printing_ops;
extern REGISTRY_OPS regdb_ops; /* these are the default */
/* array of REGISTRY_HOOK's which are read into a tree for easy access */
REGISTRY_HOOK reg_hooks[] = {
{ KEY_PRINTING, &printing_ops },
{ KEY_TREE_ROOT, &regdb_ops },
{ KEY_PRINTING, &printing_ops },
{ NULL, NULL }
};
@ -70,9 +72,12 @@ BOOL init_registry( void )
High level wrapper function for storing registry subkeys
***********************************************************************/
BOOL store_reg_keys( REGISTRY_KEY *key, char **subkeys, uint32 num_subkeys )
BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
{
return regdb_store_reg_keys( key->name, subkeys, num_subkeys );
if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys_fn )
return key->hook->ops->store_subkeys_fn( key->name, subkeys );
else
return False;
}
@ -80,60 +85,210 @@ BOOL store_reg_keys( REGISTRY_KEY *key, char **subkeys, uint32 num_subkeys )
High level wrapper function for storing registry values
***********************************************************************/
BOOL store_reg_values( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 num_values )
BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
{
return True;
if ( key->hook && key->hook->ops && key->hook->ops->store_values_fn )
return key->hook->ops->store_values_fn( key->name, val );
else
return False;
}
/***********************************************************************
High level wrapper function for enumerating registry subkeys
Initialize the TALLOC_CTX if necessary
***********************************************************************/
int fetch_reg_keys( REGISTRY_KEY *key, char **subkeys )
int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
{
int num_subkeys;
int result = -1;
if ( key->hook && key->hook->ops && key->hook->ops->subkey_fn )
num_subkeys = key->hook->ops->subkey_fn( key->name, subkeys );
else
num_subkeys = regdb_fetch_reg_keys( key->name, subkeys );
result = key->hook->ops->subkey_fn( key->name, subkey_ctr );
return num_subkeys;
return result;
}
/***********************************************************************
High level wrapper function for retreiving a specific registry subkey
given and index.
retreive a specific subkey specified by index. Caller is
responsible for freeing memory
***********************************************************************/
BOOL fetch_reg_keys_specific( REGISTRY_KEY *key, char** subkey, uint32 key_index )
{
BOOL result;
if ( key->hook && key->hook->ops && key->hook->ops->subkey_specific_fn )
result = key->hook->ops->subkey_specific_fn( key->name, subkey, key_index );
else
result = regdb_fetch_reg_keys_specific( key->name, subkey, key_index );
char *s;
REGSUBKEY_CTR ctr;
return result;
ZERO_STRUCTP( &ctr );
regsubkey_ctr_init( &ctr );
if ( fetch_reg_keys( key, &ctr) == -1 )
return False;
if ( !(s = regsubkey_ctr_specific_key( &ctr, key_index )) )
return False;
*subkey = strdup( s );
regsubkey_ctr_destroy( &ctr );
return True;
}
/***********************************************************************
High level wrapper function for enumerating registry values
Initialize the TALLOC_CTX if necessary
***********************************************************************/
int fetch_reg_values( REGISTRY_KEY *key, REGISTRY_VALUE **val )
int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
{
int num_values;
int result = -1;
if ( key->hook && key->hook->ops && key->hook->ops->value_fn )
num_values = key->hook->ops->value_fn( key->name, val );
else
num_values = regdb_fetch_reg_values( key->name, val );
return num_values;
result = key->hook->ops->value_fn( key->name, val );
return result;
}
/***********************************************************************
Utility function for splitting the base path of a registry path off
by setting base and new_path to the apprapriate offsets withing the
path.
WARNING!! Does modify the original string!
***********************************************************************/
BOOL reg_split_path( char *path, char **base, char **new_path )
{
char *p;
*new_path = *base = NULL;
if ( !path)
return False;
*base = path;
p = strchr( path, '\\' );
if ( p ) {
*p = '\0';
*new_path = p+1;
}
return True;
}
/*
* Utility functions for REGSUBKEY_CTR
*/
/***********************************************************************
Init the talloc context held by a REGSUBKEY_CTR structure
**********************************************************************/
void regsubkey_ctr_init( REGSUBKEY_CTR *ctr )
{
if ( !ctr->ctx )
ctr->ctx = talloc_init();
}
/***********************************************************************
Add a new key to the array
**********************************************************************/
int regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, char *keyname )
{
uint32 len;
if ( keyname )
{
len = strlen( keyname );
if ( ctr->subkeys == 0 )
ctr->subkeys = talloc( ctr->ctx, 1 );
else
talloc_realloc( ctr->ctx, ctr->subkeys, ctr->num_subkeys+1 );
ctr->subkeys[ctr->num_subkeys] = talloc( ctr->ctx, len+1 );
strncpy( ctr->subkeys[ctr->num_subkeys], keyname, len+1 );
ctr->num_subkeys++;
}
return ctr->num_subkeys;
}
/***********************************************************************
How many keys does the container hold ?
**********************************************************************/
int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr )
{
return ctr->num_subkeys;
}
/***********************************************************************
Retreive a specific key string
**********************************************************************/
char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 index )
{
if ( ! (index < ctr->num_subkeys) )
return NULL;
return ctr->subkeys[index];
}
/***********************************************************************
free memory held by a REGSUBKEY_CTR structure
**********************************************************************/
void regsubkey_ctr_destroy( REGSUBKEY_CTR *ctr )
{
if ( ctr )
talloc_destroy( ctr->ctx );
ctr->num_subkeys = 0;
ctr->subkeys = NULL;
}
/*
* Utility functions for REGVAL_CTR
*/
/***********************************************************************
Init the talloc context held by a REGSUBKEY_CTR structure
**********************************************************************/
void regval_ctr_init( REGVAL_CTR *ctr )
{
if ( !ctr->ctx )
ctr->ctx = talloc_init();
}
/***********************************************************************
How many keys does the container hold ?
**********************************************************************/
int regval_ctr_numvals( REGVAL_CTR *ctr )
{
return ctr->num_values;
}
/***********************************************************************
free memory held by a REGVAL_CTR structure
**********************************************************************/
void regval_ctr_destroy( REGVAL_CTR *ctr )
{
if ( ctr )
talloc_destroy( ctr->ctx );
ctr->num_values = 0;
ctr->values = NULL;
}

View File

@ -51,9 +51,26 @@ static char *top_level_keys[MAX_TOP_LEVEL_KEYS] = {
static char* trim_reg_path( char *path )
{
char *p;
uint16 key_len = strlen(KEY_PRINTING);
/*
* sanity check...this really should never be True.
* It is only here to prevent us from accessing outside
* the path buffer in the extreme case.
*/
if ( strlen(path) < key_len ) {
DEBUG(0,("trim_reg_path: Registry path too short! [%s]\n", path));
DEBUG(0,("trim_reg_path: KEY_PRINTING => [%s]!\n", KEY_PRINTING));
return NULL;
}
p = path + strlen(KEY_PRINTING);
if ( *p == '\\' )
p++;
if ( *p )
return strdup(p);
else
@ -61,15 +78,98 @@ static char* trim_reg_path( char *path )
}
/**********************************************************************
handle enumeration of subkeys below KEY_PRINTING.
handle enumeration of subkeys below KEY_PRINTING\Environments
*********************************************************************/
static int handle_printing_subpath( char *key, char **subkeys, uint32 index )
static int print_subpath_environments( char *key, REGSUBKEY_CTR *subkeys, int32 idx )
{
DEBUG(10,("print_subpath_environments: key=>[%s]\n", key ? key : "NULL" ));
if ( !key )
{
/* listed architectures of installed drivers */
}
return 0;
}
/**********************************************************************
handle enumeration of subkeys below KEY_PRINTING\Forms
*********************************************************************/
static int print_subpath_forms( char *key, REGSUBKEY_CTR *subkeys, int32 idx )
{
DEBUG(10,("print_subpath_forms: key=>[%s]\n", key ? key : "NULL" ));
return 0;
}
/**********************************************************************
handle enumeration of values below KEY_PRINTING\Forms
*********************************************************************/
static int print_values_forms( char *key, REGVAL_CTR *val, int idx )
{
int num_values = 0;
DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" ));
/* handle ..\Forms\ */
#if 0 /* JERRY */
if ( !key )
{
nt_forms_struct *forms = NULL;
int i;
if ( (num_values = get_ntforms( &forms )) == 0 )
return 0;
if ( !(*values = malloc(sizeof(REGISTRY_VALUE) * num_values)) ) {
DEBUG(0,("print_values_forms: Failed to malloc memory for [%d] REGISTRY_VALUE structs!\n",
num_values));
return -1;
}
for ( i=0; i<num_values; i++ )
{
}
}
#endif
return num_values;
}
/**********************************************************************
handle enumeration of subkeys below KEY_PRINTING\Printers
*********************************************************************/
static int print_subpath_printers( char *key, REGSUBKEY_CTR *subkeys, int32 idx )
{
DEBUG(10,("print_subpath_printers: key=>[%s]\n", key ? key : "NULL" ));
return 0;
}
/**********************************************************************
Routine to handle enumeration of subkeys and values
below KEY_PRINTING (depending on whether or not subkeys/val are
valid pointers.
*********************************************************************/
static int handle_printing_subpath( char *key, REGSUBKEY_CTR *subkeys,
REGVAL_CTR *val, int32 key_index, int32 val_index )
{
int result = 0;
char *p, *base;
int i;
DEBUG(10,("handle_printing_subpath: key=>[%s], key_index == [%d], val_index == [%d]\n",
key, key_index, val_index));
/*
* break off the first part of the path
@ -77,29 +177,36 @@ static int handle_printing_subpath( char *key, char **subkeys, uint32 index )
* in top_level_keys[]
*/
base = key;
p = strchr( key, '\\' );
if ( p )
*p = '\0';
reg_split_path( key, &base, &p);
for ( i=0; i<MAX_TOP_LEVEL_KEYS; i++ ) {
if ( StrCaseCmp( top_level_keys[i], base ) == 0 )
break;
}
if ( !(i < MAX_TOP_LEVEL_KEYS) )
DEBUG(10,("handle_printing_subpath: base=>[%s], i==[%d]\n", base, i));
if ( (key_index != -1) && !(i < MAX_TOP_LEVEL_KEYS) )
return -1;
/* Call routine to handle each top level key */
switch ( i )
{
case KEY_INDEX_ENVIR:
if ( subkeys )
print_subpath_environments( p, subkeys, key_index );
#if 0 /* JERRY */
if ( val )
print_subpath_values_environments( p, val, val_index );
#endif
break;
case KEY_INDEX_FORMS:
result = print_subpath_forms( p, subkeys, key_index );
break;
case KEY_INDEX_PRINTER:
result = print_subpath_printers( p, subkeys, key_index );
break;
/* default case for top level key that has no handler */
@ -118,7 +225,7 @@ static int handle_printing_subpath( char *key, char **subkeys, uint32 index )
Caller is responsible for freeing memory to **subkeys
*********************************************************************/
int printing_subkey_info( char *key, char **subkeys )
int printing_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr )
{
char *path;
BOOL top_level = False;
@ -134,32 +241,29 @@ int printing_subkey_info( char *key, char **subkeys )
top_level = True;
if ( top_level ) {
if ( ! (*subkeys = malloc( sizeof(top_level_keys) )) )
goto done;
num_subkeys = MAX_TOP_LEVEL_KEYS;
memcpy( *subkeys, top_level_keys, sizeof(top_level_keys) );
for ( num_subkeys=0; num_subkeys<MAX_TOP_LEVEL_KEYS; num_subkeys++ )
regsubkey_ctr_addkey( subkey_ctr, top_level_keys[num_subkeys] );
}
else
num_subkeys = handle_printing_subpath( path, subkeys, -1 );
num_subkeys = handle_printing_subpath( path, subkey_ctr, NULL, -1, -1 );
done:
SAFE_FREE( path );
return num_subkeys;
}
/**********************************************************************
Count the registry subkey names given a registry path.
Caller is responsible for freeing memory to **subkey
Enumerate registry values given a registry path.
Caller is responsible for freeing memory
*********************************************************************/
BOOL printing_subkey_specific( char *key, char** subkey, uint32 indx )
int printing_value_info( char *key, REGVAL_CTR *val )
{
char *path;
BOOL top_level = False;
BOOL result = False;
int num_values = 0;
DEBUG(10,("printing_subkey_specific: key=>[%s], index=>[%d]\n", key, indx));
DEBUG(10,("printing_value_info: key=>[%s]\n", key));
path = trim_reg_path( key );
@ -168,43 +272,16 @@ BOOL printing_subkey_specific( char *key, char** subkey, uint32 indx )
if ( !path )
top_level = True;
if ( top_level ) {
/* make sure the index is in range */
if ( !(indx < MAX_TOP_LEVEL_KEYS) )
goto done;
if ( !(*subkey = malloc( strlen(top_level_keys[indx])+1 )) )
goto done;
strncpy( *subkey, top_level_keys[indx], strlen(top_level_keys[indx])+1 );
result = True;
}
else {
if ( handle_printing_subpath( path, subkey, indx ) != -1 )
result = True;
/* fill in values from the getprinterdata_printer_server() */
if ( top_level )
{
num_values = 0;
}
else
num_values = handle_printing_subpath( path, NULL, val, -1, -1 );
done:
SAFE_FREE( path );
return result;
}
/**********************************************************************
Enumerate registry values given a registry path.
Caller is responsible for freeing memory
*********************************************************************/
int printing_value_info( char *key, REGISTRY_VALUE **val )
{
DEBUG(10,("printing_value_info: key=>[%s]\n", key));
return 0;
return num_values;
}
/**********************************************************************
@ -213,7 +290,7 @@ int printing_value_info( char *key, REGISTRY_VALUE **val )
(for now at least)
*********************************************************************/
BOOL printing_store_subkey( char *key, char **subkeys, uint32 num_subkeys )
BOOL printing_store_subkey( char *key, REGSUBKEY_CTR *subkeys )
{
return False;
}
@ -224,7 +301,7 @@ BOOL printing_store_subkey( char *key, char **subkeys, uint32 num_subkeys )
(for now at least)
*********************************************************************/
BOOL printing_store_value( char *key, REGISTRY_VALUE **val, uint32 num_values )
BOOL printing_store_value( char *key, REGVAL_CTR *val )
{
return False;
}
@ -235,9 +312,9 @@ BOOL printing_store_value( char *key, REGISTRY_VALUE **val, uint32 num_values )
REGISTRY_OPS printing_ops = {
printing_subkey_info,
printing_subkey_specific,
printing_value_info,
printing_store_subkey,
printing_store_value
};

View File

@ -40,7 +40,7 @@ static REGISTRY_KEY *regkeys_list;
free() function for REGISTRY_KEY
*****************************************************************/
static void free_reg_info(void *ptr)
static void free_regkey_info(void *ptr)
{
REGISTRY_KEY *info = (REGISTRY_KEY*)ptr;
@ -77,11 +77,10 @@ static REGISTRY_KEY *find_regkey_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY *parent,
char *subkeyname, uint32 access_granted )
{
REGISTRY_KEY *regkey = NULL;
pstring parent_keyname;
NTSTATUS result = NT_STATUS_OK;
int num_subkeys;
char *subkeys = NULL;
REGISTRY_KEY *regkey = NULL;
pstring parent_keyname;
NTSTATUS result = NT_STATUS_OK;
REGSUBKEY_CTR subkeys;
if ( parent ) {
pstrcpy( parent_keyname, parent->name );
@ -110,27 +109,23 @@ static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY
pstrcpy( regkey->name, parent_keyname );
pstrcat( regkey->name, subkeyname );
/* try to use en existing hook. Otherwise, try to lookup our own */
/* Look up the table of registry I/O operations */
if ( parent && parent->hook )
regkey->hook = parent->hook;
else
regkey->hook = reghook_cache_find( regkey->name );
if ( regkey->hook ) {
DEBUG(10,("open_registry_key: Assigned REGISTRY_HOOK to [%s]\n",
if ( !(regkey->hook = reghook_cache_find( regkey->name )) ) {
DEBUG(0,("open_registry_key: Failed to assigned a REGISTRY_HOOK to [%s]\n",
regkey->name ));
return NT_STATUS_OBJECT_PATH_NOT_FOUND;
}
/* check if the path really exists...num_subkeys should be >= 0 */
num_subkeys = fetch_reg_keys( regkey, &subkeys );
/* check if the path really exists; failed is indicated by -1 */
/* if the subkey count failed, bail out */
ZERO_STRUCTP( &subkeys );
regsubkey_ctr_init( &subkeys );
if ( fetch_reg_keys( regkey, &subkeys ) == -1 ) {
if ( num_subkeys == -1 ) {
SAFE_FREE( regkey );
/* don't really know what to return here */
result = NT_STATUS_ACCESS_DENIED;
@ -141,13 +136,18 @@ static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY
* that doesn't sound quite right to me --jerry
*/
if ( !create_policy_hnd( p, hnd, free_reg_info, regkey ) )
if ( !create_policy_hnd( p, hnd, free_regkey_info, regkey ) )
result = NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
DEBUG(7,("open_registry_key: exit\n"));
SAFE_FREE( subkeys );
/* clean up */
regsubkey_ctr_destroy( &subkeys );
if ( ! NT_STATUS_IS_OK(result) )
SAFE_FREE( regkey );
return result;
}
@ -177,37 +177,35 @@ static BOOL close_registry_key(pipes_struct *p, POLICY_HND *hnd)
static BOOL get_subkey_information( REGISTRY_KEY *key, uint32 *maxnum, uint32 *maxlen )
{
int num_subkeys, i;
uint32 max_len;
char *subkeys = NULL;
uint32 len;
char *s;
int num_subkeys, i;
uint32 max_len;
REGSUBKEY_CTR subkeys;
uint32 len;
if ( !key )
return False;
ZERO_STRUCTP( &subkeys );
/* first use any registry hook available.
Fall back to tdb if non available */
regsubkey_ctr_init( &subkeys );
num_subkeys = fetch_reg_keys( key, &subkeys );
if ( num_subkeys == -1 )
if ( fetch_reg_keys( key, &subkeys ) == -1 )
return False;
/* find the longest string */
max_len = 0;
s = subkeys;
num_subkeys = regsubkey_ctr_numkeys( &subkeys );
for ( i=0; i<num_subkeys; i++ ) {
len = strlen(s);
len = strlen( regsubkey_ctr_specific_key(&subkeys, i) );
max_len = MAX(max_len, len);
s += len + 1;
}
*maxnum = num_subkeys;
*maxlen = max_len*2;
SAFE_FREE(subkeys);
regsubkey_ctr_destroy( &subkeys );
return True;
}
@ -221,31 +219,34 @@ static BOOL get_subkey_information( REGISTRY_KEY *key, uint32 *maxnum, uint32 *m
static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum,
uint32 *maxlen, uint32 *maxsize )
{
REGISTRY_VALUE *val = NULL;
uint32 i, sizemax, lenmax;
int num_values;
REGVAL_CTR val;
uint32 sizemax, lenmax;
int num_values;
if ( !key )
return False;
num_values = fetch_reg_values( key, &val );
if ( num_values == -1 )
ZERO_STRUCTP( &val );
regval_ctr_init( &val );
if ( fetch_reg_values( key, &val ) == -1 )
return False;
lenmax = sizemax = 0;
num_values = regval_ctr_numvals( &val );
#if 0 /* JERRY */
for ( i=0; i<num_values; i++ ) {
lenmax = MAX(lenmax, strlen(val[i].valuename)+1 );
sizemax = MAX(sizemax, val[i].size );
}
#endif
*maxnum = num_values;
*maxlen = lenmax;
*maxsize = sizemax;
SAFE_FREE( val );
regval_ctr_destroy( &val );
return True;
}