From 8c2cd2f60d90afc6e3c23e0e26b43aa9fddbbd68 Mon Sep 17 00:00:00 2001 From: loki-47-6F-64 Date: Sat, 7 Aug 2021 00:05:38 +0200 Subject: [PATCH] Load mDNS at runtime on Windows --- CMakeLists.txt | 4 -- sunshine/platform/windows/publish.cpp | 59 +++++++++++++++------------ 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 704334bf..cd4e7037 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,15 +89,11 @@ if(WIN32) libstdc++.a libwinpthread.a libssp.a - Qwave - winmm ksuser wsock32 ws2_32 - iphlpapi d3d11 dxgi D3DCompiler setupapi - dnsapi ) set_source_files_properties(third-party/ViGEmClient/src/ViGEmClient.cpp PROPERTIES COMPILE_DEFINITIONS "UNICODE=1;ERROR_INVALID_DEVICE_OBJECT_PARAMETER=650") diff --git a/sunshine/platform/windows/publish.cpp b/sunshine/platform/windows/publish.cpp index 652785d0..d981593d 100644 --- a/sunshine/platform/windows/publish.cpp +++ b/sunshine/platform/windows/publish.cpp @@ -15,6 +15,9 @@ #include "sunshine/platform/common.h" #include "sunshine/thread_safe.h" +#define _FN(x, ret, args) \ + typedef ret(*x##_fn) args; \ + static x##_fn x using namespace std::literals; @@ -72,28 +75,9 @@ typedef struct _DNS_SERVICE_REGISTER_REQUEST { BOOL unicastEnabled; } DNS_SERVICE_REGISTER_REQUEST, *PDNS_SERVICE_REGISTER_REQUEST; -VOID DnsServiceFreeInstance( - _In_ PDNS_SERVICE_INSTANCE pInstance); - -DWORD DnsServiceDeRegister( - _In_ PDNS_SERVICE_REGISTER_REQUEST pRequest, - _Inout_opt_ PDNS_SERVICE_CANCEL pCancel); - -DWORD DnsServiceRegister( - _In_ PDNS_SERVICE_REGISTER_REQUEST pRequest, - _Inout_opt_ PDNS_SERVICE_CANCEL pCancel); - -PDNS_SERVICE_INSTANCE DnsServiceConstructInstance( - _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); +_FN(_DnsServiceFreeInstance, VOID, (_In_ PDNS_SERVICE_INSTANCE pInstance)); +_FN(_DnsServiceDeRegister, DWORD, (_In_ PDNS_SERVICE_REGISTER_REQUEST pRequest, _Inout_opt_ PDNS_SERVICE_CANCEL pCancel)); +_FN(_DnsServiceRegister, DWORD, (_In_ PDNS_SERVICE_REGISTER_REQUEST pRequest, _Inout_opt_ PDNS_SERVICE_CANCEL pCancel)); } /* extern "C" */ namespace platf::publish { @@ -102,7 +86,7 @@ VOID WINAPI register_cb(DWORD status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE auto fg = util::fail_guard([&]() { if(pInstance) { - DnsServiceFreeInstance(pInstance); + _DnsServiceFreeInstance(pInstance); } }); @@ -140,10 +124,10 @@ static int service(bool enable) { DNS_STATUS status {}; if(enable) { - status = DnsServiceRegister(&req, nullptr); + status = _DnsServiceRegister(&req, nullptr); } else { - status = DnsServiceDeRegister(&req, nullptr); + status = _DnsServiceDeRegister(&req, nullptr); } alarm->wait(); @@ -168,7 +152,32 @@ public: } }; +int load_funcs(HMODULE handle) { + auto fg = util::fail_guard([handle]() { + FreeLibrary(handle); + }); + + _DnsServiceFreeInstance = (_DnsServiceFreeInstance_fn)GetProcAddress(handle, "DnsServiceFreeInstance"); + _DnsServiceDeRegister = (_DnsServiceDeRegister_fn)GetProcAddress(handle, "DnsServiceDeRegister"); + _DnsServiceRegister = (_DnsServiceRegister_fn)GetProcAddress(handle, "DnsServiceRegister"); + + if(!(_DnsServiceFreeInstance && _DnsServiceDeRegister && _DnsServiceRegister)) { + BOOST_LOG(error) << "mDNS service not available in dnsapi.dll"sv; + return -1; + } + + fg.disable(); + return 0; +} + std::unique_ptr<::platf::deinit_t> start() { + HMODULE handle = LoadLibrary("dnsapi.dll"); + + if(!handle || load_funcs(handle)) { + BOOST_LOG(error) << "Couldn't load dnsapi.dll, You'll need to add PC manually from Moonlight"sv; + return nullptr; + } + if(service(true)) { return nullptr; }