diff --git a/.gitignore b/.gitignore index 0de124f9545..0e630488cf2 100644 --- a/.gitignore +++ b/.gitignore @@ -441,6 +441,10 @@ dlls/riched32/version.res dlls/rpcrt4/librpcrt4.def dlls/rpcrt4/tests/*.ok dlls/rpcrt4/tests/rpcrt4_crosstest.exe +dlls/rpcrt4/tests/server.h +dlls/rpcrt4/tests/server.h +dlls/rpcrt4/tests/server_c.c +dlls/rpcrt4/tests/server_s.c dlls/rpcrt4/tests/testlist.c dlls/rpcrt4/version.res dlls/rsabase/tests/*.ok diff --git a/dlls/rpcrt4/tests/Makefile.in b/dlls/rpcrt4/tests/Makefile.in index 036cd218a22..c497aa30f6d 100644 --- a/dlls/rpcrt4/tests/Makefile.in +++ b/dlls/rpcrt4/tests/Makefile.in @@ -5,12 +5,17 @@ VPATH = @srcdir@ TESTDLL = rpcrt4.dll IMPORTS = ole32 rpcrt4 kernel32 EXTRALIBS = -luuid +EXTRAIDLFLAGS = --prefix-server=s_ + +IDL_C_SRCS = server.idl +IDL_S_SRCS = server.idl CTESTS = \ cstub.c \ generated.c \ ndr_marshall.c \ - rpc.c + rpc.c \ + server.c @MAKE_TEST_RULES@ diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c new file mode 100644 index 00000000000..9fef738aeca --- /dev/null +++ b/dlls/rpcrt4/tests/server.c @@ -0,0 +1,262 @@ +/* + * Tests for WIDL and RPC server/clients. + * + * Copyright (C) Google 2007 (Dan Hipschman) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include "wine/test.h" +#include "server.h" + +#include + +#define PORT "4114" +#define PIPE "\\pipe\\wine_rpcrt4_test" + +#define INT_CODE 4198 + +static const char *progname; + +static HANDLE stop_event; + +void __RPC_FAR *__RPC_USER +midl_user_allocate(size_t n) +{ + return malloc(n); +} + +void __RPC_USER +midl_user_free(void __RPC_FAR *p) +{ + free(p); +} + +int +s_int_return(void) +{ + return INT_CODE; +} + +int +s_square(int x) +{ + return x * x; +} + +int +s_sum(int x, int y) +{ + return x + y; +} + +void +s_square_out(int x, int *y) +{ + *y = s_square(x); +} + +void +s_square_ref(int *x) +{ + *x = s_square(*x); +} + +int +s_str_length(const char *s) +{ + return strlen(s); +} + +int +s_dot_self(vector_t *v) +{ + return s_square(v->x) + s_square(v->y) + s_square(v->z); +} + +double +s_square_half(double x, double *y) +{ + *y = x / 2.0; + return x * x; +} + +float +s_square_half_float(float x, float *y) +{ + *y = x / 2.0f; + return x * x; +} + +long +s_square_half_long(long x, long *y) +{ + *y = x / 2; + return x * x; +} + +void +s_stop(void) +{ + ok(RPC_S_OK == RpcMgmtStopServerListening(NULL), "RpcMgmtStopServerListening\n"); + ok(RPC_S_OK == RpcServerUnregisterIf(NULL, NULL, FALSE), "RpcServerUnregisterIf\n"); + ok(SetEvent(stop_event), "SetEvent\n"); +} + +static void +make_cmdline(char buffer[MAX_PATH], const char *test) +{ + sprintf(buffer, "%s server %s", progname, test); +} + +static int +run_client(const char *test) +{ + char cmdline[MAX_PATH]; + PROCESS_INFORMATION info; + STARTUPINFOA startup; + DWORD exitcode; + + memset(&startup, 0, sizeof startup); + startup.cb = sizeof startup; + + make_cmdline(cmdline, test); + ok(CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); + ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n"); + ok(GetExitCodeProcess(info.hProcess, &exitcode), "GetExitCodeProcess\n"); + ok(CloseHandle(info.hProcess), "CloseHandle\n"); + ok(CloseHandle(info.hThread), "CloseHandle\n"); + + return exitcode == 0; +} + +static void +basic_tests(void) +{ + static char string[] = "I am a string"; + static vector_t a = {1, 3, 7}; + double u, v; + float s, t; + long q, r; + int x; + + ok(int_return() == INT_CODE, "RPC int_return\n"); + + ok(square(7) == 49, "RPC square\n"); + ok(sum(23, -4) == 19, "RPC sum\n"); + + x = 0; + square_out(11, &x); + ok(x == 121, "RPC square_out\n"); + + x = 5; + square_ref(&x); + ok(x == 25, "RPC square_ref\n"); + + ok(str_length(string) == strlen(string), "RPC str_length\n"); + ok(dot_self(&a) == 59, "RPC dot_self\n"); + + v = 0.0; + u = square_half(3.0, &v); + ok(u == 9.0, "RPC square_half\n"); + ok(v == 1.5, "RPC square_half\n"); + + t = 0.0f; + s = square_half_float(3.0f, &t); + ok(s == 9.0f, "RPC square_half_float\n"); + ok(t == 1.5f, "RPC square_half_float\n"); + + r = 0; + q = square_half_long(3, &r); + ok(q == 9, "RPC square_half_long\n"); + ok(r == 1, "RPC square_half_long\n"); +} + +static void +client(const char *test) +{ + if (strcmp(test, "tcp_basic") == 0) + { + static unsigned char iptcp[] = "ncacn_ip_tcp"; + static unsigned char address[] = "127.0.0.1"; + static unsigned char port[] = PORT; + unsigned char *binding; + + ok(RPC_S_OK == RpcStringBindingCompose(NULL, iptcp, address, port, NULL, &binding), "RpcStringBindingCompose\n"); + ok(RPC_S_OK == RpcBindingFromStringBinding(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n"); + + basic_tests(); + + ok(RPC_S_OK == RpcStringFree(&binding), "RpcStringFree\n"); + ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n"); + } + else if (strcmp(test, "np_basic") == 0) + { + static unsigned char np[] = "ncacn_np"; + static unsigned char address[] = "\\\\."; + static unsigned char pipe[] = PIPE; + unsigned char *binding; + + ok(RPC_S_OK == RpcStringBindingCompose(NULL, np, address, pipe, NULL, &binding), "RpcStringBindingCompose\n"); + ok(RPC_S_OK == RpcBindingFromStringBinding(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n"); + + basic_tests(); + stop(); + + ok(RPC_S_OK == RpcStringFree(&binding), "RpcStringFree\n"); + ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n"); + } +} + +static void +server(void) +{ + static unsigned char iptcp[] = "ncacn_ip_tcp"; + static unsigned char port[] = PORT; + static unsigned char np[] = "ncacn_np"; + static unsigned char pipe[] = PIPE; + + ok(RPC_S_OK == RpcServerUseProtseqEp(iptcp, 20, port, NULL), "RpcServerUseProtseqEp\n"); + ok(RPC_S_OK == RpcServerRegisterIf(s_IServer_v0_0_s_ifspec, NULL, NULL), "RpcServerRegisterIf\n"); + ok(RPC_S_OK == RpcServerListen(1, 20, TRUE), "RpcServerListen\n"); + + stop_event = CreateEvent(NULL, FALSE, FALSE, NULL); + ok(stop_event != NULL, "CreateEvent failed\n"); + + ok(run_client("tcp_basic"), "tcp_basic client test failed\n"); + + ok(RPC_S_OK == RpcServerUseProtseqEp(np, 0, pipe, NULL), "RpcServerUseProtseqEp\n"); + ok(run_client("np_basic"), "np_basic client test failed\n"); + + ok(WAIT_OBJECT_0 == WaitForSingleObject(stop_event, 60000), "WaitForSingleObject\n"); + todo_wine { + ok(RPC_S_OK == RpcMgmtWaitServerListen(), "RpcMgmtWaitServerListening\n"); + } +} + +START_TEST(server) +{ + int argc; + char **argv; + + argc = winetest_get_mainargs(&argv); + progname = argv[0]; + + if (argc == 3) + client(argv[2]); + else + server(); +} diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl new file mode 100644 index 00000000000..d42a3a9a6e7 --- /dev/null +++ b/dlls/rpcrt4/tests/server.idl @@ -0,0 +1,45 @@ +/* + * A simple interface to test the RPC server. + * + * Copyright (C) Google 2007 (Dan Hipschman) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +typedef struct tag_vector +{ + int x; + int y; + int z; +} vector_t; + +[ + uuid(00000000-4114-0704-2301-000000000000), + implicit_handle(handle_t IServer_IfHandle) +] +interface IServer +{ + int int_return(void); + int square(int x); + int sum(int x, int y); + void square_out(int x, [out] int *y); + void square_ref([in, out] int *x); + int str_length([string] const char *s); + int dot_self(vector_t *v); + double square_half(double x, [out] double *y); + float square_half_float(float x, [out] float *y); + long square_half_long(long x, [out] long *y); + void stop(void); +}