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:
parent
e3f7d6c03f
commit
e7b55e8f01
@ -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;
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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, ®db_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 );
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
@ -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, ®db_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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user