Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/rpcrt4/tests/server.c | 67 ++++++++++++++++++++++++++++++++++++++++++-- dlls/rpcrt4/tests/server.idl | 4 +++ 2 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index 5278a1d..e48d0c7 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -25,6 +25,7 @@ #include <secext.h> #include <rpcdce.h> #include <netfw.h> +#include "wine/heap.h" #include "wine/test.h" #include "server.h" #include "server_defines.h" @@ -72,16 +73,20 @@ static void InitFunctionPointers(void) if (!pNDRSContextMarshall2) old_windows_version = TRUE; }
+static int locks; + void __RPC_FAR *__RPC_USER midl_user_allocate(SIZE_T n) { - return HeapAlloc(GetProcessHeap(), 0, n); + locks++; + return heap_alloc(n); }
void __RPC_USER midl_user_free(void __RPC_FAR *p) { - HeapFree(GetProcessHeap(), 0, p); + locks--; + ok(HeapFree(GetProcessHeap(), 0, p), "HeapFree(%p) failed\n", p); }
static char * @@ -853,6 +858,25 @@ void __cdecl s_ip_test(ipu_t *a) ok(hr == S_OK, "got %#x\n", hr); }
+void __cdecl s_get_pint(int **a) +{ + static int b = 12345; + *a = &b; +} + +int *__cdecl s_ret_pint(void) +{ + int *ret = midl_user_allocate(sizeof(int)); + *ret = 12345; + return ret; +} + +void __cdecl s_get_str(str_t *a) +{ + *a = midl_user_allocate(5); + strcpy(*a, "wine"); +} + static void make_cmdline(char buffer[MAX_PATH], const char *test) { @@ -874,6 +898,8 @@ run_client(const char *test) winetest_wait_child_process( info.hProcess ); ok(CloseHandle(info.hProcess), "CloseHandle\n"); ok(CloseHandle(info.hThread), "CloseHandle\n"); + + ok(!locks, "got %d locks on server\n", locks); }
static void @@ -1242,6 +1268,9 @@ pointer_tests(void) int *pa2; s123_t *s123; int val = 42; + int *pint; + char buf[5]; + str_t str;
ok(test_list_length(list) == 3, "RPC test_list_length\n"); ok(square_puint(p1) == 121, "RPC square_puint\n"); @@ -1335,6 +1364,37 @@ pointer_tests(void)
full_pointer_test(&val, &val); full_pointer_null_test(&val, NULL); + + /* A simple out pointer (base type or enum) should not be allocated on the + * server side, but still must be freed on the client side. */ + pint = NULL; + get_pint(&pint); + ok(!!pint, "RPC get_pint\n"); + ok(*pint == 12345, "got %d\n", *pint); + midl_user_free(pint); + + pint = &val; + get_pint(&pint); + ok(pint == &val, "got %p\n", pint); + ok(*pint == 12345, "got %d\n", *pint); + + /* Otherwise the pointer must be allocated on the server side and freed on + * the client side. */ + pint = ret_pint(); + ok(!!pint, "RPC ret_pint\n"); + ok(*pint == 12345, "got %d\n", *pint); + midl_user_free(pint); + + str = NULL; + get_str(&str); + ok(!!str, "RPC get_str\n"); + ok(!strcmp(str, "wine"), "got %s\n", str); + midl_user_free(str); + + str = buf; + get_str(&str); + ok(str == buf, "got %p\n", str); + ok(!strcmp(str, "wine"), "got %s\n", str); }
static int @@ -1446,6 +1506,7 @@ array_tests(void) ok(get_cpsc(5, &cpsc) == 45, "RPC sum_cpsc\n"); ok( cpsc.a == 10, "RPC get_cpsc %u\n", cpsc.a ); for (n = 0; n < 10; n++) ok( cpsc.ca[n] == n, "RPC get_cpsc[%d] = %d\n", n, cpsc.ca[n] ); + midl_user_free(cpsc.ca);
memset( tmp, 0x33, sizeof(tmp) ); cpsc.ca = tmp; @@ -1592,6 +1653,8 @@ run_tests(void) pointer_tests(); array_tests(); context_handle_test(); + + ok(!locks, "got %d locks on client\n", locks); }
static void diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl index 75d78f7..52f689e 100644 --- a/dlls/rpcrt4/tests/server.idl +++ b/dlls/rpcrt4/tests/server.idl @@ -392,4 +392,8 @@ cpp_quote("#endif") } ipu_t;
void ip_test([in] ipu_t *a); + + void get_pint([out] int **a); + int *ret_pint(void); + void get_str([out] str_t *out); }