rpcrt4: Avoid reference leaks when unmarshalling [in, out] pointers.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2018-11-01 23:53:45 -05:00 committed by Alexandre Julliard
parent 66f46f8182
commit 666bbe084e
2 changed files with 8 additions and 4 deletions

View File

@ -338,19 +338,25 @@ unsigned char * WINAPI NdrInterfacePointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg
PFORMAT_STRING pFormat,
unsigned char fMustAlloc)
{
IUnknown **unk = (IUnknown **)ppMemory;
LPSTREAM stream;
HRESULT hr;
TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc);
if (!LoadCOM()) return NULL;
*(LPVOID*)ppMemory = NULL;
/* Avoid reference leaks for [in, out] pointers. */
if (pStubMsg->IsClient && *unk)
IUnknown_Release(*unk);
*unk = NULL;
if (pStubMsg->Buffer + sizeof(DWORD) < (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength) {
ULONG size;
hr = RpcStream_Create(pStubMsg, FALSE, &size, &stream);
if (hr == S_OK) {
if (size != 0)
hr = COM_UnmarshalInterface(stream, &IID_NULL, (LPVOID*)ppMemory);
hr = COM_UnmarshalInterface(stream, &IID_NULL, (void **)unk);
IStream_Release(stream);
}

View File

@ -1327,9 +1327,7 @@ static void test_iface_ptr(void)
ok(!my_alloc_called, "alloc called %d\n", my_alloc_called);
ok(!my_free_called, "free called %d\n", my_free_called);
ok(server_obj.ref > 1, "got %d references\n", server_obj.ref);
todo_wine
ok(client_obj.ref == 1, "got %d references\n", client_obj.ref);
client_obj.ref = 1;
hr = IPersist_GetClassID(proxy, &clsid);
ok(hr == S_OK, "got hr %#x\n", hr);