svn commit: samba r19860 - in branches/SAMBA_3_0/source/rpc_server: .

vlendec at samba.org vlendec at samba.org
Thu Nov 23 16:19:06 GMT 2006


Author: vlendec
Date: 2006-11-23 16:19:06 +0000 (Thu, 23 Nov 2006)
New Revision: 19860

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=19860

Log:
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

Modified:
   branches/SAMBA_3_0/source/rpc_server/srv_winreg_nt.c


Changeset:
Modified: branches/SAMBA_3_0/source/rpc_server/srv_winreg_nt.c
===================================================================
--- branches/SAMBA_3_0/source/rpc_server/srv_winreg_nt.c	2006-11-23 16:02:20 UTC (rev 19859)
+++ branches/SAMBA_3_0/source/rpc_server/srv_winreg_nt.c	2006-11-23 16:19:06 UTC (rev 19860)
@@ -348,15 +348,21 @@
  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,125 +371,100 @@
 	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;
 }
 



More information about the samba-cvs mailing list