Implement the IEnumMoniker interface for the ROT and provide tests to
exercise the interface.
This commit is contained in:
parent
7364f0a79c
commit
72f73ac452
|
@ -74,6 +74,26 @@ static RunningObjectTableImpl* runningObjectTableInstance = NULL;
|
||||||
|
|
||||||
static HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl*,DWORD,IMoniker*,DWORD *);
|
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
|
* RunningObjectTable_QueryInterface
|
||||||
*/
|
*/
|
||||||
|
@ -401,8 +421,18 @@ static HRESULT WINAPI
|
||||||
RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
|
RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
|
||||||
IEnumMoniker **ppenumMoniker)
|
IEnumMoniker **ppenumMoniker)
|
||||||
{
|
{
|
||||||
FIXME("(%p,%p) needs the IEnumMoniker implementation \n",iface,ppenumMoniker);
|
/* create the unique instance of the EnumMonkikerImpl structure
|
||||||
return E_NOTIMPL;
|
* 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;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -36,12 +36,32 @@ static void test_MkParseDisplayName()
|
||||||
{
|
{
|
||||||
IBindCtx * pbc = NULL;
|
IBindCtx * pbc = NULL;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
IMoniker * pmk = NULL;
|
IMoniker * pmk = NULL;
|
||||||
|
IMoniker * pmk1 = NULL;
|
||||||
|
IMoniker * pmk2 = NULL;
|
||||||
|
IMoniker * ppmk = NULL;
|
||||||
|
IMoniker * spMoniker;
|
||||||
ULONG eaten;
|
ULONG eaten;
|
||||||
|
int monCnt;
|
||||||
IUnknown * object = NULL;
|
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 */
|
/* CLSID of My Computer */
|
||||||
static const WCHAR wszDisplayName[] = {'c','l','s','i','d',':',
|
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};
|
'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);
|
hr = CreateBindCtx(0, &pbc);
|
||||||
ok_ole_success(hr, CreateBindCtx);
|
ok_ole_success(hr, CreateBindCtx);
|
||||||
|
@ -57,6 +77,103 @@ static void test_MkParseDisplayName()
|
||||||
IUnknown_Release(object);
|
IUnknown_Release(object);
|
||||||
}
|
}
|
||||||
IBindCtx_Release(pbc);
|
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[] =
|
static const BYTE expected_moniker_data[] =
|
||||||
|
|
Loading…
Reference in New Issue