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); }
void ept_insert(handle_t h, unsigned32 num_ents, ept_entry_t entries[], boolean32 replace, error_status_t *status) { unsigned32 i; RPC_STATUS rpc_status; WINE_TRACE("(%p, %lu, %p, %lu, %p)\n", h, num_ents, entries, replace, status); *status = RPC_S_OK; EnterCriticalSection(&csEpm); for (i = 0; i < num_ents; i++) { struct registered_ept_entry *entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry)); if (!entry) { /* FIXME: cleanup code to delete added entries */ *status = EPT_S_CANT_PERFORM_OP; break; } list_init(&entry->entry); memcpy(entry->annotation, entries[i].annotation, sizeof(entries[i].annotation)); rpc_status = TowerExplode(entries[i].tower, &entry->iface, &entry->syntax, &entry->protseq, &entry->endpoint, &entry->address); if (rpc_status != RPC_S_OK) { WINE_WARN("TowerExplode failed %lu\n", rpc_status); *status = rpc_status; break; /* FIXME: more cleanup? */ } entry->object = entries[i].object; if (replace) { /* FIXME: correct find algorithm */ struct registered_ept_entry *old_entry = find_ept_entry(&entry->iface, &entry->syntax, entry->protseq, entry->endpoint, entry->address, &entry->object); if (old_entry) delete_registered_ept_entry(old_entry); } list_add_tail(®istered_ept_entry_list, &entry->entry); } LeaveCriticalSection(&csEpm); }
void ept_delete(handle_t h, unsigned32 num_ents, ept_entry_t entries[], error_status_t *status) { unsigned32 i; RPC_STATUS rpc_status; *status = RPC_S_OK; WINE_TRACE("(%p, %lu, %p, %p)\n", h, num_ents, entries, status); EnterCriticalSection(&csEpm); for (i = 0; i < num_ents; i++) { struct registered_ept_entry *entry; RPC_SYNTAX_IDENTIFIER iface, syntax; char *protseq; char *endpoint; char *address; rpc_status = TowerExplode(entries[i].tower, &iface, &syntax, &protseq, &endpoint, &address); if (rpc_status != RPC_S_OK) break; entry = find_ept_entry(&iface, &syntax, protseq, endpoint, address, &entries[i].object); if (entry) delete_registered_ept_entry(entry); else { *status = EPT_S_NOT_REGISTERED; break; } I_RpcFree(protseq); I_RpcFree(endpoint); I_RpcFree(address); } LeaveCriticalSection(&csEpm); }
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); }