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

Last change on this file since 10367 was 8620, checked in by sandervl, 23 years ago

Resync with latest Wine

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