drop Qt discovery of best IP address in favor of pure WINAPI method (with wireless detection)

This commit is contained in:
walker0643 2018-07-03 18:48:24 -04:00
parent 2d7818fe49
commit 33224a1f97
6 changed files with 89 additions and 65 deletions

View File

@ -6,17 +6,25 @@ set (CMAKE_AUTORCC ON)
set (CMAKE_AUTOUIC ON) set (CMAKE_AUTOUIC ON)
set (CMAKE_INCLUDE_CURRENT_DIR ON) set (CMAKE_INCLUDE_CURRENT_DIR ON)
file (GLOB GUI_SOURCE_FILES src/*.cpp src/*.h)
file (GLOB GUI_UI_FILES src/*.ui)
if (WIN32) if (WIN32)
set (GUI_RC_FILES res/win/Barrier.rc) set (resources res/win/Barrier.rc)
set (arch "win32")
else()
set (arch "unix")
endif()
file (GLOB sources src/*.cpp src/${arch}/*.cpp)
file (GLOB headers src/*.h src/${arch}/*.h)
file (GLOB designs src/*.ui)
if (BARRIER_ADD_HEADERS)
list (APPEND sources ${headers})
endif() endif()
add_executable (barrier WIN32 add_executable (barrier WIN32
${GUI_SOURCE_FILES} ${sources}
${GUI_UI_FILES} ${designs}
${GUI_RC_FILES} ${resources}
res/Barrier.qrc res/Barrier.qrc
) )
@ -32,7 +40,7 @@ if (WIN32)
HINTS ENV BONJOUR_SDK_HOME HINTS ENV BONJOUR_SDK_HOME
PATH_SUFFIXES "Lib/x64") PATH_SUFFIXES "Lib/x64")
set_target_properties (barrier PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT") set_target_properties (barrier PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT")
target_link_libraries (barrier ${DNSSD_LIB}) target_link_libraries (barrier ${DNSSD_LIB} Ws2_32.lib Iphlpapi.lib)
elseif (APPLE) elseif (APPLE)
find_library(APPSERVICES_LIB ApplicationServices) find_library(APPSERVICES_LIB ApplicationServices)
target_link_libraries(barrier ${APPSERVICES_LIB}) target_link_libraries(barrier ${APPSERVICES_LIB})

View File

@ -30,8 +30,7 @@
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <wlanapi.h> #include "win32/DefaultInterfaceIP.h"
#pragma comment(lib, "wlanapi.lib")
#else #else
#include <stdlib.h> #include <stdlib.h>
#endif #endif
@ -120,75 +119,27 @@ void ZeroconfService::errorHandle(DNSServiceErrorType errorCode)
tr("Error code: %1.").arg(errorCode)); tr("Error code: %1.").arg(errorCode));
} }
#ifdef _WIN32
static QString mac_to_string(DOT11_MAC_ADDRESS mac)
{
char str[18];
snprintf(str, 18, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return str;
}
static QList<QString> wireless_mac_strings()
{
QList<QString> wlanMAC;
DWORD version;
HANDLE client;
if (WlanOpenHandle(2, NULL, &version, &client) == 0) {
WLAN_INTERFACE_INFO_LIST * list;
if (WlanEnumInterfaces(client, NULL, &list) == 0) {
for (DWORD idx = 0; idx < list->dwNumberOfItems; ++idx) {
const GUID * PGuid = &(list->InterfaceInfo[0].InterfaceGuid);
const WLAN_INTF_OPCODE OpCode = wlan_intf_opcode_current_connection;
WLAN_CONNECTION_ATTRIBUTES * attrs;
DWORD attrsSz;
if (WlanQueryInterface(client, PGuid, OpCode, NULL, &attrsSz,
(void**)&attrs, NULL) == 0) {
wlanMAC.append(mac_to_string(
attrs->wlanAssociationAttributes.dot11Bssid));
WlanFreeMemory(attrs);
}
}
WlanFreeMemory(list);
}
WlanCloseHandle(client, NULL);
}
return wlanMAC;
}
#else
static QList<QString> wireless_mac_strings()
{
// TODO
return QList<QString>();
}
#endif
QString ZeroconfService::getLocalIPAddresses() QString ZeroconfService::getLocalIPAddresses()
{ {
#ifdef _WIN32
return QString::fromStdString(Debauchee::default_interface_ip());
#else
const QString NonEthernetMAC = "00:00:00:00:00:00"; const QString NonEthernetMAC = "00:00:00:00:00:00";
const auto wlanMAC = wireless_mac_strings();
QString wirelessIP = "";
foreach(const auto qni, QNetworkInterface::allInterfaces()) { foreach(const auto qni, QNetworkInterface::allInterfaces()) {
// weed out loopback, inactive, and non-ethernet interfaces // weed out loopback, inactive, and non-ethernet interfaces
if (!qni.flags().testFlag(QNetworkInterface::IsLoopBack) && if (!qni.flags().testFlag(QNetworkInterface::IsLoopBack) &&
qni.flags().testFlag(QNetworkInterface::IsUp) && qni.flags().testFlag(QNetworkInterface::IsUp) &&
qni.hardwareAddress() != NonEthernetMAC) { qni.hardwareAddress() != NonEthernetMAC) {
bool isWireless = wlanMAC.contains(qni.hardwareAddress().toUpper());
foreach(const auto address, qni.allAddresses()) { foreach(const auto address, qni.allAddresses()) {
if (address.protocol() == QAbstractSocket::IPv4Protocol) { if (address.protocol() == QAbstractSocket::IPv4Protocol) {
// use the first non-wireless address we find // use the first address we find
if (!isWireless)
return address.toString(); return address.toString();
// save the first wireless address we find
if (wirelessIP.isEmpty())
wirelessIP = address.toString();
} }
} }
} }
} }
// if no non-wireless address could be found use a wireless one return "";
// if one was found. otherwise return an empty string #endif
return wirelessIP;
} }
bool ZeroconfService::registerService(bool server) bool ZeroconfService::registerService(bool server)

View File

@ -67,6 +67,13 @@ int main(int argc, char* argv[])
/* Workaround for QTBUG-40332 - "High ping when QNetworkAccessManager is instantiated" */ /* Workaround for QTBUG-40332 - "High ping when QNetworkAccessManager is instantiated" */
::setenv ("QT_BEARER_POLL_TIMEOUT", "-1", 1); ::setenv ("QT_BEARER_POLL_TIMEOUT", "-1", 1);
#endif #endif
#if _WIN32
// winsock needs to be initialized for DefaultInterfaceIP
WSADATA wd;
WSAStartup(MAKEWORD(2, 0), &wd);
#endif
QCoreApplication::setOrganizationName("Debauchee"); QCoreApplication::setOrganizationName("Debauchee");
QCoreApplication::setOrganizationDomain("github.com"); QCoreApplication::setOrganizationDomain("github.com");
QCoreApplication::setApplicationName("Barrier"); QCoreApplication::setApplicationName("Barrier");

Binary file not shown.

View File

@ -0,0 +1,10 @@
#pragma once
#include <string>
namespace Debauchee
{
std::string default_interface_ip();
}

View File

@ -0,0 +1,48 @@
#pragma once
namespace Debauchee
{
template<class T>
class HeapResource
{
public:
explicit HeapResource(HANDLE heap, DWORD flags, SIZE_T sz) :
_heap(heap),
_flags(flags),
_mem((T*)HeapAlloc(heap, flags, sz))
{
}
HeapResource(HeapResource<T>&& other)
: _mem(NULL)
{
swap(*this, other);
}
~HeapResource()
{
if (is_valid()) {
HeapFree(_heap, _flags, _mem);
}
}
friend void swap(HeapResource<T>& first, HeapResource<T>& second)
{
using std::swap;
swap(first._heap, second._heap);
swap(first._flags, second._flags);
swap(first._mem, second._mem);
}
bool is_valid() const { return _mem != NULL; }
operator T*() const { return _mem; }
private:
HANDLE _heap;
DWORD _flags;
T * _mem;
};
}