mirror of
https://github.com/solemnwarning/directplay-lite
synced 2024-12-30 16:45:37 +01:00
Address handling improvements.
- IDirectPlay8Peer::EnumHosts() requires a device address to specify the service provider to emulate. - IDirectPlay8Peer::EnumHosts() allows overriding the address/port that discovery messages are sent to. - IDirectPlay8Peer::Host() requires at least one address. Addresses with different service providers are not supported yet. - Implement IDirectPlay8Peer::GetPeerAddress() method. - Populate pAddressSender in DPNMSG_ENUM_HOSTS_QUERY message. - Popupate pAddressPlayer in DPNMSG_INDICATE_CONNECT message. - Base host addresses created by IDirectPlay8Peer on service provider of device address given to Host() method.
This commit is contained in:
parent
f8ee41f365
commit
b1289366be
@ -1,3 +1,5 @@
|
||||
#include <winsock2.h>
|
||||
#include <assert.h>
|
||||
#include <atomic>
|
||||
#include <dplay8.h>
|
||||
#include <objbase.h>
|
||||
@ -5,6 +7,7 @@
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#include "DirectPlay8Address.hpp"
|
||||
#include "Log.hpp"
|
||||
@ -34,6 +37,55 @@ DirectPlay8Address::~DirectPlay8Address()
|
||||
clear_components();
|
||||
}
|
||||
|
||||
/* Construct a DirectPlay8Address which represents a host address.
|
||||
*
|
||||
* service_provider must be CLSID_DP8SP_TCPIP or CLSID_DP8SP_IPX.
|
||||
* sa must be an IPv4 address with a valid IP and port.
|
||||
*/
|
||||
DirectPlay8Address *DirectPlay8Address::create_host_address(std::atomic<unsigned int> *global_refcount, GUID service_provider, const struct sockaddr *sa)
|
||||
{
|
||||
assert(service_provider == CLSID_DP8SP_TCPIP || service_provider == CLSID_DP8SP_IPX);
|
||||
assert(sa->sa_family == AF_INET);
|
||||
|
||||
const struct sockaddr_in *sa_v4 = (const struct sockaddr_in*)(sa);
|
||||
|
||||
DirectPlay8Address *address = new DirectPlay8Address(global_refcount);
|
||||
address->SetSP(&service_provider);
|
||||
|
||||
if(service_provider == CLSID_DP8SP_TCPIP)
|
||||
{
|
||||
/* TCP/IP service provider, just stick the IP in the hostname field. */
|
||||
|
||||
char hostname[16];
|
||||
inet_ntop(AF_INET, &(sa_v4->sin_addr), hostname, sizeof(hostname));
|
||||
|
||||
address->AddComponent(DPNA_KEY_HOSTNAME,
|
||||
hostname, strlen(hostname) + 1, DPNA_DATATYPE_STRING_ANSI);
|
||||
}
|
||||
else if(service_provider == CLSID_DP8SP_IPX)
|
||||
{
|
||||
/* IPX service provider.
|
||||
*
|
||||
* Network address is all zeros.
|
||||
* Host address is IP address preceeded by two zero bytes.
|
||||
*/
|
||||
|
||||
uint32_t ipaddr_he = ntohl(sa_v4->sin_addr.s_addr);
|
||||
|
||||
char hostname[32];
|
||||
snprintf(hostname, sizeof(hostname), "00000000,0000%08X", (unsigned)(ipaddr_he));
|
||||
|
||||
address->AddComponent(DPNA_KEY_HOSTNAME,
|
||||
hostname, strlen(hostname) + 1, DPNA_DATATYPE_STRING_ANSI);
|
||||
}
|
||||
|
||||
DWORD port_dw = ntohs(sa_v4->sin_port);
|
||||
|
||||
address->AddComponent(DPNA_KEY_PORT, &port_dw, sizeof(port_dw), DPNA_DATATYPE_DWORD);
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
void DirectPlay8Address::clear_components()
|
||||
{
|
||||
for(auto c = components.begin(); c != components.end(); ++c)
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef DPLITE_DIRECTPLAY8ADDRESS_HPP
|
||||
#define DPLITE_DIRECTPLAY8ADDRESS_HPP
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <atomic>
|
||||
#include <dplay8.h>
|
||||
#include <objbase.h>
|
||||
@ -69,6 +70,8 @@ class DirectPlay8Address: public IDirectPlay8Address
|
||||
DirectPlay8Address(const DirectPlay8Address &src);
|
||||
virtual ~DirectPlay8Address();
|
||||
|
||||
static DirectPlay8Address *create_host_address(std::atomic<unsigned int> *global_refcount, GUID service_provider, const struct sockaddr *sa);
|
||||
|
||||
/* IUnknown */
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override;
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef() override;
|
||||
|
@ -672,6 +672,11 @@ HRESULT DirectPlay8Peer::Host(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, IDir
|
||||
/* Not supported yet. */
|
||||
}
|
||||
|
||||
if(cDeviceInfo == 0)
|
||||
{
|
||||
return DPNERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* Generate a random GUID for this session. */
|
||||
HRESULT guid_err = CoCreateGuid(&instance_guid);
|
||||
if(guid_err != S_OK)
|
||||
@ -700,6 +705,7 @@ HRESULT DirectPlay8Peer::Host(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, IDir
|
||||
(unsigned char*)(pdnAppDesc->pvApplicationReservedData) + pdnAppDesc->dwApplicationReservedDataSize);
|
||||
}
|
||||
|
||||
GUID sp = GUID_NULL;
|
||||
uint32_t ipaddr = htonl(INADDR_ANY);
|
||||
uint16_t port = 0;
|
||||
|
||||
@ -707,6 +713,26 @@ HRESULT DirectPlay8Peer::Host(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, IDir
|
||||
{
|
||||
DirectPlay8Address *addr = (DirectPlay8Address*)(prgpDeviceInfo[i]);
|
||||
|
||||
GUID this_sp;
|
||||
if(addr->GetSP(&this_sp) != S_OK)
|
||||
{
|
||||
return DPNERR_INVALIDDEVICEADDRESS;
|
||||
}
|
||||
|
||||
if(sp != GUID_NULL && this_sp != sp)
|
||||
{
|
||||
/* Multiple service providers specified, don't support this yet. */
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if(this_sp != CLSID_DP8SP_TCPIP && this_sp != CLSID_DP8SP_IPX)
|
||||
{
|
||||
/* Only support TCP/IP and IPX addresses at this time. */
|
||||
return DPNERR_INVALIDDEVICEADDRESS;
|
||||
}
|
||||
|
||||
sp = this_sp;
|
||||
|
||||
DWORD addr_port_value;
|
||||
DWORD addr_port_size = sizeof(addr_port_value);
|
||||
DWORD addr_port_type;
|
||||
@ -725,6 +751,8 @@ HRESULT DirectPlay8Peer::Host(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, IDir
|
||||
}
|
||||
}
|
||||
|
||||
service_provider = sp;
|
||||
|
||||
if(port == 0)
|
||||
{
|
||||
for(int p = AUTO_PORT_MIN; p <= AUTO_PORT_MAX; ++p)
|
||||
@ -1274,7 +1302,22 @@ HRESULT DirectPlay8Peer::GetPeerInfo(CONST DPNID dpnid, DPN_PLAYER_INFO* CONST p
|
||||
|
||||
HRESULT DirectPlay8Peer::GetPeerAddress(CONST DPNID dpnid, IDirectPlay8Address** CONST pAddress, CONST DWORD dwFlags)
|
||||
{
|
||||
UNIMPLEMENTED("DirectPlay8Peer::GetPeerAddress");
|
||||
std::unique_lock<std::mutex> l(lock);
|
||||
|
||||
Peer *peer = get_peer_by_player_id(dpnid);
|
||||
if(peer == NULL)
|
||||
{
|
||||
return DPNERR_INVALIDPLAYER;
|
||||
}
|
||||
|
||||
struct sockaddr_in sa;
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr.s_addr = peer->ip;
|
||||
sa.sin_port = htons(peer->port);
|
||||
|
||||
*pAddress = DirectPlay8Address::create_host_address(global_refcount, service_provider, (struct sockaddr*)(&sa));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectPlay8Peer::GetLocalHostAddresses(IDirectPlay8Address** CONST prgpAddress, DWORD* CONST pcAddress, CONST DWORD dwFlags)
|
||||
@ -2245,8 +2288,11 @@ void DirectPlay8Peer::handle_host_enum_request(std::unique_lock<std::mutex> &l,
|
||||
DPNMSG_ENUM_HOSTS_QUERY ehq;
|
||||
memset(&ehq, 0, sizeof(ehq));
|
||||
|
||||
DirectPlay8Address *sender_address = DirectPlay8Address::create_host_address(
|
||||
global_refcount, service_provider, (struct sockaddr*)(from_addr));
|
||||
|
||||
ehq.dwSize = sizeof(ehq);
|
||||
ehq.pAddressSender = NULL; // TODO
|
||||
ehq.pAddressSender = sender_address;
|
||||
ehq.pAddressDevice = NULL; // TODO
|
||||
|
||||
if(!pd.is_null(1))
|
||||
@ -2265,6 +2311,8 @@ void DirectPlay8Peer::handle_host_enum_request(std::unique_lock<std::mutex> &l,
|
||||
HRESULT ehq_result = message_handler(message_handler_ctx, DPN_MSGID_ENUM_HOSTS_QUERY, &ehq);
|
||||
l.lock();
|
||||
|
||||
sender_address->Release();
|
||||
|
||||
std::vector<unsigned char> response_data_buffer;
|
||||
if(ehq.dwResponseDataSize > 0)
|
||||
{
|
||||
@ -2413,7 +2461,15 @@ void DirectPlay8Peer::handle_host_connect_request(std::unique_lock<std::mutex> &
|
||||
ic.dwUserConnectDataSize = d.second;
|
||||
}
|
||||
|
||||
ic.pAddressPlayer = NULL; /* TODO */
|
||||
struct sockaddr_in peer_sa;
|
||||
peer_sa.sin_family = AF_INET;
|
||||
peer_sa.sin_addr.s_addr = peer->ip;
|
||||
peer_sa.sin_port = htons(peer->port);
|
||||
|
||||
DirectPlay8Address *peer_address = DirectPlay8Address::create_host_address(
|
||||
global_refcount, service_provider, (struct sockaddr*)(&peer_sa));
|
||||
|
||||
ic.pAddressPlayer = peer_address;
|
||||
ic.pAddressDevice = NULL; /* TODO */
|
||||
|
||||
peer->state = Peer::PS_INDICATING;
|
||||
@ -2422,6 +2478,8 @@ void DirectPlay8Peer::handle_host_connect_request(std::unique_lock<std::mutex> &
|
||||
HRESULT ic_result = message_handler(message_handler_ctx, DPN_MSGID_INDICATE_CONNECT, &ic);
|
||||
l.lock();
|
||||
|
||||
peer_address->Release();
|
||||
|
||||
std::vector<unsigned char> reply_data_buffer;
|
||||
if(ic.dwReplyDataSize > 0)
|
||||
{
|
||||
|
@ -47,6 +47,8 @@ class DirectPlay8Peer: public IDirectPlay8Peer
|
||||
std::wstring password;
|
||||
std::vector<unsigned char> application_data;
|
||||
|
||||
GUID service_provider;
|
||||
|
||||
/* Local IP and port for all our sockets, except discovery_socket. */
|
||||
uint32_t local_ip;
|
||||
uint16_t local_port;
|
||||
|
@ -1,7 +1,9 @@
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <stdio.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#include "COMAPIException.hpp"
|
||||
#include "DirectPlay8Address.hpp"
|
||||
#include "HostEnumerator.hpp"
|
||||
#include "Messages.hpp"
|
||||
@ -35,13 +37,88 @@ HostEnumerator::HostEnumerator(
|
||||
next_tx_at(0),
|
||||
req_cancel(false)
|
||||
{
|
||||
/* TODO: Use address in pdpaddrHost, if provided. */
|
||||
if(pdpaddrDeviceInfo == NULL)
|
||||
{
|
||||
throw COMAPIException(DPNERR_INVALIDPARAM);
|
||||
}
|
||||
|
||||
if(pdpaddrDeviceInfo->GetSP(&service_provider) != S_OK)
|
||||
{
|
||||
throw COMAPIException(DPNERR_INVALIDDEVICEADDRESS);
|
||||
}
|
||||
|
||||
memset(&send_addr, 0, sizeof(send_addr));
|
||||
send_addr.sin_family = AF_INET;
|
||||
send_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
||||
send_addr.sin_port = htons(DISCOVERY_PORT);
|
||||
|
||||
if(pdpaddrHost != NULL)
|
||||
{
|
||||
GUID host_sp;
|
||||
if(pdpaddrHost->GetSP(&host_sp) != S_OK)
|
||||
{
|
||||
throw COMAPIException(DPNERR_INVALIDHOSTADDRESS);
|
||||
}
|
||||
|
||||
if(host_sp != service_provider)
|
||||
{
|
||||
/* Service Provider in host address must match device address. */
|
||||
throw COMAPIException(DPNERR_INVALIDPARAM);
|
||||
}
|
||||
|
||||
/* Hostname component overrides discovery address, if provided. */
|
||||
|
||||
wchar_t hostname_value[128];
|
||||
DWORD hostname_size = sizeof(hostname_value);
|
||||
DWORD hostname_type;
|
||||
|
||||
if(pdpaddrHost->GetComponentByName(DPNA_KEY_HOSTNAME, hostname_value, &hostname_size, &hostname_type) == S_OK)
|
||||
{
|
||||
if(hostname_type != DPNA_DATATYPE_STRING)
|
||||
{
|
||||
throw COMAPIException(DPNERR_INVALIDHOSTADDRESS);
|
||||
}
|
||||
|
||||
if(host_sp == CLSID_DP8SP_TCPIP)
|
||||
{
|
||||
struct in_addr hostname_addr;
|
||||
if(InetPtonW(AF_INET, hostname_value, &hostname_addr) == 1)
|
||||
{
|
||||
send_addr.sin_addr = hostname_addr;
|
||||
}
|
||||
else{
|
||||
throw COMAPIException(DPNERR_INVALIDHOSTADDRESS);
|
||||
}
|
||||
}
|
||||
else if(host_sp == CLSID_DP8SP_IPX)
|
||||
{
|
||||
unsigned ip;
|
||||
if(swscanf(hostname_value, L"00000000,0000%08X", &ip) != 1)
|
||||
{
|
||||
throw COMAPIException(DPNERR_INVALIDHOSTADDRESS);
|
||||
}
|
||||
|
||||
send_addr.sin_addr.s_addr = htonl(ip);
|
||||
}
|
||||
}
|
||||
|
||||
/* Port component overrides discovery port, if provided. */
|
||||
|
||||
DWORD port_value;
|
||||
DWORD port_size = sizeof(port_value);
|
||||
DWORD port_type;
|
||||
|
||||
if(pdpaddrHost->GetComponentByName(DPNA_KEY_PORT, &port_value, &port_size, &port_type) == S_OK)
|
||||
{
|
||||
if(port_type != DPNA_DATATYPE_DWORD || port_value > 65535)
|
||||
{
|
||||
throw COMAPIException(DPNERR_INVALIDHOSTADDRESS);
|
||||
}
|
||||
|
||||
send_addr.sin_port = htons(port_value);
|
||||
}
|
||||
}
|
||||
|
||||
if(pApplicationDesc != NULL)
|
||||
{
|
||||
application_guid = pApplicationDesc->guidApplication;
|
||||
@ -248,26 +325,15 @@ void HostEnumerator::handle_packet(const void *data, size_t size, struct sockadd
|
||||
* port for the host.
|
||||
*/
|
||||
|
||||
IDirectPlay8Address *sender_address = new DirectPlay8Address(global_refcount);
|
||||
sender_address->SetSP(&CLSID_DP8SP_TCPIP); /* TODO: Be IPX if application previously gave us an IPX address? */
|
||||
|
||||
char from_addr_ip_s[16];
|
||||
inet_ntop(AF_INET, &(from_addr->sin_addr), from_addr_ip_s, sizeof(from_addr_ip_s));
|
||||
|
||||
sender_address->AddComponent(DPNA_KEY_HOSTNAME,
|
||||
from_addr_ip_s, strlen(from_addr_ip_s) + 1, DPNA_DATATYPE_STRING_ANSI);
|
||||
|
||||
DWORD from_port_dw = ntohs(from_addr->sin_port);
|
||||
|
||||
sender_address->AddComponent(DPNA_KEY_PORT,
|
||||
&from_port_dw, sizeof(from_port_dw), DPNA_DATATYPE_DWORD);
|
||||
IDirectPlay8Address *sender_address = DirectPlay8Address::create_host_address(
|
||||
global_refcount, service_provider, (struct sockaddr*)(from_addr));
|
||||
|
||||
/* Build a DirectPlay8Address with the interface we received the response on.
|
||||
* TODO: Actually do this.
|
||||
*/
|
||||
|
||||
IDirectPlay8Address *device_address = new DirectPlay8Address(global_refcount);
|
||||
device_address->SetSP(&CLSID_DP8SP_TCPIP); /* TODO: Be IPX if application previously gave us an IPX address? */
|
||||
device_address->SetSP(&service_provider);
|
||||
|
||||
DPNMSG_ENUM_HOSTS_RESPONSE message;
|
||||
memset(&message, 0, sizeof(message));
|
||||
|
@ -29,6 +29,7 @@ class HostEnumerator
|
||||
|
||||
std::function<void(HRESULT)> complete_cb;
|
||||
|
||||
GUID service_provider;
|
||||
struct sockaddr_in send_addr;
|
||||
|
||||
GUID application_guid; /* GUID of application to search for, or GUID_NULL */
|
||||
|
@ -136,7 +136,12 @@ struct SessionHost
|
||||
app_desc.guidApplication = application_guid;
|
||||
app_desc.pwszSessionName = (wchar_t*)(session_description);
|
||||
|
||||
if(dp8p->Host(&app_desc, NULL, 0, NULL, NULL, (void*)(0xB00), 0) != S_OK)
|
||||
IDP8AddressInstance address;
|
||||
address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||
|
||||
IDirectPlay8Address *addresses[] = { address };
|
||||
|
||||
if(dp8p->Host(&app_desc, addresses, 1, NULL, NULL, (void*)(0xB00), 0) != S_OK)
|
||||
{
|
||||
throw std::runtime_error("DirectPlay8Peer::Host failed");
|
||||
}
|
||||
@ -338,12 +343,15 @@ TEST(DirectPlay8Peer, EnumHostsSync)
|
||||
|
||||
ASSERT_EQ(client->Initialize(&client_cb, &callback_shim, 0), S_OK);
|
||||
|
||||
IDP8AddressInstance device_address;
|
||||
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||
|
||||
DWORD start = GetTickCount();
|
||||
|
||||
ASSERT_EQ(client->EnumHosts(
|
||||
NULL, /* pApplicationDesc */
|
||||
NULL, /* pdpaddrHost */
|
||||
NULL, /* pdpaddrDeviceInfo */
|
||||
device_address, /* pdpaddrDeviceInfo */
|
||||
NULL, /* pvUserEnumData */
|
||||
0, /* dwUserEnumDataSize */
|
||||
3, /* dwEnumCount */
|
||||
@ -423,12 +431,15 @@ TEST(DirectPlay8Peer, EnumHostsAsync)
|
||||
|
||||
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
||||
|
||||
IDP8AddressInstance device_address;
|
||||
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||
|
||||
DWORD start = GetTickCount();
|
||||
|
||||
ASSERT_EQ(client->EnumHosts(
|
||||
NULL, /* pApplicationDesc */
|
||||
NULL, /* pdpaddrHost */
|
||||
NULL, /* pdpaddrDeviceInfo */
|
||||
device_address, /* pdpaddrDeviceInfo */
|
||||
NULL, /* pvUserEnumData */
|
||||
0, /* dwUserEnumDataSize */
|
||||
3, /* dwEnumCount */
|
||||
@ -492,12 +503,15 @@ TEST(DirectPlay8Peer, EnumHostsAsyncCancelByHandle)
|
||||
|
||||
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
||||
|
||||
IDP8AddressInstance device_address;
|
||||
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||
|
||||
DWORD start = GetTickCount();
|
||||
|
||||
ASSERT_EQ(client->EnumHosts(
|
||||
NULL, /* pApplicationDesc */
|
||||
NULL, /* pdpaddrHost */
|
||||
NULL, /* pdpaddrDeviceInfo */
|
||||
device_address, /* pdpaddrDeviceInfo */
|
||||
NULL, /* pvUserEnumData */
|
||||
0, /* dwUserEnumDataSize */
|
||||
3, /* dwEnumCount */
|
||||
@ -555,12 +569,15 @@ TEST(DirectPlay8Peer, EnumHostsAsyncCancelAllEnums)
|
||||
|
||||
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
||||
|
||||
IDP8AddressInstance device_address;
|
||||
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||
|
||||
DWORD start = GetTickCount();
|
||||
|
||||
ASSERT_EQ(client->EnumHosts(
|
||||
NULL, /* pApplicationDesc */
|
||||
NULL, /* pdpaddrHost */
|
||||
NULL, /* pdpaddrDeviceInfo */
|
||||
device_address, /* pdpaddrDeviceInfo */
|
||||
NULL, /* pvUserEnumData */
|
||||
0, /* dwUserEnumDataSize */
|
||||
3, /* dwEnumCount */
|
||||
@ -618,12 +635,15 @@ TEST(DirectPlay8Peer, EnumHostsAsyncCancelAllOperations)
|
||||
|
||||
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
||||
|
||||
IDP8AddressInstance device_address;
|
||||
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||
|
||||
DWORD start = GetTickCount();
|
||||
|
||||
ASSERT_EQ(client->EnumHosts(
|
||||
NULL, /* pApplicationDesc */
|
||||
NULL, /* pdpaddrHost */
|
||||
NULL, /* pdpaddrDeviceInfo */
|
||||
device_address, /* pdpaddrDeviceInfo */
|
||||
NULL, /* pvUserEnumData */
|
||||
0, /* dwUserEnumDataSize */
|
||||
3, /* dwEnumCount */
|
||||
@ -681,12 +701,15 @@ TEST(DirectPlay8Peer, EnumHostsAsyncCancelByClose)
|
||||
|
||||
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
||||
|
||||
IDP8AddressInstance device_address;
|
||||
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||
|
||||
DWORD start = GetTickCount();
|
||||
|
||||
ASSERT_EQ(client->EnumHosts(
|
||||
NULL, /* pApplicationDesc */
|
||||
NULL, /* pdpaddrHost */
|
||||
NULL, /* pdpaddrDeviceInfo */
|
||||
device_address, /* pdpaddrDeviceInfo */
|
||||
NULL, /* pvUserEnumData */
|
||||
0, /* dwUserEnumDataSize */
|
||||
3, /* dwEnumCount */
|
||||
@ -794,10 +817,13 @@ TEST(DirectPlay8Peer, EnumHostsFilterByApplicationGUID)
|
||||
app_desc.dwSize = sizeof(app_desc);
|
||||
app_desc.guidApplication = APP_GUID_2;
|
||||
|
||||
IDP8AddressInstance device_address;
|
||||
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||
|
||||
ASSERT_EQ(client->EnumHosts(
|
||||
&app_desc, /* pApplicationDesc */
|
||||
NULL, /* pdpaddrHost */
|
||||
NULL, /* pdpaddrDeviceInfo */
|
||||
device_address, /* pdpaddrDeviceInfo */
|
||||
NULL, /* pvUserEnumData */
|
||||
0, /* dwUserEnumDataSize */
|
||||
3, /* dwEnumCount */
|
||||
@ -857,10 +883,13 @@ TEST(DirectPlay8Peer, EnumHostsFilterByNULLApplicationGUID)
|
||||
app_desc.dwSize = sizeof(app_desc);
|
||||
app_desc.guidApplication = GUID_NULL;
|
||||
|
||||
IDP8AddressInstance device_address;
|
||||
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||
|
||||
ASSERT_EQ(client->EnumHosts(
|
||||
&app_desc, /* pApplicationDesc */
|
||||
NULL, /* pdpaddrHost */
|
||||
NULL, /* pdpaddrDeviceInfo */
|
||||
device_address, /* pdpaddrDeviceInfo */
|
||||
NULL, /* pvUserEnumData */
|
||||
0, /* dwUserEnumDataSize */
|
||||
3, /* dwEnumCount */
|
||||
@ -939,10 +968,13 @@ TEST(DirectPlay8Peer, EnumHostsDataInQuery)
|
||||
|
||||
ASSERT_EQ(client->Initialize(&client_cb, &callback_shim, 0), S_OK);
|
||||
|
||||
IDP8AddressInstance device_address;
|
||||
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||
|
||||
ASSERT_EQ(client->EnumHosts(
|
||||
NULL, /* pApplicationDesc */
|
||||
NULL, /* pdpaddrHost */
|
||||
NULL, /* pdpaddrDeviceInfo */
|
||||
device_address, /* pdpaddrDeviceInfo */
|
||||
(void*)(DATA), /* pvUserEnumData */
|
||||
sizeof(DATA), /* dwUserEnumDataSize */
|
||||
3, /* dwEnumCount */
|
||||
@ -1036,10 +1068,13 @@ TEST(DirectPlay8Peer, EnumHostsDataInResponse)
|
||||
|
||||
ASSERT_EQ(client->Initialize(&client_cb, &callback_shim, 0), S_OK);
|
||||
|
||||
IDP8AddressInstance device_address;
|
||||
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||
|
||||
ASSERT_EQ(client->EnumHosts(
|
||||
NULL, /* pApplicationDesc */
|
||||
NULL, /* pdpaddrHost */
|
||||
NULL, /* pdpaddrDeviceInfo */
|
||||
device_address, /* pdpaddrDeviceInfo */
|
||||
NULL, /* pvUserEnumData */
|
||||
0, /* dwUserEnumDataSize */
|
||||
3, /* dwEnumCount */
|
||||
@ -1059,7 +1094,60 @@ TEST(DirectPlay8Peer, EnumHostsDataInResponse)
|
||||
EXPECT_TRUE(got_return_buffer);
|
||||
}
|
||||
|
||||
/* TODO: Test enumerating a session directly. */
|
||||
TEST(DirectPlay8Peer, EnumHostsSpecifyPort)
|
||||
{
|
||||
SessionHost a1s1(APP_GUID_1, L"Application 1 Session 1", PORT);
|
||||
SessionHost a1s2(APP_GUID_1, L"Application 1 Session 2", PORT + 1);
|
||||
|
||||
std::map<GUID, FoundSession, CompareGUID> sessions;
|
||||
|
||||
std::function<HRESULT(DWORD,PVOID)> client_cb =
|
||||
[&sessions]
|
||||
(DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
if(dwMessageType == DPN_MSGID_ENUM_HOSTS_RESPONSE)
|
||||
{
|
||||
DPNMSG_ENUM_HOSTS_RESPONSE *ehr = (DPNMSG_ENUM_HOSTS_RESPONSE*)(pMessage);
|
||||
|
||||
sessions.emplace(
|
||||
ehr->pApplicationDescription->guidInstance,
|
||||
FoundSession(
|
||||
ehr->pApplicationDescription->guidApplication,
|
||||
ehr->pApplicationDescription->pwszSessionName));
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
};
|
||||
|
||||
IDP8PeerInstance client;
|
||||
|
||||
ASSERT_EQ(client->Initialize(&client_cb, &callback_shim, 0), S_OK);
|
||||
|
||||
IDP8AddressInstance host_address(L"127.0.0.1", PORT);
|
||||
|
||||
IDP8AddressInstance device_address;
|
||||
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||
|
||||
ASSERT_EQ(client->EnumHosts(
|
||||
NULL, /* pApplicationDesc */
|
||||
host_address, /* pdpaddrHost */
|
||||
device_address, /* pdpaddrDeviceInfo */
|
||||
NULL, /* pvUserEnumData */
|
||||
0, /* dwUserEnumDataSize */
|
||||
3, /* dwEnumCount */
|
||||
500, /* dwRetryInterval */
|
||||
500, /* dwTimeOut*/
|
||||
NULL, /* pvUserContext */
|
||||
NULL, /* pAsyncHandle */
|
||||
DPNENUMHOSTS_SYNC /* dwFlags */
|
||||
), S_OK);
|
||||
|
||||
FoundSession expect_sessions[] = {
|
||||
FoundSession(APP_GUID_1, L"Application 1 Session 1"),
|
||||
};
|
||||
|
||||
EXPECT_SESSIONS(sessions, expect_sessions, expect_sessions + 1);
|
||||
}
|
||||
|
||||
TEST(DirectPlay8Peer, ConnectSync)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user