4 * Copyright 1998 Marcus Meissner
5 * Copyright 1999 Noomen Hamza
14 #include "wine/obj_base.h"
15 #include "wine/obj_storage.h"
16 #include "wine/obj_misc.h"
17 #include "wine/obj_moniker.h"
18 #include "debugtools.h"
22 #include "compobj_private.h"
24 DEFAULT_DEBUG_CHANNEL(ole
);
26 #define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
28 /* define the structure of the running object table elements */
29 typedef struct RunObject
{
31 IUnknown
* pObj
; /* points on a running object*/
32 IMoniker
* pmkObj
; /* points on a moniker who identifies this object */
33 FILETIME lastModifObj
;
34 DWORD identRegObj
; /* registration key relative to this object */
35 DWORD regTypeObj
; /* registration type : strong or weak */
38 /* define the RunningObjectTableImpl structure */
39 typedef struct RunningObjectTableImpl
{
41 ICOM_VFIELD(IRunningObjectTable
);
44 RunObject
* runObjTab
; /* pointer to the first object in the table */
45 DWORD runObjTabSize
; /* current table size */
46 DWORD runObjTabLastIndx
; /* first free index element in the table. */
47 DWORD runObjTabRegister
; /* registration key of the next registered object */
49 } RunningObjectTableImpl
;
51 RunningObjectTableImpl
* runningObjectTableInstance
=0;
53 /* IRunningObjectTable prototype functions : */
54 /* IUnknown functions*/
55 static HRESULT WINAPI
RunningObjectTableImpl_QueryInterface(IRunningObjectTable
* iface
,REFIID riid
,void** ppvObject
);
56 static ULONG WINAPI
RunningObjectTableImpl_AddRef(IRunningObjectTable
* iface
);
57 static ULONG WINAPI
RunningObjectTableImpl_Release(IRunningObjectTable
* iface
);
58 /* IRunningObjectTable functions */
59 static HRESULT WINAPI
RunningObjectTableImpl_Register(IRunningObjectTable
* iface
, DWORD grfFlags
,IUnknown
* punkObject
,IMoniker
* pmkObjectName
,DWORD
* pdwRegister
);
60 static HRESULT WINAPI
RunningObjectTableImpl_Revoke(IRunningObjectTable
* iface
, DWORD dwRegister
);
61 static HRESULT WINAPI
RunningObjectTableImpl_IsRunning(IRunningObjectTable
* iface
, IMoniker
* pmkObjectName
);
62 static HRESULT WINAPI
RunningObjectTableImpl_GetObject(IRunningObjectTable
* iface
, IMoniker
* pmkObjectName
,IUnknown
** ppunkObject
);
63 static HRESULT WINAPI
RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable
* iface
, DWORD dwRegister
,FILETIME
* pfiletime
);
64 static HRESULT WINAPI
RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable
* iface
, IMoniker
* pmkObjectName
,FILETIME
* pfiletime
);
65 static HRESULT WINAPI
RunningObjectTableImpl_EnumRunning(IRunningObjectTable
* iface
, IEnumMoniker
** ppenumMoniker
);
67 HRESULT WINAPI
RunningObjectTableImpl_Initialize();
68 HRESULT WINAPI
RunningObjectTableImpl_UnInitialize();
69 HRESULT WINAPI
RunningObjectTableImpl_Destroy();
70 HRESULT WINAPI
RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl
* This
,DWORD identReg
,IMoniker
* pmk
,DWORD
*indx
);
72 /* Virtual function table for the IRunningObjectTable class. */
73 static ICOM_VTABLE(IRunningObjectTable
) VT_RunningObjectTableImpl
=
75 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
76 RunningObjectTableImpl_QueryInterface
,
77 RunningObjectTableImpl_AddRef
,
78 RunningObjectTableImpl_Release
,
79 RunningObjectTableImpl_Register
,
80 RunningObjectTableImpl_Revoke
,
81 RunningObjectTableImpl_IsRunning
,
82 RunningObjectTableImpl_GetObject
,
83 RunningObjectTableImpl_NoteChangeTime
,
84 RunningObjectTableImpl_GetTimeOfLastChange
,
85 RunningObjectTableImpl_EnumRunning
88 /***********************************************************************
89 * RunningObjectTable_QueryInterface
91 HRESULT WINAPI
RunningObjectTableImpl_QueryInterface(IRunningObjectTable
* iface
,REFIID riid
,void** ppvObject
)
93 ICOM_THIS(RunningObjectTableImpl
,iface
);
95 TRACE("(%p,%p,%p)\n",This
,riid
,ppvObject
);
97 /* validate arguments */
99 return CO_E_NOTINITIALIZED
;
106 if (IsEqualIID(&IID_IUnknown
, riid
))
107 *ppvObject
= (IRunningObjectTable
*)This
;
109 if (IsEqualIID(&IID_IRunningObjectTable
, riid
))
110 *ppvObject
= (IRunningObjectTable
*)This
;
113 return E_NOINTERFACE
;
115 RunningObjectTableImpl_AddRef(iface
);
120 /***********************************************************************
121 * RunningObjectTable_AddRef
123 ULONG WINAPI
RunningObjectTableImpl_AddRef(IRunningObjectTable
* iface
)
125 ICOM_THIS(RunningObjectTableImpl
,iface
);
127 TRACE("(%p)\n",This
);
129 return ++(This
->ref
);
132 /***********************************************************************
133 * RunningObjectTable_Initialize
135 HRESULT WINAPI
RunningObjectTableImpl_Destroy()
139 if (runningObjectTableInstance
==NULL
)
142 /* free the ROT table memory */
143 HeapFree(GetProcessHeap(),0,runningObjectTableInstance
->runObjTab
);
145 /* free the ROT structure memory */
146 HeapFree(GetProcessHeap(),0,runningObjectTableInstance
);
151 /***********************************************************************
152 * RunningObjectTable_Release
154 ULONG WINAPI
RunningObjectTableImpl_Release(IRunningObjectTable
* iface
)
157 ICOM_THIS(RunningObjectTableImpl
,iface
);
159 TRACE("(%p)\n",This
);
163 /* unitialize ROT structure if there's no more reference to it*/
166 /* release all registered objects */
167 for(i
=0;i
<This
->runObjTabLastIndx
;i
++)
169 if (( This
->runObjTab
[i
].regTypeObj
& ROTFLAGS_REGISTRATIONKEEPSALIVE
) != 0)
170 IUnknown_Release(This
->runObjTab
[i
].pObj
);
172 IMoniker_Release(This
->runObjTab
[i
].pmkObj
);
174 /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
175 * when RunningObjectTableImpl_UnInitialize function is called
178 /* there's no more elements in the table */
179 This
->runObjTabRegister
=0;
180 This
->runObjTabLastIndx
=0;
188 /***********************************************************************
189 * RunningObjectTable_Initialize
191 HRESULT WINAPI
RunningObjectTableImpl_Initialize()
195 /* create the unique instance of the RunningObjectTableImpl structure */
196 runningObjectTableInstance
= HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl
));
198 if (runningObjectTableInstance
== 0)
199 return E_OUTOFMEMORY
;
201 /* initialize the virtual table function */
202 ICOM_VTBL(runningObjectTableInstance
) = &VT_RunningObjectTableImpl
;
204 /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
205 /* the ROT refered many times not in the same time (all the objects in the ROT will */
206 /* be removed every time the ROT is removed ) */
207 runningObjectTableInstance
->ref
= 1;
209 /* allocate space memory for the table which contains all the running objects */
210 runningObjectTableInstance
->runObjTab
= HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject
[BLOCK_TAB_SIZE
]));
212 if (runningObjectTableInstance
->runObjTab
== NULL
)
213 return E_OUTOFMEMORY
;
215 runningObjectTableInstance
->runObjTabSize
=BLOCK_TAB_SIZE
;
216 runningObjectTableInstance
->runObjTabRegister
=1;
217 runningObjectTableInstance
->runObjTabLastIndx
=0;
222 /***********************************************************************
223 * RunningObjectTable_UnInitialize
225 HRESULT WINAPI
RunningObjectTableImpl_UnInitialize()
229 if (runningObjectTableInstance
==NULL
)
232 RunningObjectTableImpl_Release((IRunningObjectTable
*)runningObjectTableInstance
);
234 RunningObjectTableImpl_Destroy();
239 /***********************************************************************
240 * RunningObjectTable_Register
242 HRESULT WINAPI
RunningObjectTableImpl_Register(IRunningObjectTable
* iface
,
243 DWORD grfFlags
, /* Registration options */
244 IUnknown
*punkObject
, /* Pointer to the object being registered */
245 IMoniker
*pmkObjectName
, /* Pointer to the moniker of the object being registered */
246 DWORD
*pdwRegister
) /* Pointer to the value identifying the registration */
249 ICOM_THIS(RunningObjectTableImpl
,iface
);
251 TRACE("(%p,%ld,%p,%p,%p)\n",This
,grfFlags
,punkObject
,pmkObjectName
,pdwRegister
);
253 /* there's only two types of register : strong and or weak registration (only one must be passed on parameter) */
254 if ( ( (grfFlags
& ROTFLAGS_REGISTRATIONKEEPSALIVE
) || !(grfFlags
& ROTFLAGS_ALLOWANYCLIENT
)) &&
255 (!(grfFlags
& ROTFLAGS_REGISTRATIONKEEPSALIVE
) || (grfFlags
& ROTFLAGS_ALLOWANYCLIENT
)) &&
259 if (punkObject
==NULL
|| pmkObjectName
==NULL
|| pdwRegister
==NULL
)
262 /* verify if the object to be registered was registered before */
263 if (RunningObjectTableImpl_GetObjectIndex(This
,-1,pmkObjectName
,NULL
)==S_OK
)
264 res
= MK_S_MONIKERALREADYREGISTERED
;
266 /* put the new registered object in the first free element in the table */
267 This
->runObjTab
[This
->runObjTabLastIndx
].pObj
= punkObject
;
268 This
->runObjTab
[This
->runObjTabLastIndx
].pmkObj
= pmkObjectName
;
269 This
->runObjTab
[This
->runObjTabLastIndx
].regTypeObj
= grfFlags
;
270 This
->runObjTab
[This
->runObjTabLastIndx
].identRegObj
= This
->runObjTabRegister
;
271 CoFileTimeNow(&(This
->runObjTab
[This
->runObjTabLastIndx
].lastModifObj
));
273 /* gives a registration identifier to the registered object*/
274 (*pdwRegister
)= This
->runObjTabRegister
;
276 if (This
->runObjTabRegister
== 0xFFFFFFFF){
278 FIXME("runObjTabRegister: %ld is out of data limite \n",This
->runObjTabRegister
);
281 This
->runObjTabRegister
++;
282 This
->runObjTabLastIndx
++;
284 if (This
->runObjTabLastIndx
== This
->runObjTabSize
){ /* table is full ! so it must be resized */
286 This
->runObjTabSize
+=BLOCK_TAB_SIZE
; /* newsize table */
287 This
->runObjTab
=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,This
->runObjTab
,
288 This
->runObjTabSize
* sizeof(RunObject
));
289 if (!This
->runObjTab
)
290 return E_OUTOFMEMORY
;
292 /* add a reference to the object in the strong registration case */
293 if ((grfFlags
& ROTFLAGS_REGISTRATIONKEEPSALIVE
) !=0 )
294 IUnknown_AddRef(punkObject
);
296 IMoniker_AddRef(pmkObjectName
);
301 /***********************************************************************
302 * RunningObjectTable_Revoke
304 HRESULT WINAPI
RunningObjectTableImpl_Revoke( IRunningObjectTable
* iface
,
305 DWORD dwRegister
) /* Value identifying registration to be revoked*/
309 ICOM_THIS(RunningObjectTableImpl
,iface
);
311 TRACE("(%p,%ld)\n",This
,dwRegister
);
313 /* verify if the object to be revoked was registered before or not */
314 if (RunningObjectTableImpl_GetObjectIndex(This
,dwRegister
,NULL
,&index
)==S_FALSE
)
318 /* release the object if it was registered with a strong registrantion option */
319 if ((This
->runObjTab
[index
].regTypeObj
& ROTFLAGS_REGISTRATIONKEEPSALIVE
)!=0)
320 IUnknown_Release(This
->runObjTab
[index
].pObj
);
322 IMoniker_Release(This
->runObjTab
[index
].pmkObj
);
324 /* remove the object from the table */
325 for(j
=index
; j
<This
->runObjTabLastIndx
-1; j
++)
326 This
->runObjTab
[j
]= This
->runObjTab
[j
+1];
328 This
->runObjTabLastIndx
--;
333 /***********************************************************************
334 * RunningObjectTable_IsRunning
336 HRESULT WINAPI
RunningObjectTableImpl_IsRunning( IRunningObjectTable
* iface
,
337 IMoniker
*pmkObjectName
) /* Pointer to the moniker of the object whose status is desired */
339 ICOM_THIS(RunningObjectTableImpl
,iface
);
341 TRACE("(%p,%p)\n",This
,pmkObjectName
);
343 return RunningObjectTableImpl_GetObjectIndex(This
,-1,pmkObjectName
,NULL
);
346 /***********************************************************************
347 * RunningObjectTable_GetObject
349 HRESULT WINAPI
RunningObjectTableImpl_GetObject( IRunningObjectTable
* iface
,
350 IMoniker
*pmkObjectName
,/* Pointer to the moniker on the object */
351 IUnknown
**ppunkObject
) /* Address of output variable that receives the IUnknown interface pointer */
354 ICOM_THIS(RunningObjectTableImpl
,iface
);
356 TRACE("(%p,%p,%p)\n",This
,pmkObjectName
,ppunkObject
);
358 if (ppunkObject
==NULL
)
363 /* verify if the object was registered before or not */
364 if (RunningObjectTableImpl_GetObjectIndex(This
,-1,pmkObjectName
,&index
)==S_FALSE
)
365 return MK_E_UNAVAILABLE
;
367 /* add a reference to the object then set output object argument */
368 IUnknown_AddRef(This
->runObjTab
[index
].pObj
);
369 *ppunkObject
=This
->runObjTab
[index
].pObj
;
374 /***********************************************************************
375 * RunningObjectTable_NoteChangeTime
377 HRESULT WINAPI
RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable
* iface
,
378 DWORD dwRegister
, /* Value identifying registration being updated */
379 FILETIME
*pfiletime
) /* Pointer to structure containing object's last change time */
382 ICOM_THIS(RunningObjectTableImpl
,iface
);
384 TRACE("(%p,%ld,%p)\n",This
,dwRegister
,pfiletime
);
386 /* verify if the object to be changed was registered before or not */
387 if (RunningObjectTableImpl_GetObjectIndex(This
,dwRegister
,NULL
,&index
)==S_FALSE
)
390 /* set the new value of the last time change */
391 This
->runObjTab
[index
].lastModifObj
= (*pfiletime
);
396 /***********************************************************************
397 * RunningObjectTable_GetTimeOfLastChange
399 HRESULT WINAPI
RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable
* iface
,
400 IMoniker
*pmkObjectName
, /* Pointer to moniker on the object whose status is desired */
401 FILETIME
*pfiletime
) /* Pointer to structure that receives object's last change time */
404 ICOM_THIS(RunningObjectTableImpl
,iface
);
406 TRACE("(%p,%p,%p)\n",This
,pmkObjectName
,pfiletime
);
408 if (pmkObjectName
==NULL
|| pfiletime
==NULL
)
411 /* verify if the object was registered before or not */
412 if (RunningObjectTableImpl_GetObjectIndex(This
,-1,pmkObjectName
,&index
)==S_FALSE
)
413 return MK_E_UNAVAILABLE
;;
415 (*pfiletime
)= This
->runObjTab
[index
].lastModifObj
;
420 /***********************************************************************
421 * RunningObjectTable_EnumRunning
423 HRESULT WINAPI
RunningObjectTableImpl_EnumRunning(IRunningObjectTable
* iface
,
424 IEnumMoniker
**ppenumMoniker
) /* Address of output variable that receives the IEnumMoniker interface pointer */
426 FIXME("(%p,%p) needs the IEnumMoniker implementation \n",iface
,ppenumMoniker
);
430 /***********************************************************************
433 HRESULT WINAPI
RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl
* This
,
441 TRACE("(%p,%ld,%p,%p)\n",This
,identReg
,pmk
,indx
);
444 /* search object identified by a moniker */
445 for(i
=0 ; (i
< This
->runObjTabLastIndx
) &&(!IMoniker_IsEqual(This
->runObjTab
[i
].pmkObj
,pmk
)==S_OK
);i
++);
447 /* search object identified by a register identifier */
448 for(i
=0;((i
<This
->runObjTabLastIndx
)&&(This
->runObjTab
[i
].identRegObj
!=identReg
));i
++);
450 if (i
==This
->runObjTabLastIndx
) return S_FALSE
;
452 if (indx
!= NULL
) *indx
=i
;
457 /******************************************************************************
458 * GetRunningObjectTable16 [OLE2.30]
460 HRESULT WINAPI
GetRunningObjectTable16(DWORD reserved
, LPRUNNINGOBJECTTABLE
*pprot
)
462 FIXME("(%ld,%p),stub!\n",reserved
,pprot
);
466 /***********************************************************************
467 * GetRunningObjectTable (OLE2.73)
469 HRESULT WINAPI
GetRunningObjectTable(DWORD reserved
, LPRUNNINGOBJECTTABLE
*pprot
)
471 IID riid
=IID_IRunningObjectTable
;
479 if(runningObjectTableInstance
==NULL
)
480 return CO_E_NOTINITIALIZED
;
482 res
= RunningObjectTableImpl_QueryInterface((IRunningObjectTable
*)runningObjectTableInstance
,&riid
,(void**)pprot
);
487 /******************************************************************************
490 HRESULT WINAPI
OleRun(LPUNKNOWN pUnknown
)
492 IRunnableObject
*runable
;
493 ICOM_THIS(IRunnableObject
,pUnknown
);
496 ret
= IRunnableObject_QueryInterface(This
,&IID_IRunnableObject
,(LPVOID
*)&runable
);
498 return 0; /* Appears to return no error. */
499 ret
= IRunnableObject_Run(runable
,NULL
);
500 IRunnableObject_Release(runable
);
504 /******************************************************************************
505 * MkParseDisplayName [OLE32.81]
507 HRESULT WINAPI
MkParseDisplayName(LPBC pbc
, LPCOLESTR szUserName
,
508 LPDWORD pchEaten
, LPMONIKER
*ppmk
)
510 FIXME("(%p, %s, %p, %p): stub.\n", pbc
, debugstr_w(szUserName
), pchEaten
, *ppmk
);
511 if (!(IsValidInterface((LPUNKNOWN
) pbc
)))