Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/rpcrt4/ndr_marshall.c | 16 ++++++++++++++++ dlls/rpcrt4/tests/server.c | 25 +++++++++++++++++++++++++ dlls/rpcrt4/tests/server.idl | 9 +++++++++ 3 files changed, 50 insertions(+)
diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c index ee58b60..cbe8223 100644 --- a/dlls/rpcrt4/ndr_marshall.c +++ b/dlls/rpcrt4/ndr_marshall.c @@ -5745,6 +5745,10 @@ static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned c pStubMsg->Buffer = saved_buffer + 4; } break; + case RPC_FC_IP: + /* must be dereferenced first */ + m(pStubMsg, *(unsigned char **)pMemory, desc); + break; default: m(pStubMsg, pMemory, desc); } @@ -5814,6 +5818,10 @@ static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg, pStubMsg->Buffer = saved_buffer + 4; } break; + case RPC_FC_IP: + /* must be dereferenced first */ + m(pStubMsg, *(unsigned char ***)ppMemory, desc, fMustAlloc); + break; default: m(pStubMsg, ppMemory, desc, fMustAlloc); } @@ -5868,6 +5876,10 @@ static void union_arm_buffer_size(PMIDL_STUB_MESSAGE pStubMsg, pStubMsg->BufferLength = saved_buffer_length; } break; + case RPC_FC_IP: + /* must be dereferenced first */ + m(pStubMsg, *(unsigned char **)pMemory, desc); + break; default: m(pStubMsg, pMemory, desc); } @@ -5955,6 +5967,10 @@ static void union_arm_free(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_FP: PointerFree(pStubMsg, *(unsigned char **)pMemory, desc); break; + case RPC_FC_IP: + /* must be dereferenced first */ + m(pStubMsg, *(unsigned char **)pMemory, desc); + break; default: m(pStubMsg, pMemory, desc); } diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index 31f5c4d..5278a1d 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -844,6 +844,15 @@ void __cdecl s_stop(void) } }
+void __cdecl s_ip_test(ipu_t *a) +{ + STATSTG st; + HRESULT hr; + + hr = IStream_Stat(a->tagged_union.stream, &st, STATFLAG_NONAME); + ok(hr == S_OK, "got %#x\n", hr); +} + static void make_cmdline(char buffer[MAX_PATH], const char *test) { @@ -1044,6 +1053,8 @@ union_tests(void) encu_t eu; unencu_t uneu; sun_t su; + ipu_t ipu; + LONG ref; int i;
su.s = SUN_I; @@ -1084,6 +1095,15 @@ union_tests(void) eue.t = E2; eue.tagged_union.f2 = 10.0; ok(square_encue(&eue) == 100.0, "RPC square_encue\n"); + + CoInitializeEx(NULL, COINIT_MULTITHREADED); + + CreateStreamOnHGlobal(NULL, TRUE, &ipu.tagged_union.stream); + ip_test(&ipu); + ref = IStream_Release(ipu.tagged_union.stream); + ok(!ref, "got %u refs\n", ref); + + CoUninitialize(); }
static test_list_t * @@ -1701,6 +1721,9 @@ server(void) RPC_STATUS status, iptcp_status, np_status, ncalrpc_status; DWORD ret;
+ /* needed for tests involving interface pointers */ + CoInitializeEx(NULL, COINIT_MULTITHREADED); + iptcp_status = RpcServerUseProtseqEpA(iptcp, 20, port, NULL); ok(iptcp_status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_ip_tcp) failed with status %d\n", iptcp_status);
@@ -1766,6 +1789,8 @@ server(void)
CloseHandle(stop_event); stop_event = NULL; + + CoUninitialize(); }
static DWORD WINAPI listen_test_client_thread(void *binding) diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl index 8a02c29..75d78f7 100644 --- a/dlls/rpcrt4/tests/server.idl +++ b/dlls/rpcrt4/tests/server.idl @@ -21,6 +21,8 @@ #pragma makedep client #pragma makedep server
+import "objidl.idl"; + #include "server_defines.h"
typedef struct tag_vector @@ -383,4 +385,11 @@ cpp_quote("#endif") void authinfo_test(unsigned int protseq, int secure);
void stop(void); + + typedef union ipu switch(int t) + { + default: IStream *stream; + } ipu_t; + + void ip_test([in] ipu_t *a); }