windows-nt/Source/XPSP1/NT/com/ole32/cs/backend/csenum.cxx
2020-09-26 16:20:57 +08:00

308 lines
7.7 KiB
C++

//----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996
//
// File: csenum.cxx
//
// Contents: Per Class Container Package Enumeration
//
//
// History: 09-09-96 DebiM created
// 11-01-97 DebiM modified, moved to cstore
//
//----------------------------------------------------------------------------
#include "cstore.hxx"
//IEnumPackage implementation.
HRESULT CEnumPackage::QueryInterface(REFIID riid, void** ppObject)
{
if (riid==IID_IUnknown || riid==IID_IEnumPackage)
{
*ppObject=(IEnumPackage *) this;
}
else
{
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG CEnumPackage::AddRef()
{
InterlockedIncrement((long*) &m_dwRefCount);
return m_dwRefCount;
}
ULONG CEnumPackage::Release()
{
ULONG dwRefCount=m_dwRefCount-1;
if (InterlockedDecrement((long*) &m_dwRefCount)==0)
{
delete this;
return 0;
}
return dwRefCount;
}
//
// CEnumPackage::Next
// ------------------
//
//
//
// Synopsis: This method returns the next celt number of packages
// within the scope of the enumeration.
// Packages are returned in the alphabetical name order.
//
// Arguments: [in] celt - Number of package details to fetch
// INSTALLINFO *rgelt - Package detail structure
// ULONG *pceltFetched - Number of packages returned
//
// Returns: S_OK or S_FALSE if short of packages
//
//
//
HRESULT CEnumPackage::Next(ULONG celt,
PACKAGEDISPINFO *rgelt,
ULONG *pceltFetched)
{
ULONG cgot = 0, i, j;
HRESULT hr = S_OK;
if ((celt > 1) && (!pceltFetched))
return E_INVALIDARG;
if (pceltFetched)
(*pceltFetched) = 0;
if (!IsValidPtrOut(rgelt, sizeof(PACKAGEDISPINFO)*celt))
return E_INVALIDARG;
if (gDebug)
{
WCHAR Name[32];
DWORD NameSize = 32;
if ( ! GetUserName( Name, &NameSize ) )
CSDBGPrint((L"CEnumPackage::Next GetUserName failed 0x%x", GetLastError()));
else
CSDBGPrint((L"CEnumPackage::Next as %s", Name));
}
hr = FetchPackageInfo (m_hADs, m_hADsSearchHandle,
m_dwAppFlags,
m_pPlatform, celt, &cgot, rgelt,
&m_fFirst);
ERROR_ON_FAILURE(hr);
m_dwPosition += cgot;
if (pceltFetched)
*pceltFetched = cgot;
if (cgot != celt)
hr = S_FALSE;
else
hr = S_OK;
for (i=0; i < cgot; ++i)
{
memcpy (&(rgelt[i].GpoId), &m_PolicyId, sizeof(GUID));
if (m_szPolicyName[0])
{
rgelt[i].pszPolicyName = (LPOLESTR) CoTaskMemAlloc(sizeof(WCHAR) * (1+wcslen(&m_szPolicyName[0])));
if (rgelt[i].pszPolicyName)
wcscpy (rgelt[i].pszPolicyName, &m_szPolicyName[0]);
else {
for (j = 0; j < cgot; j++)
ReleasePackageInfo(rgelt+j);
if (pceltFetched)
*pceltFetched = 0;
return E_OUTOFMEMORY;
}
}
}
return hr;
Error_Cleanup:
return RemapErrorCode(hr, m_szPackageName);
}
HRESULT CEnumPackage::Skip(ULONG celt)
{
ULONG celtFetched = NULL, i;
HRESULT hr = S_OK;
PACKAGEDISPINFO *pIf = NULL;
pIf = new PACKAGEDISPINFO[celt];
hr = Next(celt, pIf, &celtFetched);
for (i = 0; i < celtFetched; i++)
ReleasePackageInfo(pIf+i);
delete pIf;
return hr;
}
HRESULT CEnumPackage::Reset()
{
HRESULT hr = S_OK;
m_dwPosition = 0;
m_fFirst = TRUE;
// execute the search and keep the handle returned.
if (m_hADsSearchHandle)
{
ADSICloseSearchHandle(m_hADs, m_hADsSearchHandle);
m_hADsSearchHandle = NULL;
}
hr = ADSIExecuteSearch(m_hADs, m_szfilter, pszPackageInfoAttrNames,
cPackageInfoAttr, &m_hADsSearchHandle);
return RemapErrorCode(hr, m_szPackageName);
}
HRESULT CEnumPackage::Clone(IEnumPackage **ppenum)
{
CEnumPackage *pClone = new CEnumPackage;
HRESULT hr = S_OK;
hr = pClone->Initialize(m_szPackageName, m_szfilter, m_dwAppFlags, m_pPlatform);
if (FAILED(hr)) {
delete pClone;
return hr;
}
hr = pClone->QueryInterface(IID_IEnumPackage, (void **)ppenum);
if (m_dwPosition)
pClone->Skip(m_dwPosition);
// we do not want to return the error code frm skip.
return hr;
}
CEnumPackage::CEnumPackage()
{
m_dwRefCount = 0;
m_fFirst = TRUE;
m_szfilter = NULL;
wcscpy(m_szPackageName, L"");
m_dwPosition = 0;
m_dwAppFlags = 0;
m_pPlatform = NULL;
m_hADs = NULL;
m_hADsSearchHandle = NULL;
memset (&m_PolicyId, 0, sizeof(GUID));
m_szPolicyName[0] = NULL;
}
CEnumPackage::CEnumPackage(GUID PolicyId, LPOLESTR pszPolicyName)
{
m_dwRefCount = 0;
m_fFirst = TRUE;
m_szfilter = NULL;
wcscpy(m_szPackageName, L"");
m_dwPosition = 0;
m_dwAppFlags = 0;
m_pPlatform = NULL;
m_hADs = NULL;
m_hADsSearchHandle = NULL;
memcpy (&m_PolicyId, &PolicyId, sizeof(GUID));
m_szPolicyName[0] = NULL;
if (pszPolicyName)
wcscpy (&m_szPolicyName[0], pszPolicyName);
}
HRESULT CEnumPackage::Initialize(WCHAR *szPackageName,
WCHAR *szfilter,
DWORD dwAppFlags,
CSPLATFORM *pPlatform)
{
HRESULT hr = S_OK;
ADS_SEARCHPREF_INFO SearchPrefs[2];
m_szfilter = (LPOLESTR)CoTaskMemAlloc (sizeof(WCHAR) * (wcslen(szfilter)+1));
if (!m_szfilter)
return E_OUTOFMEMORY;
// copy the filters, package name, flags and locale.
wcscpy(m_szfilter, szfilter);
wcscpy(m_szPackageName, szPackageName);
m_dwAppFlags = dwAppFlags;
if (gDebug)
{
WCHAR Name[32];
DWORD NameSize = 32;
if ( ! GetUserName( Name, &NameSize ) )
CSDBGPrint((L"CEnumPackage::Initialize GetUserName failed 0x%x", GetLastError()));
else
CSDBGPrint((L"CEnumPackage::Initialize as %s", Name));
}
// open the package container.
hr = ADSIOpenDSObject(szPackageName, NULL, NULL, ADS_SECURE_AUTHENTICATION | ADS_FAST_BIND,
&m_hADs);
ERROR_ON_FAILURE(hr);
// 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;
hr = ADSISetSearchPreference(m_hADs, SearchPrefs, 2);
ERROR_ON_FAILURE(hr);
// copy platform
if (pPlatform)
{
m_pPlatform = (CSPLATFORM *) CoTaskMemAlloc(sizeof(CSPLATFORM));
if (!m_pPlatform)
ERROR_ON_FAILURE(hr=E_OUTOFMEMORY);
memcpy (m_pPlatform, pPlatform, sizeof(CSPLATFORM));
}
// execute the search and keep the handle returned.
hr = ADSIExecuteSearch(m_hADs, szfilter, pszPackageInfoAttrNames,
cPackageInfoAttr, &m_hADsSearchHandle);
Error_Cleanup:
return RemapErrorCode(hr, m_szPackageName);
}
CEnumPackage::~CEnumPackage()
{
if (m_hADsSearchHandle)
ADSICloseSearchHandle(m_hADs, m_hADsSearchHandle);
if (m_hADs)
ADSICloseDSObject(m_hADs);
if (m_szfilter)
CoTaskMemFree(m_szfilter);
if (m_pPlatform)
CoTaskMemFree(m_pPlatform);
}