|
|
//
// Author: ushaji
// Date: December 1996
//
//
// Providing support for Component Categories in Class Store
//
// This source file contains implementations for Enumerator Interfaces.
//
// Refer Doc "Design for Support of File Types and Component Categories
// in Class Store" ? (or may be Class Store Schema). Most of these uses
// OLE DB interfaces within the interfaces.
//
//----------------------------------------------------------------------------
#include "cstore.hxx"
//
// Private defines
//
#define MAX_ADS_FILTERS 10
#define MAX_ADS_ENUM 100
HRESULT GetCategoryProperty (HANDLE hADs, ADS_SEARCH_HANDLE hSearchHandle, CATEGORYINFO *pcategoryinfo, LCID lcid) { HRESULT hr = S_OK; WCHAR *szName = NULL; LPOLESTR *pdesc = NULL; ULONG i, cdesc = 0; ADS_SEARCH_COLUMN column; hr = ADSIGetColumn(hADs, hSearchHandle, CATEGORYCATID, &column); RETURN_ON_FAILURE(hr); hr = UnpackGUIDFrom(column, &(pcategoryinfo->catid)); RETURN_ON_FAILURE(hr); ADSIFreeColumn(hADs, &column); hr = ADSIGetColumn(hADs, hSearchHandle, LOCALEDESCRIPTION, &column); RETURN_ON_FAILURE(hr); UnpackStrArrAllocFrom(column, &pdesc, &cdesc); pcategoryinfo->lcid = lcid; hr = GetCategoryLocaleDesc(pdesc, cdesc, &(pcategoryinfo->lcid), (pcategoryinfo->szDescription)); ADSIFreeColumn(hADs, &column); for (i = 0; i < cdesc; i++) CoTaskMemFree(pdesc[i]); CoTaskMemFree(pdesc); if (FAILED(hr)) *(pcategoryinfo->szDescription) = L'\0'; return S_OK; } //----------------------------------------------
// IEnumCATEGORYINFO:
// IUnknown methods
HRESULT CSCEnumCategories::QueryInterface(REFIID riid, void** ppObject) { *ppObject = NULL; //gd
if ((riid==IID_IUnknown) || (riid==IID_IEnumCATEGORYINFO)) { *ppObject=(IUnknown *)(IEnumCATEGORYINFO*) this; } else { return E_NOINTERFACE; } AddRef(); return S_OK; }
ULONG CSCEnumCategories::AddRef() { InterlockedIncrement((long*) &m_dwRefCount); return m_dwRefCount; }
ULONG CSCEnumCategories::Release() { ULONG dwRefCount; if ((dwRefCount = InterlockedDecrement((long*) &m_dwRefCount))==0) { delete this; return 0; } return dwRefCount; }
// IEnumCATEGORYINFO methods
//--------------------------------------------------------------------
// Next:
// celt: Number of elements to be fetched.
// rgelt: Buffer to return the elements.
// pceltFetched: ptr to Number of elements actually fetched.
// Takes care of that being NULL.
// Uses OLE DS interfaces to get the next enumerators.
//--------------------------------------------------------------------
HRESULT CSCEnumCategories::Next(ULONG celt, CATEGORYINFO *rgelt, ULONG *pceltFetched) { HRESULT hr = S_OK; ULONG dwCount = 0, cElems = 0; if ((celt > 1) && (!pceltFetched)) return E_INVALIDARG; if (pceltFetched) (*pceltFetched) = 0; if (celt < 0) return E_INVALIDARG; if (!IsValidPtrOut(rgelt, sizeof(CATEGORYINFO)*celt)) return E_INVALIDARG; for ((dwCount) = 0; (dwCount) < celt;) { if ((!m_dwPosition) && (!cElems)) hr = ADSIGetFirstRow(m_hADs, m_hADsSearchHandle); else hr = ADSIGetNextRow(m_hADs, m_hADsSearchHandle); cElems++; if ((FAILED(hr)) || (hr == S_ADS_NOMORE_ROWS)) break; hr = GetCategoryProperty(m_hADs, m_hADsSearchHandle, &(rgelt[dwCount]), m_lcid); if (FAILED(hr)) continue; (dwCount)++; } m_dwPosition += dwCount; if (pceltFetched) (*pceltFetched) = dwCount;
if (dwCount == celt) return S_OK; return S_FALSE;
}
//---------------------------------------------------
// skip:
// skips elements.
// celt Number of elements to skip.
//---------------------------------------------------
HRESULT CSCEnumCategories::Skip(ULONG celt) { CATEGORYINFO *dummy = NULL; ULONG got = 0; HRESULT hr = S_OK; dummy = new CATEGORYINFO[celt]; if (!dummy) return E_OUTOFMEMORY; hr = Next(celt, dummy, &got); delete dummy; return hr; }
//---------------------------------------------------
// Reset:
// Resets the pointer.
//---------------------------------------------------
HRESULT CSCEnumCategories::Reset(void) { HRESULT hr = S_OK; WCHAR szfilter[_MAX_PATH]; m_dwPosition = 0;
if (m_hADsSearchHandle) { ADSICloseSearchHandle(m_hADs, m_hADsSearchHandle); m_hADsSearchHandle = NULL; }
wsprintf(szfilter, L"(objectClass=%s)", CLASS_CS_CATEGORY); hr = ADSIExecuteSearch(m_hADs, szfilter, pszCategoryAttrNames, cCategoryAttr, &m_hADsSearchHandle); return RemapErrorCode(hr, m_szCategoryName); } //--------------------------------------------------------------
// Clone:
// returns another interface which points to the same data.
// ppenum: enumerator
//--------------------------------------------------------------
HRESULT CSCEnumCategories::Clone(IEnumCATEGORYINFO **ppenum) { CSCEnumCategories* pClone=NULL; if (!IsValidPtrOut(ppenum, sizeof(IEnumCATEGORYINFO *))) { return E_INVALIDARG; } pClone=new CSCEnumCategories(); if (!pClone) { return E_OUTOFMEMORY; } if (FAILED(pClone->Initialize(m_szCategoryName, m_lcid))) { delete pClone; return E_UNEXPECTED; } pClone->Skip(m_dwPosition); if (SUCCEEDED(pClone->QueryInterface(IID_IEnumCATEGORYINFO, (void**) ppenum))) { return S_OK; } delete pClone; return E_UNEXPECTED; }
CSCEnumCategories::CSCEnumCategories() { m_dwRefCount=0; m_hADs = NULL; m_hADsSearchHandle = NULL; wcscpy(m_szCategoryName, L""); m_lcid = 0; m_dwPosition = 0; }
// clone will go over the wire again.
// reference counting will be good.
HRESULT CSCEnumCategories::Initialize(WCHAR *szCategoryName, LCID lcid) { HRESULT hr = S_OK; WCHAR szfilter[_MAX_PATH]; ADS_SEARCHPREF_INFO SearchPrefs[2]; // set the search preference.
SearchPrefs[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE; SearchPrefs[0].vValue.dwType = ADSTYPE_INTEGER; SearchPrefs[0].vValue.Integer = ADS_SCOPE_ONELEVEL; SearchPrefs[1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE; SearchPrefs[1].vValue.dwType = ADSTYPE_INTEGER; SearchPrefs[1].vValue.Integer = 20; wcscpy(m_szCategoryName, szCategoryName); hr = ADSIOpenDSObject(m_szCategoryName, NULL, NULL, ADS_SECURE_AUTHENTICATION, &m_hADs); RETURN_ON_FAILURE(hr); hr = ADSISetSearchPreference(m_hADs, SearchPrefs, 2); RETURN_ON_FAILURE(hr); wsprintf(szfilter, L"(objectClass=%s)", CLASS_CS_CATEGORY); hr = ADSIExecuteSearch(m_hADs, szfilter, pszCategoryAttrNames, cCategoryAttr, &m_hADsSearchHandle); RETURN_ON_FAILURE(hr); m_lcid = lcid; return S_OK; } /* EnumCategories */
CSCEnumCategories::~CSCEnumCategories() { if (m_hADs) ADSICloseDSObject(m_hADs); if (m_hADsSearchHandle) ADSICloseSearchHandle(m_hADs, m_hADsSearchHandle); }
// CSCEnumCategoriesOfClass:
// IUnknown methods
HRESULT CSCEnumCategoriesOfClass::QueryInterface(REFIID riid, void** ppObject) { if ((riid==IID_IUnknown) || (riid==IID_IEnumCATID)) { *ppObject=(IEnumCATID*) this; } else { return E_NOINTERFACE; } AddRef(); return S_OK; }
ULONG CSCEnumCategoriesOfClass::AddRef() { InterlockedIncrement((long*) &m_dwRefCount); return m_dwRefCount; }
ULONG CSCEnumCategoriesOfClass::Release() { ULONG dwRefCount; if ((dwRefCount = InterlockedDecrement((long*) &m_dwRefCount))==0) { delete this; return 0; } return dwRefCount; }
// IEnumCATID methods
HRESULT CSCEnumCategoriesOfClass::Next(ULONG celt, GUID *rgelt, ULONG *pceltFetched) { ULONG dwCount; if ((celt > 1) && (!pceltFetched)) return E_INVALIDARG; if (pceltFetched) (*pceltFetched) = 0; if (celt < 0) return E_INVALIDARG; if (!IsValidPtrOut(rgelt, sizeof(GUID)*celt)) return E_INVALIDARG; for ( (dwCount) = 0; (((dwCount) < celt) && (m_dwPosition < m_cCatid)); (dwCount)++, m_dwPosition++) rgelt[(dwCount)] = m_catid[m_dwPosition]; if (pceltFetched) (*pceltFetched) = dwCount; if (dwCount == celt) return S_OK; return S_FALSE; }
HRESULT CSCEnumCategoriesOfClass::Skip(ULONG celt) { if (m_cCatid >= (celt + m_dwPosition)) { m_dwPosition += celt; return S_OK; } m_dwPosition = m_cCatid; return S_FALSE; }
HRESULT CSCEnumCategoriesOfClass::Reset(void) { m_dwPosition = 0; return S_OK; }
HRESULT CSCEnumCategoriesOfClass::Clone(IEnumGUID **ppenum) { HRESULT hr = S_OK; CSCEnumCategoriesOfClass *pEnumClone = NULL; if (!IsValidPtrOut(ppenum, sizeof(IEnumGUID *))) return E_POINTER; pEnumClone = new CSCEnumCategoriesOfClass; if (pEnumClone == NULL) return E_OUTOFMEMORY; pEnumClone->Initialize(m_catid, m_cCatid); pEnumClone->m_dwPosition = m_dwPosition; if (SUCCEEDED(hr = pEnumClone->QueryInterface(IID_IEnumCATID, (void**) ppenum))) return S_OK; delete pEnumClone; return hr; }
CSCEnumCategoriesOfClass::CSCEnumCategoriesOfClass() { m_dwRefCount=0; m_dwPosition = 0; m_catid = NULL; }
HRESULT CSCEnumCategoriesOfClass::Initialize(CATID catid[], ULONG cCatid) { ULONG i; m_catid = new CATID[cCatid]; if ((cCatid) && (!m_catid)) return E_OUTOFMEMORY; m_cCatid = cCatid; for (i = 0; i < cCatid; i++) m_catid[i] = catid[i]; m_dwPosition = 0; return S_OK; }
CSCEnumCategoriesOfClass::~CSCEnumCategoriesOfClass() { if (m_catid) delete m_catid; }
// CEnumClassesOfCategories:
// IUnknown methods
HRESULT CSCEnumClassesOfCategories::QueryInterface(REFIID riid, void** ppObject) { if (riid==IID_IUnknown || riid==IID_IEnumCLSID) { *ppObject=(IEnumCLSID*) this; } else { return E_NOINTERFACE; } AddRef(); return S_OK; }
ULONG CSCEnumClassesOfCategories::AddRef() { InterlockedIncrement((long*) &m_dwRefCount); return m_dwRefCount; }
ULONG CSCEnumClassesOfCategories::Release() { ULONG dwRefCount; if ((dwRefCount = InterlockedDecrement((long*) &m_dwRefCount))==0) { delete this; return 0; } return dwRefCount; }
// IEnumGUID methods
HRESULT CSCEnumClassesOfCategories::Next(ULONG celt, GUID *rgelt, ULONG *pceltFetched) { ULONG i, dwCount=0; HRESULT hr = S_OK; CLSID clsid; WCHAR * szClsid = NULL; DWORD cElems = 0; ADS_SEARCH_COLUMN column; if ((celt > 1) && (!pceltFetched)) return E_INVALIDARG; if (pceltFetched) (*pceltFetched) = 0; if ((celt < 0) || (!IsValidPtrOut(rgelt, sizeof(GUID)*celt))) return E_INVALIDARG; for ((dwCount) = 0; (dwCount) < celt;) { if ((!m_dwPosition) && (!cElems)) hr = ADSIGetFirstRow(m_hADs, m_hADsSearchHandle); else hr = ADSIGetNextRow(m_hADs, m_hADsSearchHandle); cElems++; if ((FAILED(hr)) || (hr == S_ADS_NOMORE_ROWS)) { if (pceltFetched) *pceltFetched = dwCount; return S_FALSE; } hr = ADSIGetColumn(m_hADs, m_hADsSearchHandle, CLASSCLSID, &column); if (FAILED(hr)) { if (pceltFetched) *pceltFetched = dwCount; return S_FALSE; } UnpackStrFrom(column, &szClsid); GUIDFromString(szClsid, &clsid); if ((ImplSatisfied(m_cImplemented, m_rgcatidImpl, m_hADs, m_hADsSearchHandle) == S_OK) && (ReqSatisfied(m_cRequired, m_rgcatidReq, m_hADs, m_hADsSearchHandle) == S_OK)) { rgelt[dwCount] = clsid; (dwCount)++; } } m_dwPosition += dwCount; if (pceltFetched) *pceltFetched = dwCount; return S_OK; }
HRESULT CSCEnumClassesOfCategories::Skip(ULONG celt) { CLSID *dummyclasses=NULL; ULONG celtFetched=0; HRESULT hr=S_OK; dummyclasses = new CLSID[celt]; hr = Next(celt, dummyclasses, &celtFetched); delete dummyclasses; return hr; }
HRESULT CSCEnumClassesOfCategories::Reset() { LPOLESTR AttrNames[] = {CLASSCLSID, IMPL_CATEGORIES, REQ_CATEGORIES}; DWORD cAttrs = 3; WCHAR szfilter[_MAX_PATH]; HRESULT hr = S_OK;
m_dwPosition = 0; if (m_hADsSearchHandle) { ADSICloseSearchHandle(m_hADs, m_hADsSearchHandle); m_hADsSearchHandle = NULL; }
wsprintf(szfilter, L"(objectClass=%s)", CLASS_CS_CLASS); hr = ADSIExecuteSearch(m_hADs, szfilter, AttrNames, cAttrs, &m_hADsSearchHandle);
return RemapErrorCode(hr, m_szClassName); }
HRESULT CSCEnumClassesOfCategories::Clone(IEnumGUID **ppenum) { HRESULT hr=S_OK; CSCEnumClassesOfCategories *pEnumClone=NULL; if (!ppenum) return E_INVALIDARG; pEnumClone = new CSCEnumClassesOfCategories; if (!pEnumClone) return E_OUTOFMEMORY; hr = pEnumClone->Initialize(m_cRequired, m_rgcatidReq, m_cImplemented, m_rgcatidImpl, m_szClassName); if (FAILED(hr)) { delete pEnumClone; return hr; } pEnumClone->Skip(m_dwPosition); hr = pEnumClone->QueryInterface(IID_IEnumCLSID, (void **)ppenum); if (FAILED(hr)) { delete pEnumClone; } return hr; }
CSCEnumClassesOfCategories::CSCEnumClassesOfCategories() { m_dwRefCount = 0; m_rgcatidReq = NULL; m_rgcatidImpl = NULL; wcscpy(m_szClassName,L""); m_dwPosition = 0; m_hADs = NULL; m_hADsSearchHandle = NULL; }
HRESULT CSCEnumClassesOfCategories::Initialize(ULONG cRequired, CATID rgcatidReq[], ULONG cImplemented, CATID rgcatidImpl[], WCHAR *szClassName) { ULONG i; HRESULT hr = S_OK; ADS_SEARCHPREF_INFO SearchPrefs[2]; LPOLESTR AttrNames[] = {CLASSCLSID, IMPL_CATEGORIES, REQ_CATEGORIES}; DWORD cAttrs = 3; WCHAR szfilter[_MAX_PATH]; SearchPrefs[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE; SearchPrefs[0].vValue.dwType = ADSTYPE_INTEGER; SearchPrefs[0].vValue.Integer = ADS_SCOPE_ONELEVEL; SearchPrefs[1].dwSearchPref = ADS_SEARCHPREF_PAGESIZE; SearchPrefs[1].vValue.dwType = ADSTYPE_INTEGER; SearchPrefs[1].vValue.Integer = 20; wcscpy(m_szClassName, szClassName); hr = ADSIOpenDSObject(m_szClassName, NULL, NULL, ADS_SECURE_AUTHENTICATION, &m_hADs); ERROR_ON_FAILURE(hr); hr = ADSISetSearchPreference(m_hADs, SearchPrefs, 2); ERROR_ON_FAILURE(hr); wsprintf(szfilter, L"(objectClass=%s)", CLASS_CS_CLASS); hr = ADSIExecuteSearch(m_hADs, szfilter, AttrNames, cAttrs, &m_hADsSearchHandle); ERROR_ON_FAILURE(hr); m_cRequired = cRequired; if (cRequired != -1) { m_rgcatidReq = new CATID[cRequired]; if (!m_rgcatidReq) { hr = E_OUTOFMEMORY; ERROR_ON_FAILURE(hr); } for (i = 0; i < m_cRequired; i++) m_rgcatidReq[i] = rgcatidReq[i]; } m_cImplemented = cImplemented; if (cImplemented != -1) { m_rgcatidImpl = new CATID[cImplemented]; if (!m_rgcatidImpl) { hr = E_OUTOFMEMORY; ERROR_ON_FAILURE(hr); } for (i = 0; i < m_cImplemented; i++) m_rgcatidImpl[i] = rgcatidImpl[i]; } Error_Cleanup: return RemapErrorCode(hr, m_szClassName); }
CSCEnumClassesOfCategories::~CSCEnumClassesOfCategories() { if (m_rgcatidReq) delete m_rgcatidReq; if (m_rgcatidImpl) delete m_rgcatidImpl; if (m_hADsSearchHandle) ADSICloseSearchHandle(m_hADs, m_hADsSearchHandle); if (m_hADs) ADSICloseDSObject(m_hADs); }
|