Converted to the new debug interface, using script written by Patrik
[wine/multimedia.git] / ole / moniker.c
blob32a9e6d8f940be800d4e5fc679684499ce85df9a
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 "debugtools.h"
12 #include "heap.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 */
26 }RunObject;
28 /* define de RunningObjectTableImpl structure */
29 typedef struct RunningObjectTableImpl{
31 ICOM_VTABLE(IRunningObjectTable)* lpvtbl;
32 ULONG ref;
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);
56 /* Local functions*/
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*/
88 if (This==0)
89 return CO_E_NOTINITIALIZED;
91 if (ppvObject==0)
92 return E_INVALIDARG;
94 *ppvObject = 0;
96 if (IsEqualIID(&IID_IUnknown, riid))
97 *ppvObject = (IRunningObjectTable*)This;
98 else
99 if (IsEqualIID(&IID_IRunningObjectTable, riid))
100 *ppvObject = (IRunningObjectTable*)This;
102 if ((*ppvObject)==0)
103 return E_NOINTERFACE;
105 RunningObjectTableImpl_AddRef(iface);
107 return S_OK;
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()
127 TRACE("()\n");
129 if (runningObjectTableInstance==NULL)
130 return E_INVALIDARG;
132 /* free the ROT table memory */
133 HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
135 /* free the ROT structure memory */
136 HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
138 return S_OK;
141 /***********************************************************************
142 * RunningObjectTable_Release
144 ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
146 DWORD i;
147 ICOM_THIS(RunningObjectTableImpl,iface);
149 TRACE("(%p)\n",This);
151 This->ref--;
153 /* unitialize ROT structure if there's no more reference to it*/
154 if (This->ref==0){
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;
172 return 0;
175 return This->ref;
178 /***********************************************************************
179 * RunningObjectTable_Initialize
181 HRESULT WINAPI RunningObjectTableImpl_Initialize()
183 TRACE("()\n");
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;
209 return S_OK;
212 /***********************************************************************
213 * RunningObjectTable_UnInitialize
215 HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
217 TRACE("()\n");
219 if (runningObjectTableInstance==NULL)
220 return E_POINTER;
222 RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
224 RunningObjectTableImpl_Destroy();
226 return S_OK;
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 */
238 HRESULT res=S_OK;
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)) &&
246 (grfFlags) )
247 return E_INVALIDARG;
249 if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
250 return E_INVALIDARG;
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);
269 return E_FAIL;
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);
288 return res;
291 /***********************************************************************
292 * RunningObjectTable_Revoke
294 HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface,
295 DWORD dwRegister) /* Value identifying registration to be revoked*/
298 DWORD index,j;
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)
306 return E_INVALIDARG;
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--;
320 return S_OK;
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 */
343 DWORD index;
344 ICOM_THIS(RunningObjectTableImpl,iface);
346 TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
348 if (ppunkObject==NULL)
349 return E_POINTER;
351 *ppunkObject=0;
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;
361 return S_OK;
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 */
371 DWORD index=-1;
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)
378 return E_INVALIDARG;
380 /* set the new value of the last time change */
381 This->runObjTab[index].lastModifObj= (*pfiletime);
383 return S_OK;
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 */
393 DWORD index=-1;
394 ICOM_THIS(RunningObjectTableImpl,iface);
396 TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
398 if (pmkObjectName==NULL || pfiletime==NULL)
399 return E_INVALIDARG;
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;
407 return S_OK;
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);
417 return E_NOTIMPL;
420 /***********************************************************************
421 * GetObjectIndex
423 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
424 DWORD identReg,
425 IMoniker* pmk,
426 DWORD *indx)
429 DWORD i;
431 TRACE("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);
433 if (pmk!=NULL)
434 /* search object identified by a moniker*/
435 for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
436 else
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;
444 return S_OK;
447 /******************************************************************************
448 * GetRunningObjectTable16 [OLE2.30]
450 HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
452 FIXME("(%ld,%p),stub!\n",reserved,pprot);
453 return E_NOTIMPL;
456 /***********************************************************************
457 * GetRunningObjectTable (OLE2.73)
459 HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
461 IID riid=IID_IRunningObjectTable;
462 HRESULT res;
464 TRACE("()\n");
466 if (reserved!=0)
467 return E_UNEXPECTED;
469 if(runningObjectTableInstance==NULL)
470 return CO_E_NOTINITIALIZED;
472 res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
474 return res;