4 * Copyright 1998 Marcus Meissner
5 * Copyright 1999 Noomen Hamza
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "wine/debug.h"
34 #include "compobj_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(ole);
38 #define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
40 /* define the structure of the running object table elements */
41 typedef struct RunObject{
43 IUnknown* pObj; /* points on a running object*/
44 IMoniker* pmkObj; /* points on a moniker who identifies this object */
45 FILETIME lastModifObj;
46 DWORD identRegObj; /* registration key relative to this object */
47 DWORD regTypeObj; /* registration type : strong or weak */
50 /* define the RunningObjectTableImpl structure */
51 typedef struct RunningObjectTableImpl{
53 ICOM_VFIELD(IRunningObjectTable);
56 RunObject* runObjTab; /* pointer to the first object in the table */
57 DWORD runObjTabSize; /* current table size */
58 DWORD runObjTabLastIndx; /* first free index element in the table. */
59 DWORD runObjTabRegister; /* registration key of the next registered object */
61 } RunningObjectTableImpl;
63 RunningObjectTableImpl* runningObjectTableInstance=0;
65 /* IRunningObjectTable prototype functions : */
66 /* IUnknown functions*/
67 static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject);
68 static ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface);
69 static ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface);
70 /* IRunningObjectTable functions */
71 static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister);
72 static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister);
73 static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName);
74 static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject);
75 static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime);
76 static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime);
77 static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker);
79 HRESULT WINAPI RunningObjectTableImpl_Initialize();
80 HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
81 HRESULT WINAPI RunningObjectTableImpl_Destroy();
82 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);
84 /* Virtual function table for the IRunningObjectTable class. */
85 static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl =
87 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
88 RunningObjectTableImpl_QueryInterface,
89 RunningObjectTableImpl_AddRef,
90 RunningObjectTableImpl_Release,
91 RunningObjectTableImpl_Register,
92 RunningObjectTableImpl_Revoke,
93 RunningObjectTableImpl_IsRunning,
94 RunningObjectTableImpl_GetObject,
95 RunningObjectTableImpl_NoteChangeTime,
96 RunningObjectTableImpl_GetTimeOfLastChange,
97 RunningObjectTableImpl_EnumRunning
100 /***********************************************************************
101 * RunningObjectTable_QueryInterface
103 HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
105 ICOM_THIS(RunningObjectTableImpl,iface);
107 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
109 /* validate arguments */
111 return CO_E_NOTINITIALIZED;
118 if (IsEqualIID(&IID_IUnknown, riid))
119 *ppvObject = (IRunningObjectTable*)This;
121 if (IsEqualIID(&IID_IRunningObjectTable, riid))
122 *ppvObject = (IRunningObjectTable*)This;
125 return E_NOINTERFACE;
127 RunningObjectTableImpl_AddRef(iface);
132 /***********************************************************************
133 * RunningObjectTable_AddRef
135 ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
137 ICOM_THIS(RunningObjectTableImpl,iface);
139 TRACE("(%p)\n",This);
141 return ++(This->ref);
144 /***********************************************************************
145 * RunningObjectTable_Initialize
147 HRESULT WINAPI RunningObjectTableImpl_Destroy()
151 if (runningObjectTableInstance==NULL)
154 /* free the ROT table memory */
155 HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
157 /* free the ROT structure memory */
158 HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
163 /***********************************************************************
164 * RunningObjectTable_Release
166 ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
169 ICOM_THIS(RunningObjectTableImpl,iface);
171 TRACE("(%p)\n",This);
175 /* unitialize ROT structure if there's no more reference to it*/
178 /* release all registered objects */
179 for(i=0;i<This->runObjTabLastIndx;i++)
181 if (( This->runObjTab[i].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
182 IUnknown_Release(This->runObjTab[i].pObj);
184 IMoniker_Release(This->runObjTab[i].pmkObj);
186 /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
187 * when RunningObjectTableImpl_UnInitialize function is called
190 /* there's no more elements in the table */
191 This->runObjTabRegister=0;
192 This->runObjTabLastIndx=0;
200 /***********************************************************************
201 * RunningObjectTable_Initialize
203 HRESULT WINAPI RunningObjectTableImpl_Initialize()
207 /* create the unique instance of the RunningObjectTableImpl structure */
208 runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));
210 if (runningObjectTableInstance == 0)
211 return E_OUTOFMEMORY;
213 /* initialize the virtual table function */
214 runningObjectTableInstance->lpVtbl = &VT_RunningObjectTableImpl;
216 /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
217 /* the ROT referred many times not in the same time (all the objects in the ROT will */
218 /* be removed every time the ROT is removed ) */
219 runningObjectTableInstance->ref = 1;
221 /* allocate space memory for the table which contains all the running objects */
222 runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));
224 if (runningObjectTableInstance->runObjTab == NULL)
225 return E_OUTOFMEMORY;
227 runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
228 runningObjectTableInstance->runObjTabRegister=1;
229 runningObjectTableInstance->runObjTabLastIndx=0;
234 /***********************************************************************
235 * RunningObjectTable_UnInitialize
237 HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
241 if (runningObjectTableInstance==NULL)
244 RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
246 RunningObjectTableImpl_Destroy();
251 /***********************************************************************
252 * RunningObjectTable_Register
254 HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface,
255 DWORD grfFlags, /* Registration options */
256 IUnknown *punkObject, /* Pointer to the object being registered */
257 IMoniker *pmkObjectName, /* Pointer to the moniker of the object being registered */
258 DWORD *pdwRegister) /* Pointer to the value identifying the registration */
261 ICOM_THIS(RunningObjectTableImpl,iface);
263 TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
265 /* there's only two types of register : strong and or weak registration (only one must be passed on parameter) */
266 if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
267 (!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
271 if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
274 /* verify if the object to be registered was registered before */
275 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
276 res = MK_S_MONIKERALREADYREGISTERED;
278 /* put the new registered object in the first free element in the table */
279 This->runObjTab[This->runObjTabLastIndx].pObj = punkObject;
280 This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName;
281 This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags;
282 This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister;
283 CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj));
285 /* gives a registration identifier to the registered object*/
286 (*pdwRegister)= This->runObjTabRegister;
288 if (This->runObjTabRegister == 0xFFFFFFFF){
290 FIXME("runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister);
293 This->runObjTabRegister++;
294 This->runObjTabLastIndx++;
296 if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */
298 This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */
299 This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab,
300 This->runObjTabSize * sizeof(RunObject));
301 if (!This->runObjTab)
302 return E_OUTOFMEMORY;
304 /* add a reference to the object in the strong registration case */
305 if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 )
306 IUnknown_AddRef(punkObject);
308 IMoniker_AddRef(pmkObjectName);
313 /***********************************************************************
314 * RunningObjectTable_Revoke
316 HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface,
317 DWORD dwRegister) /* Value identifying registration to be revoked*/
321 ICOM_THIS(RunningObjectTableImpl,iface);
323 TRACE("(%p,%ld)\n",This,dwRegister);
325 /* verify if the object to be revoked was registered before or not */
326 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
330 /* release the object if it was registered with a strong registrantion option */
331 if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0)
332 IUnknown_Release(This->runObjTab[index].pObj);
334 IMoniker_Release(This->runObjTab[index].pmkObj);
336 /* remove the object from the table */
337 for(j=index; j<This->runObjTabLastIndx-1; j++)
338 This->runObjTab[j]= This->runObjTab[j+1];
340 This->runObjTabLastIndx--;
345 /***********************************************************************
346 * RunningObjectTable_IsRunning
348 HRESULT WINAPI RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface,
349 IMoniker *pmkObjectName) /* Pointer to the moniker of the object whose status is desired */
351 ICOM_THIS(RunningObjectTableImpl,iface);
353 TRACE("(%p,%p)\n",This,pmkObjectName);
355 return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
358 /***********************************************************************
359 * RunningObjectTable_GetObject
361 HRESULT WINAPI RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
362 IMoniker *pmkObjectName,/* Pointer to the moniker on the object */
363 IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */
366 ICOM_THIS(RunningObjectTableImpl,iface);
368 TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
370 if (ppunkObject==NULL)
375 /* verify if the object was registered before or not */
376 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
377 return MK_E_UNAVAILABLE;
379 /* add a reference to the object then set output object argument */
380 IUnknown_AddRef(This->runObjTab[index].pObj);
381 *ppunkObject=This->runObjTab[index].pObj;
386 /***********************************************************************
387 * RunningObjectTable_NoteChangeTime
389 HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
390 DWORD dwRegister, /* Value identifying registration being updated */
391 FILETIME *pfiletime) /* Pointer to structure containing object's last change time */
394 ICOM_THIS(RunningObjectTableImpl,iface);
396 TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);
398 /* verify if the object to be changed was registered before or not */
399 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
402 /* set the new value of the last time change */
403 This->runObjTab[index].lastModifObj= (*pfiletime);
408 /***********************************************************************
409 * RunningObjectTable_GetTimeOfLastChange
411 HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
412 IMoniker *pmkObjectName, /* Pointer to moniker on the object whose status is desired */
413 FILETIME *pfiletime) /* Pointer to structure that receives object's last change time */
416 ICOM_THIS(RunningObjectTableImpl,iface);
418 TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
420 if (pmkObjectName==NULL || pfiletime==NULL)
423 /* verify if the object was registered before or not */
424 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
425 return MK_E_UNAVAILABLE;
427 (*pfiletime)= This->runObjTab[index].lastModifObj;
432 /***********************************************************************
433 * RunningObjectTable_EnumRunning
435 HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
436 IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
438 FIXME("(%p,%p) needs the IEnumMoniker implementation \n",iface,ppenumMoniker);
442 /***********************************************************************
445 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
453 TRACE("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);
456 /* search object identified by a moniker */
457 for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
459 /* search object identified by a register identifier */
460 for(i=0;((i<This->runObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++);
462 if (i==This->runObjTabLastIndx) return S_FALSE;
464 if (indx != NULL) *indx=i;
469 /******************************************************************************
470 * GetRunningObjectTable [OLE2.@]
472 HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
474 FIXME("(%ld,%p),stub!\n",reserved,pprot);
478 /***********************************************************************
479 * GetRunningObjectTable (OLE32.@)
481 HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
483 IID riid=IID_IRunningObjectTable;
491 if(runningObjectTableInstance==NULL)
492 return CO_E_NOTINITIALIZED;
494 res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
499 /******************************************************************************
502 HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
504 IRunnableObject *runable;
505 ICOM_THIS(IRunnableObject,pUnknown);
508 ret = IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable);
510 return 0; /* Appears to return no error. */
511 ret = IRunnableObject_Run(runable,NULL);
512 IRunnableObject_Release(runable);
516 /******************************************************************************
517 * MkParseDisplayName [OLE32.@]
519 HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szUserName,
520 LPDWORD pchEaten, LPMONIKER *ppmk)
522 FIXME("(%p, %s, %p, %p): stub.\n", pbc, debugstr_w(szUserName), pchEaten, *ppmk);
523 if (!(IsValidInterface((LPUNKNOWN) pbc)))
529 /******************************************************************************
530 * CreateClassMoniker [OLE32.*]
532 HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, IMoniker ** ppmk)
534 FIXME("%s\n", debugstr_guid( rclsid ));