mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-20 01:19:00 +00:00
ole32: Don't keep the local server named pipe open for a single-use object.
This commit is contained in:
parent
7ba4b81675
commit
15a0b7fad5
|
@ -1622,6 +1622,7 @@ HRESULT WINAPI CoRegisterClassObject(
|
|||
|
||||
hr = RPC_StartLocalServer(&newClass->classIdentifier,
|
||||
newClass->pMarshaledData,
|
||||
flags & (REGCLS_MULTIPLEUSE|REGCLS_MULTI_SEPARATE),
|
||||
&newClass->RpcRegistration);
|
||||
}
|
||||
return S_OK;
|
||||
|
|
|
@ -221,7 +221,7 @@ HRESULT RPC_CreateServerChannel(IRpcChannelBuffer **chan);
|
|||
void RPC_ExecuteCall(struct dispatch_params *params);
|
||||
HRESULT RPC_RegisterInterface(REFIID riid);
|
||||
void RPC_UnregisterInterface(REFIID riid);
|
||||
HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, void **registration);
|
||||
HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, BOOL multi_use, void **registration);
|
||||
void RPC_StopLocalServer(void *registration);
|
||||
HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
|
||||
HRESULT RPC_RegisterChannelHook(REFGUID rguid, IChannelHook *hook);
|
||||
|
|
|
@ -1732,6 +1732,7 @@ struct local_server_params
|
|||
CLSID clsid;
|
||||
IStream *stream;
|
||||
HANDLE ready_event;
|
||||
BOOL multi_use;
|
||||
HANDLE pipe;
|
||||
};
|
||||
|
||||
|
@ -1749,6 +1750,7 @@ static DWORD WINAPI local_server_thread(LPVOID param)
|
|||
LARGE_INTEGER seekto;
|
||||
ULARGE_INTEGER newpos;
|
||||
ULONG res;
|
||||
BOOL multi_use = lsp->multi_use;
|
||||
|
||||
TRACE("Starting threader for %s.\n",debugstr_guid(&lsp->clsid));
|
||||
|
||||
|
@ -1817,13 +1819,20 @@ static DWORD WINAPI local_server_thread(LPVOID param)
|
|||
DisconnectNamedPipe(hPipe);
|
||||
|
||||
TRACE("done marshalling IClassFactory\n");
|
||||
|
||||
if (!multi_use)
|
||||
{
|
||||
TRACE("single use object, shutting down pipe %s\n", debugstr_w(pipefn));
|
||||
CloseHandle(hPipe);
|
||||
break;
|
||||
}
|
||||
}
|
||||
IStream_Release(pStm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* starts listening for a local server */
|
||||
HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, void **registration)
|
||||
HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, BOOL multi_use, void **registration)
|
||||
{
|
||||
DWORD tid;
|
||||
HANDLE thread, ready_event;
|
||||
|
@ -1833,6 +1842,7 @@ HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, void **registratio
|
|||
lsp->stream = stream;
|
||||
IStream_AddRef(stream);
|
||||
lsp->ready_event = ready_event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
lsp->multi_use = multi_use;
|
||||
|
||||
thread = CreateThread(NULL, 0, local_server_thread, lsp, 0, &tid);
|
||||
if (!thread)
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define CONST_VTABLE
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
|
@ -50,6 +51,14 @@ static const IID IID_IWineTest =
|
|||
#define EXTENTID_WineTest IID_IWineTest
|
||||
#define CLSID_WineTest IID_IWineTest
|
||||
|
||||
static const CLSID CLSID_WineOOPTest =
|
||||
{
|
||||
0x5201163f,
|
||||
0x8164,
|
||||
0x4fd0,
|
||||
{0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
|
||||
}; /* 5201163f-8164-4fd0-a1a2-5d5a3654d3bd */
|
||||
|
||||
static void test_cocreateinstance_proxy(void)
|
||||
{
|
||||
IUnknown *pProxy;
|
||||
|
@ -2152,6 +2161,11 @@ static HRESULT WINAPI TestOOP_IClassFactory_CreateInstance(
|
|||
REFIID riid,
|
||||
LPVOID *ppvObj)
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown))
|
||||
{
|
||||
*ppvObj = iface;
|
||||
return S_OK;
|
||||
}
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
|
@ -2177,19 +2191,72 @@ static const IClassFactoryVtbl TestClassFactoryOOP_Vtbl =
|
|||
|
||||
static IClassFactory TestOOP_ClassFactory = { &TestClassFactoryOOP_Vtbl };
|
||||
|
||||
static void test_register_local_server(void)
|
||||
{
|
||||
DWORD cookie;
|
||||
HRESULT hr;
|
||||
HANDLE ready_event;
|
||||
HANDLE quit_event;
|
||||
DWORD wait;
|
||||
|
||||
heventShutdown = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&TestOOP_ClassFactory,
|
||||
CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
|
||||
ok_ole_success(hr, CoRegisterClassObject);
|
||||
|
||||
ready_event = CreateEvent(NULL, FALSE, FALSE, "Wine COM Test Ready Event");
|
||||
SetEvent(ready_event);
|
||||
|
||||
quit_event = CreateEvent(NULL, FALSE, FALSE, "Wine COM Test Quit Event");
|
||||
|
||||
do
|
||||
{
|
||||
wait = MsgWaitForMultipleObjects(1, &quit_event, FALSE, INFINITE, QS_ALLINPUT);
|
||||
if (wait == WAIT_OBJECT_0+1)
|
||||
{
|
||||
MSG msg;
|
||||
BOOL ret = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
|
||||
if (ret)
|
||||
{
|
||||
trace("Message 0x%x\n", msg.message);
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (wait == WAIT_OBJECT_0+1);
|
||||
|
||||
hr = CoRevokeClassObject(cookie);
|
||||
ok_ole_success(hr, CoRevokeClassObject);
|
||||
}
|
||||
|
||||
static HANDLE create_target_process(const char *arg)
|
||||
{
|
||||
char **argv;
|
||||
char cmdline[MAX_PATH];
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFO si = { 0 };
|
||||
si.cb = sizeof(si);
|
||||
|
||||
winetest_get_mainargs( &argv );
|
||||
sprintf(cmdline, "%s %s %s", argv[0], argv[1], arg);
|
||||
ok(CreateProcess(argv[0], cmdline, NULL, NULL, FALSE, 0, NULL, NULL,
|
||||
&si, &pi) != 0, "error: %u\n", GetLastError());
|
||||
ok(CloseHandle(pi.hThread) != 0, "error %u\n", GetLastError());
|
||||
return pi.hProcess;
|
||||
}
|
||||
|
||||
/* tests functions commonly used by out of process COM servers */
|
||||
static void test_local_server(void)
|
||||
{
|
||||
static const CLSID CLSID_WineOOPTest = {
|
||||
0x5201163f,
|
||||
0x8164,
|
||||
0x4fd0,
|
||||
{0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
|
||||
}; /* 5201163f-8164-4fd0-a1a2-5d5a3654d3bd */
|
||||
DWORD cookie;
|
||||
HRESULT hr;
|
||||
IClassFactory * cf;
|
||||
DWORD ret;
|
||||
HANDLE process;
|
||||
HANDLE quit_event;
|
||||
HANDLE ready_event;
|
||||
|
||||
heventShutdown = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
|
@ -2249,6 +2316,28 @@ static void test_local_server(void)
|
|||
ok_ole_success(hr, CoRevokeClassObject);
|
||||
|
||||
CloseHandle(heventShutdown);
|
||||
|
||||
process = create_target_process("-Embedding");
|
||||
ok(process != NULL, "couldn't start local server process, error was %d\n", GetLastError());
|
||||
|
||||
ready_event = CreateEvent(NULL, FALSE, FALSE, "Wine COM Test Ready Event");
|
||||
WaitForSingleObject(ready_event, 1000);
|
||||
CloseHandle(ready_event);
|
||||
|
||||
hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IClassFactory, (void **)&cf);
|
||||
ok_ole_success(hr, CoCreateInstance);
|
||||
|
||||
IClassFactory_Release(cf);
|
||||
|
||||
hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IClassFactory, (void **)&cf);
|
||||
ok(hr == REGDB_E_CLASSNOTREG, "Second CoCreateInstance on REGCLS_SINGLEUSE object should have failed\n");
|
||||
|
||||
quit_event = CreateEvent(NULL, FALSE, FALSE, "Wine COM Test Quit Event");
|
||||
SetEvent(quit_event);
|
||||
|
||||
WaitForSingleObject(process, INFINITE);
|
||||
CloseHandle(quit_event);
|
||||
CloseHandle(process);
|
||||
}
|
||||
|
||||
struct git_params
|
||||
|
@ -2532,8 +2621,21 @@ START_TEST(marshal)
|
|||
{
|
||||
WNDCLASS wndclass;
|
||||
HMODULE hOle32 = GetModuleHandle("ole32");
|
||||
int argc;
|
||||
char **argv;
|
||||
|
||||
if (!(pCoInitializeEx = (void*)GetProcAddress(hOle32, "CoInitializeEx"))) goto no_test;
|
||||
|
||||
argc = winetest_get_mainargs( &argv );
|
||||
if (argc > 2 && (!strcmp(argv[2], "-Embedding")))
|
||||
{
|
||||
pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
test_register_local_server();
|
||||
CoUninitialize();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* register a window class used in several tests */
|
||||
memset(&wndclass, 0, sizeof(wndclass));
|
||||
wndclass.lpfnWndProc = window_proc;
|
||||
|
|
Loading…
Reference in a new issue