337 lines
8.9 KiB
C
337 lines
8.9 KiB
C
|
/*************************************************************************
|
||
|
**
|
||
|
** OLE 2 Utility Code
|
||
|
**
|
||
|
** enumstat.c
|
||
|
**
|
||
|
** This file contains a standard implementation of IEnumStatData
|
||
|
** interface.
|
||
|
** This file is part of the OLE 2.0 User Interface support library.
|
||
|
**
|
||
|
** (c) Copyright Microsoft Corp. 1990 - 1992 All Rights Reserved
|
||
|
**
|
||
|
*************************************************************************/
|
||
|
|
||
|
#define STRICT 1
|
||
|
#include "ole2ui.h"
|
||
|
|
||
|
|
||
|
typedef struct tagOleStdEnumStatData {
|
||
|
IEnumSTATDATAVtbl FAR* lpVtbl;
|
||
|
ULONG m_dwRefs; /* referance count */
|
||
|
ULONG m_nIndex; /* current index in list */
|
||
|
ULONG m_nCount; /* how many items in list */
|
||
|
LPSTATDATA m_lpStat; /* list of STATDATA */
|
||
|
} OLESTDENUMSTATDATA, FAR* LPOLESTDENUMSTATDATA;
|
||
|
|
||
|
VOID OleStdEnumStatData_Destroy(LPOLESTDENUMSTATDATA pStat);
|
||
|
|
||
|
STDMETHODIMP OleStdEnumStatData_QueryInterface(
|
||
|
LPENUMSTATDATA lpThis, REFIID riid, LPVOID FAR* ppobj);
|
||
|
STDMETHODIMP_(ULONG) OleStdEnumStatData_AddRef(LPENUMSTATDATA lpThis);
|
||
|
STDMETHODIMP_(ULONG) OleStdEnumStatData_Release(LPENUMSTATDATA lpThis);
|
||
|
STDMETHODIMP OleStdEnumStatData_Next(LPENUMSTATDATA lpThis, ULONG celt,
|
||
|
LPSTATDATA rgelt, ULONG FAR* pceltFetched);
|
||
|
STDMETHODIMP OleStdEnumStatData_Skip(LPENUMSTATDATA lpThis, ULONG celt);
|
||
|
STDMETHODIMP OleStdEnumStatData_Reset(LPENUMSTATDATA lpThis);
|
||
|
STDMETHODIMP OleStdEnumStatData_Clone(LPENUMSTATDATA lpThis,
|
||
|
LPENUMSTATDATA FAR* ppenum);
|
||
|
|
||
|
static IEnumSTATDATAVtbl g_EnumSTATDATAVtbl = {
|
||
|
OleStdEnumStatData_QueryInterface,
|
||
|
OleStdEnumStatData_AddRef,
|
||
|
OleStdEnumStatData_Release,
|
||
|
OleStdEnumStatData_Next,
|
||
|
OleStdEnumStatData_Skip,
|
||
|
OleStdEnumStatData_Reset,
|
||
|
OleStdEnumStatData_Clone,
|
||
|
};
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
STDAPI_(BOOL)
|
||
|
OleStdCopyStatData(LPSTATDATA pDest, LPSTATDATA pSrc)
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
{
|
||
|
if ((pDest == NULL) || (pSrc == NULL)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (OleStdCopyFormatEtc(&pDest->formatetc, &pSrc->formatetc) == FALSE) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
pDest->advf = pSrc->advf;
|
||
|
pDest->pAdvSink = pSrc->pAdvSink;
|
||
|
pDest->dwConnection = pSrc->dwConnection;
|
||
|
|
||
|
if (pDest->pAdvSink != NULL) {
|
||
|
pDest->pAdvSink->lpVtbl->AddRef(pDest->pAdvSink);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
} /* OleStdCopyStatData()
|
||
|
*/
|
||
|
|
||
|
STDAPI_(LPENUMSTATDATA)
|
||
|
OleStdEnumStatData_Create(ULONG nCount, LPSTATDATA lpStatOrg)
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
{
|
||
|
LPMALLOC lpMalloc=NULL;
|
||
|
LPOLESTDENUMSTATDATA lpSD=NULL;
|
||
|
DWORD dwSize;
|
||
|
WORD i;
|
||
|
HRESULT hRes;
|
||
|
|
||
|
hRes = CoGetMalloc(MEMCTX_TASK, &lpMalloc);
|
||
|
if (hRes != NOERROR) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
lpSD = (LPOLESTDENUMSTATDATA)lpMalloc->lpVtbl->Alloc(lpMalloc,
|
||
|
sizeof(OLESTDENUMSTATDATA));
|
||
|
if (lpSD == NULL) {
|
||
|
goto errReturn;
|
||
|
}
|
||
|
|
||
|
lpSD->lpVtbl = &g_EnumSTATDATAVtbl;
|
||
|
lpSD->m_dwRefs = 1;
|
||
|
lpSD->m_nCount = nCount;
|
||
|
lpSD->m_nIndex = 0;
|
||
|
|
||
|
dwSize = sizeof(STATDATA) * lpSD->m_nCount;
|
||
|
|
||
|
lpSD->m_lpStat = (LPSTATDATA)lpMalloc->lpVtbl->Alloc(lpMalloc, dwSize);
|
||
|
if (lpSD->m_lpStat == NULL)
|
||
|
goto errReturn;
|
||
|
|
||
|
lpMalloc->lpVtbl->Release(lpMalloc);
|
||
|
|
||
|
for (i=0; i<nCount; i++) {
|
||
|
OleStdCopyStatData(
|
||
|
(LPSTATDATA)&(lpSD->m_lpStat[i]), (LPSTATDATA)&(lpStatOrg[i]));
|
||
|
}
|
||
|
|
||
|
return (LPENUMSTATDATA)lpSD;
|
||
|
|
||
|
errReturn:
|
||
|
if (lpSD != NULL)
|
||
|
lpMalloc->lpVtbl->Free(lpMalloc, lpSD);
|
||
|
|
||
|
if (lpMalloc != NULL)
|
||
|
lpMalloc->lpVtbl->Release(lpMalloc);
|
||
|
|
||
|
return NULL;
|
||
|
|
||
|
} /* OleStdEnumStatData_Create()
|
||
|
*/
|
||
|
|
||
|
|
||
|
VOID
|
||
|
OleStdEnumStatData_Destroy(LPOLESTDENUMSTATDATA lpSD)
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
{
|
||
|
LPMALLOC lpMalloc=NULL;
|
||
|
WORD i;
|
||
|
|
||
|
if (lpSD != NULL) {
|
||
|
|
||
|
if (CoGetMalloc(MEMCTX_TASK, &lpMalloc) == NOERROR) {
|
||
|
|
||
|
/* OLE2NOTE: we MUST free any memory that was allocated for
|
||
|
** TARGETDEVICES contained within the STATDATA elements.
|
||
|
*/
|
||
|
for (i=0; i<lpSD->m_nCount; i++) {
|
||
|
if( lpSD->m_lpStat[i].pAdvSink )
|
||
|
lpSD->m_lpStat[i].pAdvSink->lpVtbl->Release(lpSD->m_lpStat[i].pAdvSink);
|
||
|
|
||
|
OleStdFree(lpSD->m_lpStat[i].formatetc.ptd);
|
||
|
}
|
||
|
|
||
|
if (lpSD->m_lpStat != NULL) {
|
||
|
lpMalloc->lpVtbl->Free(lpMalloc, lpSD->m_lpStat);
|
||
|
}
|
||
|
|
||
|
lpMalloc->lpVtbl->Free(lpMalloc, lpSD);
|
||
|
lpMalloc->lpVtbl->Release(lpMalloc);
|
||
|
}
|
||
|
}
|
||
|
} /* OleStdEnumStatData_Destroy()
|
||
|
*/
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
OleStdEnumStatData_QueryInterface(
|
||
|
LPENUMSTATDATA lpThis, REFIID riid, LPVOID FAR* ppobj)
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
{
|
||
|
LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
|
||
|
*ppobj = NULL;
|
||
|
|
||
|
if (IsEqualIID(riid,&IID_IUnknown) || IsEqualIID(riid,&IID_IEnumSTATDATA)){
|
||
|
*ppobj = (LPVOID)lpSD;
|
||
|
}
|
||
|
|
||
|
if (*ppobj == NULL) return ResultFromScode(E_NOINTERFACE);
|
||
|
else{
|
||
|
OleStdEnumStatData_AddRef(lpThis);
|
||
|
return NOERROR;
|
||
|
}
|
||
|
|
||
|
} /* OleStdEnumStatData_QueryInterface()
|
||
|
*/
|
||
|
|
||
|
|
||
|
STDMETHODIMP_(ULONG)
|
||
|
OleStdEnumStatData_AddRef(LPENUMSTATDATA lpThis)
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
{
|
||
|
LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
|
||
|
return lpSD->m_dwRefs++;
|
||
|
|
||
|
} /* OleStdEnumStatData_AddRef()
|
||
|
*/
|
||
|
|
||
|
|
||
|
STDMETHODIMP_(ULONG)
|
||
|
OleStdEnumStatData_Release(LPENUMSTATDATA lpThis)
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
{
|
||
|
LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
|
||
|
DWORD dwRefs = --lpSD->m_dwRefs;
|
||
|
|
||
|
if (dwRefs == 0)
|
||
|
OleStdEnumStatData_Destroy(lpSD);
|
||
|
|
||
|
return dwRefs;
|
||
|
|
||
|
} /* OleStdEnumStatData_Release()
|
||
|
*/
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
OleStdEnumStatData_Next(LPENUMSTATDATA lpThis, ULONG celt, LPSTATDATA rgelt,
|
||
|
ULONG FAR* pceltFetched)
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
{
|
||
|
LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
|
||
|
ULONG i=0;
|
||
|
ULONG nOffset;
|
||
|
|
||
|
if (rgelt == NULL) {
|
||
|
return ResultFromScode(E_INVALIDARG);
|
||
|
}
|
||
|
|
||
|
while (i < celt) {
|
||
|
nOffset = lpSD->m_nIndex + i;
|
||
|
|
||
|
if (nOffset < lpSD->m_nCount) {
|
||
|
OleStdCopyStatData(
|
||
|
(LPSTATDATA)&(rgelt[i]), (LPSTATDATA)&(lpSD->m_lpStat[nOffset]));
|
||
|
i++;
|
||
|
}else{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
lpSD->m_nIndex += (WORD)i;
|
||
|
|
||
|
if (pceltFetched != NULL) {
|
||
|
*pceltFetched = i;
|
||
|
}
|
||
|
|
||
|
if (i != celt) {
|
||
|
return ResultFromScode(S_FALSE);
|
||
|
}
|
||
|
|
||
|
return NOERROR;
|
||
|
} /* OleStdEnumStatData_Next()
|
||
|
*/
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
OleStdEnumStatData_Skip(LPENUMSTATDATA lpThis, ULONG celt)
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
{
|
||
|
LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
|
||
|
ULONG i=0;
|
||
|
ULONG nOffset;
|
||
|
|
||
|
while (i < celt) {
|
||
|
nOffset = lpSD->m_nIndex + i;
|
||
|
|
||
|
if (nOffset < lpSD->m_nCount) {
|
||
|
i++;
|
||
|
}else{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
lpSD->m_nIndex += (WORD)i;
|
||
|
|
||
|
if (i != celt) {
|
||
|
return ResultFromScode(S_FALSE);
|
||
|
}
|
||
|
|
||
|
return NOERROR;
|
||
|
} /* OleStdEnumStatData_Skip()
|
||
|
*/
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
OleStdEnumStatData_Reset(LPENUMSTATDATA lpThis)
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
{
|
||
|
LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
|
||
|
lpSD->m_nIndex = 0;
|
||
|
|
||
|
return NOERROR;
|
||
|
} /* OleStdEnumStatData_Reset()
|
||
|
*/
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
OleStdEnumStatData_Clone(LPENUMSTATDATA lpThis, LPENUMSTATDATA FAR* ppenum)
|
||
|
//----------------------------------------------------------------------------
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
{
|
||
|
LPOLESTDENUMSTATDATA lpSD = (LPOLESTDENUMSTATDATA)lpThis;
|
||
|
|
||
|
if (ppenum == NULL) {
|
||
|
return ResultFromScode(E_INVALIDARG);
|
||
|
}
|
||
|
|
||
|
*ppenum = OleStdEnumStatData_Create(lpSD->m_nCount, lpSD->m_lpStat);
|
||
|
|
||
|
// make sure cloned enumerator has same index state as the original
|
||
|
if (*ppenum) {
|
||
|
LPOLESTDENUMSTATDATA lpSDClone = (LPOLESTDENUMSTATDATA)*ppenum;
|
||
|
lpSDClone->m_nIndex = lpSD->m_nIndex;
|
||
|
return NOERROR;
|
||
|
} else
|
||
|
return ResultFromScode(E_OUTOFMEMORY);
|
||
|
|
||
|
} /* OleStdEnumStatData_Clone()
|
||
|
*/
|
||
|
|