Click here to Skip to main content
Click here to Skip to main content
Go to top

Copy an entire registry key with one simple function

, 31 Mar 2001
Rate this:
Please Sign up or sign in to vote.
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();
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Ziv Ayalon

Israel Israel
No Biography provided

Comments and Discussions

 
QuestionUse SHCopyKey() instead PinmemberTornacious12-Mar-12 12:30 
GeneralMy vote of 3 PinmemberTornacious12-Mar-12 12:21 
GeneralMy vote of 2 Pinmemberoren.shnitzer30-Oct-11 4:52 
GeneralMy vote of 2 Pinmemberkpavelko24-Nov-08 6:26 
GeneralThank you!! Pinmemberpointer19-Aug-08 3:38 
Generalin addition PinmemberValery A. Boronin5-May-06 9:43 
Generalunicode & security PinmemberValery A. Boronin5-May-06 7:53 
Generali get errors C3861 PinmemberE-Male19-May-04 0:08 
i added this function to a program (which for now does nothing)
then i got these errors:
 
p:\regtest2\regtest2.cpp(20) : error C3861: 'free': identifier not found, even with argument-dependent lookup
p:\regtest2\regtest2.cpp(31) : error C3861: 'malloc': identifier not found, even with argument-dependent lookup
p:\regtest2\regtest2.cpp(110) : error C3861: 'CopyKey': identifier not found, even with argument-dependent lookup
 
did i do anythign wrong?
maybe forgot to include something or add a namespace?
 
i use ms visual studio .net 2003 c++
 
thx in advance
E-Male
GeneralFixed > 1024 issue PinsussHarlan Seymour12-Feb-04 9:01 
GeneralRe: Fixed > 1024 issue Pinmemberwschmidt21-Feb-04 3:00 
GeneralThe best i´ve ever seen PinsussAnonymous26-Nov-03 5:30 
GeneralThank you! PinmemberEugene Plokhov26-Oct-03 18:07 
GeneralDeserves a big 5! PinmemberGeert Delmeiren4-Apr-02 1:13 
GeneralSome bugs PinmemberMichael Walz20-Mar-02 3:18 
GeneralExcellent PinmemberMandalis16-Mar-02 6:24 
GeneralRegKeyOpenEx PinmemberAnonymous7-Mar-02 11:33 
GeneralImporting Reg files PinmemberKunjan14-Jan-02 23:48 
GeneralRe: Importing Reg files PinmemberAnonymous7-May-02 4:36 
QuestionKEY_READ? PinmemberIstrebitjel6-Nov-01 22:25 
AnswerRe: KEY_READ? PinmemberZiv Ayalon8-Nov-01 5:05 
GeneralRe: KEY_READ? PinmemberXIIX11-Aug-02 9:52 
GeneralGood job PinmemberAnonymous1-Apr-01 20:30 
GeneralNice, but... PinmemberAnonymous26-Feb-01 5:53 
GeneralRe: Nice, but... PinmemberJohn Miller Smith Ann28-Feb-02 8:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140921.1 | Last Updated 1 Apr 2001
Article Copyright 2001 by Ziv Ayalon
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid