mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[wpinet] Directly link to mDNS APIs on Windows (#8374)
These were added in Windows 10 1703. Technically Windows 10 in general is out of support, but versions of Windows 10 older than that are _well_ out of support. And we do directly link to other APIs that are newer. So no need to do the dynamic linking.
This commit is contained in:
@@ -1,41 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "DynamicDns.hpp"
|
||||
|
||||
using namespace wpi::net;
|
||||
|
||||
DynamicDns& DynamicDns::GetDynamicDns() {
|
||||
static DynamicDns dns;
|
||||
return dns;
|
||||
}
|
||||
|
||||
DynamicDns::DynamicDns() {
|
||||
HMODULE library = LoadLibraryW(L"dnsapi");
|
||||
|
||||
if (library == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
DnsServiceFreeInstancePtr = (DnsServiceFreeInstanceFunc)GetProcAddress(
|
||||
library, "DnsServiceFreeInstance");
|
||||
DnsServiceConstructInstancePtr =
|
||||
(DnsServiceConstructInstanceFunc)GetProcAddress(
|
||||
library, "DnsServiceConstructInstance");
|
||||
DnsServiceRegisterPtr =
|
||||
(DnsServiceRegisterFunc)GetProcAddress(library, "DnsServiceRegister");
|
||||
DnsServiceDeRegisterPtr =
|
||||
(DnsServiceDeRegisterFunc)GetProcAddress(library, "DnsServiceDeRegister");
|
||||
|
||||
CanDnsAnnounce = DnsServiceFreeInstancePtr &&
|
||||
DnsServiceConstructInstancePtr && DnsServiceRegisterPtr &&
|
||||
DnsServiceDeRegisterPtr;
|
||||
|
||||
DnsServiceBrowsePtr =
|
||||
(DnsServiceBrowseFunc)GetProcAddress(library, "DnsServiceBrowse");
|
||||
DnsServiceBrowseCancelPtr = (DnsServiceBrowseCancelFunc)GetProcAddress(
|
||||
library, "DnsServiceBrowseCancel");
|
||||
|
||||
CanDnsResolve = DnsServiceBrowsePtr && DnsServiceBrowseCancelPtr;
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <windns.h>
|
||||
|
||||
namespace wpi::net {
|
||||
class DynamicDns {
|
||||
public:
|
||||
using DnsServiceFreeInstanceFunc =
|
||||
VOID(WINAPI*)(_In_ PDNS_SERVICE_INSTANCE pInstance);
|
||||
|
||||
using DnsServiceConstructInstanceFunc = PDNS_SERVICE_INSTANCE(WINAPI*)(
|
||||
_In_ PCWSTR pServiceName, _In_ PCWSTR pHostName,
|
||||
_In_opt_ PIP4_ADDRESS pIp4, _In_opt_ PIP6_ADDRESS pIp6, _In_ WORD wPort,
|
||||
_In_ WORD wPriority, _In_ WORD wWeight, _In_ DWORD dwPropertiesCount,
|
||||
_In_reads_(dwPropertiesCount) PCWSTR* keys,
|
||||
_In_reads_(dwPropertiesCount) PCWSTR* values);
|
||||
|
||||
using DnsServiceRegisterFunc =
|
||||
DWORD(WINAPI*)(_In_ PDNS_SERVICE_REGISTER_REQUEST pRequest,
|
||||
_Inout_opt_ PDNS_SERVICE_CANCEL pCancel);
|
||||
|
||||
using DnsServiceDeRegisterFunc =
|
||||
DWORD(WINAPI*)(_In_ PDNS_SERVICE_REGISTER_REQUEST pRequest,
|
||||
_Inout_opt_ PDNS_SERVICE_CANCEL pCancel);
|
||||
|
||||
using DnsServiceBrowseFunc =
|
||||
DNS_STATUS(WINAPI*)(_In_ PDNS_SERVICE_BROWSE_REQUEST pRequest,
|
||||
_Inout_ PDNS_SERVICE_CANCEL pCancel);
|
||||
|
||||
using DnsServiceBrowseCancelFunc =
|
||||
DNS_STATUS(WINAPI*)(_In_ PDNS_SERVICE_CANCEL pCancelHandle);
|
||||
|
||||
DnsServiceBrowseFunc DnsServiceBrowsePtr{nullptr};
|
||||
DnsServiceBrowseCancelFunc DnsServiceBrowseCancelPtr{nullptr};
|
||||
|
||||
DnsServiceFreeInstanceFunc DnsServiceFreeInstancePtr{nullptr};
|
||||
DnsServiceConstructInstanceFunc DnsServiceConstructInstancePtr{nullptr};
|
||||
DnsServiceRegisterFunc DnsServiceRegisterPtr{nullptr};
|
||||
DnsServiceDeRegisterFunc DnsServiceDeRegisterPtr{nullptr};
|
||||
|
||||
bool CanDnsAnnounce{false};
|
||||
bool CanDnsResolve{false};
|
||||
|
||||
static DynamicDns& GetDynamicDns();
|
||||
|
||||
private:
|
||||
DynamicDns();
|
||||
};
|
||||
} // namespace wpi::net
|
||||
@@ -8,12 +8,14 @@
|
||||
|
||||
#include "wpi/net/MulticastServiceAnnouncer.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <WinDNS.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "DynamicDns.hpp"
|
||||
#include "wpi/net/hostname.hpp"
|
||||
#include "wpi/util/ConvertUTF.hpp"
|
||||
#include "wpi/util/SmallString.hpp"
|
||||
@@ -23,7 +25,6 @@
|
||||
using namespace wpi::net;
|
||||
|
||||
struct ImplBase {
|
||||
wpi::net::DynamicDns& dynamicDns = wpi::net::DynamicDns::GetDynamicDns();
|
||||
PDNS_SERVICE_INSTANCE serviceInstance = nullptr;
|
||||
HANDLE event = nullptr;
|
||||
};
|
||||
@@ -47,10 +48,6 @@ template <typename T>
|
||||
MulticastServiceAnnouncer::Impl::Impl(std::string_view serviceName,
|
||||
std::string_view serviceType, int port,
|
||||
std::span<const std::pair<T, T>> txt) {
|
||||
if (!dynamicDns.CanDnsAnnounce) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->port = port;
|
||||
|
||||
wpi::util::SmallVector<wchar_t, 128> wideStorage;
|
||||
@@ -127,7 +124,7 @@ MulticastServiceAnnouncer::~MulticastServiceAnnouncer() noexcept {
|
||||
}
|
||||
|
||||
bool MulticastServiceAnnouncer::HasImplementation() const {
|
||||
return pImpl->dynamicDns.CanDnsAnnounce;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void WINAPI DnsServiceRegisterCallback(DWORD /*Status*/,
|
||||
@@ -145,15 +142,10 @@ void MulticastServiceAnnouncer::Start() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pImpl->dynamicDns.CanDnsAnnounce) {
|
||||
return;
|
||||
}
|
||||
|
||||
PDNS_SERVICE_INSTANCE serviceInst =
|
||||
pImpl->dynamicDns.DnsServiceConstructInstancePtr(
|
||||
pImpl->serviceInstanceName.c_str(), pImpl->hostName.c_str(), nullptr,
|
||||
nullptr, pImpl->port, 0, 0, static_cast<DWORD>(pImpl->keyPtrs.size()),
|
||||
pImpl->keyPtrs.data(), pImpl->valuePtrs.data());
|
||||
PDNS_SERVICE_INSTANCE serviceInst = DnsServiceConstructInstance(
|
||||
pImpl->serviceInstanceName.c_str(), pImpl->hostName.c_str(), nullptr,
|
||||
nullptr, pImpl->port, 0, 0, static_cast<DWORD>(pImpl->keyPtrs.size()),
|
||||
pImpl->keyPtrs.data(), pImpl->valuePtrs.data());
|
||||
if (serviceInst == nullptr) {
|
||||
return;
|
||||
}
|
||||
@@ -168,12 +160,11 @@ void MulticastServiceAnnouncer::Start() {
|
||||
|
||||
pImpl->event = CreateEvent(NULL, true, false, NULL);
|
||||
|
||||
if (pImpl->dynamicDns.DnsServiceRegisterPtr(®isterRequest, nullptr) ==
|
||||
DNS_REQUEST_PENDING) {
|
||||
if (DnsServiceRegister(®isterRequest, nullptr) == DNS_REQUEST_PENDING) {
|
||||
WaitForSingleObject(pImpl->event, INFINITE);
|
||||
}
|
||||
|
||||
pImpl->dynamicDns.DnsServiceFreeInstancePtr(serviceInst);
|
||||
DnsServiceFreeInstance(serviceInst);
|
||||
CloseHandle(pImpl->event);
|
||||
pImpl->event = nullptr;
|
||||
}
|
||||
@@ -183,7 +174,7 @@ static void WINAPI DnsServiceDeRegisterCallback(
|
||||
ImplBase* impl = reinterpret_cast<ImplBase*>(pQueryContext);
|
||||
|
||||
if (pInstance != nullptr) {
|
||||
impl->dynamicDns.DnsServiceFreeInstancePtr(pInstance);
|
||||
DnsServiceFreeInstance(pInstance);
|
||||
pInstance = nullptr;
|
||||
}
|
||||
|
||||
@@ -191,10 +182,6 @@ static void WINAPI DnsServiceDeRegisterCallback(
|
||||
}
|
||||
|
||||
void MulticastServiceAnnouncer::Stop() {
|
||||
if (!pImpl->dynamicDns.CanDnsAnnounce) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pImpl->serviceInstance == nullptr) {
|
||||
return;
|
||||
}
|
||||
@@ -208,12 +195,11 @@ void MulticastServiceAnnouncer::Stop() {
|
||||
registerRequest.pServiceInstance = pImpl->serviceInstance;
|
||||
registerRequest.InterfaceIndex = 0;
|
||||
|
||||
if (pImpl->dynamicDns.DnsServiceDeRegisterPtr(®isterRequest, nullptr) ==
|
||||
DNS_REQUEST_PENDING) {
|
||||
if (DnsServiceDeRegister(®isterRequest, nullptr) == DNS_REQUEST_PENDING) {
|
||||
WaitForSingleObject(pImpl->event, INFINITE);
|
||||
}
|
||||
|
||||
pImpl->dynamicDns.DnsServiceFreeInstancePtr(pImpl->serviceInstance);
|
||||
DnsServiceFreeInstance(pImpl->serviceInstance);
|
||||
pImpl->serviceInstance = nullptr;
|
||||
CloseHandle(pImpl->event);
|
||||
pImpl->event = nullptr;
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
|
||||
#include "wpi/net/MulticastServiceResolver.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <WinDNS.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "DynamicDns.hpp"
|
||||
#include "wpi/util/ConvertUTF.hpp"
|
||||
#include "wpi/util/SmallString.hpp"
|
||||
#include "wpi/util/SmallVector.hpp"
|
||||
@@ -23,7 +25,6 @@
|
||||
using namespace wpi::net;
|
||||
|
||||
struct MulticastServiceResolver::Impl {
|
||||
wpi::net::DynamicDns& dynamicDns = wpi::net::DynamicDns::GetDynamicDns();
|
||||
std::wstring serviceType;
|
||||
DNS_SERVICE_CANCEL serviceCancel{nullptr};
|
||||
|
||||
@@ -39,10 +40,6 @@ MulticastServiceResolver::MulticastServiceResolver(
|
||||
pImpl = std::make_unique<Impl>();
|
||||
pImpl->resolver = this;
|
||||
|
||||
if (!pImpl->dynamicDns.CanDnsResolve) {
|
||||
return;
|
||||
}
|
||||
|
||||
wpi::util::SmallVector<wchar_t, 128> wideStorage;
|
||||
|
||||
if (wpi::util::ends_with_lower(serviceType, ".local")) {
|
||||
@@ -61,7 +58,7 @@ MulticastServiceResolver::~MulticastServiceResolver() noexcept {
|
||||
}
|
||||
|
||||
bool MulticastServiceResolver::HasImplementation() const {
|
||||
return pImpl->dynamicDns.CanDnsResolve;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MulticastServiceResolver::SetCopyCallback(
|
||||
@@ -204,28 +201,20 @@ void MulticastServiceResolver::Start() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pImpl->dynamicDns.CanDnsResolve) {
|
||||
return;
|
||||
}
|
||||
|
||||
DNS_SERVICE_BROWSE_REQUEST request = {};
|
||||
request.InterfaceIndex = 0;
|
||||
request.pQueryContext = pImpl.get();
|
||||
request.QueryName = pImpl->serviceType.c_str();
|
||||
request.Version = 2;
|
||||
request.pBrowseCallbackV2 = DnsCompletion;
|
||||
pImpl->dynamicDns.DnsServiceBrowsePtr(&request, &pImpl->serviceCancel);
|
||||
DnsServiceBrowse(&request, &pImpl->serviceCancel);
|
||||
}
|
||||
|
||||
void MulticastServiceResolver::Stop() {
|
||||
if (!pImpl->dynamicDns.CanDnsResolve) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pImpl->serviceCancel.reserved == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
pImpl->dynamicDns.DnsServiceBrowseCancelPtr(&pImpl->serviceCancel);
|
||||
DnsServiceBrowseCancel(&pImpl->serviceCancel);
|
||||
pImpl->serviceCancel.reserved = nullptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user