4 * Copyright 1998 Marcus Meissner
5 * Copyright 1999 Noomen Hamza
6 * Copyright 2005 Robert Shearman (for CodeWeavers)
7 * Copyright 2007 Robert Shearman
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include <wine/exception.h>
30 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
32 /* see MSDN docs for IROTData::GetComparisonData, which states what this
35 #define MAX_COMPARISON_DATA 2048
37 static LONG WINAPI
rpc_filter(EXCEPTION_POINTERS
*eptr
)
39 return I_RpcExceptionFilter(eptr
->ExceptionRecord
->ExceptionCode
);
42 /* define the structure of the running object table elements */
46 InterfaceData
* object
; /* marshaled running object*/
47 MonikerComparisonData
* moniker_data
; /* moniker comparison data that identifies this object */
48 DWORD cookie
; /* cookie identifying this object */
49 FILETIME last_modified
;
50 IrotContextHandle ctxt_handle
;
53 /* define the RunningObjectTableImpl structure */
54 typedef struct RunningObjectTableImpl
56 IRunningObjectTable IRunningObjectTable_iface
;
59 struct list rot
; /* list of ROT entries */
60 CRITICAL_SECTION lock
;
61 } RunningObjectTableImpl
;
63 static RunningObjectTableImpl
* runningObjectTableInstance
= NULL
;
64 static IrotHandle irot_handle
;
66 /* define the EnumMonikerImpl structure */
67 typedef struct EnumMonikerImpl
69 IEnumMoniker IEnumMoniker_iface
;
72 InterfaceList
*moniker_list
;
76 static inline RunningObjectTableImpl
*impl_from_IRunningObjectTable(IRunningObjectTable
*iface
)
78 return CONTAINING_RECORD(iface
, RunningObjectTableImpl
, IRunningObjectTable_iface
);
81 static inline EnumMonikerImpl
*impl_from_IEnumMoniker(IEnumMoniker
*iface
)
83 return CONTAINING_RECORD(iface
, EnumMonikerImpl
, IEnumMoniker_iface
);
86 /* IEnumMoniker Local functions*/
87 static HRESULT
EnumMonikerImpl_CreateEnumROTMoniker(InterfaceList
*moniker_list
,
88 ULONG pos
, IEnumMoniker
**ppenumMoniker
);
90 static IrotHandle
get_irot_handle(void)
96 IrotHandle new_handle
;
97 unsigned short ncacn_np
[] = IROT_PROTSEQ
;
98 unsigned short endpoint
[] = IROT_ENDPOINT
;
99 status
= RpcStringBindingComposeW(NULL
, ncacn_np
, NULL
, endpoint
, NULL
, &binding
);
100 if (status
== RPC_S_OK
)
102 status
= RpcBindingFromStringBindingW(binding
, &new_handle
);
103 RpcStringFreeW(&binding
);
105 if (status
!= RPC_S_OK
)
107 if (InterlockedCompareExchangePointer(&irot_handle
, new_handle
, NULL
))
108 /* another thread beat us to it */
109 RpcBindingFree(&new_handle
);
114 static BOOL
start_rpcss(void)
116 PROCESS_INFORMATION pi
;
119 static const WCHAR rpcss
[] = {'\\','r','p','c','s','s','.','e','x','e',0};
125 ZeroMemory(&si
, sizeof(STARTUPINFOA
));
126 si
.cb
= sizeof(STARTUPINFOA
);
127 GetSystemDirectoryW( cmd
, MAX_PATH
- sizeof(rpcss
)/sizeof(WCHAR
) );
128 strcatW( cmd
, rpcss
);
130 Wow64DisableWow64FsRedirection( &redir
);
131 rslt
= CreateProcessW( cmd
, cmd
, NULL
, NULL
, FALSE
, DETACHED_PROCESS
, NULL
, NULL
, &si
, &pi
);
132 Wow64RevertWow64FsRedirection( redir
);
136 CloseHandle(pi
.hProcess
);
137 CloseHandle(pi
.hThread
);
144 static HRESULT
create_stream_on_mip_ro(const InterfaceData
*mip
, IStream
**stream
)
146 HGLOBAL hglobal
= GlobalAlloc(0, mip
->ulCntData
);
147 void *pv
= GlobalLock(hglobal
);
148 memcpy(pv
, mip
->abData
, mip
->ulCntData
);
149 GlobalUnlock(hglobal
);
150 return CreateStreamOnHGlobal(hglobal
, TRUE
, stream
);
153 static void rot_entry_delete(struct rot_entry
*rot_entry
)
155 if (rot_entry
->cookie
)
157 InterfaceData
*object
= NULL
;
158 InterfaceData
*moniker
= NULL
;
161 IrotRevoke(get_irot_handle(), rot_entry
->cookie
,
162 &rot_entry
->ctxt_handle
, &object
, &moniker
);
168 MIDL_user_free(object
);
173 hr
= create_stream_on_mip_ro(moniker
, &stream
);
176 CoReleaseMarshalData(stream
);
177 IStream_Release(stream
);
180 MIDL_user_free(moniker
);
182 if (rot_entry
->object
)
186 hr
= create_stream_on_mip_ro(rot_entry
->object
, &stream
);
189 CoReleaseMarshalData(stream
);
190 IStream_Release(stream
);
193 HeapFree(GetProcessHeap(), 0, rot_entry
->object
);
194 HeapFree(GetProcessHeap(), 0, rot_entry
->moniker_data
);
195 HeapFree(GetProcessHeap(), 0, rot_entry
);
198 /* moniker_data must be freed with HeapFree when no longer in use */
199 static HRESULT
get_moniker_comparison_data(IMoniker
*pMoniker
, MonikerComparisonData
**moniker_data
)
202 IROTData
*pROTData
= NULL
;
203 hr
= IMoniker_QueryInterface(pMoniker
, &IID_IROTData
, (void *)&pROTData
);
206 ULONG size
= MAX_COMPARISON_DATA
;
207 *moniker_data
= HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MonikerComparisonData
, abData
[size
]));
210 IROTData_Release(pROTData
);
211 return E_OUTOFMEMORY
;
213 hr
= IROTData_GetComparisonData(pROTData
, (*moniker_data
)->abData
, size
, &size
);
214 IROTData_Release(pROTData
);
217 ERR("Failed to copy comparison data into buffer, hr = 0x%08x\n", hr
);
218 HeapFree(GetProcessHeap(), 0, *moniker_data
);
221 (*moniker_data
)->ulCntData
= size
;
226 LPOLESTR pszDisplayName
;
230 TRACE("generating comparison data from display name\n");
232 hr
= CreateBindCtx(0, &pbc
);
235 hr
= IMoniker_GetDisplayName(pMoniker
, pbc
, NULL
, &pszDisplayName
);
236 IBindCtx_Release(pbc
);
239 hr
= IMoniker_GetClassID(pMoniker
, &clsid
);
242 CoTaskMemFree(pszDisplayName
);
246 len
= strlenW(pszDisplayName
);
247 *moniker_data
= HeapAlloc(GetProcessHeap(), 0,
248 FIELD_OFFSET(MonikerComparisonData
, abData
[sizeof(CLSID
) + (len
+1)*sizeof(WCHAR
)]));
251 CoTaskMemFree(pszDisplayName
);
252 return E_OUTOFMEMORY
;
254 (*moniker_data
)->ulCntData
= sizeof(CLSID
) + (len
+1)*sizeof(WCHAR
);
256 memcpy(&(*moniker_data
)->abData
[0], &clsid
, sizeof(clsid
));
257 memcpy(&(*moniker_data
)->abData
[sizeof(clsid
)], pszDisplayName
, (len
+1)*sizeof(WCHAR
));
258 CoTaskMemFree(pszDisplayName
);
263 static HRESULT
reduce_moniker(IMoniker
*pmk
, IBindCtx
*pbc
, IMoniker
**pmkReduced
)
265 IBindCtx
*pbcNew
= NULL
;
269 hr
= CreateBindCtx(0, &pbcNew
);
274 hr
= IMoniker_Reduce(pmk
, pbc
, MKRREDUCE_ALL
, NULL
, pmkReduced
);
276 ERR("reducing moniker failed with error 0x%08x\n", hr
);
277 if (pbcNew
) IBindCtx_Release(pbcNew
);
281 /***********************************************************************
282 * RunningObjectTable_QueryInterface
284 static HRESULT WINAPI
285 RunningObjectTableImpl_QueryInterface(IRunningObjectTable
* iface
,
286 REFIID riid
,void** ppvObject
)
288 RunningObjectTableImpl
*This
= impl_from_IRunningObjectTable(iface
);
290 TRACE("(%p,%p,%p)\n",This
,riid
,ppvObject
);
292 /* validate arguments */
299 if (IsEqualIID(&IID_IUnknown
, riid
) ||
300 IsEqualIID(&IID_IRunningObjectTable
, riid
))
304 return E_NOINTERFACE
;
306 IRunningObjectTable_AddRef(iface
);
311 /***********************************************************************
312 * RunningObjectTable_AddRef
315 RunningObjectTableImpl_AddRef(IRunningObjectTable
* iface
)
317 RunningObjectTableImpl
*This
= impl_from_IRunningObjectTable(iface
);
319 TRACE("(%p)\n",This
);
321 return InterlockedIncrement(&This
->ref
);
324 /***********************************************************************
325 * RunningObjectTable_Destroy
328 RunningObjectTableImpl_Destroy(void)
330 struct list
*cursor
, *cursor2
;
331 IrotHandle old_handle
;
335 if (runningObjectTableInstance
==NULL
)
338 /* free the ROT table memory */
339 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &runningObjectTableInstance
->rot
)
341 struct rot_entry
*rot_entry
= LIST_ENTRY(cursor
, struct rot_entry
, entry
);
342 list_remove(&rot_entry
->entry
);
343 rot_entry_delete(rot_entry
);
346 DEBUG_CLEAR_CRITSEC_NAME(&runningObjectTableInstance
->lock
);
347 DeleteCriticalSection(&runningObjectTableInstance
->lock
);
349 /* free the ROT structure memory */
350 HeapFree(GetProcessHeap(),0,runningObjectTableInstance
);
351 runningObjectTableInstance
= NULL
;
353 old_handle
= irot_handle
;
356 RpcBindingFree(&old_handle
);
361 /***********************************************************************
362 * RunningObjectTable_Release
365 RunningObjectTableImpl_Release(IRunningObjectTable
* iface
)
367 RunningObjectTableImpl
*This
= impl_from_IRunningObjectTable(iface
);
370 TRACE("(%p)\n",This
);
372 ref
= InterlockedDecrement(&This
->ref
);
374 /* uninitialize ROT structure if there's no more references to it */
377 struct list
*cursor
, *cursor2
;
378 LIST_FOR_EACH_SAFE(cursor
, cursor2
, &This
->rot
)
380 struct rot_entry
*rot_entry
= LIST_ENTRY(cursor
, struct rot_entry
, entry
);
381 list_remove(&rot_entry
->entry
);
382 rot_entry_delete(rot_entry
);
384 /* RunningObjectTable data structure will be not destroyed here ! the destruction will be done only
385 * when RunningObjectTableImpl_UnInitialize function is called
392 /***********************************************************************
393 * RunningObjectTable_Register
396 * grfFlags [in] Registration options
397 * punkObject [in] the object being registered
398 * pmkObjectName [in] the moniker of the object being registered
399 * pdwRegister [out] the value identifying the registration
401 static HRESULT WINAPI
402 RunningObjectTableImpl_Register(IRunningObjectTable
* iface
, DWORD grfFlags
,
403 IUnknown
*punkObject
, IMoniker
*pmkObjectName
, DWORD
*pdwRegister
)
405 RunningObjectTableImpl
*This
= impl_from_IRunningObjectTable(iface
);
406 struct rot_entry
*rot_entry
;
408 IStream
*pStream
= NULL
;
411 InterfaceData
*moniker
= NULL
;
413 TRACE("(%p,%d,%p,%p,%p)\n",This
,grfFlags
,punkObject
,pmkObjectName
,pdwRegister
);
415 if (grfFlags
& ~(ROTFLAGS_REGISTRATIONKEEPSALIVE
|ROTFLAGS_ALLOWANYCLIENT
))
417 ERR("Invalid grfFlags: 0x%08x\n", grfFlags
& ~(ROTFLAGS_REGISTRATIONKEEPSALIVE
|ROTFLAGS_ALLOWANYCLIENT
));
421 if (punkObject
==NULL
|| pmkObjectName
==NULL
|| pdwRegister
==NULL
)
424 rot_entry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*rot_entry
));
426 return E_OUTOFMEMORY
;
429 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStream
);
432 rot_entry_delete(rot_entry
);
435 mshlflags
= (grfFlags
& ROTFLAGS_REGISTRATIONKEEPSALIVE
) ? MSHLFLAGS_TABLESTRONG
: MSHLFLAGS_TABLEWEAK
;
436 hr
= CoMarshalInterface(pStream
, &IID_IUnknown
, punkObject
, MSHCTX_LOCAL
| MSHCTX_NOSHAREDMEM
, NULL
, mshlflags
);
437 /* FIXME: a cleaner way would be to create an IStream class that writes
438 * directly to an MInterfacePointer */
442 hr
= GetHGlobalFromStream(pStream
, &hglobal
);
445 SIZE_T size
= GlobalSize(hglobal
);
446 const void *pv
= GlobalLock(hglobal
);
447 rot_entry
->object
= HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MInterfacePointer
, abData
[size
]));
448 rot_entry
->object
->ulCntData
= size
;
449 memcpy(rot_entry
->object
->abData
, pv
, size
);
450 GlobalUnlock(hglobal
);
453 IStream_Release(pStream
);
456 rot_entry_delete(rot_entry
);
460 hr
= CreateBindCtx(0, &pbc
);
463 rot_entry_delete(rot_entry
);
467 hr
= reduce_moniker(pmkObjectName
, pbc
, &pmkObjectName
);
470 rot_entry_delete(rot_entry
);
471 IBindCtx_Release(pbc
);
475 hr
= IMoniker_GetTimeOfLastChange(pmkObjectName
, pbc
, NULL
,
476 &rot_entry
->last_modified
);
477 IBindCtx_Release(pbc
);
480 CoFileTimeNow(&rot_entry
->last_modified
);
484 hr
= get_moniker_comparison_data(pmkObjectName
,
485 &rot_entry
->moniker_data
);
488 rot_entry_delete(rot_entry
);
489 IMoniker_Release(pmkObjectName
);
493 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &pStream
);
496 rot_entry_delete(rot_entry
);
497 IMoniker_Release(pmkObjectName
);
500 /* marshal moniker */
501 hr
= CoMarshalInterface(pStream
, &IID_IMoniker
, (IUnknown
*)pmkObjectName
,
502 MSHCTX_LOCAL
| MSHCTX_NOSHAREDMEM
, NULL
, MSHLFLAGS_TABLESTRONG
);
503 /* FIXME: a cleaner way would be to create an IStream class that writes
504 * directly to an MInterfacePointer */
508 hr
= GetHGlobalFromStream(pStream
, &hglobal
);
511 SIZE_T size
= GlobalSize(hglobal
);
512 const void *pv
= GlobalLock(hglobal
);
513 moniker
= HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData
, abData
[size
]));
514 moniker
->ulCntData
= size
;
515 memcpy(moniker
->abData
, pv
, size
);
516 GlobalUnlock(hglobal
);
519 IStream_Release(pStream
);
520 IMoniker_Release(pmkObjectName
);
523 HeapFree(GetProcessHeap(), 0, moniker
);
524 rot_entry_delete(rot_entry
);
533 hr
= IrotRegister(get_irot_handle(), rot_entry
->moniker_data
,
534 rot_entry
->object
, moniker
,
535 &rot_entry
->last_modified
, grfFlags
,
536 &rot_entry
->cookie
, &rot_entry
->ctxt_handle
);
540 hr
= HRESULT_FROM_WIN32(GetExceptionCode());
543 if (hr
== HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE
))
550 HeapFree(GetProcessHeap(), 0, moniker
);
553 rot_entry_delete(rot_entry
);
557 /* gives a registration identifier to the registered object*/
558 *pdwRegister
= rot_entry
->cookie
;
560 EnterCriticalSection(&This
->lock
);
561 list_add_tail(&This
->rot
, &rot_entry
->entry
);
562 LeaveCriticalSection(&This
->lock
);
567 /***********************************************************************
568 * RunningObjectTable_Revoke
571 * dwRegister [in] Value identifying registration to be revoked
573 static HRESULT WINAPI
574 RunningObjectTableImpl_Revoke( IRunningObjectTable
* iface
, DWORD dwRegister
)
576 RunningObjectTableImpl
*This
= impl_from_IRunningObjectTable(iface
);
577 struct rot_entry
*rot_entry
;
579 TRACE("(%p,%d)\n",This
,dwRegister
);
581 EnterCriticalSection(&This
->lock
);
582 LIST_FOR_EACH_ENTRY(rot_entry
, &This
->rot
, struct rot_entry
, entry
)
584 if (rot_entry
->cookie
== dwRegister
)
586 list_remove(&rot_entry
->entry
);
587 LeaveCriticalSection(&This
->lock
);
589 rot_entry_delete(rot_entry
);
593 LeaveCriticalSection(&This
->lock
);
598 /***********************************************************************
599 * RunningObjectTable_IsRunning
602 * pmkObjectName [in] moniker of the object whose status is desired
604 static HRESULT WINAPI
605 RunningObjectTableImpl_IsRunning( IRunningObjectTable
* iface
, IMoniker
*pmkObjectName
)
607 RunningObjectTableImpl
*This
= impl_from_IRunningObjectTable(iface
);
608 MonikerComparisonData
*moniker_data
;
610 const struct rot_entry
*rot_entry
;
612 TRACE("(%p,%p)\n",This
,pmkObjectName
);
614 hr
= reduce_moniker(pmkObjectName
, NULL
, &pmkObjectName
);
617 hr
= get_moniker_comparison_data(pmkObjectName
, &moniker_data
);
618 IMoniker_Release(pmkObjectName
);
623 EnterCriticalSection(&This
->lock
);
624 LIST_FOR_EACH_ENTRY(rot_entry
, &This
->rot
, const struct rot_entry
, entry
)
626 if ((rot_entry
->moniker_data
->ulCntData
== moniker_data
->ulCntData
) &&
627 !memcmp(moniker_data
->abData
, rot_entry
->moniker_data
->abData
, moniker_data
->ulCntData
))
633 LeaveCriticalSection(&This
->lock
);
641 hr
= IrotIsRunning(get_irot_handle(), moniker_data
);
645 hr
= HRESULT_FROM_WIN32(GetExceptionCode());
648 if (hr
== HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE
))
657 HeapFree(GetProcessHeap(), 0, moniker_data
);
662 /***********************************************************************
663 * RunningObjectTable_GetObject
666 * pmkObjectName [in] Pointer to the moniker on the object
667 * ppunkObject [out] variable that receives the IUnknown interface pointer
669 static HRESULT WINAPI
670 RunningObjectTableImpl_GetObject( IRunningObjectTable
* iface
,
671 IMoniker
*pmkObjectName
, IUnknown
**ppunkObject
)
673 RunningObjectTableImpl
*This
= impl_from_IRunningObjectTable(iface
);
674 MonikerComparisonData
*moniker_data
;
675 InterfaceData
*object
= NULL
;
678 struct rot_entry
*rot_entry
;
680 TRACE("(%p,%p,%p)\n",This
,pmkObjectName
,ppunkObject
);
682 if (ppunkObject
== NULL
)
687 hr
= reduce_moniker(pmkObjectName
, NULL
, &pmkObjectName
);
690 hr
= get_moniker_comparison_data(pmkObjectName
, &moniker_data
);
691 IMoniker_Release(pmkObjectName
);
695 EnterCriticalSection(&This
->lock
);
696 LIST_FOR_EACH_ENTRY(rot_entry
, &This
->rot
, struct rot_entry
, entry
)
698 if ((rot_entry
->moniker_data
->ulCntData
== moniker_data
->ulCntData
) &&
699 !memcmp(moniker_data
->abData
, rot_entry
->moniker_data
->abData
, moniker_data
->ulCntData
))
702 hr
= create_stream_on_mip_ro(rot_entry
->object
, &pStream
);
705 hr
= CoUnmarshalInterface(pStream
, &IID_IUnknown
, (void **)ppunkObject
);
706 IStream_Release(pStream
);
709 LeaveCriticalSection(&This
->lock
);
710 HeapFree(GetProcessHeap(), 0, moniker_data
);
715 LeaveCriticalSection(&This
->lock
);
717 TRACE("moniker unavailable locally, calling SCM\n");
723 hr
= IrotGetObject(get_irot_handle(), moniker_data
, &object
, &cookie
);
727 hr
= HRESULT_FROM_WIN32(GetExceptionCode());
730 if (hr
== HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE
))
741 hr
= create_stream_on_mip_ro(object
, &pStream
);
744 hr
= CoUnmarshalInterface(pStream
, &IID_IUnknown
, (void **)ppunkObject
);
745 IStream_Release(pStream
);
749 WARN("Moniker unavailable, IrotGetObject returned 0x%08x\n", hr
);
751 HeapFree(GetProcessHeap(), 0, moniker_data
);
756 /***********************************************************************
757 * RunningObjectTable_NoteChangeTime
760 * dwRegister [in] Value identifying registration being updated
761 * pfiletime [in] Pointer to structure containing object's last change time
763 static HRESULT WINAPI
764 RunningObjectTableImpl_NoteChangeTime(IRunningObjectTable
* iface
,
765 DWORD dwRegister
, FILETIME
*pfiletime
)
767 RunningObjectTableImpl
*This
= impl_from_IRunningObjectTable(iface
);
768 struct rot_entry
*rot_entry
;
769 HRESULT hr
= E_INVALIDARG
;
771 TRACE("(%p,%d,%p)\n",This
,dwRegister
,pfiletime
);
773 EnterCriticalSection(&This
->lock
);
774 LIST_FOR_EACH_ENTRY(rot_entry
, &This
->rot
, struct rot_entry
, entry
)
776 if (rot_entry
->cookie
== dwRegister
)
778 rot_entry
->last_modified
= *pfiletime
;
779 LeaveCriticalSection(&This
->lock
);
785 hr
= IrotNoteChangeTime(get_irot_handle(), dwRegister
, pfiletime
);
789 hr
= HRESULT_FROM_WIN32(GetExceptionCode());
792 if (hr
== HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE
))
803 LeaveCriticalSection(&This
->lock
);
806 TRACE("-- 0x08%x\n", hr
);
810 /***********************************************************************
811 * RunningObjectTable_GetTimeOfLastChange
814 * pmkObjectName [in] moniker of the object whose status is desired
815 * pfiletime [out] structure that receives object's last change time
817 static HRESULT WINAPI
818 RunningObjectTableImpl_GetTimeOfLastChange(IRunningObjectTable
* iface
,
819 IMoniker
*pmkObjectName
, FILETIME
*pfiletime
)
821 HRESULT hr
= MK_E_UNAVAILABLE
;
822 RunningObjectTableImpl
*This
= impl_from_IRunningObjectTable(iface
);
823 MonikerComparisonData
*moniker_data
;
824 const struct rot_entry
*rot_entry
;
826 TRACE("(%p,%p,%p)\n",This
,pmkObjectName
,pfiletime
);
828 if (pmkObjectName
==NULL
|| pfiletime
==NULL
)
831 hr
= reduce_moniker(pmkObjectName
, NULL
, &pmkObjectName
);
834 hr
= get_moniker_comparison_data(pmkObjectName
, &moniker_data
);
835 IMoniker_Release(pmkObjectName
);
839 hr
= MK_E_UNAVAILABLE
;
841 EnterCriticalSection(&This
->lock
);
842 LIST_FOR_EACH_ENTRY(rot_entry
, &This
->rot
, const struct rot_entry
, entry
)
844 if ((rot_entry
->moniker_data
->ulCntData
== moniker_data
->ulCntData
) &&
845 !memcmp(moniker_data
->abData
, rot_entry
->moniker_data
->abData
, moniker_data
->ulCntData
))
847 *pfiletime
= rot_entry
->last_modified
;
852 LeaveCriticalSection(&This
->lock
);
860 hr
= IrotGetTimeOfLastChange(get_irot_handle(), moniker_data
, pfiletime
);
864 hr
= HRESULT_FROM_WIN32(GetExceptionCode());
867 if (hr
== HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE
))
876 HeapFree(GetProcessHeap(), 0, moniker_data
);
878 TRACE("-- 0x%08x\n", hr
);
882 /***********************************************************************
883 * RunningObjectTable_EnumRunning
886 * ppenumMoniker [out] receives the IEnumMoniker interface pointer
888 static HRESULT WINAPI
889 RunningObjectTableImpl_EnumRunning(IRunningObjectTable
* iface
,
890 IEnumMoniker
**ppenumMoniker
)
892 RunningObjectTableImpl
*This
= impl_from_IRunningObjectTable(iface
);
893 InterfaceList
*interface_list
= NULL
;
896 TRACE("(%p, %p)\n", This
, ppenumMoniker
);
898 *ppenumMoniker
= NULL
;
904 hr
= IrotEnumRunning(get_irot_handle(), &interface_list
);
908 hr
= HRESULT_FROM_WIN32(GetExceptionCode());
911 if (hr
== HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE
))
920 hr
= EnumMonikerImpl_CreateEnumROTMoniker(interface_list
,
926 /* Virtual function table for the IRunningObjectTable class. */
927 static const IRunningObjectTableVtbl VT_RunningObjectTableImpl
=
929 RunningObjectTableImpl_QueryInterface
,
930 RunningObjectTableImpl_AddRef
,
931 RunningObjectTableImpl_Release
,
932 RunningObjectTableImpl_Register
,
933 RunningObjectTableImpl_Revoke
,
934 RunningObjectTableImpl_IsRunning
,
935 RunningObjectTableImpl_GetObject
,
936 RunningObjectTableImpl_NoteChangeTime
,
937 RunningObjectTableImpl_GetTimeOfLastChange
,
938 RunningObjectTableImpl_EnumRunning
941 /***********************************************************************
942 * RunningObjectTable_Initialize
944 HRESULT WINAPI
RunningObjectTableImpl_Initialize(void)
948 /* create the unique instance of the RunningObjectTableImpl structure */
949 runningObjectTableInstance
= HeapAlloc(GetProcessHeap(), 0, sizeof(RunningObjectTableImpl
));
951 if (!runningObjectTableInstance
)
952 return E_OUTOFMEMORY
;
954 /* initialize the virtual table function */
955 runningObjectTableInstance
->IRunningObjectTable_iface
.lpVtbl
= &VT_RunningObjectTableImpl
;
957 /* the initial reference is set to "1" so that it isn't destroyed after its
958 * first use until the process is destroyed, as the running object table is
959 * a process-wide cache of a global table */
960 runningObjectTableInstance
->ref
= 1;
962 list_init(&runningObjectTableInstance
->rot
);
963 InitializeCriticalSection(&runningObjectTableInstance
->lock
);
964 DEBUG_SET_CRITSEC_NAME(&runningObjectTableInstance
->lock
, "RunningObjectTableImpl.lock");
969 /***********************************************************************
970 * RunningObjectTable_UnInitialize
972 HRESULT WINAPI
RunningObjectTableImpl_UnInitialize(void)
976 if (runningObjectTableInstance
==NULL
)
979 RunningObjectTableImpl_Release(&runningObjectTableInstance
->IRunningObjectTable_iface
);
981 RunningObjectTableImpl_Destroy();
986 /***********************************************************************
987 * GetRunningObjectTable (OLE32.@)
989 * Retrieves the global running object table.
992 * reserved [I] Reserved. Set to 0.
993 * pprot [O] Address that receives the pointer to the running object table.
997 * Failure: Any HRESULT code.
1000 GetRunningObjectTable(DWORD reserved
, LPRUNNINGOBJECTTABLE
*pprot
)
1002 IID riid
=IID_IRunningObjectTable
;
1008 return E_UNEXPECTED
;
1010 if(runningObjectTableInstance
==NULL
)
1011 return CO_E_NOTINITIALIZED
;
1013 res
= IRunningObjectTable_QueryInterface(&runningObjectTableInstance
->IRunningObjectTable_iface
,
1014 &riid
,(void**)pprot
);
1019 static HRESULT
get_moniker_for_progid_display_name(LPBC pbc
,
1020 LPCOLESTR szDisplayName
,
1027 LPCWSTR start
= szDisplayName
;
1030 IMoniker
*class_moniker
;
1035 /* find end delimiter */
1036 for (end
= start
; *end
; end
++)
1042 /* must start with '@' or have a ':' somewhere and mustn't be one character
1043 * long (since that looks like an absolute path) */
1044 if (((start
== szDisplayName
) && (*end
== '\0')) || (len
<= 1))
1047 progid
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(WCHAR
));
1050 memcpy(progid
, start
, len
* sizeof(WCHAR
));
1053 hr
= CLSIDFromProgID(progid
, &clsid
);
1054 HeapFree(GetProcessHeap(), 0, progid
);
1058 hr
= CreateClassMoniker(&clsid
, &class_moniker
);
1061 IParseDisplayName
*pdn
;
1062 hr
= IMoniker_BindToObject(class_moniker
, pbc
, NULL
,
1063 &IID_IParseDisplayName
, (void **)&pdn
);
1064 /* fallback to using IClassFactory to get IParseDisplayName -
1065 * adsldp.dll depends on this */
1069 hr
= IMoniker_BindToObject(class_moniker
, pbc
, NULL
,
1070 &IID_IClassFactory
, (void **)&pcf
);
1073 hr
= IClassFactory_CreateInstance(pcf
, NULL
,
1074 &IID_IParseDisplayName
,
1076 IClassFactory_Release(pcf
);
1079 IMoniker_Release(class_moniker
);
1082 hr
= IParseDisplayName_ParseDisplayName(pdn
, pbc
,
1083 (LPOLESTR
)szDisplayName
,
1085 IParseDisplayName_Release(pdn
);
1091 /******************************************************************************
1092 * MkParseDisplayName [OLE32.@]
1094 HRESULT WINAPI
MkParseDisplayName(LPBC pbc
, LPCOLESTR szDisplayName
,
1095 LPDWORD pchEaten
, LPMONIKER
*ppmk
)
1097 HRESULT hr
= MK_E_SYNTAX
;
1098 static const WCHAR wszClsidColon
[] = {'c','l','s','i','d',':'};
1102 TRACE("(%p, %s, %p, %p)\n", pbc
, debugstr_w(szDisplayName
), pchEaten
, ppmk
);
1104 if (!pbc
|| !IsValidInterface((LPUNKNOWN
) pbc
))
1105 return E_INVALIDARG
;
1107 if (!szDisplayName
|| !*szDisplayName
)
1108 return E_INVALIDARG
;
1110 if (!pchEaten
|| !ppmk
)
1111 return E_INVALIDARG
;
1116 if (!strncmpiW(szDisplayName
, wszClsidColon
, sizeof(wszClsidColon
)/sizeof(wszClsidColon
[0])))
1118 hr
= ClassMoniker_CreateFromDisplayName(pbc
, szDisplayName
, &chEaten
, &moniker
);
1119 if (FAILED(hr
) && (hr
!= MK_E_SYNTAX
))
1124 hr
= get_moniker_for_progid_display_name(pbc
, szDisplayName
, &chEaten
, &moniker
);
1125 if (FAILED(hr
) && (hr
!= MK_E_SYNTAX
))
1131 hr
= FileMoniker_CreateFromDisplayName(pbc
, szDisplayName
, &chEaten
, &moniker
);
1132 if (FAILED(hr
) && (hr
!= MK_E_SYNTAX
))
1140 IMoniker
*next_moniker
;
1141 *pchEaten
+= chEaten
;
1142 szDisplayName
+= chEaten
;
1143 if (!*szDisplayName
)
1149 hr
= IMoniker_ParseDisplayName(moniker
, pbc
, NULL
,
1150 (LPOLESTR
)szDisplayName
, &chEaten
,
1152 IMoniker_Release(moniker
);
1158 moniker
= next_moniker
;
1165 /***********************************************************************
1166 * GetClassFile (OLE32.@)
1168 * Retrieves the class ID associated with the given filename.
1171 * filePathName [I] Filename to retrieve the class ID for.
1172 * pclsid [O] Address that receives the class ID for the file.
1176 * Failure: Any HRESULT code.
1178 HRESULT WINAPI
GetClassFile(LPCOLESTR filePathName
,CLSID
*pclsid
)
1182 int nbElm
, length
, i
;
1184 LPOLESTR
*pathDec
=0,absFile
=0,progId
=0;
1186 static const WCHAR bkslashW
[] = {'\\',0};
1187 static const WCHAR dotW
[] = {'.',0};
1189 TRACE("%s, %p\n", debugstr_w(filePathName
), pclsid
);
1191 /* if the file contain a storage object the return the CLSID written by IStorage_SetClass method*/
1192 if((StgIsStorageFile(filePathName
))==S_OK
){
1194 res
=StgOpenStorage(filePathName
,NULL
,STGM_READ
| STGM_SHARE_DENY_WRITE
,NULL
,0,&pstg
);
1197 res
=ReadClassStg(pstg
,pclsid
);
1199 IStorage_Release(pstg
);
1203 /* If the file is not a storage object then attempt to match various bits in the file against a
1204 pattern in the registry. This case is not frequently used, so I present only the pseudocode for
1207 for(i=0;i<nFileTypes;i++)
1209 for(i=0;j<nPatternsForType;j++){
1214 pat=ReadPatternFromRegistry(i,j);
1215 hFile=CreateFileW(filePathName,,,,,,hFile);
1216 SetFilePosition(hFile,pat.offset);
1217 ReadFile(hFile,buf,pat.size,&r,NULL);
1218 if (memcmp(buf&pat.mask,pat.pattern.pat.size)==0){
1220 *pclsid=ReadCLSIDFromRegistry(i);
1226 /* if the above strategies fail then search for the extension key in the registry */
1228 /* get the last element (absolute file) in the path name */
1229 nbElm
=FileMonikerImpl_DecomposePath(filePathName
,&pathDec
);
1230 absFile
=pathDec
[nbElm
-1];
1232 /* failed if the path represents a directory and not an absolute file name*/
1233 if (!lstrcmpW(absFile
, bkslashW
))
1234 return MK_E_INVALIDEXTENSION
;
1236 /* get the extension of the file */
1238 length
=lstrlenW(absFile
);
1239 for(i
= length
-1; (i
>= 0) && *(extension
= &absFile
[i
]) != '.'; i
--)
1242 if (!extension
|| !lstrcmpW(extension
, dotW
))
1243 return MK_E_INVALIDEXTENSION
;
1245 res
=RegQueryValueW(HKEY_CLASSES_ROOT
, extension
, NULL
, &sizeProgId
);
1247 /* get the progId associated to the extension */
1248 progId
= CoTaskMemAlloc(sizeProgId
);
1249 res
= RegQueryValueW(HKEY_CLASSES_ROOT
, extension
, progId
, &sizeProgId
);
1251 if (res
==ERROR_SUCCESS
)
1252 /* return the clsid associated to the progId */
1253 res
= CLSIDFromProgID(progId
,pclsid
);
1255 for(i
=0; pathDec
[i
]!=NULL
;i
++)
1256 CoTaskMemFree(pathDec
[i
]);
1257 CoTaskMemFree(pathDec
);
1259 CoTaskMemFree(progId
);
1261 if (res
==ERROR_SUCCESS
)
1264 return MK_E_INVALIDEXTENSION
;
1267 /***********************************************************************
1268 * EnumMoniker_QueryInterface
1270 static HRESULT WINAPI
EnumMonikerImpl_QueryInterface(IEnumMoniker
* iface
,REFIID riid
,void** ppvObject
)
1272 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
1274 TRACE("(%p,%p,%p)\n",This
,riid
,ppvObject
);
1276 /* validate arguments */
1277 if (ppvObject
== NULL
)
1278 return E_INVALIDARG
;
1282 if (IsEqualIID(&IID_IUnknown
, riid
))
1285 if (IsEqualIID(&IID_IEnumMoniker
, riid
))
1288 if ((*ppvObject
)==NULL
)
1289 return E_NOINTERFACE
;
1291 IEnumMoniker_AddRef(iface
);
1296 /***********************************************************************
1297 * EnumMoniker_AddRef
1299 static ULONG WINAPI
EnumMonikerImpl_AddRef(IEnumMoniker
* iface
)
1301 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
1303 TRACE("(%p)\n",This
);
1305 return InterlockedIncrement(&This
->ref
);
1308 /***********************************************************************
1309 * EnumMoniker_release
1311 static ULONG WINAPI
EnumMonikerImpl_Release(IEnumMoniker
* iface
)
1313 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
1316 TRACE("(%p)\n",This
);
1318 ref
= InterlockedDecrement(&This
->ref
);
1320 /* uninitialize rot structure if there's no more reference to it*/
1325 TRACE("(%p) Deleting\n",This
);
1327 for (i
= 0; i
< This
->moniker_list
->size
; i
++)
1328 HeapFree(GetProcessHeap(), 0, This
->moniker_list
->interfaces
[i
]);
1329 HeapFree(GetProcessHeap(), 0, This
->moniker_list
);
1330 HeapFree(GetProcessHeap(), 0, This
);
1335 /***********************************************************************
1338 static HRESULT WINAPI
EnumMonikerImpl_Next(IEnumMoniker
* iface
, ULONG celt
, IMoniker
** rgelt
, ULONG
* pceltFetched
)
1341 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
1344 TRACE("(%p) TabCurrentPos %d Tablastindx %d\n", This
, This
->pos
, This
->moniker_list
->size
);
1346 /* retrieve the requested number of moniker from the current position */
1347 for(i
= 0; (This
->pos
< This
->moniker_list
->size
) && (i
< celt
); i
++)
1350 hr
= create_stream_on_mip_ro(This
->moniker_list
->interfaces
[This
->pos
++], &stream
);
1351 if (hr
!= S_OK
) break;
1352 hr
= CoUnmarshalInterface(stream
, &IID_IMoniker
, (void **)&rgelt
[i
]);
1353 IStream_Release(stream
);
1354 if (hr
!= S_OK
) break;
1357 if (pceltFetched
!= NULL
)
1370 /***********************************************************************
1373 static HRESULT WINAPI
EnumMonikerImpl_Skip(IEnumMoniker
* iface
, ULONG celt
)
1375 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
1377 TRACE("(%p)\n",This
);
1379 if (This
->pos
+ celt
>= This
->moniker_list
->size
)
1387 /***********************************************************************
1390 static HRESULT WINAPI
EnumMonikerImpl_Reset(IEnumMoniker
* iface
)
1392 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
1394 This
->pos
= 0; /* set back to start of list */
1396 TRACE("(%p)\n",This
);
1401 /***********************************************************************
1404 static HRESULT WINAPI
EnumMonikerImpl_Clone(IEnumMoniker
* iface
, IEnumMoniker
** ppenum
)
1406 EnumMonikerImpl
*This
= impl_from_IEnumMoniker(iface
);
1407 InterfaceList
*moniker_list
;
1410 TRACE("(%p)\n",This
);
1414 moniker_list
= HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceList
, interfaces
[This
->moniker_list
->size
]));
1416 return E_OUTOFMEMORY
;
1418 moniker_list
->size
= This
->moniker_list
->size
;
1419 for (i
= 0; i
< This
->moniker_list
->size
; i
++)
1421 SIZE_T size
= FIELD_OFFSET(InterfaceData
, abData
[This
->moniker_list
->interfaces
[i
]->ulCntData
]);
1422 moniker_list
->interfaces
[i
] = HeapAlloc(GetProcessHeap(), 0, size
);
1423 if (!moniker_list
->interfaces
[i
])
1426 for (i
= 0; i
< end
; i
++)
1427 HeapFree(GetProcessHeap(), 0, moniker_list
->interfaces
[i
]);
1428 HeapFree(GetProcessHeap(), 0, moniker_list
);
1429 return E_OUTOFMEMORY
;
1431 memcpy(moniker_list
->interfaces
[i
], This
->moniker_list
->interfaces
[i
], size
);
1434 /* copy the enum structure */
1435 return EnumMonikerImpl_CreateEnumROTMoniker(moniker_list
, This
->pos
, ppenum
);
1438 /* Virtual function table for the IEnumMoniker class. */
1439 static const IEnumMonikerVtbl VT_EnumMonikerImpl
=
1441 EnumMonikerImpl_QueryInterface
,
1442 EnumMonikerImpl_AddRef
,
1443 EnumMonikerImpl_Release
,
1444 EnumMonikerImpl_Next
,
1445 EnumMonikerImpl_Skip
,
1446 EnumMonikerImpl_Reset
,
1447 EnumMonikerImpl_Clone
1450 /***********************************************************************
1451 * EnumMonikerImpl_CreateEnumROTMoniker
1452 * Used by EnumRunning to create the structure and EnumClone
1453 * to copy the structure
1455 static HRESULT
EnumMonikerImpl_CreateEnumROTMoniker(InterfaceList
*moniker_list
,
1457 IEnumMoniker
**ppenumMoniker
)
1459 EnumMonikerImpl
* This
= NULL
;
1462 return E_INVALIDARG
;
1464 This
= HeapAlloc(GetProcessHeap(), 0, sizeof(EnumMonikerImpl
));
1465 if (!This
) return E_OUTOFMEMORY
;
1467 TRACE("(%p)\n", This
);
1469 /* initialize the virtual table function */
1470 This
->IEnumMoniker_iface
.lpVtbl
= &VT_EnumMonikerImpl
;
1472 /* the initial reference is set to "1" */
1473 This
->ref
= 1; /* set the ref count to one */
1474 This
->pos
= current_pos
; /* Set the list start posn */
1475 This
->moniker_list
= moniker_list
;
1477 *ppenumMoniker
= &This
->IEnumMoniker_iface
;
1483 /* Shared implementation of moniker marshaler based on saving and loading of
1486 typedef struct MonikerMarshal
1488 IUnknown IUnknown_iface
;
1489 IMarshal IMarshal_iface
;
1495 static inline MonikerMarshal
*impl_from_IUnknown(IUnknown
*iface
)
1497 return CONTAINING_RECORD(iface
, MonikerMarshal
, IUnknown_iface
);
1500 static inline MonikerMarshal
*impl_from_IMarshal( IMarshal
*iface
)
1502 return CONTAINING_RECORD(iface
, MonikerMarshal
, IMarshal_iface
);
1505 static HRESULT WINAPI
MonikerMarshalInner_QueryInterface(IUnknown
*iface
, REFIID riid
, LPVOID
*ppv
)
1507 MonikerMarshal
*This
= impl_from_IUnknown(iface
);
1508 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
1510 if (IsEqualIID(&IID_IUnknown
, riid
) || IsEqualIID(&IID_IMarshal
, riid
))
1512 *ppv
= &This
->IMarshal_iface
;
1513 IUnknown_AddRef((IUnknown
*)&This
->IMarshal_iface
);
1516 FIXME("No interface for %s\n", debugstr_guid(riid
));
1517 return E_NOINTERFACE
;
1520 static ULONG WINAPI
MonikerMarshalInner_AddRef(IUnknown
*iface
)
1522 MonikerMarshal
*This
= impl_from_IUnknown(iface
);
1523 return InterlockedIncrement(&This
->ref
);
1526 static ULONG WINAPI
MonikerMarshalInner_Release(IUnknown
*iface
)
1528 MonikerMarshal
*This
= impl_from_IUnknown(iface
);
1529 ULONG ref
= InterlockedDecrement(&This
->ref
);
1531 if (!ref
) HeapFree(GetProcessHeap(), 0, This
);
1535 static const IUnknownVtbl VT_MonikerMarshalInner
=
1537 MonikerMarshalInner_QueryInterface
,
1538 MonikerMarshalInner_AddRef
,
1539 MonikerMarshalInner_Release
1542 static HRESULT WINAPI
MonikerMarshal_QueryInterface(IMarshal
*iface
, REFIID riid
, LPVOID
*ppv
)
1544 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1545 return IMoniker_QueryInterface(This
->moniker
, riid
, ppv
);
1548 static ULONG WINAPI
MonikerMarshal_AddRef(IMarshal
*iface
)
1550 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1551 return IMoniker_AddRef(This
->moniker
);
1554 static ULONG WINAPI
MonikerMarshal_Release(IMarshal
*iface
)
1556 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1557 return IMoniker_Release(This
->moniker
);
1560 static HRESULT WINAPI
MonikerMarshal_GetUnmarshalClass(
1561 LPMARSHAL iface
, REFIID riid
, void* pv
, DWORD dwDestContext
,
1562 void* pvDestContext
, DWORD mshlflags
, CLSID
* pCid
)
1564 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1566 TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid
), pv
,
1567 dwDestContext
, pvDestContext
, mshlflags
, pCid
);
1569 return IMoniker_GetClassID(This
->moniker
, pCid
);
1572 static HRESULT WINAPI
MonikerMarshal_GetMarshalSizeMax(
1573 LPMARSHAL iface
, REFIID riid
, void* pv
, DWORD dwDestContext
,
1574 void* pvDestContext
, DWORD mshlflags
, DWORD
* pSize
)
1576 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1578 ULARGE_INTEGER size
;
1580 TRACE("(%s, %p, %x, %p, %x, %p)\n", debugstr_guid(riid
), pv
,
1581 dwDestContext
, pvDestContext
, mshlflags
, pSize
);
1583 hr
= IMoniker_GetSizeMax(This
->moniker
, &size
);
1585 *pSize
= (DWORD
)size
.QuadPart
;
1589 static HRESULT WINAPI
MonikerMarshal_MarshalInterface(LPMARSHAL iface
, IStream
*pStm
,
1590 REFIID riid
, void* pv
, DWORD dwDestContext
,
1591 void* pvDestContext
, DWORD mshlflags
)
1593 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1595 TRACE("(%p, %s, %p, %x, %p, %x)\n", pStm
, debugstr_guid(riid
), pv
,
1596 dwDestContext
, pvDestContext
, mshlflags
);
1598 return IMoniker_Save(This
->moniker
, pStm
, FALSE
);
1601 static HRESULT WINAPI
MonikerMarshal_UnmarshalInterface(LPMARSHAL iface
, IStream
*pStm
, REFIID riid
, void **ppv
)
1603 MonikerMarshal
*This
= impl_from_IMarshal(iface
);
1606 TRACE("(%p, %s, %p)\n", pStm
, debugstr_guid(riid
), ppv
);
1608 hr
= IMoniker_Load(This
->moniker
, pStm
);
1610 hr
= IMoniker_QueryInterface(This
->moniker
, riid
, ppv
);
1614 static HRESULT WINAPI
MonikerMarshal_ReleaseMarshalData(LPMARSHAL iface
, IStream
*pStm
)
1617 /* can't release a state-based marshal as nothing on server side to
1622 static HRESULT WINAPI
MonikerMarshal_DisconnectObject(LPMARSHAL iface
, DWORD dwReserved
)
1625 /* can't disconnect a state-based marshal as nothing on server side to
1626 * disconnect from */
1630 static const IMarshalVtbl VT_MonikerMarshal
=
1632 MonikerMarshal_QueryInterface
,
1633 MonikerMarshal_AddRef
,
1634 MonikerMarshal_Release
,
1635 MonikerMarshal_GetUnmarshalClass
,
1636 MonikerMarshal_GetMarshalSizeMax
,
1637 MonikerMarshal_MarshalInterface
,
1638 MonikerMarshal_UnmarshalInterface
,
1639 MonikerMarshal_ReleaseMarshalData
,
1640 MonikerMarshal_DisconnectObject
1643 HRESULT
MonikerMarshal_Create(IMoniker
*inner
, IUnknown
**outer
)
1645 MonikerMarshal
*This
= HeapAlloc(GetProcessHeap(), 0, sizeof(*This
));
1646 if (!This
) return E_OUTOFMEMORY
;
1648 This
->IUnknown_iface
.lpVtbl
= &VT_MonikerMarshalInner
;
1649 This
->IMarshal_iface
.lpVtbl
= &VT_MonikerMarshal
;
1651 This
->moniker
= inner
;
1653 *outer
= &This
->IUnknown_iface
;
1657 void * __RPC_USER
MIDL_user_allocate(SIZE_T size
)
1659 return HeapAlloc(GetProcessHeap(), 0, size
);
1662 void __RPC_USER
MIDL_user_free(void *p
)
1664 HeapFree(GetProcessHeap(), 0, p
);