diff options
Diffstat (limited to 'Common/ComponentData.cpp')
-rw-r--r-- | Common/ComponentData.cpp | 407 |
1 files changed, 407 insertions, 0 deletions
diff --git a/Common/ComponentData.cpp b/Common/ComponentData.cpp new file mode 100644 index 0000000..5b4d75d --- /dev/null +++ b/Common/ComponentData.cpp @@ -0,0 +1,407 @@ +// ComponentData.cpp : implementation file +// + +#include "stdafx.h" +#include "ComponentData.h" +#include "types.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +#ifdef _DEBUG + +void DumpVariant(VARIANT& var) +{ + USES_CONVERSION; + + switch(var.vt) + { + case VT_NULL: + ATLTRACE(_T("VT_NULL")); + break; + case VT_EMPTY: + ATLTRACE(_T("VT_EMPTY")); + break; + case VT_UI1: + ATLTRACE(_T("VT_UI1: ")); + ATLTRACE(_T("%u"), (int)var.bVal); + break; + case VT_I2: + ATLTRACE(_T("VT_I2: ")); + ATLTRACE(_T("%d"), (int)var.bVal); + break; + case VT_I4: + ATLTRACE(_T("VT_I4: ")); + ATLTRACE(_T("%d"), (int)var.bVal); + break; + case VT_R4: + ATLTRACE(_T("VT_R4: ")); + ATLTRACE(_T("%f"), (double)var.bVal); + break; + case VT_R8: + ATLTRACE(_T("VT_R8: ")); + ATLTRACE(_T("%f"), (double)var.bVal); + break; + case VT_BOOL: + ATLTRACE(_T("VT_BOOL: ")); + ATLTRACE(_T("%s"), var.boolVal ? _T("true") : _T("false")); + break; + case VT_ERROR: + ATLTRACE(_T("VT_ERROR: ")); + ATLTRACE(_T("%d"), var.scode); + break; + case VT_CY: + ATLTRACE(_T("VT_CY: ")); + ATLTRACE(_T("%d"), var.cyVal); + break; + case VT_DATE: + ATLTRACE(_T("VT_DATE ")); + break; + case VT_BSTR: + ATLTRACE(_T("VT_BSTR: ")); + ATLTRACE(_T("%s"), OLE2T(var.bstrVal)); + break; + case VT_UNKNOWN: + ATLTRACE(_T("VT_UNKNOWN: ")); + break; + default: + ATLTRACE(_T("VT_ Other")); + break; + } +} + +#define TRACEVARIANT(var) DumpVariant(var) + +#else + +#define TRACEVARIANT(var) ((void)0) +#endif + + + +///////////////////////////////////////////////////////////////////////////// +// CComponentData + + +CComponentData::CComponentData() +{ +} + +CComponentData::~CComponentData() +{ +} + +///////////////////////////////////////////////////////////////////////////// +// CComponentData message handlers + +HRESULT CComponentData::Initialize(const string & sKey) +{ + // Need a registry key to read from + if(sKey.empty()) + return E_INVALIDARG; + + m_sKey = sKey; + + return S_OK; + +} + + +////////////////////////////////////////////////////////////////// +// Does the actual saving to the Registry + +HRESULT CComponentData::Save(string sKey /* = "" */) +{ + ATLTRACE(_T("DATA SAVE\n==========\n")); + + long lRet = 0; + CRegKey regKey; + + + // Set to Internal Key if sKey Is Empty + if(sKey.empty()) sKey = m_sKey; + + + // Try and open Our Key + if((lRet = regKey.Create(HKEY_CURRENT_USER, sKey)) != ERROR_SUCCESS) + return HRESULT_FROM_WIN32(lRet); + + + // Now do actual saving + // Only support number and String types for now + DWORD dwData = 0; + + string_variant_map::iterator iter = m_mapValues.begin(); + + for( ;iter != m_mapValues.end(); iter++) + { + ATLTRACE(_T("Saving: %s -- Value: "), iter->first.c_str()); + TRACEVARIANT(iter->second); + ATLTRACE(_T("\n")); + + switch(iter->second.vt) + { + // Number Types + case VT_UI1: + case VT_I2: + case VT_I4: + case VT_R4: + case VT_R8: + case VT_CY: + + lRet = regKey.SetValue(iter->second.lVal, iter->first); +// ASSERT(lRet == ERROR_SUCCESS); + break; + + // It's a String + case VT_BSTR: + + lRet = regKey.SetValue(string(iter->second.bstrVal), iter->first); +// ASSERT(lRet == ERROR_SUCCESS); + break; + + + // Delete the Key if NULL or Empty value + case VT_NULL: + case VT_EMPTY: + + lRet = regKey.DeleteValue(iter->first); +// ASSERT(lRet == ERROR_SUCCESS); + break; + + default: + break; + + + + } + + } + + return S_OK; + +} + +////////////////////////////////////////////////////////////////// +// Passes the caller a IUnknown to the the underlying IPropertyBag + +/*IUnknown* CComponentData::GetIUnknown(bool bAddRef) +{ + // If asked not to increment then Release + if(bAddRef) + this->AddRef(); + + + return GetUnknown(); +} +*/ + +////////////////////////////////////////////////////////////////// +// Reads actual Value from Registry + +HRESULT CComponentData::Read(const string & sValName, VARIANT& varVal) +{ + // First Lookup the Value in the current map + string_variant_map::iterator iter = m_mapValues.find(sValName); + if(iter != m_mapValues.end()) + return ::VariantCopy(&varVal, &(iter->second)); + + + + // Make sure we are initialized with a key + if(m_sKey == "") + return E_UNEXPECTED; + + // Open Key + CRegKey regDataKey; + if(regDataKey.Create(HKEY_CURRENT_USER, m_sKey) == ERROR_SUCCESS) + { + + // Get Size and Type of Registry Value + DWORD dwType = NULL; + DWORD dwSize; + if(::RegQueryValueEx(regDataKey.m_hKey, sValName, 0, &dwType, NULL, &dwSize) == ERROR_SUCCESS) + { + + + // We Only Support DWORD and String + switch(dwType) + { + + case REG_DWORD: + + // Get DWORD Value + DWORD dwData; + dwSize = sizeof(DWORD); + if(::RegQueryValueEx(regDataKey.m_hKey, sValName, 0, &dwType, (LPBYTE)&dwData, &dwSize) == ERROR_SUCCESS) + { + + // Make sure we have a clean variant + ::VariantClear(&varVal); + // Return a 4 byte Integer + varVal.vt = VT_I4; + varVal.lVal = dwData; + + + regDataKey.Close(); + return S_OK; + + } + break; + + + case REG_SZ: + + + // Get String Value + string sData; + if(::RegQueryValueEx(regDataKey.m_hKey, sValName, 0, &dwType, (LPBYTE)sData.get_buffer(dwSize), &dwSize) == ERROR_SUCCESS) + { + // Have to Release before we can AllocSysString + sData.release_buffer(); + + + // Make sure we have a clean variant + ::VariantClear(&varVal); + // Return a BSTR (Client responsible for cleanup) + varVal.vt = VT_BSTR; + varVal.bstrVal = _bstr_t(sData); + + regDataKey.Close(); + return S_OK; + + } + break; + } + + + } + + regDataKey.Close(); + return REGDB_E_KEYMISSING; + + } + + regDataKey.Close(); + return REGDB_E_READREGDB; + +} + +////////////////////////////////////////////////////////////////// +// Saves the value passed to Internal Map where it stays until +// saved by the function Save + +HRESULT CComponentData::Write(const string& sValName, const VARIANT & varVal) +{ + HRESULT hr; + CComVariant varCopy = varVal; + + // Check what we've got + // We only support DWORD and String + switch(varVal.vt) + { + + case VT_UI1: + case VT_I2: + case VT_I4: + case VT_R4: + case VT_R8: + case VT_CY: + + // First try and make a 4 byte integer out of it (DWORD) + hr = VariantChangeType(&varCopy, &varCopy, 0, VT_I4); + if(FAILED(hr)) + return hr; + + case VT_BSTR: + case VT_NULL: + case VT_EMPTY: + + // Add Item to Variant Map + m_mapValues.erase(sValName); + m_mapValues.insert(make_pair(sValName, varCopy)); + return S_OK; + break; + + + default: + + return E_INVALIDARG; + break; + + } + + return S_OK; + +} + + + +///////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// IPropertyBag + +STDMETHODIMP CComponentData::Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog* pErrorLog) +{ +// TRACE("CComponentData::XPropertyBag::Read\n"); + + // Pass calls + ATLTRACE(_T("Read: %s -- Value: "), (LPCTSTR)string(pszPropName)); + HRESULT hr = Read(string(pszPropName), *pVar); + TRACEVARIANT(*pVar); + ATLTRACE(_T("\n")); + return hr; +} + +STDMETHODIMP CComponentData::Write(LPCOLESTR pszPropName, VARIANT* pVar) +{ +// TRACE("CComponentData::XPropertyBag::Write\n"); + + // Pass calls + ATLTRACE(_T("Write: %s -- Value: "), (LPCTSTR)string(pszPropName)); + TRACEVARIANT(*pVar); + ATLTRACE(_T("\n")); + return Write(string(pszPropName), *pVar); + +} + + +////////////////////////////////////////////////////////////////// +// Host specific Functions (returns default if error or can't find) + +int CComponentData::GetInt(const string& sKey, int nDefault) +{ + CComVariant var; + + var.vt = VT_I4; + var.lVal = nDefault; + + if(FAILED(Read(sKey, var))) + return nDefault; + else + return var.lVal; +} + +////////////////////////////////////////////////////////////////// +// Host specific Function + +bool CComponentData::WriteInt(const string& sKey, int nValue) +{ + CComVariant var; + + var.vt = VT_I4; + var.lVal = nValue; + + return SUCCEEDED(Write(sKey, var)); + +} + +bool CComponentData::Delete(const string& sKey) +{ + CComVariant var; + var.vt = VT_NULL; + return SUCCEEDED(Write(sKey, var)); +} |