From 6b0819e96cb4bb1692485a6c7e841330687c63f8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 23 Nov 2006 16:19:06 +0000 Subject: r19860: Streamline _winreg_QueryValue a bit. We've been pushing around memory considerably here. This temporarily removes a cache for the tdb based registry, I'll re-add that in srv_winreg_nt.c in the next step. This fixes creating/renaming values from the windows regedit.exe, as "New Value #1" was not entering the cache after being created. Volker (This used to be commit c8c81f0e86256f769765c142e4f1e4c45cb74296) --- source3/rpc_server/srv_winreg_nt.c | 191 +++++++++++++++++-------------------- 1 file 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; inum_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; } -- cgit