Fixes crash when calling Treeview_EndEditLabelNow and no node is
[wine.git] / dlls / ole32 / moniker.c
blob81dca80aab8db7bde06c555761fb15a3af742c1b
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"
13 #include "ole2.h"
15 DEFAULT_DEBUG_CHANNEL(ole)
17 #define BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
19 /* define the structure of the running object table elements */
20 typedef struct RunObject{
22 IUnknown* pObj; /* points on a running object*/
23 IMoniker* pmkObj; /* points on a moniker who identifies this object */
24 FILETIME lastModifObj;
25 DWORD identRegObj; /* registration key relative to this object */
26 DWORD regTypeObj; /* registration type : strong or weak */
27 }RunObject;
29 /* define the RunningObjectTableImpl structure */
30 typedef struct RunningObjectTableImpl{
32 ICOM_VFIELD(IRunningObjectTable);
33 ULONG ref;
35 RunObject* runObjTab; /* pointer to the first object in the table */
36 DWORD runObjTabSize; /* current table size */
37 DWORD runObjTabLastIndx; /* first free index element in the table. */
38 DWORD runObjTabRegister; /* registration key of the next registered object */
40 } RunningObjectTableImpl;
42 RunningObjectTableImpl* runningObjectTableInstance=0;
44 /* IRunningObjectTable prototype functions : */
45 /* IUnknown functions*/
46 static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject);
47 static ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface);
48 static ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface);
49 /* IRunningObjectTable functions */
50 static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister);
51 static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister);
52 static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName);
53 static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject);
54 static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime);
55 static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime);
56 static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker);
57 /* Local functions*/
58 HRESULT WINAPI RunningObjectTableImpl_Initialize();
59 HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
60 HRESULT WINAPI RunningObjectTableImpl_Destroy();
61 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);
63 /* Virtual function table for the IRunningObjectTable class. */
64 static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl =
66 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
67 RunningObjectTableImpl_QueryInterface,
68 RunningObjectTableImpl_AddRef,
69 RunningObjectTableImpl_Release,
70 RunningObjectTableImpl_Register,
71 RunningObjectTableImpl_Revoke,
72 RunningObjectTableImpl_IsRunning,
73 RunningObjectTableImpl_GetObject,
74 RunningObjectTableImpl_NoteChangeTime,
75 RunningObjectTableImpl_GetTimeOfLastChange,
76 RunningObjectTableImpl_EnumRunning
79 /***********************************************************************
80 * RunningObjectTable_QueryInterface
82 HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
84 ICOM_THIS(RunningObjectTableImpl,iface);
86 TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
88 /* validate arguments */
89 if (This==0)
90 return CO_E_NOTINITIALIZED;
92 if (ppvObject==0)
93 return E_INVALIDARG;
95 *ppvObject = 0;
97 if (IsEqualIID(&IID_IUnknown, riid))
98 *ppvObject = (IRunningObjectTable*)This;
99 else
100 if (IsEqualIID(&IID_IRunningObjectTable, riid))
101 *ppvObject = (IRunningObjectTable*)This;
103 if ((*ppvObject)==0)
104 return E_NOINTERFACE;
106 RunningObjectTableImpl_AddRef(iface);
108 return S_OK;
111 /***********************************************************************
112 * RunningObjectTable_AddRef
114 ULONG WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
116 ICOM_THIS(RunningObjectTableImpl,iface);
118 TRACE("(%p)\n",This);
120 return ++(This->ref);
123 /***********************************************************************
124 * RunningObjectTable_Initialize
126 HRESULT WINAPI RunningObjectTableImpl_Destroy()
128 TRACE("()\n");
130 if (runningObjectTableInstance==NULL)
131 return E_INVALIDARG;
133 /* free the ROT table memory */
134 HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
136 /* free the ROT structure memory */
137 HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
139 return S_OK;
142 /***********************************************************************
143 * RunningObjectTable_Release
145 ULONG WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
147 DWORD i;
148 ICOM_THIS(RunningObjectTableImpl,iface);
150 TRACE("(%p)\n",This);
152 This->ref--;
154 /* unitialize ROT structure if there's no more reference to it*/
155 if (This->ref==0){
157 /* release all registered objects */
158 for(i=0;i<This->runObjTabLastIndx;i++)
160 if (( This->runObjTab[i].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
161 IUnknown_Release(This->runObjTab[i].pObj);
163 IMoniker_Release(This->runObjTab[i].pmkObj);
165 /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
166 * when RunningObjectTableImpl_UnInitialize function is called
169 /* there's no more elements in the table */
170 This->runObjTabRegister=0;
171 This->runObjTabLastIndx=0;
173 return 0;
176 return This->ref;
179 /***********************************************************************
180 * RunningObjectTable_Initialize
182 HRESULT WINAPI RunningObjectTableImpl_Initialize()
184 TRACE("()\n");
186 /* create the unique instance of the RunningObjectTableImpl structure */
187 runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));
189 if (runningObjectTableInstance == 0)
190 return E_OUTOFMEMORY;
192 /* initialize the virtual table function */
193 ICOM_VTBL(runningObjectTableInstance) = &VT_RunningObjectTableImpl;
195 /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
196 /* the ROT refered many times not in the same time (all the objects in the ROT will */
197 /* be removed evry time the ROT is removed ) */
198 runningObjectTableInstance->ref = 1;
200 /* allocate space memory for the table witch contains all the running objects */
201 runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));
203 if (runningObjectTableInstance->runObjTab == NULL)
204 return E_OUTOFMEMORY;
206 runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
207 runningObjectTableInstance->runObjTabRegister=1;
208 runningObjectTableInstance->runObjTabLastIndx=0;
210 return S_OK;
213 /***********************************************************************
214 * RunningObjectTable_UnInitialize
216 HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
218 TRACE("()\n");
220 if (runningObjectTableInstance==NULL)
221 return E_POINTER;
223 RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
225 RunningObjectTableImpl_Destroy();
227 return S_OK;
230 /***********************************************************************
231 * RunningObjectTable_Register
233 HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface,
234 DWORD grfFlags, /* Registration options */
235 IUnknown *punkObject, /* Pointer to the object being registered */
236 IMoniker *pmkObjectName, /* Pointer to the moniker of the object being registered */
237 DWORD *pdwRegister) /* Pointer to the value identifying the registration */
239 HRESULT res=S_OK;
240 ICOM_THIS(RunningObjectTableImpl,iface);
242 TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
244 /* there's only tow types of register : strong and or weak registration (only one must be passed on parameter) */
245 if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
246 (!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
247 (grfFlags) )
248 return E_INVALIDARG;
250 if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
251 return E_INVALIDARG;
253 /* verify if the object to be registered was registered before */
254 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
255 res = MK_S_MONIKERALREADYREGISTERED;
257 /* put the new registered object in the first free element in the table */
258 This->runObjTab[This->runObjTabLastIndx].pObj = punkObject;
259 This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName;
260 This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags;
261 This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister;
262 CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj));
264 /* gives a registration identifier to the registered object*/
265 (*pdwRegister)= This->runObjTabRegister;
267 if (This->runObjTabRegister == 0xFFFFFFFF){
269 FIXME("runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister);
270 return E_FAIL;
272 This->runObjTabRegister++;
273 This->runObjTabLastIndx++;
275 if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */
277 This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */
278 This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab,
279 This->runObjTabSize * sizeof(RunObject));
280 if (!This->runObjTab)
281 return E_OUTOFMEMORY;
283 /* add a reference to the object in the strong registration case */
284 if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 )
285 IUnknown_AddRef(punkObject);
287 IMoniker_AddRef(pmkObjectName);
289 return res;
292 /***********************************************************************
293 * RunningObjectTable_Revoke
295 HRESULT WINAPI RunningObjectTableImpl_Revoke( IRunningObjectTable* iface,
296 DWORD dwRegister) /* Value identifying registration to be revoked*/
299 DWORD index,j;
300 ICOM_THIS(RunningObjectTableImpl,iface);
302 TRACE("(%p,%ld)\n",This,dwRegister);
304 /* verify if the object to be revoked was registered before or not */
305 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
307 return E_INVALIDARG;
309 /* release the object if it was registered with a strong registrantion option */
310 if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0)
311 IUnknown_Release(This->runObjTab[index].pObj);
313 IMoniker_Release(This->runObjTab[index].pmkObj);
315 /* remove the object from the table */
316 for(j=index; j<This->runObjTabLastIndx-1; j++)
317 This->runObjTab[j]= This->runObjTab[j+1];
319 This->runObjTabLastIndx--;
321 return S_OK;
324 /***********************************************************************
325 * RunningObjectTable_IsRunning
327 HRESULT WINAPI RunningObjectTableImpl_IsRunning( IRunningObjectTable* iface,
328 IMoniker *pmkObjectName) /* Pointer to the moniker of the object whose status is desired */
330 ICOM_THIS(RunningObjectTableImpl,iface);
332 TRACE("(%p,%p)\n",This,pmkObjectName);
334 return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
337 /***********************************************************************
338 * RunningObjectTable_GetObject
340 HRESULT WINAPI RunningObjectTableImpl_GetObject( IRunningObjectTable* iface,
341 IMoniker *pmkObjectName,/* Pointer to the moniker on the object */
342 IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */
344 DWORD index;
345 ICOM_THIS(RunningObjectTableImpl,iface);
347 TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
349 if (ppunkObject==NULL)
350 return E_POINTER;
352 *ppunkObject=0;
354 /* verify if the object was registered before or not */
355 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
356 return MK_E_UNAVAILABLE;
358 /* add a reference to the object then set output object argument */
359 IUnknown_AddRef(This->runObjTab[index].pObj);
360 *ppunkObject=This->runObjTab[index].pObj;
362 return S_OK;
365 /***********************************************************************
366 * RunningObjectTable_NoteChangeTime
368 HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
369 DWORD dwRegister, /* Value identifying registration being updated */
370 FILETIME *pfiletime) /* Pointer to structure containing object's last change time */
372 DWORD index=-1;
373 ICOM_THIS(RunningObjectTableImpl,iface);
375 TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);
377 /* verify if the object to be changed was registered before or not */
378 if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
379 return E_INVALIDARG;
381 /* set the new value of the last time change */
382 This->runObjTab[index].lastModifObj= (*pfiletime);
384 return S_OK;
387 /***********************************************************************
388 * RunningObjectTable_GetTimeOfLastChange
390 HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
391 IMoniker *pmkObjectName, /* Pointer to moniker on the object whose status is desired */
392 FILETIME *pfiletime) /* Pointer to structure that receives object's last change time */
394 DWORD index=-1;
395 ICOM_THIS(RunningObjectTableImpl,iface);
397 TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
399 if (pmkObjectName==NULL || pfiletime==NULL)
400 return E_INVALIDARG;
402 /* verify if the object was registered before or not */
403 if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
404 return MK_E_UNAVAILABLE;;
406 (*pfiletime)= This->runObjTab[index].lastModifObj;
408 return S_OK;
411 /***********************************************************************
412 * RunningObjectTable_EnumRunning
414 HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
415 IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
417 FIXME("(%p,%p) needs the IEnumMoniker implementation \n",iface,ppenumMoniker);
418 return E_NOTIMPL;
421 /***********************************************************************
422 * GetObjectIndex
424 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
425 DWORD identReg,
426 IMoniker* pmk,
427 DWORD *indx)
430 DWORD i;
432 TRACE("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);
434 if (pmk!=NULL)
435 /* search object identified by a moniker */
436 for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
437 else
438 /* search object identified by a register identifier */
439 for(i=0;((i<This->runObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++);
441 if (i==This->runObjTabLastIndx) return S_FALSE;
443 if (indx != NULL) *indx=i;
445 return S_OK;
448 /******************************************************************************
449 * GetRunningObjectTable16 [OLE2.30]
451 HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
453 FIXME("(%ld,%p),stub!\n",reserved,pprot);
454 return E_NOTIMPL;
457 /***********************************************************************
458 * GetRunningObjectTable (OLE2.73)
460 HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
462 IID riid=IID_IRunningObjectTable;
463 HRESULT res;
465 TRACE("()\n");
467 if (reserved!=0)
468 return E_UNEXPECTED;
470 if(runningObjectTableInstance==NULL)
471 return CO_E_NOTINITIALIZED;
473 res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
475 return res;
478 /******************************************************************************
479 * OleRun [OLE32.123]
481 HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
483 IRunnableObject *runable;
484 ICOM_THIS(IRunnableObject,pUnknown);
485 LRESULT ret;
487 ret = IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable);
488 if (ret)
489 return 0; /* Appears to return no error. */
490 ret = IRunnableObject_Run(runable,NULL);
491 IRunnableObject_Release(runable);
492 return ret;
495 /******************************************************************************
496 * MkParseDisplayName [OLE32.81]
498 HRESULT MkParseDisplayName( LPBC pbc, LPCOLESTR szUserName,
499 LPDWORD pchEaten, LPMONIKER *ppmk)
501 FIXME("(%p, %s, %p, %p): stub.\n", pbc, debugstr_w(szUserName), pchEaten, *ppmk);
502 if (!(IsValidInterface((LPUNKNOWN) pbc)))
503 return E_INVALIDARG;
505 return MK_E_SYNTAX;