/********************************************************************
created: 2001/11/07
created: 7:11:2001 12:50
filename: d:\My Projects\Own\Add-on\ToDoCached\regRegistryEx.cpp
file path: d:\My Projects\Own\Add-on\ToDoCached
file base: regRegistryEx
file ext: cpp
author: Alex Kucherenko
purpose:
*********************************************************************/
#include "stdafx.h"
#include "regRegistryEx.h"
#ifdef _DEBUG
# undef THIS_FILE
static char THIS_FILE[]=__FILE__;
# define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////////
// constructor
CRegistryEx::CRegistryEx( const HKEY hKey, const string &startPoint )
: m_hInitKey( hKey )
, m_strInitPoint( startPoint )
{
};
/////////////////////////////////////////////////////////////////////////
// destructor
CRegistryEx::~CRegistryEx()
{
RefreshRegistry();
m_mapValues.clear();
Close();
};
/////////////////////////////////////////////////////////////////////////
// function read all values from registry
void CRegistryEx::RefreshContents( void ) throw( string )
{
// set default values into registryu class cache
SetDefaults();
LONG status = Open( m_hInitKey, m_strInitPoint.c_str() );
if( status != ERROR_SUCCESS )
RefreshRegistry();
else
{
char buffer[ MAX_STRING_LENGTH ];
BYTE databuf[ MAX_STRING_LENGTH ];
DWORD dwIndex = 0;
DWORD dwType = 0;
DWORD dwSize = sizeof( buffer );
DWORD dwDatSize = sizeof( databuf );
// Enum All subkeys
do
{
status = ::RegEnumKeyEx( m_hKey, dwIndex, buffer, &dwSize, NULL, NULL, NULL, NULL );
if( status != ERROR_SUCCESS ) break;
m_qSubKeys.push( strlwr( buffer ) );
dwSize = sizeof( buffer );
dwIndex++;
} while( 1 );
// Enum All Values in subkeys
dwIndex = 0;
dwSize = sizeof( buffer );
string subKey;
string varName, varData;
do
{
status = ::RegEnumValue( m_hKey, dwIndex, buffer, &dwSize, NULL, &dwType, databuf, &dwDatSize );
dwSize = sizeof( buffer );
dwDatSize = sizeof( databuf );
if( status != ERROR_SUCCESS )
{
if( m_qSubKeys.empty() ) break;
subKey = m_strInitPoint + "\\" + m_qSubKeys.front();
Close();
status = Open( m_hInitKey, subKey.c_str() );
if( status != ERROR_SUCCESS ) break;
subKey = m_qSubKeys.front();
m_qSubKeys.pop();
dwIndex = 0;
continue;
};
varName = subKey + "\\" + strlwr( buffer );
if( dwType == REG_SZ ) varData = (char *)databuf;
else continue;
m_mapValues[ varName ] = varData;
dwIndex++;
} while( 1 );
Close();
Open( m_hInitKey, m_strInitPoint.c_str( ) );
}
};
/////////////////////////////////////////////////////////////////////////
// Function set value to registry
void CRegistryEx::RefreshRegistry( void ) throw( string )
{
LONG state = Create( m_hInitKey, m_strInitPoint.c_str() );
if( state != ERROR_SUCCESS ) throw string( "Error! Cannot create registry key!" );
TRegIter i;
std::stack<string> stSubKeys;
string temp, subKey;
stSubKeys.push( "::" );
for( i = m_mapValues.begin(); i != m_mapValues.end(); i++ )
{
string first = i->first;
string::size_type pos = first.find( "\\" );
if( pos != first.npos )
{
temp = first.substr( 0, pos );
if( temp.empty() || temp == stSubKeys.top() )
{
if( !temp.empty() ) stSubKeys.push( temp );
subKey = first.substr( pos+1 );
SetValue( i->second.c_str( ), subKey.c_str( ) );
}
else
{
Close();
subKey = m_strInitPoint + "\\" + temp;
stSubKeys.push( temp );
state = Create( m_hInitKey, subKey.c_str( ) );
if( state != ERROR_SUCCESS ) throw string( "Error! Cannot create registry key!" );
subKey = first.substr( pos+1 );
SetValue( i->second.c_str( ), subKey.c_str( ) );
}
}
}
Close();
Open( m_hInitKey, m_strInitPoint.c_str( ) );
};
/////////////////////////////////////////////////////////////////////////
// function return value by param name
LONG CRegistryEx::GetValueByName(IN const string &name,OUT string &result)
{
result = m_mapValues[ CorrentRegistryPath( name ) ];
return 0;
}
//////////////////////////////////////////////////////////////////////////
// function return pointer to value string
LONG CRegistryEx::GetValueByName(IN const char *czName,OUT char *czResult)
{
czResult = const_cast<char *>( m_mapValues[ CorrentRegistryPath( string( czName ) ) ].c_str() );
return 0;
}
//////////////////////////////////////////////////////////////////////////
// function set output value to lResult
LONG CRegistryEx::GetValueByName(IN const string &name,OUT long &lResult)
{
lResult = atol( m_mapValues[ CorrentRegistryPath( name ) ].c_str() );
return 0;
}
//////////////////////////////////////////////////////////////////////////
// function set output value to lResult
LONG CRegistryEx::GetValueByName(IN const char *czName,OUT long &lResult)
{
lResult = atol( m_mapValues[ CorrentRegistryPath( string( czName ) ) ].c_str() );
return 0;
}
/////////////////////////////////////////////////////////////////////////
// Set value in registry
void CRegistryEx::SetValueByName(IN const string &name,IN const string &value)
{
m_mapValues[ CorrentRegistryPath( name ) ] = value;
}
//////////////////////////////////////////////////////////////////////////
// Set value in registry
void CRegistryEx::SetValueByName(IN const char *czName,IN const char *czValue)
{
m_mapValues[ CorrentRegistryPath( string( czName ) ) ] = czValue;
}
//////////////////////////////////////////////////////////////////////////
// Set value in registry
void CRegistryEx::SetValueByName(IN const string &name,IN long lValue)
{
char buffer[ 32 ];
ltoa( lValue, buffer, 10 );
m_mapValues[ CorrentRegistryPath( name ) ] = buffer;
}
//////////////////////////////////////////////////////////////////////////
// Set value in registry
void CRegistryEx::SetValueByName(IN const char *czName,IN long lValue)
{
char buffer[ 32 ];
ltoa( lValue, buffer, 10 );
m_mapValues[ CorrentRegistryPath( string( czName ) ) ] = buffer;
}
/////////////////////////////////////////////////////////////////////////
// function return array of registry values according to input template
LONG CRegistryEx::GetArrayByTemplate(IN const string &templ,OUT TStrArray &arrResult)
{
return GetArrayByTemplate( templ.c_str(), arrResult );
}
//////////////////////////////////////////////////////////////////////////
// Function return values according to input template
LONG CRegistryEx::GetArrayByTemplate(IN const char *czTempl,OUT TStrArray &arrResult)
{
TRegIter i;
DWORD dwValue = 0;
for( i = m_mapValues.begin(); i != m_mapValues.end(); i++ )
{
int ret = sscanf( i->first.c_str( ), czTempl, &dwValue );
if( ret == 1 ) arrResult.push_back( i->second );
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
// Return array of values according to input array of registry pathes
LONG CRegistryEx::GetArrayByArray(IN const TStrArray &arrNames,OUT TStrArray &arrResult)
{
for( UINT i=0; i<arrNames.size( ); i++ )
arrResult.push_back( m_mapValues[ CorrentRegistryPath( arrNames[i] ) ] );
return 0;
}
/////////////////////////////////////////////////////////////////////////
// set values of regitry pathes according to template
void CRegistryEx::SetValueByTemplate( const string &templ, const TStrArray &arrValue )
{
char buffer[ MAX_STRING_LENGTH ];
for( UINT k=0; k<arrValue.size(); k++ )
{
_snprintf( buffer, sizeof(buffer), templ.c_str(), k+1 );
m_mapValues[ CorrentRegistryPath( string( buffer ) ) ] = arrValue[ k ];
}
};
//////////////////////////////////////////////////////////////////////////
// Function set default values to params of registry
void CRegistryEx::SetDefaults( void )
{
/* E_NOTIMPL - empty function */
}
/////////////////////////////////////////////////////////////////////////
// Function set multiple params to new values
void CRegistryEx::SetArrayByArray( const TStrArray &arrNames, const TStrArray &arrValues ) throw( string )
{
if( arrNames.size() != arrValues.size() )
throw string( "Size of values and params arrays not equel" );
for( UINT i = 0; i<arrNames.size( ); i++ )
m_mapValues[ CorrentRegistryPath( arrNames[ i ] ) ] = arrValues[ i ];
};
//////////////////////////////////////////////////////////////////////////
// Delete param from registry
void CRegistryEx::DeleteByName( const string &name )
{
TRegIter i = m_mapValues.find( name );
if( i != m_mapValues.end() )
{
m_mapValues.erase( i );
string::size_type pos = name.find( "\\" );
string newPoint = m_strInitPoint + "\\" + name.substr( 0, pos );
Close();
LONG lRes = Open( m_hInitKey, newPoint.c_str() );
if( lRes == ERROR_SUCCESS )
DeleteValue( name.substr( pos+1 ).c_str( ) );
}
};
//////////////////////////////////////////////////////////////////////////
// Delete values from registry according to template
void CRegistryEx::DeleteByTemplate( const string &templ )
{
TStrArray temp;
GetNamesByTemplate( templ, temp );
DeleteByArray( temp );
};
//////////////////////////////////////////////////////////////////////////
// Delete values from registry according to array of registry pathes
void CRegistryEx::DeleteByArray( const TStrArray &array )
{
TStrArray::const_iterator j;
for( j = array.begin(); j != array.end(); j++ )
DeleteByName( *j );
};
//////////////////////////////////////////////////////////////////////////
// Function return array of registry names according to template
LONG CRegistryEx::GetNamesByTemplate(IN const string &templ,OUT TStrArray &arrResult)
{
return GetNamesByTemplate( templ.c_str(), arrResult );
}
//////////////////////////////////////////////////////////////////////////
// Function return array of registry names according to template
LONG CRegistryEx::GetNamesByTemplate(IN const char *czTempl,OUT TStrArray &arrResult)
{
DWORD dwValue = 0;
for( TRegIter i = m_mapValues.begin(); i != m_mapValues.end(); i++ )
{
int ret = sscanf( i->first.c_str( ), czTempl, &dwValue );
if( ret == 1 ) arrResult.push_back( i->first );
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
// Function set registry key/values according to template and input array
// of values.
void CRegistryEx::SetValueByTemplate( IN const char *czTempl, IN const TStrArray &arrValue )
{
string temp = czTempl;
SetValueByTemplate( temp, arrValue );
};
//////////////////////////////////////////////////////////////////////////
// Delete value from registry
void CRegistryEx::DeleteByName( IN const char *czName )
{
string temp = czName;
DeleteByName( temp );
};
//////////////////////////////////////////////////////////////////////////
// Try to resolve variable path before using it
string &CRegistryEx::CorrentRegistryPath( IN const string &path )
{
m_strTmpPath = path;
TRegMap::iterator iter = m_mapValues.find( path );
if( iter == m_mapValues.end() )
{
iter = m_mapValues.find( "\\" + m_strTmpPath );
if( iter != m_mapValues.end() )
m_strTmpPath = "\\" + path;
else
if( m_strTmpPath.find( "\\" ) == string::npos )
m_strTmpPath = "\\" + path;
}
return m_strTmpPath;
}
//:> end of file