void ept_map(handle_t h, uuid_p_t object, twr_p_t map_tower, ept_lookup_handle_t *entry_handle, unsigned32 max_towers, unsigned32 *num_towers, twr_p_t *towers, error_status_t *status) { RPC_STATUS rpc_status; RPC_SYNTAX_IDENTIFIER iface, syntax; char *protseq; struct registered_ept_entry *entry; *status = RPC_S_OK; *num_towers = 0; WINE_TRACE("(%p, %p, %p, %p, %lu, %p, %p, %p)\n", h, object, map_tower, entry_handle, max_towers, num_towers, towers, status); rpc_status = TowerExplode(map_tower, &iface, &syntax, &protseq, NULL, NULL); if (rpc_status != RPC_S_OK) { *status = rpc_status; return; } EnterCriticalSection(&csEpm); LIST_FOR_EACH_ENTRY(entry, ®istered_ept_entry_list, struct registered_ept_entry, entry) { if (IsEqualGUID(&entry->iface.SyntaxGUID, &iface.SyntaxGUID) && (entry->iface.SyntaxVersion.MajorVersion == iface.SyntaxVersion.MajorVersion) && (entry->iface.SyntaxVersion.MinorVersion >= iface.SyntaxVersion.MinorVersion) && !memcmp(&entry->syntax, &syntax, sizeof(syntax)) && !strcmp(entry->protseq, protseq) && ((!object && IsEqualGUID(&entry->object, &nil_object)) || IsEqualGUID(object, &entry->object))) { if (*num_towers < max_towers) { rpc_status = TowerConstruct(&entry->iface, &entry->syntax, entry->protseq, entry->endpoint, entry->address, &towers[*num_towers]); if (rpc_status != RPC_S_OK) { *status = rpc_status; break; /* FIXME: more cleanup? */ } } (*num_towers)++; } } LeaveCriticalSection(&csEpm); }
/*********************************************************************** * RpcEpUnregister (RPCRT4.@) */ RPC_STATUS WINAPI RpcEpUnregister( RPC_IF_HANDLE IfSpec, RPC_BINDING_VECTOR *BindingVector, UUID_VECTOR *UuidVector ) { PRPC_SERVER_INTERFACE If = IfSpec; ULONG i; RPC_STATUS status = RPC_S_OK; error_status_t status2; ept_entry_t *entries; handle_t handle; TRACE("(%p,%p,%p)\n", IfSpec, BindingVector, UuidVector); TRACE(" ifid=%s\n", debugstr_guid(&If->InterfaceId.SyntaxGUID)); for (i=0; i<BindingVector->Count; i++) { RpcBinding* bind = BindingVector->BindingH[i]; TRACE(" protseq[%d]=%s\n", i, debugstr_a(bind->Protseq)); TRACE(" endpoint[%d]=%s\n", i, debugstr_a(bind->Endpoint)); } if (UuidVector) { for (i=0; i<UuidVector->Count; i++) TRACE(" obj[%d]=%s\n", i, debugstr_guid(UuidVector->Uuid[i])); } entries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*entries) * BindingVector->Count * (UuidVector ? UuidVector->Count : 1)); if (!entries) return RPC_S_OUT_OF_MEMORY; status = get_epm_handle_server(&handle); if (status != RPC_S_OK) { HeapFree(GetProcessHeap(), 0, entries); return status; } for (i = 0; i < BindingVector->Count; i++) { unsigned j; RpcBinding* bind = BindingVector->BindingH[i]; for (j = 0; j < (UuidVector ? UuidVector->Count : 1); j++) { status = TowerConstruct(&If->InterfaceId, &If->TransferSyntax, bind->Protseq, bind->Endpoint, bind->NetworkAddr, &entries[i*(UuidVector ? UuidVector->Count : 1) + j].tower); if (status != RPC_S_OK) break; if (UuidVector) memcpy(&entries[i * UuidVector->Count + j].object, &UuidVector->Uuid[j], sizeof(GUID)); else memset(&entries[i].object, 0, sizeof(entries[i].object)); } } if (status == RPC_S_OK) { __TRY { ept_insert(handle, BindingVector->Count * (UuidVector ? UuidVector->Count : 1), entries, TRUE, &status2); } __EXCEPT(rpc_filter) { status2 = GetExceptionCode(); } __ENDTRY if (status2 == RPC_S_SERVER_UNAVAILABLE) status2 = EPT_S_NOT_REGISTERED; if (status2 != RPC_S_OK) ERR("ept_insert failed with error %d\n", status2); status = status2; /* FIXME: convert status? */ }
static void test_towers(void) { RPC_STATUS ret; twr_t *tower; static const RPC_SYNTAX_IDENTIFIER mapi_if_id = { { 0xa4f1db00, 0xca47, 0x1067, { 0xb3, 0x1f, 0x00, 0xdd, 0x01, 0x06, 0x62, 0xda } }, { 0, 0 } }; static const RPC_SYNTAX_IDENTIFIER ndr_syntax = { { 0x8a885d04, 0x1ceb, 0x11c9, { 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60 } }, { 2, 0 } }; RPC_SYNTAX_IDENTIFIER object, syntax; char *protseq, *endpoint, *address; BOOL same; ret = TowerConstruct(&mapi_if_id, &ndr_syntax, "ncacn_ip_tcp", "135", "10.0.0.1", &tower); ok(ret == RPC_S_OK || broken(ret == RPC_S_INVALID_RPC_PROTSEQ), /* Vista */ "TowerConstruct failed with error %d\n", ret); if (ret == RPC_S_INVALID_RPC_PROTSEQ) { /* Windows Vista fails with this error and crashes if we continue */ win_skip("TowerConstruct failed, we are most likely on Windows Vista\n"); return; } /* first check we have the right amount of data */ ok(tower->tower_length == sizeof(tower_data_tcp_ip1) || tower->tower_length == sizeof(tower_data_tcp_ip2), "Wrong size of tower %d\n", tower->tower_length); /* then do a byte-by-byte comparison */ same = ((tower->tower_length == sizeof(tower_data_tcp_ip1)) && !memcmp(&tower->tower_octet_string, tower_data_tcp_ip1, sizeof(tower_data_tcp_ip1))) || ((tower->tower_length == sizeof(tower_data_tcp_ip2)) && !memcmp(&tower->tower_octet_string, tower_data_tcp_ip2, sizeof(tower_data_tcp_ip2))); ok(same, "Tower data differs\n"); if (!same) { unsigned32 i; for (i = 0; i < tower->tower_length; i++) { if (i % 8 == 0) printf(" "); printf("0x%02x,", tower->tower_octet_string[i]); if (i % 8 == 7) printf("\n"); } printf("\n"); } ret = TowerExplode(tower, &object, &syntax, &protseq, &endpoint, &address); ok(ret == RPC_S_OK, "TowerExplode failed with error %d\n", ret); ok(!memcmp(&object, &mapi_if_id, sizeof(mapi_if_id)), "object id didn't match\n"); ok(!memcmp(&syntax, &ndr_syntax, sizeof(syntax)), "syntax id didn't match\n"); ok(!strcmp(protseq, "ncacn_ip_tcp"), "protseq was \"%s\" instead of \"ncacn_ip_tcp\"\n", protseq); ok(!strcmp(endpoint, "135"), "endpoint was \"%s\" instead of \"135\"\n", endpoint); ok(!strcmp(address, "10.0.0.1"), "address was \"%s\" instead of \"10.0.0.1\"\n", address); I_RpcFree(protseq); I_RpcFree(endpoint); I_RpcFree(address); ret = TowerExplode(tower, NULL, NULL, NULL, NULL, NULL); ok(ret == RPC_S_OK, "TowerExplode failed with error %d\n", ret); I_RpcFree(tower); /* test the behaviour for ip_tcp with name instead of dotted IP notation */ ret = TowerConstruct(&mapi_if_id, &ndr_syntax, "ncacn_ip_tcp", "135", "localhost", &tower); ok(ret == RPC_S_OK, "TowerConstruct failed with error %d\n", ret); ret = TowerExplode(tower, NULL, NULL, NULL, NULL, &address); ok(ret == RPC_S_OK, "TowerExplode failed with error %d\n", ret); ok(!strcmp(address, "0.0.0.0") || broken(!strcmp(address, "255.255.255.255")), "address was \"%s\" instead of \"0.0.0.0\"\n", address); I_RpcFree(address); I_RpcFree(tower); /* test the behaviour for np with no address */ ret = TowerConstruct(&mapi_if_id, &ndr_syntax, "ncacn_np", "\\pipe\\test", NULL, &tower); ok(ret == RPC_S_OK, "TowerConstruct failed with error %d\n", ret); ret = TowerExplode(tower, NULL, NULL, NULL, NULL, &address); ok(ret == RPC_S_OK || broken(ret != RPC_S_OK), /* win2k, indeterminate */ "TowerExplode failed with error %d\n", ret); /* Windows XP SP3 sets address to NULL */ ok(!address || !strcmp(address, ""), "address was \"%s\" instead of \"\" or NULL (XP SP3)\n", address); I_RpcFree(address); I_RpcFree(tower); }