mirror of
https://github.com/reactos/wine.git
synced 2024-11-24 20:30:01 +00:00
359f497e97
Stridvall.
476 lines
17 KiB
C
476 lines
17 KiB
C
/*
|
|
* Monikers
|
|
*
|
|
* Copyright 1998 Marcus Meissner
|
|
* Copyright 1999 Noomen Hamza
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include "winerror.h"
|
|
#include "wine/obj_moniker.h"
|
|
#include "debugtools.h"
|
|
#include "heap.h"
|
|
|
|
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 de RunningObjectTableImpl structure */
|
|
typedef struct RunningObjectTableImpl{
|
|
|
|
ICOM_VTABLE(IRunningObjectTable)* lpvtbl;
|
|
ULONG ref;
|
|
|
|
RunObject* runObjTab; /* pointe 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 registred object */
|
|
|
|
} RunningObjectTableImpl;
|
|
|
|
RunningObjectTableImpl* runningObjectTableInstance=0;
|
|
|
|
/* IRunningObjectTable prototipe functions : */
|
|
/* IUnknown functions*/
|
|
static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject);
|
|
static ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface);
|
|
static ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface);
|
|
/* IRunningObjectTable functions */
|
|
static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister);
|
|
static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister);
|
|
static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName);
|
|
static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject);
|
|
static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime);
|
|
static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime);
|
|
static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker);
|
|
/* Local functions*/
|
|
HRESULT WINAPI RunningObjectTableImpl_Initialize();
|
|
HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
|
|
HRESULT WINAPI RunningObjectTableImpl_Destroy();
|
|
HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);
|
|
|
|
/* Virtual function table for the IRunningObjectTable class. */
|
|
static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl =
|
|
{
|
|
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
|
RunningObjectTableImpl_QueryInterface,
|
|
RunningObjectTableImpl_AddRef,
|
|
RunningObjectTableImpl_Release,
|
|
RunningObjectTableImpl_Register,
|
|
RunningObjectTableImpl_Revoke,
|
|
RunningObjectTableImpl_IsRunning,
|
|
RunningObjectTableImpl_GetObject,
|
|
RunningObjectTableImpl_NoteChangeTime,
|
|
RunningObjectTableImpl_GetTimeOfLastChange,
|
|
RunningObjectTableImpl_EnumRunning
|
|
};
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_QueryInterface
|
|
*/
|
|
HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
|
|
{
|
|
ICOM_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))
|
|
*ppvObject = (IRunningObjectTable*)This;
|
|
else
|
|
if (IsEqualIID(&IID_IRunningObjectTable, riid))
|
|
*ppvObject = (IRunningObjectTable*)This;
|
|
|
|
if ((*ppvObject)==0)
|
|
return E_NOINTERFACE;
|
|
|
|
RunningObjectTableImpl_AddRef(iface);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_AddRef
|
|
*/
|
|
ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
|
|
{
|
|
ICOM_THIS(RunningObjectTableImpl,iface);
|
|
|
|
TRACE("(%p)\n",This);
|
|
|
|
return ++(This->ref);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_Initialize
|
|
*/
|
|
HRESULT WINAPI RunningObjectTableImpl_Destroy()
|
|
{
|
|
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);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_Release
|
|
*/
|
|
ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
|
|
{
|
|
DWORD i;
|
|
ICOM_THIS(RunningObjectTableImpl,iface);
|
|
|
|
TRACE("(%p)\n",This);
|
|
|
|
This->ref--;
|
|
|
|
/* unitialize ROT structure if there's no more reference to it*/
|
|
if (This->ref==0){
|
|
|
|
/* release all registred 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 0;
|
|
}
|
|
|
|
return This->ref;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_Initialize
|
|
*/
|
|
HRESULT WINAPI RunningObjectTableImpl_Initialize()
|
|
{
|
|
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 refered many times not in the same time (all the objects in the ROT will */
|
|
/* be removed evry time the ROT is removed ) */
|
|
runningObjectTableInstance->ref = 1;
|
|
|
|
/* allocate space memory for the table witch 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=0;
|
|
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;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_Register
|
|
*/
|
|
HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface,
|
|
DWORD grfFlags, /* Registration options */
|
|
IUnknown *punkObject, /* Pointer to the object being registered */
|
|
IMoniker *pmkObjectName, /* Pointer to the moniker of the object being registered */
|
|
DWORD *pdwRegister) /* Pointer to the value identifying the registration */
|
|
{
|
|
HRESULT res=S_OK;
|
|
ICOM_THIS(RunningObjectTableImpl,iface);
|
|
|
|
TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
|
|
|
|
/* there's only tow 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 registred was registred befor */
|
|
if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
|
|
res = MK_S_MONIKERALREADYREGISTERED;
|
|
|
|
/* put the new registred 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 registred 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 )
|
|
IUnknown_AddRef(punkObject);
|
|
|
|
IMoniker_AddRef(pmkObjectName);
|
|
|
|
return res;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_Revoke
|
|
*/
|
|
HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface,
|
|
DWORD dwRegister) /* Value identifying registration to be revoked*/
|
|
{
|
|
|
|
DWORD index,j;
|
|
ICOM_THIS(RunningObjectTableImpl,iface);
|
|
|
|
TRACE("(%p,%ld)\n",This,dwRegister);
|
|
|
|
/* verify if the object to be revoked was registred befor or not */
|
|
if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
/* release the object if it was registred with a strong registrantion option */
|
|
if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0)
|
|
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
|
|
*/
|
|
HRESULT WINAPI RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface,
|
|
IMoniker *pmkObjectName) /* Pointer to the moniker of the object whose status is desired */
|
|
{
|
|
ICOM_THIS(RunningObjectTableImpl,iface);
|
|
|
|
TRACE("(%p,%p)\n",This,pmkObjectName);
|
|
|
|
return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
|
|
}
|
|
|
|
/***********************************************************************
|
|
* RunningObjectTable_GetObject
|
|
*/
|
|
HRESULT WINAPI RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
|
|
IMoniker *pmkObjectName,/* Pointer to the moniker on the object */
|
|
IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */
|
|
{
|
|
DWORD index;
|
|
ICOM_THIS(RunningObjectTableImpl,iface);
|
|
|
|
TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
|
|
|
|
if (ppunkObject==NULL)
|
|
return E_POINTER;
|
|
|
|
*ppunkObject=0;
|
|
|
|
/* verify if the object was registred befor or not */
|
|
if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
|
|
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
|
|
*/
|
|
HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
|
|
DWORD dwRegister, /* Value identifying registration being updated */
|
|
FILETIME *pfiletime) /* Pointer to structure containing object's last change time */
|
|
{
|
|
DWORD index=-1;
|
|
ICOM_THIS(RunningObjectTableImpl,iface);
|
|
|
|
TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);
|
|
|
|
/* verify if the object to be changed was registred befor 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
|
|
*/
|
|
HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
|
|
IMoniker *pmkObjectName, /* Pointer to moniker on the object whose status is desired */
|
|
FILETIME *pfiletime) /* Pointer to structure that receives object's last change time */
|
|
{
|
|
DWORD index=-1;
|
|
ICOM_THIS(RunningObjectTableImpl,iface);
|
|
|
|
TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
|
|
|
|
if (pmkObjectName==NULL || pfiletime==NULL)
|
|
return E_INVALIDARG;
|
|
|
|
/* verify if the object was registred befor 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
|
|
*/
|
|
HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
|
|
IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
|
|
{
|
|
FIXME("(%p,%p) needs the IEnumMoniker implementation \n",iface,ppenumMoniker);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* GetObjectIndex
|
|
*/
|
|
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;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* GetRunningObjectTable16 [OLE2.30]
|
|
*/
|
|
HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
|
|
{
|
|
FIXME("(%ld,%p),stub!\n",reserved,pprot);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* GetRunningObjectTable (OLE2.73)
|
|
*/
|
|
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 = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
|
|
|
|
return res;
|
|
}
|