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

* changed structure of REG_R_ENUM_VALUE structure since the BUFFER2

is not and [in/out] buffer

* registry value enumeration is working now for the Print\Forms
  key.  The format of the binary data is not quite right yet
  but all installed forms are listed
(This used to be commit 998eb9c7312c3c9a9ed1e9ec294593503c0304bf)
This commit is contained in:
Gerald Carter 2002-07-23 04:55:06 +00:00
parent 445a52ebb0
commit e8177d1104
6 changed files with 401 additions and 180 deletions

View File

@ -32,7 +32,6 @@
#define REG_CREATE_KEY 0x06
#define REG_DELETE_KEY 0x07
#define REG_DELETE_VALUE 0x08
#define REG_ENUM_VALUE 0x0a
#define REG_FLUSH_KEY 0x0b
#define REG_GET_KEY_SEC 0x0c
#define _REG_UNK_0D 0x0d
@ -50,6 +49,7 @@
#define REG_OPEN_HKU 0x04
#define REG_CLOSE 0x05
#define REG_ENUM_KEY 0x09
#define REG_ENUM_VALUE 0x0a
#define REG_OPEN_ENTRY 0x0f
#define REG_QUERY_KEY 0x10
#define REG_INFO 0x11
@ -97,6 +97,7 @@ typedef struct {
char *string;
uint32 dword;
uint8 *binary;
void *void_ptr; /* for casting only */
} data;
} REGISTRY_VALUE;
@ -314,6 +315,7 @@ typedef struct q_reg_query_value_info
uint32 ptr2; /* pointer */
uint32 len_value2; /* */
} REG_Q_ENUM_VALUE;
/* REG_R_ENUM_VALUE */
@ -326,7 +328,7 @@ typedef struct r_reg_enum_value_info
uint32 type; /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */
uint32 ptr_value; /* pointer */
BUFFER2 *buf_value; /* value, in byte buffer */
BUFFER2 buf_value; /* value, in byte buffer */
uint32 ptr1; /* pointer */
uint32 len_value1; /* */

View File

@ -37,6 +37,264 @@ REGISTRY_HOOK reg_hooks[] = {
};
/*
* 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;
char **pp;
if ( keyname )
{
len = strlen( keyname );
/* allocate a space for the char* in the array */
if ( ctr->subkeys == 0 )
ctr->subkeys = talloc( ctr->ctx, sizeof(char*) );
else {
pp = talloc_realloc( ctr->ctx, ctr->subkeys, sizeof(char*)*(ctr->num_subkeys+1) );
if ( pp )
ctr->subkeys = pp;
}
/* allocate the string and save it in the array */
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 key_index )
{
if ( ! (key_index < ctr->num_subkeys) )
return NULL;
return ctr->subkeys[key_index];
}
/***********************************************************************
free memory held by a REGSUBKEY_CTR structure
**********************************************************************/
void regsubkey_ctr_destroy( REGSUBKEY_CTR *ctr )
{
if ( ctr ) {
talloc_destroy( ctr->ctx );
ZERO_STRUCTP( ctr );
}
}
/*
* 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;
}
/***********************************************************************
allocate memory for and duplicate a REGISTRY_VALUE.
This is malloc'd memory so the caller should free it when done
**********************************************************************/
REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val )
{
REGISTRY_VALUE *copy = NULL;
BOOL fail = True;
if ( !val )
return NULL;
if ( !(copy = malloc( sizeof(REGISTRY_VALUE) )) ) {
DEBUG(0,("dup_registry_value: malloc() failed!\n"));
return NULL;
}
/* copy all the non-pointer initial data */
memcpy( copy, val, sizeof(REGISTRY_VALUE) );
switch ( val->type ) {
case REG_SZ:
if ( !(copy->data.string = strdup( val->data.string )) ) {
DEBUG(0,("dup_registry_value: strdup() failed for [%s]!\n",
val->data.string));
goto done;
}
break;
case REG_DWORD:
/* nothing to be done; already copied by memcpy() */
break;
case REG_BINARY:
if ( !(copy->data.string = memdup( val->data.binary, val->size )) ) {
DEBUG(0,("dup_registry_value: memdup() failed for [%d] bytes!\n",
val->size));
goto done;
}
break;
}
fail = False;
done:
if ( fail )
SAFE_FREE( copy );
return copy;
}
/**********************************************************************
free the memory allocated to a REGISTRY_VALUE
*********************************************************************/
void free_registry_value( REGISTRY_VALUE *val )
{
if ( !val )
return;
switch ( val->type )
{
case REG_SZ:
SAFE_FREE( val->data.string );
break;
case REG_BINARY:
SAFE_FREE( val->data.binary );
break;
}
SAFE_FREE( val );
return;
}
/***********************************************************************
Retreive a pointer to a specific value. Caller shoud dup the structure
since this memory may go away with a regval_ctr_destroy()
**********************************************************************/
REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
{
if ( !(idx < ctr->num_values) )
return NULL;
return ctr->values[idx];
}
/***********************************************************************
Ad a new regostry value to the array
**********************************************************************/
int regval_ctr_addvalue( REGVAL_CTR *ctr, char *name, uint16 type,
char *data_p, size_t size )
{
REGISTRY_VALUE **ppreg;
uint16 len;
if ( name )
{
len = strlen( name );
/* allocate a slot in the array of pointers */
if ( ctr->num_values == 0 )
ctr->values = talloc( ctr->ctx, sizeof(REGISTRY_VALUE*) );
else {
ppreg = talloc_realloc( ctr->ctx, ctr->values, sizeof(REGISTRY_VALUE*)*(ctr->num_values+1) );
if ( ppreg )
ctr->values = ppreg;
}
/* allocate a new valuie and store the pointer in the arrya */
ctr->values[ctr->num_values] = talloc( ctr->ctx, sizeof(REGISTRY_VALUE) );
/* init the value */
fstrcpy( ctr->values[ctr->num_values]->valuename, name );
ctr->values[ctr->num_values]->type = type;
switch ( type )
{
case REG_SZ:
ctr->values[ctr->num_values]->data.string = talloc_strdup( ctr->ctx, data_p );
break;
case REG_DWORD:
break;
case REG_BINARY:
ctr->values[ctr->num_values]->data.binary = talloc_memdup( ctr->ctx, data_p, size );
break;
}
ctr->values[ctr->num_values]->size = size;
ctr->num_values++;
}
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 );
ZERO_STRUCTP( ctr );
}
}
/***********************************************************************
Open the registry database and initialize the REGISTRY_HOOK cache
***********************************************************************/
@ -152,6 +410,34 @@ int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
return result;
}
/***********************************************************************
retreive a specific subkey specified by index. Caller is
responsible for freeing memory
***********************************************************************/
BOOL fetch_reg_values_specific( REGISTRY_KEY *key, REGISTRY_VALUE **val, uint32 key_index )
{
REGVAL_CTR ctr;
REGISTRY_VALUE *v;
ZERO_STRUCTP( &ctr );
regval_ctr_init( &ctr );
if ( fetch_reg_values( key, &ctr) == -1 )
return False;
if ( !(v = regval_ctr_specific_value( &ctr, key_index )) )
return False;
*val = dup_registry_value( v );
regval_ctr_destroy( &ctr );
return True;
}
/***********************************************************************
Utility function for splitting the base path of a registry path off
by setting base and new_path to the apprapriate offsets withing the
@ -182,175 +468,4 @@ BOOL reg_split_path( char *path, char **base, char **new_path )
}
/*
* 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;
char **pp;
if ( keyname )
{
len = strlen( keyname );
if ( ctr->subkeys == 0 )
ctr->subkeys = talloc( ctr->ctx, sizeof(char*) );
else {
pp = talloc_realloc( ctr->ctx, ctr->subkeys, sizeof(char*)*(ctr->num_subkeys+1) );
if ( pp )
ctr->subkeys = pp;
}
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 key_index )
{
if ( ! (key_index < ctr->num_subkeys) )
return NULL;
return ctr->subkeys[key_index];
}
/***********************************************************************
free memory held by a REGSUBKEY_CTR structure
**********************************************************************/
void regsubkey_ctr_destroy( REGSUBKEY_CTR *ctr )
{
if ( ctr ) {
talloc_destroy( ctr->ctx );
ZERO_STRUCTP( ctr );
}
}
/*
* 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;
}
REGISTRY_VALUE* regval_ctr_specific_value( REGVAL_CTR *ctr, uint32 idx )
{
if ( !(idx < ctr->num_values) )
return NULL;
return ctr->values[idx];
}
/***********************************************************************
Ad a new regostry value to the array
**********************************************************************/
int regval_ctr_addvalue( REGVAL_CTR *ctr, char *name, uint16 type,
char *data_p, size_t size )
{
REGISTRY_VALUE **ppreg;
uint16 len;
if ( name )
{
len = strlen( name );
/* allocate a slot in the array of pointers */
if ( ctr->num_values == 0 )
ctr->values = talloc( ctr->ctx, sizeof(REGISTRY_VALUE*) );
else {
ppreg = talloc_realloc( ctr->ctx, ctr->values, sizeof(REGISTRY_VALUE*)*(ctr->num_values+1) );
if ( ppreg )
ctr->values = ppreg;
}
/* allocate a new valuie and store the pointer in the arrya */
ctr->values[ctr->num_values] = talloc( ctr->ctx, sizeof(REGISTRY_VALUE) );
/* init the value */
fstrcpy( ctr->values[ctr->num_values]->valuename, name );
ctr->values[ctr->num_values]->type = type;
switch ( type )
{
case REG_SZ:
ctr->values[ctr->num_values]->data.string = talloc_strdup( ctr->ctx, data_p );
break;
case REG_DWORD:
break;
case REG_BINARY:
ctr->values[ctr->num_values]->data.binary = talloc_memdup( ctr->ctx, data_p, size );
break;
}
ctr->values[ctr->num_values]->size = size;
ctr->num_values++;
}
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 );
ZERO_STRUCTP( ctr );
}
}

View File

@ -893,9 +893,11 @@ BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *
return False;
if (UNMARSHALLING(ps)) {
str->buffer = (uint16 *)prs_alloc_mem(ps,str->buf_len);
if (str->buffer == NULL)
return False;
if ( str->buf_len ) {
str->buffer = (uint16 *)prs_alloc_mem(ps,str->buf_len);
if ( str->buffer == NULL )
return False;
}
}
p = (char *)str->buffer;

View File

@ -1138,6 +1138,38 @@ void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
q_i->len_value2 = 0;
}
/*******************************************************************
makes a structure.
********************************************************************/
void init_reg_r_enum_val(REG_R_ENUM_VALUE *r_u, REGISTRY_VALUE *val )
{
ZERO_STRUCTP(r_u);
/* value name */
init_uni_hdr( &r_u->hdr_name, strlen(val->valuename)+1 );
init_unistr2( &r_u->uni_name, val->valuename, strlen(val->valuename)+1 );
/* type */
r_u->ptr_type = 1;
r_u->type = val->type;
/* data */
r_u->ptr_value = 1;
init_buffer2( &r_u->buf_value, val->data.void_ptr, val->size );
/* lengths */
r_u->ptr1 = 1;
r_u->len_value1 = val->size;
r_u->ptr2 = 1;
r_u->len_value2 = val->size;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
@ -1158,6 +1190,7 @@ BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int d
if(!prs_uint32("val_index", ps, depth, &q_q->val_index))
return False;
if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
return False;
if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
@ -1228,7 +1261,7 @@ BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int d
if(!prs_uint32("ptr_value", ps, depth, &r_q->ptr_value))
return False;
if(!smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps, depth))
if(!smb_io_buffer2("buf_value", &r_q->buf_value, r_q->ptr_value, ps, depth))
return False;
if(!prs_align(ps))
return False;

View File

@ -290,6 +290,31 @@ static BOOL api_reg_enum_key(pipes_struct *p)
return True;
}
/*******************************************************************
api_reg_enum_value
********************************************************************/
static BOOL api_reg_enum_value(pipes_struct *p)
{
REG_Q_ENUM_VALUE q_u;
REG_R_ENUM_VALUE r_u;
prs_struct *data = &p->in_data.data;
prs_struct *rdata = &p->out_data.rdata;
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
if(!reg_io_q_enum_val("", &q_u, data, 0))
return False;
r_u.status = _reg_enum_value(p, &q_u, &r_u);
if(!reg_io_r_enum_val("", &r_u, rdata, 0))
return False;
return True;
}
/*******************************************************************
@ -302,6 +327,7 @@ static struct api_struct api_reg_cmds[] =
{ "REG_OPEN_HKLM" , REG_OPEN_HKLM , api_reg_open_hklm },
{ "REG_OPEN_HKU" , REG_OPEN_HKU , api_reg_open_hku },
{ "REG_ENUM_KEY" , REG_ENUM_KEY , api_reg_enum_key },
{ "REG_ENUM_VALUE" , REG_ENUM_VALUE , api_reg_enum_value },
{ "REG_QUERY_KEY" , REG_QUERY_KEY , api_reg_query_key },
{ "REG_INFO" , REG_INFO , api_reg_info },
{ "REG_SHUTDOWN" , REG_SHUTDOWN , api_reg_shutdown },

View File

@ -237,10 +237,14 @@ static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum,
lenmax = sizemax = 0;
num_values = regval_ctr_numvals( &values );
for ( i=0; i<num_values && val; i++ ) {
val = regval_ctr_specific_value( &values, 0 );
for ( i=0; i<num_values && val; i++ )
{
lenmax = MAX(lenmax, strlen(val->valuename)+1 );
sizemax = MAX(sizemax, val->size );
val = regval_ctr_specific_value( &values, i );
lenmax = MAX(lenmax, strlen(val[i].valuename)+1 );
sizemax = MAX(sizemax, val[i].size );
}
*maxnum = num_values;
@ -480,6 +484,45 @@ done:
return status;
}
/*****************************************************************************
Implementation of REG_ENUM_VALUE
****************************************************************************/
NTSTATUS _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALUE *r_u)
{
NTSTATUS status = NT_STATUS_OK;
REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
REGISTRY_VALUE *val;
DEBUG(5,("_reg_enum_value: Enter\n"));
if ( !regkey )
return NT_STATUS_INVALID_HANDLE;
DEBUG(8,("_reg_enum_key: enumerating values for key [%s]\n", regkey->name));
if ( !fetch_reg_values_specific( regkey, &val, q_u->val_index ) )
{
status = NT_STATUS_NO_MORE_ENTRIES;
goto done;
}
DEBUG(10,("_reg_enum_value: retrieved value named [%s]\n", val->valuename));
/* subkey has the string name now */
init_reg_r_enum_val( r_u, val );
DEBUG(5,("_reg_enum_value: Exit\n"));
done:
SAFE_FREE( val );
return status;
}
/*******************************************************************
reg_shutdwon