Renaming registry keys...

Mike Hearn mike at theoretic.com
Thu Jan 1 09:10:34 CST 2004


On Thu, 2004-01-01 at 13:38, Robert van Herk wrote:
> When someone configures app1.exe, and later on decides that he actually 
> meant app2.exe, he might want to rename app1.exe to app2.exe, and so 
> migrate all the settings.

Oh, I see.... I was intending to simply not support that :) 

What you want is a deep tree copy function. You can then do renaming by
copying the contents of a key to a new key, and deleting the old one.

Here's one I just knocked up. Total pain in the ass isn't it! Hopefully
when we get a standard config system on Linux it will be a bit better
designed....

/* Copy the values and subkeys of the registry key source to dest recursively.
 * Returns NO_ERROR if the copy completed OK, otherwise it propagates the error.
 */
LONG copytree(HKEY source, HKEY dest) {
    int i = 0;
    LONG res;
    
    /* first of all, copy the values */
    while (1) {
	char valname[MAX_VALUE_NAME];
	DWORD valname_size = sizeof(valname);
	DWORD size;
	DWORD typecode;
	char *value;
	
	/* determine size of the buffer we'll need */
	res = RegEnumValue(source, i, valname, &valname_size, NULL, &typecode, NULL, &size);
	if (res == ERROR_NO_MORE_ITEMS) break;
	if (res != NO_ERROR) return res;

	value = HeapAlloc(GetProcessHeap(), 0, size);
	if (!value) return ERROR_OUTOFMEMORY;

	valname_size = sizeof(valname); /* RegEnumValue blasts this even though it doesn't need to */
	res = RegEnumValue(source, i, valname, &valname_size, NULL, &typecode, value, &size);
	if (res != NO_ERROR) return res;

	res = RegSetValueEx(dest, valname, 0, typecode, value, size);
	if (res != NO_ERROR) return res;

	HeapFree(GetProcessHeap(), 0, value);
	
	i++;
    }

    /* for each subkey, create an equivalent under dest then recurse into ourselves to complete the copy */
    i = 0;
    while (1) {
	HKEY subkey_src, subkey_dest;
	char name[MAX_KEY_LENGTH];
	DWORD size = sizeof(name);
	FILETIME time;

	res = RegEnumKeyEx(source, i, name, &size, NULL, NULL, NULL, &time);
	if (res == ERROR_NO_MORE_ITEMS) break;
	if (res != NO_ERROR) return res;

	/* create the destination subkey */
	res = RegCreateKey(dest, name, &subkey_dest);
	if (res != NO_ERROR) return res;

	/* open the source subkey */
	res = RegOpenKey(source, name, &subkey_src);
	if (res != NO_ERROR) return res;

	/* perform the recursive copy */
	res = copytree(subkey_src, subkey_dest);
	if (res != NO_ERROR) return res;

	i++;
    }
    return NO_ERROR;
}

Hope that helps!
thanks -mike




More information about the wine-devel mailing list