summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/rpc_reg.h9
-rw-r--r--source3/registry/reg_db.c186
-rw-r--r--source3/registry/reg_eventlog.c12
-rw-r--r--source3/registry/reg_frontend.c11
-rw-r--r--source3/registry/reg_objects.c35
-rw-r--r--source3/registry/reg_printing.c12
-rw-r--r--source3/registry/reg_shares.c12
-rw-r--r--source3/rpc_parse/parse_reg.c5
-rw-r--r--source3/rpc_server/srv_reg_nt.c32
9 files changed, 231 insertions, 83 deletions
diff --git a/source3/include/rpc_reg.h b/source3/include/rpc_reg.h
index 7ef2696228..7d6469bc8e 100644
--- a/source3/include/rpc_reg.h
+++ b/source3/include/rpc_reg.h
@@ -92,10 +92,10 @@
typedef struct {
/* functions for enumerating subkeys and values */
- int (*fetch_subkeys)( char *key, REGSUBKEY_CTR *subkeys);
- int (*fetch_values) ( char *key, REGVAL_CTR *val );
- BOOL (*store_subkeys)( char *key, REGSUBKEY_CTR *subkeys );
- BOOL (*store_values)( char *key, REGVAL_CTR *val );
+ int (*fetch_subkeys)( const char *key, REGSUBKEY_CTR *subkeys);
+ int (*fetch_values) ( const char *key, REGVAL_CTR *val );
+ BOOL (*store_subkeys)( const char *key, REGSUBKEY_CTR *subkeys );
+ BOOL (*store_values)( const char *key, REGVAL_CTR *val );
BOOL (*reg_access_check)( const char *keyname, uint32 requested, uint32 *granted, NT_USER_TOKEN *token );
} REGISTRY_OPS;
@@ -252,7 +252,6 @@ typedef struct {
} REG_Q_DELETE_VALUE;
typedef struct {
- POLICY_HND key_pol;
WERROR status;
} REG_R_DELETE_VALUE;
diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c
index af0a30b76c..3f618fbba4 100644
--- a/source3/registry/reg_db.c
+++ b/source3/registry/reg_db.c
@@ -27,9 +27,13 @@
static TDB_CONTEXT *tdb_reg;
+#define VALUE_PREFIX "SAMBA_REGVAL"
+
+static BOOL regdb_store_reg_keys( const char *keyname, REGSUBKEY_CTR *subkeys );
+static BOOL regdb_store_reg_values( const char *keyname, REGVAL_CTR *values);
+static int regdb_fetch_reg_keys( const char* key, REGSUBKEY_CTR *subkeys );
+static int regdb_fetch_reg_values( const char* key, REGVAL_CTR *values );
-static BOOL regdb_store_reg_keys( char *keyname, REGSUBKEY_CTR *ctr );
-static int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr );
@@ -56,7 +60,6 @@ static const char *builtin_registry_paths[] = {
"HKCR",
NULL };
-#if 0 /* not used yet */
struct builtin_regkey_value {
const char *path;
const char *valuename;
@@ -67,10 +70,10 @@ struct builtin_regkey_value {
} data;
};
-static struct builtin_regkey_value builtin_values[] = {
+static struct builtin_regkey_value builtin_registry_values[] = {
{ "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "SystemRoot", REG_SZ, { "c:\\Windows" } },
+ { NULL, NULL, 0, { NULL } }
};
-#endif
#define REGVER_V1 1 /* first db version with write support */
@@ -83,8 +86,10 @@ static BOOL init_registry_data( void )
pstring path, base, remaining;
fstring keyname, subkeyname;
REGSUBKEY_CTR subkeys;
+ REGVAL_CTR values;
int i;
const char *p, *p2;
+ UNISTR2 data;
/* loop over all of the predefined paths and add each component */
@@ -134,6 +139,39 @@ static BOOL init_registry_data( void )
}
}
+ /* loop over all of the predefined values and add each component */
+
+ for ( i=0; builtin_registry_values[i].path != NULL; i++ ) {
+ regval_ctr_init( &values );
+
+ regdb_fetch_reg_values( builtin_registry_values[i].path, &values );
+ switch( builtin_registry_values[i].type ) {
+ case REG_DWORD:
+ regval_ctr_addvalue( &values,
+ builtin_registry_values[i].valuename,
+ REG_DWORD,
+ (char*)&builtin_registry_values[i].data.dw_value,
+ sizeof(uint32) );
+ break;
+
+ case REG_SZ:
+ init_unistr2( &data, builtin_registry_values[i].data.string, UNI_STR_TERMINATE);
+ regval_ctr_addvalue( &values,
+ builtin_registry_values[i].valuename,
+ REG_SZ,
+ (char*)data.buffer,
+ data.uni_str_len*sizeof(uint16) );
+ break;
+
+ default:
+ DEBUG(0,("init_registry_data: invalid value type in builtin_registry_values [%d]\n",
+ builtin_registry_values[i].type));
+ }
+ regdb_store_reg_values( builtin_registry_values[i].path, &values );
+
+ regval_ctr_destroy( &values );
+ }
+
return True;
}
@@ -197,7 +235,7 @@ static void normalize_reg_path( pstring keyname )
fstrings
***********************************************************************/
-static BOOL regdb_store_reg_keys_internal( char *key, REGSUBKEY_CTR *ctr )
+static BOOL regdb_store_reg_keys_internal( const char *key, REGSUBKEY_CTR *ctr )
{
TDB_DATA kbuf, dbuf;
char *buffer, *tmpbuf;
@@ -263,7 +301,7 @@ done:
do not currently exist
***********************************************************************/
-static BOOL regdb_store_reg_keys( char *key, REGSUBKEY_CTR *ctr )
+static BOOL regdb_store_reg_keys( const char *key, REGSUBKEY_CTR *ctr )
{
int num_subkeys, i;
pstring path;
@@ -317,11 +355,10 @@ static BOOL regdb_store_reg_keys( char *key, REGSUBKEY_CTR *ctr )
/***********************************************************************
Retrieve an array of strings containing subkeys. Memory should be
- released by the caller. The subkeys are stored in a catenated string
- of null terminated character strings
+ released by the caller.
***********************************************************************/
-static int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr )
+static int regdb_fetch_reg_keys( const char* key, REGSUBKEY_CTR *ctr )
{
pstring path;
uint32 num_items;
@@ -363,20 +400,105 @@ static int regdb_fetch_reg_keys( char* key, REGSUBKEY_CTR *ctr )
return num_items;
}
+/****************************************************************************
+ Unpack a list of registry values frem the TDB
+ ***************************************************************************/
+
+static int regdb_unpack_values(REGVAL_CTR *values, char *buf, int buflen)
+{
+ int len = 0;
+ uint32 type;
+ pstring valuename;
+ int size;
+ uint8 *data_p;
+ uint32 num_values = 0;
+ int i;
+
+
+
+ /* loop and unpack the rest of the registry values */
+
+ len += tdb_unpack(buf+len, buflen-len, "d", &num_values);
+
+ for ( i=0; i<num_values; i++ ) {
+ /* unpack the next regval */
+
+ len += tdb_unpack(buf+len, buflen-len, "fdB",
+ valuename,
+ &type,
+ &size,
+ &data_p);
+
+ /* add the new value */
+
+ regval_ctr_addvalue( values, valuename, type, (const char *)data_p, size );
+
+ SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
+
+ DEBUG(8,("specific: [%s], len: %d\n", valuename, size));
+ }
+
+ return len;
+}
+
+/****************************************************************************
+ Pack all values in all printer keys
+ ***************************************************************************/
+
+static int regdb_pack_values(REGVAL_CTR *values, char *buf, int buflen)
+{
+ int len = 0;
+ int i;
+ REGISTRY_VALUE *val;
+ int num_values = regval_ctr_numvals( values );
+
+ if ( !values )
+ return 0;
+
+ /* pack the number of values first */
+
+ len += tdb_pack( buf+len, buflen-len, "d", num_values );
+
+ /* loop over all values */
+
+ for ( i=0; i<num_values; i++ ) {
+ val = regval_ctr_specific_value( values, i );
+ len += tdb_pack(buf+len, buflen-len, "fdB",
+ regval_name(val),
+ regval_type(val),
+ regval_size(val),
+ regval_data_p(val) );
+ }
+
+ return len;
+}
/***********************************************************************
Retrieve an array of strings containing subkeys. Memory should be
- released by the caller. The subkeys are stored in a catenated string
- of null terminated character strings
+ released by the caller.
***********************************************************************/
-static int regdb_fetch_reg_values( char* key, REGVAL_CTR *val )
+static int regdb_fetch_reg_values( const char* key, REGVAL_CTR *values )
{
- int num_vals = 0;
+ TDB_DATA data;
+ pstring keystr;
+ int len;
DEBUG(10,("regdb_fetch_reg_values: Looking for value of key [%s] \n", key));
-
- return num_vals;
+
+ pstr_sprintf( keystr, "%s/%s", VALUE_PREFIX, key );
+ normalize_reg_path( keystr );
+
+ data = tdb_fetch_bystring( tdb_reg, keystr );
+
+ if ( !data.dptr )
+ return 0;
+
+ len = regdb_unpack_values( values, data.dptr, data.dsize );
+
+ SAFE_FREE( data.dptr );
+
+ return regval_ctr_numvals(values);
}
/***********************************************************************
@@ -384,9 +506,37 @@ static int regdb_fetch_reg_values( char* key, REGVAL_CTR *val )
values in the registry.tdb
***********************************************************************/
-static BOOL regdb_store_reg_values( char *key, REGVAL_CTR *val )
+static BOOL regdb_store_reg_values( const char *key, REGVAL_CTR *values )
{
- return False;
+ TDB_DATA data;
+ pstring keystr;
+ int len, ret;
+
+ DEBUG(10,("regdb_store_reg_values: Looking for value of key [%s] \n", key));
+
+ ZERO_STRUCT( data );
+
+ len = regdb_pack_values( values, data.dptr, data.dsize );
+ if ( len <= 0 ) {
+ DEBUG(0,("regdb_store_reg_values: unable to pack values. len <= 0\n"));
+ return False;
+ }
+
+ data.dptr = SMB_MALLOC_ARRAY( char, len );
+ data.dsize = len;
+
+ len = regdb_pack_values( values, data.dptr, data.dsize );
+
+ SMB_ASSERT( len == data.dsize );
+
+ pstr_sprintf( keystr, "%s/%s", VALUE_PREFIX, key );
+ normalize_reg_path( keystr );
+
+ ret = tdb_store_bystring(tdb_reg, keystr, data, TDB_REPLACE);
+
+ SAFE_FREE( data.dptr );
+
+ return ret != -1 ;
}
diff --git a/source3/registry/reg_eventlog.c b/source3/registry/reg_eventlog.c
index 4c3f144980..b20eb046db 100644
--- a/source3/registry/reg_eventlog.c
+++ b/source3/registry/reg_eventlog.c
@@ -154,9 +154,9 @@ static int eventlog_subkey_values( char *key, REGVAL_CTR *val )
the memory allocated here.
**********************************************************************/
-static char* trim_eventlog_reg_path( char *path )
+static char* trim_eventlog_reg_path( const char *path )
{
- char *p;
+ const char *p;
uint16 key_len = strlen(KEY_EVENTLOG);
/*
@@ -186,7 +186,7 @@ static char* trim_eventlog_reg_path( char *path )
Enumerate registry subkey names given a registry path.
Caller is responsible for freeing memory to **subkeys
*********************************************************************/
-static int eventlog_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr )
+static int eventlog_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr )
{
char *path;
BOOL top_level = False;
@@ -251,7 +251,7 @@ static int eventlog_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr )
Caller is responsible for freeing memory
*********************************************************************/
-static int eventlog_value_info( char *key, REGVAL_CTR *val )
+static int eventlog_value_info( const char *key, REGVAL_CTR *val )
{
char *path;
BOOL top_level = False;
@@ -280,7 +280,7 @@ static int eventlog_value_info( char *key, REGVAL_CTR *val )
people storing eventlog information directly via registry calls
(for now at least)
*********************************************************************/
-static BOOL eventlog_store_subkey( char *key, REGSUBKEY_CTR *subkeys )
+static BOOL eventlog_store_subkey( const char *key, REGSUBKEY_CTR *subkeys )
{
return False;
}
@@ -290,7 +290,7 @@ static BOOL eventlog_store_subkey( char *key, REGSUBKEY_CTR *subkeys )
people storing eventlog information directly via registry calls
(for now at least)
*********************************************************************/
-static BOOL eventlog_store_value( char *key, REGVAL_CTR *val )
+static BOOL eventlog_store_value( const char *key, REGVAL_CTR *val )
{
return False;
}
diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c
index 9c7420ef86..8b722ba1f5 100644
--- a/source3/registry/reg_frontend.c
+++ b/source3/registry/reg_frontend.c
@@ -70,9 +70,6 @@ BOOL init_registry( void )
return True;
}
-
-
-
/***********************************************************************
High level wrapper function for storing registry subkeys
***********************************************************************/
@@ -81,8 +78,8 @@ BOOL store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
{
if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys )
return key->hook->ops->store_subkeys( key->name, subkeys );
- else
- return False;
+
+ return False;
}
@@ -94,8 +91,8 @@ BOOL store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
{
if ( key->hook && key->hook->ops && key->hook->ops->store_values )
return key->hook->ops->store_values( key->name, val );
- else
- return False;
+
+ return False;
}
diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c
index 582a696529..7ee2cd8414 100644
--- a/source3/registry/reg_objects.c
+++ b/source3/registry/reg_objects.c
@@ -114,7 +114,6 @@ BOOL regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname )
}
return False;
-
}
/***********************************************************************
@@ -276,10 +275,24 @@ TALLOC_CTX* regval_ctr_getctx( REGVAL_CTR *val )
if ( !val )
return NULL;
- return val->ctx;
-}
+ return val->ctx; }
/***********************************************************************
+ Check for the existance of a value
+ **********************************************************************/
+
+BOOL regval_ctr_key_exists( REGVAL_CTR *ctr, const char *value )
+{
+ int i;
+
+ for ( i=0; i<ctr->num_values; i++ ) {
+ if ( strequal( ctr->values[i]->valuename, value) )
+ return True;
+ }
+
+ return False;
+}
+/***********************************************************************
Add a new registry value to the array
**********************************************************************/
@@ -291,6 +304,10 @@ int regval_ctr_addvalue( REGVAL_CTR *ctr, const char *name, uint16 type,
if ( !name )
return ctr->num_values;
+ /* Delete the current value (if it exists) and add the new one */
+
+ regval_ctr_delvalue( ctr, name );
+
/* allocate a slot in the array of pointers */
if ( ctr->num_values == 0 )
@@ -366,7 +383,7 @@ int regval_ctr_delvalue( REGVAL_CTR *ctr, const char *name )
return 0;
for ( i=0; i<ctr->num_values; i++ ) {
- if ( strcmp( ctr->values[i]->valuename, name ) == 0)
+ if ( strequal( ctr->values[i]->valuename, name ) )
break;
}
@@ -376,15 +393,9 @@ int regval_ctr_delvalue( REGVAL_CTR *ctr, const char *name )
return ctr->num_values;
/* just shift everything down one */
-
- for ( /* use previous i */; i<(ctr->num_values-1); i++ )
- memcpy( ctr->values[i], ctr->values[i+1], sizeof(REGISTRY_VALUE) );
-
- /* paranoia */
-
- ZERO_STRUCTP( ctr->values[i] );
-
ctr->num_values--;
+ if ( ctr->num_values )
+ memmove( ctr->values[i], ctr->values[i+1], sizeof(REGISTRY_VALUE)*(ctr->num_values-i) );
return ctr->num_values;
}
diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c
index 1ac91f4b90..30f2d74660 100644
--- a/source3/registry/reg_printing.c
+++ b/source3/registry/reg_printing.c
@@ -49,9 +49,9 @@ static const char *top_level_keys[MAX_TOP_LEVEL_KEYS] = {
the memory allocated here.
**********************************************************************/
-static char* trim_reg_path( char *path )
+static char* trim_reg_path( const char *path )
{
- char *p;
+ const char *p;
uint16 key_len = strlen(path);
uint16 base_key_len;
@@ -837,7 +837,7 @@ static int handle_printing_subpath( char *key, REGSUBKEY_CTR *subkeys, REGVAL_CT
Caller is responsible for freeing memory to **subkeys
*********************************************************************/
-static int printing_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr )
+static int printing_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr )
{
char *path;
BOOL top_level = False;
@@ -876,7 +876,7 @@ static int printing_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr )
Caller is responsible for freeing memory
*********************************************************************/
-static int printing_value_info( char *key, REGVAL_CTR *val )
+static int printing_value_info( const char *key, REGVAL_CTR *val )
{
char *path;
BOOL top_level = False;
@@ -908,7 +908,7 @@ static int printing_value_info( char *key, REGVAL_CTR *val )
(for now at least)
*********************************************************************/
-static BOOL printing_store_subkey( char *key, REGSUBKEY_CTR *subkeys )
+static BOOL printing_store_subkey( const char *key, REGSUBKEY_CTR *subkeys )
{
return True;
}
@@ -919,7 +919,7 @@ static BOOL printing_store_subkey( char *key, REGSUBKEY_CTR *subkeys )
(for now at least)
*********************************************************************/
-static BOOL printing_store_value( char *key, REGVAL_CTR *val )
+static BOOL printing_store_value( const char *key, REGVAL_CTR *val )
{
return True;
}
diff --git a/source3/registry/reg_shares.c b/source3/registry/reg_shares.c
index 4531327d94..85ac812101 100644
--- a/source3/registry/reg_shares.c
+++ b/source3/registry/reg_shares.c
@@ -34,9 +34,9 @@
the memory allocated here.
**********************************************************************/
-static char* trim_reg_path( char *path )
+static char* trim_reg_path( const char *path )
{
- char *p;
+ const char *p;
uint16 key_len = strlen(KEY_SHARES);
/*
@@ -67,7 +67,7 @@ static char* trim_reg_path( char *path )
Caller is responsible for freeing memory to **subkeys
*********************************************************************/
-static int shares_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr )
+static int shares_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr )
{
char *path;
BOOL top_level = False;
@@ -101,7 +101,7 @@ static int shares_subkey_info( char *key, REGSUBKEY_CTR *subkey_ctr )
Caller is responsible for freeing memory
*********************************************************************/
-static int shares_value_info( char *key, REGVAL_CTR *val )
+static int shares_value_info( const char *key, REGVAL_CTR *val )
{
char *path;
BOOL top_level = False;
@@ -134,7 +134,7 @@ static int shares_value_info( char *key, REGVAL_CTR *val )
(for now at least)
*********************************************************************/
-static BOOL shares_store_subkey( char *key, REGSUBKEY_CTR *subkeys )
+static BOOL shares_store_subkey( const char *key, REGSUBKEY_CTR *subkeys )
{
return False;
}
@@ -145,7 +145,7 @@ static BOOL shares_store_subkey( char *key, REGSUBKEY_CTR *subkeys )
(for now at least)
*********************************************************************/
-static BOOL shares_store_value( char *key, REGVAL_CTR *val )
+static BOOL shares_store_value( const char *key, REGVAL_CTR *val )
{
return False;
}
diff --git a/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c
index 190f39eb79..9048f0f58f 100644
--- a/source3/rpc_parse/parse_reg.c
+++ b/source3/rpc_parse/parse_reg.c
@@ -343,8 +343,6 @@ BOOL reg_io_q_delete_value(const char *desc, REG_Q_DELETE_VALUE *q_u,
if(!prs_unistr4("name", ps, depth, &q_u->name))
return False;
- if(!prs_align(ps))
- return False;
return True;
}
@@ -464,9 +462,6 @@ BOOL reg_io_q_query_key(const char *desc, REG_Q_QUERY_KEY *q_u, prs_struct *ps,
if(!prs_unistr4("key_class", ps, depth, &q_u->key_class))
return False;
- if(!prs_align(ps))
- return False;
-
return True;
}
diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c
index 3b25f11359..0e4c49aa48 100644
--- a/source3/rpc_server/srv_reg_nt.c
+++ b/source3/rpc_server/srv_reg_nt.c
@@ -464,6 +464,7 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL
regval_ctr_init( &regvals );
+ /* FIXME!!! Move these to a dynmanic lookup in the reg_fetch_values() */
/* couple of hard coded registry values */
if ( strequal(name, "RefusePasswordChange") ) {
@@ -544,20 +545,6 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL
goto out;
}
- /* "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" */
-
- if ( strequal( name, "SystemRoot") ) {
- value_length = push_ucs2( value, value, "c:\\windows", sizeof(value), STR_TERMINATE|STR_NOALIGN);
- regval_ctr_addvalue( &regvals, "SystemRoot", REG_SZ, value, value_length );
-
- val = dup_registry_value( regval_ctr_specific_value( &regvals, 0 ) );
-
- status = WERR_OK;
-
- goto out;
- }
-
-
/* else fall back to actually looking up the value */
for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ )
@@ -1311,6 +1298,7 @@ WERROR _reg_set_value(pipes_struct *p, REG_Q_SET_VALUE *q_u, REG_R_SET_VALUE *r
REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle);
REGVAL_CTR values;
BOOL write_result;
+ fstring valuename;
if ( !key )
return WERR_BADFID;
@@ -1320,12 +1308,16 @@ WERROR _reg_set_value(pipes_struct *p, REG_Q_SET_VALUE *q_u, REG_R_SET_VALUE *r
if ( !(key->access_granted & SEC_RIGHTS_SET_VALUE) )
return WERR_ACCESS_DENIED;
+ rpcstr_pull( valuename, q_u->name.string->buffer, sizeof(valuename), q_u->name.string->uni_str_len*2, 0 );
+
+
regval_ctr_init( &values );
/* lookup the current values and add the new one */
fetch_reg_values( key, &values );
- /* FIXME!!!! regval_ctr_addvalue( &values, .... ); */
+
+ regval_ctr_addvalue( &values, valuename, q_u->type, q_u->value.buffer, q_u->value.buf_len );
/* now write to the registry backend */
@@ -1440,7 +1432,8 @@ WERROR _reg_delete_value(pipes_struct *p, REG_Q_DELETE_VALUE *q_u, REG_R_DELETE
REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->handle);
REGVAL_CTR values;
BOOL write_result;
-
+ fstring valuename;
+
if ( !key )
return WERR_BADFID;
@@ -1448,13 +1441,16 @@ WERROR _reg_delete_value(pipes_struct *p, REG_Q_DELETE_VALUE *q_u, REG_R_DELETE
if ( !(key->access_granted & SEC_RIGHTS_SET_VALUE) )
return WERR_ACCESS_DENIED;
-
+
+ rpcstr_pull( valuename, q_u->name.string->buffer, sizeof(valuename), q_u->name.string->uni_str_len*2, 0 );
+
regval_ctr_init( &values );
/* lookup the current values and add the new one */
fetch_reg_values( key, &values );
- /* FIXME!!!! regval_ctr_delval( &values, .... ); */
+
+ regval_ctr_delvalue( &values, valuename );
/* now write to the registry backend */