diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c index 367ca357715..b4dc9bc61cc 100644 --- a/dlls/rpcrt4/rpc_transport.c +++ b/dlls/rpcrt4/rpc_transport.c @@ -257,6 +257,17 @@ static RPC_STATUS rpcrt4_protseq_ncalrpc_open_endpoint(RpcServerProtseq* protseq RPC_STATUS r; LPSTR pname; RpcConnection *Connection; + char generated_endpoint[22]; + + if (!endpoint) + { + static LONG lrpc_nameless_id; + DWORD process_id = GetCurrentProcessId(); + ULONG id = InterlockedIncrement(&lrpc_nameless_id); + snprintf(generated_endpoint, sizeof(generated_endpoint), + "LRPC%08x.%08x", process_id, id); + endpoint = generated_endpoint; + } r = RPCRT4_CreateConnection(&Connection, TRUE, protseq->Protseq, NULL, endpoint, NULL, NULL, NULL); @@ -304,6 +315,17 @@ static RPC_STATUS rpcrt4_protseq_ncacn_np_open_endpoint(RpcServerProtseq *protse RPC_STATUS r; LPSTR pname; RpcConnection *Connection; + char generated_endpoint[21]; + + if (!endpoint) + { + static LONG np_nameless_id; + DWORD process_id = GetCurrentProcessId(); + ULONG id = InterlockedExchangeAdd(&np_nameless_id, 1 ); + snprintf(generated_endpoint, sizeof(generated_endpoint), + "\\\\pipe\\\\%08x.%03x", process_id, id); + endpoint = generated_endpoint; + } r = RPCRT4_CreateConnection(&Connection, TRUE, protseq->Protseq, NULL, endpoint, NULL, NULL, NULL); diff --git a/dlls/rpcrt4/tests/Makefile.in b/dlls/rpcrt4/tests/Makefile.in index ae7d2d2c13b..69bbd622109 100644 --- a/dlls/rpcrt4/tests/Makefile.in +++ b/dlls/rpcrt4/tests/Makefile.in @@ -15,6 +15,7 @@ CTESTS = \ ndr_marshall.c \ rpc.c \ rpc_async.c \ + rpc_protseq.c \ server.c @MAKE_TEST_RULES@ diff --git a/dlls/rpcrt4/tests/rpc.c b/dlls/rpcrt4/tests/rpc.c index bf538e47c75..725dbba6221 100644 --- a/dlls/rpcrt4/tests/rpc.c +++ b/dlls/rpcrt4/tests/rpc.c @@ -680,62 +680,6 @@ static void test_I_RpcExceptionFilter(void) } } -static void test_endpoint_mapper(RPC_CSTR protseq, RPC_CSTR address, - RPC_CSTR endpoint) -{ - static unsigned char annotation[] = "Test annotation string."; - RPC_STATUS status; - RPC_BINDING_VECTOR *binding_vector; - handle_t handle; - unsigned char *binding; - - status = RpcServerUseProtseqEp(protseq, 20, endpoint, NULL); - ok(status == RPC_S_OK || broken(status == RPC_S_PROTSEQ_NOT_SUPPORTED), /* win9x */ - "%s: RpcServerUseProtseqEp failed (%u)\n", protseq, status); - - status = RpcServerRegisterIf(IFoo_v0_0_s_ifspec, NULL, NULL); - ok(status == RPC_S_OK, "%s: RpcServerRegisterIf failed (%u)\n", protseq, status); - - status = RpcServerInqBindings(&binding_vector); - ok(status == RPC_S_OK, "%s: RpcServerInqBindings failed with error %u\n", protseq, status); - - status = RpcEpRegisterA(IFoo_v0_0_s_ifspec, binding_vector, NULL, annotation); - ok(status == RPC_S_OK, "%s: RpcEpRegisterA failed with error %u\n", protseq, status); - - status = RpcStringBindingCompose(NULL, protseq, address, - NULL, NULL, &binding); - ok(status == RPC_S_OK, "%s: RpcStringBindingCompose failed (%u)\n", protseq, status); - - status = RpcBindingFromStringBinding(binding, &handle); - ok(status == RPC_S_OK, "%s: RpcBindingFromStringBinding failed (%u)\n", protseq, status); - - RpcStringFree(&binding); - - status = RpcBindingReset(handle); - ok(status == RPC_S_OK, "%s: RpcBindingReset failed with error %u\n", protseq, status); - - RpcStringFree(&binding); - - status = RpcEpResolveBinding(handle, IFoo_v0_0_s_ifspec); - ok(status == RPC_S_OK || broken(status == RPC_S_SERVER_UNAVAILABLE), /* win9x */ - "%s: RpcEpResolveBinding failed with error %u\n", protseq, status); - - status = RpcBindingReset(handle); - ok(status == RPC_S_OK, "%s: RpcBindingReset failed with error %u\n", protseq, status); - - status = RpcBindingFree(&handle); - ok(status == RPC_S_OK, "%s: RpcBindingFree failed with error %u\n", protseq, status); - - status = RpcServerUnregisterIf(NULL, NULL, FALSE); - ok(status == RPC_S_OK, "%s: RpcServerUnregisterIf failed (%u)\n", protseq, status); - - status = RpcEpUnregister(IFoo_v0_0_s_ifspec, binding_vector, NULL); - ok(status == RPC_S_OK, "%s: RpcEpUnregisterA failed with error %u\n", protseq, status); - - status = RpcBindingVectorFree(&binding_vector); - ok(status == RPC_S_OK, "%s: RpcBindingVectorFree failed with error %u\n", protseq, status); -} - static void test_RpcStringBindingFromBinding(void) { static unsigned char ncacn_np[] = "ncacn_np"; @@ -832,12 +776,6 @@ static void test_UuidCreate(void) START_TEST( rpc ) { - static unsigned char ncacn_np[] = "ncacn_np"; - static unsigned char ncalrpc[] = "ncalrpc"; - static unsigned char np_address[] = "."; - static unsigned char np_endpoint[] = "\\pipe\\wine_rpc_test"; - static unsigned char lrpc_endpoint[] = "wine_rpc_test"; - UuidConversionAndComparison(); TestDceErrorInqText(); test_rpc_ncacn_ip_tcp(); @@ -845,8 +783,6 @@ START_TEST( rpc ) test_I_RpcMapWin32Status(); test_RpcStringBindingParseA(); test_I_RpcExceptionFilter(); - test_endpoint_mapper(ncacn_np, np_address, np_endpoint); - test_endpoint_mapper(ncalrpc, NULL, lrpc_endpoint); test_RpcStringBindingFromBinding(); test_UuidCreate(); } diff --git a/dlls/rpcrt4/tests/rpc_protseq.c b/dlls/rpcrt4/tests/rpc_protseq.c new file mode 100644 index 00000000000..a4589d6f157 --- /dev/null +++ b/dlls/rpcrt4/tests/rpc_protseq.c @@ -0,0 +1,208 @@ +/* + * RPC Protocol Sequence Server Tests + * + * Copyright 2008-2009 Robert Shearman + * + * 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 + +#include "wine/test.h" +#include +#include +#include +#include + +#include "rpc.h" +#include "rpcdce.h" + +static void test_RpcServerUseProtseq(void) +{ + RPC_STATUS status; + RPC_BINDING_VECTOR *bindings; + ULONG i; + ULONG binding_count_before; + ULONG binding_count_after1; + ULONG binding_count_after2; + ULONG endpoints_registered = 0; + static unsigned char iptcp[] = "ncacn_ip_tcp"; + static unsigned char np[] = "ncacn_np"; + static unsigned char ncalrpc[] = "ncalrpc"; + + /* show that RpcServerUseProtseqEp(..., NULL, ...) isn't the same as + * RpcServerUseProtseq(...) */ + status = RpcServerUseProtseqEp(ncalrpc, 0, NULL, NULL); + todo_wine + ok(status == RPC_S_INVALID_ENDPOINT_FORMAT, + "RpcServerUseProtseqEp with NULL endpoint should have failed with " + "RPC_S_INVALID_ENDPOINT_FORMAT instead of %d\n", status); + + status = RpcServerInqBindings(&bindings); + if (status == RPC_S_NO_BINDINGS) + binding_count_before = 0; + else + { + binding_count_before = bindings->Count; + ok(status == RPC_S_OK, "RpcServerInqBindings failed with status %d\n", status); + RpcBindingVectorFree(&bindings); + } + + /* register protocol sequences without explicit endpoints */ + status = RpcServerUseProtseq(np, 0, NULL); + if (status == RPC_S_PROTSEQ_NOT_SUPPORTED) + win_skip("ncacn_np not supported\n"); + else + ok(status == RPC_S_OK, "RpcServerUseProtseq(ncacn_np) failed with status %d\n", status); + if (status == RPC_S_OK) endpoints_registered++; + + status = RpcServerUseProtseq(iptcp, 0, NULL); + todo_wine + ok(status == RPC_S_OK, "RpcServerUseProtseq(ncacn_ip_tcp) failed with status %d\n", status); + if (status == RPC_S_OK) endpoints_registered++; + + status = RpcServerUseProtseq(ncalrpc, 0, NULL); + ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncalrpc) failed with status %d\n", status); + if (status == RPC_S_OK) endpoints_registered++; + + status = RpcServerInqBindings(&bindings); + ok(status == RPC_S_OK, "RpcServerInqBindings failed with status %d\n", status); + binding_count_after1 = bindings->Count; + ok(binding_count_after1 == binding_count_before + endpoints_registered, + "wrong binding count - before: %u, after %u, endpoints registered %u\n", + binding_count_before, binding_count_after1, endpoints_registered); + for (i = 0; i < bindings->Count; i++) + { + RPC_CSTR str_bind; + status = RpcBindingToStringBinding(bindings->BindingH[i], &str_bind); + ok(status == RPC_S_OK, "RpcBindingToStringBinding failed with status %d\n", status); + trace("string binding: %s\n", str_bind); + RpcStringFree(&str_bind); + } + RpcBindingVectorFree(&bindings); + + /* re-register - endpoints should be reused */ + status = RpcServerUseProtseq(np, 0, NULL); + if (status == RPC_S_PROTSEQ_NOT_SUPPORTED) + win_skip("ncacn_np not supported\n"); + else + ok(status == RPC_S_OK, "RpcServerUseProtseq(ncacn_np) failed with status %d\n", status); + + status = RpcServerUseProtseq(iptcp, 0, NULL); + todo_wine + ok(status == RPC_S_OK, "RpcServerUseProtseq(ncacn_ip_tcp) failed with status %d\n", status); + + status = RpcServerUseProtseq(ncalrpc, 0, NULL); + ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncalrpc) failed with status %d\n", status); + + status = RpcServerInqBindings(&bindings); + ok(status == RPC_S_OK, "RpcServerInqBindings failed with status %d\n", status); + binding_count_after2 = bindings->Count; + todo_wine + ok(binding_count_after2 == binding_count_after1, + "bindings should have been re-used - after1: %u after2: %u\n", + binding_count_after1, binding_count_after2); + RpcBindingVectorFree(&bindings); +} + +static RPC_DISPATCH_FUNCTION IFoo_table[] = +{ + 0 +}; + +static RPC_DISPATCH_TABLE IFoo_v0_0_DispatchTable = +{ + 0, + IFoo_table +}; + +static const RPC_SERVER_INTERFACE IFoo___RpcServerInterface = +{ + sizeof(RPC_SERVER_INTERFACE), + {{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x34}},{0,0}}, + {{0x8a885d04,0x1ceb,0x11c9,{0x9f,0xe8,0x08,0x00,0x2b,0x10,0x48,0x60}},{2,0}}, + &IFoo_v0_0_DispatchTable, + 0, + 0, + 0, + 0, + 0, +}; + +static RPC_IF_HANDLE IFoo_v0_0_s_ifspec = (RPC_IF_HANDLE)& IFoo___RpcServerInterface; + +static void test_endpoint_mapper(RPC_CSTR protseq, RPC_CSTR address) +{ + static unsigned char annotation[] = "Test annotation string."; + RPC_STATUS status; + RPC_BINDING_VECTOR *binding_vector; + handle_t handle; + unsigned char *binding; + + status = RpcServerRegisterIf(IFoo_v0_0_s_ifspec, NULL, NULL); + ok(status == RPC_S_OK, "%s: RpcServerRegisterIf failed (%u)\n", protseq, status); + + status = RpcServerInqBindings(&binding_vector); + ok(status == RPC_S_OK, "%s: RpcServerInqBindings failed with error %u\n", protseq, status); + + /* register endpoints created in test_RpcServerUseProtseq */ + status = RpcEpRegisterA(IFoo_v0_0_s_ifspec, binding_vector, NULL, annotation); + ok(status == RPC_S_OK, "%s: RpcEpRegisterA failed with error %u\n", protseq, status); + + status = RpcStringBindingCompose(NULL, protseq, address, + NULL, NULL, &binding); + ok(status == RPC_S_OK, "%s: RpcStringBindingCompose failed (%u)\n", protseq, status); + + status = RpcBindingFromStringBinding(binding, &handle); + ok(status == RPC_S_OK, "%s: RpcBindingFromStringBinding failed (%u)\n", protseq, status); + + RpcStringFree(&binding); + + status = RpcBindingReset(handle); + ok(status == RPC_S_OK, "%s: RpcBindingReset failed with error %u\n", protseq, status); + + RpcStringFree(&binding); + + status = RpcEpResolveBinding(handle, IFoo_v0_0_s_ifspec); + ok(status == RPC_S_OK || broken(status == RPC_S_SERVER_UNAVAILABLE), /* win9x */ + "%s: RpcEpResolveBinding failed with error %u\n", protseq, status); + + status = RpcBindingReset(handle); + ok(status == RPC_S_OK, "%s: RpcBindingReset failed with error %u\n", protseq, status); + + status = RpcBindingFree(&handle); + ok(status == RPC_S_OK, "%s: RpcBindingFree failed with error %u\n", protseq, status); + + status = RpcServerUnregisterIf(NULL, NULL, FALSE); + ok(status == RPC_S_OK, "%s: RpcServerUnregisterIf failed (%u)\n", protseq, status); + + status = RpcEpUnregister(IFoo_v0_0_s_ifspec, binding_vector, NULL); + ok(status == RPC_S_OK, "%s: RpcEpUnregisterA failed with error %u\n", protseq, status); + + status = RpcBindingVectorFree(&binding_vector); + ok(status == RPC_S_OK, "%s: RpcBindingVectorFree failed with error %u\n", protseq, status); +} + +START_TEST( rpc_protseq ) +{ + static unsigned char ncacn_np[] = "ncacn_np"; + static unsigned char ncalrpc[] = "ncalrpc"; + static unsigned char np_address[] = "."; + + test_RpcServerUseProtseq(); + test_endpoint_mapper(ncacn_np, np_address); + test_endpoint_mapper(ncalrpc, NULL); +}