r23583: Add a utility function to recursively delete a Registry
authorMichael Adam <obnox@samba.org>
Fri, 22 Jun 2007 11:21:59 +0000 (11:21 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:23:32 +0000 (12:23 -0500)
key with all its subkeys. (reg_deletekey will refuse to
delete a key with subkeys with WERR_ACCESS_DENIED).

Michael

source/registry/reg_api.c

index 4fbf54e75376bc65df97c1a219645ca2f7aaddd1..e2bb56deea073df6f50fde6bdf1afe75d5db5483 100644 (file)
@@ -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;
+}