4 * Copyright 1998 Marcus Meissner
5 * Copyright 1999 Noomen Hamza
6 * Copyright 2005 Robert Shearman (for CodeWeavers)
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 * - IRunningObjectTable should work interprocess, but currently doesn't.
24 * Native (on Win2k at least) uses an undocumented RPC interface, IROT, to
25 * communicate with RPCSS which contains the table of marshalled data.
41 #include "wine/list.h"
42 #include "wine/debug.h"
43 #include "wine/unicode.h"
45 #include "compobj_private.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
49 /* see MSDN docs for IROTData::GetComparisonData, which states what this
50 * constant is (http://msdn2.microsoft.com/en-us/library/ms693773.aspx) */
51 #define MAX_COMPARISON_DATA 2048
53 /* define the structure of the running object table elements */
57 MInterfacePointer
* object
; /* marshaled running object*/
58 MInterfacePointer
* moniker
; /* marshaled moniker that identifies this object */
59 MInterfacePointer
* moniker_data
; /* moniker comparison data that identifies this object */
60 DWORD cookie
; /* cookie identifying this object */
61 FILETIME last_modified
;
64 /* define the RunningObjectTableImpl structure */
65 typedef struct RunningObjectTableImpl
67 const IRunningObjectTableVtbl
*lpVtbl
;
70 struct list rot
; /* list of ROT entries */
71 CRITICAL_SECTION lock
;
72 } RunningObjectTableImpl
;
74 static RunningObjectTableImpl
* runningObjectTableInstance
= NULL
;
78 static inline HRESULT WINAPI
79 IrotRegister(DWORD
*cookie
)
81 static LONG last_cookie
= 1;
82 *cookie
= InterlockedIncrement(&last_cookie
);
86 /* define the EnumMonikerImpl structure */
87 typedef struct EnumMonikerImpl
89 const IEnumMonikerVtbl
*lpVtbl
;
92 MInterfacePointer
**monikers
;
98 /* IEnumMoniker Local functions*/
99 static HRESULT WINAPI
EnumMonikerImpl_CreateEnumROTMoniker(MInterfacePointer
**monikers
,
100 ULONG moniker_count
, ULONG pos
, IEnumMoniker
**ppenumMoniker
);
102 static HRESULT
create_stream_on_mip_ro(const MInterfacePointer
*mip
, IStream
**stream
)
104 HGLOBAL hglobal
= GlobalAlloc(0, mip
->ulCntData
);
105 void *pv
= GlobalLock(hglobal
);
106 memcpy(pv
, mip
->abData
, mip
->ulCntData
);
107 GlobalUnlock(hglobal
);
108 return CreateStreamOnHGlobal(hglobal
, TRUE
, stream
);
111 static inline void rot_entry_delete(struct rot_entry
*rot_entry
)
113 /* FIXME: revoke entry from rpcss's copy of the ROT */
114 if (rot_entry
->object
)
118 hr
= create_stream_on_mip_ro(rot_entry
->object
, &stream
);
121 CoReleaseMarshalData(stream
);
122 IUnknown_Release(stream
);
125 if (rot_entry
->moniker
)
129 hr
= create_stream_on_mip_ro(rot_entry
->moniker
, &stream
);
132 CoReleaseMarshalData(stream
);
133 IUnknown_Release(stream
);
136 HeapFree(GetProcessHeap(), 0, rot_entry
->object
);
137 HeapFree(GetProcessHeap(), 0, rot_entry
->moniker
);
138 HeapFree(GetProcessHeap(), 0, rot_entry
->moniker_data
);
139 HeapFree(GetProcessHeap(), 0, rot_entry
);
142 /* moniker_data must be freed with HeapFree when no longer in use */
143 static HRESULT
get_moniker_comparison_data(IMoniker
*pMoniker
, MInterfacePointer
**moniker_data
)
146 IROTData
*pROTData
= NULL
;
147 hr
= IMoniker_QueryInterface(pMoniker
, &IID_IROTData
, (void *)&pROTData
);
150 ULONG size
= MAX_COMPARISON_DATA
;
151 *moniker_data
= HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MInterfacePointer
, abData
[size
]));
152 hr
= IROTData_GetComparisonData(pROTData
, (*moniker_data
)->abData
, size
, &size
);
155 ERR("Failed to copy comparison data into buffer, hr = 0x%08x\n", hr
);
156 HeapFree(GetProcessHeap(), 0, *moniker_data
);
159 (*moniker_data
)->ulCntData
= size
;
164 LPOLESTR pszDisplayName
;
168 TRACE("generating comparison data from display name\n");
170 hr
= CreateBindCtx(0, &pbc
);
173 hr
= IMoniker_GetDisplayName(pMoniker
, pbc
, NULL
, &pszDisplayName
);
174 IBindCtx_Release(pbc
);
177 hr
= IMoniker_GetClassID(pMoniker
, &clsid
);
180 CoTaskMemFree(pszDisplayName
);
184 len
= strlenW(pszDisplayName
);
185 *moniker_data
= HeapAlloc(GetProcessHeap(), 0,
186 FIELD_OFFSET(MInterfacePointer
, abData
[sizeof(CLSID
) + (len
+1)*sizeof(WCHAR
)]));
189 CoTaskMemFree(pszDisplayName
);
190 return E_OUTOFMEMORY
;
192 (*moniker_data
)->ulCntData
= sizeof(CLSID
) + (len
+1)*sizeof(WCHAR
);
194 memcpy(&(*moniker_data
)->abData
[0], &clsid
, sizeof(clsid
));
195 memcpy(&(*moniker_data
)->abData
[sizeof(clsid
)], pszDisplayName
, (len
+1)*sizeof(WCHAR
));
200 static HRESULT
reduce_moniker(IMoniker
*pmk
, IBindCtx
*pbc
, IMoniker
**pmkReduced
)
202 IBindCtx
*pbcNew
= NULL
;
206 hr
= CreateBindCtx(0, &pbcNew
);
211 hr
= IMoniker_Reduce(pmk
, pbc
, MKRREDUCE_ALL
, NULL
, pmkReduced
);
213 ERR("reducing moniker failed with error 0x%08x\n", hr
);
214 if (pbcNew
) IBindCtx_Release(pbcNew
);
218 /***********************************************************************
219 * RunningObjectTable_QueryInterface
221 static HRESULT WINAPI
222 RunningObjectTableImpl_QueryInterface(IRunningObjectTable
* iface
,
223 REFIID riid
,void** ppvObject
)
225 RunningObjectTableImpl
*This
= (RunningObjectTableImpl
*)iface
;
227 TRACE("(%p,%p,%p)\n",This
,riid
,ppvObject
);
229 /* validate arguments */
236 if (IsEqualIID(&IID_IUnknown
, riid
) ||
237 IsEqualIID(&IID_IRunningObjectTable
, riid
))
238 *ppvObject
= (IRunningObjectTable
*)This
;
241 return E_NOINTERFACE
;
243 IRunningObjectTable_AddRef(iface
);
248 /***********************************************************************
249 * RunningObjectTable_AddRef
252 RunningObjectTableImpl_AddRef(IRunningObjectTable
* iface
)
254 RunningObjectTableImpl
*This
= (RunningObjectTableImpl
*)iface
;
256 TRACE("(%p)\n",This
);
258 return InterlockedIncrement(&This
->ref
);
261 /***********************************************************************
262 * RunningObjectTable_Initialize
264 static HRESULT WINAPI
265 RunningObjectTableImpl_Destroy(void)
267 struct list
*cursor
, *cursor2
;
271 if (runningObjectTableInstance
==NULL
)
274 /* free the ROT table memory */
275 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &runningObjectTableInstance
->rot
)
277 struct rot_entry
*rot_entry
= LIST_ENTRY(cursor
, struct rot_entry
, entry
);
278 list_remove(&rot_entry
->entry
);
279 rot_entry_delete(rot_entry
);
282 /* free the ROT structure memory */
283 HeapFree(GetProcessHeap(),0,runningObjectTableInstance
);
284 runningObjectTableInstance
= NULL
;
289 /***********************************************************************
290 * RunningObjectTable_Release
293 RunningObjectTableImpl_Release(IRunningObjectTable
* iface
)
295 RunningObjectTableImpl
*This
= (RunningObjectTableImpl
*)iface
;
298 TRACE("(%p)\n",This
);
300 ref
= InterlockedDecrement(&This
->ref
);
302 /* uninitialize ROT structure if there's no more references to it */
305 struct list
*cursor
, *cursor2
;
306 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->rot
)
308 struct rot_entry
*rot_entry
= LIST_ENTRY(cursor
, struct rot_entry
, entry
);
309 list_remove(&rot_entry
->entry
);
310 rot_entry_delete(rot_entry
);
312 /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
313 * when RunningObjectTableImpl_UnInitialize function is called
320 /***********************************************************************
321 * RunningObjectTable_Register
324 * grfFlags [in] Registration options
325 * punkObject [in] the object being registered
326 * pmkObjectName [in] the moniker of the object being registered
327 * pdwRegister [in] the value identifying the registration
329 static HRESULT WINAPI
330 RunningObjectTableImpl_Register(IRunningObjectTable
* iface
, DWORD grfFlags
,
331 IUnknown
*punkObject
, IMoniker
*pmkObjectName
, DWORD
*pdwRegister
)
333 RunningObjectTableImpl
*This
= (RunningObjectTableImpl
*)iface
;
334 struct rot_entry
*rot_entry
;
336 IStream
*pStream
= NULL
;
340 TRACE("(%p,%d,%p,%p,%p)\n",This
,grfFlags
,punkObject
,pmkObjectName
,pdwRegister
);
342 if (grfFlags
& ~(ROTFLAGS_REGISTRATIONKEEPSALIVE
|ROTFLAGS_ALLOWANYCLIENT
))
344 ERR("Invalid grfFlags: 0x%08x\n", grfFlags
& ~(ROTFLAGS_REGISTRATIONKEEPSALIVE
|ROTFLAGS_ALLOWANYCLIENT
));
348 if (punkObject
==NULL
|| pmkObjectName
==NULL
|| pdwRegister
==NULL
)
351 rot_entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*rot_entry
));
353 return E_OUTOFMEMORY
;
356 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStream
);
359 rot_entry_delete(rot_entry
);
362 mshlflags
= (grfFlags
& ROTFLAGS_REGISTRATIONKEEPSALIVE
) ? MSHLFLAGS_TABLESTRONG
: MSHLFLAGS_TABLEWEAK
;
363 hr
= CoMarshalInterface(pStream
, &IID_IUnknown
, punkObject
, MSHCTX_LOCAL
| MSHCTX_NOSHAREDMEM
, NULL
, mshlflags
);
364 /* FIXME: a cleaner way would be to create an IStream class that writes
365 * directly to an MInterfacePointer */
369 hr
= GetHGlobalFromStream(pStream
, &hglobal
);
372 SIZE_T size
= GlobalSize(hglobal
);
373 const void *pv
= GlobalLock(hglobal
);
374 rot_entry
->object
= HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MInterfacePointer
, abData
[size
]));
375 rot_entry
->object
->ulCntData
= size
;
376 memcpy(&rot_entry
->object
->abData
, pv
, size
);
377 GlobalUnlock(hglobal
);
380 IStream_Release(pStream
);
383 rot_entry_delete(rot_entry
);
387 hr
= CreateBindCtx(0, &pbc
);
390 rot_entry_delete(rot_entry
);
394 hr
= reduce_moniker(pmkObjectName
, pbc
, &pmkObjectName
);
397 rot_entry_delete(rot_entry
);
398 IBindCtx_Release(pbc
);
402 hr
= IMoniker_GetTimeOfLastChange(pmkObjectName
, pbc
, NULL
,
403 &rot_entry
->last_modified
);
404 IBindCtx_Release(pbc
);
407 CoFileTimeNow(&rot_entry
->last_modified
);
411 hr
= get_moniker_comparison_data(pmkObjectName
,
412 &rot_entry
->moniker_data
);
415 rot_entry_delete(rot_entry
);
416 IMoniker_Release(pmkObjectName
);
420 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStream
);
423 rot_entry_delete(rot_entry
);
424 IMoniker_Release(pmkObjectName
);
427 /* marshal moniker */
428 hr
= CoMarshalInterface(pStream
, &IID_IMoniker
, (IUnknown
*)pmkObjectName
,
429 MSHCTX_LOCAL
| MSHCTX_NOSHAREDMEM
, NULL
, MSHLFLAGS_TABLESTRONG
);
430 /* FIXME: a cleaner way would be to create an IStream class that writes
431 * directly to an MInterfacePointer */
435 hr
= GetHGlobalFromStream(pStream
, &hglobal
);
438 SIZE_T size
= GlobalSize(hglobal
);
439 const void *pv
= GlobalLock(hglobal
);
440 rot_entry
->moniker
= HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MInterfacePointer
, abData
[size
]));
441 rot_entry
->moniker
->ulCntData
= size
;
442 memcpy(&rot_entry
->moniker
->abData
, pv
, size
);
443 GlobalUnlock(hglobal
);
446 IStream_Release(pStream
);
447 IMoniker_Release(pmkObjectName
);
450 rot_entry_delete(rot_entry
);
454 /* FIXME: not the right signature of IrotRegister function */
455 hr
= IrotRegister(&rot_entry
->cookie
);
458 rot_entry_delete(rot_entry
);
462 /* gives a registration identifier to the registered object*/
463 *pdwRegister
= rot_entry
->cookie
;
465 EnterCriticalSection(&This
->lock
);
466 /* FIXME: see if object was registered before and return MK_S_MONIKERALREADYREGISTERED */
467 list_add_tail(&This
->rot
, &rot_entry
->entry
);
468 LeaveCriticalSection(&This
->lock
);
473 /***********************************************************************
474 * RunningObjectTable_Revoke
477 * dwRegister [in] Value identifying registration to be revoked
479 static HRESULT WINAPI
480 RunningObjectTableImpl_Revoke( IRunningObjectTable
* iface
, DWORD dwRegister
)
482 RunningObjectTableImpl
*This
= (RunningObjectTableImpl
*)iface
;
483 struct rot_entry
*rot_entry
;
485 TRACE("(%p,%d)\n",This
,dwRegister
);
487 EnterCriticalSection(&This
->lock
);
488 LIST_FOR_EACH_ENTRY(rot_entry
, &This
->rot
, struct rot_entry
, entry
)
490 if (rot_entry
->cookie
== dwRegister
)
492 list_remove(&rot_entry
->entry
);
493 LeaveCriticalSection(&This
->lock
);
495 rot_entry_delete(rot_entry
);
499 LeaveCriticalSection(&This
->lock
);
504 /***********************************************************************
505 * RunningObjectTable_IsRunning
508 * pmkObjectName [in] moniker of the object whose status is desired
510 static HRESULT WINAPI
511 RunningObjectTableImpl_IsRunning( IRunningObjectTable
* iface
, IMoniker
*pmkObjectName
)
513 RunningObjectTableImpl
*This
= (RunningObjectTableImpl
*)iface
;
514 MInterfacePointer
*moniker_data
;
516 struct rot_entry
*rot_entry
;
518 TRACE("(%p,%p)\n",This
,pmkObjectName
);
520 hr
= reduce_moniker(pmkObjectName
, NULL
, &pmkObjectName
);
523 hr
= get_moniker_comparison_data(pmkObjectName
, &moniker_data
);
524 IMoniker_Release(pmkObjectName
);
529 EnterCriticalSection(&This
->lock
);
530 LIST_FOR_EACH_ENTRY(rot_entry
, &This
->rot
, struct rot_entry
, entry
)
532 if ((rot_entry
->moniker_data
->ulCntData
== moniker_data
->ulCntData
) &&
533 !memcmp(&moniker_data
->abData
, &rot_entry
->moniker_data
->abData
, moniker_data
->ulCntData
))
539 LeaveCriticalSection(&This
->lock
);
541 /* FIXME: call IrotIsRunning */
543 HeapFree(GetProcessHeap(), 0, moniker_data
);
548 /***********************************************************************
549 * RunningObjectTable_GetObject
552 * pmkObjectName [in] Pointer to the moniker on the object
553 * ppunkObject [out] variable that receives the IUnknown interface pointer
555 static HRESULT WINAPI
556 RunningObjectTableImpl_GetObject( IRunningObjectTable
* iface
,
557 IMoniker
*pmkObjectName
, IUnknown
**ppunkObject
)
559 RunningObjectTableImpl
*This
= (RunningObjectTableImpl
*)iface
;
560 MInterfacePointer
*moniker_data
;
562 struct rot_entry
*rot_entry
;
564 TRACE("(%p,%p,%p)\n",This
,pmkObjectName
,ppunkObject
);
566 if (ppunkObject
== NULL
)
571 hr
= reduce_moniker(pmkObjectName
, NULL
, &pmkObjectName
);
574 hr
= get_moniker_comparison_data(pmkObjectName
, &moniker_data
);
575 IMoniker_Release(pmkObjectName
);
579 EnterCriticalSection(&This
->lock
);
580 LIST_FOR_EACH_ENTRY(rot_entry
, &This
->rot
, struct rot_entry
, entry
)
582 if ((rot_entry
->moniker_data
->ulCntData
== moniker_data
->ulCntData
) &&
583 !memcmp(&moniker_data
->abData
, &rot_entry
->moniker_data
->abData
, moniker_data
->ulCntData
))
586 hr
= create_stream_on_mip_ro(rot_entry
->object
, &pStream
);
589 hr
= CoUnmarshalInterface(pStream
, &IID_IUnknown
, (void **)ppunkObject
);
590 IStream_Release(pStream
);
593 LeaveCriticalSection(&This
->lock
);
594 HeapFree(GetProcessHeap(), 0, moniker_data
);
599 LeaveCriticalSection(&This
->lock
);
601 /* FIXME: call IrotGetObject */
602 WARN("Moniker unavailable - app may require interprocess running object table\n");
603 hr
= MK_E_UNAVAILABLE
;
605 HeapFree(GetProcessHeap(), 0, moniker_data
);
610 /***********************************************************************
611 * RunningObjectTable_NoteChangeTime
614 * dwRegister [in] Value identifying registration being updated
615 * pfiletime [in] Pointer to structure containing object's last change time
617 static HRESULT WINAPI
618 RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable
* iface
,
619 DWORD dwRegister
, FILETIME
*pfiletime
)
621 RunningObjectTableImpl
*This
= (RunningObjectTableImpl
*)iface
;
622 struct rot_entry
*rot_entry
;
624 TRACE("(%p,%d,%p)\n",This
,dwRegister
,pfiletime
);
626 EnterCriticalSection(&This
->lock
);
627 LIST_FOR_EACH_ENTRY(rot_entry
, &This
->rot
, struct rot_entry
, entry
)
629 if (rot_entry
->cookie
== dwRegister
)
631 rot_entry
->last_modified
= *pfiletime
;
632 LeaveCriticalSection(&This
->lock
);
636 LeaveCriticalSection(&This
->lock
);
638 /* FIXME: call IrotNoteChangeTime */
643 /***********************************************************************
644 * RunningObjectTable_GetTimeOfLastChange
647 * pmkObjectName [in] moniker of the object whose status is desired
648 * pfiletime [out] structure that receives object's last change time
650 static HRESULT WINAPI
651 RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable
* iface
,
652 IMoniker
*pmkObjectName
, FILETIME
*pfiletime
)
654 HRESULT hr
= MK_E_UNAVAILABLE
;
655 RunningObjectTableImpl
*This
= (RunningObjectTableImpl
*)iface
;
656 MInterfacePointer
*moniker_data
;
657 struct rot_entry
*rot_entry
;
659 TRACE("(%p,%p,%p)\n",This
,pmkObjectName
,pfiletime
);
661 if (pmkObjectName
==NULL
|| pfiletime
==NULL
)
664 hr
= reduce_moniker(pmkObjectName
, NULL
, &pmkObjectName
);
667 hr
= get_moniker_comparison_data(pmkObjectName
, &moniker_data
);
668 IMoniker_Release(pmkObjectName
);
672 hr
= MK_E_UNAVAILABLE
;
674 EnterCriticalSection(&This
->lock
);
675 LIST_FOR_EACH_ENTRY(rot_entry
, &This
->rot
, struct rot_entry
, entry
)
677 if ((rot_entry
->moniker_data
->ulCntData
== moniker_data
->ulCntData
) &&
678 !memcmp(&moniker_data
->abData
, &rot_entry
->moniker_data
->abData
, moniker_data
->ulCntData
))
680 *pfiletime
= rot_entry
->last_modified
;
685 LeaveCriticalSection(&This
->lock
);
687 /* FIXME: if (hr != S_OK) call IrotGetTimeOfLastChange */
689 HeapFree(GetProcessHeap(), 0, moniker_data
);
693 /***********************************************************************
694 * RunningObjectTable_EnumRunning
697 * ppenumMoniker [out] receives the IEnumMoniker interface pointer
699 static HRESULT WINAPI
700 RunningObjectTableImpl_EnumRunning(IRunningObjectTable
* iface
,
701 IEnumMoniker
**ppenumMoniker
)
704 RunningObjectTableImpl
*This
= (RunningObjectTableImpl
*)iface
;
705 MInterfacePointer
**monikers
;
706 ULONG moniker_count
= 0;
707 const struct rot_entry
*rot_entry
;
710 EnterCriticalSection(&This
->lock
);
712 LIST_FOR_EACH_ENTRY( rot_entry
, &This
->rot
, const struct rot_entry
, entry
)
715 monikers
= HeapAlloc(GetProcessHeap(), 0, moniker_count
* sizeof(*monikers
));
717 LIST_FOR_EACH_ENTRY( rot_entry
, &This
->rot
, const struct rot_entry
, entry
)
719 SIZE_T size
= FIELD_OFFSET(MInterfacePointer
, abData
[rot_entry
->moniker
->ulCntData
]);
720 monikers
[i
] = HeapAlloc(GetProcessHeap(), 0, size
);
721 memcpy(monikers
[i
], rot_entry
->moniker
, size
);
725 LeaveCriticalSection(&This
->lock
);
727 /* FIXME: call IrotEnumRunning and append data */
729 hr
= EnumMonikerImpl_CreateEnumROTMoniker(monikers
, moniker_count
, 0, ppenumMoniker
);
734 /***********************************************************************
735 * GetRunningObjectTable (OLE32.@)
738 GetRunningObjectTable(DWORD reserved
, LPRUNNINGOBJECTTABLE
*pprot
)
740 IID riid
=IID_IRunningObjectTable
;
748 if(runningObjectTableInstance
==NULL
)
749 return CO_E_NOTINITIALIZED
;
751 res
= IRunningObjectTable_QueryInterface((IRunningObjectTable
*)runningObjectTableInstance
,&riid
,(void**)pprot
);
756 /******************************************************************************
759 HRESULT WINAPI
OleRun(LPUNKNOWN pUnknown
)
761 IRunnableObject
*runable
;
764 TRACE("(%p)\n", pUnknown
);
766 hres
= IUnknown_QueryInterface(pUnknown
, &IID_IRunnableObject
, (void**)&runable
);
768 return S_OK
; /* Appears to return no error. */
770 hres
= IRunnableObject_Run(runable
, NULL
);
771 IRunnableObject_Release(runable
);
775 /******************************************************************************
776 * MkParseDisplayName [OLE32.@]
778 HRESULT WINAPI
MkParseDisplayName(LPBC pbc
, LPCOLESTR szUserName
,
779 LPDWORD pchEaten
, LPMONIKER
*ppmk
)
781 FIXME("(%p, %s, %p, %p): stub.\n", pbc
, debugstr_w(szUserName
), pchEaten
, *ppmk
);
783 if (!(IsValidInterface((LPUNKNOWN
) pbc
)))
789 /* Virtual function table for the IRunningObjectTable class. */
790 static const IRunningObjectTableVtbl VT_RunningObjectTableImpl
=
792 RunningObjectTableImpl_QueryInterface
,
793 RunningObjectTableImpl_AddRef
,
794 RunningObjectTableImpl_Release
,
795 RunningObjectTableImpl_Register
,
796 RunningObjectTableImpl_Revoke
,
797 RunningObjectTableImpl_IsRunning
,
798 RunningObjectTableImpl_GetObject
,
799 RunningObjectTableImpl_NoteChangeTime
,
800 RunningObjectTableImpl_GetTimeOfLastChange
,
801 RunningObjectTableImpl_EnumRunning
804 /***********************************************************************
805 * RunningObjectTable_Initialize
807 HRESULT WINAPI
RunningObjectTableImpl_Initialize(void)
811 /* create the unique instance of the RunningObjectTableImpl structure */
812 runningObjectTableInstance
= HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl
));
814 if (!runningObjectTableInstance
)
815 return E_OUTOFMEMORY
;
817 /* initialize the virtual table function */
818 runningObjectTableInstance
->lpVtbl
= &VT_RunningObjectTableImpl
;
820 /* the initial reference is set to "1" ! because if set to "0" it will be not practis when */
821 /* the ROT referred many times not in the same time (all the objects in the ROT will */
822 /* be removed every time the ROT is removed ) */
823 runningObjectTableInstance
->ref
= 1;
825 list_init(&runningObjectTableInstance
->rot
);
826 InitializeCriticalSection(&runningObjectTableInstance
->lock
);
831 /***********************************************************************
832 * RunningObjectTable_UnInitialize
834 HRESULT WINAPI
RunningObjectTableImpl_UnInitialize()
838 if (runningObjectTableInstance
==NULL
)
841 RunningObjectTableImpl_Release((IRunningObjectTable
*)runningObjectTableInstance
);
843 RunningObjectTableImpl_Destroy();
848 /***********************************************************************
849 * EnumMoniker_QueryInterface
851 static HRESULT WINAPI
EnumMonikerImpl_QueryInterface(IEnumMoniker
* iface
,REFIID riid
,void** ppvObject
)
853 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
855 TRACE("(%p,%p,%p)\n",This
,riid
,ppvObject
);
857 /* validate arguments */
858 if (ppvObject
== NULL
)
863 if (IsEqualIID(&IID_IUnknown
, riid
))
864 *ppvObject
= (IEnumMoniker
*)This
;
866 if (IsEqualIID(&IID_IEnumMoniker
, riid
))
867 *ppvObject
= (IEnumMoniker
*)This
;
869 if ((*ppvObject
)==NULL
)
870 return E_NOINTERFACE
;
872 IEnumMoniker_AddRef(iface
);
877 /***********************************************************************
880 static ULONG WINAPI
EnumMonikerImpl_AddRef(IEnumMoniker
* iface
)
882 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
884 TRACE("(%p)\n",This
);
886 return InterlockedIncrement(&This
->ref
);
889 /***********************************************************************
890 * EnumMoniker_release
892 static ULONG WINAPI
EnumMonikerImpl_Release(IEnumMoniker
* iface
)
894 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
897 TRACE("(%p)\n",This
);
899 ref
= InterlockedDecrement(&This
->ref
);
901 /* uninitialize rot structure if there's no more reference to it*/
906 TRACE("(%p) Deleting\n",This
);
908 for (i
= 0; i
< This
->moniker_count
; i
++)
909 HeapFree(GetProcessHeap(), 0, This
->monikers
[i
]);
910 HeapFree(GetProcessHeap(), 0, This
->monikers
);
911 HeapFree(GetProcessHeap(), 0, This
);
916 /***********************************************************************
919 static HRESULT WINAPI
EnumMonikerImpl_Next(IEnumMoniker
* iface
, ULONG celt
, IMoniker
** rgelt
, ULONG
* pceltFetched
)
922 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
925 TRACE("(%p) TabCurrentPos %d Tablastindx %d\n", This
, This
->pos
, This
->moniker_count
);
927 /* retrieve the requested number of moniker from the current position */
928 for(i
= 0; (This
->pos
< This
->moniker_count
) && (i
< celt
); i
++)
931 hr
= create_stream_on_mip_ro(This
->monikers
[This
->pos
++], &stream
);
932 if (hr
!= S_OK
) break;
933 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void **)&rgelt
[i
]);
934 IStream_Release(stream
);
935 if (hr
!= S_OK
) break;
938 if (pceltFetched
!= NULL
)
951 /***********************************************************************
954 static HRESULT WINAPI
EnumMonikerImpl_Skip(IEnumMoniker
* iface
, ULONG celt
)
956 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
958 TRACE("(%p)\n",This
);
960 if (This
->pos
+ celt
>= This
->moniker_count
)
968 /***********************************************************************
971 static HRESULT WINAPI
EnumMonikerImpl_Reset(IEnumMoniker
* iface
)
973 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
975 This
->pos
= 0; /* set back to start of list */
977 TRACE("(%p)\n",This
);
982 /***********************************************************************
985 static HRESULT WINAPI
EnumMonikerImpl_Clone(IEnumMoniker
* iface
, IEnumMoniker
** ppenum
)
987 EnumMonikerImpl
*This
= (EnumMonikerImpl
*)iface
;
988 MInterfacePointer
**monikers
= HeapAlloc(GetProcessHeap(), 0, sizeof(*monikers
)*This
->moniker_count
);
991 TRACE("(%p)\n",This
);
993 for (i
= 0; i
< This
->moniker_count
; i
++)
995 SIZE_T size
= FIELD_OFFSET(MInterfacePointer
, abData
[This
->monikers
[i
]->ulCntData
]);
996 monikers
[i
] = HeapAlloc(GetProcessHeap(), 0, size
);
997 memcpy(monikers
[i
], This
->monikers
[i
], size
);
1000 /* copy the enum structure */
1001 return EnumMonikerImpl_CreateEnumROTMoniker(monikers
, This
->moniker_count
,
1005 /* Virtual function table for the IEnumMoniker class. */
1006 static const IEnumMonikerVtbl VT_EnumMonikerImpl
=
1008 EnumMonikerImpl_QueryInterface
,
1009 EnumMonikerImpl_AddRef
,
1010 EnumMonikerImpl_Release
,
1011 EnumMonikerImpl_Next
,
1012 EnumMonikerImpl_Skip
,
1013 EnumMonikerImpl_Reset
,
1014 EnumMonikerImpl_Clone
1017 /***********************************************************************
1018 * EnumMonikerImpl_CreateEnumROTMoniker
1019 * Used by EnumRunning to create the structure and EnumClone
1020 * to copy the structure
1022 static HRESULT WINAPI
EnumMonikerImpl_CreateEnumROTMoniker(MInterfacePointer
**monikers
,
1023 ULONG moniker_count
,
1025 IEnumMoniker
**ppenumMoniker
)
1027 EnumMonikerImpl
* This
= NULL
;
1030 return E_INVALIDARG
;
1032 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl
));
1033 if (!This
) return E_OUTOFMEMORY
;
1035 TRACE("(%p)\n", This
);
1037 /* initialize the virtual table function */
1038 This
->lpVtbl
= &VT_EnumMonikerImpl
;
1040 /* the initial reference is set to "1" */
1041 This
->ref
= 1; /* set the ref count to one */
1042 This
->pos
= current_pos
; /* Set the list start posn */
1043 This
->moniker_count
= moniker_count
; /* Need the same size table as ROT */
1044 This
->monikers
= monikers
;
1046 *ppenumMoniker
= (IEnumMoniker
*)This
;
1052 /* Shared implementation of moniker marshaler based on saving and loading of
1055 typedef struct MonikerMarshal
1057 const IUnknownVtbl
*lpVtbl
;
1058 const IMarshalVtbl
*lpVtblMarshal
;
1064 static inline MonikerMarshal
*impl_from_IMarshal( IMarshal
*iface
)
1066 return (MonikerMarshal
*)((char*)iface
- FIELD_OFFSET(MonikerMarshal
, lpVtblMarshal
));
1069 static HRESULT WINAPI
MonikerMarshalInner_QueryInterface(IUnknown
*iface
, REFIID riid
, LPVOID
*ppv
)
1071 MonikerMarshal
*This
= (MonikerMarshal
*)iface
;
1072 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
1074 if (IsEqualIID(&IID_IUnknown
, riid
) || IsEqualIID(&IID_IMarshal
, riid
))
1076 *ppv
= &This
->lpVtblMarshal
;
1077 IUnknown_AddRef((IUnknown
*)&This
->lpVtblMarshal
);
1080 FIXME("No interface for %s\n", debugstr_guid(riid
));
1081 return E_NOINTERFACE
;
1084 static ULONG WINAPI
MonikerMarshalInner_AddRef(IUnknown
*iface
)
1086 MonikerMarshal
*This
= (MonikerMarshal
*)iface
;
1087 return InterlockedIncrement(&This
->ref
);
1090 static ULONG WINAPI
MonikerMarshalInner_Release(IUnknown
*iface
)
1092 MonikerMarshal
*This
= (MonikerMarshal
*)iface
;
1093 ULONG ref
= InterlockedDecrement(&This
->ref
);
1095 if (!ref
) HeapFree(GetProcessHeap(), 0, This
);
1099 static const IUnknownVtbl VT_MonikerMarshalInner
=
1101 MonikerMarshalInner_QueryInterface
,
1102 MonikerMarshalInner_AddRef
,
1103 MonikerMarshalInner_Release
1106 static HRESULT WINAPI
MonikerMarshal_QueryInterface(IMarshal
*iface
, REFIID riid
, LPVOID
*ppv
)
1108 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1109 return IMoniker_QueryInterface(This
->moniker
, riid
, ppv
);
1112 static ULONG WINAPI
MonikerMarshal_AddRef(IMarshal
*iface
)
1114 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1115 return IMoniker_AddRef(This
->moniker
);
1118 static ULONG WINAPI
MonikerMarshal_Release(IMarshal
*iface
)
1120 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1121 return IMoniker_Release(This
->moniker
);
1124 static HRESULT WINAPI
MonikerMarshal_GetUnmarshalClass(
1125 LPMARSHAL iface
, REFIID riid
, void* pv
, DWORD dwDestContext
,
1126 void* pvDestContext
, DWORD mshlflags
, CLSID
* pCid
)
1128 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1130 TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid
), pv
,
1131 dwDestContext
, pvDestContext
, mshlflags
, pCid
);
1133 return IMoniker_GetClassID(This
->moniker
, pCid
);
1136 static HRESULT WINAPI
MonikerMarshal_GetMarshalSizeMax(
1137 LPMARSHAL iface
, REFIID riid
, void* pv
, DWORD dwDestContext
,
1138 void* pvDestContext
, DWORD mshlflags
, DWORD
* pSize
)
1140 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1142 ULARGE_INTEGER size
;
1144 TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid
), pv
,
1145 dwDestContext
, pvDestContext
, mshlflags
, pSize
);
1147 hr
= IMoniker_GetSizeMax(This
->moniker
, &size
);
1149 *pSize
= (DWORD
)size
.QuadPart
;
1153 static HRESULT WINAPI
MonikerMarshal_MarshalInterface(LPMARSHAL iface
, IStream
*pStm
,
1154 REFIID riid
, void* pv
, DWORD dwDestContext
,
1155 void* pvDestContext
, DWORD mshlflags
)
1157 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1159 TRACE("(%p, %s, %p, %x, %p, %x)\n", pStm
, debugstr_guid(riid
), pv
,
1160 dwDestContext
, pvDestContext
, mshlflags
);
1162 return IMoniker_Save(This
->moniker
, pStm
, FALSE
);
1165 static HRESULT WINAPI
MonikerMarshal_UnmarshalInterface(LPMARSHAL iface
, IStream
*pStm
, REFIID riid
, void **ppv
)
1167 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1170 TRACE("(%p, %s, %p)\n", pStm
, debugstr_guid(riid
), ppv
);
1172 hr
= IMoniker_Load(This
->moniker
, pStm
);
1174 hr
= IMoniker_QueryInterface(This
->moniker
, riid
, ppv
);
1178 static HRESULT WINAPI
MonikerMarshal_ReleaseMarshalData(LPMARSHAL iface
, IStream
*pStm
)
1181 /* can't release a state-based marshal as nothing on server side to
1186 static HRESULT WINAPI
MonikerMarshal_DisconnectObject(LPMARSHAL iface
, DWORD dwReserved
)
1189 /* can't disconnect a state-based marshal as nothing on server side to
1190 * disconnect from */
1194 static const IMarshalVtbl VT_MonikerMarshal
=
1196 MonikerMarshal_QueryInterface
,
1197 MonikerMarshal_AddRef
,
1198 MonikerMarshal_Release
,
1199 MonikerMarshal_GetUnmarshalClass
,
1200 MonikerMarshal_GetMarshalSizeMax
,
1201 MonikerMarshal_MarshalInterface
,
1202 MonikerMarshal_UnmarshalInterface
,
1203 MonikerMarshal_ReleaseMarshalData
,
1204 MonikerMarshal_DisconnectObject
1207 HRESULT
MonikerMarshal_Create(IMoniker
*inner
, IUnknown
**outer
)
1209 MonikerMarshal
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
1210 if (!This
) return E_OUTOFMEMORY
;
1212 This
->lpVtbl
= &VT_MonikerMarshalInner
;
1213 This
->lpVtblMarshal
= &VT_MonikerMarshal
;
1215 This
->moniker
= inner
;
1217 *outer
= (IUnknown
*)&This
->lpVtbl
;