Author: jelmer Date: 2007-08-06 23:37:24 +0000 (Mon, 06 Aug 2007) New Revision: 24258
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=24258 Log: Fix flush_key, del_value. Modified: branches/4.0-regwrite/source/lib/registry/dir.c branches/4.0-regwrite/source/lib/registry/hive.c branches/4.0-regwrite/source/lib/registry/hive.h branches/4.0-regwrite/source/lib/registry/ldb.c branches/4.0-regwrite/source/lib/registry/local.c branches/4.0-regwrite/source/lib/registry/tests/hive.c branches/4.0-regwrite/source/lib/registry/tests/registry.c Changeset: Modified: branches/4.0-regwrite/source/lib/registry/dir.c =================================================================== --- branches/4.0-regwrite/source/lib/registry/dir.c 2007-08-06 22:24:12 UTC (rev 24257) +++ branches/4.0-regwrite/source/lib/registry/dir.c 2007-08-06 23:37:24 UTC (rev 24258) @@ -214,24 +214,58 @@ return WERR_OK; } -static WERROR reg_dir_enum_value (TALLOC_CTX *mem_ctx, +static WERROR reg_dir_get_value (TALLOC_CTX *mem_ctx, struct hive_key *key, const char *name, uint32_t *type, DATA_BLOB *data) { const struct dir_key *dk = talloc_get_type(key, struct dir_key); + char *path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name); + size_t size; + char *contents; + + contents = file_load(path, &size, mem_ctx); + talloc_free(path); + if (contents == NULL) + return WERR_NOT_FOUND; + + if (type != NULL) + *type = 4; /* FIXME */ + + data->data = (uint8_t *)contents; + data->length = size; + + return WERR_OK; +} + +static WERROR reg_dir_enum_value (TALLOC_CTX *mem_ctx, + const struct hive_key *key, int idx, + const char **name, + uint32_t *type, DATA_BLOB *data) +{ + const struct dir_key *dk = talloc_get_type(key, struct dir_key); DIR *d; + struct dirent *e; + int i; d = opendir(dk->path); if (d == NULL) { - DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno))); + DEBUG(3,("Unable to open '%s': %s\n", dk->path, strerror(errno))); return WERR_BADFILE; } + i = 0; while((e = readdir(d))) { if (ISDOT(e->d_name) || ISDOTDOT(e->d_name)) continue; + if (i == idx) { + if (name != NULL) + *name = talloc_strdup(mem_ctx, e->d_name); + W_ERROR_NOT_OK_RETURN(reg_dir_get_value(mem_ctx, key, *name, type, data)); + return WERR_OK; + } + i++; } closedir(d); @@ -239,29 +273,20 @@ } -static WERROR reg_dir_get_value (TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data) +static WERROR reg_dir_del_value (struct hive_key *key, const char *name) { const struct dir_key *dk = talloc_get_type(key, struct dir_key); - char *path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name); - size_t size; - char *contents; - - contents = file_load(path, &size, mem_ctx); + char *path = talloc_asprintf(key, "%s/%s", dk->path, name); + if (unlink(path) < 0) { + talloc_free(path); + if (errno == ENOENT) + return WERR_NOT_FOUND; + return WERR_GENERAL_FAILURE; + } talloc_free(path); - if (contents == NULL) - return WERR_NOT_FOUND; - - if (type != NULL) - *type = 4; /* FIXME */ - - data->data = (uint8_t *)contents; - data->length = size; - + return WERR_OK; } - static struct hive_operations reg_backend_dir = { .name = "dir", @@ -272,5 +297,6 @@ .enum_key = reg_dir_key_by_index, .set_value = reg_dir_set_value, .get_value_by_name = reg_dir_get_value, - .get_value_by_index = reg_dir_enum_value, + .enum_value = reg_dir_enum_value, + .delete_value = reg_dir_del_value, }; Modified: branches/4.0-regwrite/source/lib/registry/hive.c =================================================================== --- branches/4.0-regwrite/source/lib/registry/hive.c 2007-08-06 22:24:12 UTC (rev 24257) +++ branches/4.0-regwrite/source/lib/registry/hive.c 2007-08-06 23:37:24 UTC (rev 24258) @@ -125,3 +125,20 @@ return key->ops->enum_value(mem_ctx, key, idx, name, type, data); } + + +WERROR hive_del_value (struct hive_key *key, const char *name) +{ + if (key->ops->delete_value == NULL) + return WERR_NOT_SUPPORTED; + + return key->ops->delete_value(key, name); +} + +WERROR hive_key_flush(struct hive_key *key) +{ + if (key->ops->flush_key == NULL) + return WERR_OK; + + return key->ops->flush_key(key); +} Modified: branches/4.0-regwrite/source/lib/registry/hive.h =================================================================== --- branches/4.0-regwrite/source/lib/registry/hive.h 2007-08-06 22:24:12 UTC (rev 24257) +++ branches/4.0-regwrite/source/lib/registry/hive.h 2007-08-06 23:37:24 UTC (rev 24258) @@ -170,10 +170,11 @@ struct hive_key *key, uint32_t idx, const char **name, uint32_t *type, DATA_BLOB *data); +WERROR hive_del_value (struct hive_key *key, const char *name); +WERROR hive_key_flush(struct hive_key *key); - /* Individual backends */ WERROR reg_open_directory(TALLOC_CTX *parent_ctx, const char *location, struct hive_key **key); Modified: branches/4.0-regwrite/source/lib/registry/ldb.c =================================================================== --- branches/4.0-regwrite/source/lib/registry/ldb.c 2007-08-06 22:24:12 UTC (rev 24257) +++ branches/4.0-regwrite/source/lib/registry/ldb.c 2007-08-06 23:37:24 UTC (rev 24258) @@ -401,7 +401,9 @@ talloc_free(childdn); - if (ret < 0) { + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + return WERR_NOT_FOUND; + } else if (ret < 0) { DEBUG(1, ("ldb_del_value: %s\n", ldb_errstring(kd->ldb))); return WERR_FOOBAR; } Modified: branches/4.0-regwrite/source/lib/registry/local.c =================================================================== --- branches/4.0-regwrite/source/lib/registry/local.c 2007-08-06 22:24:12 UTC (rev 24257) +++ branches/4.0-regwrite/source/lib/registry/local.c 2007-08-06 23:37:24 UTC (rev 24258) @@ -215,6 +215,27 @@ name, type, data); } +static WERROR local_delete_key (struct registry_key *key, const char *name) +{ + const struct local_key *local = (const struct local_key *)key; + + return hive_key_del(local->hive_key, name); +} + +static WERROR local_delete_value (struct registry_key *key, const char *name) +{ + const struct local_key *local = (const struct local_key *)key; + + return hive_del_value(local->hive_key, name); +} + +static WERROR local_flush_key (struct registry_key *key) +{ + const struct local_key *local = (const struct local_key *)key; + + return hive_key_flush(local->hive_key); +} + const static struct registry_operations local_ops = { .name = "local", .open_key = local_open_key, @@ -224,6 +245,9 @@ .set_value = local_set_value, .get_value = local_get_value, .enum_value = local_enum_value, + .delete_key = local_delete_key, + .delete_value = local_delete_value, + .flush_key = local_flush_key, }; WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, Modified: branches/4.0-regwrite/source/lib/registry/tests/hive.c =================================================================== --- branches/4.0-regwrite/source/lib/registry/tests/hive.c 2007-08-06 22:24:12 UTC (rev 24257) +++ branches/4.0-regwrite/source/lib/registry/tests/hive.c 2007-08-06 23:37:24 UTC (rev 24258) @@ -81,6 +81,36 @@ return true; } +static bool test_flush_key(struct torture_context *tctx, + const void *test_data) +{ + struct hive_key *root = test_data; + + torture_assert_werr_ok(tctx, hive_key_flush(root), "flush key"); + + return true; +} + +static bool test_del_key(struct torture_context *tctx, const void *test_data) +{ + WERROR error; + struct hive_key *subkey; + const struct hive_key *root = test_data; + TALLOC_CTX *mem_ctx = tctx; + + error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL, + NULL, &subkey); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + error = hive_key_del(root, "Nested Key"); + torture_assert_werr_ok(tctx, error, "reg_key_del"); + + error = hive_key_del(root, "Nested Key"); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "reg_key_del"); + + return true; +} + static bool test_set_value(struct torture_context *tctx, const void *test_data) { @@ -134,6 +164,36 @@ return true; } +static bool test_del_value(struct torture_context *tctx, const void *test_data) +{ + WERROR error; + struct hive_key *subkey; + const struct hive_key *root = test_data; + TALLOC_CTX *mem_ctx = tctx; + uint32_t data = 42; + uint32_t type; + DATA_BLOB value; + + error = hive_key_add_name(mem_ctx, root, "EEYA Nested Key", NULL, + NULL, &subkey); + torture_assert_werr_ok(tctx, error, "hive_key_add_name"); + + error = hive_set_value(subkey, "Answer", REG_DWORD, + data_blob_talloc(mem_ctx, &data, sizeof(data))); + torture_assert_werr_ok(tctx, error, "hive_set_value"); + + error = hive_del_value(subkey, "Answer"); + torture_assert_werr_ok(tctx, error, "deleting value"); + + error = hive_get_value(mem_ctx, subkey, "Answer", &type, &value); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "getting value"); + + error = hive_del_value(subkey, "Answer"); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "deleting value"); + + return true; +} + static bool test_list_values(struct torture_context *tctx, const void *test_data) { @@ -174,17 +234,14 @@ { torture_tcase_add_simple_test(tcase, "del_nonexistant_key", test_del_nonexistant_key); - torture_tcase_add_simple_test(tcase, "add_subkey", test_add_subkey); - + torture_tcase_add_simple_test(tcase, "flush_key", test_flush_key); torture_tcase_add_simple_test(tcase, "get_info", test_keyinfo_root); - torture_tcase_add_simple_test(tcase, "set_value", test_set_value); - torture_tcase_add_simple_test(tcase, "get_value", test_get_value); - torture_tcase_add_simple_test(tcase, "list_values", test_list_values); - + torture_tcase_add_simple_test(tcase, "del_key", test_del_key); + torture_tcase_add_simple_test(tcase, "del_value", test_del_value); } static bool hive_setup_dir(struct torture_context *tctx, void **data) Modified: branches/4.0-regwrite/source/lib/registry/tests/registry.c =================================================================== --- branches/4.0-regwrite/source/lib/registry/tests/registry.c 2007-08-06 22:24:12 UTC (rev 24257) +++ branches/4.0-regwrite/source/lib/registry/tests/registry.c 2007-08-06 23:37:24 UTC (rev 24258) @@ -68,6 +68,32 @@ return true; } + +static bool test_del_key(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root, *newkey; + WERROR error; + + error = reg_get_predefined_key(rctx, HKEY_CLASSES_ROOT, &root); + torture_assert_werr_ok(tctx, error, + "getting predefined key failed"); + + error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL, &newkey); + + torture_assert_werr_ok(tctx, error, "Creating key return code"); + torture_assert(tctx, newkey != NULL, "Creating new key"); + + error = reg_key_del(root, "Hamburg"); + torture_assert_werr_ok(tctx, error, "Delete key"); + + error = reg_key_del(root, "Hamburg"); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "Delete missing key"); + + return true; +} + /** * Convenience function for opening the HKEY_CLASSES_ROOT hive and * creating a single key for testing purposes. @@ -90,6 +116,22 @@ return true; } + +static bool test_flush_key(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *root, *subkey; + WERROR error; + + if (!create_test_key(tctx, rctx, "Munchen", &root, &subkey)) + return false; + + error = reg_key_flush(subkey); + torture_assert_werr_ok(tctx, error, "flush key"); + + return true; +} + /** * Test that the subkeys of a key can be enumerated, that * the returned parameters for get_subkey_by_index are optional and @@ -186,6 +228,40 @@ } /** + * Test unsetting a value + */ +static bool test_del_value(struct torture_context *tctx, const void *_data) +{ + const struct registry_context *rctx = _data; + struct registry_key *subkey = NULL, *root; + WERROR error; + DATA_BLOB data; + uint32_t value = 42; + uint32_t type; + + if (!create_test_key(tctx, rctx, "Duisburg", &root, &subkey)) + return false; + + error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, + &data); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "getting missing value"); + + error = reg_val_set(subkey, __FUNCTION__, REG_DWORD, + data_blob_talloc(tctx, &value, 4)); + torture_assert_werr_ok (tctx, error, "setting value"); + + error = reg_del_value(subkey, __FUNCTION__); + torture_assert_werr_ok (tctx, error, "unsetting value"); + + error = reg_key_get_value_by_name(tctx, subkey, __FUNCTION__, &type, &data); + torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, + "getting missing value"); + + return true; +} + +/** * Test listing values */ static bool test_list_values(struct torture_context *tctx, const void *_data) @@ -262,6 +338,9 @@ torture_tcase_add_simple_test(tcase, "set_value", test_set_value); torture_tcase_add_simple_test(tcase, "get_value", test_get_value); torture_tcase_add_simple_test(tcase, "list_values", test_list_values); + torture_tcase_add_simple_test(tcase, "del_key", test_del_key); + torture_tcase_add_simple_test(tcase, "del_value", test_del_value); + torture_tcase_add_simple_test(tcase, "flush_key", test_flush_key); } struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx)