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

Last change on this file since 6648 was 6648, checked in by bird, 24 years ago

Added $Id:$ keyword.

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