4 * Copyright 1998 Marcus Meissner
5 * Copyright 1999 Noomen Hamza
10 #include "wine/obj_moniker.h"
11 #include "debugtools.h"
14 DEFAULT_DEBUG_CHANNEL(ole
)
16 #define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
18 /* define the structure of the running object table elements */
19 typedef struct RunObject
{
21 IUnknown
* pObj
; /* points on a running object*/
22 IMoniker
* pmkObj
; /* points on a moniker who identifies this object */
23 FILETIME lastModifObj
;
24 DWORD identRegObj
; /* registration key relative to this object */
25 DWORD regTypeObj
; /* registration type : strong or weak */
28 /* define de RunningObjectTableImpl structure */
29 typedef struct RunningObjectTableImpl
{
31 ICOM_VTABLE(IRunningObjectTable
)* lpvtbl
;
34 RunObject
* runObjTab
; /* pointe to the first object in the table */
35 DWORD runObjTabSize
; /* current table size */
36 DWORD runObjTabLastIndx
; /* first free index element in the table. */
37 DWORD runObjTabRegister
; /* registration key of the next registred object */
39 } RunningObjectTableImpl
;
41 RunningObjectTableImpl
* runningObjectTableInstance
=0;
43 /* IRunningObjectTable prototipe functions : */
44 /* IUnknown functions*/
45 static HRESULT WINAPI
RunningObjectTableImpl_QueryInterface(IRunningObjectTable
* iface
,REFIID riid
,void** ppvObject
);
46 static ULONG WINAPI
RunningObjectTableImpl_AddRef(IRunningObjectTable
* iface
);
47 static ULONG WINAPI
RunningObjectTableImpl_Release(IRunningObjectTable
* iface
);
48 /* IRunningObjectTable functions */
49 static HRESULT WINAPI
RunningObjectTableImpl_Register(IRunningObjectTable
* iface
, DWORD grfFlags
,IUnknown
* punkObject
,IMoniker
* pmkObjectName
,DWORD
* pdwRegister
);
50 static HRESULT WINAPI
RunningObjectTableImpl_Revoke(IRunningObjectTable
* iface
, DWORD dwRegister
);
51 static HRESULT WINAPI
RunningObjectTableImpl_IsRunning(IRunningObjectTable
* iface
, IMoniker
* pmkObjectName
);
52 static HRESULT WINAPI
RunningObjectTableImpl_GetObject(IRunningObjectTable
* iface
, IMoniker
* pmkObjectName
,IUnknown
** ppunkObject
);
53 static HRESULT WINAPI
RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable
* iface
, DWORD dwRegister
,FILETIME
* pfiletime
);
54 static HRESULT WINAPI
RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable
* iface
, IMoniker
* pmkObjectName
,FILETIME
* pfiletime
);
55 static HRESULT WINAPI
RunningObjectTableImpl_EnumRunning(IRunningObjectTable
* iface
, IEnumMoniker
** ppenumMoniker
);
57 HRESULT WINAPI
RunningObjectTableImpl_Initialize();
58 HRESULT WINAPI
RunningObjectTableImpl_UnInitialize();
59 HRESULT WINAPI
RunningObjectTableImpl_Destroy();
60 HRESULT WINAPI
RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl
* This
,DWORD identReg
,IMoniker
* pmk
,DWORD
*indx
);
62 /* Virtual function table for the IRunningObjectTable class. */
63 static ICOM_VTABLE(IRunningObjectTable
) VT_RunningObjectTableImpl
=
65 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
66 RunningObjectTableImpl_QueryInterface
,
67 RunningObjectTableImpl_AddRef
,
68 RunningObjectTableImpl_Release
,
69 RunningObjectTableImpl_Register
,
70 RunningObjectTableImpl_Revoke
,
71 RunningObjectTableImpl_IsRunning
,
72 RunningObjectTableImpl_GetObject
,
73 RunningObjectTableImpl_NoteChangeTime
,
74 RunningObjectTableImpl_GetTimeOfLastChange
,
75 RunningObjectTableImpl_EnumRunning
78 /***********************************************************************
79 * RunningObjectTable_QueryInterface
81 HRESULT WINAPI
RunningObjectTableImpl_QueryInterface(IRunningObjectTable
* iface
,REFIID riid
,void** ppvObject
)
83 ICOM_THIS(RunningObjectTableImpl
,iface
);
85 TRACE("(%p,%p,%p)\n",This
,riid
,ppvObject
);
87 /* validate arguments*/
89 return CO_E_NOTINITIALIZED
;
96 if (IsEqualIID(&IID_IUnknown
, riid
))
97 *ppvObject
= (IRunningObjectTable
*)This
;
99 if (IsEqualIID(&IID_IRunningObjectTable
, riid
))
100 *ppvObject
= (IRunningObjectTable
*)This
;
103 return E_NOINTERFACE
;
105 RunningObjectTableImpl_AddRef(iface
);
110 /***********************************************************************
111 * RunningObjectTable_AddRef
113 ULONG WINAPI
RunningObjectTableImpl_AddRef(IRunningObjectTable
* iface
)
115 ICOM_THIS(RunningObjectTableImpl
,iface
);
117 TRACE("(%p)\n",This
);
119 return ++(This
->ref
);
122 /***********************************************************************
123 * RunningObjectTable_Initialize
125 HRESULT WINAPI
RunningObjectTableImpl_Destroy()
129 if (runningObjectTableInstance
==NULL
)
132 /* free the ROT table memory */
133 HeapFree(GetProcessHeap(),0,runningObjectTableInstance
->runObjTab
);
135 /* free the ROT structure memory */
136 HeapFree(GetProcessHeap(),0,runningObjectTableInstance
);
141 /***********************************************************************
142 * RunningObjectTable_Release
144 ULONG WINAPI
RunningObjectTableImpl_Release(IRunningObjectTable
* iface
)
147 ICOM_THIS(RunningObjectTableImpl
,iface
);
149 TRACE("(%p)\n",This
);
153 /* unitialize ROT structure if there's no more reference to it*/
156 /* release all registred objects */
157 for(i
=0;i
<This
->runObjTabLastIndx
;i
++)
159 if (( This
->runObjTab
[i
].regTypeObj
& ROTFLAGS_REGISTRATIONKEEPSALIVE
) != 0)
160 IUnknown_Release(This
->runObjTab
[i
].pObj
);
162 IMoniker_Release(This
->runObjTab
[i
].pmkObj
);
164 /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
165 * when RunningObjectTableImpl_UnInitialize function is called
168 /* there's no more elements in the table */
169 This
->runObjTabRegister
=0;
170 This
->runObjTabLastIndx
=0;
178 /***********************************************************************
179 * RunningObjectTable_Initialize
181 HRESULT WINAPI
RunningObjectTableImpl_Initialize()
185 /* create the unique instance of the RunningObjectTableImpl structure */
186 runningObjectTableInstance
= HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl
));
188 if (runningObjectTableInstance
== 0)
189 return E_OUTOFMEMORY
;
191 /* initialize the virtual table function */
192 runningObjectTableInstance
->lpvtbl
= &VT_RunningObjectTableImpl
;
194 /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
195 /* the ROT refered many times not in the same time (all the objects in the ROT will */
196 /* be removed evry time the ROT is removed ) */
197 runningObjectTableInstance
->ref
= 1;
199 /* allocate space memory for the table witch contains all the running objects */
200 runningObjectTableInstance
->runObjTab
= HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject
[BLOCK_TAB_SIZE
]));
202 if (runningObjectTableInstance
->runObjTab
== NULL
)
203 return E_OUTOFMEMORY
;
205 runningObjectTableInstance
->runObjTabSize
=BLOCK_TAB_SIZE
;
206 runningObjectTableInstance
->runObjTabRegister
=0;
207 runningObjectTableInstance
->runObjTabLastIndx
=0;
212 /***********************************************************************
213 * RunningObjectTable_UnInitialize
215 HRESULT WINAPI
RunningObjectTableImpl_UnInitialize()
219 if (runningObjectTableInstance
==NULL
)
222 RunningObjectTableImpl_Release((IRunningObjectTable
*)runningObjectTableInstance
);
224 RunningObjectTableImpl_Destroy();
229 /***********************************************************************
230 * RunningObjectTable_Register
232 HRESULT WINAPI
RunningObjectTableImpl_Register(IRunningObjectTable
* iface
,
233 DWORD grfFlags
, /* Registration options */
234 IUnknown
*punkObject
, /* Pointer to the object being registered */
235 IMoniker
*pmkObjectName
, /* Pointer to the moniker of the object being registered */
236 DWORD
*pdwRegister
) /* Pointer to the value identifying the registration */
239 ICOM_THIS(RunningObjectTableImpl
,iface
);
241 TRACE("(%p,%ld,%p,%p,%p)\n",This
,grfFlags
,punkObject
,pmkObjectName
,pdwRegister
);
243 /* there's only tow types of register : strong and or weak registration (only one must be passed on parameter) */
244 if ( ( (grfFlags
& ROTFLAGS_REGISTRATIONKEEPSALIVE
) || !(grfFlags
& ROTFLAGS_ALLOWANYCLIENT
)) &&
245 (!(grfFlags
& ROTFLAGS_REGISTRATIONKEEPSALIVE
) || (grfFlags
& ROTFLAGS_ALLOWANYCLIENT
)) &&
249 if (punkObject
==NULL
|| pmkObjectName
==NULL
|| pdwRegister
==NULL
)
252 /* verify if the object to be registred was registred befor */
253 if (RunningObjectTableImpl_GetObjectIndex(This
,-1,pmkObjectName
,NULL
)==S_OK
)
254 res
= MK_S_MONIKERALREADYREGISTERED
;
256 /* put the new registred object in the first free element in the table */
257 This
->runObjTab
[This
->runObjTabLastIndx
].pObj
= punkObject
;
258 This
->runObjTab
[This
->runObjTabLastIndx
].pmkObj
= pmkObjectName
;
259 This
->runObjTab
[This
->runObjTabLastIndx
].regTypeObj
= grfFlags
;
260 This
->runObjTab
[This
->runObjTabLastIndx
].identRegObj
= This
->runObjTabRegister
;
261 CoFileTimeNow(&(This
->runObjTab
[This
->runObjTabLastIndx
].lastModifObj
));
263 /* gives a registration identifier to the registred object*/
264 (*pdwRegister
)= This
->runObjTabRegister
;
266 if (This
->runObjTabRegister
== 0xFFFFFFFF){
268 FIXME("runObjTabRegister: %ld is out of data limite \n",This
->runObjTabRegister
);
271 This
->runObjTabRegister
++;
272 This
->runObjTabLastIndx
++;
274 if (This
->runObjTabLastIndx
== This
->runObjTabSize
){ /* table is full ! so it must be resized */
276 This
->runObjTabSize
+=BLOCK_TAB_SIZE
; /* newsize table */
277 This
->runObjTab
=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,This
->runObjTab
,
278 This
->runObjTabSize
* sizeof(RunObject
));
279 if (!This
->runObjTab
)
280 return E_OUTOFMEMORY
;
282 /* add a reference to the object in the strong registration case */
283 if ((grfFlags
& ROTFLAGS_REGISTRATIONKEEPSALIVE
) !=0 )
284 IUnknown_AddRef(punkObject
);
286 IMoniker_AddRef(pmkObjectName
);
291 /***********************************************************************
292 * RunningObjectTable_Revoke
294 HRESULT WINAPI
RunningObjectTableImpl_Revoke( IRunningObjectTable
* iface
,
295 DWORD dwRegister
) /* Value identifying registration to be revoked*/
299 ICOM_THIS(RunningObjectTableImpl
,iface
);
301 TRACE("(%p,%ld)\n",This
,dwRegister
);
303 /* verify if the object to be revoked was registred befor or not */
304 if (RunningObjectTableImpl_GetObjectIndex(This
,dwRegister
,NULL
,&index
)==S_FALSE
)
308 /* release the object if it was registred with a strong registrantion option */
309 if ((This
->runObjTab
[index
].regTypeObj
& ROTFLAGS_REGISTRATIONKEEPSALIVE
)!=0)
310 IUnknown_Release(This
->runObjTab
[index
].pObj
);
312 IMoniker_Release(This
->runObjTab
[index
].pmkObj
);
314 /* remove the object from the table */
315 for(j
=index
; j
<This
->runObjTabLastIndx
-1; j
++)
316 This
->runObjTab
[j
]= This
->runObjTab
[j
+1];
318 This
->runObjTabLastIndx
--;
323 /***********************************************************************
324 * RunningObjectTable_IsRunning
326 HRESULT WINAPI
RunningObjectTableImpl_IsRunning( IRunningObjectTable
* iface
,
327 IMoniker
*pmkObjectName
) /* Pointer to the moniker of the object whose status is desired */
329 ICOM_THIS(RunningObjectTableImpl
,iface
);
331 TRACE("(%p,%p)\n",This
,pmkObjectName
);
333 return RunningObjectTableImpl_GetObjectIndex(This
,-1,pmkObjectName
,NULL
);
336 /***********************************************************************
337 * RunningObjectTable_GetObject
339 HRESULT WINAPI
RunningObjectTableImpl_GetObject( IRunningObjectTable
* iface
,
340 IMoniker
*pmkObjectName
,/* Pointer to the moniker on the object */
341 IUnknown
**ppunkObject
) /* Address of output variable that receives the IUnknown interface pointer */
344 ICOM_THIS(RunningObjectTableImpl
,iface
);
346 TRACE("(%p,%p,%p)\n",This
,pmkObjectName
,ppunkObject
);
348 if (ppunkObject
==NULL
)
353 /* verify if the object was registred befor or not */
354 if (RunningObjectTableImpl_GetObjectIndex(This
,-1,pmkObjectName
,&index
)==S_FALSE
)
355 return MK_E_UNAVAILABLE
;
357 /* add a reference to the object then set output object argument */
358 IUnknown_AddRef(This
->runObjTab
[index
].pObj
);
359 *ppunkObject
=This
->runObjTab
[index
].pObj
;
364 /***********************************************************************
365 * RunningObjectTable_NoteChangeTime
367 HRESULT WINAPI
RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable
* iface
,
368 DWORD dwRegister
, /* Value identifying registration being updated */
369 FILETIME
*pfiletime
) /* Pointer to structure containing object's last change time */
372 ICOM_THIS(RunningObjectTableImpl
,iface
);
374 TRACE("(%p,%ld,%p)\n",This
,dwRegister
,pfiletime
);
376 /* verify if the object to be changed was registred befor or not */
377 if (RunningObjectTableImpl_GetObjectIndex(This
,dwRegister
,NULL
,&index
)==S_FALSE
)
380 /* set the new value of the last time change */
381 This
->runObjTab
[index
].lastModifObj
= (*pfiletime
);
386 /***********************************************************************
387 * RunningObjectTable_GetTimeOfLastChange
389 HRESULT WINAPI
RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable
* iface
,
390 IMoniker
*pmkObjectName
, /* Pointer to moniker on the object whose status is desired */
391 FILETIME
*pfiletime
) /* Pointer to structure that receives object's last change time */
394 ICOM_THIS(RunningObjectTableImpl
,iface
);
396 TRACE("(%p,%p,%p)\n",This
,pmkObjectName
,pfiletime
);
398 if (pmkObjectName
==NULL
|| pfiletime
==NULL
)
401 /* verify if the object was registred befor or not */
402 if (RunningObjectTableImpl_GetObjectIndex(This
,-1,pmkObjectName
,&index
)==S_FALSE
)
403 return MK_E_UNAVAILABLE
;;
405 (*pfiletime
)= This
->runObjTab
[index
].lastModifObj
;
410 /***********************************************************************
411 * RunningObjectTable_EnumRunning
413 HRESULT WINAPI
RunningObjectTableImpl_EnumRunning(IRunningObjectTable
* iface
,
414 IEnumMoniker
**ppenumMoniker
) /* Address of output variable that receives the IEnumMoniker interface pointer */
416 FIXME("(%p,%p) needs the IEnumMoniker implementation \n",iface
,ppenumMoniker
);
420 /***********************************************************************
423 HRESULT WINAPI
RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl
* This
,
431 TRACE("(%p,%ld,%p,%p)\n",This
,identReg
,pmk
,indx
);
434 /* search object identified by a moniker*/
435 for(i
=0 ; (i
< This
->runObjTabLastIndx
) &&(!IMoniker_IsEqual(This
->runObjTab
[i
].pmkObj
,pmk
)==S_OK
);i
++);
437 /* search object identified by a register identifier*/
438 for(i
=0;((i
<This
->runObjTabLastIndx
)&&(This
->runObjTab
[i
].identRegObj
!=identReg
));i
++);
440 if (i
==This
->runObjTabLastIndx
) return S_FALSE
;
442 if (indx
!= NULL
) *indx
=i
;
447 /******************************************************************************
448 * GetRunningObjectTable16 [OLE2.30]
450 HRESULT WINAPI
GetRunningObjectTable16(DWORD reserved
, LPRUNNINGOBJECTTABLE
*pprot
)
452 FIXME("(%ld,%p),stub!\n",reserved
,pprot
);
456 /***********************************************************************
457 * GetRunningObjectTable (OLE2.73)
459 HRESULT WINAPI
GetRunningObjectTable(DWORD reserved
, LPRUNNINGOBJECTTABLE
*pprot
)
461 IID riid
=IID_IRunningObjectTable
;
469 if(runningObjectTableInstance
==NULL
)
470 return CO_E_NOTINITIALIZED
;
472 res
= RunningObjectTableImpl_QueryInterface((IRunningObjectTable
*)runningObjectTableInstance
,&riid
,(void**)pprot
);