static struct db_context *regdb = NULL;
static int regdb_refcount;
+static bool regdb_key_exists(const char *key);
+
/* List the deepest path into the registry. All part components will be created.*/
/* If you want to have a part of the path controlled by the tdb and part by
{
WERROR werr;
+ if (regdb_key_exists(add_path)) {
+ return WERR_OK;
+ }
+
if (regdb->transaction_start(regdb) != 0) {
DEBUG(0, ("init_registry_key: transaction_start failed\n"));
return WERR_REG_IO_FAILURE;
WERROR init_registry_data(void)
{
WERROR werr;
- TALLOC_CTX *frame = NULL;
+ TALLOC_CTX *frame = talloc_stackframe();
REGVAL_CTR *values;
int i;
UNISTR2 data;
+ /*
+ * First, check for the existence of the needed keys and values.
+ * If all do already exist, we can save the writes.
+ */
+ for (i=0; builtin_registry_paths[i] != NULL; i++) {
+ if (!regdb_key_exists(builtin_registry_paths[i])) {
+ goto do_init;
+ }
+ }
+
+ for (i=0; builtin_registry_values[i].path != NULL; i++) {
+ values = TALLOC_ZERO_P(frame, REGVAL_CTR);
+ if (values == NULL) {
+ werr = WERR_NOMEM;
+ goto done;
+ }
+
+ regdb_fetch_values(builtin_registry_values[i].path, values);
+ if (!regval_ctr_key_exists(values,
+ builtin_registry_values[i].valuename))
+ {
+ TALLOC_FREE(values);
+ goto do_init;
+ }
+
+ TALLOC_FREE(values);
+ }
+
+ werr = WERR_OK;
+ goto done;
+
+do_init:
+
/*
* There are potentially quite a few store operations which are all
* indiviually wrapped in tdb transactions. Wrapping them in a single
if (regdb->transaction_start(regdb) != 0) {
DEBUG(0, ("init_registry_data: tdb_transaction_start "
"failed\n"));
- return WERR_REG_IO_FAILURE;
+ werr = WERR_REG_IO_FAILURE;
+ goto done;
}
/* loop over all of the predefined paths and add each component */
for (i=0; builtin_registry_paths[i] != NULL; i++) {
+ if (regdb_key_exists(builtin_registry_paths[i])) {
+ continue;
+ }
werr = init_registry_key_internal(builtin_registry_paths[i]);
if (!W_ERROR_IS_OK(werr)) {
goto fail;
/* loop over all of the predefined values and add each component */
- frame = talloc_stackframe();
-
for (i=0; builtin_registry_values[i].path != NULL; i++) {
values = TALLOC_ZERO_P(frame, REGVAL_CTR);
TALLOC_FREE(values);
}
- TALLOC_FREE(frame);
-
if (regdb->transaction_commit(regdb) != 0) {
DEBUG(0, ("init_registry_data: Could not commit "
"transaction\n"));
- return WERR_REG_IO_FAILURE;
+ werr = WERR_REG_IO_FAILURE;
+ } else {
+ werr = WERR_OK;
}
- return WERR_OK;
-
- fail:
-
- TALLOC_FREE(frame);
+ goto done;
+fail:
if (regdb->transaction_cancel(regdb) != 0) {
smb_panic("init_registry_data: tdb_transaction_cancel "
"failed\n");
}
+done:
+ TALLOC_FREE(frame);
return werr;
}
}
-static TDB_DATA regdb_fetch_key_internal(const char *key, TALLOC_CTX *mem_ctx)
+static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key)
{
char *path = NULL;
+ TDB_DATA data;
path = normalize_reg_path(mem_ctx, key);
if (!path) {
return make_tdb_data(NULL, 0);
}
- return dbwrap_fetch_bystring(regdb, mem_ctx, path);
+ data = dbwrap_fetch_bystring(regdb, mem_ctx, path);
+
+ TALLOC_FREE(path);
+ return data;
+}
+
+
+static bool regdb_key_exists(const char *key)
+{
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+ TDB_DATA value;
+ bool ret;
+
+ value = regdb_fetch_key_internal(mem_ctx, key);
+ ret = (value.dptr != NULL);
+
+ TALLOC_FREE(mem_ctx);
+ return ret;
}
+
/***********************************************************************
Retrieve an array of strings containing subkeys. Memory should be
released by the caller.
ctr->seqnum = regdb_get_seqnum();
- value = regdb_fetch_key_internal(key, frame);
+ value = regdb_fetch_key_internal(frame, key);
buf = value.dptr;
buflen = value.dsize;
values->seqnum = regdb_get_seqnum();
- value = regdb_fetch_key_internal(keystr, ctx);
+ value = regdb_fetch_key_internal(ctx, keystr);
if (!value.dptr) {
/* all keys have zero values by default */