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