VARTYPE CTCPropBagOnRegKey::_GetSubkeyVarType(CRegKey& key, const _bstr_t& strPropName) { ASSERT(key.Exists(strPropName)); // Open the subkey with the specified name CRegKey subkey; if (!subkey.Open(key, strPropName)) return VT_EMPTY; // Read the subkey's variant type value DWORD dwVT; if (!subkey.GetDWord(m_szVariantType, dwVT)) return VT_EMPTY; // Return the subkey's variant type value return VARTYPE(dwVT); }
HRESULT CTCPropBagOnRegKey::_ReadVariant(CRegKey& key, const _bstr_t& strValueName, VARIANT* pVar, IErrorLog* pErrorLog) { // Create an empty CComVariant object CComVariant v; // Read the specified property from the registry DWORD nType = 0; int cbData = 0; if (key.QueryValue(strValueName, nType, cbData)) // Name is a value? { // Read property in registry value as a VARIANT HRESULT hr = _ReadVariantFromValue(key, strValueName, nType, cbData, v, pErrorLog); if (FAILED(hr)) return hr; } else if (key.Exists(strValueName)) // Name is a subkey? { // Read property on subkey as specified by subkey's VariantType value HRESULT hr = E_FAIL; if (IsSubkeySafeArray(key, strValueName)) hr = ReadSafeArray(key, strValueName, pVar, pErrorLog); else if (IsSubkeyObject(key, strValueName)) { // Read property on subkey as an object CComObjectStack<CTCPropBagOnRegKey> bag; bag.Init(key, _bstr_t(), this); V_VT(&v) = VT_UNKNOWN; hr = bag._CreateObject(strValueName, &V_UNKNOWN(&v), pErrorLog); } if (FAILED(hr)) return hr; } else { // Specified name does not exist TRACE1("CTCPropBagOnRegKey::_ReadVariant: Property \"%s\" does not exist\n", strValueName); return E_INVALIDARG; } // Coerce the value to the specified variant type switch (V_VT(pVar)) { // Leave value as-is if no VARIANT type was specified case VT_EMPTY: VariantCopy(pVar, v); break; // Coerce supported VARIANT types case VT_BOOL: case VT_I1: case VT_I2: case VT_I4: case VT_UI1: case VT_UI2: case VT_UI4: case VT_ERROR: case VT_R4: case VT_R8: case VT_DECIMAL: case VT_CY: case VT_DATE: case VT_BSTR: case VT_UNKNOWN: case VT_DISPATCH: case VT_ARRAY | VT_BOOL: case VT_ARRAY | VT_I1: case VT_ARRAY | VT_I2: case VT_ARRAY | VT_I4: case VT_ARRAY | VT_UI1: case VT_ARRAY | VT_UI2: case VT_ARRAY | VT_UI4: case VT_ARRAY | VT_ERROR: case VT_ARRAY | VT_R4: case VT_ARRAY | VT_R8: case VT_ARRAY | VT_DECIMAL: case VT_ARRAY | VT_CY: case VT_ARRAY | VT_DATE: case VT_ARRAY | VT_BSTR: case VT_ARRAY | VT_UNKNOWN: case VT_ARRAY | VT_DISPATCH: case VT_ARRAY | VT_VARIANT: { // Coerce the value to the specified VARIANT type VariantChangeTypeEx(pVar, v, GetThreadLocale(), m_wChangeTypeFlags, V_VT(pVar)); break; } // All other VARIANT types are unsupported default: { // Use local resources MCLibRes res; // Format a description string _bstr_t strDesc; strDesc.Format(IDS_FMT_UNSUPPORTED_VT, UINT(V_VT(pVar)), UINT(V_VT(pVar))); // Log the error USES_CONVERSION; return LogError("ReadVariant", strDesc, E_FAIL, T2COLE(strValueName), pErrorLog); } } // Indicate success return S_OK; }