Fixed header dependencies to be fully compatible with the Windows
[wine/multimedia.git] / dlls / ole32 / moniker.c
blob5163321a7b7ee748ec0d9118c72a4d065dd5bb6a
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
22 #include <assert.h>
23 #include <stdarg.h>
24 #include <string.h>
26 #include "winerror.h"
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wtypes.h"
30 #include "wine/debug.h"
31 #include "ole2.h"
33 #include "compobj_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ole);
37 #define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
39 /* define the structure of the running object table elements */
40 typedef struct RunObject{
42 IUnknown* pObj; /* points on a running object*/
43 IMoniker* pmkObj; /* points on a moniker who identifies this object */
44 FILETIME lastModifObj;
45 DWORD identRegObj; /* registration key relative to this object */
46 DWORD regTypeObj; /* registration type : strong or weak */
47 }RunObject;
49 /* define the RunningObjectTableImpl structure */
50 typedef struct RunningObjectTableImpl{
52 ICOM_VFIELD(IRunningObjectTable);
53 ULONG ref;
55 RunObject* runObjTab; /* pointer to the first object in the table */
56 DWORD runObjTabSize; /* current table size */
57 DWORD runObjTabLastIndx; /* first free index element in the table. */
58 DWORD runObjTabRegister; /* registration key of the next registered object */
60 } RunningObjectTableImpl;
62 RunningObjectTableImpl* runningObjectTableInstance=0;
64 /* IRunningObjectTable prototype functions : */
65 /* IUnknown functions*/
66 static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject);
67 static ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface);
68 static ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface);
69 /* IRunningObjectTable functions */
70 static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister);
71 static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister);
72 static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName);
73 static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject);
74 static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime);
75 static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime);
76 static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker);
77 /* Local functions*/
78 HRESULT WINAPI RunningObjectTableImpl_Initialize();
79 HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
80 HRESULT WINAPI RunningObjectTableImpl_Destroy();
81 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);
83 /* Virtual function table for the IRunningObjectTable class. */
84 static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl =
86 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
87 RunningObjectTableImpl_QueryInterface,
88 RunningObjectTableImpl_AddRef,
89 RunningObjectTableImpl_Release,
90 RunningObjectTableImpl_Register,
91 RunningObjectTableImpl_Revoke,
92 RunningObjectTableImpl_IsRunning,
93 RunningObjectTableImpl_GetObject,
94 RunningObjectTableImpl_NoteChangeTime,
95 RunningObjectTableImpl_GetTimeOfLastChange,
96 RunningObjectTableImpl_EnumRunning
99 /***********************************************************************
100 * RunningObjectTable_QueryInterface
102 HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
104 ICOM_THIS(RunningObjectTableImpl,iface);
106 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
108 /* validate arguments */
109 if (This==0)
110 return CO_E_NOTINITIALIZED;
112 if (ppvObject==0)
113 return E_INVALIDARG;
115 *ppvObject = 0;
117 if (IsEqualIID(&IID_IUnknown, riid))
118 *ppvObject = (IRunningObjectTable*)This;
119 else
120 if (IsEqualIID(&IID_IRunningObjectTable, riid))
121 *ppvObject = (IRunningObjectTable*)This;
123 if ((*ppvObject)==0)
124 return E_NOINTERFACE;
126 RunningObjectTableImpl_AddRef(iface);
128 return S_OK;
131 /***********************************************************************
132 * RunningObjectTable_AddRef
134 ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
136 ICOM_THIS(RunningObjectTableImpl,iface);
138 TRACE("(%p)\n",This);
140 return ++(This->ref);
143 /***********************************************************************
144 * RunningObjectTable_Initialize
146 HRESULT WINAPI RunningObjectTableImpl_Destroy()
148 TRACE("()\n");
150 if (runningObjectTableInstance==NULL)
151 return E_INVALIDARG;
153 /* free the ROT table memory */
154 HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
156 /* free the ROT structure memory */
157 HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
159 return S_OK;
162 /***********************************************************************
163 * RunningObjectTable_Release
165 ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
167 DWORD i;
168 ICOM_THIS(RunningObjectTableImpl,iface);
170 TRACE("(%p)\n",This);
172 This->ref--;
174 /* unitialize ROT structure if there's no more reference to it*/
175 if (This->ref==0){
177 /* release all registered objects */
178 for(i=0;i<This->runObjTabLastIndx;i++)
180 if (( This->runObjTab[i].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
181 IUnknown_Release(This->runObjTab[i].pObj);
183 IMoniker_Release(This->runObjTab[i].pmkObj);
185 /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
186 * when RunningObjectTableImpl_UnInitialize function is called
189 /* there's no more elements in the table */
190 This->runObjTabRegister=0;
191 This->runObjTabLastIndx=0;
193 return 0;
196 return This->ref;
199 /***********************************************************************
200 * RunningObjectTable_Initialize
202 HRESULT WINAPI RunningObjectTableImpl_Initialize()
204 TRACE("()\n");
206 /* create the unique instance of the RunningObjectTableImpl structure */
207 runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));
209 if (runningObjectTableInstance == 0)
210 return E_OUTOFMEMORY;
212 /* initialize the virtual table function */
213 runningObjectTableInstance->lpVtbl = &VT_RunningObjectTableImpl;
215 /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
216 /* the ROT referred many times not in the same time (all the objects in the ROT will */
217 /* be removed every time the ROT is removed ) */
218 runningObjectTableInstance->ref = 1;
220 /* allocate space memory for the table which contains all the running objects */
221 runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));
223 if (runningObjectTableInstance->runObjTab == NULL)
224 return E_OUTOFMEMORY;
226 runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
227 runningObjectTableInstance->runObjTabRegister=1;
228 runningObjectTableInstance->runObjTabLastIndx=0;
230 return S_OK;
233 /***********************************************************************
234 * RunningObjectTable_UnInitialize
236 HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
238 TRACE("()\n");
240 if (runningObjectTableInstance==NULL)
241 return E_POINTER;
243 RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
245 RunningObjectTableImpl_Destroy();
247 return S_OK;
250 /***********************************************************************
251 * RunningObjectTable_Register
253 HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface,
254 DWORD grfFlags, /* Registration options */
255 IUnknown *punkObject, /* Pointer to the object being registered */
256 IMoniker *pmkObjectName, /* Pointer to the moniker of the object being registered */
257 DWORD *pdwRegister) /* Pointer to the value identifying the registration */
259 HRESULT res=S_OK;
260 ICOM_THIS(RunningObjectTableImpl,iface);
262 TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
264 /* there's only two types of register : strong and or weak registration (only one must be passed on parameter) */
265 if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
266 (!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
267 (grfFlags) )
268 return E_INVALIDARG;
270 if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
271 return E_INVALIDARG;
273 /* verify if the object to be registered was registered before */
274 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
275 res = MK_S_MONIKERALREADYREGISTERED;
277 /* put the new registered object in the first free element in the table */
278 This->runObjTab[This->runObjTabLastIndx].pObj = punkObject;
279 This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName;
280 This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags;
281 This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister;
282 CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj));
284 /* gives a registration identifier to the registered object*/
285 (*pdwRegister)= This->runObjTabRegister;
287 if (This->runObjTabRegister == 0xFFFFFFFF){
289 FIXME("runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister);
290 return E_FAIL;
292 This->runObjTabRegister++;
293 This->runObjTabLastIndx++;
295 if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */
297 This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */
298 This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab,
299 This->runObjTabSize * sizeof(RunObject));
300 if (!This->runObjTab)
301 return E_OUTOFMEMORY;
303 /* add a reference to the object in the strong registration case */
304 if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 )
305 IUnknown_AddRef(punkObject);
307 IMoniker_AddRef(pmkObjectName);
309 return res;
312 /***********************************************************************
313 * RunningObjectTable_Revoke
315 HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface,
316 DWORD dwRegister) /* Value identifying registration to be revoked*/
319 DWORD index,j;
320 ICOM_THIS(RunningObjectTableImpl,iface);
322 TRACE("(%p,%ld)\n",This,dwRegister);
324 /* verify if the object to be revoked was registered before or not */
325 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
327 return E_INVALIDARG;
329 /* release the object if it was registered with a strong registrantion option */
330 if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0)
331 IUnknown_Release(This->runObjTab[index].pObj);
333 IMoniker_Release(This->runObjTab[index].pmkObj);
335 /* remove the object from the table */
336 for(j=index; j<This->runObjTabLastIndx-1; j++)
337 This->runObjTab[j]= This->runObjTab[j+1];
339 This->runObjTabLastIndx--;
341 return S_OK;
344 /***********************************************************************
345 * RunningObjectTable_IsRunning
347 HRESULT WINAPI RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface,
348 IMoniker *pmkObjectName) /* Pointer to the moniker of the object whose status is desired */
350 ICOM_THIS(RunningObjectTableImpl,iface);
352 TRACE("(%p,%p)\n",This,pmkObjectName);
354 return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
357 /***********************************************************************
358 * RunningObjectTable_GetObject
360 HRESULT WINAPI RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
361 IMoniker *pmkObjectName,/* Pointer to the moniker on the object */
362 IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */
364 DWORD index;
365 ICOM_THIS(RunningObjectTableImpl,iface);
367 TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
369 if (ppunkObject==NULL)
370 return E_POINTER;
372 *ppunkObject=0;
374 /* verify if the object was registered before or not */
375 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
376 return MK_E_UNAVAILABLE;
378 /* add a reference to the object then set output object argument */
379 IUnknown_AddRef(This->runObjTab[index].pObj);
380 *ppunkObject=This->runObjTab[index].pObj;
382 return S_OK;
385 /***********************************************************************
386 * RunningObjectTable_NoteChangeTime
388 HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
389 DWORD dwRegister, /* Value identifying registration being updated */
390 FILETIME *pfiletime) /* Pointer to structure containing object's last change time */
392 DWORD index=-1;
393 ICOM_THIS(RunningObjectTableImpl,iface);
395 TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);
397 /* verify if the object to be changed was registered before or not */
398 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
399 return E_INVALIDARG;
401 /* set the new value of the last time change */
402 This->runObjTab[index].lastModifObj= (*pfiletime);
404 return S_OK;
407 /***********************************************************************
408 * RunningObjectTable_GetTimeOfLastChange
410 HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
411 IMoniker *pmkObjectName, /* Pointer to moniker on the object whose status is desired */
412 FILETIME *pfiletime) /* Pointer to structure that receives object's last change time */
414 DWORD index=-1;
415 ICOM_THIS(RunningObjectTableImpl,iface);
417 TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
419 if (pmkObjectName==NULL || pfiletime==NULL)
420 return E_INVALIDARG;
422 /* verify if the object was registered before or not */
423 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
424 return MK_E_UNAVAILABLE;
426 (*pfiletime)= This->runObjTab[index].lastModifObj;
428 return S_OK;
431 /***********************************************************************
432 * RunningObjectTable_EnumRunning
434 HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
435 IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
437 FIXME("(%p,%p) needs the IEnumMoniker implementation \n",iface,ppenumMoniker);
438 return E_NOTIMPL;
441 /***********************************************************************
442 * GetObjectIndex
444 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
445 DWORD identReg,
446 IMoniker* pmk,
447 DWORD *indx)
450 DWORD i;
452 TRACE("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);
454 if (pmk!=NULL)
455 /* search object identified by a moniker */
456 for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
457 else
458 /* search object identified by a register identifier */
459 for(i=0;((i<This->runObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++);
461 if (i==This->runObjTabLastIndx) return S_FALSE;
463 if (indx != NULL) *indx=i;
465 return S_OK;
468 /******************************************************************************
469 * GetRunningObjectTable [OLE2.30]
471 HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
473 FIXME("(%ld,%p),stub!\n",reserved,pprot);
474 return E_NOTIMPL;
477 /***********************************************************************
478 * GetRunningObjectTable (OLE32.73)
480 HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
482 IID riid=IID_IRunningObjectTable;
483 HRESULT res;
485 TRACE("()\n");
487 if (reserved!=0)
488 return E_UNEXPECTED;
490 if(runningObjectTableInstance==NULL)
491 return CO_E_NOTINITIALIZED;
493 res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
495 return res;
498 /******************************************************************************
499 * OleRun [OLE32.123]
501 HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
503 IRunnableObject *runable;
504 ICOM_THIS(IRunnableObject,pUnknown);
505 LRESULT ret;
507 ret = IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable);
508 if (ret)
509 return 0; /* Appears to return no error. */
510 ret = IRunnableObject_Run(runable,NULL);
511 IRunnableObject_Release(runable);
512 return ret;
515 /******************************************************************************
516 * MkParseDisplayName [OLE32.81]
518 HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szUserName,
519 LPDWORD pchEaten, LPMONIKER *ppmk)
521 FIXME("(%p, %s, %p, %p): stub.\n", pbc, debugstr_w(szUserName), pchEaten, *ppmk);
522 if (!(IsValidInterface((LPUNKNOWN) pbc)))
523 return E_INVALIDARG;
525 return MK_E_SYNTAX;
528 /******************************************************************************
529 * CreateClassMoniker [OLE32.*]
531 HRESULT WINAPI CreateClassMoniker(REFCLSID rclsid, IMoniker ** ppmk)
533 FIXME("%s\n", debugstr_guid( rclsid ));
534 if( ppmk )
535 *ppmk = NULL;
536 return E_NOTIMPL;