|
|
//-----------------------------------------------------------------------//
//
// File: copy.cpp
// Created: April 1997
// By: Martin Holladay (a-martih)
// Purpose: Registry Copy Support for REG.CPP
// Modification History:
// Copied from Update.cpp and modificd - April 1997 (a-martih)
// April 1999 Zeyong Xu: re-design, revision -> version 2.0
//
//------------------------------------------------------------------------//
#include "stdafx.h"
#include "reg.h"
//-----------------------------------------------------------------------//
//
// CopyRegistry()
//
//-----------------------------------------------------------------------//
LONG CopyRegistry(PAPPVARS pAppVars, PAPPVARS pDstVars, UINT argc, TCHAR *argv[]) { LONG nResult; HKEY hKey; HKEY hDstKey; DWORD dwDisposition; BOOL bOverWriteAll = FALSE;
//
// Parse the cmd-line
//
nResult = ParseCopyCmdLine(pAppVars, pDstVars, argc, argv); if (nResult != ERROR_SUCCESS) { return nResult; }
//
// Connect to the Remote Machine(s) - if applicable
//
nResult = RegConnectMachine(pAppVars); if (nResult != ERROR_SUCCESS) { return nResult; } nResult = RegConnectMachine(pDstVars); if (nResult != ERROR_SUCCESS) { return nResult; }
//
// Now implement the body of the Copy Operation
//
nResult = RegOpenKeyEx(pAppVars->hRootKey, pAppVars->szSubKey, 0, KEY_READ, &hKey); if (nResult != ERROR_SUCCESS) { return nResult; }
if (pAppVars->hRootKey == pDstVars->hRootKey && _tcsicmp(pAppVars->szFullKey, pDstVars->szFullKey) == 0) { RegCloseKey(hKey); return REG_STATUS_COPYTOSELF; } else { //
// Different Key or Different Root or Different Machine
// So Create/Open it
//
nResult = RegCreateKeyEx(pDstVars->hRootKey, pDstVars->szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hDstKey, &dwDisposition);
if (nResult != ERROR_SUCCESS) { RegCloseKey(hKey); return nResult; } }
//
// Recursively copy all subkeys and values
//
bOverWriteAll = pAppVars->bForce; nResult = CopyEnumerateKey(hKey, pAppVars->szSubKey, hDstKey, pDstVars->szSubKey, &bOverWriteAll, pAppVars->bRecurseSubKeys);
//
// lets clean up
//
RegCloseKey(hDstKey); RegCloseKey(hKey);
return nResult; }
REG_STATUS ParseCopyCmdLine(PAPPVARS pAppVars, PAPPVARS pDstVars, UINT argc, TCHAR *argv[]) { UINT i; REG_STATUS nResult = ERROR_SUCCESS;
//
// Do we have a *valid* number of cmd-line params
//
if(argc < 4) { return REG_STATUS_TOFEWPARAMS; } else if(argc > 6) { return REG_STATUS_TOMANYPARAMS; }
//
// Source Machine Name and Registry key
//
nResult = BreakDownKeyString(argv[2], pAppVars); if(nResult != ERROR_SUCCESS) return nResult;
//
// Destination Machine Name and Registry key
//
nResult = BreakDownKeyString(argv[3], pDstVars); if(nResult != ERROR_SUCCESS) return nResult;
// parsing
for(i=4; i<argc; i++) { if(!_tcsicmp(argv[i], _T("/f"))) { pAppVars->bForce = TRUE; } else if(!_tcsicmp(argv[i], _T("/s"))) { pAppVars->bRecurseSubKeys = TRUE; } else { nResult = REG_STATUS_INVALIDPARAMS; } }
return nResult; }
//-----------------------------------------------------------------------//
//
// QueryValue()
//
//-----------------------------------------------------------------------//
LONG CopyValue(HKEY hKey, TCHAR* szValueName, HKEY hDstKey, TCHAR* szDstValueName, BOOL *pbOverWriteAll) {
LONG nResult; DWORD dwType, dwTmpType; DWORD dwSize, dwTmpSize; BYTE *pBuff; TCHAR ch; PTSTR PromptBuffer,PromptBufferFmt; DWORD PromptBufferSize;
//
// First find out how much memory to allocate.
//
nResult = RegQueryValueEx(hKey, szValueName, 0, &dwType, NULL, &dwSize);
if (nResult != ERROR_SUCCESS) { return nResult; }
pBuff = (BYTE*) calloc(dwSize + 1, sizeof(BYTE)); if (!pBuff) return ERROR_NOT_ENOUGH_MEMORY;
//
// Now get the data
//
nResult = RegQueryValueEx(hKey, szValueName, 0, &dwType, (LPBYTE) pBuff, &dwSize);
if (nResult != ERROR_SUCCESS) { return nResult; }
//
// Copy it to the destination
//
if (!*pbOverWriteAll) { //
// See if it already exists
//
nResult = RegQueryValueEx(hDstKey, szDstValueName, 0, &dwTmpType, NULL, &dwTmpSize); if (nResult == ERROR_SUCCESS) { BOOL bGoodResponse = FALSE;
//
// allocate and fill in the prompt message
//
PromptBufferSize = 100; PromptBufferSize += _tcslen( szDstValueName ? szDstValueName : g_NoName); PromptBuffer = calloc(PromptBufferSize, sizeof(TCHAR)); if (!PromptBuffer) { return ERROR_SUCCESS; } PromptBufferFmt = calloc(PromptBufferSize, sizeof(TCHAR)); if (!PromptBufferFmt) { free(PromptBuffer); return ERROR_SUCCESS; } LoadString( NULL, IDS_OVERWRITE, PromptBufferFmt, PromptBufferSize); wsprintf( PromptBuffer, PromptBufferFmt, szDstValueName ? szDstValueName : g_NoName ); free( PromptBufferFmt);
while (!bGoodResponse) { MyTPrintf(stdout,PromptBuffer); ch = _gettchar(); _flushall(); switch (ch) { case _T('a'): //fall through
case _T('y'): //fall through
case _T('n'): bGoodResponse = TRUE; break; default: //
// keep scanning.
//
; } }
free(PromptBuffer); MyTPrintf(stdout,_T("\r\n"));
if (ch == _T('a') || ch == _T('A')) { *pbOverWriteAll = TRUE; bGoodResponse = TRUE; } else if (ch == _T('y') || ch == _T('Y')) { bGoodResponse = TRUE; } else if (ch == _T('n') || ch == _T('N')) { return ERROR_SUCCESS; } } }
//
// Write the Value
//
nResult = RegSetValueEx(hDstKey, szDstValueName, 0, dwType, (PBYTE) pBuff, dwSize);
if(pBuff) free(pBuff);
return nResult; }
//-----------------------------------------------------------------------//
//
// EnumerateKey() - Recursive
//
//-----------------------------------------------------------------------//
LONG CopyEnumerateKey(HKEY hKey, TCHAR* szSubKey, HKEY hDstKey, TCHAR* szDstSubKey, BOOL *pbOverWriteAll, BOOL bRecurseSubKeys) {
DWORD nResult; UINT i; DWORD dwSize; DWORD dwDisposition; HKEY hSubKey; HKEY hDstSubKey; TCHAR* szNameBuf; TCHAR* szTempName; TCHAR* szDstTempName;
// query source key info
DWORD dwLenOfKeyName; DWORD dwLenOfValueName; nResult = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, &dwLenOfKeyName, NULL, NULL, &dwLenOfValueName, NULL, NULL, NULL);
if (nResult != ERROR_SUCCESS) { return nResult; }
#ifndef REG_FOR_WIN2000 // ansi version for win98
// fix API bugs: RegQueryInfoKey() returns non-correct length values
// on remote Win98
if(dwLenOfKeyName < MAX_PATH) dwLenOfKeyName = MAX_PATH; if(dwLenOfValueName < MAX_PATH) dwLenOfValueName = MAX_PATH; #endif
//
// First enumerate all of the values
//
dwLenOfValueName++; szNameBuf = (TCHAR*) calloc(dwLenOfValueName, sizeof(TCHAR)); if (!szNameBuf) { return ERROR_NOT_ENOUGH_MEMORY; } i = 0; do { dwSize = dwLenOfValueName; nResult = RegEnumValue(hKey, i, szNameBuf, &dwSize, NULL, NULL, NULL, NULL);
if (nResult == ERROR_SUCCESS) { nResult = CopyValue(hKey, szNameBuf, hDstKey, szNameBuf, pbOverWriteAll); }
i++;
} while (nResult == ERROR_SUCCESS);
if(szNameBuf) free(szNameBuf);
if (nResult == ERROR_NO_MORE_ITEMS) nResult = ERROR_SUCCESS;
if( !bRecurseSubKeys || nResult != ERROR_SUCCESS ) return nResult;
//
// Now Enumerate all of the keys
//
dwLenOfKeyName++; szNameBuf = (TCHAR*) calloc(dwLenOfKeyName, sizeof(TCHAR)); if (!szNameBuf) { return ERROR_NOT_ENOUGH_MEMORY; } i = 0; do { dwSize = dwLenOfKeyName; nResult = RegEnumKeyEx(hKey, i, szNameBuf, &dwSize, NULL, NULL, NULL, NULL);
//
// Else open up the subkey, create the destination key
// and enumerate it
//
if (nResult == ERROR_SUCCESS) { nResult = RegOpenKeyEx(hKey, szNameBuf, 0, KEY_READ, &hSubKey); }
if (nResult == ERROR_SUCCESS) { nResult = RegCreateKeyEx(hDstKey, szNameBuf, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hDstSubKey, &dwDisposition);
if (nResult == ERROR_SUCCESS) { //
// Build up the needed string and go to town enumerating again
//
szTempName = (TCHAR*) calloc(_tcslen(szSubKey) + _tcslen(szNameBuf) + 3, sizeof(TCHAR)); if (!szTempName) { nResult = ERROR_NOT_ENOUGH_MEMORY; goto Cleanup; }
if(_tcslen(szSubKey) > 0) { _tcscpy(szTempName, szSubKey); _tcscat(szTempName, _T("\\")); } _tcscat(szTempName, szNameBuf);
szDstTempName = (TCHAR*) calloc(_tcslen(szDstSubKey) + _tcslen(szNameBuf) + 3, sizeof(TCHAR));
if (!szDstTempName) { free (szTempName); nResult = ERROR_NOT_ENOUGH_MEMORY; goto Cleanup; }
if(_tcslen(szDstSubKey) > 0) { _tcscpy(szDstTempName, szDstSubKey); _tcscat(szDstTempName, _T("\\")); } _tcscat(szDstTempName, szNameBuf);
// recursive copy
nResult = CopyEnumerateKey(hSubKey, szTempName, hDstSubKey, szDstTempName, pbOverWriteAll, bRecurseSubKeys);
RegCloseKey(hSubKey); RegCloseKey(hDstSubKey);
if(szTempName) free(szTempName); if(szDstTempName) free(szDstTempName); } }
i++;
} while (nResult == ERROR_SUCCESS);
Cleanup: if(szNameBuf) free(szNameBuf);
if (nResult == ERROR_NO_MORE_ITEMS) nResult = ERROR_SUCCESS;
return nResult; }
|