Added timeout to critical section waiting.
[wine/multimedia.git] / ole / moniker.c
blob44c968d8b7123705b62ed37f0221f50fdb8ab8af
1 /*
2 * Monikers
4 * Copyright 1998 Marcus Meissner
5 * Copyright 1999 Noomen Hamza
6 */
8 #include <assert.h>
9 #include "winerror.h"
10 #include "wine/obj_moniker.h"
11 #include "debug.h"
12 #include "heap.h"
14 #define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
16 /* define the structure of the running object table elements */
17 typedef struct RunObject{
19 IUnknown* pObj; /* points on a running object*/
20 IMoniker* pmkObj; /* points on a moniker who identifies this object */
21 FILETIME lastModifObj;
22 DWORD identRegObj; /* registration key relative to this object */
23 DWORD regTypeObj; /* registration type : strong or weak */
24 }RunObject;
26 /* define de RunningObjectTableImpl structure */
27 typedef struct RunningObjectTableImpl{
29 ICOM_VTABLE(IRunningObjectTable)* lpvtbl;
30 ULONG ref;
32 RunObject* runObjTab; /* pointe to the first object in the table */
33 DWORD runObjTabSize; /* current table size */
34 DWORD runObjTabLastIndx; /* first free index element in the table. */
35 DWORD runObjTabRegister; /* registration key of the next registred object */
37 } RunningObjectTableImpl;
39 RunningObjectTableImpl* runningObjectTableInstance=0;
41 /* IRunningObjectTable prototipe functions : */
42 /* IUnknown functions*/
43 static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject);
44 static ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface);
45 static ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface);
46 /* IRunningObjectTable functions */
47 static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister);
48 static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister);
49 static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName);
50 static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject);
51 static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime);
52 static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime);
53 static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker);
54 /* Local functions*/
55 HRESULT WINAPI RunningObjectTableImpl_Initialize();
56 HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
57 HRESULT WINAPI RunningObjectTableImpl_Destroy();
58 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);
60 /* Virtual function table for the IRunningObjectTable class. */
61 static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl =
63 RunningObjectTableImpl_QueryInterface,
64 RunningObjectTableImpl_AddRef,
65 RunningObjectTableImpl_Release,
66 RunningObjectTableImpl_Register,
67 RunningObjectTableImpl_Revoke,
68 RunningObjectTableImpl_IsRunning,
69 RunningObjectTableImpl_GetObject,
70 RunningObjectTableImpl_NoteChangeTime,
71 RunningObjectTableImpl_GetTimeOfLastChange,
72 RunningObjectTableImpl_EnumRunning
75 /***********************************************************************
76 * RunningObjectTable_QueryInterface
78 HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
80 ICOM_THIS(RunningObjectTableImpl,iface);
82 TRACE(ole,"(%p,%p,%p)\n",This,riid,ppvObject);
84 /* validate arguments*/
85 if (This==0)
86 return CO_E_NOTINITIALIZED;
88 if (ppvObject==0)
89 return E_INVALIDARG;
91 *ppvObject = 0;
93 if (IsEqualIID(&IID_IUnknown, riid))
94 *ppvObject = (IRunningObjectTable*)This;
95 else
96 if (IsEqualIID(&IID_IRunningObjectTable, riid))
97 *ppvObject = (IRunningObjectTable*)This;
99 if ((*ppvObject)==0)
100 return E_NOINTERFACE;
102 RunningObjectTableImpl_AddRef(iface);
104 return S_OK;
107 /***********************************************************************
108 * RunningObjectTable_AddRef
110 ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
112 ICOM_THIS(RunningObjectTableImpl,iface);
114 TRACE(ole,"(%p)\n",This);
116 return ++(This->ref);
119 /***********************************************************************
120 * RunningObjectTable_Initialize
122 HRESULT WINAPI RunningObjectTableImpl_Destroy()
124 TRACE(ole,"()\n");
126 if (runningObjectTableInstance==NULL)
127 return E_INVALIDARG;
129 /* free the ROT table memory */
130 HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
132 /* free the ROT structure memory */
133 HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
135 return S_OK;
138 /***********************************************************************
139 * RunningObjectTable_Release
141 ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
143 DWORD i;
144 ICOM_THIS(RunningObjectTableImpl,iface);
146 TRACE(ole,"(%p)\n",This);
148 This->ref--;
150 /* unitialize ROT structure if there's no more reference to it*/
151 if (This->ref==0){
153 /* release all registred objects */
154 for(i=0;i<This->runObjTabLastIndx;i++)
156 if (( This->runObjTab[i].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
157 IUnknown_Release(This->runObjTab[i].pObj);
159 IMoniker_Release(This->runObjTab[i].pmkObj);
161 /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
162 * when RunningObjectTableImpl_UnInitialize function is called
165 /* there's no more elements in the table */
166 This->runObjTabRegister=0;
167 This->runObjTabLastIndx=0;
169 return 0;
172 return This->ref;
175 /***********************************************************************
176 * RunningObjectTable_Initialize
178 HRESULT WINAPI RunningObjectTableImpl_Initialize()
180 TRACE(ole,"()\n");
182 /* create the unique instance of the RunningObjectTableImpl structure */
183 runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));
185 if (runningObjectTableInstance == 0)
186 return E_OUTOFMEMORY;
188 /* initialize the virtual table function */
189 runningObjectTableInstance->lpvtbl = &VT_RunningObjectTableImpl;
191 /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
192 /* the ROT refered many times not in the same time (all the objects in the ROT will */
193 /* be removed evry time the ROT is removed ) */
194 runningObjectTableInstance->ref = 1;
196 /* allocate space memory for the table witch contains all the running objects */
197 runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));
199 if (runningObjectTableInstance->runObjTab == NULL)
200 return E_OUTOFMEMORY;
202 runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
203 runningObjectTableInstance->runObjTabRegister=0;
204 runningObjectTableInstance->runObjTabLastIndx=0;
206 return S_OK;
209 /***********************************************************************
210 * RunningObjectTable_UnInitialize
212 HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
214 TRACE(ole,"()\n");
216 if (runningObjectTableInstance==NULL)
217 return E_POINTER;
219 RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
221 RunningObjectTableImpl_Destroy();
223 return S_OK;
226 /***********************************************************************
227 * RunningObjectTable_Register
229 HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface,
230 DWORD grfFlags, /* Registration options */
231 IUnknown *punkObject, /* Pointer to the object being registered */
232 IMoniker *pmkObjectName, /* Pointer to the moniker of the object being registered */
233 DWORD *pdwRegister) /* Pointer to the value identifying the registration */
235 HRESULT res=S_OK;
236 ICOM_THIS(RunningObjectTableImpl,iface);
238 TRACE(ole,"(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
240 /* there's only tow types of register : strong and or weak registration (only one must be passed on parameter) */
241 if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
242 (!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
243 (grfFlags) )
244 return E_INVALIDARG;
246 if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
247 return E_INVALIDARG;
249 /* verify if the object to be registred was registred befor */
250 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
251 res = MK_S_MONIKERALREADYREGISTERED;
253 /* put the new registred object in the first free element in the table */
254 This->runObjTab[This->runObjTabLastIndx].pObj = punkObject;
255 This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName;
256 This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags;
257 This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister;
258 CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj));
260 /* gives a registration identifier to the registred object*/
261 (*pdwRegister)= This->runObjTabRegister;
263 if (This->runObjTabRegister == 0xFFFFFFFF){
265 FIXME(ole,"runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister);
266 return E_FAIL;
268 This->runObjTabRegister++;
269 This->runObjTabLastIndx++;
271 if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */
273 This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */
274 This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab,
275 This->runObjTabSize * sizeof(RunObject));
276 if (!This->runObjTab)
277 return E_OUTOFMEMORY;
279 /* add a reference to the object in the strong registration case */
280 if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 )
281 IUnknown_AddRef(punkObject);
283 IMoniker_AddRef(pmkObjectName);
285 return res;
288 /***********************************************************************
289 * RunningObjectTable_Revoke
291 HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface,
292 DWORD dwRegister) /* Value identifying registration to be revoked*/
295 DWORD index,j;
296 ICOM_THIS(RunningObjectTableImpl,iface);
298 TRACE(ole,"(%p,%ld)\n",This,dwRegister);
300 /* verify if the object to be revoked was registred befor or not */
301 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
303 return E_INVALIDARG;
305 /* release the object if it was registred with a strong registrantion option */
306 if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0)
307 IUnknown_Release(This->runObjTab[index].pObj);
309 IMoniker_Release(This->runObjTab[index].pmkObj);
311 /* remove the object from the table */
312 for(j=index; j<This->runObjTabLastIndx-1; j++)
313 This->runObjTab[j]= This->runObjTab[j+1];
315 This->runObjTabLastIndx--;
317 return S_OK;
320 /***********************************************************************
321 * RunningObjectTable_IsRunning
323 HRESULT WINAPI RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface,
324 IMoniker *pmkObjectName) /* Pointer to the moniker of the object whose status is desired */
326 ICOM_THIS(RunningObjectTableImpl,iface);
328 TRACE(ole,"(%p,%p)\n",This,pmkObjectName);
330 return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
333 /***********************************************************************
334 * RunningObjectTable_GetObject
336 HRESULT WINAPI RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
337 IMoniker *pmkObjectName,/* Pointer to the moniker on the object */
338 IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */
340 DWORD index;
341 ICOM_THIS(RunningObjectTableImpl,iface);
343 TRACE(ole,"(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
345 if (ppunkObject==NULL)
346 return E_POINTER;
348 *ppunkObject=0;
350 /* verify if the object was registred befor or not */
351 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
352 return MK_E_UNAVAILABLE;
354 /* add a reference to the object then set output object argument */
355 IUnknown_AddRef(This->runObjTab[index].pObj);
356 *ppunkObject=This->runObjTab[index].pObj;
358 return S_OK;
361 /***********************************************************************
362 * RunningObjectTable_NoteChangeTime
364 HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
365 DWORD dwRegister, /* Value identifying registration being updated */
366 FILETIME *pfiletime) /* Pointer to structure containing object's last change time */
368 DWORD index=-1;
369 ICOM_THIS(RunningObjectTableImpl,iface);
371 TRACE(ole,"(%p,%ld,%p)\n",This,dwRegister,pfiletime);
373 /* verify if the object to be changed was registred befor or not */
374 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
375 return E_INVALIDARG;
377 /* set the new value of the last time change */
378 This->runObjTab[index].lastModifObj= (*pfiletime);
380 return S_OK;
383 /***********************************************************************
384 * RunningObjectTable_GetTimeOfLastChange
386 HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
387 IMoniker *pmkObjectName, /* Pointer to moniker on the object whose status is desired */
388 FILETIME *pfiletime) /* Pointer to structure that receives object's last change time */
390 DWORD index=-1;
391 ICOM_THIS(RunningObjectTableImpl,iface);
393 TRACE(ole,"(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
395 if (pmkObjectName==NULL || pfiletime==NULL)
396 return E_INVALIDARG;
398 /* verify if the object was registred befor or not */
399 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
400 return MK_E_UNAVAILABLE;;
402 (*pfiletime)= This->runObjTab[index].lastModifObj;
404 return S_OK;
407 /***********************************************************************
408 * RunningObjectTable_EnumRunning
410 HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
411 IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
413 FIXME(ole,"(%p,%p) needs the IEnumMoniker implementation \n",iface,ppenumMoniker);
414 return E_NOTIMPL;
417 /***********************************************************************
418 * GetObjectIndex
420 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
421 DWORD identReg,
422 IMoniker* pmk,
423 DWORD *indx)
426 DWORD i;
428 TRACE(ole,"(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);
430 if (pmk!=NULL)
431 /* search object identified by a moniker*/
432 for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
433 else
434 /* search object identified by a register identifier*/
435 for(i=0;((i<This->runObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++);
437 if (i==This->runObjTabLastIndx) return S_FALSE;
439 if (indx != NULL) *indx=i;
441 return S_OK;
444 /******************************************************************************
445 * GetRunningObjectTable16 [OLE2.30]
447 HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPVOID *pprot)
449 FIXME(ole,"(%ld,%p),stub!\n",reserved,pprot);
450 return E_NOTIMPL;
453 /***********************************************************************
454 * GetRunningObjectTable (OLE2.73)
456 HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPVOID *pprot)
458 IID riid=IID_IRunningObjectTable;
459 HRESULT res;
461 TRACE(ole,"()\n");
463 if (reserved!=0)
464 return E_UNEXPECTED;
466 if(runningObjectTableInstance==NULL)
467 return CO_E_NOTINITIALIZED;
469 res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
471 return res;