Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/rpcrt4/ndr_ole.c | 10 ++++++++-- dlls/rpcrt4/tests/ndr_marshall.c | 2 -- 2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/dlls/rpcrt4/ndr_ole.c b/dlls/rpcrt4/ndr_ole.c index 8608691231..c8026c0ff1 100644 --- a/dlls/rpcrt4/ndr_ole.c +++ b/dlls/rpcrt4/ndr_ole.c @@ -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); } diff --git a/dlls/rpcrt4/tests/ndr_marshall.c b/dlls/rpcrt4/tests/ndr_marshall.c index 5da03e2ef7..d436b42648 100644 --- a/dlls/rpcrt4/tests/ndr_marshall.c +++ b/dlls/rpcrt4/tests/ndr_marshall.c @@ -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);