summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2007-06-22 11:21:59 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:23:32 -0500
commit394291281a0be7a150086fc459614f4fe3f56c1f (patch)
tree8006ca34206d6fa68231d708b399c2dca2604963
parentc66831e04b468743df8993edc68cd72ebb4a391d (diff)
downloadsamba-394291281a0be7a150086fc459614f4fe3f56c1f.tar.gz
samba-394291281a0be7a150086fc459614f4fe3f56c1f.tar.bz2
samba-394291281a0be7a150086fc459614f4fe3f56c1f.zip
r23583: 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 (This used to be commit 41c3ff6e277601a9c7ac29009fd89ff9c961ca46)
-rw-r--r--source3/registry/reg_api.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c
index 4fbf54e753..e2bb56deea 100644
--- a/source3/registry/reg_api.c
+++ b/source3/registry/reg_api.c
@@ -677,3 +677,59 @@ WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path,
*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;
+}