//--------------------------------------------------------------------------- // Copyright (C) 1998, Interscope Ltd. All rights reserved. // Reproduction or distribution of this program, or any portion of it, // is permitted only if this header is kept as it is. // For more information, contact: // // Interscope Ltd., 5 Culturii St., 5th Floor, 4800 Baia Mare, RO // Phone/Fax: +40-62-215023 // E-mail: office@interscope.ro // // $Author: Levente Farkas $ // $Date: 5/12/98 11:50p $ // $Modtime: 4/27/98 6:50a $ // $Revision: 41 $ // $Archive: /Interscope/Thebe/InstallMaster/Registry.cpp $ // $Workfile: Registry.cpp $ //----------------------------------------------------------------------- #include "stdafx.h" //--- Miscellaneous ----------------------------------------------------- const int MAX_REG_MACHINE_NAME_LEN = 50; //----------------------------------------------------------------------- // Pre : // Post : // Globals : // I/O : // Task : Create a new registry key object, butdo not attach it 2 any key yet //----------------------------------------------------------------------- CRegistry::CRegistry(): m_hKey(NULL), m_bStatus(FALSE) { } //----------------------------------------------------------------------- // Pre : // Post : Set the status 2 TRUE if opened OK // Globals : // I/O : // Task : Open a registry key //----------------------------------------------------------------------- CRegistry::CRegistry(HKEY hKey, // A previously open key or a section LPCTSTR lpcszSubKey, // Path relative 2 hKey REGSAM dwDesiredSecurityAccessMask, // Desired open/create access BOOL bAllowCreate, // Create new, if does not exist DWORD dwOptions, // New key options LPSECURITY_ATTRIBUTES lpSecurityAttributes, // New key security LPDWORD lpdwDisposition): // Cretion disposition (created or opened) m_hKey(NULL), m_bStatus(FALSE) { Open(hKey,lpcszSubKey,dwDesiredSecurityAccessMask,bAllowCreate,dwOptions,lpSecurityAttributes,lpdwDisposition); } //----------------------------------------------------------------------- // Pre : // Post : Set the status 2 TRUE if opened OK // Globals : // I/O : // Task : Open a registry key //----------------------------------------------------------------------- BOOL CRegistry::Open(HKEY hKey, // A previously open key or a section LPCTSTR lpcszSubKey, // Path relative 2 hKey REGSAM dwDesiredSecurityAccessMask, // Desired open/create access BOOL bAllowCreate, // Create new, if does not exist DWORD dwOptions, // New key options LPSECURITY_ATTRIBUTES lpSecurityAttributes, // New key security LPDWORD lpdwDisposition) // Creation disposition (created or opened) { // If already attached 2 a key, close it now Close(); #ifdef _DEBUG // Store the key's parent and the key's path m_hKeyParent =hKey; _tcsncpy(m_hKeyPath,lpcszSubKey,sizeof(m_hKeyPath)/sizeof(TCHAR)); #endif // Attempt 2 open specified key m_nErrorCode =RegOpenKeyEx(hKey,lpcszSubKey,0,dwDesiredSecurityAccessMask,&m_hKey); if(m_nErrorCode == ERROR_SUCCESS) { m_bStatus=TRUE; if(lpdwDisposition) *lpdwDisposition =REG_OPENED_EXISTING_KEY; } if(!m_bStatus && bAllowCreate) { // Could not open key, probably inexistent // Attempt 2 create it DWORD operation; m_nErrorCode =RegCreateKeyEx(hKey,lpcszSubKey,0,NULL,dwOptions,dwDesiredSecurityAccessMask,lpSecurityAttributes,&m_hKey,&operation); if(m_nErrorCode == ERROR_SUCCESS) { m_bStatus=TRUE; if(lpdwDisposition) *lpdwDisposition =operation; } } return m_bStatus; } //--------------------------------------------------------------------------- // Pre : // Post : Returns size in bytes, -1 on error // Globals : // I/O : // Task : Get the size of the specified value //--------------------------------------------------------------------------- DWORD CRegistry::GetValueSize(LPCTSTR name) { if(!m_bStatus) return (DWORD)-1; DWORD value_size; if(!GetValue(name,NULL,value_size)) return (DWORD)-1; return value_size; } //----------------------------------------------------------------------- // Pre : data_size must be initialized before this call 2 the size of // the buffer where you expect data 2 be returned // Post : Return TRUE on success // Globals : // I/O : // Task : Extract a value from current key //----------------------------------------------------------------------- BOOL CRegistry::GetValue(LPCTSTR name, BYTE *data, DWORD &data_size, DWORD *type) { if(!m_bStatus) return FALSE; m_nErrorCode=RegQueryValueEx(m_hKey,name,NULL,type,data,&data_size); return m_nErrorCode==ERROR_SUCCESS; } //----------------------------------------------------------------------- // Pre : buffsize must be initialized before this call 2 the size of // the buffer where you expect data 2 be returned // Post : Return TRUE on success // Globals : // I/O : // Task : Extract default value from current key //----------------------------------------------------------------------- BOOL CRegistry::GetDefaultValue(LPTSTR def_value_buff, DWORD &buffsize) { if(!m_bStatus) return FALSE; m_nErrorCode=RegQueryValueEx(m_hKey,NULL,0,NULL,(BYTE *)def_value_buff,&buffsize); return m_nErrorCode==ERROR_SUCCESS; } //----------------------------------------------------------------------- // Pre : // Post : Return TRUE on success // Globals : // I/O : // Task : Set a value of the current key //----------------------------------------------------------------------- BOOL CRegistry::SetValue(LPCTSTR name, const BYTE *data, DWORD data_size, DWORD type) { if(!m_bStatus) return FALSE; m_nErrorCode=RegSetValueEx(m_hKey,name,0,type,data,data_size); return m_nErrorCode==ERROR_SUCCESS; } //----------------------------------------------------------------------- // Pre : // Post : Return TRUE on success // Globals : // I/O : // Task : Set default value of current key //----------------------------------------------------------------------- BOOL CRegistry::SetDefaultValue(LPCTSTR def_value) { if(!m_bStatus) return FALSE; m_nErrorCode=RegSetValueEx(m_hKey,NULL,0,REG_SZ,(BYTE *)def_value,lstrlen(def_value)+1); return m_nErrorCode==ERROR_SUCCESS; } //----------------------------------------------------------------------- // Pre : // Post : Return TRUE on success // Globals : // I/O : // Task : Deletete specified value of current key //----------------------------------------------------------------------- BOOL CRegistry::DeleteValue(LPCTSTR name) { if(!m_bStatus) return FALSE; m_nErrorCode=RegDeleteValue(m_hKey,name); return m_nErrorCode==ERROR_SUCCESS; } //----------------------------------------------------------------------- // Pre : data_size must be initialized before this call 2 the size of // the buffer where you expect data 2 be returned // Post : Return TRUE on success // Globals : // I/O : // Task : Extract a value from current key //----------------------------------------------------------------------- /*BOOL CRegistry::GetValue(LPCTSTR name, BYTE *data, DWORD &data_size, DWORD *type) { if(!m_bStatus) return FALSE; m_nErrorCode=RegQueryValueEx(m_hKey,name,NULL,type,data,&data_size); return m_nErrorCode==ERROR_SUCCESS; }*/ stdstr CRegistry::GetString(LPCTSTR name) { DWORD ValSize = GetValueSize(name); if (static_cast(ValSize) <= 0) { return _T(""); } DWORD ValType; LPTSTR String = new TCHAR[ValSize]; if (!GetValue(name,reinterpret_cast(String),ValSize,&ValType)) { return stdstr(_T("")); } stdstr Result(String); delete [] String; return Result; } //----------------------------------------------------------------------- // Pre : // Post : Return TRUE on success // Globals : // I/O : // Task : Enumerate subkeys of the current key // You can use this by calling CountSubKeys 2 get the number of // subkeys, then calling this member with 0-based indexes of subkey // 2 get info about //----------------------------------------------------------------------- BOOL CRegistry::EnumerateSubKeys(DWORD index, LPTSTR name, DWORD &name_size) { if(!m_bStatus) return FALSE; m_nErrorCode=RegEnumKeyEx(m_hKey,index,name,&name_size,NULL,NULL,0,NULL); return (m_nErrorCode==ERROR_SUCCESS); } //----------------------------------------------------------------------- // Pre : If a pointer 2 value data is specified (retrieving value data too) // then data_size must not be NULL and the pointed DWORD must hold // the size of the data buffer // Post : Return TRUE on success // Globals : // I/O : // Task : Enumerate values of current key // You can use this by calling CountValues 2 get the number of // values, then calling this member with 0-based indexes of value // 2 get info about //----------------------------------------------------------------------- BOOL CRegistry::EnumerateValues(DWORD index, LPTSTR name, DWORD &name_size, DWORD *type, BYTE *data, DWORD *data_size) { if(!m_bStatus) return FALSE; m_nErrorCode=RegEnumValue(m_hKey,index,name,&name_size,NULL,type,data,data_size); return (m_nErrorCode==ERROR_SUCCESS); } //----------------------------------------------------------------------- // Pre : // Post : Return TRUE if info was retrieved OK // Globals : // I/O : // Task : Query info about registy key //----------------------------------------------------------------------- BOOL CRegistry::GetInfo(LPTSTR lpszKeyClass, LPDWORD lpcKeyClassSize, // Non-NULL values should be supplied 4 at least LPDWORD lpcSubKeyCount, // parameters from one line LPDWORD lpcbLongestSubKeyName, LPDWORD lpcbLargestSubKeyClass, LPDWORD lpcValueCount, LPDWORD lpcbLongestValueName, LPDWORD lpcbLargestValueData, LPDWORD lpcbSecurityDescriptorSize, PFILETIME lpLastWriteTime) // NT only { #ifdef _WIN95 if(lpLastWriteTime) ASSERT(FALSE); // This should be used only on NT, because on Windows 95 it gets filled with 0s #endif if(!m_bStatus) return FALSE; m_nErrorCode=RegQueryInfoKey(m_hKey,lpszKeyClass,lpcKeyClassSize,NULL, lpcSubKeyCount,lpcbLongestSubKeyName,lpcbLargestSubKeyClass, lpcValueCount,lpcbLongestValueName,lpcbLargestValueData, lpcbSecurityDescriptorSize, lpLastWriteTime); return m_nErrorCode==ERROR_SUCCESS; } //----------------------------------------------------------------------- // Pre : // Post : On error returns -1 // Globals : // I/O : // Task : Return the number of subkeys of this key //----------------------------------------------------------------------- DWORD CRegistry::CountSubKeys() { DWORD subkeys; if(!GetInfo(NULL,NULL,&subkeys)) return (DWORD)-1; return subkeys; } //----------------------------------------------------------------------- // Pre : // Post : On error returns FALSE // Globals : // I/O : // Task : Remove this key and its descendants // Because on NT the key 2 be removed must not have subkeys, remove // first all the subkeys //----------------------------------------------------------------------- BOOL CRegistry::Delete(BOOL bDeleteSubkeys) { if(!m_bStatus) return FALSE; BOOL success =TRUE; if(bDeleteSubkeys) { // Attempt 2 delete all subkeys DWORD keys =CountSubKeys(); while(keys>0) { TCHAR key_name[MAX_PATH]; DWORD key_name_size =sizeof(key_name); // Get a subkey... if(EnumerateSubKeys(0,key_name,key_name_size)) { // Got a subkey, now delete it CRegistry sub_key(*this,key_name); success =sub_key.Delete(); } if(success) keys =CountSubKeys(); else break; } } if(success) { m_nErrorCode=RegDeleteKey(m_hKey,_T("")); if(m_nErrorCode==ERROR_SUCCESS) Close(); } return success; } //----------------------------------------------------------------------- // Pre : // Post : On error returns -1 // Globals : // I/O : // Task : Return the number of values in this key // This count does not include the default value //----------------------------------------------------------------------- DWORD CRegistry::CountValues() { DWORD values; if(!GetInfo(NULL,NULL,NULL,NULL,NULL,&values)) return (DWORD)-1; return values; } //----------------------------------------------------------------------- // Pre : // Post : Return TRUE on success // Globals : // I/O : // Task : Force saving of registry key data back in the registry //----------------------------------------------------------------------- BOOL CRegistry::Flush() { if(!m_bStatus) return FALSE; m_nErrorCode=RegFlushKey(m_hKey); return m_nErrorCode==ERROR_SUCCESS; } //----------------------------------------------------------------------- // Pre : // Post : Return TRUE on success // Globals : // I/O : // Task : Conect to a remote computer's HKEY_LOCAL_MACHINE key //----------------------------------------------------------------------- BOOL CRegistry::Connect_HKEY_LOCAL_MACHINE(LPCTSTR machine) { Close(); TCHAR machine_name[MAX_REG_MACHINE_NAME_LEN]; lstrcpy(machine_name,machine); m_nErrorCode=RegConnectRegistry(machine_name,HKEY_LOCAL_MACHINE,&m_hKey); if(m_nErrorCode==ERROR_SUCCESS) m_bStatus=TRUE; else m_bStatus=FALSE; return m_bStatus; } //----------------------------------------------------------------------- // Pre : // Post : Return TRUE on success // Globals : // I/O : // Task : Conect to a remote computer's HKLM key //----------------------------------------------------------------------- BOOL CRegistry::Connect_HKEY_USERS(LPCTSTR machine) { Close(); TCHAR machine_name[MAX_REG_MACHINE_NAME_LEN]; lstrcpy(machine_name,machine); m_nErrorCode=RegConnectRegistry(machine_name,HKEY_USERS,&m_hKey); if(m_nErrorCode==ERROR_SUCCESS) m_bStatus=TRUE; else m_bStatus=FALSE; return m_bStatus; } //----------------------------------------------------------------------- // Pre : // Post : // Globals : // I/O : // Task : Close key //----------------------------------------------------------------------- void CRegistry::Close() { if(m_bStatus) RegCloseKey(m_hKey); m_hKey =NULL; m_bStatus =FALSE; } //----------------------------------------------------------------------- // Pre : // Post : // Globals : // I/O : // Task : Close registry key before destruction //----------------------------------------------------------------------- CRegistry::~CRegistry() { Close(); }