Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/combase/combase.c | 2 +- dlls/combase/combase.spec | 14 ++--- dlls/combase/combase_private.h | 2 +- dlls/combase/irpcss.idl | 1 + dlls/combase/rpc.c | 108 +++++++++++++++++++++++++++------ 5 files changed, 98 insertions(+), 29 deletions(-)
diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c index df97799fe08..80d6ece266e 100644 --- a/dlls/combase/combase.c +++ b/dlls/combase/combase.c @@ -2245,7 +2245,7 @@ DWORD WINAPI CoGetCurrentProcess(void) return 0;
if (!tlsdata->thread_seqid) - tlsdata->thread_seqid = rpcss_get_next_seqid(); + rpcss_get_next_seqid(&tlsdata->thread_seqid);
return tlsdata->thread_seqid; } diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index a88c5d66fe1..9038d5fa8bf 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -255,13 +255,13 @@ @ stub InternalFillLocalOXIDInfo @ stub InternalFreeObjRef @ stub InternalGetWindowPropInterface -@ stub InternalIrotEnumRunning -@ stub InternalIrotGetObject -@ stub InternalIrotGetTimeOfLastChange -@ stub InternalIrotIsRunning -@ stub InternalIrotNoteChangeTime -@ stub InternalIrotRegister -@ stub InternalIrotRevoke +@ stdcall InternalIrotEnumRunning(ptr) +@ stdcall InternalIrotGetObject(ptr ptr ptr) +@ stdcall InternalIrotGetTimeOfLastChange(ptr ptr) +@ stdcall InternalIrotIsRunning(ptr) +@ stdcall InternalIrotNoteChangeTime(long ptr) +@ stdcall InternalIrotRegister(ptr ptr ptr ptr long ptr ptr) +@ stdcall InternalIrotRevoke(long ptr ptr ptr) @ stub InternalIsApartmentInitialized @ stub InternalIsProcessInitialized @ stub InternalMarshalObjRef diff --git a/dlls/combase/combase_private.h b/dlls/combase/combase_private.h index e910166fff2..7d7583282e1 100644 --- a/dlls/combase/combase_private.h +++ b/dlls/combase/combase_private.h @@ -90,4 +90,4 @@ static inline struct apartment* com_get_current_apt(void) }
/* RpcSs interface */ -DWORD rpcss_get_next_seqid(void) DECLSPEC_HIDDEN; +HRESULT rpcss_get_next_seqid(DWORD *id) DECLSPEC_HIDDEN; diff --git a/dlls/combase/irpcss.idl b/dlls/combase/irpcss.idl index 65078167de2..fab69f7310c 100644 --- a/dlls/combase/irpcss.idl +++ b/dlls/combase/irpcss.idl @@ -18,4 +18,5 @@
#pragma makedep client
+#include "wine/irot.idl" #include "wine/irpcss.idl" diff --git a/dlls/combase/rpc.c b/dlls/combase/rpc.c index 2fbccfd740d..3b531661726 100644 --- a/dlls/combase/rpc.c +++ b/dlls/combase/rpc.c @@ -127,29 +127,97 @@ static RPC_BINDING_HANDLE get_irpcss_handle(void) return irpcss_handle; }
-DWORD rpcss_get_next_seqid(void) +static RPC_BINDING_HANDLE get_irot_handle(void) { - DWORD id = 0; - HRESULT hr; + static RPC_BINDING_HANDLE irot_handle;
- for (;;) + if (!irot_handle) { - __TRY - { - hr = irpcss_get_thread_seq_id(get_irpcss_handle(), &id); - } - __EXCEPT(rpc_filter) - { - hr = HRESULT_FROM_WIN32(GetExceptionCode()); - } - __ENDTRY - if (hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE)) - { - if (start_rpcss()) - continue; - } - break; + unsigned short protseq[] = IROT_PROTSEQ; + unsigned short endpoint[] = IROT_ENDPOINT; + + RPC_BINDING_HANDLE new_handle = get_rpc_handle(protseq, endpoint); + if (InterlockedCompareExchangePointer(&irot_handle, new_handle, NULL)) + /* another thread beat us to it */ + RpcBindingFree(&new_handle); } + return irot_handle; +} + +#define RPCSS_CALL_START \ + HRESULT hr; \ + for (;;) { \ + __TRY { + +#define RPCSS_CALL_END \ + } __EXCEPT(rpc_filter) { \ + hr = HRESULT_FROM_WIN32(GetExceptionCode()); \ + } \ + __ENDTRY \ + if (hr == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE)) { \ + if (start_rpcss()) \ + continue; \ + } \ + break; \ + } \ + return hr; + +HRESULT rpcss_get_next_seqid(DWORD *id) +{ + RPCSS_CALL_START + hr = irpcss_get_thread_seq_id(get_irpcss_handle(), id); + RPCSS_CALL_END +} + +HRESULT WINAPI InternalIrotRegister(const MonikerComparisonData *moniker_data, + const InterfaceData *object, const InterfaceData *moniker, + const FILETIME *time, DWORD flags, IrotCookie *cookie, IrotContextHandle *ctxt_handle) +{ + RPCSS_CALL_START + hr = IrotRegister(get_irot_handle(), moniker_data, object, moniker, time, flags, cookie, ctxt_handle); + RPCSS_CALL_END +} + +HRESULT WINAPI InternalIrotIsRunning(const MonikerComparisonData *moniker_data) +{ + RPCSS_CALL_START + hr = IrotIsRunning(get_irot_handle(), moniker_data); + RPCSS_CALL_END +} + +HRESULT WINAPI InternalIrotGetObject(const MonikerComparisonData *moniker_data, PInterfaceData *obj, + IrotCookie *cookie) +{ + RPCSS_CALL_START + hr = IrotGetObject(get_irot_handle(), moniker_data, obj, cookie); + RPCSS_CALL_END +} + +HRESULT WINAPI InternalIrotNoteChangeTime(IrotCookie cookie, const FILETIME *time) +{ + RPCSS_CALL_START + hr = IrotNoteChangeTime(get_irot_handle(), cookie, time); + RPCSS_CALL_END +}
- return id; +HRESULT WINAPI InternalIrotGetTimeOfLastChange(const MonikerComparisonData *moniker_data, FILETIME *time) +{ + RPCSS_CALL_START + hr = IrotGetTimeOfLastChange(get_irot_handle(), moniker_data, time); + RPCSS_CALL_END +} + +HRESULT WINAPI InternalIrotEnumRunning(PInterfaceList *list) +{ + RPCSS_CALL_START + hr = IrotEnumRunning(get_irot_handle(), list); + RPCSS_CALL_END +} + +HRESULT WINAPI InternalIrotRevoke(IrotCookie cookie, IrotContextHandle *ctxt_handle, PInterfaceData *object, + PInterfaceData *moniker) +{ + RPCSS_CALL_START + hr = IrotRevoke(get_irot_handle(), cookie, ctxt_handle, object, moniker); + RPCSS_CALL_END }