Improved a bit link handling (a few more link types loaded from file
[wine/hacks.git] / dlls / ole32 / moniker.c
blob103d450896b5c984f3afebc1ff7677603b020161
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 <string.h>
25 #include "winerror.h"
26 #include "winbase.h"
27 #include "wtypes.h"
28 #include "wine/obj_base.h"
29 #include "wine/obj_storage.h"
30 #include "wine/obj_misc.h"
31 #include "wine/obj_moniker.h"
32 #include "wine/debug.h"
33 #include "ole2.h"
35 #include "compobj_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(ole);
39 #define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
41 /* define the structure of the running object table elements */
42 typedef struct RunObject{
44 IUnknown* pObj; /* points on a running object*/
45 IMoniker* pmkObj; /* points on a moniker who identifies this object */
46 FILETIME lastModifObj;
47 DWORD identRegObj; /* registration key relative to this object */
48 DWORD regTypeObj; /* registration type : strong or weak */
49 }RunObject;
51 /* define the RunningObjectTableImpl structure */
52 typedef struct RunningObjectTableImpl{
54 ICOM_VFIELD(IRunningObjectTable);
55 ULONG ref;
57 RunObject* runObjTab; /* pointer to the first object in the table */
58 DWORD runObjTabSize; /* current table size */
59 DWORD runObjTabLastIndx; /* first free index element in the table. */
60 DWORD runObjTabRegister; /* registration key of the next registered object */
62 } RunningObjectTableImpl;
64 RunningObjectTableImpl* runningObjectTableInstance=0;
66 /* IRunningObjectTable prototype functions : */
67 /* IUnknown functions*/
68 static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject);
69 static ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface);
70 static ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface);
71 /* IRunningObjectTable functions */
72 static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister);
73 static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister);
74 static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName);
75 static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject);
76 static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime);
77 static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime);
78 static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker);
79 /* Local functions*/
80 HRESULT WINAPI RunningObjectTableImpl_Initialize();
81 HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
82 HRESULT WINAPI RunningObjectTableImpl_Destroy();
83 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);
85 /* Virtual function table for the IRunningObjectTable class. */
86 static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl =
88 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
89 RunningObjectTableImpl_QueryInterface,
90 RunningObjectTableImpl_AddRef,
91 RunningObjectTableImpl_Release,
92 RunningObjectTableImpl_Register,
93 RunningObjectTableImpl_Revoke,
94 RunningObjectTableImpl_IsRunning,
95 RunningObjectTableImpl_GetObject,
96 RunningObjectTableImpl_NoteChangeTime,
97 RunningObjectTableImpl_GetTimeOfLastChange,
98 RunningObjectTableImpl_EnumRunning
101 /***********************************************************************
102 * RunningObjectTable_QueryInterface
104 HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
106 ICOM_THIS(RunningObjectTableImpl,iface);
108 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
110 /* validate arguments */
111 if (This==0)
112 return CO_E_NOTINITIALIZED;
114 if (ppvObject==0)
115 return E_INVALIDARG;
117 *ppvObject = 0;
119 if (IsEqualIID(&IID_IUnknown, riid))
120 *ppvObject = (IRunningObjectTable*)This;
121 else
122 if (IsEqualIID(&IID_IRunningObjectTable, riid))
123 *ppvObject = (IRunningObjectTable*)This;
125 if ((*ppvObject)==0)
126 return E_NOINTERFACE;
128 RunningObjectTableImpl_AddRef(iface);
130 return S_OK;
133 /***********************************************************************
134 * RunningObjectTable_AddRef
136 ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
138 ICOM_THIS(RunningObjectTableImpl,iface);
140 TRACE("(%p)\n",This);
142 return ++(This->ref);
145 /***********************************************************************
146 * RunningObjectTable_Initialize
148 HRESULT WINAPI RunningObjectTableImpl_Destroy()
150 TRACE("()\n");
152 if (runningObjectTableInstance==NULL)
153 return E_INVALIDARG;
155 /* free the ROT table memory */
156 HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
158 /* free the ROT structure memory */
159 HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
161 return S_OK;
164 /***********************************************************************
165 * RunningObjectTable_Release
167 ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
169 DWORD i;
170 ICOM_THIS(RunningObjectTableImpl,iface);
172 TRACE("(%p)\n",This);
174 This->ref--;
176 /* unitialize ROT structure if there's no more reference to it*/
177 if (This->ref==0){
179 /* release all registered objects */
180 for(i=0;i<This->runObjTabLastIndx;i++)
182 if (( This->runObjTab[i].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
183 IUnknown_Release(This->runObjTab[i].pObj);
185 IMoniker_Release(This->runObjTab[i].pmkObj);
187 /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
188 * when RunningObjectTableImpl_UnInitialize function is called
191 /* there's no more elements in the table */
192 This->runObjTabRegister=0;
193 This->runObjTabLastIndx=0;
195 return 0;
198 return This->ref;
201 /***********************************************************************
202 * RunningObjectTable_Initialize
204 HRESULT WINAPI RunningObjectTableImpl_Initialize()
206 TRACE("()\n");
208 /* create the unique instance of the RunningObjectTableImpl structure */
209 runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));
211 if (runningObjectTableInstance == 0)
212 return E_OUTOFMEMORY;
214 /* initialize the virtual table function */
215 ICOM_VTBL(runningObjectTableInstance) = &VT_RunningObjectTableImpl;
217 /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
218 /* the ROT refered many times not in the same time (all the objects in the ROT will */
219 /* be removed every time the ROT is removed ) */
220 runningObjectTableInstance->ref = 1;
222 /* allocate space memory for the table which contains all the running objects */
223 runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));
225 if (runningObjectTableInstance->runObjTab == NULL)
226 return E_OUTOFMEMORY;
228 runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
229 runningObjectTableInstance->runObjTabRegister=1;
230 runningObjectTableInstance->runObjTabLastIndx=0;
232 return S_OK;
235 /***********************************************************************
236 * RunningObjectTable_UnInitialize
238 HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
240 TRACE("()\n");
242 if (runningObjectTableInstance==NULL)
243 return E_POINTER;
245 RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
247 RunningObjectTableImpl_Destroy();
249 return S_OK;
252 /***********************************************************************
253 * RunningObjectTable_Register
255 HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface,
256 DWORD grfFlags, /* Registration options */
257 IUnknown *punkObject, /* Pointer to the object being registered */
258 IMoniker *pmkObjectName, /* Pointer to the moniker of the object being registered */
259 DWORD *pdwRegister) /* Pointer to the value identifying the registration */
261 HRESULT res=S_OK;
262 ICOM_THIS(RunningObjectTableImpl,iface);
264 TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
266 /* there's only two types of register : strong and or weak registration (only one must be passed on parameter) */
267 if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
268 (!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
269 (grfFlags) )
270 return E_INVALIDARG;
272 if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
273 return E_INVALIDARG;
275 /* verify if the object to be registered was registered before */
276 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
277 res = MK_S_MONIKERALREADYREGISTERED;
279 /* put the new registered object in the first free element in the table */
280 This->runObjTab[This->runObjTabLastIndx].pObj = punkObject;
281 This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName;
282 This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags;
283 This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister;
284 CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj));
286 /* gives a registration identifier to the registered object*/
287 (*pdwRegister)= This->runObjTabRegister;
289 if (This->runObjTabRegister == 0xFFFFFFFF){
291 FIXME("runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister);
292 return E_FAIL;
294 This->runObjTabRegister++;
295 This->runObjTabLastIndx++;
297 if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */
299 This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */
300 This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab,
301 This->runObjTabSize * sizeof(RunObject));
302 if (!This->runObjTab)
303 return E_OUTOFMEMORY;
305 /* add a reference to the object in the strong registration case */
306 if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 )
307 IUnknown_AddRef(punkObject);
309 IMoniker_AddRef(pmkObjectName);
311 return res;
314 /***********************************************************************
315 * RunningObjectTable_Revoke
317 HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface,
318 DWORD dwRegister) /* Value identifying registration to be revoked*/
321 DWORD index,j;
322 ICOM_THIS(RunningObjectTableImpl,iface);
324 TRACE("(%p,%ld)\n",This,dwRegister);
326 /* verify if the object to be revoked was registered before or not */
327 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
329 return E_INVALIDARG;
331 /* release the object if it was registered with a strong registrantion option */
332 if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0)
333 IUnknown_Release(This->runObjTab[index].pObj);
335 IMoniker_Release(This->runObjTab[index].pmkObj);
337 /* remove the object from the table */
338 for(j=index; j<This->runObjTabLastIndx-1; j++)
339 This->runObjTab[j]= This->runObjTab[j+1];
341 This->runObjTabLastIndx--;
343 return S_OK;
346 /***********************************************************************
347 * RunningObjectTable_IsRunning
349 HRESULT WINAPI RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface,
350 IMoniker *pmkObjectName) /* Pointer to the moniker of the object whose status is desired */
352 ICOM_THIS(RunningObjectTableImpl,iface);
354 TRACE("(%p,%p)\n",This,pmkObjectName);
356 return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
359 /***********************************************************************
360 * RunningObjectTable_GetObject
362 HRESULT WINAPI RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
363 IMoniker *pmkObjectName,/* Pointer to the moniker on the object */
364 IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */
366 DWORD index;
367 ICOM_THIS(RunningObjectTableImpl,iface);
369 TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
371 if (ppunkObject==NULL)
372 return E_POINTER;
374 *ppunkObject=0;
376 /* verify if the object was registered before or not */
377 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
378 return MK_E_UNAVAILABLE;
380 /* add a reference to the object then set output object argument */
381 IUnknown_AddRef(This->runObjTab[index].pObj);
382 *ppunkObject=This->runObjTab[index].pObj;
384 return S_OK;
387 /***********************************************************************
388 * RunningObjectTable_NoteChangeTime
390 HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
391 DWORD dwRegister, /* Value identifying registration being updated */
392 FILETIME *pfiletime) /* Pointer to structure containing object's last change time */
394 DWORD index=-1;
395 ICOM_THIS(RunningObjectTableImpl,iface);
397 TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);
399 /* verify if the object to be changed was registered before or not */
400 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
401 return E_INVALIDARG;
403 /* set the new value of the last time change */
404 This->runObjTab[index].lastModifObj= (*pfiletime);
406 return S_OK;
409 /***********************************************************************
410 * RunningObjectTable_GetTimeOfLastChange
412 HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
413 IMoniker *pmkObjectName, /* Pointer to moniker on the object whose status is desired */
414 FILETIME *pfiletime) /* Pointer to structure that receives object's last change time */
416 DWORD index=-1;
417 ICOM_THIS(RunningObjectTableImpl,iface);
419 TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
421 if (pmkObjectName==NULL || pfiletime==NULL)
422 return E_INVALIDARG;
424 /* verify if the object was registered before or not */
425 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
426 return MK_E_UNAVAILABLE;
428 (*pfiletime)= This->runObjTab[index].lastModifObj;
430 return S_OK;
433 /***********************************************************************
434 * RunningObjectTable_EnumRunning
436 HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
437 IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
439 FIXME("(%p,%p) needs the IEnumMoniker implementation \n",iface,ppenumMoniker);
440 return E_NOTIMPL;
443 /***********************************************************************
444 * GetObjectIndex
446 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
447 DWORD identReg,
448 IMoniker* pmk,
449 DWORD *indx)
452 DWORD i;
454 TRACE("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);
456 if (pmk!=NULL)
457 /* search object identified by a moniker */
458 for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
459 else
460 /* search object identified by a register identifier */
461 for(i=0;((i<This->runObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++);
463 if (i==This->runObjTabLastIndx) return S_FALSE;
465 if (indx != NULL) *indx=i;
467 return S_OK;
470 /******************************************************************************
471 * GetRunningObjectTable [OLE2.30]
473 HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
475 FIXME("(%ld,%p),stub!\n",reserved,pprot);
476 return E_NOTIMPL;
479 /***********************************************************************
480 * GetRunningObjectTable (OLE32.73)
482 HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
484 IID riid=IID_IRunningObjectTable;
485 HRESULT res;
487 TRACE("()\n");
489 if (reserved!=0)
490 return E_UNEXPECTED;
492 if(runningObjectTableInstance==NULL)
493 return CO_E_NOTINITIALIZED;
495 res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
497 return res;
500 /******************************************************************************
501 * OleRun [OLE32.123]
503 HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
505 IRunnableObject *runable;
506 ICOM_THIS(IRunnableObject,pUnknown);
507 LRESULT ret;
509 ret = IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable);
510 if (ret)
511 return 0; /* Appears to return no error. */
512 ret = IRunnableObject_Run(runable,NULL);
513 IRunnableObject_Release(runable);
514 return ret;
517 /******************************************************************************
518 * MkParseDisplayName [OLE32.81]
520 HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szUserName,
521 LPDWORD pchEaten, LPMONIKER *ppmk)
523 FIXME("(%p, %s, %p, %p): stub.\n", pbc, debugstr_w(szUserName), pchEaten, *ppmk);
524 if (!(IsValidInterface((LPUNKNOWN) pbc)))
525 return E_INVALIDARG;
527 return MK_E_SYNTAX;