Click here to Skip to main content
12,897,739 members (59,411 online)
Click here to Skip to main content
Add your own
alternative version

Stats

110.8K views
22 bookmarked
Posted 30 Jan 2001

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

You may also be interested in...

Pro

Comments and Discussions

 
GeneralFixed > 1024 issue Pin
Harlan Seymour12-Feb-04 9:01
sussHarlan Seymour12-Feb-04 9:01 
GeneralRe: Fixed > 1024 issue Pin
wschmidt21-Feb-04 3:00
memberwschmidt21-Feb-04 3:00 

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.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170424.1 | Last Updated 1 Apr 2001
Article Copyright 2001 by Ziv Ayalon
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid