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