807 lines
25 KiB
C
807 lines
25 KiB
C
/*
|
|
* Monikers
|
|
*
|
|
* Copyright 1998 Marcus Meissner
|
|
* Copyright 1999 Noomen Hamza
|
|
*
|
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* TODO:
|
|
* - IRunningObjectTable should work interprocess, but currently doesn't.
|
|
* Native (on Win2k at least) uses an undocumented RPC interface, IROT, to
|
|
* communicate with RPCSS which contains the table of marshalled data.
|
|
* - IRunningObjectTable should use marshalling instead of simple ref
|
|
* counting as there is the possibility of using the running object table
|
|
* to access objects in other apartments.
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
|
|
#define COBJMACROS
|
|
|
|
#include "winerror.h"
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "winuser.h"
|
|
#include "wtypes.h"
|
|
#include "wine/debug.h"
|
|
#include "ole2.h"
|
|
|
|
#include "compobj_private.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
|
|
|
#define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
|
|
|
|
/* define the structure of the running object table elements */
|
|
typedef struct RunObject{
|
|
|
|
IUnknown* pObj; /* points on a running object*/
|
|
IMoniker* pmkObj; /* points on a moniker who identifies this object */
|
|
FILETIME lastModifObj;
|
|
DWORD identRegObj; /* registration key relative to this object */
|
|
DWORD regTypeObj; /* registration type : strong or weak */
|
|
}RunObject;
|
|
|
|
/* define the RunningObjectTableImpl structure */
|
|
typedef struct RunningObjectTableImpl{
|
|
|
|
IRunningObjectTableVtbl *lpVtbl;
|
|
ULONG ref;
|
|
|
|
RunObject* runObjTab; /* pointer to the first object in the table */
|
|
DWORD runObjTabSize; /* current table size */
|
|
DWORD runObjTabLastIndx; /* first free index element in the table. */
|
|
DWORD runObjTabRegister; /* registration key of the next registered object */
|
|
|
|
} RunningObjectTableImpl;
|
|
|
|
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
|
|
*/
|
|
static HRESULT WINAPI
|
|
RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,
|
|
REFIID riid,void** ppvObject)
|
|
{
|
|
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
|
|
|
TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
|
|
|
|
/* validate arguments */
|
|
if (This==0)
|
|
return CO_E_NOTINITIALIZED;
|
|
|
|
if (ppvObject==0)
|
|
return E_INVALIDARG;
|
|
|
|
*ppvObject = 0;
|
|
|
|
if (IsEqualIID(&IID_IUnknown, riid) ||
|
|
IsEqualIID(&IID_IRunningObjectTable, riid))
|
|
*ppvObject = (IRunningObjectTable*)This;
|
|
|
|
if ((*ppvObject)==0)
|
|
return E_NOINTERFACE;
|
|
|
|
IRunningObjectTable_AddRef(iface);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_AddRef
|
|
*/
|
|
static ULONG WINAPI
|
|
RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
|
|
{
|
|
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
|
|
|
TRACE("(%p)\n",This);
|
|
|
|
return InterlockedIncrement(&This->ref);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_Initialize
|
|
*/
|
|
static HRESULT WINAPI
|
|
RunningObjectTableImpl_Destroy(void)
|
|
{
|
|
TRACE("()\n");
|
|
|
|
if (runningObjectTableInstance==NULL)
|
|
return E_INVALIDARG;
|
|
|
|
/* free the ROT table memory */
|
|
HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
|
|
|
|
/* free the ROT structure memory */
|
|
HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
|
|
runningObjectTableInstance = NULL;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_Release
|
|
*/
|
|
static ULONG WINAPI
|
|
RunningObjectTableImpl_Release(IRunningObjectTable* iface)
|
|
{
|
|
DWORD i;
|
|
RunningObjectTableImpl *This = (RunningObjectTableImpl *)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 */
|
|
for(i=0;i<This->runObjTabLastIndx;i++)
|
|
{
|
|
if (( This->runObjTab[i].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
|
|
IUnknown_Release(This->runObjTab[i].pObj);
|
|
|
|
IMoniker_Release(This->runObjTab[i].pmkObj);
|
|
}
|
|
/* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
|
|
* when RunningObjectTableImpl_UnInitialize function is called
|
|
*/
|
|
|
|
/* there's no more elements in the table */
|
|
This->runObjTabRegister=0;
|
|
This->runObjTabLastIndx=0;
|
|
}
|
|
|
|
return ref;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_Register
|
|
*
|
|
* PARAMS
|
|
* grfFlags [in] Registration options
|
|
* punkObject [in] the object being registered
|
|
* pmkObjectName [in] the moniker of the object being registered
|
|
* pdwRegister [in] the value identifying the registration
|
|
*/
|
|
static HRESULT WINAPI
|
|
RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,
|
|
IUnknown *punkObject, IMoniker *pmkObjectName, DWORD *pdwRegister)
|
|
{
|
|
HRESULT res=S_OK;
|
|
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
|
|
|
TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
|
|
|
|
/*
|
|
* there's only two types of register : strong and or weak registration
|
|
* (only one must be passed on parameter)
|
|
*/
|
|
if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
|
|
(!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
|
|
(grfFlags) )
|
|
return E_INVALIDARG;
|
|
|
|
if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
|
|
return E_INVALIDARG;
|
|
|
|
/* verify if the object to be registered was registered before */
|
|
if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
|
|
res = MK_S_MONIKERALREADYREGISTERED;
|
|
|
|
/* put the new registered object in the first free element in the table */
|
|
This->runObjTab[This->runObjTabLastIndx].pObj = punkObject;
|
|
This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName;
|
|
This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags;
|
|
This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister;
|
|
CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj));
|
|
|
|
/* gives a registration identifier to the registered object*/
|
|
(*pdwRegister)= This->runObjTabRegister;
|
|
|
|
if (This->runObjTabRegister == 0xFFFFFFFF){
|
|
|
|
FIXME("runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister);
|
|
return E_FAIL;
|
|
}
|
|
This->runObjTabRegister++;
|
|
This->runObjTabLastIndx++;
|
|
|
|
if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */
|
|
|
|
This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */
|
|
This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab,
|
|
This->runObjTabSize * sizeof(RunObject));
|
|
if (!This->runObjTab)
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
/* add a reference to the object in the strong registration case */
|
|
if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 ) {
|
|
TRACE("strong registration, reffing %p\n", punkObject);
|
|
/* this is wrong; we should always add a reference to the object */
|
|
IUnknown_AddRef(punkObject);
|
|
}
|
|
|
|
IMoniker_AddRef(pmkObjectName);
|
|
|
|
return res;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_Revoke
|
|
*
|
|
* PARAMS
|
|
* dwRegister [in] Value identifying registration to be revoked
|
|
*/
|
|
static HRESULT WINAPI
|
|
RunningObjectTableImpl_Revoke( IRunningObjectTable* iface, DWORD dwRegister)
|
|
{
|
|
|
|
DWORD index,j;
|
|
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
|
|
|
TRACE("(%p,%ld)\n",This,dwRegister);
|
|
|
|
/* verify if the object to be revoked was registered before or not */
|
|
if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
/* release the object if it was registered with a strong registrantion option */
|
|
if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0) {
|
|
TRACE("releasing %p\n", This->runObjTab[index].pObj);
|
|
/* this is also wrong; we should always release the object (see above) */
|
|
IUnknown_Release(This->runObjTab[index].pObj);
|
|
}
|
|
|
|
IMoniker_Release(This->runObjTab[index].pmkObj);
|
|
|
|
/* remove the object from the table */
|
|
for(j=index; j<This->runObjTabLastIndx-1; j++)
|
|
This->runObjTab[j]= This->runObjTab[j+1];
|
|
|
|
This->runObjTabLastIndx--;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_IsRunning
|
|
*
|
|
* PARAMS
|
|
* pmkObjectName [in] moniker of the object whose status is desired
|
|
*/
|
|
static HRESULT WINAPI
|
|
RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface, IMoniker *pmkObjectName)
|
|
{
|
|
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
|
|
|
TRACE("(%p,%p)\n",This,pmkObjectName);
|
|
|
|
return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_GetObject
|
|
*
|
|
* PARAMS
|
|
* pmkObjectName [in] Pointer to the moniker on the object
|
|
* ppunkObject [out] variable that receives the IUnknown interface pointer
|
|
*/
|
|
static HRESULT WINAPI
|
|
RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
|
|
IMoniker *pmkObjectName, IUnknown **ppunkObject)
|
|
{
|
|
DWORD index;
|
|
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
|
|
|
TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
|
|
|
|
if (ppunkObject==NULL)
|
|
return E_POINTER;
|
|
|
|
*ppunkObject=0;
|
|
|
|
/* verify if the object was registered before or not */
|
|
if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE) {
|
|
WARN("Moniker unavailable - needs to work interprocess?\n");
|
|
return MK_E_UNAVAILABLE;
|
|
}
|
|
|
|
/* add a reference to the object then set output object argument */
|
|
IUnknown_AddRef(This->runObjTab[index].pObj);
|
|
*ppunkObject=This->runObjTab[index].pObj;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_NoteChangeTime
|
|
*
|
|
* PARAMS
|
|
* dwRegister [in] Value identifying registration being updated
|
|
* pfiletime [in] Pointer to structure containing object's last change time
|
|
*/
|
|
static HRESULT WINAPI
|
|
RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
|
|
DWORD dwRegister, FILETIME *pfiletime)
|
|
{
|
|
DWORD index=-1;
|
|
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
|
|
|
TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);
|
|
|
|
/* verify if the object to be changed was registered before or not */
|
|
if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
|
|
return E_INVALIDARG;
|
|
|
|
/* set the new value of the last time change */
|
|
This->runObjTab[index].lastModifObj= (*pfiletime);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_GetTimeOfLastChange
|
|
*
|
|
* PARAMS
|
|
* pmkObjectName [in] moniker of the object whose status is desired
|
|
* pfiletime [out] structure that receives object's last change time
|
|
*/
|
|
static HRESULT WINAPI
|
|
RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
|
|
IMoniker *pmkObjectName, FILETIME *pfiletime)
|
|
{
|
|
DWORD index=-1;
|
|
RunningObjectTableImpl *This = (RunningObjectTableImpl *)iface;
|
|
|
|
TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
|
|
|
|
if (pmkObjectName==NULL || pfiletime==NULL)
|
|
return E_INVALIDARG;
|
|
|
|
/* verify if the object was registered before or not */
|
|
if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
|
|
return MK_E_UNAVAILABLE;
|
|
|
|
(*pfiletime)= This->runObjTab[index].lastModifObj;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_EnumRunning
|
|
*
|
|
* PARAMS
|
|
* ppenumMoniker [out] receives the IEnumMoniker interface pointer
|
|
*/
|
|
static HRESULT WINAPI
|
|
RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
|
|
IEnumMoniker **ppenumMoniker)
|
|
{
|
|
/* 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;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* GetObjectIndex
|
|
*/
|
|
static HRESULT WINAPI
|
|
RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
|
|
DWORD identReg, IMoniker* pmk, DWORD *indx)
|
|
{
|
|
|
|
DWORD i;
|
|
|
|
TRACE("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);
|
|
|
|
if (pmk!=NULL)
|
|
/* search object identified by a moniker */
|
|
for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
|
|
else
|
|
/* search object identified by a register identifier */
|
|
for(i=0;((i<This->runObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++);
|
|
|
|
if (i==This->runObjTabLastIndx) return S_FALSE;
|
|
|
|
if (indx != NULL) *indx=i;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* GetRunningObjectTable (OLE2.30)
|
|
*/
|
|
HRESULT WINAPI
|
|
GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
|
|
{
|
|
FIXME("(%ld,%p),stub!\n",reserved,pprot);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* GetRunningObjectTable (OLE32.@)
|
|
*/
|
|
HRESULT WINAPI
|
|
GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
|
|
{
|
|
IID riid=IID_IRunningObjectTable;
|
|
HRESULT res;
|
|
|
|
TRACE("()\n");
|
|
|
|
if (reserved!=0)
|
|
return E_UNEXPECTED;
|
|
|
|
if(runningObjectTableInstance==NULL)
|
|
return CO_E_NOTINITIALIZED;
|
|
|
|
res = IRunningObjectTable_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
|
|
|
|
return res;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* OleRun [OLE32.@]
|
|
*/
|
|
HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
|
|
{
|
|
IRunnableObject *runable;
|
|
IRunnableObject *This = (IRunnableObject *)pUnknown;
|
|
LRESULT ret;
|
|
|
|
ret = IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable);
|
|
if (ret)
|
|
return 0; /* Appears to return no error. */
|
|
ret = IRunnableObject_Run(runable,NULL);
|
|
IRunnableObject_Release(runable);
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* MkParseDisplayName [OLE32.@]
|
|
*/
|
|
HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szUserName,
|
|
LPDWORD pchEaten, LPMONIKER *ppmk)
|
|
{
|
|
FIXME("(%p, %s, %p, %p): stub.\n", pbc, debugstr_w(szUserName), pchEaten, *ppmk);
|
|
|
|
if (!(IsValidInterface((LPUNKNOWN) pbc)))
|
|
return E_INVALIDARG;
|
|
|
|
return MK_E_SYNTAX;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* CreateClassMoniker [OLE32.@]
|
|
*/
|
|
HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, IMoniker ** ppmk)
|
|
{
|
|
FIXME("%s\n", debugstr_guid( rclsid ));
|
|
if( ppmk )
|
|
*ppmk = NULL;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/* Virtual function table for the IRunningObjectTable class. */
|
|
static IRunningObjectTableVtbl VT_RunningObjectTableImpl =
|
|
{
|
|
RunningObjectTableImpl_QueryInterface,
|
|
RunningObjectTableImpl_AddRef,
|
|
RunningObjectTableImpl_Release,
|
|
RunningObjectTableImpl_Register,
|
|
RunningObjectTableImpl_Revoke,
|
|
RunningObjectTableImpl_IsRunning,
|
|
RunningObjectTableImpl_GetObject,
|
|
RunningObjectTableImpl_NoteChangeTime,
|
|
RunningObjectTableImpl_GetTimeOfLastChange,
|
|
RunningObjectTableImpl_EnumRunning
|
|
};
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_Initialize
|
|
*/
|
|
HRESULT WINAPI RunningObjectTableImpl_Initialize(void)
|
|
{
|
|
TRACE("\n");
|
|
|
|
/* create the unique instance of the RunningObjectTableImpl structure */
|
|
runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));
|
|
|
|
if (runningObjectTableInstance == 0)
|
|
return E_OUTOFMEMORY;
|
|
|
|
/* initialize the virtual table function */
|
|
runningObjectTableInstance->lpVtbl = &VT_RunningObjectTableImpl;
|
|
|
|
/* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
|
|
/* the ROT referred many times not in the same time (all the objects in the ROT will */
|
|
/* be removed every time the ROT is removed ) */
|
|
runningObjectTableInstance->ref = 1;
|
|
|
|
/* allocate space memory for the table which contains all the running objects */
|
|
runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));
|
|
|
|
if (runningObjectTableInstance->runObjTab == NULL)
|
|
return E_OUTOFMEMORY;
|
|
|
|
runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
|
|
runningObjectTableInstance->runObjTabRegister=1;
|
|
runningObjectTableInstance->runObjTabLastIndx=0;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_UnInitialize
|
|
*/
|
|
HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
|
|
{
|
|
TRACE("\n");
|
|
|
|
if (runningObjectTableInstance==NULL)
|
|
return E_POINTER;
|
|
|
|
RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
|
|
|
|
RunningObjectTableImpl_Destroy();
|
|
|
|
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;
|
|
}
|