diff options
-rw-r--r-- | source3/registry/reg_api.c | 56 |
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; +} |