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

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

Wine 20020215 resync

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