4 * Copyright 1998 Marcus Meissner
5 * Copyright 1999 Noomen Hamza
11 #include <ole32/ole32.h>
13 #include <storage32.h>
19 #define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
21 /* define the structure of the running object table elements */
22 typedef struct RunObject{
24 IUnknown* pObj; /* points on a running object*/
25 IMoniker* pmkObj; /* points on a moniker who identifies this object */
26 FILETIME lastModifObj;
27 DWORD identRegObj; /* registration key relative to this object */
28 DWORD regTypeObj; /* registration type : strong or weak */
31 /* define the RunningObjectTableImpl structure */
32 typedef struct RunningObjectTableImpl{
34 ICOM_VFIELD(IRunningObjectTable);
37 RunObject* runObjTab; /* pointer to the first object in the table */
38 DWORD runObjTabSize; /* current table size */
39 DWORD runObjTabLastIndx; /* first free index element in the table. */
40 DWORD runObjTabRegister; /* registration key of the next registered object */
42 } RunningObjectTableImpl;
44 RunningObjectTableImpl* runningObjectTableInstance=0;
46 /* IRunningObjectTable prototype functions : */
47 /* IUnknown functions*/
48 static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject);
49 static ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface);
50 static ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface);
51 /* IRunningObjectTable functions */
52 static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister);
53 static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister);
54 static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName);
55 static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject);
56 static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime);
57 static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime);
58 static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker);
60 HRESULT WINAPI RunningObjectTableImpl_Initialize();
61 HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
62 HRESULT WINAPI RunningObjectTableImpl_Destroy();
63 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);
65 /* Virtual function table for the IRunningObjectTable class. */
66 static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl =
68 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
69 RunningObjectTableImpl_QueryInterface,
70 RunningObjectTableImpl_AddRef,
71 RunningObjectTableImpl_Release,
72 RunningObjectTableImpl_Register,
73 RunningObjectTableImpl_Revoke,
74 RunningObjectTableImpl_IsRunning,
75 RunningObjectTableImpl_GetObject,
76 RunningObjectTableImpl_NoteChangeTime,
77 RunningObjectTableImpl_GetTimeOfLastChange,
78 RunningObjectTableImpl_EnumRunning
81 /***********************************************************************
82 * RunningObjectTable_QueryInterface
84 HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
86 ICOM_THIS(RunningObjectTableImpl,iface);
88 Print(MAX_TRACE, ("(%p,%p,%p)\n",This,riid,ppvObject));
90 /* validate arguments */
92 return CO_E_NOTINITIALIZED;
99 if (IsEqualIID(&IID_IUnknown, riid))
100 *ppvObject = (IRunningObjectTable*)This;
102 if (IsEqualIID(&IID_IRunningObjectTable, riid))
103 *ppvObject = (IRunningObjectTable*)This;
106 return E_NOINTERFACE;
108 RunningObjectTableImpl_AddRef(iface);
113 /***********************************************************************
114 * RunningObjectTable_AddRef
116 ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
118 ICOM_THIS(RunningObjectTableImpl,iface);
120 Print(MAX_TRACE, ("(%p)\n",This));
122 return ++(This->ref);
125 /***********************************************************************
126 * RunningObjectTable_Initialize
128 HRESULT WINAPI RunningObjectTableImpl_Destroy()
130 Print(MAX_TRACE, ("()\n"));
132 if (runningObjectTableInstance==NULL)
135 /* free the ROT table memory */
136 HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
138 /* free the ROT structure memory */
139 HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
144 /***********************************************************************
145 * RunningObjectTable_Release
147 ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
150 ICOM_THIS(RunningObjectTableImpl,iface);
152 Print(MAX_TRACE, ("(%p)\n",This));
156 /* unitialize ROT structure if there's no more reference to it*/
159 /* release all registered objects */
160 for(i=0;i<This->runObjTabLastIndx;i++)
162 if (( This->runObjTab[i].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
163 IUnknown_Release(This->runObjTab[i].pObj);
165 IMoniker_Release(This->runObjTab[i].pmkObj);
167 /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
168 * when RunningObjectTableImpl_UnInitialize function is called
171 /* there's no more elements in the table */
172 This->runObjTabRegister=0;
173 This->runObjTabLastIndx=0;
181 /***********************************************************************
182 * RunningObjectTable_Initialize
184 HRESULT WINAPI RunningObjectTableImpl_Initialize()
186 Print(MAX_TRACE, ("()\n"));
188 /* create the unique instance of the RunningObjectTableImpl structure */
189 runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));
191 if (runningObjectTableInstance == 0)
192 return E_OUTOFMEMORY;
194 /* initialize the virtual table function */
195 ICOM_VTBL(runningObjectTableInstance) = &VT_RunningObjectTableImpl;
197 /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
198 /* the ROT refered many times not in the same time (all the objects in the ROT will */
199 /* be removed every time the ROT is removed ) */
200 runningObjectTableInstance->ref = 1;
202 /* allocate space memory for the table which contains all the running objects */
203 runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));
205 if (runningObjectTableInstance->runObjTab == NULL)
206 return E_OUTOFMEMORY;
208 runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
209 runningObjectTableInstance->runObjTabRegister=1;
210 runningObjectTableInstance->runObjTabLastIndx=0;
215 /***********************************************************************
216 * RunningObjectTable_UnInitialize
218 HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
220 Print(MAX_TRACE, ("()\n"));
222 if (runningObjectTableInstance==NULL)
225 RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
227 RunningObjectTableImpl_Destroy();
232 /***********************************************************************
233 * RunningObjectTable_Register
235 HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface,
236 DWORD grfFlags, /* Registration options */
237 IUnknown *punkObject, /* Pointer to the object being registered */
238 IMoniker *pmkObjectName, /* Pointer to the moniker of the object being registered */
239 DWORD *pdwRegister) /* Pointer to the value identifying the registration */
242 ICOM_THIS(RunningObjectTableImpl,iface);
244 Print(MAX_TRACE, ("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister));
246 /* there's only two types of register : strong and or weak registration (only one must be passed on parameter) */
247 if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
248 (!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
252 if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
255 /* verify if the object to be registered was registered before */
256 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
257 res = MK_S_MONIKERALREADYREGISTERED;
259 /* put the new registered object in the first free element in the table */
260 This->runObjTab[This->runObjTabLastIndx].pObj = punkObject;
261 This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName;
262 This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags;
263 This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister;
264 CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj));
266 /* gives a registration identifier to the registered object*/
267 (*pdwRegister)= This->runObjTabRegister;
269 if (This->runObjTabRegister == 0xFFFFFFFF){
271 Print(MIN_TRACE, ("runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister));
274 This->runObjTabRegister++;
275 This->runObjTabLastIndx++;
277 if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */
279 This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */
280 This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab,
281 This->runObjTabSize * sizeof(RunObject));
282 if (!This->runObjTab)
283 return E_OUTOFMEMORY;
285 /* add a reference to the object in the strong registration case */
286 if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 )
287 IUnknown_AddRef(punkObject);
289 IMoniker_AddRef(pmkObjectName);
294 /***********************************************************************
295 * RunningObjectTable_Revoke
297 HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface,
298 DWORD dwRegister) /* Value identifying registration to be revoked*/
302 ICOM_THIS(RunningObjectTableImpl,iface);
304 Print(MAX_TRACE, ("(%p,%ld)\n",This,dwRegister));
306 /* verify if the object to be revoked was registered before or not */
307 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
311 /* release the object if it was registered with a strong registrantion option */
312 if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0)
313 IUnknown_Release(This->runObjTab[index].pObj);
315 IMoniker_Release(This->runObjTab[index].pmkObj);
317 /* remove the object from the table */
318 for(j=index; j<This->runObjTabLastIndx-1; j++)
319 This->runObjTab[j]= This->runObjTab[j+1];
321 This->runObjTabLastIndx--;
326 /***********************************************************************
327 * RunningObjectTable_IsRunning
329 HRESULT WINAPI RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface,
330 IMoniker *pmkObjectName) /* Pointer to the moniker of the object whose status is desired */
332 ICOM_THIS(RunningObjectTableImpl,iface);
334 Print(MAX_TRACE, ("(%p,%p)\n",This,pmkObjectName));
336 return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
339 /***********************************************************************
340 * RunningObjectTable_GetObject
342 HRESULT WINAPI RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
343 IMoniker *pmkObjectName,/* Pointer to the moniker on the object */
344 IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */
347 ICOM_THIS(RunningObjectTableImpl,iface);
349 Print(MAX_TRACE, ("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject));
351 if (ppunkObject==NULL)
356 /* verify if the object was registered before or not */
357 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
358 return MK_E_UNAVAILABLE;
360 /* add a reference to the object then set output object argument */
361 IUnknown_AddRef(This->runObjTab[index].pObj);
362 *ppunkObject=This->runObjTab[index].pObj;
367 /***********************************************************************
368 * RunningObjectTable_NoteChangeTime
370 HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
371 DWORD dwRegister, /* Value identifying registration being updated */
372 FILETIME *pfiletime) /* Pointer to structure containing object's last change time */
375 ICOM_THIS(RunningObjectTableImpl,iface);
377 Print(MAX_TRACE, ("(%p,%ld,%p)\n",This,dwRegister,pfiletime));
379 /* verify if the object to be changed was registered before or not */
380 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
383 /* set the new value of the last time change */
384 This->runObjTab[index].lastModifObj= (*pfiletime);
389 /***********************************************************************
390 * RunningObjectTable_GetTimeOfLastChange
392 HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
393 IMoniker *pmkObjectName, /* Pointer to moniker on the object whose status is desired */
394 FILETIME *pfiletime) /* Pointer to structure that receives object's last change time */
397 ICOM_THIS(RunningObjectTableImpl,iface);
399 Print(MAX_TRACE, ("(%p,%p,%p)\n",This,pmkObjectName,pfiletime));
401 if (pmkObjectName==NULL || pfiletime==NULL)
404 /* verify if the object was registered before or not */
405 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
406 return MK_E_UNAVAILABLE;;
408 (*pfiletime)= This->runObjTab[index].lastModifObj;
413 /***********************************************************************
414 * RunningObjectTable_EnumRunning
416 HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
417 IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
423 /***********************************************************************
426 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
434 Print(MAX_TRACE, ("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx));
437 /* search object identified by a moniker */
438 for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
440 /* search object identified by a register identifier */
441 for(i=0;((i<This->runObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++);
443 if (i==This->runObjTabLastIndx) return S_FALSE;
445 if (indx != NULL) *indx=i;
450 /******************************************************************************
451 * GetRunningObjectTable16 [OLE2.30]
453 HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
459 /***********************************************************************
460 * GetRunningObjectTable (OLE2.73)
462 HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
464 IID riid=IID_IRunningObjectTable;
467 Print(MAX_TRACE, ("()\n"));
472 if(runningObjectTableInstance==NULL)
473 return CO_E_NOTINITIALIZED;
475 res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
480 /******************************************************************************
483 HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
485 IRunnableObject *runable;
486 ICOM_THIS(IRunnableObject,pUnknown);
489 ret = IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable);
491 return 0; /* Appears to return no error. */
492 ret = IRunnableObject_Run(runable,NULL);
493 IRunnableObject_Release(runable);
497 /******************************************************************************
498 * MkParseDisplayName [OLE32.81]
500 HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szUserName,
501 LPDWORD pchEaten, LPMONIKER *ppmk)
503 Print(MIN_TRACE, ("(%p, %S, %p, %p): stub.\n", pbc, szUserName, pchEaten, *ppmk));
504 if (!(IsValidInterface((LPUNKNOWN) pbc)))