diff options
author | Günther Deschner <gd@samba.org> | 2010-06-30 02:03:27 +0200 |
---|---|---|
committer | Günther Deschner <gd@samba.org> | 2010-06-30 21:46:08 +0200 |
commit | de0d9e0bff7d39c3f784112bd043095aeaa1042a (patch) | |
tree | 252d650f0c396f13c0b5bef6f1b55b3ea5a31148 /source3 | |
parent | 21869f5ed00af5a05f1d109339cd8b725fcc7d61 (diff) | |
download | samba-de0d9e0bff7d39c3f784112bd043095aeaa1042a.tar.gz samba-de0d9e0bff7d39c3f784112bd043095aeaa1042a.tar.bz2 samba-de0d9e0bff7d39c3f784112bd043095aeaa1042a.zip |
s3-winreg: implement _winreg_QueryMultipleValues2().
Guenther
Diffstat (limited to 'source3')
-rw-r--r-- | source3/rpc_server/srv_winreg_nt.c | 119 |
1 files changed, 114 insertions, 5 deletions
diff --git a/source3/rpc_server/srv_winreg_nt.c b/source3/rpc_server/srv_winreg_nt.c index 28d5ac9237..f54f5b56a6 100644 --- a/source3/rpc_server/srv_winreg_nt.c +++ b/source3/rpc_server/srv_winreg_nt.c @@ -978,16 +978,125 @@ WERROR _winreg_QueryMultipleValues(pipes_struct *p, struct winreg_QueryMultipleV } /******************************************************************* + ********************************************************************/ + +static WERROR construct_multiple_entry(TALLOC_CTX *mem_ctx, + const char *valuename, + uint32_t value_length, + uint32_t offset, + enum winreg_Type type, + struct QueryMultipleValue *r) +{ + r->ve_valuename = talloc_zero(mem_ctx, struct winreg_ValNameBuf); + if (r->ve_valuename == NULL) { + return WERR_NOMEM; + } + + r->ve_valuename->name = talloc_strdup(r->ve_valuename, valuename ? valuename : ""); + if (r->ve_valuename->name == NULL) { + return WERR_NOMEM; + } + + r->ve_valuename->size = strlen_m_term(r->ve_valuename->name)*2; + r->ve_valuelen = value_length; + r->ve_valueptr = offset; + r->ve_type = type; + + return WERR_OK; +} + +/******************************************************************* _winreg_QueryMultipleValues2 ********************************************************************/ -WERROR _winreg_QueryMultipleValues2(pipes_struct *p, struct winreg_QueryMultipleValues2 *r) +WERROR _winreg_QueryMultipleValues2(pipes_struct *p, + struct winreg_QueryMultipleValues2 *r) { - /* fill in your code here if you think this call should - do anything */ + struct registry_key *regkey = find_regkey_by_hnd(p, r->in.key_handle); + struct registry_value *vals = NULL; + const char **names = NULL; + uint32_t offset = 0, num_vals = 0; + DATA_BLOB result; + int i; + WERROR err; - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + if (!regkey) { + return WERR_BADFID; + } + + names = talloc_zero_array(p->mem_ctx, const char *, r->in.num_values); + if (names == NULL) { + return WERR_NOMEM; + } + + for (i=0; i < r->in.num_values; i++) { + if (r->in.values_in[i].ve_valuename && + r->in.values_in[i].ve_valuename->name) { + names[i] = talloc_strdup(names, + r->in.values_in[i].ve_valuename->name); + if (names[i] == NULL) { + return WERR_NOMEM; + } + } + } + + err = reg_querymultiplevalues(p->mem_ctx, regkey, + r->in.num_values, names, + &num_vals, &vals); + if (!W_ERROR_IS_OK(err)) { + return err; + } + + result = data_blob_talloc(p->mem_ctx, NULL, 0); + + for (i=0; i < r->in.num_values; i++) { + const char *valuename = NULL; + DATA_BLOB blob = data_blob_null; + + if (vals[i].type != REG_NONE) { + err = registry_push_value(p->mem_ctx, &vals[i], &blob); + if (!W_ERROR_IS_OK(err)) { + return err; + } + + if (!data_blob_append(p->mem_ctx, &result, + blob.data, blob.length)) { + return WERR_NOMEM; + } + } + + if (r->in.values_in[i].ve_valuename && + r->in.values_in[i].ve_valuename->name) { + valuename = r->in.values_in[i].ve_valuename->name; + } + + err = construct_multiple_entry(r->out.values_out, + valuename, + blob.length, + offset, + vals[i].type, + &r->out.values_out[i]); + if (!W_ERROR_IS_OK(err)) { + return err; + } + + offset += blob.length; + } + + *r->out.needed = result.length; + + if (r->in.num_values != num_vals) { + return WERR_BADFILE; + } + + if (*r->in.offered >= *r->out.needed) { + if (r->out.buffer) { + memcpy(r->out.buffer, result.data, MIN(result.length, *r->in.offered)); + } + return WERR_OK; + } else { + return WERR_MORE_DATA; + } } /******************************************************************* |