Commit c79b9bb4 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

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

parent 9bec4bb5
......@@ -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
......
......@@ -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;
}
/***********************************************************************
......
......@@ -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 */
/*
* 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"
......@@ -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);
......
......@@ -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 );
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment