diff --git a/dlls/combase/Makefile.in b/dlls/combase/Makefile.in index 09e76e48bbb..16a2bfa3167 100644 --- a/dlls/combase/Makefile.in +++ b/dlls/combase/Makefile.in @@ -11,5 +11,9 @@ C_SRCS = \ malloc.c \ marshal.c \ roapi.c \ + rpc.c \ string.c \ usrmarshal.c + +IDL_SRCS = \ + irpcss.idl diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c index 8ad95329d08..df97799fe08 100644 --- a/dlls/combase/combase.c +++ b/dlls/combase/combase.c @@ -2233,3 +2233,19 @@ HRESULT WINAPI CoGetCurrentLogicalThreadId(GUID *id) return S_OK; } + +/****************************************************************************** + * CoGetCurrentProcess (combase.@) + */ +DWORD WINAPI CoGetCurrentProcess(void) +{ + struct tlsdata *tlsdata; + + if (FAILED(com_get_tlsdata(&tlsdata))) + return 0; + + if (!tlsdata->thread_seqid) + tlsdata->thread_seqid = rpcss_get_next_seqid(); + + return tlsdata->thread_seqid; +} diff --git a/dlls/combase/combase.spec b/dlls/combase/combase.spec index af83e89d174..a88c5d66fe1 100644 --- a/dlls/combase/combase.spec +++ b/dlls/combase/combase.spec @@ -105,7 +105,7 @@ @ stub CoGetClassVersion @ stdcall CoGetContextToken(ptr) @ stdcall CoGetCurrentLogicalThreadId(ptr) -@ stdcall CoGetCurrentProcess() ole32.CoGetCurrentProcess +@ stdcall CoGetCurrentProcess() @ stdcall CoGetDefaultContext(long ptr ptr) @ stdcall CoGetErrorInfo(long ptr) GetErrorInfo @ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr) diff --git a/dlls/combase/combase_private.h b/dlls/combase/combase_private.h index 28a98fd5803..e910166fff2 100644 --- a/dlls/combase/combase_private.h +++ b/dlls/combase/combase_private.h @@ -88,3 +88,6 @@ static inline struct apartment* com_get_current_apt(void) com_get_tlsdata(&tlsdata); return tlsdata->apt; } + +/* RpcSs interface */ +DWORD rpcss_get_next_seqid(void) DECLSPEC_HIDDEN; diff --git a/dlls/ole32/irpcss.idl b/dlls/combase/irpcss.idl similarity index 100% rename from dlls/ole32/irpcss.idl rename to dlls/combase/irpcss.idl diff --git a/dlls/combase/rpc.c b/dlls/combase/rpc.c new file mode 100644 index 00000000000..2fbccfd740d --- /dev/null +++ b/dlls/combase/rpc.c @@ -0,0 +1,155 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "windef.h" +#include "winbase.h" +#include "winsvc.h" + +#include "wine/debug.h" +#include "wine/exception.h" +#include "wine/heap.h" + +#include "irpcss.h" + +WINE_DEFAULT_DEBUG_CHANNEL(ole); + +void * __RPC_USER MIDL_user_allocate(SIZE_T size) +{ + return heap_alloc(size); +} + +void __RPC_USER MIDL_user_free(void *p) +{ + heap_free(p); +} + +static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *eptr) +{ + return I_RpcExceptionFilter(eptr->ExceptionRecord->ExceptionCode); +} + +static BOOL start_rpcss(void) +{ + SERVICE_STATUS_PROCESS status; + SC_HANDLE scm, service; + BOOL ret = FALSE; + + TRACE("\n"); + + if (!(scm = OpenSCManagerW(NULL, NULL, 0))) + { + ERR("Failed to open service manager\n"); + return FALSE; + } + + if (!(service = OpenServiceW(scm, L"RpcSs", SERVICE_START | SERVICE_QUERY_STATUS))) + { + ERR("Failed to open RpcSs service\n"); + CloseServiceHandle( scm ); + return FALSE; + } + + if (StartServiceW(service, 0, NULL) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) + { + ULONGLONG start_time = GetTickCount64(); + do + { + DWORD dummy; + + if (!QueryServiceStatusEx(service, SC_STATUS_PROCESS_INFO, (BYTE *)&status, sizeof(status), &dummy)) + break; + if (status.dwCurrentState == SERVICE_RUNNING) + { + ret = TRUE; + break; + } + if (GetTickCount64() - start_time > 30000) break; + Sleep( 100 ); + + } while (status.dwCurrentState == SERVICE_START_PENDING); + + if (status.dwCurrentState != SERVICE_RUNNING) + WARN("RpcSs failed to start %u\n", status.dwCurrentState); + } + else + ERR("Failed to start RpcSs service\n"); + + CloseServiceHandle(service); + CloseServiceHandle(scm); + return ret; +} + +static RPC_BINDING_HANDLE get_rpc_handle(unsigned short *protseq, unsigned short *endpoint) +{ + RPC_BINDING_HANDLE handle = NULL; + RPC_STATUS status; + RPC_WSTR binding; + + status = RpcStringBindingComposeW(NULL, protseq, NULL, endpoint, NULL, &binding); + if (status == RPC_S_OK) + { + status = RpcBindingFromStringBindingW(binding, &handle); + RpcStringFreeW(&binding); + } + + return handle; +} + +static RPC_BINDING_HANDLE get_irpcss_handle(void) +{ + static RPC_BINDING_HANDLE irpcss_handle; + + if (!irpcss_handle) + { + unsigned short protseq[] = IRPCSS_PROTSEQ; + unsigned short endpoint[] = IRPCSS_ENDPOINT; + + RPC_BINDING_HANDLE new_handle = get_rpc_handle(protseq, endpoint); + if (InterlockedCompareExchangePointer(&irpcss_handle, new_handle, NULL)) + /* another thread beat us to it */ + RpcBindingFree(&new_handle); + } + return irpcss_handle; +} + +DWORD rpcss_get_next_seqid(void) +{ + DWORD id = 0; + HRESULT hr; + + for (;;) + { + __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; + } + + return id; +} diff --git a/dlls/ole32/Makefile.in b/dlls/ole32/Makefile.in index a113c7622b4..1c1e28fa4c5 100644 --- a/dlls/ole32/Makefile.in +++ b/dlls/ole32/Makefile.in @@ -45,7 +45,6 @@ RC_SRCS = ole32res.rc IDL_SRCS = \ dcom.idl \ irot.idl \ - irpcss.idl \ ole32_objidl.idl \ ole32_oleidl.idl \ ole32_unknwn.idl diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index 671f60e231a..d45cbcc1734 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -2898,22 +2898,6 @@ done: return res; } -/****************************************************************************** - * CoGetCurrentProcess [OLE32.@] - */ -DWORD WINAPI CoGetCurrentProcess(void) -{ - struct oletls *info = COM_CurrentInfo(); - - if (!info) - return 0; - - if (!info->thread_seqid) - info->thread_seqid = rpcss_get_next_seqid(); - - return info->thread_seqid; -} - /*********************************************************************** * CoIsOle1Class [OLE32.@] * diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h index 8419fd04ffa..003cf767cb4 100644 --- a/dlls/ole32/compobj_private.h +++ b/dlls/ole32/compobj_private.h @@ -353,6 +353,4 @@ static inline HRESULT copy_formatetc(FORMATETC *dst, const FORMATETC *src) extern HRESULT EnumSTATDATA_Construct(IUnknown *holder, ULONG index, DWORD array_len, STATDATA *data, BOOL copy, IEnumSTATDATA **ppenum) DECLSPEC_HIDDEN; -extern DWORD rpcss_get_next_seqid(void) DECLSPEC_HIDDEN; - #endif /* __WINE_OLE_COMPOBJ_H */ diff --git a/dlls/ole32/moniker.c b/dlls/ole32/moniker.c index f82159d9e12..e0cdd865c83 100644 --- a/dlls/ole32/moniker.c +++ b/dlls/ole32/moniker.c @@ -41,7 +41,6 @@ #include "compobj_private.h" #include "moniker.h" #include "irot.h" -#include "irpcss.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); @@ -78,7 +77,6 @@ typedef struct RunningObjectTableImpl static RunningObjectTableImpl* runningObjectTableInstance = NULL; static IrotHandle irot_handle; -static RPC_BINDING_HANDLE irpcss_handle; /* define the EnumMonikerImpl structure */ typedef struct EnumMonikerImpl @@ -135,21 +133,6 @@ static IrotHandle get_irot_handle(void) return irot_handle; } -static RPC_BINDING_HANDLE get_irpcss_handle(void) -{ - if (!irpcss_handle) - { - unsigned short protseq[] = IROT_PROTSEQ; - unsigned short endpoint[] = IROT_ENDPOINT; - - RPC_BINDING_HANDLE new_handle = get_rpc_handle(protseq, endpoint); - if (InterlockedCompareExchangePointer(&irpcss_handle, new_handle, NULL)) - /* another thread beat us to it */ - RpcBindingFree(&new_handle); - } - return irpcss_handle; -} - static BOOL start_rpcss(void) { static const WCHAR rpcssW[] = {'R','p','c','S','s',0}; @@ -200,33 +183,6 @@ static BOOL start_rpcss(void) return ret; } -DWORD rpcss_get_next_seqid(void) -{ - DWORD id = 0; - HRESULT hr; - - for (;;) - { - __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; - } - - return id; -} - static HRESULT create_stream_on_mip_ro(const InterfaceData *mip, IStream **stream) { HGLOBAL hglobal = GlobalAlloc(0, mip->ulCntData); diff --git a/dlls/ole32/ole32.spec b/dlls/ole32/ole32.spec index 543126e02bd..2564851c4b5 100644 --- a/dlls/ole32/ole32.spec +++ b/dlls/ole32/ole32.spec @@ -33,7 +33,7 @@ @ stdcall CoGetClassObject(ptr long ptr ptr ptr) @ stdcall CoGetContextToken(ptr) combase.CoGetContextToken @ stdcall CoGetCurrentLogicalThreadId(ptr) combase.CoGetCurrentLogicalThreadId -@ stdcall CoGetCurrentProcess() +@ stdcall CoGetCurrentProcess() combase.CoGetCurrentProcess @ stdcall CoGetDefaultContext(long ptr ptr) combase.CoGetDefaultContext @ stdcall CoGetInstanceFromFile(ptr ptr ptr long long wstr long ptr) combase.CoGetInstanceFromFile @ stdcall CoGetInstanceFromIStorage(ptr ptr ptr long ptr long ptr) combase.CoGetInstanceFromIStorage