svn commit: samba r23583 - in branches: SAMBA_3_0/source/registry	SAMBA_3_0_26/source/registry Author: obnox
Date: 2007-06-22 11:21:59 +0000 (Fri, 22 Jun 2007)
New Revision: 23583

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

Log:
Add a utility function to recursively delete a Registry
key with all its subkeys. (reg_deletekey will refuse to
delete a key with subkeys with WERR_ACCESS_DENIED).

Michael


Modified:
   branches/SAMBA_3_0/source/registry/reg_api.c
   branches/SAMBA_3_0_26/source/registry/reg_api.c


Changeset:
Modified: branches/SAMBA_3_0/source/registry/reg_api.c
===================================================================
--- branches/SAMBA_3_0/source/registry/reg_api.c	2007-06-22 11:20:37 UTC (rev 23582)
+++ branches/SAMBA_3_0/source/registry/reg_api.c	2007-06-22 11:21:59 UTC (rev 23583)
@@ -677,3 +677,59 @@
 	*pkey = key;
 	return WERR_OK;
 }
+
+
+/*
+ * Utility function to delete a registry key with all its subkeys. 
+ * Note that reg_deletekey returns ACCESS_DENIED when called on a 
+ * key that has subkeys.
+ */
+WERROR reg_deletekey_recursive(TALLOC_CTX *ctx,
+			       struct registry_key *parent, 
+			       const char *path)
+{
+	TALLOC_CTX *mem_ctx = NULL;
+	WERROR werr = WERR_OK;
+	struct registry_key *key;
+	uint32 idx = 0;
+	char *subkey_name = NULL;
+
+	mem_ctx = talloc_new(ctx);
+	if (mem_ctx == NULL) {
+		werr = WERR_NOMEM;
+		goto done;
+	}
+
+	/* recurse through subkeys first */
+	werr = reg_openkey(mem_ctx, parent, path, REG_KEY_WRITE, &key);
+	if (!W_ERROR_IS_OK(werr)) {
+		goto done;
+	}
+
+	/* NOTE: we *must not* increment idx in this loop since
+	 * the list of subkeys shrinks with each loop body. 
+	 * so this way, we repeatedly delete the *first* entry
+	 * of a shrinking list. */
+	for (idx = 0;
+	     W_ERROR_IS_OK(werr = reg_enumkey(mem_ctx, key, idx,
+			     		      &subkey_name, NULL));
+	    ) 
+	{
+		werr = reg_deletekey_recursive(mem_ctx, key, subkey_name);
+		if (!W_ERROR_IS_OK(werr)) {
+			goto done;
+		}
+	}
+	if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
+		DEBUG(1, ("reg_deletekey_recursive: Error enumerating "
+			  "subkeys: %s\\n", dos_errstr(werr)));
+		goto done;
+	}
+
+	/* now delete the actual key */
+	werr = reg_deletekey(parent, path);
+	
+done:
+	TALLOC_FREE(mem_ctx);
+	return werr;
+}

Modified: branches/SAMBA_3_0_26/source/registry/reg_api.c
===================================================================
--- branches/SAMBA_3_0_26/source/registry/reg_api.c	2007-06-22 11:20:37 UTC (rev 23582)
+++ branches/SAMBA_3_0_26/source/registry/reg_api.c	2007-06-22 11:21:59 UTC (rev 23583)
@@ -677,3 +677,59 @@
 	*pkey = key;
 	return WERR_OK;
 }
+
+
+/*
+ * Utility function to delete a registry key with all its subkeys. 
+ * Note that reg_deletekey returns ACCESS_DENIED when called on a 
+ * key that has subkeys.
+ */
+WERROR reg_deletekey_recursive(TALLOC_CTX *ctx,
+			       struct registry_key *parent, 
+			       const char *path)
+{
+	TALLOC_CTX *mem_ctx = NULL;
+	WERROR werr = WERR_OK;
+	struct registry_key *key;
+	uint32 idx = 0;
+	char *subkey_name = NULL;
+
+	mem_ctx = talloc_new(ctx);
+	if (mem_ctx == NULL) {
+		werr = WERR_NOMEM;
+		goto done;
+	}
+
+	/* recurse through subkeys first */
+	werr = reg_openkey(mem_ctx, parent, path, REG_KEY_WRITE, &key);
+	if (!W_ERROR_IS_OK(werr)) {
+		goto done;
+	}
+
+	/* NOTE: we *must not* increment idx in this loop since
+	 * the list of subkeys shrinks with each loop body. 
+	 * so this way, we repeatedly delete the *first* entry
+	 * of a shrinking list. */
+	for (idx = 0;
+	     W_ERROR_IS_OK(werr = reg_enumkey(mem_ctx, key, idx,
+			     		      &subkey_name, NULL));
+	    ) 
+	{
+		werr = reg_deletekey_recursive(mem_ctx, key, subkey_name);
+		if (!W_ERROR_IS_OK(werr)) {
+			goto done;
+		}
+	}
+	if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
+		DEBUG(1, ("reg_deletekey_recursive: Error enumerating "
+			  "subkeys: %s\\n", dos_errstr(werr)));
+		goto done;
+	}
+
+	/* now delete the actual key */
+	werr = reg_deletekey(parent, path);
+	
+done:
+	TALLOC_FREE(mem_ctx);
+	return werr;
+}

