/////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 1999, Microsoft Corp. All rights reserved. // // FILE // // enumerators.cpp // // SYNOPSIS // // Defines the class Enumerators. // // MODIFICATION HISTORY // // 02/25/1999 Original version. // /////////////////////////////////////////////////////////////////////////////// #include #include #include #include Enumerators::~Enumerators() throw () { for ( ; next != end; ++next) { SysFreeString(next->name); } CoTaskMemFree(begin); } HRESULT Enumerators::getEnumerators( LONG id, VARIANT* pNames, VARIANT* pValues ) throw () { VariantInit(pNames); VariantInit(pValues); HRESULT hr = getEnumerators( id, &V_ARRAY(pNames), &V_ARRAY(pValues) ); if (SUCCEEDED(hr) && V_ARRAY(pNames)) { V_VT(pNames) = VT_ARRAY | VT_VARIANT; V_VT(pValues) = VT_ARRAY | VT_VARIANT; } return hr; } HRESULT Enumerators::getEnumerators( LONG id, LPSAFEARRAY* pNames, LPSAFEARRAY* pValues ) throw () { // Initialize the out parameters. *pNames = *pValues = NULL; // If this is less than next, it must not be an enumerator. if (id < next->enumerates) { return S_OK; } // If this is greater than next, we skipped one. if (id > next->enumerates) { return E_INVALIDARG; } // Find the range of enumerations for this id. Enumeration* last = next; do { ++last; } while (last->enumerates == id); ULONG num = (ULONG)(last - next); // Create a SAFEARRAY to hold the names. *pNames = SafeArrayCreateVector(VT_VARIANT, 0, num); if (*pNames == NULL) { return E_OUTOFMEMORY; } // Create a SAFEARRAY to hold the values. *pValues = SafeArrayCreateVector(VT_VARIANT, 0, num); if (*pValues == NULL) { SafeArrayDestroy(*pNames); *pNames = NULL; return E_OUTOFMEMORY; } // Fill in the VARIANTs in the array. VARIANT* name = (VARIANT*)(*pNames)->pvData; VARIANT* value = (VARIANT*)(*pValues)->pvData; for ( ; next != last; ++next, ++name, ++value) { VariantInit(name); V_VT(name) = VT_BSTR; V_BSTR(name) = next->name; VariantInit(value); V_VT(value) = VT_I4; V_I4(value) = next->value; } return S_OK; } HRESULT Enumerators::initialize(IUnknown* session) throw () { HRESULT hr; LONG count; hr = IASExecuteSQLFunction( session, L"SELECT Count(*) AS X From Enumerators;", &count ); if (FAILED(hr)) { return hr; } CComPtr rowset; hr = IASExecuteSQLCommand( session, L"SELECT Name, Enumerates, Value FROM Enumerators " L"ORDER BY Enumerates, Value;", &rowset ); if (FAILED(hr)) { return hr; } CSimpleTable table; hr = table.Attach(rowset); if (FAILED(hr)) { return hr; } // Allocate one extra slot for the sentinel. begin = (Enumeration*)CoTaskMemAlloc((count + 1) * sizeof(Enumeration)); if (!begin) { return E_OUTOFMEMORY; } // Iterate through the rowset. for (end = begin; count-- && !table.MoveNext(); ++end) { end->enumerates = *(PLONG)table.GetValue(2); end->value = *(PLONG)table.GetValue(3); end->name = SysAllocString((PCWSTR)table.GetValue(1)); if (!end->name) { return E_OUTOFMEMORY; } } // Set the sentinel. end->enumerates = MAXLONG; // We start at the beginning. next = begin; return S_OK; }