Commit 72f73ac4 authored by Jeff Latimer's avatar Jeff Latimer Committed by Alexandre Julliard

Implement the IEnumMoniker interface for the ROT and provide tests to

exercise the interface.
parent 7364f0a7
......@@ -74,6 +74,26 @@ static RunningObjectTableImpl* runningObjectTableInstance = NULL;
static HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl*,DWORD,IMoniker*,DWORD *);
/* define the EnumMonikerImpl structure */
typedef struct EnumMonikerImpl{
IEnumMonikerVtbl *lpVtbl;
ULONG ref;
RunObject* TabMoniker; /* pointer to the first object in the table */
DWORD TabSize; /* current table size */
DWORD TabLastIndx; /* last used index element in the table. */
DWORD TabCurrentPos; /* enum position in the list */
} EnumMonikerImpl;
/* IEnumMoniker Local functions*/
static HRESULT WINAPI EnumMonikerImpl_CreateEnumROTMoniker(RunObject* runObjTab,
ULONG TabSize,
ULONG TabLastIndx,
ULONG TabCurrentPos,
IEnumMoniker ** ppenumMoniker);
/***********************************************************************
* RunningObjectTable_QueryInterface
*/
......@@ -401,8 +421,18 @@ static HRESULT WINAPI
RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
IEnumMoniker **ppenumMoniker)
{
FIXME("(%p,%p) needs the IEnumMoniker implementation \n",iface,ppenumMoniker);
return E_NOTIMPL;
/* create the unique instance of the EnumMonkikerImpl structure
* and copy the Monikers referenced in the ROT so that they can be
* enumerated by the Enum interface
*/
HRESULT rc = 0;
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
rc=EnumMonikerImpl_CreateEnumROTMoniker(This->runObjTab,
This->runObjTabSize,
This->runObjTabLastIndx, 0,
ppenumMoniker);
return rc;
}
/***********************************************************************
......@@ -570,3 +600,207 @@ HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
return S_OK;
}
/***********************************************************************
* EnumMoniker_QueryInterface
*/
static HRESULT WINAPI EnumMonikerImpl_QueryInterface(IEnumMoniker* iface,REFIID riid,void** ppvObject)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
/* validate arguments */
if (ppvObject == NULL)
return E_INVALIDARG;
*ppvObject = NULL;
if (IsEqualIID(&IID_IUnknown, riid))
*ppvObject = (IEnumMoniker*)This;
else
if (IsEqualIID(&IID_IEnumMoniker, riid))
*ppvObject = (IEnumMoniker*)This;
if ((*ppvObject)==NULL)
return E_NOINTERFACE;
IEnumMoniker_AddRef(iface);
return S_OK;
}
/***********************************************************************
* EnumMoniker_AddRef
*/
static ULONG WINAPI EnumMonikerImpl_AddRef(IEnumMoniker* iface)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
TRACE("(%p)\n",This);
return InterlockedIncrement(&This->ref);
}
/***********************************************************************
* EnumMoniker_release
*/
static ULONG WINAPI EnumMonikerImpl_Release(IEnumMoniker* iface)
{
DWORD i;
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
ULONG ref;
TRACE("(%p)\n",This);
ref = InterlockedDecrement(&This->ref);
/* unitialize rot structure if there's no more reference to it*/
if (ref == 0) {
/* release all registered objects in Moniker list */
for(i=0; i < This->TabLastIndx ;i++)
{
IMoniker_Release(This->TabMoniker[i].pmkObj);
}
/* there're no more elements in the table */
TRACE("(%p) Deleting\n",This);
HeapFree (GetProcessHeap(), 0, This->TabMoniker); /* free Moniker list */
HeapFree (GetProcessHeap(), 0, This); /* free Enum Instance */
}
return ref;
}
/***********************************************************************
* EnmumMoniker_Next
*/
static HRESULT WINAPI EnumMonikerImpl_Next(IEnumMoniker* iface, ULONG celt, IMoniker** rgelt, ULONG * pceltFetched)
{
ULONG i;
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
TRACE("(%p) TabCurrentPos %ld Tablastindx %ld\n",This, This->TabCurrentPos, This->TabLastIndx);
/* retrieve the requested number of moniker from the current position */
for(i=0; (This->TabCurrentPos < This->TabLastIndx) && (i < celt); i++)
rgelt[i]=(IMoniker*)This->TabMoniker[This->TabCurrentPos++].pmkObj;
if (pceltFetched!=NULL)
*pceltFetched= i;
if (i==celt)
return S_OK;
else
return S_FALSE;
}
/***********************************************************************
* EnmumMoniker_Skip
*/
static HRESULT WINAPI EnumMonikerImpl_Skip(IEnumMoniker* iface, ULONG celt)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
TRACE("(%p)\n",This);
if (This->TabCurrentPos+celt >= This->TabLastIndx)
return S_FALSE;
This->TabCurrentPos+=celt;
return S_OK;
}
/***********************************************************************
* EnmumMoniker_Reset
*/
static HRESULT WINAPI EnumMonikerImpl_Reset(IEnumMoniker* iface)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
This->TabCurrentPos = 0; /* set back to start of list */
TRACE("(%p)\n",This);
return S_OK;
}
/***********************************************************************
* EnmumMoniker_Clone
*/
static HRESULT WINAPI EnumMonikerImpl_Clone(IEnumMoniker* iface, IEnumMoniker ** ppenum)
{
EnumMonikerImpl *This = (EnumMonikerImpl *)iface;
TRACE("(%p)\n",This);
/* copy the enum structure */
return EnumMonikerImpl_CreateEnumROTMoniker(This->TabMoniker, This->TabSize,
This->TabLastIndx, This->TabCurrentPos,
ppenum);
}
/* Virtual function table for the IEnumMoniker class. */
static IEnumMonikerVtbl VT_EnumMonikerImpl =
{
EnumMonikerImpl_QueryInterface,
EnumMonikerImpl_AddRef,
EnumMonikerImpl_Release,
EnumMonikerImpl_Next,
EnumMonikerImpl_Skip,
EnumMonikerImpl_Reset,
EnumMonikerImpl_Clone
};
/***********************************************************************
* EnumMonikerImpl_CreateEnumROTMoniker
* Used by EnumRunning to create the structure and EnumClone
* to copy the structure
*/
HRESULT WINAPI EnumMonikerImpl_CreateEnumROTMoniker(RunObject* TabMoniker,
ULONG TabSize,
ULONG TabLastIndx,
ULONG TabCurrentPos,
IEnumMoniker ** ppenumMoniker)
{
int i;
EnumMonikerImpl* This = NULL;
if (TabCurrentPos > TabSize)
return E_INVALIDARG;
if (ppenumMoniker == NULL)
return E_INVALIDARG;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl));
if (!ppenumMoniker) return E_OUTOFMEMORY;
TRACE("(%p)\n", This);
/* initialize the virtual table function */
This->lpVtbl = &VT_EnumMonikerImpl;
/* the initial reference is set to "1" */
This->ref = 1; /* set the ref count to one */
This->TabCurrentPos=0; /* Set the list start posn to start */
This->TabSize=TabSize; /* Need the same size table as ROT */
This->TabLastIndx=TabLastIndx; /* end element */
This->TabMoniker=HeapAlloc(GetProcessHeap(),0,This->TabSize*sizeof(RunObject));
if (This->TabMoniker==NULL) {
HeapFree(GetProcessHeap(), 0, This);
return E_OUTOFMEMORY;
}
for (i=0; i < This->TabLastIndx; i++){
This->TabMoniker[i]=TabMoniker[i];
IMoniker_AddRef(TabMoniker[i].pmkObj);
}
*ppenumMoniker = (IEnumMoniker*)This;
return S_OK;
}
......@@ -37,11 +37,31 @@ static void test_MkParseDisplayName()
IBindCtx * pbc = NULL;
HRESULT hr;
IMoniker * pmk = NULL;
IMoniker * pmk1 = NULL;
IMoniker * pmk2 = NULL;
IMoniker * ppmk = NULL;
IMoniker * spMoniker;
ULONG eaten;
int monCnt;
IUnknown * object = NULL;
IUnknown *lpEM1;
IEnumMoniker *spEM1 = NULL;
IEnumMoniker *spEM2 = NULL;
IEnumMoniker *spEM3 = NULL;
DWORD pdwReg1=0;
DWORD grflags=0;
DWORD pdwReg2=0;
IRunningObjectTable * pprot=NULL;
/* CLSID of My Computer */
static const WCHAR wszDisplayName[] = {'c','l','s','i','d',':',
'2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8','-','0','8','0','0','2','B','3','0','3','0','9','D',':',0};
static const WCHAR wszFileName1[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','1','.','d','o','c',0};
static const WCHAR wszFileName2[] = {'c',':','\\','w','i','n','d','o','w','s','\\','t','e','s','t','2','.','d','o','c',0};
WCHAR * szDisplayn;
hr = CreateBindCtx(0, &pbc);
ok_ole_success(hr, CreateBindCtx);
......@@ -57,6 +77,103 @@ static void test_MkParseDisplayName()
IUnknown_Release(object);
}
IBindCtx_Release(pbc);
/* Test the EnumMoniker interface */
hr = CreateBindCtx(0, &pbc);
ok_ole_success(hr, CreateBindCtx);
hr = CreateFileMoniker(wszFileName1, &pmk1);
ok(hr==0, "CreateFileMoniker for file hr=%08lx\n", hr);
hr = CreateFileMoniker(wszFileName2, &pmk2);
ok(hr==0, "CreateFileMoniker for file hr=%08lx\n", hr);
hr = IBindCtx_GetRunningObjectTable(pbc, &pprot);
ok(hr==0, "IBindCtx_GetRunningObjectTable hr=%08lx\n", hr);
/* Check EnumMoniker before registering */
hr = IRunningObjectTable_EnumRunning(pprot, &spEM1);
ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08lx\n", hr);
hr = IEnumMoniker_QueryInterface(spEM1, &IID_IUnknown, (void*) &lpEM1);
/* Register a couple of Monikers and check is ok */
ok(hr==0, "IEnumMoniker_QueryInterface hr %08lx %p\n", hr, lpEM1);
hr = MK_E_NOOBJECT;
monCnt = 0;
while ((IEnumMoniker_Next(spEM1, 1, &spMoniker, NULL)==S_OK) &&
(ppmk ==NULL))
{
monCnt++;
szDisplayn=NULL;
hr=IMoniker_GetDisplayName(spMoniker, pbc, NULL,
(LPOLESTR*) &szDisplayn);
/* szDisplayn needs to be freed by
* IMalloc_Free hence the use of
* CoGetMalloc */
if (SUCCEEDED(hr))
{
CoTaskMemFree(szDisplayn);
}
}
ok(monCnt==0, "Number of monikers should be equal to 0 not %i\n", monCnt); grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk1, &pdwReg1);
ok(hr==0, "IRunningObjectTable_Register hr=%08lx %p %08lx %p %p %ld\n",
hr, pprot, grflags, lpEM1, pmk1, pdwReg1);
grflags=0;
grflags= grflags | ROTFLAGS_REGISTRATIONKEEPSALIVE;
hr = IRunningObjectTable_Register(pprot, grflags, lpEM1, pmk2, &pdwReg2);
ok(hr==0, "IRunningObjectTable_Register hr=%08lx %p %08lx %p %p %ld\n", hr,
pprot, grflags, lpEM1, pmk2, pdwReg2);
hr = IRunningObjectTable_EnumRunning(pprot, &spEM2);
ok(hr==0, "IRunningObjectTable_EnumRunning hr=%08lx\n", hr);
monCnt=0;
while ((IEnumMoniker_Next(spEM2, 1, &spMoniker, NULL)==S_OK) &&
(ppmk ==NULL))
{
WCHAR *szDisplayn=NULL;
monCnt++;
hr=IMoniker_GetDisplayName(spMoniker, pbc, NULL,
(LPOLESTR*) &szDisplayn);
/* szDisplayn needs to be freed by
* IMalloc_Free hence the use of
* CoGetMalloc */
if (SUCCEEDED(hr))
{
CoTaskMemFree(szDisplayn);
}
}
ok(monCnt==2, "Number of monikers should be equal to 2 not %i\n", monCnt);
IEnumMoniker_Clone(spEM2, &spEM3);
monCnt=0;
while ((IEnumMoniker_Next(spEM3, 1, &spMoniker, NULL)==S_OK) &&
(ppmk ==NULL))
{
WCHAR *szDisplayn=NULL;
monCnt++;
hr=IMoniker_GetDisplayName(spMoniker, pbc, NULL,
(LPOLESTR*) &szDisplayn);
/* szDisplayn needs to be freed by
* IMalloc_Free hence the use of
* CoGetMalloc */
if (SUCCEEDED(hr))
{
CoTaskMemFree(szDisplayn);
}
}
ok(monCnt==2, "Number of monikers should be equal to 2 not %i\n", monCnt);
IRunningObjectTable_Revoke(pprot,pdwReg1);
IRunningObjectTable_Revoke(pprot,pdwReg2);
IEnumMoniker_Release(spEM1);
IEnumMoniker_Release(spEM1);
IEnumMoniker_Release(spEM2);
IEnumMoniker_Release(spEM3);
IMoniker_Release(pmk1);
IMoniker_Release(pmk2);
IRunningObjectTable_Release(pprot);
IBindCtx_Release(pbc);
/* Finished testing EnumMoniker */
}
static const BYTE expected_moniker_data[] =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment