mirror of
https://github.com/solemnwarning/directplay-lite
synced 2024-12-30 16:45:37 +01:00
Implement IDirectPlay8Peer::GetLocalHostAddresses() method
This commit is contained in:
parent
b04735e8ea
commit
780a37965b
@ -58,7 +58,7 @@ SET TEST_OBJS=^
|
||||
tests/PacketSerialiser.obj^
|
||||
tests/SendQueue.obj
|
||||
|
||||
SET TEST_LIBS=ws2_32.lib dxguid.lib ole32.lib
|
||||
SET TEST_LIBS=ws2_32.lib dxguid.lib ole32.lib iphlpapi.lib
|
||||
|
||||
SET HOOK_DLLS=ddraw
|
||||
|
||||
@ -81,7 +81,7 @@ SET HOOK_OBJS=^
|
||||
src/packet.obj^
|
||||
src/SendQueue.obj
|
||||
|
||||
SET HOOK_LIBS=ws2_32.lib dxguid.lib ole32.lib
|
||||
SET HOOK_LIBS=ws2_32.lib dxguid.lib ole32.lib iphlpapi.lib
|
||||
|
||||
SET CFLAGS=^
|
||||
/Zi^
|
||||
|
@ -1567,7 +1567,64 @@ HRESULT DirectPlay8Peer::GetPeerAddress(CONST DPNID dpnid, IDirectPlay8Address**
|
||||
|
||||
HRESULT DirectPlay8Peer::GetLocalHostAddresses(IDirectPlay8Address** CONST prgpAddress, DWORD* CONST pcAddress, CONST DWORD dwFlags)
|
||||
{
|
||||
UNIMPLEMENTED("DirectPlay8Peer::GetLocalHostAddresses");
|
||||
std::unique_lock<std::mutex> l(lock);
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case STATE_NEW: return DPNERR_UNINITIALIZED;
|
||||
case STATE_INITIALISED: return DPNERR_NOCONNECTION;
|
||||
case STATE_HOSTING: break;
|
||||
case STATE_CONNECTING_TO_HOST: return DPNERR_NOCONNECTION;
|
||||
case STATE_CONNECTING_TO_PEERS: return DPNERR_NOCONNECTION;
|
||||
case STATE_CONNECT_FAILED: return DPNERR_NOCONNECTION;
|
||||
case STATE_CONNECTED: return DPNERR_NOTHOST;
|
||||
case STATE_CLOSING: return DPNERR_NOCONNECTION;
|
||||
case STATE_TERMINATED: return DPNERR_NOCONNECTION;
|
||||
}
|
||||
|
||||
if(dwFlags & DPNGETLOCALHOSTADDRESSES_COMBINED)
|
||||
{
|
||||
/* TODO: Implement DPNGETLOCALHOSTADDRESSES_COMBINED */
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/* We don't support binding to specific interfaces yet, so we just return all the IPv4
|
||||
* addresses assigned to the system.
|
||||
*/
|
||||
|
||||
std::list<SystemNetworkInterface> interfaces = get_network_interfaces();
|
||||
std::list<struct sockaddr_in> local_addrs;
|
||||
|
||||
for(auto i = interfaces.begin(); i != interfaces.end(); ++i)
|
||||
{
|
||||
for(auto a = i->unicast_addrs.begin(); a != i->unicast_addrs.end(); ++a)
|
||||
{
|
||||
if(a->ss_family == AF_INET)
|
||||
{
|
||||
struct sockaddr_in sa_v4 = *(struct sockaddr_in*)(&(*a));
|
||||
sa_v4.sin_port = htons(local_port);
|
||||
|
||||
local_addrs.push_back(sa_v4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(*pcAddress < local_addrs.size())
|
||||
{
|
||||
*pcAddress = local_addrs.size();
|
||||
return DPNERR_BUFFERTOOSMALL;
|
||||
}
|
||||
|
||||
IDirectPlay8Address **dest = prgpAddress;
|
||||
for(auto a = local_addrs.begin(); a != local_addrs.end(); ++a)
|
||||
{
|
||||
*dest = DirectPlay8Address::create_host_address(global_refcount, service_provider, (struct sockaddr*)(&(*a)));
|
||||
++dest;
|
||||
}
|
||||
|
||||
*pcAddress = local_addrs.size();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectPlay8Peer::Close(CONST DWORD dwFlags)
|
||||
|
@ -1,10 +1,13 @@
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
#include "network.hpp"
|
||||
#include "log.hpp"
|
||||
|
||||
int create_udp_socket(uint32_t ipaddr, uint16_t port)
|
||||
{
|
||||
@ -173,3 +176,66 @@ int create_discovery_socket()
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
std::list<SystemNetworkInterface> get_network_interfaces()
|
||||
{
|
||||
std::vector<unsigned char> buf;
|
||||
|
||||
while(1)
|
||||
{
|
||||
ULONG size = buf.size();
|
||||
ULONG err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, (IP_ADAPTER_ADDRESSES*)(buf.data()), &size);
|
||||
|
||||
if(err == ERROR_SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(err == ERROR_NO_DATA)
|
||||
{
|
||||
return std::list<SystemNetworkInterface>();
|
||||
}
|
||||
else if(err == ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
buf.resize(size);
|
||||
}
|
||||
else{
|
||||
log_printf("GetAdaptersAddresses: %s", win_strerror(err).c_str());
|
||||
return std::list<SystemNetworkInterface>();
|
||||
}
|
||||
}
|
||||
|
||||
std::list<SystemNetworkInterface> interfaces;
|
||||
|
||||
for(IP_ADAPTER_ADDRESSES *ipaa = (IP_ADAPTER_ADDRESSES*)(buf.data()); ipaa != NULL; ipaa = ipaa->Next)
|
||||
{
|
||||
if(ipaa->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
SystemNetworkInterface iface;
|
||||
|
||||
iface.friendly_name = ipaa->FriendlyName;
|
||||
|
||||
for(IP_ADAPTER_UNICAST_ADDRESS_LH *uc = ipaa->FirstUnicastAddress; uc != NULL; uc = uc->Next)
|
||||
{
|
||||
if(uc->Address.iSockaddrLength > sizeof(struct sockaddr_storage))
|
||||
{
|
||||
log_printf("Ignoring oversize address (family = %u, size = %u)",
|
||||
(unsigned)(uc->Address.lpSockaddr->sa_family),
|
||||
(unsigned)(uc->Address.iSockaddrLength));
|
||||
continue;
|
||||
}
|
||||
|
||||
struct sockaddr_storage ss;
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
memcpy(&ss, uc->Address.lpSockaddr, uc->Address.iSockaddrLength);
|
||||
|
||||
iface.unicast_addrs.push_back(ss);
|
||||
}
|
||||
|
||||
interfaces.push_back(iface);
|
||||
}
|
||||
|
||||
return interfaces;
|
||||
}
|
||||
|
@ -1,16 +1,26 @@
|
||||
#ifndef DPLITE_NETWORK_HPP
|
||||
#define DPLITE_NETWORK_HPP
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <list>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#define DISCOVERY_PORT 6073
|
||||
#define DEFAULT_HOST_PORT 6072
|
||||
#define LISTEN_QUEUE_SIZE 16
|
||||
#define MAX_PACKET_SIZE (60 * 1024)
|
||||
|
||||
struct SystemNetworkInterface {
|
||||
std::wstring friendly_name;
|
||||
|
||||
std::list<struct sockaddr_storage> unicast_addrs;
|
||||
};
|
||||
|
||||
int create_udp_socket(uint32_t ipaddr, uint16_t port);
|
||||
int create_listener_socket(uint32_t ipaddr, uint16_t port);
|
||||
int create_client_socket(uint32_t local_ipaddr, uint16_t local_port);
|
||||
int create_discovery_socket();
|
||||
std::list<SystemNetworkInterface> get_network_interfaces();
|
||||
|
||||
#endif /* !DPLITE_NETWORK_HPP */
|
||||
|
Loading…
x
Reference in New Issue
Block a user