Fixed some warnings.
[wine] / dlls / ole32 / moniker.c
1 /*
2  *      Monikers
3  *
4  *      Copyright 1998  Marcus Meissner
5  *      Copyright 1999  Noomen Hamza
6  */
7
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"
14
15 DEFAULT_DEBUG_CHANNEL(ole)
16
17 #define  BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
18
19 /* define the structure of the running object table elements */
20 typedef struct RunObject{
21
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;
28
29 /* define the RunningObjectTableImpl structure */
30 typedef struct RunningObjectTableImpl{
31
32     ICOM_VFIELD(IRunningObjectTable);
33     ULONG      ref;
34
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 */
39     
40 } RunningObjectTableImpl;
41
42 RunningObjectTableImpl* runningObjectTableInstance=0;
43
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);
62
63 /* Virtual function table for the IRunningObjectTable class. */
64 static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl =
65 {
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
77 };
78
79 /***********************************************************************
80  *        RunningObjectTable_QueryInterface
81  */
82 HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
83 {
84     ICOM_THIS(RunningObjectTableImpl,iface);
85
86     TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
87
88     /* validate arguments */
89     if (This==0)
90         return CO_E_NOTINITIALIZED;
91
92     if (ppvObject==0)
93         return E_INVALIDARG;
94
95     *ppvObject = 0;
96
97     if (IsEqualIID(&IID_IUnknown, riid))
98         *ppvObject = (IRunningObjectTable*)This;
99     else
100         if (IsEqualIID(&IID_IRunningObjectTable, riid))
101             *ppvObject = (IRunningObjectTable*)This;
102
103     if ((*ppvObject)==0)
104         return E_NOINTERFACE;
105
106     RunningObjectTableImpl_AddRef(iface);
107
108     return S_OK;
109 }
110
111 /***********************************************************************
112  *        RunningObjectTable_AddRef
113  */
114 ULONG   WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
115 {
116     ICOM_THIS(RunningObjectTableImpl,iface);
117
118     TRACE("(%p)\n",This);
119
120     return ++(This->ref);
121 }
122
123 /***********************************************************************
124  *        RunningObjectTable_Initialize
125  */
126 HRESULT WINAPI RunningObjectTableImpl_Destroy()
127 {
128     TRACE("()\n");
129     
130     if (runningObjectTableInstance==NULL)
131         return E_INVALIDARG;
132
133     /* free the ROT table memory */
134     HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
135
136     /* free the ROT structure memory */
137     HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
138
139     return S_OK;
140 }
141
142 /***********************************************************************
143  *        RunningObjectTable_Release
144  */
145 ULONG   WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
146 {
147     DWORD i;
148     ICOM_THIS(RunningObjectTableImpl,iface);
149
150     TRACE("(%p)\n",This);
151
152     This->ref--;
153
154     /* unitialize ROT structure if there's no more reference to it*/
155     if (This->ref==0){
156
157         /* release all registered objects */
158         for(i=0;i<This->runObjTabLastIndx;i++)
159         {
160             if (( This->runObjTab[i].regTypeObj &  ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
161                 IUnknown_Release(This->runObjTab[i].pObj);
162  
163             IMoniker_Release(This->runObjTab[i].pmkObj);
164         }
165        /*  RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
166         *  when RunningObjectTableImpl_UnInitialize function is called
167         */
168
169         /* there's no more elements in the table */
170         This->runObjTabRegister=0;
171         This->runObjTabLastIndx=0;
172
173         return 0;
174     }
175
176     return This->ref;
177 }
178
179 /***********************************************************************
180  *        RunningObjectTable_Initialize
181  */
182 HRESULT WINAPI RunningObjectTableImpl_Initialize()
183 {
184     TRACE("()\n");
185
186     /* create the unique instance of the RunningObjectTableImpl structure */
187     runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));
188
189     if (runningObjectTableInstance == 0)
190         return E_OUTOFMEMORY;
191
192     /* initialize the virtual table function */
193     ICOM_VTBL(runningObjectTableInstance) = &VT_RunningObjectTableImpl;
194
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;
199
200     /* allocate space memory for the table witch contains all the running objects */
201     runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));
202
203     if (runningObjectTableInstance->runObjTab == NULL)
204         return E_OUTOFMEMORY;
205
206     runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
207     runningObjectTableInstance->runObjTabRegister=1;
208     runningObjectTableInstance->runObjTabLastIndx=0;
209
210     return S_OK;
211 }
212
213 /***********************************************************************
214  *        RunningObjectTable_UnInitialize
215  */
216 HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
217 {
218     TRACE("()\n");
219
220     if (runningObjectTableInstance==NULL)
221         return E_POINTER;
222     
223     RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
224
225     RunningObjectTableImpl_Destroy();
226
227     return S_OK;
228 }
229
230 /***********************************************************************
231  *        RunningObjectTable_Register
232  */
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 */
238 {
239     HRESULT res=S_OK;
240     ICOM_THIS(RunningObjectTableImpl,iface);
241
242     TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
243
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;
249
250     if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
251         return E_INVALIDARG;
252
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;
256
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));
263     
264     /* gives a registration identifier to the registered object*/
265     (*pdwRegister)= This->runObjTabRegister;
266
267     if (This->runObjTabRegister == 0xFFFFFFFF){
268
269         FIXME("runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister);
270         return E_FAIL;
271 }
272     This->runObjTabRegister++;
273     This->runObjTabLastIndx++;
274     
275     if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */
276
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;
282     }
283     /* add a reference to the object in the strong registration case */
284     if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 )
285         IUnknown_AddRef(punkObject);
286
287     IMoniker_AddRef(pmkObjectName);
288     
289     return res;
290 }
291
292 /***********************************************************************
293  *        RunningObjectTable_Revoke
294  */
295 HRESULT WINAPI RunningObjectTableImpl_Revoke(  IRunningObjectTable* iface,
296                                                DWORD dwRegister)  /* Value identifying registration to be revoked*/
297 {
298
299     DWORD index,j;
300     ICOM_THIS(RunningObjectTableImpl,iface);
301
302     TRACE("(%p,%ld)\n",This,dwRegister);
303
304     /* verify if the object to be revoked was registered before or not */
305     if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
306
307         return E_INVALIDARG;
308
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);
312
313     IMoniker_Release(This->runObjTab[index].pmkObj);
314     
315     /* remove the object from the table */
316     for(j=index; j<This->runObjTabLastIndx-1; j++)
317         This->runObjTab[j]= This->runObjTab[j+1];
318     
319     This->runObjTabLastIndx--;
320
321     return S_OK;
322 }
323
324 /***********************************************************************
325  *        RunningObjectTable_IsRunning
326  */
327 HRESULT WINAPI RunningObjectTableImpl_IsRunning(  IRunningObjectTable* iface,
328                                                   IMoniker *pmkObjectName)  /* Pointer to the moniker of the object whose status is desired */
329 {    
330     ICOM_THIS(RunningObjectTableImpl,iface);
331
332     TRACE("(%p,%p)\n",This,pmkObjectName);
333
334     return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
335 }
336
337 /***********************************************************************
338  *        RunningObjectTable_GetObject
339  */
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 */
343 {
344     DWORD index;
345     ICOM_THIS(RunningObjectTableImpl,iface);
346
347     TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
348
349     if (ppunkObject==NULL)
350         return E_POINTER;
351     
352     *ppunkObject=0;
353
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;
357
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;
361
362     return S_OK;
363 }
364
365 /***********************************************************************
366  *        RunningObjectTable_NoteChangeTime
367  */
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 */
371 {
372     DWORD index=-1;
373     ICOM_THIS(RunningObjectTableImpl,iface);
374
375     TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);
376
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;
380
381     /* set the new value of the last time change */
382     This->runObjTab[index].lastModifObj= (*pfiletime);
383
384     return S_OK;
385 }
386     
387 /***********************************************************************
388  *        RunningObjectTable_GetTimeOfLastChange
389  */
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 */
393 {
394     DWORD index=-1;
395     ICOM_THIS(RunningObjectTableImpl,iface);
396
397     TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
398
399     if (pmkObjectName==NULL || pfiletime==NULL)
400         return E_INVALIDARG;
401
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;;
405
406     (*pfiletime)= This->runObjTab[index].lastModifObj;
407
408     return S_OK;
409 }
410
411 /***********************************************************************
412  *        RunningObjectTable_EnumRunning
413  */
414 HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
415                                                   IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
416 {
417     FIXME("(%p,%p) needs the IEnumMoniker implementation  \n",iface,ppenumMoniker);
418     return E_NOTIMPL;
419 }
420
421 /***********************************************************************
422  *        GetObjectIndex
423  */
424 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
425                                                      DWORD identReg,
426                                                      IMoniker* pmk,
427                                                      DWORD *indx)
428 {
429
430     DWORD i;
431
432     TRACE("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);
433
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++);
440     
441     if (i==This->runObjTabLastIndx)  return S_FALSE;
442
443     if (indx != NULL)  *indx=i;
444
445     return S_OK;
446 }
447
448 /******************************************************************************
449  *              GetRunningObjectTable16 [OLE2.30]
450  */
451 HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
452 {
453         FIXME("(%ld,%p),stub!\n",reserved,pprot);
454     return E_NOTIMPL;
455 }
456
457 /***********************************************************************
458  *           GetRunningObjectTable (OLE2.73)
459  */
460 HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
461 {
462     IID riid=IID_IRunningObjectTable;
463     HRESULT res;
464
465     TRACE("()\n");
466
467     if (reserved!=0)
468         return E_UNEXPECTED;
469
470     if(runningObjectTableInstance==NULL)
471         return CO_E_NOTINITIALIZED;
472
473     res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
474
475     return res;
476 }
477
478 /******************************************************************************
479  *              OleRun        [OLE32.123]
480  */
481 HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
482 {
483   IRunnableObject       *runable;
484   ICOM_THIS(IRunnableObject,pUnknown);
485   LRESULT               ret;
486
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;
493 }
494
495 /******************************************************************************
496  *              MkParseDisplayName        [OLE32.81]
497  */
498 HRESULT MkParseDisplayName(     LPBC pbc, LPCOLESTR szUserName,
499                                 LPDWORD pchEaten, LPMONIKER *ppmk)
500 {
501     FIXME("(%p, %s, %p, %p): stub.\n", pbc, debugstr_w(szUserName), pchEaten, *ppmk);
502     if (!(IsValidInterface((LPUNKNOWN) pbc)))
503         return E_INVALIDARG;
504
505     return MK_E_SYNTAX;
506 }