summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/rpc_server/srv_winreg_nt.c191
1 files changed, 86 insertions, 105 deletions
diff --git a/source3/rpc_server/srv_winreg_nt.c b/source3/rpc_server/srv_winreg_nt.c
index 23b594ac78..b81b4be32d 100644
--- a/source3/rpc_server/srv_winreg_nt.c
+++ b/source3/rpc_server/srv_winreg_nt.c
@@ -348,14 +348,20 @@ WERROR _winreg_OpenKey(pipes_struct *p, struct policy_handle *parent_handle, str
reg_reply_info
********************************************************************/
-WERROR _winreg_QueryValue(pipes_struct *p, struct policy_handle *handle, struct winreg_String value_name, enum winreg_Type *type, uint8_t *data, uint32_t *data_size, uint32_t *value_length)
+WERROR _winreg_QueryValue(pipes_struct *p, struct policy_handle *handle,
+ struct winreg_String value_name,
+ enum winreg_Type *type, uint8_t *data,
+ uint32_t *data_size, uint32_t *value_length)
{
- WERROR status = WERR_BADFILE;
- char *name;
- REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, handle );
- REGISTRY_VALUE *val = NULL;
- REGVAL_CTR *regvals;
- int i;
+ WERROR status = WERR_BADFILE;
+ REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, handle );
+ prs_struct prs_hkpd;
+
+ uint8_t *outbuf;
+ uint32_t outbuf_size;
+
+ BOOL free_buf = False;
+ BOOL free_prs = False;
if ( !regkey )
return WERR_BADFID;
@@ -365,124 +371,99 @@ WERROR _winreg_QueryValue(pipes_struct *p, struct policy_handle *handle, struct
DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name));
DEBUG(7,("_reg_info: policy key type = [%08x]\n", regkey->type));
- if ( (name = talloc_strdup( p->mem_ctx, value_name.name )) == NULL ) {
- return WERR_NOMEM;
- }
-
- DEBUG(5,("_reg_info: looking up value: [%s]\n", name));
-
- if ( !(regvals = TALLOC_ZERO_P( p->mem_ctx, REGVAL_CTR )) )
- return WERR_NOMEM;
-
/* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
if(regkey->type == REG_KEY_HKPD)
{
- if(strequal(name, "Global"))
- {
- uint32 outbuf_len;
- prs_struct prs_hkpd;
+ if(strequal(value_name.name, "Global")) {
prs_init(&prs_hkpd, *data_size, p->mem_ctx, MARSHALL);
- status = reg_perfcount_get_hkpd(&prs_hkpd, *data_size, &outbuf_len, NULL);
- regval_ctr_addvalue(regvals, "HKPD", REG_BINARY,
- prs_hkpd.data_p, outbuf_len);
- val = dup_registry_value(regval_ctr_specific_value(regvals, 0));
- prs_mem_free(&prs_hkpd);
+ status = reg_perfcount_get_hkpd(
+ &prs_hkpd, *data_size, &outbuf_size, NULL);
+ outbuf = (uint8_t *)prs_hkpd.data_p;
+ free_prs = True;
}
- else if(strequal(name, "Counter 009"))
- {
- uint32 base_index;
- uint32 buffer_size;
- char *buffer;
-
- buffer = NULL;
- base_index = reg_perfcount_get_base_index();
- buffer_size = reg_perfcount_get_counter_names(base_index, &buffer);
- regval_ctr_addvalue(regvals, "Counter 009",
- REG_MULTI_SZ, buffer, buffer_size);
-
- val = dup_registry_value(regval_ctr_specific_value(regvals, 0));
-
- if(buffer_size > 0)
- {
- SAFE_FREE(buffer);
- status = WERR_OK;
- }
+ else if(strequal(value_name.name, "Counter 009")) {
+ outbuf_size = reg_perfcount_get_counter_names(
+ reg_perfcount_get_base_index(),
+ (char **)&outbuf);
+ free_buf = True;
}
- else if(strequal(name, "Explain 009"))
- {
- uint32 base_index;
- uint32 buffer_size;
- char *buffer;
-
- buffer = NULL;
- base_index = reg_perfcount_get_base_index();
- buffer_size = reg_perfcount_get_counter_help(base_index, &buffer);
- regval_ctr_addvalue(regvals, "Explain 009",
- REG_MULTI_SZ, buffer, buffer_size);
-
- val = dup_registry_value(regval_ctr_specific_value(regvals, 0));
-
- if(buffer_size > 0)
- {
- SAFE_FREE(buffer);
- status = WERR_OK;
- }
+ else if(strequal(value_name.name, "Explain 009")) {
+ outbuf_size = reg_perfcount_get_counter_help(
+ reg_perfcount_get_base_index(),
+ (char **)&outbuf);
+ free_buf = True;
}
- else if(isdigit(name[0]))
- {
- /* we probably have a request for a specific object here */
- uint32 outbuf_len;
- prs_struct prs_hkpd;
+ else if(isdigit(value_name.name[0])) {
+ /* we probably have a request for a specific object
+ * here */
prs_init(&prs_hkpd, *data_size, p->mem_ctx, MARSHALL);
- status = reg_perfcount_get_hkpd(&prs_hkpd, *data_size, &outbuf_len, name);
- regval_ctr_addvalue(regvals, "HKPD", REG_BINARY,
- prs_hkpd.data_p, outbuf_len);
-
- val = dup_registry_value(regval_ctr_specific_value(regvals, 0));
- prs_mem_free(&prs_hkpd);
+ status = reg_perfcount_get_hkpd(
+ &prs_hkpd, *data_size, &outbuf_size,
+ value_name.name);
+ outbuf = (uint8_t *)prs_hkpd.data_p;
+ free_prs = True;
}
- else
- {
- DEBUG(3,("Unsupported key name [%s] for HKPD.\n", name));
+ else {
+ DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
+ value_name.name));
return WERR_BADFILE;
}
+
+ *type = REG_BINARY;
}
- /* HKPT calls can be handled out of reg_dynamic.c with the hkpt_params handler */
- else
- {
- for ( i=0; fetch_reg_values_specific(regkey, &val, i); i++ )
- {
- DEBUG(10,("_reg_info: Testing value [%s]\n", val->valuename));
- if ( strequal( val->valuename, name ) ) {
- DEBUG(10,("_reg_info: Found match for value [%s]\n", name));
- status = WERR_OK;
- break;
+ else {
+ /* HKPT calls can be handled out of reg_dynamic.c with the
+ * hkpt_params handler */
+
+ REGVAL_CTR *regvals;
+ uint32 i;
+
+ if (!(regvals = TALLOC_ZERO_P(p->mem_ctx, REGVAL_CTR))) {
+ return WERR_NOMEM;
}
-
- free_registry_value( val );
- }
- }
- /* if we have a value then copy it to the output */
+ /*
+ * Don't use fetch_reg_values_specific here, there is too much
+ * memory copying around. I'll re-add the cache later. VL
+ */
- if ( val ) {
- *value_length = regval_size( val );
- *type = val->type;
+ if (fetch_reg_values(regkey, regvals) == -1) {
+ TALLOC_FREE(regvals);
+ return WERR_BADFILE;
+ }
- if ( *data_size == 0 || !data ) {
- status = WERR_OK;
- } else if ( *value_length > *data_size ) {
- status = WERR_MORE_DATA;
- } else {
- memcpy( data, regval_data_p(val), *value_length );
- status = WERR_OK;
+ for (i=0; i<regvals->num_values; i++) {
+ if (strequal(regvals->values[i]->valuename,
+ value_name.name)) {
+ break;
+ }
}
- *data_size = *value_length;
+ if (i == regvals->num_values) {
+ TALLOC_FREE(regvals);
+ return WERR_BADFILE;
+ }
+
+ outbuf = regvals->values[i]->data_p;
+ outbuf_size = regvals->values[i]->size;
+ *type = regvals->values[i]->type;
}
- TALLOC_FREE( regvals );
- free_registry_value( val );
+ *value_length = outbuf_size;
+
+ if ( *data_size == 0 || !data ) {
+ status = WERR_OK;
+ } else if ( *value_length > *data_size ) {
+ status = WERR_MORE_DATA;
+ } else {
+ memcpy( data, outbuf, *value_length );
+ status = WERR_OK;
+ }
+
+ *data_size = *value_length;
+
+ if (free_prs) prs_mem_free(&prs_hkpd);
+ if (free_buf) SAFE_FREE(outbuf);
return status;
}