summaryrefslogtreecommitdiff
path: root/source3/registry
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2008-02-15 15:31:31 +0100
committerMichael Adam <obnox@samba.org>2008-02-15 16:23:10 +0100
commit355faf2e3d0aa83401c63e70a5aff9c9f5466195 (patch)
tree0c80bf9c7db9b1b56dc6148bbe9116861448e410 /source3/registry
parentc720a0e228bd157b8c743f8b98cc63817650d364 (diff)
downloadsamba-355faf2e3d0aa83401c63e70a5aff9c9f5466195.tar.gz
samba-355faf2e3d0aa83401c63e70a5aff9c9f5466195.tar.bz2
samba-355faf2e3d0aa83401c63e70a5aff9c9f5466195.zip
Move the implementation of _winreg_RestoreKey to reg_api.c
This removes the internals of reg_api from srv_winreg_nt.c entirely, only reg_api is used there, now. This enlarges the dependencies of reg_api somewhat now since it adds regfio. But this can be separated out later. The current goal is to achieve a complete use of reg_api. Michael (This used to be commit 2222acbac955cd6d5bd48d1ce5cf4b4c7c067093)
Diffstat (limited to 'source3/registry')
-rw-r--r--source3/registry/reg_api.c126
1 files changed, 125 insertions, 1 deletions
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c
index fd3e08cacd..6be60f04ec 100644
--- a/source3/registry/reg_api.c
+++ b/source3/registry/reg_api.c
@@ -43,7 +43,7 @@
* 0x10 winreg_QueryInfoKey reg_queryinfokey
* 0x11 winreg_QueryValue reg_queryvalue
* 0x12 winreg_ReplaceKey
- * 0x13 winreg_RestoreKey
+ * 0x13 winreg_RestoreKey reg_restorekey
* 0x14 winreg_SaveKey reg_savekey
* 0x15 winreg_SetKeySecurity reg_setkeysecurity
* 0x16 winreg_SetValue reg_setvalue
@@ -697,6 +697,130 @@ WERROR reg_getversion(uint32_t *version)
return WERR_OK;
}
+/*******************************************************************
+ Note: topkeypat is the *full* path that this *key will be
+ loaded into (including the name of the key)
+ ********************************************************************/
+
+static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath,
+ REGF_NK_REC *key )
+{
+ REGF_NK_REC *subkey;
+ REGISTRY_KEY registry_key;
+ REGVAL_CTR *values;
+ REGSUBKEY_CTR *subkeys;
+ int i;
+ char *path = NULL;
+ WERROR result = WERR_OK;
+
+ /* initialize the REGISTRY_KEY structure */
+
+ if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) {
+ DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n",
+ topkeypath ));
+ return WERR_BADFILE;
+ }
+
+ registry_key.name = talloc_strdup( regfile->mem_ctx, topkeypath );
+ if ( !registry_key.name ) {
+ DEBUG(0,("reg_load_tree: Talloc failed for reg_key.name!\n"));
+ return WERR_NOMEM;
+ }
+
+ /* now start parsing the values and subkeys */
+
+ if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) )
+ return WERR_NOMEM;
+
+ if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) )
+ return WERR_NOMEM;
+
+ /* copy values into the REGVAL_CTR */
+
+ for ( i=0; i<key->num_values; i++ ) {
+ regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type,
+ (char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) );
+ }
+
+ /* copy subkeys into the REGSUBKEY_CTR */
+
+ key->subkey_index = 0;
+ while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
+ regsubkey_ctr_addkey( subkeys, subkey->keyname );
+ }
+
+ /* write this key and values out */
+
+ if ( !store_reg_values( &registry_key, values )
+ || !store_reg_keys( &registry_key, subkeys ) )
+ {
+ DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
+ result = WERR_REG_IO_FAILURE;
+ }
+
+ TALLOC_FREE( subkeys );
+
+ if ( !W_ERROR_IS_OK(result) )
+ return result;
+
+ /* now continue to load each subkey registry tree */
+
+ key->subkey_index = 0;
+ while ( (subkey = regfio_fetch_subkey( regfile, key )) ) {
+ path = talloc_asprintf(regfile->mem_ctx,
+ "%s\\%s",
+ topkeypath,
+ subkey->keyname);
+ if (!path) {
+ return WERR_NOMEM;
+ }
+ result = reg_load_tree( regfile, path, subkey );
+ if ( !W_ERROR_IS_OK(result) )
+ break;
+ }
+
+ return result;
+}
+
+/*******************************************************************
+ ********************************************************************/
+
+static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname )
+{
+ REGF_FILE *regfile;
+ REGF_NK_REC *rootkey;
+ WERROR result;
+
+ /* open the registry file....fail if the file already exists */
+
+ if ( !(regfile = regfio_open( fname, (O_RDONLY), 0 )) ) {
+ DEBUG(0,("restore_registry_key: failed to open \"%s\" (%s)\n",
+ fname, strerror(errno) ));
+ return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) );
+ }
+
+ /* get the rootkey from the regf file and then load the tree
+ via recursive calls */
+
+ if ( !(rootkey = regfio_rootkey( regfile )) ) {
+ regfio_close( regfile );
+ return WERR_REG_FILE_INVALID;
+ }
+
+ result = reg_load_tree( regfile, krecord->name, rootkey );
+
+ /* cleanup */
+
+ regfio_close( regfile );
+
+ return result;
+}
+
+WERROR reg_restorekey(struct registry_key *key, const char *fname)
+{
+ return restore_registry_key(key->key, fname);
+}
+
/********************************************************************
********************************************************************/