Nikolay Sivov : ole32: Reimplement CoGetCurrentProcess() to use global counter from rpcss.

Alexandre Julliard julliard at winehq.org
Fri Nov 8 17:25:25 CST 2019


Module: wine
Branch: master
Commit: c79b9bb46fca1df2d10b58ce3ea032016c8a0d53
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c79b9bb46fca1df2d10b58ce3ea032016c8a0d53

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Nov  7 23:00:01 2019 +0300

ole32: Reimplement CoGetCurrentProcess() to use global counter from rpcss.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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(-)

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 );
 }




More information about the wine-cvs mailing list