Copy an entire registry key with one simple function






4.15/5 (11 votes)
Jan 31, 2001

134031
A simple API like function that will do this job for you.
Introduction
This small function will copy an entire registry key including all it's values and sub-keys to a new key.
For example, if you wish to copy: HKEY_CURRENT_USER\SoftWare\MySoftware to HKEY_CURRENT_USER\SoftWare\$MYTEMP$, you'll need to do the following:
HKEY SrcKey; HKEY TrgKey; RegOpenKeyEx(HKEY_CURRENT_USER,"SoftWare\\MySoftware", 0, KEY_READ, &SrcKey); RegOpenKeyEx(HKEY_CURRENT_USER,"SoftWare", 0, KEY_READ, &TrgKey); if (RegCopyKey(SrcKey, TrgKey, "$MYTEMP$") == ERROR_SUCCESS) ; // All went okay else ; // Something went wrong
The code
//------------------------------------------------ // free buffer //------------------------------------------------ __forceinline void FreeBuff(unsigned char** Buff) { if (*Buff) { free(*Buff); *Buff = NULL; } } //------------------------------------------------- // allocate buffer //------------------------------------------------- __forceinline void AllocBuff(unsigned char** Buff, DWORD BuffSize) { FreeBuff(Buff); *Buff = (unsigned char*)malloc(BuffSize); } //-------------------------------------------------- // copy key to new position //-------------------------------------------------- LONG RegCopyKey(HKEY SrcKey, HKEY TrgKey, char* TrgSubKeyName) { HKEY SrcSubKey; HKEY TrgSubKey; int ValEnumIndx=0; int KeyEnumIndx=0; char ValName[MAX_PATH+1]; char KeyName[MAX_PATH+1]; DWORD size; DWORD VarType; DWORD BuffSize; unsigned char* Buff=NULL; LONG Err; DWORD KeyDisposition; FILETIME LastWriteTime; // create target key if (RegCreateKeyEx(TrgKey,TrgSubKeyName, NULL,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,NULL,&TrgSubKey, &KeyDisposition) != ERROR_SUCCESS) return GetLastError(); do { do { // read value from source key Err = ERROR_NOT_ENOUGH_MEMORY; BuffSize = 1024; do { AllocBuff(&Buff,BuffSize); size=MAX_PATH+1; Err = RegEnumValue(SrcKey,ValEnumIndx, ValName,&size,NULL,&VarType, Buff,&BuffSize); if ((Err != ERROR_SUCCESS) && (Err != ERROR_NO_MORE_ITEMS)) Err = GetLastError(); } while (Err == ERROR_NOT_ENOUGH_MEMORY); // done copying this key if (Err == ERROR_NO_MORE_ITEMS) break; // unknown error return if (Err != ERROR_SUCCESS) goto quit_err; // write value to target key if (RegSetValueEx(TrgSubKey,ValName, NULL,VarType,Buff, BuffSize) != ERROR_SUCCESS) goto quit_get_err; // read next value ValEnumIndx++; } while (true); // free buffer FreeBuff(&Buff); // if copying under the same // key avoid endless recursions do { // enum sub keys size=MAX_PATH+1; Err = RegEnumKeyEx(SrcKey,KeyEnumIndx++, KeyName,&size,NULL,NULL, NULL,&LastWriteTime); } while ((SrcKey == TrgKey) && !strnicmp(KeyName,TrgSubKeyName,strlen(KeyName)) && (Err == ERROR_SUCCESS)); // done copying this key if (Err == ERROR_NO_MORE_ITEMS) break; // unknown error return if (Err != ERROR_SUCCESS) goto quit_get_err; // open the source subkey if (RegOpenKeyEx(SrcKey,KeyName,NULL, KEY_ALL_ACCESS, &SrcSubKey) != ERROR_SUCCESS) goto quit_get_err; // recurs with the subkey if ((Err = CopyKey(SrcSubKey, TrgSubKey, KeyName)) != ERROR_SUCCESS) break; if (RegCloseKey(SrcSubKey) != ERROR_SUCCESS) goto quit_get_err; } while (true); // normal quit quit_err: FreeBuff(&Buff); RegCloseKey(TrgSubKey); if (Err == ERROR_NO_MORE_ITEMS) return ERROR_SUCCESS; else return Err; // abnormal quit quit_get_err: FreeBuff(&Buff); RegCloseKey(TrgSubKey); return GetLastError(); }