From 355faf2e3d0aa83401c63e70a5aff9c9f5466195 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 15 Feb 2008 15:31:31 +0100 Subject: 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) --- source3/registry/reg_api.c | 126 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) (limited to 'source3/registry') 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; inum_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( ®istry_key, values ) + || !store_reg_keys( ®istry_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); +} + /******************************************************************** ********************************************************************/ -- cgit