Fixed miscellaneous typos, syntactic and grammatical errors.
[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
10 #include "winerror.h"
11 #include "winbase.h"
12 #include "wtypes.h"
13 #include "wine/obj_base.h"
14 #include "wine/obj_storage.h"
15 #include "wine/obj_misc.h"
16 #include "wine/obj_moniker.h"
17 #include "debugtools.h"
18 #include "heap.h"
19 #include "ole2.h"
20
21 #include "compobj_private.h"
22
23 DEFAULT_DEBUG_CHANNEL(ole);
24
25 #define  BLOCK_TAB_SIZE 20 /* represent the first size table and it's increment block size */
26
27 /* define the structure of the running object table elements */
28 typedef struct RunObject{
29
30     IUnknown*  pObj; /* points on a running object*/
31     IMoniker*  pmkObj; /* points on a moniker who identifies this object */
32     FILETIME   lastModifObj;
33     DWORD      identRegObj; /* registration key relative to this object */
34     DWORD      regTypeObj; /* registration type : strong or weak */
35 }RunObject;
36
37 /* define the RunningObjectTableImpl structure */
38 typedef struct RunningObjectTableImpl{
39
40     ICOM_VFIELD(IRunningObjectTable);
41     ULONG      ref;
42
43     RunObject* runObjTab;            /* pointer to the first object in the table       */
44     DWORD      runObjTabSize;       /* current table size                            */
45     DWORD      runObjTabLastIndx;  /* first free index element in the table.        */
46     DWORD      runObjTabRegister; /* registration key of the next registered object */
47     
48 } RunningObjectTableImpl;
49
50 RunningObjectTableImpl* runningObjectTableInstance=0;
51
52 /* IRunningObjectTable prototype functions : */
53 /* IUnknown functions*/
54 static HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject);
55 static ULONG   WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface);
56 static ULONG   WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface);
57 /* IRunningObjectTable functions */
58 static HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface, DWORD grfFlags,IUnknown* punkObject,IMoniker* pmkObjectName,DWORD* pdwRegister);
59 static HRESULT WINAPI RunningObjectTableImpl_Revoke(IRunningObjectTable* iface, DWORD dwRegister);
60 static HRESULT WINAPI RunningObjectTableImpl_IsRunning(IRunningObjectTable* iface, IMoniker* pmkObjectName);
61 static HRESULT WINAPI RunningObjectTableImpl_GetObject(IRunningObjectTable* iface, IMoniker* pmkObjectName,IUnknown** ppunkObject);
62 static HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface, DWORD dwRegister,FILETIME* pfiletime);
63 static HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface, IMoniker* pmkObjectName,FILETIME* pfiletime);
64 static HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface, IEnumMoniker** ppenumMoniker);
65 /* Local functions*/
66 HRESULT WINAPI RunningObjectTableImpl_Initialize();
67 HRESULT WINAPI RunningObjectTableImpl_UnInitialize();
68 HRESULT WINAPI RunningObjectTableImpl_Destroy();
69 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,DWORD identReg,IMoniker* pmk,DWORD *indx);
70
71 /* Virtual function table for the IRunningObjectTable class. */
72 static ICOM_VTABLE(IRunningObjectTable) VT_RunningObjectTableImpl =
73 {
74     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
75     RunningObjectTableImpl_QueryInterface,
76     RunningObjectTableImpl_AddRef,
77     RunningObjectTableImpl_Release,
78     RunningObjectTableImpl_Register,
79     RunningObjectTableImpl_Revoke,
80     RunningObjectTableImpl_IsRunning,
81     RunningObjectTableImpl_GetObject,
82     RunningObjectTableImpl_NoteChangeTime,
83     RunningObjectTableImpl_GetTimeOfLastChange,
84     RunningObjectTableImpl_EnumRunning
85 };
86
87 /***********************************************************************
88  *        RunningObjectTable_QueryInterface
89  */
90 HRESULT WINAPI RunningObjectTableImpl_QueryInterface(IRunningObjectTable* iface,REFIID riid,void** ppvObject)
91 {
92     ICOM_THIS(RunningObjectTableImpl,iface);
93
94     TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
95
96     /* validate arguments */
97     if (This==0)
98         return CO_E_NOTINITIALIZED;
99
100     if (ppvObject==0)
101         return E_INVALIDARG;
102
103     *ppvObject = 0;
104
105     if (IsEqualIID(&IID_IUnknown, riid))
106         *ppvObject = (IRunningObjectTable*)This;
107     else
108         if (IsEqualIID(&IID_IRunningObjectTable, riid))
109             *ppvObject = (IRunningObjectTable*)This;
110
111     if ((*ppvObject)==0)
112         return E_NOINTERFACE;
113
114     RunningObjectTableImpl_AddRef(iface);
115
116     return S_OK;
117 }
118
119 /***********************************************************************
120  *        RunningObjectTable_AddRef
121  */
122 ULONG   WINAPI RunningObjectTableImpl_AddRef(IRunningObjectTable* iface)
123 {
124     ICOM_THIS(RunningObjectTableImpl,iface);
125
126     TRACE("(%p)\n",This);
127
128     return ++(This->ref);
129 }
130
131 /***********************************************************************
132  *        RunningObjectTable_Initialize
133  */
134 HRESULT WINAPI RunningObjectTableImpl_Destroy()
135 {
136     TRACE("()\n");
137     
138     if (runningObjectTableInstance==NULL)
139         return E_INVALIDARG;
140
141     /* free the ROT table memory */
142     HeapFree(GetProcessHeap(),0,runningObjectTableInstance->runObjTab);
143
144     /* free the ROT structure memory */
145     HeapFree(GetProcessHeap(),0,runningObjectTableInstance);
146
147     return S_OK;
148 }
149
150 /***********************************************************************
151  *        RunningObjectTable_Release
152  */
153 ULONG   WINAPI RunningObjectTableImpl_Release(IRunningObjectTable* iface)
154 {
155     DWORD i;
156     ICOM_THIS(RunningObjectTableImpl,iface);
157
158     TRACE("(%p)\n",This);
159
160     This->ref--;
161
162     /* unitialize ROT structure if there's no more reference to it*/
163     if (This->ref==0){
164
165         /* release all registered objects */
166         for(i=0;i<This->runObjTabLastIndx;i++)
167         {
168             if (( This->runObjTab[i].regTypeObj &  ROTFLAGS_REGISTRATIONKEEPSALIVE) != 0)
169                 IUnknown_Release(This->runObjTab[i].pObj);
170  
171             IMoniker_Release(This->runObjTab[i].pmkObj);
172         }
173        /*  RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
174         *  when RunningObjectTableImpl_UnInitialize function is called
175         */
176
177         /* there's no more elements in the table */
178         This->runObjTabRegister=0;
179         This->runObjTabLastIndx=0;
180
181         return 0;
182     }
183
184     return This->ref;
185 }
186
187 /***********************************************************************
188  *        RunningObjectTable_Initialize
189  */
190 HRESULT WINAPI RunningObjectTableImpl_Initialize()
191 {
192     TRACE("()\n");
193
194     /* create the unique instance of the RunningObjectTableImpl structure */
195     runningObjectTableInstance = HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl));
196
197     if (runningObjectTableInstance == 0)
198         return E_OUTOFMEMORY;
199
200     /* initialize the virtual table function */
201     ICOM_VTBL(runningObjectTableInstance) = &VT_RunningObjectTableImpl;
202
203     /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
204     /* the ROT refered many times  not in the same time (all the objects in the ROT will  */
205     /* be removed evry time the ROT is removed ) */
206     runningObjectTableInstance->ref = 1;
207
208     /* allocate space memory for the table witch contains all the running objects */
209     runningObjectTableInstance->runObjTab = HeapAlloc(GetProcessHeap(), 0, sizeof(RunObject[BLOCK_TAB_SIZE]));
210
211     if (runningObjectTableInstance->runObjTab == NULL)
212         return E_OUTOFMEMORY;
213
214     runningObjectTableInstance->runObjTabSize=BLOCK_TAB_SIZE;
215     runningObjectTableInstance->runObjTabRegister=1;
216     runningObjectTableInstance->runObjTabLastIndx=0;
217
218     return S_OK;
219 }
220
221 /***********************************************************************
222  *        RunningObjectTable_UnInitialize
223  */
224 HRESULT WINAPI RunningObjectTableImpl_UnInitialize()
225 {
226     TRACE("()\n");
227
228     if (runningObjectTableInstance==NULL)
229         return E_POINTER;
230     
231     RunningObjectTableImpl_Release((IRunningObjectTable*)runningObjectTableInstance);
232
233     RunningObjectTableImpl_Destroy();
234
235     return S_OK;
236 }
237
238 /***********************************************************************
239  *        RunningObjectTable_Register
240  */
241 HRESULT WINAPI RunningObjectTableImpl_Register(IRunningObjectTable* iface,
242                                                DWORD grfFlags,           /* Registration options */
243                                                IUnknown *punkObject,     /* Pointer to the object being registered */
244                                                IMoniker *pmkObjectName,  /* Pointer to the moniker of the object being registered */
245                                                DWORD *pdwRegister)       /* Pointer to the value identifying the  registration */
246 {
247     HRESULT res=S_OK;
248     ICOM_THIS(RunningObjectTableImpl,iface);
249
250     TRACE("(%p,%ld,%p,%p,%p)\n",This,grfFlags,punkObject,pmkObjectName,pdwRegister);
251
252     /* there's only tow types of register : strong and or weak registration (only one must be passed on parameter) */
253     if ( ( (grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) || !(grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
254          (!(grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) ||  (grfFlags & ROTFLAGS_ALLOWANYCLIENT)) &&
255          (grfFlags) )
256         return E_INVALIDARG;
257
258     if (punkObject==NULL || pmkObjectName==NULL || pdwRegister==NULL)
259         return E_INVALIDARG;
260
261     /* verify if the object to be registered was registered before */
262     if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL)==S_OK)
263         res = MK_S_MONIKERALREADYREGISTERED;
264
265     /* put the new registered object in the first free element in the table */
266     This->runObjTab[This->runObjTabLastIndx].pObj = punkObject;
267     This->runObjTab[This->runObjTabLastIndx].pmkObj = pmkObjectName;
268     This->runObjTab[This->runObjTabLastIndx].regTypeObj = grfFlags;
269     This->runObjTab[This->runObjTabLastIndx].identRegObj = This->runObjTabRegister;
270     CoFileTimeNow(&(This->runObjTab[This->runObjTabLastIndx].lastModifObj));
271     
272     /* gives a registration identifier to the registered object*/
273     (*pdwRegister)= This->runObjTabRegister;
274
275     if (This->runObjTabRegister == 0xFFFFFFFF){
276
277         FIXME("runObjTabRegister: %ld is out of data limite \n",This->runObjTabRegister);
278         return E_FAIL;
279 }
280     This->runObjTabRegister++;
281     This->runObjTabLastIndx++;
282     
283     if (This->runObjTabLastIndx == This->runObjTabSize){ /* table is full ! so it must be resized */
284
285         This->runObjTabSize+=BLOCK_TAB_SIZE; /* newsize table */
286         This->runObjTab=HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->runObjTab,
287                         This->runObjTabSize * sizeof(RunObject));
288         if (!This->runObjTab)
289             return E_OUTOFMEMORY;
290     }
291     /* add a reference to the object in the strong registration case */
292     if ((grfFlags & ROTFLAGS_REGISTRATIONKEEPSALIVE) !=0 )
293         IUnknown_AddRef(punkObject);
294
295     IMoniker_AddRef(pmkObjectName);
296     
297     return res;
298 }
299
300 /***********************************************************************
301  *        RunningObjectTable_Revoke
302  */
303 HRESULT WINAPI RunningObjectTableImpl_Revoke(  IRunningObjectTable* iface,
304                                                DWORD dwRegister)  /* Value identifying registration to be revoked*/
305 {
306
307     DWORD index,j;
308     ICOM_THIS(RunningObjectTableImpl,iface);
309
310     TRACE("(%p,%ld)\n",This,dwRegister);
311
312     /* verify if the object to be revoked was registered before or not */
313     if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
314
315         return E_INVALIDARG;
316
317     /* release the object if it was registered with a strong registrantion option */
318     if ((This->runObjTab[index].regTypeObj & ROTFLAGS_REGISTRATIONKEEPSALIVE)!=0)
319         IUnknown_Release(This->runObjTab[index].pObj);
320
321     IMoniker_Release(This->runObjTab[index].pmkObj);
322     
323     /* remove the object from the table */
324     for(j=index; j<This->runObjTabLastIndx-1; j++)
325         This->runObjTab[j]= This->runObjTab[j+1];
326     
327     This->runObjTabLastIndx--;
328
329     return S_OK;
330 }
331
332 /***********************************************************************
333  *        RunningObjectTable_IsRunning
334  */
335 HRESULT WINAPI RunningObjectTableImpl_IsRunning(  IRunningObjectTable* iface,
336                                                   IMoniker *pmkObjectName)  /* Pointer to the moniker of the object whose status is desired */
337 {    
338     ICOM_THIS(RunningObjectTableImpl,iface);
339
340     TRACE("(%p,%p)\n",This,pmkObjectName);
341
342     return RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,NULL);
343 }
344
345 /***********************************************************************
346  *        RunningObjectTable_GetObject
347  */
348 HRESULT WINAPI RunningObjectTableImpl_GetObject(  IRunningObjectTable* iface,
349                                                   IMoniker *pmkObjectName,/* Pointer to the moniker on the object */
350                                                   IUnknown **ppunkObject) /* Address of output variable that receives the IUnknown interface pointer */
351 {
352     DWORD index;
353     ICOM_THIS(RunningObjectTableImpl,iface);
354
355     TRACE("(%p,%p,%p)\n",This,pmkObjectName,ppunkObject);
356
357     if (ppunkObject==NULL)
358         return E_POINTER;
359     
360     *ppunkObject=0;
361
362     /* verify if the object was registered before or not */
363     if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
364         return MK_E_UNAVAILABLE;
365
366     /* add a reference to the object then set output object argument */
367     IUnknown_AddRef(This->runObjTab[index].pObj);
368     *ppunkObject=This->runObjTab[index].pObj;
369
370     return S_OK;
371 }
372
373 /***********************************************************************
374  *        RunningObjectTable_NoteChangeTime
375  */
376 HRESULT WINAPI RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable* iface,
377                                                      DWORD dwRegister,  /* Value identifying registration being updated */
378                                                      FILETIME *pfiletime) /* Pointer to structure containing object's last change time */
379 {
380     DWORD index=-1;
381     ICOM_THIS(RunningObjectTableImpl,iface);
382
383     TRACE("(%p,%ld,%p)\n",This,dwRegister,pfiletime);
384
385     /* verify if the object to be changed was registered before or not */
386     if (RunningObjectTableImpl_GetObjectIndex(This,dwRegister,NULL,&index)==S_FALSE)
387         return E_INVALIDARG;
388
389     /* set the new value of the last time change */
390     This->runObjTab[index].lastModifObj= (*pfiletime);
391
392     return S_OK;
393 }
394     
395 /***********************************************************************
396  *        RunningObjectTable_GetTimeOfLastChange
397  */
398 HRESULT WINAPI RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable* iface,
399                                                           IMoniker *pmkObjectName,  /* Pointer to moniker on the object whose status is desired */
400                                                           FILETIME *pfiletime)       /* Pointer to structure that receives object's last change time */
401 {
402     DWORD index=-1;
403     ICOM_THIS(RunningObjectTableImpl,iface);
404
405     TRACE("(%p,%p,%p)\n",This,pmkObjectName,pfiletime);
406
407     if (pmkObjectName==NULL || pfiletime==NULL)
408         return E_INVALIDARG;
409
410     /* verify if the object was registered before or not */
411     if (RunningObjectTableImpl_GetObjectIndex(This,-1,pmkObjectName,&index)==S_FALSE)
412         return MK_E_UNAVAILABLE;;
413
414     (*pfiletime)= This->runObjTab[index].lastModifObj;
415
416     return S_OK;
417 }
418
419 /***********************************************************************
420  *        RunningObjectTable_EnumRunning
421  */
422 HRESULT WINAPI RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
423                                                   IEnumMoniker **ppenumMoniker) /* Address of output variable that receives the IEnumMoniker interface pointer */
424 {
425     FIXME("(%p,%p) needs the IEnumMoniker implementation  \n",iface,ppenumMoniker);
426     return E_NOTIMPL;
427 }
428
429 /***********************************************************************
430  *        GetObjectIndex
431  */
432 HRESULT WINAPI RunningObjectTableImpl_GetObjectIndex(RunningObjectTableImpl* This,
433                                                      DWORD identReg,
434                                                      IMoniker* pmk,
435                                                      DWORD *indx)
436 {
437
438     DWORD i;
439
440     TRACE("(%p,%ld,%p,%p)\n",This,identReg,pmk,indx);
441
442     if (pmk!=NULL)
443         /* search object identified by a moniker */
444         for(i=0 ; (i < This->runObjTabLastIndx) &&(!IMoniker_IsEqual(This->runObjTab[i].pmkObj,pmk)==S_OK);i++);
445     else
446         /* search object identified by a register identifier */
447         for(i=0;((i<This->runObjTabLastIndx)&&(This->runObjTab[i].identRegObj!=identReg));i++);
448     
449     if (i==This->runObjTabLastIndx)  return S_FALSE;
450
451     if (indx != NULL)  *indx=i;
452
453     return S_OK;
454 }
455
456 /******************************************************************************
457  *              GetRunningObjectTable16 [OLE2.30]
458  */
459 HRESULT WINAPI GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
460 {
461         FIXME("(%ld,%p),stub!\n",reserved,pprot);
462     return E_NOTIMPL;
463 }
464
465 /***********************************************************************
466  *           GetRunningObjectTable (OLE2.73)
467  */
468 HRESULT WINAPI GetRunningObjectTable(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
469 {
470     IID riid=IID_IRunningObjectTable;
471     HRESULT res;
472
473     TRACE("()\n");
474
475     if (reserved!=0)
476         return E_UNEXPECTED;
477
478     if(runningObjectTableInstance==NULL)
479         return CO_E_NOTINITIALIZED;
480
481     res = RunningObjectTableImpl_QueryInterface((IRunningObjectTable*)runningObjectTableInstance,&riid,(void**)pprot);
482
483     return res;
484 }
485
486 /******************************************************************************
487  *              OleRun        [OLE32.123]
488  */
489 HRESULT WINAPI OleRun(LPUNKNOWN pUnknown)
490 {
491   IRunnableObject       *runable;
492   ICOM_THIS(IRunnableObject,pUnknown);
493   LRESULT               ret;
494
495   ret = IRunnableObject_QueryInterface(This,&IID_IRunnableObject,(LPVOID*)&runable);
496   if (ret) 
497         return 0; /* Appears to return no error. */
498   ret  = IRunnableObject_Run(runable,NULL);
499   IRunnableObject_Release(runable);
500   return ret;
501 }
502
503 /******************************************************************************
504  *              MkParseDisplayName        [OLE32.81]
505  */
506 HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szUserName,
507                                 LPDWORD pchEaten, LPMONIKER *ppmk)
508 {
509     FIXME("(%p, %s, %p, %p): stub.\n", pbc, debugstr_w(szUserName), pchEaten, *ppmk);
510     if (!(IsValidInterface((LPUNKNOWN) pbc)))
511         return E_INVALIDARG;
512
513     return MK_E_SYNTAX;
514 }