Get rid of the no longer used ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
[wine/multimedia.git] / dlls / ole32 / moniker.c
blob56dc4ae6d8b59be67c76d9d4e846495be955f8a9
1 /*
2 * Monikers
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
21 * TODO:
22 * - IRunningObjectTable should work interprocess, but currently doesn't.
23 * Native (on Win2k at least) uses an undocumented RPC interface, IROT, to
24 * communicate with RPCSS which contains the table of marshalled data.
25 * - IRunningObjectTable should use marshalling instead of simple ref
26 * counting as there is the possibility of using the running object table
27 * to access objects in other apartments.
30 #include <assert.h>
31 #include <stdarg.h>
32 #include <string.h>
34 #include "winerror.h"
35 #include "windef.h"
36 #include "winbase.h"
37 #include "winuser.h"
38 #include "wtypes.h"
39 #include "wine/debug.h"
40 #include "ole2.h"
42 #include "compobj_private.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(ole);
46 #define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
48 /* define the structure of the running object table elements */
49 typedef struct RunObject{
51 IUnknown* pObj; /* points on a running object*/
52 IMoniker* pmkObj; /* points on a moniker who identifies this object */
53 FILETIME lastModifObj;
54 DWORD identRegObj; /* registration key relative to this object */
55 DWORD regTypeObj; /* registration type : strong or weak */
56 }RunObject;
58 /* define the RunningObjectTableImpl structure */
59 typedef struct RunningObjectTableImpl{
61 IRunningObjectTableVtbl *lpVtbl;
62 ULONG ref;
64 RunObject* runObjTab; /* pointer to the first object in the table */
65 DWORD runObjTabSize; /* current table size */
66 DWORD runObjTabLastIndx; /* first free index element in the table. */
67 DWORD runObjTabRegister; /* registration key of the next registered object */
69 } RunningObjectTableImpl;
71 RunningObjectTableImpl* runningObjectTableInstance=0;
73 /* IRunningObjectTable prototype functions : */
74 /* IUnknown functions*/
75 static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject);
76 static ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface);
77 static ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface);
78 /* IRunningObjectTable functions */
79 static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister);
80 static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister);
81 static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName);
82 static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject);
83 static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime);
84 static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime);
85 static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker);
86 /* Local functions*/
87 HRESULT WINAPI RunningObjectTableImpl_Initialize();
88 HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
89 HRESULT WINAPI RunningObjectTableImpl_Destroy();
90 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);
92 /* Virtual function table for the IRunningObjectTable class. */
93 static IRunningObjectTableVtbl VT_RunningObjectTableImpl =
95 RunningObjectTableImpl_QueryInterface,
96 RunningObjectTableImpl_AddRef,
97 RunningObjectTableImpl_Release,
98 RunningObjectTableImpl_Register,
99 RunningObjectTableImpl_Revoke,
100 RunningObjectTableImpl_IsRunning,
101 RunningObjectTableImpl_GetObject,
102 RunningObjectTableImpl_NoteChangeTime,
103 RunningObjectTableImpl_GetTimeOfLastChange,
104 RunningObjectTableImpl_EnumRunning
107 /***********************************************************************
108 * RunningObjectTable_QueryInterface
110 HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
112 ICOM_THIS(RunningObjectTableImpl,iface);
114 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
116 /* validate arguments */
117 if (This==0)
118 return CO_E_NOTINITIALIZED;
120 if (ppvObject==0)
121 return E_INVALIDARG;
123 *ppvObject = 0;
125 if (IsEqualIID(&IID_IUnknown, riid))
126 *ppvObject = (IRunningObjectTable*)This;
127 else
128 if (IsEqualIID(&IID_IRunningObjectTable, riid))
129 *ppvObject = (IRunningObjectTable*)This;
131 if ((*ppvObject)==0)
132 return E_NOINTERFACE;
134 RunningObjectTableImpl_AddRef(iface);
136 return S_OK;
139 /***********************************************************************
140 * RunningObjectTable_AddRef
142 ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
144 ICOM_THIS(RunningObjectTableImpl,iface);
146 TRACE("(%p)\n",This);
148 return ++(This->ref);
151 /***********************************************************************
152 * RunningObjectTable_Initialize
154 HRESULT WINAPI RunningObjectTableImpl_Destroy()
156 TRACE("()\n");
158 if (runningObjectTableInstance==NULL)
159 return E_INVALIDARG;
161 /* free the ROT table memory */
162 HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
164 /* free the ROT structure memory */
165 HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
167 return S_OK;
170 /***********************************************************************
171 * RunningObjectTable_Release
173 ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
175 DWORD i;
176 ICOM_THIS(RunningObjectTableImpl,iface);
178 TRACE("(%p)\n",This);
180 This->ref--;
182 /* unitialize ROT structure if there's no more reference to it*/
183 if (This->ref==0){
185 /* release all registered objects */
186 for(i=0;i<This->runObjTabLastIndx;i++)
188 if (( This->runObjTab[i].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
189 IUnknown_Release(This->runObjTab[i].pObj);
191 IMoniker_Release(This->runObjTab[i].pmkObj);
193 /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
194 * when RunningObjectTableImpl_UnInitialize function is called
197 /* there's no more elements in the table */
198 This->runObjTabRegister=0;
199 This->runObjTabLastIndx=0;
201 return 0;
204 return This->ref;
207 /***********************************************************************
208 * RunningObjectTable_Initialize
210 HRESULT WINAPI RunningObjectTableImpl_Initialize()
212 TRACE("()\n");
214 /* create the unique instance of the RunningObjectTableImpl structure */
215 runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));
217 if (runningObjectTableInstance == 0)
218 return E_OUTOFMEMORY;
220 /* initialize the virtual table function */
221 runningObjectTableInstance->lpVtbl = &VT_RunningObjectTableImpl;
223 /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
224 /* the ROT referred many times not in the same time (all the objects in the ROT will */
225 /* be removed every time the ROT is removed ) */
226 runningObjectTableInstance->ref = 1;
228 /* allocate space memory for the table which contains all the running objects */
229 runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));
231 if (runningObjectTableInstance->runObjTab == NULL)
232 return E_OUTOFMEMORY;
234 runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
235 runningObjectTableInstance->runObjTabRegister=1;
236 runningObjectTableInstance->runObjTabLastIndx=0;
238 return S_OK;
241 /***********************************************************************
242 * RunningObjectTable_UnInitialize
244 HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
246 TRACE("()\n");
248 if (runningObjectTableInstance==NULL)
249 return E_POINTER;
251 RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
253 RunningObjectTableImpl_Destroy();
255 return S_OK;
258 /***********************************************************************
259 * RunningObjectTable_Register
261 HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface,
262 DWORD grfFlags, /* Registration options */
263 IUnknown *punkObject, /* Pointer to the object being registered */
264 IMoniker *pmkObjectName, /* Pointer to the moniker of the object being registered */
265 DWORD *pdwRegister) /* Pointer to the value identifying the registration */
267 HRESULT res=S_OK;
268 ICOM_THIS(RunningObjectTableImpl,iface);
270 TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
272 /* there's only two types of register : strong and or weak registration (only one must be passed on parameter) */
273 if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
274 (!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
275 (grfFlags) )
276 return E_INVALIDARG;
278 if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
279 return E_INVALIDARG;
281 /* verify if the object to be registered was registered before */
282 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
283 res = MK_S_MONIKERALREADYREGISTERED;
285 /* put the new registered object in the first free element in the table */
286 This->runObjTab[This->runObjTabLastIndx].pObj = punkObject;
287 This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName;
288 This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags;
289 This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister;
290 CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj));
292 /* gives a registration identifier to the registered object*/
293 (*pdwRegister)= This->runObjTabRegister;
295 if (This->runObjTabRegister == 0xFFFFFFFF){
297 FIXME("runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister);
298 return E_FAIL;
300 This->runObjTabRegister++;
301 This->runObjTabLastIndx++;
303 if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */
305 This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */
306 This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab,
307 This->runObjTabSize * sizeof(RunObject));
308 if (!This->runObjTab)
309 return E_OUTOFMEMORY;
311 /* add a reference to the object in the strong registration case */
312 if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 ) {
313 TRACE("strong registration, reffing %p\n", punkObject);
314 /* this is wrong; we should always add a reference to the object */
315 IUnknown_AddRef(punkObject);
318 IMoniker_AddRef(pmkObjectName);
320 return res;
323 /***********************************************************************
324 * RunningObjectTable_Revoke
326 HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface,
327 DWORD dwRegister) /* Value identifying registration to be revoked*/
330 DWORD index,j;
331 ICOM_THIS(RunningObjectTableImpl,iface);
333 TRACE("(%p,%ld)\n",This,dwRegister);
335 /* verify if the object to be revoked was registered before or not */
336 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
338 return E_INVALIDARG;
340 /* release the object if it was registered with a strong registrantion option */
341 if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0) {
342 TRACE("releasing %p\n", This->runObjTab[index].pObj);
343 /* this is also wrong; we should always release the object (see above) */
344 IUnknown_Release(This->runObjTab[index].pObj);
347 IMoniker_Release(This->runObjTab[index].pmkObj);
349 /* remove the object from the table */
350 for(j=index; j<This->runObjTabLastIndx-1; j++)
351 This->runObjTab[j]= This->runObjTab[j+1];
353 This->runObjTabLastIndx--;
355 return S_OK;
358 /***********************************************************************
359 * RunningObjectTable_IsRunning
361 HRESULT WINAPI RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface,
362 IMoniker *pmkObjectName) /* Pointer to the moniker of the object whose status is desired */
364 ICOM_THIS(RunningObjectTableImpl,iface);
366 TRACE("(%p,%p)\n",This,pmkObjectName);
368 return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
371 /***********************************************************************
372 * RunningObjectTable_GetObject
374 HRESULT WINAPI RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
375 IMoniker *pmkObjectName,/* Pointer to the moniker on the object */
376 IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */
378 DWORD index;
379 ICOM_THIS(RunningObjectTableImpl,iface);
381 TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
383 if (ppunkObject==NULL)
384 return E_POINTER;
386 *ppunkObject=0;
388 /* verify if the object was registered before or not */
389 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE) {
390 WARN("Moniker unavailable - needs to work interprocess?\n");
391 return MK_E_UNAVAILABLE;
394 /* add a reference to the object then set output object argument */
395 IUnknown_AddRef(This->runObjTab[index].pObj);
396 *ppunkObject=This->runObjTab[index].pObj;
398 return S_OK;
401 /***********************************************************************
402 * RunningObjectTable_NoteChangeTime
404 HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
405 DWORD dwRegister, /* Value identifying registration being updated */
406 FILETIME *pfiletime) /* Pointer to structure containing object's last change time */
408 DWORD index=-1;
409 ICOM_THIS(RunningObjectTableImpl,iface);
411 TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);
413 /* verify if the object to be changed was registered before or not */
414 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
415 return E_INVALIDARG;
417 /* set the new value of the last time change */
418 This->runObjTab[index].lastModifObj= (*pfiletime);
420 return S_OK;
423 /***********************************************************************
424 * RunningObjectTable_GetTimeOfLastChange
426 HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
427 IMoniker *pmkObjectName, /* Pointer to moniker on the object whose status is desired */
428 FILETIME *pfiletime) /* Pointer to structure that receives object's last change time */
430 DWORD index=-1;
431 ICOM_THIS(RunningObjectTableImpl,iface);
433 TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
435 if (pmkObjectName==NULL || pfiletime==NULL)
436 return E_INVALIDARG;
438 /* verify if the object was registered before or not */
439 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
440 return MK_E_UNAVAILABLE;
442 (*pfiletime)= This->runObjTab[index].lastModifObj;
444 return S_OK;
447 /***********************************************************************
448 * RunningObjectTable_EnumRunning
450 HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
451 IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
453 FIXME("(%p,%p) needs the IEnumMoniker implementation \n",iface,ppenumMoniker);
454 return E_NOTIMPL;
457 /***********************************************************************
458 * GetObjectIndex
460 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
461 DWORD identReg,
462 IMoniker* pmk,
463 DWORD *indx)
466 DWORD i;
468 TRACE("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);
470 if (pmk!=NULL)
471 /* search object identified by a moniker */
472 for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
473 else
474 /* search object identified by a register identifier */
475 for(i=0;((i<This->runObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++);
477 if (i==This->runObjTabLastIndx) return S_FALSE;
479 if (indx != NULL) *indx=i;
481 return S_OK;
484 /******************************************************************************
485 * GetRunningObjectTable (OLE2.30)
487 HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
489 FIXME("(%ld,%p),stub!\n",reserved,pprot);
490 return E_NOTIMPL;
493 /***********************************************************************
494 * GetRunningObjectTable (OLE32.@)
496 HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
498 IID riid=IID_IRunningObjectTable;
499 HRESULT res;
501 TRACE("()\n");
503 if (reserved!=0)
504 return E_UNEXPECTED;
506 if(runningObjectTableInstance==NULL)
507 return CO_E_NOTINITIALIZED;
509 res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
511 return res;
514 /******************************************************************************
515 * OleRun [OLE32.@]
517 HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
519 IRunnableObject *runable;
520 ICOM_THIS(IRunnableObject,pUnknown);
521 LRESULT ret;
523 ret = IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable);
524 if (ret)
525 return 0; /* Appears to return no error. */
526 ret = IRunnableObject_Run(runable,NULL);
527 IRunnableObject_Release(runable);
528 return ret;
531 /******************************************************************************
532 * MkParseDisplayName [OLE32.@]
534 HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szUserName,
535 LPDWORD pchEaten, LPMONIKER *ppmk)
537 FIXME("(%p, %s, %p, %p): stub.\n", pbc, debugstr_w(szUserName), pchEaten, *ppmk);
538 if (!(IsValidInterface((LPUNKNOWN) pbc)))
539 return E_INVALIDARG;
541 return MK_E_SYNTAX;
544 /******************************************************************************
545 * CreateClassMoniker [OLE32.@]
547 HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, IMoniker ** ppmk)
549 FIXME("%s\n", debugstr_guid( rclsid ));
550 if( ppmk )
551 *ppmk = NULL;
552 return E_NOTIMPL;