[PATCH 3/3] ole32: Reimplement CoGetCurrentProcess() to use global counter from rpcss.
Nikolay Sivov
nsivov at codeweavers.com
Thu Nov 7 14:00:01 CST 2019
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/ole32/Makefile.in | 1 +
dlls/ole32/compobj.c | 18 ++++-----
dlls/ole32/compobj_private.h | 5 ++-
dlls/ole32/irpcss.idl | 21 ++++++++++
dlls/ole32/moniker.c | 75 ++++++++++++++++++++++++++++++------
dlls/ole32/tests/compobj.c | 27 +++++++++++++
6 files changed, 125 insertions(+), 22 deletions(-)
create mode 100644 dlls/ole32/irpcss.idl
diff --git a/dlls/ole32/Makefile.in b/dlls/ole32/Makefile.in
index 6c2f1231f1..32de987a8c 100644
--- a/dlls/ole32/Makefile.in
+++ b/dlls/ole32/Makefile.in
@@ -48,6 +48,7 @@ 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 0dc0d39c22..a91067fcb7 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -4027,18 +4027,18 @@ done:
/******************************************************************************
* CoGetCurrentProcess [OLE32.@]
- *
- * Gets the current process ID.
- *
- * RETURNS
- * The current process ID.
- *
- * NOTES
- * Is DWORD really the correct return type for this function?
*/
DWORD WINAPI CoGetCurrentProcess(void)
{
- return GetCurrentProcessId();
+ struct oletls *info = COM_CurrentInfo();
+
+ if (!info)
+ return 0;
+
+ if (!info->thread_seqid)
+ info->thread_seqid = rpcss_get_next_seqid();
+
+ return info->thread_seqid;
}
/***********************************************************************
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index bda1c6bff2..29f94421d1 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -165,7 +165,7 @@ struct oletls
{
struct apartment *apt;
IErrorInfo *errorinfo; /* see errorinfo.c */
- IUnknown *state; /* see CoSetState */
+ DWORD thread_seqid;/* returned with CoGetCurrentProcess */
DWORD apt_mask; /* apartment mask (+0Ch on x86) */
void *unknown0;
DWORD inits; /* number of times CoInitializeEx called */
@@ -178,6 +178,7 @@ struct oletls
IUnknown *call_state; /* current call context (+3Ch on x86) */
DWORD unknown2[46];
IUnknown *cancel_object; /* cancel object set by CoSetCancelObject (+F8h on x86) */
+ IUnknown *state; /* see CoSetState */
struct list spies; /* Spies installed with CoRegisterInitializeSpy */
DWORD spies_lock;
};
@@ -355,4 +356,6 @@ 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/irpcss.idl b/dlls/ole32/irpcss.idl
new file mode 100644
index 0000000000..65078167de
--- /dev/null
+++ b/dlls/ole32/irpcss.idl
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2019 Nikolay Sivov for CodeWeavers
+ *
+ * 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
+ */
+
+#pragma makedep client
+
+#include "wine/irpcss.idl"
diff --git a/dlls/ole32/moniker.c b/dlls/ole32/moniker.c
index 82d829d719..f82159d9e1 100644
--- a/dlls/ole32/moniker.c
+++ b/dlls/ole32/moniker.c
@@ -41,6 +41,7 @@
#include "compobj_private.h"
#include "moniker.h"
#include "irot.h"
+#include "irpcss.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -77,6 +78,7 @@ typedef struct RunningObjectTableImpl
static RunningObjectTableImpl* runningObjectTableInstance = NULL;
static IrotHandle irot_handle;
+static RPC_BINDING_HANDLE irpcss_handle;
/* define the EnumMonikerImpl structure */
typedef struct EnumMonikerImpl
@@ -102,23 +104,30 @@ static inline EnumMonikerImpl *impl_from_IEnumMoniker(IEnumMoniker *iface)
static HRESULT EnumMonikerImpl_CreateEnumROTMoniker(InterfaceList *moniker_list,
ULONG pos, IEnumMoniker **ppenumMoniker);
+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 IrotHandle get_irot_handle(void)
{
if (!irot_handle)
{
- RPC_STATUS status;
- RPC_WSTR binding;
- IrotHandle new_handle;
- unsigned short ncacn_np[] = IROT_PROTSEQ;
+ unsigned short protseq[] = IROT_PROTSEQ;
unsigned short endpoint[] = IROT_ENDPOINT;
- status = RpcStringBindingComposeW(NULL, ncacn_np, NULL, endpoint, NULL, &binding);
- if (status == RPC_S_OK)
- {
- status = RpcBindingFromStringBindingW(binding, &new_handle);
- RpcStringFreeW(&binding);
- }
- if (status != RPC_S_OK)
- return NULL;
+
+ IrotHandle new_handle = get_rpc_handle(protseq, endpoint);
if (InterlockedCompareExchangePointer(&irot_handle, new_handle, NULL))
/* another thread beat us to it */
RpcBindingFree(&new_handle);
@@ -126,6 +135,21 @@ 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};
@@ -176,6 +200,33 @@ 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/tests/compobj.c b/dlls/ole32/tests/compobj.c
index 8412ee45a0..6b15040ebe 100644
--- a/dlls/ole32/tests/compobj.c
+++ b/dlls/ole32/tests/compobj.c
@@ -3893,6 +3893,31 @@ static void test_implicit_mta(void)
CoUninitialize();
}
+static DWORD WINAPI co_get_current_process_thread(void *param)
+{
+ DWORD *id = param;
+
+ *id = CoGetCurrentProcess();
+ return 0;
+}
+
+static void test_CoGetCurrentProcess(void)
+{
+ DWORD id, id2;
+ HANDLE thread;
+
+ id = CoGetCurrentProcess();
+ ok(!!id && id != GetCurrentProcessId() && id != GetCurrentThreadId(), "Unexpected result %d.\n", id);
+
+ id2 = 0;
+ thread = CreateThread(NULL, 0, co_get_current_process_thread, &id2, 0, NULL);
+ ok(thread != NULL, "Failed to create test thread.\n");
+ ok(!WaitForSingleObject(thread, 10000), "Wait timed out.\n");
+ CloseHandle(thread);
+
+ ok(id2 && id2 != id, "Unexpected id from another thread.\n");
+}
+
START_TEST(compobj)
{
init_funcs();
@@ -3949,5 +3974,7 @@ START_TEST(compobj)
test_CoGetInstanceFromFile();
test_GlobalOptions();
test_implicit_mta();
+ test_CoGetCurrentProcess();
+
DeleteFileA( testlib );
}
--
2.24.0.rc1
More information about the wine-devel
mailing list