source: trunk/src/ole32/moniker.c@ 5602

Last change on this file since 5602 was 5602, checked in by sandervl, 24 years ago

resync with Wine 20010418

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