diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index 6148e8a960..cb6ba378a0 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -1159,6 +1159,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + diff --git a/stepmania/src/archutils/Win32/RegistryAccess.cpp b/stepmania/src/archutils/Win32/RegistryAccess.cpp new file mode 100644 index 0000000000..cd3411620e --- /dev/null +++ b/stepmania/src/archutils/Win32/RegistryAccess.cpp @@ -0,0 +1,140 @@ +#include "global.h" +#include "RegistryAccess.h" +#include "RageLog.h" +#include "RageUtil.h" + +/* Given "HKEY_LOCAL_MACHINE\hardware\foo", return "hardware\foo", and place + * the HKEY_LOCAL_MACHINE constant in key. */ +static bool GetRegKeyType( const CString &in, CString &out, HKEY &key ) +{ + unsigned backslash = in.find( '\\' ); + if( backslash == in.npos ) + { + LOG->Warn( "Invalid registry key: \"%s\" ", in.c_str() ); + return false; + } + + CString type = in.substr( 0, backslash ); + + if( !type.CompareNoCase( "HKEY_CLASSES_ROOT" ) ) key = HKEY_CLASSES_ROOT; + else if( !type.CompareNoCase( "HKEY_CURRENT_CONFIG" ) ) key = HKEY_CURRENT_CONFIG; + else if( !type.CompareNoCase( "HKEY_CURRENT_USER" ) ) key = HKEY_CURRENT_USER; + else if( !type.CompareNoCase( "HKEY_LOCAL_MACHINE" ) ) key = HKEY_LOCAL_MACHINE; + else if( !type.CompareNoCase( "HKEY_USERS" ) ) key = HKEY_USERS; + else + { + LOG->Warn( "Invalid registry key: \"%s\" ", in.c_str() ); + return false; + } + + out = in.substr( backslash+1 ); + + return true; +} + +/* Given a full key, eg. "HKEY_LOCAL_MACHINE\hardware\foo", open it and return it. + * On error, return NULL. */ +static HKEY OpenRegKey( const CString &key ) +{ + CString subkey; + HKEY type; + if( !GetRegKeyType( key, subkey, type ) ) + return NULL; + + HKEY retkey; + LONG retval = RegOpenKeyEx( type, subkey, 0, KEY_READ, &retkey ); + if ( retval != ERROR_SUCCESS ) + { + LOG->Warn( werr_ssprintf(retval, "RegOpenKeyEx(%i,%s) error", type, subkey.c_str()) ); + return NULL; + } + + return retkey; +} + +bool GetRegValue( const CString &key, const CString &sName, CString &val ) +{ + HKEY hkey = OpenRegKey( key ); + if( hkey == NULL ) + return false; + + char sBuffer[MAX_PATH]; + DWORD nSize = sizeof(sBuffer); + DWORD Type; + LONG ret = RegQueryValueEx( hkey, sName, NULL, &Type, (LPBYTE)sBuffer, &nSize ); + RegCloseKey( hkey ); + if( ret != ERROR_SUCCESS ) + return false; + + /* Actually, CStrings are 8-bit clean, so we can accept any type of data. Remove + * this if that becomes useful. */ + if( Type != REG_SZ && Type != REG_MULTI_SZ && Type != REG_EXPAND_SZ && Type != REG_BINARY ) + return false; /* type mismatch */ + + if( nSize && (Type == REG_SZ || Type == REG_MULTI_SZ || Type == REG_EXPAND_SZ) ) + --nSize; /* remove nul terminator */ + + val = CString( sBuffer, nSize ); + return true; +} + +bool GetRegValue( const CString &key, CString sName, int &val ) +{ + HKEY hkey = OpenRegKey( key ); + if( hkey == NULL ) + return false; + + DWORD value; + DWORD nSize = sizeof(value); + DWORD Type; + LONG ret = RegQueryValueEx( hkey, sName, NULL, &Type, (LPBYTE) &value, &nSize ); + RegCloseKey( hkey ); + if( ret != ERROR_SUCCESS ) + return false; + + if( Type != REG_DWORD ) + return false; /* type mismatch */ + + val = value; + return true; +} + +bool GetRegSubKeys( const CString &key, vector &lst, const CString ®ex, bool bReturnPathToo ) +{ + HKEY hkey = OpenRegKey( key ); + if ( hkey == NULL ) + return false; + + Regex re(regex); + + bool bError = false; + for( int index = 0; ; ++index ) + { + FILETIME ft; + char szBuffer[MAX_PATH]; + DWORD nSize = sizeof(szBuffer); + LONG ret = RegEnumKeyEx( hkey, index, szBuffer, &nSize, NULL, NULL, NULL, &ft); + if( ret == ERROR_NO_MORE_ITEMS ) + break; + + if( ret != ERROR_SUCCESS ) + { + LOG->Warn( werr_ssprintf(ret, "GetRegSubKeys(%p,%i) error", hkey, index) ); + bError = true; + break; + } + + CString str( szBuffer, nSize ); + + if( re.Compare(str) ) + { + if( bReturnPathToo ) + str = key + "\\" + str; + lst.push_back( str ); + } + } + + RegCloseKey( hkey ); + + return !bError; +} diff --git a/stepmania/src/archutils/Win32/RegistryAccess.h b/stepmania/src/archutils/Win32/RegistryAccess.h new file mode 100644 index 0000000000..c3bc97356c --- /dev/null +++ b/stepmania/src/archutils/Win32/RegistryAccess.h @@ -0,0 +1,9 @@ +#ifndef REGISTRY_ACCESS_H +#define REGISTRY_ACCESS_H + +#include "windows.h" +bool GetRegValue( const CString &key, const CString &sName, CString &val ); +bool GetRegValue( const CString &key, CString sName, int &val ); +bool GetRegSubKeys( const CString &key, vector &lst, const CString ®ex = ".*", bool bReturnPathToo = true ); + +#endif