Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

512 lines
12 KiB

//----------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996-1999
//
// File: enumapp.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;
//
// Clear up this structure in case our fetch fails --
// we don't want callers freeing invalid memory
//
memset(rgelt, 0, sizeof(*rgelt) * celt);
hr = FetchPackageInfo (
m_hADs,
m_hADsSearchHandle,
m_dwAppFlags,
m_dwQuerySpec,
m_pPlatform,
celt,
&cgot,
rgelt,
&m_fFirst,
&m_PolicyId,
m_szGpoPath,
m_pRsopUserToken);
if (FAILED(hr))
{
//
// Clear up this structure so that callers don't
// try to free invalid memory when this fails
//
memset(rgelt, 0, sizeof(*rgelt) * celt);
cgot = 0;
if ( ( ( APPQUERY_RSOP_ARP == m_dwQuerySpec ) || ( APPQUERY_USERDISPLAY == m_dwQuerySpec ) ) &&
( hr == HRESULT_FROM_WIN32(ERROR_DS_NO_SUCH_OBJECT) ) )
{
hr = S_FALSE;
}
}
ERROR_ON_FAILURE(hr);
m_dwPosition += cgot;
if (pceltFetched)
*pceltFetched = cgot;
if (cgot != celt)
hr = S_FALSE;
else
hr = S_OK;
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;
LPOLESTR* ppszAttrs;
DWORD cAttrs;
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;
}
ppszAttrs = GetAttributesFromQuerySpec(
m_dwQuerySpec,
&cAttrs);
if ( ppszAttrs )
{
hr = ADSIExecuteSearch(
m_hADs,
m_szfilter,
ppszAttrs,
cAttrs,
&m_hADsSearchHandle);
}
else
{
hr = E_INVALIDARG;
}
return RemapErrorCode(hr, m_szPackageName);
}
CEnumPackage::CEnumPackage(CServerContext* pServerContext, GUID PolicyId, LPOLESTR pszPolicyName, LPOLESTR pszClassStorePath, PRSOPTOKEN pRsopToken )
{
m_dwRefCount = 0;
m_fFirst = TRUE;
m_szfilter = NULL;
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;
m_pRsopUserToken = pRsopToken;
m_szPackageName[0] = L'\0';
if (pszPolicyName)
{
(void) StringCchCopy (m_szPolicyName, _MAX_PATH, pszPolicyName);
}
if ( pServerContext )
{
HRESULT hrContext;
hrContext = m_ServerContext.Initialize( pServerContext );
//
// If this fails, we will skip subsequent initialization as well,
// and any operations with this object will fail because those
// intiailziations are not complete
//
if ( FAILED(hrContext) )
{
return;
}
}
//
// Remember the path of the gpo from which we are originating
// This information is needed for RSOP to determine where
// the package came from
//
// Note that if this fails, no operations on this object will succeed
//
m_szGpoPath = AllocGpoPathFromClassStorePath( pszClassStorePath );
}
HRESULT CEnumPackage::Initialize(
WCHAR *szPackageName,
WCHAR *szfilter,
DWORD dwAppFlags,
BOOL bPlanning,
CSPLATFORM *pPlatform)
{
HRESULT hr = S_OK;
ADS_SEARCHPREF_INFO SearchPrefs[3];
LPOLESTR* ppszAttrs;
DWORD cAttrs;
LONG lSecurityFlags;
DWORD cPrefs;
cPrefs = 2;
//
// Be sure we're properly initialized
//
if ( ! m_szGpoPath )
{
return E_OUTOFMEMORY;
}
//
// Set the security of our communications based on the preference
// of the caller
//
lSecurityFlags = GetDsFlags();
m_szfilter = (LPOLESTR)CsMemAlloc (sizeof(WCHAR) * (wcslen(szfilter)+1));
if (!m_szfilter)
return E_OUTOFMEMORY;
// copy the filters, package name, flags and locale.
hr = StringCchCopy(m_szfilter, wcslen(szfilter)+1, szfilter);
ERROR_ON_FAILURE(hr);
hr = StringCchCopy(m_szPackageName, _MAX_PATH, szPackageName);
ERROR_ON_FAILURE(hr);
m_dwAppFlags = ClientSideFilterFromQuerySpec( dwAppFlags, bPlanning );
m_dwQuerySpec = dwAppFlags;
// open the package container.
hr = DSServerOpenDSObject(&m_ServerContext, szPackageName, lSecurityFlags,
&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 = SEARCHPAGESIZE;
//
// For RSOP, we need to add an extra search pref to obtain the security
// descriptor
//
if ( ( APPQUERY_RSOP_ARP == dwAppFlags ) ||
( APPQUERY_RSOP_LOGGING == dwAppFlags ) )
{
SearchPrefs[2].dwSearchPref = ADS_SEARCHPREF_SECURITY_MASK;
SearchPrefs[2].vValue.dwType = ADSTYPE_INTEGER;
//
// Request everything but the SACL
//
SearchPrefs[2].vValue.Integer =
OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION;
cPrefs ++;
}
hr = ADSISetSearchPreference(m_hADs, SearchPrefs, cPrefs);
ERROR_ON_FAILURE(hr);
// copy platform
if (pPlatform)
{
m_pPlatform = (CSPLATFORM *) CsMemAlloc(sizeof(CSPLATFORM));
if (!m_pPlatform)
ERROR_ON_FAILURE(hr=E_OUTOFMEMORY);
memcpy (m_pPlatform, pPlatform, sizeof(CSPLATFORM));
}
ppszAttrs = GetAttributesFromQuerySpec(
m_dwQuerySpec,
&cAttrs);
// execute the search and keep the handle returned.
hr = ADSIExecuteSearch(
m_hADs,
szfilter,
ppszAttrs,
cAttrs,
&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)
CsMemFree(m_szfilter);
if (m_pPlatform)
CsMemFree(m_pPlatform);
if (m_szGpoPath)
CsMemFree(m_szGpoPath);
}
//--------------------------------------------------------------
CMergedEnumPackage::CMergedEnumPackage()
{
m_pcsEnum = NULL;
m_cEnum = 0;
m_csnum = 0;
m_dwRefCount = 0;
}
CMergedEnumPackage::~CMergedEnumPackage()
{
ULONG i;
for (i = 0; i < m_cEnum; i++)
m_pcsEnum[i]->Release();
CsMemFree(m_pcsEnum);
}
HRESULT __stdcall CMergedEnumPackage::QueryInterface(REFIID riid,
void * * ppObject)
{
*ppObject = NULL; //gd
if ((riid==IID_IUnknown) || (riid==IID_IEnumPackage))
{
*ppObject=(IEnumPackage *) this;
}
else
{
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG __stdcall CMergedEnumPackage::AddRef()
{
InterlockedIncrement((long*) &m_dwRefCount);
return m_dwRefCount;
}
ULONG __stdcall CMergedEnumPackage::Release()
{
ULONG dwRefCount;
if ((dwRefCount = InterlockedDecrement((long*) &m_dwRefCount))==0)
{
delete this;
return 0;
}
return dwRefCount;
}
HRESULT __stdcall CMergedEnumPackage::Next(
ULONG celt,
PACKAGEDISPINFO *rgelt,
ULONG *pceltFetched)
{
ULONG count=0, total = 0;
HRESULT hr;
//
// Clear everything
//
memset( rgelt, 0, sizeof(*rgelt) * celt );
for (; m_csnum < m_cEnum; m_csnum++)
{
count = 0;
hr = m_pcsEnum[m_csnum]->Next(celt, rgelt+total, &count);
if (FAILED(hr))
{
//
// Release everything on failure
//
ULONG iAllocated;
for ( iAllocated = 0; iAllocated < total; iAllocated++ )
{
ReleasePackageInfo( rgelt+iAllocated );
}
return hr;
}
total += count;
celt -= count;
if (!celt)
break;
}
if (pceltFetched)
*pceltFetched = total;
if (!celt)
return S_OK;
return S_FALSE;
}
HRESULT __stdcall CMergedEnumPackage::Skip(
ULONG celt)
{
PACKAGEDISPINFO *pPackageInfo = NULL;
HRESULT hr = S_OK;
ULONG cgot = 0, i;
pPackageInfo = (PACKAGEDISPINFO *)CsMemAlloc(sizeof(PACKAGEDISPINFO)*celt);
if (!pPackageInfo)
return E_OUTOFMEMORY;
hr = Next(celt, pPackageInfo, &cgot);
for (i = 0; i < cgot; i++)
ReleasePackageInfo(pPackageInfo+i);
CsMemFree(pPackageInfo);
return hr;
}
HRESULT __stdcall CMergedEnumPackage::Reset()
{
ULONG i;
for (i = 0; ((i <= m_csnum) && (i < m_cEnum)); i++)
m_pcsEnum[i]->Reset(); // ignoring all error values
m_csnum = 0;
return S_OK;
}
HRESULT CMergedEnumPackage::Initialize(IEnumPackage **pcsEnum, ULONG cEnum)
{
ULONG i;
m_csnum = 0;
m_pcsEnum = (IEnumPackage **)CsMemAlloc(sizeof(IEnumPackage *) * cEnum);
if (!m_pcsEnum)
return E_OUTOFMEMORY;
for (i = 0; i < cEnum; i++)
m_pcsEnum[i] = pcsEnum[i];
m_cEnum = cEnum;
return S_OK;
}