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 <atomic>
|
||||||
#include <dplay8.h>
|
#include <dplay8.h>
|
||||||
#include <objbase.h>
|
#include <objbase.h>
|
||||||
@ -5,6 +7,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
#include "DirectPlay8Address.hpp"
|
#include "DirectPlay8Address.hpp"
|
||||||
#include "Log.hpp"
|
#include "Log.hpp"
|
||||||
@ -34,6 +37,55 @@ DirectPlay8Address::~DirectPlay8Address()
|
|||||||
clear_components();
|
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()
|
void DirectPlay8Address::clear_components()
|
||||||
{
|
{
|
||||||
for(auto c = components.begin(); c != components.end(); ++c)
|
for(auto c = components.begin(); c != components.end(); ++c)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef DPLITE_DIRECTPLAY8ADDRESS_HPP
|
#ifndef DPLITE_DIRECTPLAY8ADDRESS_HPP
|
||||||
#define DPLITE_DIRECTPLAY8ADDRESS_HPP
|
#define DPLITE_DIRECTPLAY8ADDRESS_HPP
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <dplay8.h>
|
#include <dplay8.h>
|
||||||
#include <objbase.h>
|
#include <objbase.h>
|
||||||
@ -69,6 +70,8 @@ class DirectPlay8Address: public IDirectPlay8Address
|
|||||||
DirectPlay8Address(const DirectPlay8Address &src);
|
DirectPlay8Address(const DirectPlay8Address &src);
|
||||||
virtual ~DirectPlay8Address();
|
virtual ~DirectPlay8Address();
|
||||||
|
|
||||||
|
static DirectPlay8Address *create_host_address(std::atomic<unsigned int> *global_refcount, GUID service_provider, const struct sockaddr *sa);
|
||||||
|
|
||||||
/* IUnknown */
|
/* IUnknown */
|
||||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override;
|
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override;
|
||||||
virtual ULONG STDMETHODCALLTYPE AddRef() override;
|
virtual ULONG STDMETHODCALLTYPE AddRef() override;
|
||||||
|
@ -672,6 +672,11 @@ HRESULT DirectPlay8Peer::Host(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, IDir
|
|||||||
/* Not supported yet. */
|
/* Not supported yet. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(cDeviceInfo == 0)
|
||||||
|
{
|
||||||
|
return DPNERR_INVALIDPARAM;
|
||||||
|
}
|
||||||
|
|
||||||
/* Generate a random GUID for this session. */
|
/* Generate a random GUID for this session. */
|
||||||
HRESULT guid_err = CoCreateGuid(&instance_guid);
|
HRESULT guid_err = CoCreateGuid(&instance_guid);
|
||||||
if(guid_err != S_OK)
|
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);
|
(unsigned char*)(pdnAppDesc->pvApplicationReservedData) + pdnAppDesc->dwApplicationReservedDataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GUID sp = GUID_NULL;
|
||||||
uint32_t ipaddr = htonl(INADDR_ANY);
|
uint32_t ipaddr = htonl(INADDR_ANY);
|
||||||
uint16_t port = 0;
|
uint16_t port = 0;
|
||||||
|
|
||||||
@ -707,6 +713,26 @@ HRESULT DirectPlay8Peer::Host(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, IDir
|
|||||||
{
|
{
|
||||||
DirectPlay8Address *addr = (DirectPlay8Address*)(prgpDeviceInfo[i]);
|
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_value;
|
||||||
DWORD addr_port_size = sizeof(addr_port_value);
|
DWORD addr_port_size = sizeof(addr_port_value);
|
||||||
DWORD addr_port_type;
|
DWORD addr_port_type;
|
||||||
@ -725,6 +751,8 @@ HRESULT DirectPlay8Peer::Host(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, IDir
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
service_provider = sp;
|
||||||
|
|
||||||
if(port == 0)
|
if(port == 0)
|
||||||
{
|
{
|
||||||
for(int p = AUTO_PORT_MIN; p <= AUTO_PORT_MAX; ++p)
|
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)
|
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)
|
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;
|
DPNMSG_ENUM_HOSTS_QUERY ehq;
|
||||||
memset(&ehq, 0, sizeof(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.dwSize = sizeof(ehq);
|
||||||
ehq.pAddressSender = NULL; // TODO
|
ehq.pAddressSender = sender_address;
|
||||||
ehq.pAddressDevice = NULL; // TODO
|
ehq.pAddressDevice = NULL; // TODO
|
||||||
|
|
||||||
if(!pd.is_null(1))
|
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);
|
HRESULT ehq_result = message_handler(message_handler_ctx, DPN_MSGID_ENUM_HOSTS_QUERY, &ehq);
|
||||||
l.lock();
|
l.lock();
|
||||||
|
|
||||||
|
sender_address->Release();
|
||||||
|
|
||||||
std::vector<unsigned char> response_data_buffer;
|
std::vector<unsigned char> response_data_buffer;
|
||||||
if(ehq.dwResponseDataSize > 0)
|
if(ehq.dwResponseDataSize > 0)
|
||||||
{
|
{
|
||||||
@ -2413,7 +2461,15 @@ void DirectPlay8Peer::handle_host_connect_request(std::unique_lock<std::mutex> &
|
|||||||
ic.dwUserConnectDataSize = d.second;
|
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 */
|
ic.pAddressDevice = NULL; /* TODO */
|
||||||
|
|
||||||
peer->state = Peer::PS_INDICATING;
|
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);
|
HRESULT ic_result = message_handler(message_handler_ctx, DPN_MSGID_INDICATE_CONNECT, &ic);
|
||||||
l.lock();
|
l.lock();
|
||||||
|
|
||||||
|
peer_address->Release();
|
||||||
|
|
||||||
std::vector<unsigned char> reply_data_buffer;
|
std::vector<unsigned char> reply_data_buffer;
|
||||||
if(ic.dwReplyDataSize > 0)
|
if(ic.dwReplyDataSize > 0)
|
||||||
{
|
{
|
||||||
|
@ -47,6 +47,8 @@ class DirectPlay8Peer: public IDirectPlay8Peer
|
|||||||
std::wstring password;
|
std::wstring password;
|
||||||
std::vector<unsigned char> application_data;
|
std::vector<unsigned char> application_data;
|
||||||
|
|
||||||
|
GUID service_provider;
|
||||||
|
|
||||||
/* Local IP and port for all our sockets, except discovery_socket. */
|
/* Local IP and port for all our sockets, except discovery_socket. */
|
||||||
uint32_t local_ip;
|
uint32_t local_ip;
|
||||||
uint16_t local_port;
|
uint16_t local_port;
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <stdio.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
#include "COMAPIException.hpp"
|
||||||
#include "DirectPlay8Address.hpp"
|
#include "DirectPlay8Address.hpp"
|
||||||
#include "HostEnumerator.hpp"
|
#include "HostEnumerator.hpp"
|
||||||
#include "Messages.hpp"
|
#include "Messages.hpp"
|
||||||
@ -35,13 +37,88 @@ HostEnumerator::HostEnumerator(
|
|||||||
next_tx_at(0),
|
next_tx_at(0),
|
||||||
req_cancel(false)
|
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));
|
memset(&send_addr, 0, sizeof(send_addr));
|
||||||
send_addr.sin_family = AF_INET;
|
send_addr.sin_family = AF_INET;
|
||||||
send_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
send_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
|
||||||
send_addr.sin_port = htons(DISCOVERY_PORT);
|
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)
|
if(pApplicationDesc != NULL)
|
||||||
{
|
{
|
||||||
application_guid = pApplicationDesc->guidApplication;
|
application_guid = pApplicationDesc->guidApplication;
|
||||||
@ -248,26 +325,15 @@ void HostEnumerator::handle_packet(const void *data, size_t size, struct sockadd
|
|||||||
* port for the host.
|
* port for the host.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IDirectPlay8Address *sender_address = new DirectPlay8Address(global_refcount);
|
IDirectPlay8Address *sender_address = DirectPlay8Address::create_host_address(
|
||||||
sender_address->SetSP(&CLSID_DP8SP_TCPIP); /* TODO: Be IPX if application previously gave us an IPX address? */
|
global_refcount, service_provider, (struct sockaddr*)(from_addr));
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* Build a DirectPlay8Address with the interface we received the response on.
|
/* Build a DirectPlay8Address with the interface we received the response on.
|
||||||
* TODO: Actually do this.
|
* TODO: Actually do this.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IDirectPlay8Address *device_address = new DirectPlay8Address(global_refcount);
|
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;
|
DPNMSG_ENUM_HOSTS_RESPONSE message;
|
||||||
memset(&message, 0, sizeof(message));
|
memset(&message, 0, sizeof(message));
|
||||||
|
@ -29,6 +29,7 @@ class HostEnumerator
|
|||||||
|
|
||||||
std::function<void(HRESULT)> complete_cb;
|
std::function<void(HRESULT)> complete_cb;
|
||||||
|
|
||||||
|
GUID service_provider;
|
||||||
struct sockaddr_in send_addr;
|
struct sockaddr_in send_addr;
|
||||||
|
|
||||||
GUID application_guid; /* GUID of application to search for, or GUID_NULL */
|
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.guidApplication = application_guid;
|
||||||
app_desc.pwszSessionName = (wchar_t*)(session_description);
|
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");
|
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);
|
ASSERT_EQ(client->Initialize(&client_cb, &callback_shim, 0), S_OK);
|
||||||
|
|
||||||
|
IDP8AddressInstance device_address;
|
||||||
|
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||||
|
|
||||||
DWORD start = GetTickCount();
|
DWORD start = GetTickCount();
|
||||||
|
|
||||||
ASSERT_EQ(client->EnumHosts(
|
ASSERT_EQ(client->EnumHosts(
|
||||||
NULL, /* pApplicationDesc */
|
NULL, /* pApplicationDesc */
|
||||||
NULL, /* pdpaddrHost */
|
NULL, /* pdpaddrHost */
|
||||||
NULL, /* pdpaddrDeviceInfo */
|
device_address, /* pdpaddrDeviceInfo */
|
||||||
NULL, /* pvUserEnumData */
|
NULL, /* pvUserEnumData */
|
||||||
0, /* dwUserEnumDataSize */
|
0, /* dwUserEnumDataSize */
|
||||||
3, /* dwEnumCount */
|
3, /* dwEnumCount */
|
||||||
@ -423,12 +431,15 @@ TEST(DirectPlay8Peer, EnumHostsAsync)
|
|||||||
|
|
||||||
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
||||||
|
|
||||||
|
IDP8AddressInstance device_address;
|
||||||
|
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||||
|
|
||||||
DWORD start = GetTickCount();
|
DWORD start = GetTickCount();
|
||||||
|
|
||||||
ASSERT_EQ(client->EnumHosts(
|
ASSERT_EQ(client->EnumHosts(
|
||||||
NULL, /* pApplicationDesc */
|
NULL, /* pApplicationDesc */
|
||||||
NULL, /* pdpaddrHost */
|
NULL, /* pdpaddrHost */
|
||||||
NULL, /* pdpaddrDeviceInfo */
|
device_address, /* pdpaddrDeviceInfo */
|
||||||
NULL, /* pvUserEnumData */
|
NULL, /* pvUserEnumData */
|
||||||
0, /* dwUserEnumDataSize */
|
0, /* dwUserEnumDataSize */
|
||||||
3, /* dwEnumCount */
|
3, /* dwEnumCount */
|
||||||
@ -492,12 +503,15 @@ TEST(DirectPlay8Peer, EnumHostsAsyncCancelByHandle)
|
|||||||
|
|
||||||
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
||||||
|
|
||||||
|
IDP8AddressInstance device_address;
|
||||||
|
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||||
|
|
||||||
DWORD start = GetTickCount();
|
DWORD start = GetTickCount();
|
||||||
|
|
||||||
ASSERT_EQ(client->EnumHosts(
|
ASSERT_EQ(client->EnumHosts(
|
||||||
NULL, /* pApplicationDesc */
|
NULL, /* pApplicationDesc */
|
||||||
NULL, /* pdpaddrHost */
|
NULL, /* pdpaddrHost */
|
||||||
NULL, /* pdpaddrDeviceInfo */
|
device_address, /* pdpaddrDeviceInfo */
|
||||||
NULL, /* pvUserEnumData */
|
NULL, /* pvUserEnumData */
|
||||||
0, /* dwUserEnumDataSize */
|
0, /* dwUserEnumDataSize */
|
||||||
3, /* dwEnumCount */
|
3, /* dwEnumCount */
|
||||||
@ -555,12 +569,15 @@ TEST(DirectPlay8Peer, EnumHostsAsyncCancelAllEnums)
|
|||||||
|
|
||||||
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
||||||
|
|
||||||
|
IDP8AddressInstance device_address;
|
||||||
|
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||||
|
|
||||||
DWORD start = GetTickCount();
|
DWORD start = GetTickCount();
|
||||||
|
|
||||||
ASSERT_EQ(client->EnumHosts(
|
ASSERT_EQ(client->EnumHosts(
|
||||||
NULL, /* pApplicationDesc */
|
NULL, /* pApplicationDesc */
|
||||||
NULL, /* pdpaddrHost */
|
NULL, /* pdpaddrHost */
|
||||||
NULL, /* pdpaddrDeviceInfo */
|
device_address, /* pdpaddrDeviceInfo */
|
||||||
NULL, /* pvUserEnumData */
|
NULL, /* pvUserEnumData */
|
||||||
0, /* dwUserEnumDataSize */
|
0, /* dwUserEnumDataSize */
|
||||||
3, /* dwEnumCount */
|
3, /* dwEnumCount */
|
||||||
@ -618,12 +635,15 @@ TEST(DirectPlay8Peer, EnumHostsAsyncCancelAllOperations)
|
|||||||
|
|
||||||
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
||||||
|
|
||||||
|
IDP8AddressInstance device_address;
|
||||||
|
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||||
|
|
||||||
DWORD start = GetTickCount();
|
DWORD start = GetTickCount();
|
||||||
|
|
||||||
ASSERT_EQ(client->EnumHosts(
|
ASSERT_EQ(client->EnumHosts(
|
||||||
NULL, /* pApplicationDesc */
|
NULL, /* pApplicationDesc */
|
||||||
NULL, /* pdpaddrHost */
|
NULL, /* pdpaddrHost */
|
||||||
NULL, /* pdpaddrDeviceInfo */
|
device_address, /* pdpaddrDeviceInfo */
|
||||||
NULL, /* pvUserEnumData */
|
NULL, /* pvUserEnumData */
|
||||||
0, /* dwUserEnumDataSize */
|
0, /* dwUserEnumDataSize */
|
||||||
3, /* dwEnumCount */
|
3, /* dwEnumCount */
|
||||||
@ -681,12 +701,15 @@ TEST(DirectPlay8Peer, EnumHostsAsyncCancelByClose)
|
|||||||
|
|
||||||
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
ASSERT_EQ(client->Initialize(&callback, &callback_shim, 0), S_OK);
|
||||||
|
|
||||||
|
IDP8AddressInstance device_address;
|
||||||
|
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||||
|
|
||||||
DWORD start = GetTickCount();
|
DWORD start = GetTickCount();
|
||||||
|
|
||||||
ASSERT_EQ(client->EnumHosts(
|
ASSERT_EQ(client->EnumHosts(
|
||||||
NULL, /* pApplicationDesc */
|
NULL, /* pApplicationDesc */
|
||||||
NULL, /* pdpaddrHost */
|
NULL, /* pdpaddrHost */
|
||||||
NULL, /* pdpaddrDeviceInfo */
|
device_address, /* pdpaddrDeviceInfo */
|
||||||
NULL, /* pvUserEnumData */
|
NULL, /* pvUserEnumData */
|
||||||
0, /* dwUserEnumDataSize */
|
0, /* dwUserEnumDataSize */
|
||||||
3, /* dwEnumCount */
|
3, /* dwEnumCount */
|
||||||
@ -794,10 +817,13 @@ TEST(DirectPlay8Peer, EnumHostsFilterByApplicationGUID)
|
|||||||
app_desc.dwSize = sizeof(app_desc);
|
app_desc.dwSize = sizeof(app_desc);
|
||||||
app_desc.guidApplication = APP_GUID_2;
|
app_desc.guidApplication = APP_GUID_2;
|
||||||
|
|
||||||
|
IDP8AddressInstance device_address;
|
||||||
|
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||||
|
|
||||||
ASSERT_EQ(client->EnumHosts(
|
ASSERT_EQ(client->EnumHosts(
|
||||||
&app_desc, /* pApplicationDesc */
|
&app_desc, /* pApplicationDesc */
|
||||||
NULL, /* pdpaddrHost */
|
NULL, /* pdpaddrHost */
|
||||||
NULL, /* pdpaddrDeviceInfo */
|
device_address, /* pdpaddrDeviceInfo */
|
||||||
NULL, /* pvUserEnumData */
|
NULL, /* pvUserEnumData */
|
||||||
0, /* dwUserEnumDataSize */
|
0, /* dwUserEnumDataSize */
|
||||||
3, /* dwEnumCount */
|
3, /* dwEnumCount */
|
||||||
@ -857,10 +883,13 @@ TEST(DirectPlay8Peer, EnumHostsFilterByNULLApplicationGUID)
|
|||||||
app_desc.dwSize = sizeof(app_desc);
|
app_desc.dwSize = sizeof(app_desc);
|
||||||
app_desc.guidApplication = GUID_NULL;
|
app_desc.guidApplication = GUID_NULL;
|
||||||
|
|
||||||
|
IDP8AddressInstance device_address;
|
||||||
|
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||||
|
|
||||||
ASSERT_EQ(client->EnumHosts(
|
ASSERT_EQ(client->EnumHosts(
|
||||||
&app_desc, /* pApplicationDesc */
|
&app_desc, /* pApplicationDesc */
|
||||||
NULL, /* pdpaddrHost */
|
NULL, /* pdpaddrHost */
|
||||||
NULL, /* pdpaddrDeviceInfo */
|
device_address, /* pdpaddrDeviceInfo */
|
||||||
NULL, /* pvUserEnumData */
|
NULL, /* pvUserEnumData */
|
||||||
0, /* dwUserEnumDataSize */
|
0, /* dwUserEnumDataSize */
|
||||||
3, /* dwEnumCount */
|
3, /* dwEnumCount */
|
||||||
@ -939,10 +968,13 @@ TEST(DirectPlay8Peer, EnumHostsDataInQuery)
|
|||||||
|
|
||||||
ASSERT_EQ(client->Initialize(&client_cb, &callback_shim, 0), S_OK);
|
ASSERT_EQ(client->Initialize(&client_cb, &callback_shim, 0), S_OK);
|
||||||
|
|
||||||
|
IDP8AddressInstance device_address;
|
||||||
|
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||||
|
|
||||||
ASSERT_EQ(client->EnumHosts(
|
ASSERT_EQ(client->EnumHosts(
|
||||||
NULL, /* pApplicationDesc */
|
NULL, /* pApplicationDesc */
|
||||||
NULL, /* pdpaddrHost */
|
NULL, /* pdpaddrHost */
|
||||||
NULL, /* pdpaddrDeviceInfo */
|
device_address, /* pdpaddrDeviceInfo */
|
||||||
(void*)(DATA), /* pvUserEnumData */
|
(void*)(DATA), /* pvUserEnumData */
|
||||||
sizeof(DATA), /* dwUserEnumDataSize */
|
sizeof(DATA), /* dwUserEnumDataSize */
|
||||||
3, /* dwEnumCount */
|
3, /* dwEnumCount */
|
||||||
@ -1036,10 +1068,13 @@ TEST(DirectPlay8Peer, EnumHostsDataInResponse)
|
|||||||
|
|
||||||
ASSERT_EQ(client->Initialize(&client_cb, &callback_shim, 0), S_OK);
|
ASSERT_EQ(client->Initialize(&client_cb, &callback_shim, 0), S_OK);
|
||||||
|
|
||||||
|
IDP8AddressInstance device_address;
|
||||||
|
device_address->SetSP(&CLSID_DP8SP_TCPIP);
|
||||||
|
|
||||||
ASSERT_EQ(client->EnumHosts(
|
ASSERT_EQ(client->EnumHosts(
|
||||||
NULL, /* pApplicationDesc */
|
NULL, /* pApplicationDesc */
|
||||||
NULL, /* pdpaddrHost */
|
NULL, /* pdpaddrHost */
|
||||||
NULL, /* pdpaddrDeviceInfo */
|
device_address, /* pdpaddrDeviceInfo */
|
||||||
NULL, /* pvUserEnumData */
|
NULL, /* pvUserEnumData */
|
||||||
0, /* dwUserEnumDataSize */
|
0, /* dwUserEnumDataSize */
|
||||||
3, /* dwEnumCount */
|
3, /* dwEnumCount */
|
||||||
@ -1059,7 +1094,60 @@ TEST(DirectPlay8Peer, EnumHostsDataInResponse)
|
|||||||
EXPECT_TRUE(got_return_buffer);
|
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)
|
TEST(DirectPlay8Peer, ConnectSync)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user