Click here to Skip to main content
15,860,844 members
Articles / Programming Languages / C++
Article

Copy an entire registry key with one simple function

Rate me:
Please Sign up or sign in to vote.
4.15/5 (13 votes)
31 Mar 2001 130.9K   22   24
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


Written By
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionUse SHCopyKey() instead Pin
Tornacious12-Mar-12 12:30
Tornacious12-Mar-12 12:30 
GeneralMy vote of 3 Pin
Tornacious12-Mar-12 12:21
Tornacious12-Mar-12 12:21 
GeneralMy vote of 2 Pin
oren.shnitzer30-Oct-11 4:52
oren.shnitzer30-Oct-11 4:52 
GeneralMy vote of 2 Pin
kpavelko24-Nov-08 6:26
kpavelko24-Nov-08 6:26 
GeneralThank you!! Pin
pointer19-Aug-08 3:38
pointer19-Aug-08 3:38 
Generalin addition Pin
Valery A. Boronin5-May-06 9:43
Valery A. Boronin5-May-06 9:43 
Generalunicode & security Pin
Valery A. Boronin5-May-06 7:53
Valery A. Boronin5-May-06 7:53 
Generali get errors C3861 Pin
E-Male19-May-04 0:08
E-Male19-May-04 0:08 
GeneralFixed > 1024 issue Pin
Harlan Seymour12-Feb-04 9:01
Harlan Seymour12-Feb-04 9:01 
GeneralRe: Fixed > 1024 issue Pin
wschmidt21-Feb-04 3:00
wschmidt21-Feb-04 3:00 
GeneralThe best i´ve ever seen Pin
Anonymous26-Nov-03 5:30
Anonymous26-Nov-03 5:30 
GeneralThank you! Pin
Eugene Plokhov26-Oct-03 18:07
Eugene Plokhov26-Oct-03 18:07 
GeneralDeserves a big 5! Pin
4-Apr-02 1:13
suss4-Apr-02 1:13 
GeneralSome bugs Pin
Michael Walz20-Mar-02 3:18
Michael Walz20-Mar-02 3:18 
GeneralExcellent Pin
Mandalis16-Mar-02 6:24
Mandalis16-Mar-02 6:24 
GeneralRegKeyOpenEx Pin
7-Mar-02 11:33
suss7-Mar-02 11:33 
GeneralImporting Reg files Pin
14-Jan-02 23:48
suss14-Jan-02 23:48 
GeneralRe: Importing Reg files Pin
7-May-02 4:36
suss7-May-02 4:36 
QuestionKEY_READ? Pin
6-Nov-01 22:25
suss6-Nov-01 22:25 
AnswerRe: KEY_READ? Pin
8-Nov-01 5:05
suss8-Nov-01 5:05 
GeneralRe: KEY_READ? Pin
XIIX11-Aug-02 9:52
XIIX11-Aug-02 9:52 
GeneralGood job Pin
1-Apr-01 20:30
suss1-Apr-01 20:30 
GeneralNice, but... Pin
26-Feb-01 5:53
suss26-Feb-01 5:53 
The code is very useful to me, thank you!

But, what has this code to do with 'Book Chapters', as it is in the Book Chapters category of the site.
GeneralRe: Nice, but... Pin
28-Feb-02 8:18
suss28-Feb-02 8:18 

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

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