2007-04-20 12:23:52 +00:00
|
|
|
/*
|
|
|
|
* IEnum* implementation
|
|
|
|
*
|
|
|
|
* Copyright 2006 Mike McCormack
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
2018-03-20 11:38:17 +00:00
|
|
|
#define COBJMACROS
|
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "objbase.h"
|
|
|
|
|
|
|
|
#include "enumx.h"
|
|
|
|
|
|
|
|
#include "wine/list.h"
|
|
|
|
#include "wine/debug.h"
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|
|
|
|
2008-07-10 09:14:19 +00:00
|
|
|
struct tagEnumSTATPROPSETSTG_impl
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
|
|
|
const void *vtbl;
|
|
|
|
LONG ref;
|
|
|
|
struct list elements;
|
|
|
|
struct list *current;
|
|
|
|
ULONG elem_size;
|
|
|
|
GUID riid;
|
2018-03-20 11:38:17 +00:00
|
|
|
IUnknown *parent;
|
|
|
|
enumx_copy_cb copy_cb;
|
2008-07-10 09:14:19 +00:00
|
|
|
};
|
2007-04-20 12:23:52 +00:00
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* enumx_QueryInterface
|
|
|
|
*/
|
|
|
|
HRESULT WINAPI enumx_QueryInterface(
|
|
|
|
enumx_impl *This,
|
|
|
|
REFIID riid,
|
|
|
|
void** ppvObject)
|
|
|
|
{
|
Finish the Wine sync. These components are not just rc file changes
atl, comctl32, comdlg32, dwmapi, fusion, gdiplus, jscript, mpr, mshtml, msi, msimtf, msxml3, ole32, oleaut32, riched20, shdocvw, shlwapi, urlmon, usp10, version and windowscodecs
Seems to build and boot. /me hides
svn path=/trunk/; revision=48273
2010-07-26 02:26:04 +00:00
|
|
|
if ( ppvObject==0 )
|
2007-04-20 12:23:52 +00:00
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
*ppvObject = 0;
|
|
|
|
|
|
|
|
if (IsEqualGUID(&IID_IUnknown, riid) ||
|
|
|
|
IsEqualGUID(&This->riid, riid))
|
|
|
|
{
|
|
|
|
IUnknown_AddRef(((IUnknown*)This));
|
|
|
|
*ppvObject = This;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* enumx_AddRef
|
|
|
|
*/
|
|
|
|
ULONG WINAPI enumx_AddRef(enumx_impl *This)
|
|
|
|
{
|
|
|
|
return InterlockedIncrement(&This->ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* enumx_Release
|
|
|
|
*/
|
|
|
|
ULONG WINAPI enumx_Release(enumx_impl *This)
|
|
|
|
{
|
|
|
|
ULONG ref;
|
|
|
|
|
|
|
|
ref = InterlockedDecrement(&This->ref);
|
|
|
|
if (ref == 0)
|
|
|
|
{
|
|
|
|
while (!list_empty(&This->elements))
|
|
|
|
{
|
|
|
|
struct list *x = list_head(&This->elements);
|
|
|
|
list_remove(x);
|
|
|
|
HeapFree(GetProcessHeap(), 0, x);
|
|
|
|
}
|
2018-03-20 11:38:17 +00:00
|
|
|
IUnknown_Release(This->parent);
|
2007-04-20 12:23:52 +00:00
|
|
|
HeapFree(GetProcessHeap(), 0, This);
|
|
|
|
}
|
|
|
|
return ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* enumx_Next
|
|
|
|
*/
|
|
|
|
HRESULT WINAPI enumx_Next(enumx_impl *This, ULONG celt,
|
|
|
|
void *rgelt, ULONG *pceltFetched)
|
|
|
|
{
|
|
|
|
unsigned char *p;
|
|
|
|
ULONG count = 0;
|
|
|
|
|
|
|
|
TRACE("%p %u %p\n", This, celt, pceltFetched);
|
|
|
|
|
|
|
|
if (This->current == NULL)
|
|
|
|
This->current = list_head(&This->elements);
|
|
|
|
p = rgelt;
|
|
|
|
while (count < celt && This->current && This->current != &This->elements)
|
|
|
|
{
|
2018-03-20 11:38:17 +00:00
|
|
|
if (This->copy_cb)
|
|
|
|
This->copy_cb(This->parent, &This->current[1], p);
|
|
|
|
else
|
|
|
|
memcpy(p, &This->current[1], This->elem_size);
|
2007-04-20 12:23:52 +00:00
|
|
|
p += This->elem_size;
|
|
|
|
This->current = This->current->next;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
if (pceltFetched)
|
|
|
|
*pceltFetched = count;
|
|
|
|
if (count < celt)
|
|
|
|
return S_FALSE;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* enumx_Skip
|
|
|
|
*/
|
|
|
|
HRESULT WINAPI enumx_Skip(enumx_impl *This, ULONG celt)
|
|
|
|
{
|
|
|
|
ULONG count = 0;
|
|
|
|
|
|
|
|
TRACE("%p %u\n", This, celt);
|
|
|
|
|
|
|
|
if (This->current == NULL)
|
|
|
|
This->current = list_head(&This->elements);
|
|
|
|
|
|
|
|
while (count < celt && This->current && This->current != &This->elements)
|
|
|
|
count++;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* enumx_Reset
|
|
|
|
*/
|
|
|
|
HRESULT WINAPI enumx_Reset(enumx_impl *This)
|
|
|
|
{
|
|
|
|
TRACE("\n");
|
|
|
|
|
|
|
|
This->current = NULL;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* enumx_fnClone
|
|
|
|
*/
|
|
|
|
HRESULT WINAPI enumx_Clone(
|
|
|
|
enumx_impl *iface,
|
|
|
|
enumx_impl **ppenum)
|
|
|
|
{
|
|
|
|
FIXME("\n");
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* enumx_allocate
|
|
|
|
*
|
|
|
|
* Allocate a generic enumerator
|
|
|
|
*/
|
2018-03-20 11:38:17 +00:00
|
|
|
enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size,
|
|
|
|
IUnknown *parent, enumx_copy_cb copy_cb)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
|
|
|
enumx_impl *enumx;
|
|
|
|
|
|
|
|
enumx = HeapAlloc(GetProcessHeap(), 0, sizeof *enumx);
|
|
|
|
if (enumx)
|
|
|
|
{
|
|
|
|
enumx->vtbl = vtbl;
|
|
|
|
enumx->ref = 1;
|
|
|
|
enumx->current = NULL;
|
|
|
|
enumx->elem_size = elem_size;
|
2008-07-10 09:14:19 +00:00
|
|
|
enumx->riid = *riid;
|
2018-03-20 11:38:17 +00:00
|
|
|
enumx->parent = parent;
|
|
|
|
enumx->copy_cb = copy_cb;
|
|
|
|
|
|
|
|
IUnknown_AddRef(parent);
|
|
|
|
|
2007-04-20 12:23:52 +00:00
|
|
|
list_init(&enumx->elements);
|
|
|
|
}
|
|
|
|
|
|
|
|
return enumx;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
* enumx_add_element
|
|
|
|
*
|
|
|
|
* Add an element to the enumeration.
|
|
|
|
*/
|
2007-07-27 09:49:52 +00:00
|
|
|
void *enumx_add_element(enumx_impl *enumx, const void *data)
|
2007-04-20 12:23:52 +00:00
|
|
|
{
|
|
|
|
struct list *element;
|
|
|
|
|
|
|
|
element = HeapAlloc(GetProcessHeap(), 0, sizeof *element + enumx->elem_size);
|
|
|
|
if (!element)
|
|
|
|
return NULL;
|
|
|
|
memcpy(&element[1], data, enumx->elem_size);
|
|
|
|
list_add_tail(&enumx->elements, element);
|
|
|
|
return &element[1];
|
|
|
|
}
|