Click here to Skip to main content
15,895,799 members
Articles / Desktop Programming / MFC

Adding high score capability to MS Solitaire

Rate me:
Please Sign up or sign in to vote.
4.70/5 (16 votes)
25 Jul 2007CPOL14 min read 44.1K   713   18  
An application that manages MS Solitaire high scores by reading and writing Solitaire memory
// AESEncRegKey.cpp : implementation file
//

#include "stdafx.h"
#include "AESEncRegKey.h"

// Crypto++ Includes
#pragma warning(push, 3)
#  include "modes.h"
#  include "aes.h"
#  include "filters.h"
#pragma warning(pop)

// Crypto++ Library
#ifdef _DEBUG
#  pragma comment ( lib, "cryptlibd" )
#else
#  pragma comment ( lib, "cryptlib" )
#endif

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAESEncRegKey

CAESEncRegKey::CAESEncRegKey() : _hKey( NULL )
{
    CString szCompanyName = AfxGetAppName();

    CString szSubKey = _T("Software\\") + szCompanyName;

    SetSubKey( szSubKey );
}

CAESEncRegKey::CAESEncRegKey(const BYTE* cbKey, UINT nKeyLength, const BYTE* cbIV, UINT nIVLength) : _hKey( NULL )
{
    ASSERT( NULL != cbKey );
    ASSERT( NULL != cbIV );

    SetHKEY( NULL );

    SetKey( cbKey, nKeyLength );

    SetIV( cbIV, nIVLength );
}

CAESEncRegKey::CAESEncRegKey(HKEY hKey, LPCTSTR pszSubKey, LPCTSTR pszValueName)
{
    SetHKEY( hKey );

    SetSubKey( pszSubKey );

    SetValueName( pszValueName );
}

CAESEncRegKey::~CAESEncRegKey() { }

const BYTE* CAESEncRegKey::GetKey() const
{
    return _EncKey._cbKey;
}

const BYTE* CAESEncRegKey::GetIV() const
{
    return _EncIV._cbIV;
}

UINT CAESEncRegKey::GetIVLength() const
{
    return CryptoPP::AES::BLOCKSIZE;
}

UINT CAESEncRegKey::GetKeyLength() const
{
    return CryptoPP::AES::DEFAULT_KEYLENGTH;
}

const CString& CAESEncRegKey::GetSubKey() const
{
    return _szSubKey;
}

const CString& CAESEncRegKey::GetValueName() const
{
    return _szValueName;
}

BOOL CAESEncRegKey::SetHKEY(HKEY hKey) 
{
    _hKey = hKey;

    return TRUE;
}

BOOL CAESEncRegKey::DeleteKey(const CString& szSubKey)
{
	long lResult = RegDeleteKey(_hKey, szSubKey);
	return (ERROR_SUCCESS == lResult);
}

BOOL CAESEncRegKey::DeleteValue(const CString& szSubKey, const CString& szValue)
{
	HKEY hKey    = NULL;
	long lResult = RegOpenKeyEx(_hKey, szSubKey, 0, KEY_ALL_ACCESS, &hKey);
	if( ERROR_SUCCESS == lResult)
	{
		lResult = RegDeleteValue(hKey, szValue);
		RegCloseKey(hKey);
	}
	return (ERROR_SUCCESS == lResult);
}

BOOL CAESEncRegKey::SetSubKey(LPCTSTR pszSubKey)
{
    BOOL bResult = FALSE;

    ASSERT( NULL != pszSubKey );

    if( NULL != pszSubKey ) {

        CString szTemp = pszSubKey;

        // Strip leading slashes. Windows 9x can deal with them,
        //   but Windows NT/2000 cannot
        while( 0 < szTemp.GetLength() && _T('\\') == szTemp.Left( 1 ) ) {

            szTemp = szTemp.Right( szTemp.GetLength() - 1 );
        }
    
        _szSubKey = szTemp;

        bResult = TRUE;

        ::OutputDebugString( _T("_szSubKey set to ") );
        ::OutputDebugString( _szSubKey );
        ::OutputDebugString( _T("\n") );
    }

    return bResult;
}

BOOL CAESEncRegKey::SetValueName(LPCTSTR pszValueName)
{
    BOOL bResult = FALSE;

    ASSERT( NULL != pszValueName );

    if( NULL != pszValueName ) {
    
        _szValueName = pszValueName;

        bResult = TRUE;

        ::OutputDebugString( _T("_szValueName set to ") );
        ::OutputDebugString( _szValueName );
        ::OutputDebugString( _T("\n") );
    }

    return bResult;
}

BOOL CAESEncRegKey::SetIV(const BYTE *cbIV, UINT nLength)
{
    BOOL bResult = FALSE;

    ASSERT( CryptoPP::AES::BLOCKSIZE == nLength );
    ASSERT( NULL != cbIV );

    if( CryptoPP::AES::BLOCKSIZE == nLength && NULL != cbIV ) {
    
        _EncIV = cbIV;

        bResult = TRUE;
    }

    return bResult;
}

BOOL CAESEncRegKey::SetKey(const BYTE *cbKey, UINT nLength)
{
    BOOL bResult = FALSE;

    ASSERT( CryptoPP::AES::DEFAULT_KEYLENGTH == nLength );
    ASSERT( NULL != cbKey );

    if( CryptoPP::AES::DEFAULT_KEYLENGTH == nLength && NULL != cbKey ) {
    
        _EncKey = cbKey;

        bResult = TRUE;
    }

    return bResult;
}


LONG CAESEncRegKey::WriteString(LPCTSTR pszData, BOOL bEncrypt /*=FALSE*/) const
{
    LONG lResult = ERROR_SUCCESS;

    if( TRUE == bEncrypt ) {

        lResult = WriteEncString( pszData );

    } else {

        lResult = WriteNonEncString( pszData );
    }

    return lResult;
}

LONG CAESEncRegKey::WriteDWORD(DWORD dwValue, BOOL bEncrypt /*=FALSE*/) const
{
    LONG lResult = ERROR_SUCCESS;

    if( TRUE == bEncrypt ) {

        lResult = WriteEncDWORD( dwValue );

    } else {

        lResult = WriteNonEncDWORD( dwValue );
    }

    return lResult;
}

LONG CAESEncRegKey::WriteBinary(const BYTE *pcbData, UINT nSize, BOOL bEncrypt /*= FALSE*/) const
{
    LONG lResult = ERROR_SUCCESS;

    if( TRUE == bEncrypt ) {

        lResult = WriteEncBinary( pcbData, nSize );

    } else {

        lResult = WriteNonEncBinary( pcbData, nSize );
    }

    return lResult;
}

LONG CAESEncRegKey::WriteNonEncString(LPCTSTR pszData) const
{
    LONG lResult = ERROR_SUCCESS;

    lResult = WriteData( reinterpret_cast<const BYTE*>( pszData ),
                       ( ::lstrlen( pszData ) + 1 ) * sizeof( TCHAR ),
                       REG_SZ );

    return lResult;
}

LONG CAESEncRegKey::WriteNonEncDWORD(DWORD dwData) const
{
    LONG lResult = ERROR_SUCCESS;

    lResult = WriteData( reinterpret_cast<const BYTE*>( &dwData ),
                         sizeof( DWORD ), REG_DWORD );

    return lResult;
}


LONG CAESEncRegKey::WriteEncDWORD(DWORD dwData) const
{
    LONG lResult = ERROR_SUCCESS;

    // Returned from EncryptData()
    BYTE* pcbEncryptedData = NULL;
    DWORD dwEncryptedSize = 0;

    //
    // Anti-snoop it...
    lResult = EncryptData( reinterpret_cast<const BYTE*>(&dwData), sizeof( DWORD ), 
                           &pcbEncryptedData, &dwEncryptedSize );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Save it...
    lResult = WriteNonEncBinary( pcbEncryptedData, dwEncryptedSize );

FINISHED:

    //
    // Cleanup...
    if( NULL != pcbEncryptedData ) { delete[] pcbEncryptedData; }

    return lResult;
}

LONG CAESEncRegKey::WriteEncString(LPCTSTR pszData) const
{
    LONG lResult = ERROR_SUCCESS;

    // Returned from EncryptData()
    BYTE* pcbEncryptedData = NULL;
    DWORD dwEncryptedSize = 0;

    //
    // Anti-snoop it...
    lResult = EncryptData( reinterpret_cast<const BYTE*>(pszData),
                           ( ::lstrlen( pszData ) + 1 ) * sizeof( TCHAR ),
                           &pcbEncryptedData, &dwEncryptedSize );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Save it...
    lResult = WriteNonEncBinary( pcbEncryptedData, dwEncryptedSize );

FINISHED:

    //
    // Cleanup...
    if( NULL != pcbEncryptedData ) { delete[] pcbEncryptedData; }

    return lResult;
}

LONG CAESEncRegKey::WriteEncBinary(const BYTE *pcbData, UINT nSize) const
{
    LONG lResult = ERROR_SUCCESS;

    // Returned from EncryptData()
    BYTE* pcbEncryptedData = NULL;
    DWORD dwEncryptedSize = 0;

    //
    // Anti-snoop it...
    lResult = EncryptData( pcbData, nSize, &pcbEncryptedData, &dwEncryptedSize );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Persit it...
    lResult = WriteNonEncBinary( pcbEncryptedData, dwEncryptedSize );

FINISHED:

    //
    // Cleanup...
    if( NULL != pcbEncryptedData ) { delete[] pcbEncryptedData; }

    return lResult;
}

LONG CAESEncRegKey::WriteNonEncBinary(const BYTE *pcbData, UINT nSize) const
{
    LONG lResult = ERROR_SUCCESS;

    lResult = WriteData( pcbData, nSize, REG_BINARY );

    return lResult;
}

LONG CAESEncRegKey::ReadDWORD(DWORD &dwValue, BOOL bEncrypted) const
{
    LONG lResult = ERROR_SUCCESS;

    if( TRUE == bEncrypted ) {

        lResult = ReadEncDWORD( dwValue );

    } else {

        lResult = ReadNonEncDWORD( dwValue );
    }

    return lResult;
}

LONG CAESEncRegKey::ReadString(CString &szValue, BOOL bEncrypted /*=FALSE*/) const
{
    LONG lResult = ERROR_SUCCESS;

    if( TRUE == bEncrypted ) {

        lResult = ReadEncString( szValue );

    } else {

        lResult = ReadNonEncString( szValue );
    }

    return lResult;
}

LONG CAESEncRegKey::ReadString(LPTSTR pszValue, DWORD *dwCharCount, BOOL bEncrypted /*=FALSE*/) const
{
    LONG    lResult = ERROR_SUCCESS;
    CString szTemp;
    DWORD   dwRequiredSize = 0;     // In TCHARs, not BYTEs

    //
    // Emulate the RegQueryValue(...) Function
    //   See http://msdn.microsoft.com/library/default.asp?
    //       url=/library/en-us/sysinfo/base/regqueryvalueex.asp
    //   It appears Caller is asking for dwType
    if( NULL == pszValue && NULL == dwCharCount ) {     
        lResult = ERROR_SUCCESS;
        goto FINISHED;
    }

    if( TRUE == bEncrypted ) {

        lResult = ReadEncString( szTemp );

    } else {

        lResult = ReadNonEncString( szTemp );
    }

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // '+ 1' to catch the trailing '\0'
    dwRequiredSize = szTemp.GetLength() + 1;

    //
    // Emulate the RegQueryValue(...) Function
    //   See http://msdn.microsoft.com/library/default.asp?
    //       url=/library/en-us/sysinfo/base/regqueryvalueex.asp
    //   It appears Caller is asking for size of pszValue
    if( *dwCharCount < dwRequiredSize && NULL != pszValue ) {

        lResult = ERROR_MORE_DATA;
        *dwCharCount = dwRequiredSize;

        goto FINISHED;
    }

    //
    // Emulate the RegQueryValue(...) Function
    //   See http://msdn.microsoft.com/library/default.asp?
    //       url=/library/en-us/sysinfo/base/regqueryvalueex.asp
    //   Caller is asking for size of pszValue
    if( *dwCharCount < dwRequiredSize && NULL != pszValue ) {

        lResult = ERROR_SUCCESS;
        *dwCharCount = dwRequiredSize;

        goto FINISHED;
    }

    *dwCharCount = dwRequiredSize;

    ::memcpy( pszValue, static_cast<LPCTSTR>( szTemp ), dwRequiredSize * sizeof( TCHAR ) );

FINISHED:

    return lResult;
}

LONG CAESEncRegKey::ReadNonEncString(CString &szValue) const
{
    LONG    lResult = ERROR_SUCCESS;
    HKEY    hKey    = NULL;
    DWORD    dwSize    = 0;
    BYTE*    pcbData = NULL;

    //
    // Open the key - do not create
    lResult = RegOpenKeyEx( _hKey, _szSubKey, 0, KEY_READ, &hKey );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Query for needed buffer size
    lResult = RegQueryValueEx( hKey, _szValueName, 0, NULL, NULL, &dwSize );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Add '+ sizeof(TCHAR)' in case the string is not
    //   stored in the registry with a trailing '\0'
    pcbData = new BYTE[ dwSize + sizeof(TCHAR) ];

    //
    // Sanity Check
    if( NULL == pcbData ) {        
        lResult = ERROR_NOT_ENOUGH_MEMORY;
        goto FINISHED;
    }

    //
    // Add the trailing '\0', taking into account UNICODEness
    reinterpret_cast<TCHAR*>(pcbData)[ dwSize/sizeof(TCHAR) - 1 ] = _T('\0'); 

    //
    // Query for the actual value
    lResult = RegQueryValueEx( hKey, _szValueName, 0, NULL, pcbData, &dwSize );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Paydirt...
    szValue = reinterpret_cast<TCHAR*>(pcbData);

FINISHED:

    //
    // Cleanup...
    if( NULL != hKey ) { RegCloseKey( hKey ); }

    if( NULL != pcbData ) { delete[] pcbData; }

    return lResult;
}

LONG CAESEncRegKey::ReadEncString(CString &szValue) const
{
    LONG lResult = ERROR_SUCCESS;

    // Returned from the Registry
    DWORD    dwSize    = 0;
    BYTE*    pcbData = NULL;

    // Returned from DecryptData(...)
    DWORD    dwDecryptedSize     = 0;
    BYTE*   pcbDecryptedData = NULL;
  
    // Read From the Registry
    lResult = ReadData( &pcbData, &dwSize );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Undo it...
    lResult = DecryptData( pcbData, dwSize, &pcbDecryptedData, &dwDecryptedSize );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Paydirt...
    szValue = reinterpret_cast<const TCHAR*>( pcbDecryptedData );

FINISHED:

    //
    // Cleanup...
    if( NULL != pcbData ) { delete[] pcbData; }

    if( NULL != pcbDecryptedData ) { delete[] pcbDecryptedData; }

    return lResult;
}

////////////////////////////////
//
// EncryptData
//
LONG CAESEncRegKey::EncryptData(const BYTE *pcbPlainText, DWORD dwPlainTextSize, BYTE **pcbEncryptedData, DWORD *pdwEncryptedSize) const
{
    LONG lResult = ERROR_SUCCESS;

    ASSERT( NULL != pcbPlainText );
    ASSERT( NULL != pcbEncryptedData );
    ASSERT( NULL != pdwEncryptedSize );

    if( NULL == pcbEncryptedData || NULL == pdwEncryptedSize ) {

        lResult = ERROR_INVALID_PARAMETER;
    }

    try {

        CryptoPP::AES::Encryption aesEncryption( _EncKey._cbKey, CryptoPP::AES::DEFAULT_KEYLENGTH);
        CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, _EncIV._cbIV );

        std::string cipher;

        CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink( cipher ) );
        stfEncryptor.Put( reinterpret_cast<const BYTE*>( pcbPlainText ), dwPlainTextSize );
        stfEncryptor.MessageEnd();

        if( ERROR_SUCCESS == lResult ) {
        
            *pdwEncryptedSize = (DWORD)cipher.size();
        
            *pcbEncryptedData = new BYTE[ *pdwEncryptedSize ];

        
            ::memcpy( *pcbEncryptedData, reinterpret_cast<const BYTE*>( cipher.data() ), *pdwEncryptedSize );
        }

    } catch( CryptoPP::Exception& e ) {

        ::OutputDebugString( _T("Caught Crypto++ exception: '") );
        ::OutputDebugStringA( e.what() );
        ::OutputDebugString( _T("'\n") );

        lResult = ERROR_INVALID_DATA;
    
    } catch( ... ) {

        ::OutputDebugString( _T("Caught other exception.") );

        lResult = ERROR_INVALID_DATA;
    }

    return lResult;
}

////////////////////////////////
//
// DecryptData
//
LONG CAESEncRegKey::DecryptData(const BYTE *pcbEncryptedData, DWORD dwEncryptedSize, BYTE **pcbDecryptedData, DWORD *pdwDecryptedSize) const
{
    LONG lResult = ERROR_SUCCESS;

    *pcbDecryptedData = NULL;
    *pdwDecryptedSize = 0;

    try {

        std::string decrypted;
        CryptoPP::AES::Decryption aesDecryption( _EncKey._cbKey, CryptoPP::AES::DEFAULT_KEYLENGTH);
        CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, _EncIV._cbIV );
        CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink( decrypted ) );

        //
        // Push our blob into the decryptor
        stfDecryptor.Put( pcbEncryptedData, dwEncryptedSize );
        stfDecryptor.MessageEnd();

        *pcbDecryptedData = new BYTE[ decrypted.size() ];

        if( NULL != *pcbDecryptedData ) {

            *pdwDecryptedSize = (DWORD)decrypted.size();

            ::memcpy( *pcbDecryptedData, decrypted.data(), decrypted.size() );
        }
    }

    catch( CryptoPP::Exception& e ) {

        lResult = ERROR_INVALID_DATA;

        ::OutputDebugString( _T("Caught Crypto++ exception: '") );
        ::OutputDebugStringA( e.what() );
        ::OutputDebugString( _T("'\n") );
    }

    catch( ... ) {

        lResult = ERROR_INVALID_DATA;

        ::OutputDebugString( _T("Caught other exception") );
    }

    return lResult;
}

LONG CAESEncRegKey::ReadData(BYTE **pcbData, DWORD *pdwSize) const
{
    LONG    lResult = ERROR_SUCCESS;
    HKEY    hKey    = NULL;

    ASSERT( NULL != pcbData && NULL != pdwSize );

    //
    // Sanity Check
    if( NULL == pcbData || NULL == pdwSize ) {        
        lResult = ERROR_INVALID_PARAMETER;
        goto FINISHED;
    }

    //
    // Open the Key
    lResult = RegOpenKeyEx( _hKey, _szSubKey, 0, KEY_READ, &hKey );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Query for needed buffer size
    lResult = RegQueryValueEx( hKey, _szValueName, 0, NULL, NULL, pdwSize );

    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Allocate a buffer
    *pcbData = new BYTE[ *pdwSize + sizeof(TCHAR) ];

    //
    // Sanity Check
    if( NULL == *pcbData ) {
        
        lResult = ERROR_NOT_ENOUGH_MEMORY;
        goto FINISHED;
    }

    //
    // Query for the actual value
    lResult = RegQueryValueEx( hKey, _szValueName, 0, NULL, *pcbData, pdwSize );

FINISHED:

    if( NULL != hKey ) { RegCloseKey( hKey ); }

    return lResult;
}

LONG CAESEncRegKey::ReadEncDWORD(DWORD &dwValue) const
{
    LONG lResult = ERROR_SUCCESS;

    // Returned from the Registry by way of ReadData(...)
    DWORD    dwSize    = 0;
    BYTE*    pcbData = NULL;

    // Returned from DecryptData(...)
    DWORD    dwDecryptedSize     = 0;
    BYTE*   pcbDecryptedData = NULL;
  
    // Read From the Registry
    lResult = ReadData( &pcbData, &dwSize );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Undo it...
    lResult = DecryptData( pcbData, dwSize, &pcbDecryptedData, &dwDecryptedSize );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Paydirt...
    dwValue = *( reinterpret_cast<DWORD*>( pcbDecryptedData ) );

FINISHED:

    //
    // Cleanup...
    if( NULL != pcbData ) { delete[] pcbData; }

    if( NULL != pcbDecryptedData ) { delete[] pcbDecryptedData; }

    return lResult;
}

LONG CAESEncRegKey::ReadNonEncDWORD(DWORD& dwValue) const
{
    LONG    lResult = ERROR_SUCCESS;
    HKEY    hKey    = NULL;
    DWORD   dwSize  = sizeof( DWORD );

    //
    // Open the HKey
    lResult = RegOpenKeyEx( _hKey, _szSubKey, 0, KEY_READ, &hKey );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Query for the actual value
    lResult = RegQueryValueEx( hKey, _szValueName, 0, NULL, 
                               reinterpret_cast<BYTE*>(&dwValue), &dwSize );

FINISHED:

    //
    // Cleanup...
    if( NULL != hKey ) { RegCloseKey( hKey ); }

    return lResult;
}

LONG CAESEncRegKey::ReadBinary( BYTE* pcbData, DWORD* dwSize, BOOL bEncrypted /*=FALSE*/) const
{
    LONG lResult = ERROR_SUCCESS;

    if( TRUE == bEncrypted ) {

        lResult = ReadEncBinary( pcbData, dwSize );

    } else {

        lResult = ReadNonEncBinary( pcbData, dwSize );
    }

    return lResult;
}

LONG CAESEncRegKey::ReadNonEncBinary(BYTE* pcbData, DWORD* dwSize) const
{
    LONG    lResult = ERROR_SUCCESS;
    HKEY    hKey    = NULL;

    //
    // Open the HKey
    lResult = RegOpenKeyEx( _hKey, _szSubKey, 0, KEY_READ, &hKey );

    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Query for the actual value
    lResult = RegQueryValueEx( hKey, _szValueName, 0, NULL, 
                               reinterpret_cast<BYTE*>(pcbData), dwSize );

FINISHED:

    //
    // Cleanup...
    if( NULL != hKey ) { RegCloseKey( hKey ); }

    return lResult;
}

LONG CAESEncRegKey::ReadEncBinary(BYTE* pcbData, DWORD* dwSize) const
{
    LONG lResult = ERROR_SUCCESS;

    //
    // Returned from ReadData(...)
    DWORD dwRegistrySize  = 0;
    BYTE* pcbRegistryData = NULL;

    //
    // Returned from DecryptData(...)
    DWORD dwDecryptedSize  = 0;
    BYTE* pcbDecryptedData = NULL;
  
    //
    // Read From the Registry
    lResult = ReadData( &pcbRegistryData, &dwRegistrySize );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Just undo it...
    lResult = DecryptData( pcbRegistryData, dwRegistrySize, &pcbDecryptedData, &dwDecryptedSize );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Emulate the RegQueryValueEx(...) Function
    //   See http://msdn.microsoft.com/library/default.asp?
    //       url=/library/en-us/sysinfo/base/regqueryvalueex.asp
    if( *dwSize < dwDecryptedSize && NULL != pcbData ) {

        lResult = ERROR_MORE_DATA;
        *dwSize = dwDecryptedSize;

        goto FINISHED;
    }

    //
    // Emulate the RegQueryValueEx(...) Function
    //   See http://msdn.microsoft.com/library/default.asp?
    //       url=/library/en-us/sysinfo/base/regqueryvalueex.asp
    if( *dwSize < dwDecryptedSize && NULL == pcbData ) {

        lResult = ERROR_SUCCESS;
        *dwSize = dwDecryptedSize;

        goto FINISHED;
    }

    //
    // Inform Caller of size of pcbData
    *dwSize = dwDecryptedSize;

    //
    // Copy the Data out
    ::memcpy( pcbData, pcbDecryptedData, dwDecryptedSize );

    lResult = ERROR_SUCCESS;

FINISHED:

    if( NULL != pcbRegistryData )  { delete[] pcbRegistryData; }

    if( NULL != pcbDecryptedData ) { delete[] pcbDecryptedData; }

    return lResult;
}


LONG CAESEncRegKey::WriteData( const BYTE *pcbData, UINT nSize, DWORD dwType /*=REG_BINARY*/) const
{
    LONG lResult = ERROR_SUCCESS;
    HKEY hKey    = NULL;

    //
    // When writing, create the Key if it does not exist
    lResult = RegCreateKeyEx( _hKey, _szSubKey, 0, NULL,
                              REG_OPTION_NON_VOLATILE,
                              KEY_WRITE, NULL, &hKey, NULL );

    //
    // Sanity Check
    if( ERROR_SUCCESS != lResult ) { goto FINISHED; }

    //
    // Paydirt
    lResult = RegSetValueEx( hKey, _szValueName, 0, dwType, 
                             reinterpret_cast<const BYTE*>( pcbData ), nSize );

FINISHED:

    //
    // Cleanup...
    if( NULL != hKey ) { RegCloseKey( hKey ); }

    return lResult;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Israel Israel
Software designer and programmer.
Programming languages:
MFC, C++, Java , C#, VB and sometimes C and assembly.

Comments and Discussions