Platform SDK

CAppSettings


#define MANDATED_SETTING _T("Software\\Policies\\PDBP\\Guidelines\\1.0\\Settings")
#define USER_SETTING     _T("Software\\PDBP\\Guidelines\\1.0\\Settings")
#define ADMIN_SETTING    _T("Software\\Policies\\PDBP\\Guidelines\\1.0\\DefaultSettings")

class CAppSettings
{
    private:
        HKEY m_hKeyMandated;
        HKEY m_hKeyUser;
        HKEY m_hKeyAdminDefault;

        HRESULT hrReadReg(HKEY hKey, LPCTSTR tszSettingName, 
                          LPTSTR tszSetting, LPDWORD lpccbSize, 
                          BOOL fExpand=TRUE);

    public:
        CAppSettings(LPCTSTR tszMandatedSubKey, LPCTSTR tszUserSubKey, LPCTSTR tszAdminSubKey);
        ~CAppSettings();

        // Read REG_SZ or REG_EXPAND_SZ
        HRESULT hrReadSettings(LPCTSTR tszSettingName, 
                               LPTSTR tszSetting, LPDWORD lpccbSize, 
                               LPCTSTR tszDefaultSetting, BOOL fExpand=TRUE);
        // Read REG_DWORD
        HRESULT hrReadSettings(LPCTSTR tszSettingName, 
                               LPDWORD lpdwSetting,  
                               DWORD dwDefaultSetting);
};

CAppSettings::CAppSettings(LPCTSTR tszMandatedSubKey, LPCTSTR tszUserSubKey, LPCTSTR tszAdminSubKey)
{
    LONG    lResult = ERROR_SUCCESS;	

    m_hKeyMandated= NULL;
    m_hKeyAdminDefault= NULL;
    m_hKeyUser= NULL;	

    // Open Mandated Key
    lResult = RegOpenKeyEx(HKEY_CURRENT_USER, 
                           tszMandatedSubKey, 
                           NULL, 
                           KEY_QUERY_VALUE,
                           &m_hKeyMandated
                          );
    if (ERROR_SUCCESS != lResult)
    {
        assert(FALSE);
    }

    // Open Admin Key
    lResult = RegOpenKeyEx(HKEY_CURRENT_USER, 
                           tszAdminSubKey, 
                           NULL, 
                           KEY_QUERY_VALUE,
                           &m_hKeyAdminDefault
                          );
    if (ERROR_SUCCESS != lResult)
    {
        assert(FALSE);
    }

    // Open User Key
    lResult = RegOpenKeyEx(HKEY_CURRENT_USER, 
                          tszUserSubKey, 
                          NULL, 
                          KEY_QUERY_VALUE,
                          &m_hKeyUser
                         );
    if (ERROR_SUCCESS != lResult)
    {
        assert(FALSE);
    }
}

//DESTRUCTOR
CAppSettings::~CAppSettings()
{
    // Close open Keys
    if (m_hKeyMandated)
        RegCloseKey(m_hKeyMandated);

    if (m_hKeyAdminDefault)
        RegCloseKey(m_hKeyAdminDefault);

    if (m_hKeyUser)
        RegCloseKey(m_hKeyUser);
}

HRESULT CAppSettings::hrReadReg(HKEY hKey, LPCTSTR tszSettingName, 
                                LPTSTR tszSetting, LPDWORD lpccbSize, BOOL fExpand)
{
    HRESULT    hr = S_OK;
    LPTSTR     lptszTempBuffer = NULL;
    DWORD      dwType  = 0;	
    DWORD      ccbBufferSize  = 0;
    LONG       lResult = ERROR_SUCCESS;	

    // Sanity check passed in values
    // ...

    ccbBufferSize  = *lpccbSize;
    
    // Read the data from the reg key.
    lResult = RegQueryValueEx(hKey, tszSettingName, NULL, &dwType, 
                               (LPBYTE) tszSetting, lpccbSize
                             );

    // If the read op failed
    if(ERROR_SUCCESS != lResult)
    {
        if(ERROR_MORE_DATA == lResult)
        {	
            // oops! tszSetting wasn't big enough to hold the data
            hr = E_OUTOFMEMORY;
            SetLastError(ERROR_INSUFFICIENT_BUFFER);
        }	
        else
        {
            assert(FALSE);
            hr = E_FAIL;
        }
			
        goto __end;
    }

    if ((TRUE == fExpand) && (REG_EXPAND_SZ == dwType))
    {
        // Allocate a temp buffer for the expanded path
        lptszTempBuffer = (LPTSTR) malloc(ccbBufferSize);

        if (NULL == lptszTempBuffer)
        {
            hr = E_OUTOFMEMORY;
            assert(FALSE);
            goto __end;
        }

        //expand the path into temp buffer
        *lpccbSize = ExpandEnvironmentStrings(tszSetting,lptszTempBuffer, MAX_PATH);
		
        if(*lpccbSize == 0)
        {
            // We failed when expanding the path somehow
            hr = E_FAIL;
            assert(FALSE);	
            goto __end;
        }

        // Check to see if we need more buffer space than we have allocated
        if (*lpccbSize > ccbBufferSize)
        {
            // if the expanded path is too big to fit...
            hr = E_FAIL;
            SetLastError(ERROR_INSUFFICIENT_BUFFER);
            assert(FALSE);
            goto __end;
        }
        else // If we fit OK..
        {
            // Copy the expanded path back into our OutString
            _tcscpy(tszSetting,lptszTempBuffer);
        }
    }

__end:
    if(lptszTempBuffer)
    {
        // free our temp buffer 
        free(lptszTempBuffer);
        lptszTempBuffer = NULL;
    }

    return hr;
}

HRESULT CAppSettings::hrReadSettings(LPCTSTR tszSettingName, LPTSTR tszSetting, 
                                     LPDWORD lpccbSize, LPCTSTR tszDefaultSetting, 
                                     BOOL fExpand)
{    
    HRESULT hr = S_OK;
    DWORD   ccbTemp = 0;
    DWORD   dwType  = 0;
    LONG    lResult = ERROR_SUCCESS;	

    // Sanity check passed in values
    // ...

    ccbTemp = *lpccbSize;

    // Try to Read Mandated Setting
    hr = hrReadReg(m_hKeyMandated, tszSettingName, tszSetting, lpccbSize, TRUE);

    // If tszSetting is not > 1 the setting is empty,so we need to try again
    if ( (S_OK == lResult) && (_tcslen(tszSetting) > 1) )
    {
        // Succesfully Read Mandated Setting
    }
    else // No Mandated Setting, try to read User Setting
    {
        // Reset the size of the buffer for this read
        *lpccbSize = ccbTemp;

        hr = hrReadReg(m_hKeyUser, tszSettingName, tszSetting, lpccbSize, TRUE);

        if ( (S_OK == lResult) && (_tcslen(tszSetting) > 1) )
        {	
            // Succesfully Read User Setting		
        }
        else // No User Setting, try to read Admin Setting
        {
            // Reset the size of the buffer for this read
            *lpccbSize = ccbTemp;	
		
            hr = hrReadReg(m_hKeyAdminDefault, tszSettingName, tszSetting, lpccbSize, TRUE);
			
            if ( (S_OK == lResult) && (_tcslen(tszSetting) > 1) )
            {	
                // Succesfully read Admin Setting
            }
            else 
            {	
                // No Admin Setting. Use the default that was passed in
                
                // Set the size of the buffer to the size of the default
                 *lpccbSize = (_tcslen(tszDefaultSetting) * sizeof(TCHAR));

                // Make sure that the buffer is big enough to hold the default
                if (ccbTemp >= *lpccbSize)
                {
                    // copy the default that was passed in into 
                    // the buffer
                    _tcscpy(tszSetting,tszDefaultSetting);

                }
                else
                {
                    // oops. The bufer was too small for the default
                    hr = E_INVALIDARG;
                    goto __end;
                }
            }
        }
    }

__end:
    return hr;
}