mirror of
https://github.com/moonlight-stream/Internet-Hosting-Tool.git
synced 2025-07-01 15:26:54 +00:00
Compare commits
47 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ddd86d91eb | ||
|
546e30f363 | ||
|
432c2e226c | ||
|
cc98c2cd17 | ||
|
c8a5fe2efa | ||
|
6d5d83d420 | ||
|
1e1d347052 | ||
|
307623914b | ||
|
8f011440b4 | ||
|
771e34f199 | ||
|
c8e8af7d4b | ||
|
18b914d9f6 | ||
|
e9ddf91157 | ||
|
28a5935ee7 | ||
|
ce3b9c3d31 | ||
|
0f3506a92c | ||
|
1e6337b9b0 | ||
|
363b62f69f | ||
|
3175b1c4fa | ||
|
404af38d10 | ||
|
dd72f65ffb | ||
|
6589dc4853 | ||
|
9772139229 | ||
|
03c89e4022 | ||
|
d1fe5f6a9b | ||
|
a88b8d0d04 | ||
|
fa5ae73abb | ||
|
4d197cae02 | ||
|
624af65b55 | ||
|
6b1a0856cc | ||
|
01a1012e74 | ||
|
66b36684ec | ||
|
e7db5242c9 | ||
|
5e09217af4 | ||
|
c21a64c874 | ||
|
ebe91d6799 | ||
|
077c9814e0 | ||
|
393dfb70a7 | ||
|
88fb77083f | ||
|
38514d08c1 | ||
|
5d75b11a35 | ||
|
f511b830ea | ||
|
8a45ea2066 | ||
|
3844ea59de | ||
|
a19b95f259 | ||
|
ae81d4305d | ||
|
8066cf4be1 |
@ -1 +1 @@
|
||||
Subproject commit 665958b7595ff25d181742dc18ddac329ddc7253
|
||||
Subproject commit e0db902f7dffb80aa63d5d330fceed243efe66a4
|
@ -1,9 +1,9 @@
|
||||
/* $Id: miniupnpc.h,v 1.53 2018/05/07 11:05:16 nanard Exp $ */
|
||||
/* $Id: miniupnpc.h,v 1.59 2021/09/28 21:39:17 nanard Exp $ */
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
* Project: miniupnp
|
||||
* http://miniupnp.free.fr/
|
||||
* Author: Thomas Bernard
|
||||
* Copyright (c) 2005-2018 Thomas Bernard
|
||||
* Copyright (c) 2005-2021 Thomas Bernard
|
||||
* This software is subjects to the conditions detailed
|
||||
* in the LICENCE file provided within this distribution */
|
||||
#ifndef MINIUPNPC_H_INCLUDED
|
||||
@ -20,7 +20,7 @@
|
||||
#define UPNPDISCOVER_MEMORY_ERROR (-102)
|
||||
|
||||
/* versions : */
|
||||
#define MINIUPNPC_VERSION "2.1"
|
||||
#define MINIUPNPC_VERSION "2.2.3"
|
||||
#define MINIUPNPC_API_VERSION 17
|
||||
|
||||
/* Source port:
|
||||
|
@ -7,7 +7,7 @@
|
||||
#ifndef MINIUPNPC_SOCKETDEF_H_INCLUDED
|
||||
#define MINIUPNPC_SOCKETDEF_H_INCLUDED
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _WIN32
|
||||
|
||||
#define ISINVALID(s) (INVALID_SOCKET==(s))
|
||||
|
||||
|
@ -1,13 +1,15 @@
|
||||
/* $Id: miniupnpctypes.h,v 1.1 2011/02/15 11:10:40 nanard Exp $ */
|
||||
/* Miniupnp project : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org
|
||||
* Author : Thomas Bernard
|
||||
* Copyright (c) 2011 Thomas Bernard
|
||||
* Copyright (c) 2021 Thomas Bernard
|
||||
* This software is subject to the conditions detailed in the
|
||||
* LICENCE file provided within this distribution */
|
||||
#ifndef MINIUPNPCTYPES_H_INCLUDED
|
||||
#define MINIUPNPCTYPES_H_INCLUDED
|
||||
|
||||
#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
|
||||
/* Use unsigned long long when available :
|
||||
* strtoull is C99 */
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
#define UNSIGNED_INTEGER unsigned long long
|
||||
#define STRTOUI strtoull
|
||||
#else
|
||||
|
65
libs/include/miniupnpc/portlistingparse.h
Normal file
65
libs/include/miniupnpc/portlistingparse.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* $Id: portlistingparse.h,v 1.10 2014/11/01 10:37:32 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2011-2015 Thomas Bernard
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
#ifndef PORTLISTINGPARSE_H_INCLUDED
|
||||
#define PORTLISTINGPARSE_H_INCLUDED
|
||||
|
||||
#include "miniupnpc_declspec.h"
|
||||
/* for the definition of UNSIGNED_INTEGER */
|
||||
#include "miniupnpctypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* sample of PortMappingEntry :
|
||||
<p:PortMappingEntry>
|
||||
<p:NewRemoteHost>202.233.2.1</p:NewRemoteHost>
|
||||
<p:NewExternalPort>2345</p:NewExternalPort>
|
||||
<p:NewProtocol>TCP</p:NewProtocol>
|
||||
<p:NewInternalPort>2345</p:NewInternalPort>
|
||||
<p:NewInternalClient>192.168.1.137</p:NewInternalClient>
|
||||
<p:NewEnabled>1</p:NewEnabled>
|
||||
<p:NewDescription>dooom</p:NewDescription>
|
||||
<p:NewLeaseTime>345</p:NewLeaseTime>
|
||||
</p:PortMappingEntry>
|
||||
*/
|
||||
typedef enum { PortMappingEltNone,
|
||||
PortMappingEntry, NewRemoteHost,
|
||||
NewExternalPort, NewProtocol,
|
||||
NewInternalPort, NewInternalClient,
|
||||
NewEnabled, NewDescription,
|
||||
NewLeaseTime } portMappingElt;
|
||||
|
||||
struct PortMapping {
|
||||
struct PortMapping * l_next; /* list next element */
|
||||
UNSIGNED_INTEGER leaseTime;
|
||||
unsigned short externalPort;
|
||||
unsigned short internalPort;
|
||||
char remoteHost[64];
|
||||
char internalClient[64];
|
||||
char description[64];
|
||||
char protocol[4];
|
||||
unsigned char enabled;
|
||||
};
|
||||
|
||||
struct PortMappingParserData {
|
||||
struct PortMapping * l_head; /* list head */
|
||||
portMappingElt curelt;
|
||||
};
|
||||
|
||||
MINIUPNP_LIBSPEC void
|
||||
ParsePortListing(const char * buffer, int bufsize,
|
||||
struct PortMappingParserData * pdata);
|
||||
|
||||
MINIUPNP_LIBSPEC void
|
||||
FreePortListing(struct PortMappingParserData * pdata);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,8 +1,8 @@
|
||||
/* $Id: upnpdev.h,v 1.1 2015/08/28 12:14:19 nanard Exp $ */
|
||||
/* $Id: upnpdev.h,v 1.4 2021/08/21 09:45:01 nanard Exp $ */
|
||||
/* Project : miniupnp
|
||||
* Web : http://miniupnp.free.fr/
|
||||
* Web : http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
|
||||
* Author : Thomas BERNARD
|
||||
* copyright (c) 2005-2018 Thomas Bernard
|
||||
* copyright (c) 2005-2021 Thomas Bernard
|
||||
* This software is subjet to the conditions detailed in the
|
||||
* provided LICENSE file. */
|
||||
#ifndef UPNPDEV_H_INCLUDED
|
||||
@ -20,7 +20,15 @@ struct UPNPDev {
|
||||
char * st;
|
||||
char * usn;
|
||||
unsigned int scope_id;
|
||||
char buffer[3];
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
/* C99 flexible array member */
|
||||
char buffer[];
|
||||
#elif defined(__GNUC__)
|
||||
char buffer[0];
|
||||
#else
|
||||
/* Fallback to a hack */
|
||||
char buffer[1];
|
||||
#endif
|
||||
};
|
||||
|
||||
/* freeUPNPDevlist()
|
||||
|
63
libs/include/miniupnpc/upnpreplyparse.h
Normal file
63
libs/include/miniupnpc/upnpreplyparse.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* $Id: upnpreplyparse.h,v 1.19 2014/10/27 16:33:19 nanard Exp $ */
|
||||
/* MiniUPnP project
|
||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
||||
* (c) 2006-2013 Thomas Bernard
|
||||
* This software is subject to the conditions detailed
|
||||
* in the LICENCE file provided within the distribution */
|
||||
|
||||
#ifndef UPNPREPLYPARSE_H_INCLUDED
|
||||
#define UPNPREPLYPARSE_H_INCLUDED
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct NameValue {
|
||||
struct NameValue * l_next;
|
||||
char name[64];
|
||||
char value[128];
|
||||
};
|
||||
|
||||
struct NameValueParserData {
|
||||
struct NameValue * l_head;
|
||||
char curelt[64];
|
||||
char * portListing;
|
||||
int portListingLength;
|
||||
int topelt;
|
||||
const char * cdata;
|
||||
int cdatalen;
|
||||
};
|
||||
|
||||
/* ParseNameValue() */
|
||||
void
|
||||
ParseNameValue(const char * buffer, int bufsize,
|
||||
struct NameValueParserData * data);
|
||||
|
||||
/* ClearNameValueList() */
|
||||
void
|
||||
ClearNameValueList(struct NameValueParserData * pdata);
|
||||
|
||||
/* GetValueFromNameValueList() */
|
||||
char *
|
||||
GetValueFromNameValueList(struct NameValueParserData * pdata,
|
||||
const char * Name);
|
||||
|
||||
#if 0
|
||||
/* GetValueFromNameValueListIgnoreNS() */
|
||||
char *
|
||||
GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
|
||||
const char * Name);
|
||||
#endif
|
||||
|
||||
/* DisplayNameValueList() */
|
||||
#ifdef DEBUG
|
||||
void
|
||||
DisplayNameValueList(char * buffer, int bufsize);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -51,6 +51,13 @@ typedef unsigned short uint16_t;
|
||||
#endif /* _WIN32 */
|
||||
#include "natpmp_declspec.h"
|
||||
|
||||
/* Set to 9 by https://tools.ietf.org/html/rfc6886#section-3.1 which leads to a
|
||||
* maximum timeout of 127.75 seconds, due to the initial 250 ms timeout doubling
|
||||
* each time, so we allow a compile-time modification here.*/
|
||||
#ifndef NATPMP_MAX_RETRIES
|
||||
#define NATPMP_MAX_RETRIES (9)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int s; /* socket */
|
||||
in_addr_t gateway; /* default gateway (IPv4) */
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef DECLSPEC_H_INCLUDED
|
||||
#define DECLSPEC_H_INCLUDED
|
||||
#ifndef NATPMP_DECLSPEC_H_INCLUDED
|
||||
#define NATPMP_DECLSPEC_H_INCLUDED
|
||||
|
||||
#if defined(_WIN32) && !defined(NATPMP_STATICLIB)
|
||||
/* for windows dll */
|
||||
|
BIN
libs/x86/Debug/libnatpmp.dll
Normal file
BIN
libs/x86/Debug/libnatpmp.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
libs/x86/Debug/miniupnpc.dll
Normal file
BIN
libs/x86/Debug/miniupnpc.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
libs/x86/Release/libnatpmp.dll
Normal file
BIN
libs/x86/Release/libnatpmp.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
libs/x86/Release/miniupnpc.dll
Normal file
BIN
libs/x86/Release/miniupnpc.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,6 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?define VCREDIST_VER = "14.36.32532.0" ?>
|
||||
<?define VCREDIST_X86_SIZE = "13837672" ?>
|
||||
<?define VCREDIST_X86_SHA1 = "C9B5B7969E499A4FD9E580EF4187322778E1936A" ?>
|
||||
<?define VCREDIST_X86_URL = "https://download.visualstudio.microsoft.com/download/pr/eaab1f82-787d-4fd7-8c73-f782341a0c63/5365A927487945ECB040E143EA770ADBB296074ECE4021B1D14213BDE538C490/VC_redist.x86.exe" ?>
|
||||
<?define VCREDIST_X86_UPGRADE_CODE = "65E5BD06-6392-3027-8C26-853107D3CF1A" ?>
|
||||
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
|
||||
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
|
||||
xmlns:bal="http://schemas.microsoft.com/wix/BalExtension"
|
||||
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
|
||||
<Bundle Name="Moonlight Internet Hosting Tool" Manufacturer="Moonlight Game Streaming Project" Version="!(bind.packageVersion.mish)" UpgradeCode="a2ce5056-1114-44b9-b79b-952ef46d3d50">
|
||||
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
|
||||
<bal:WixStandardBootstrapperApplication
|
||||
@ -12,7 +20,31 @@
|
||||
|
||||
<WixVariable Id="WixUILicenseRtf" Value="" />
|
||||
|
||||
<util:ProductSearch Id="VCREDIST_14_x86"
|
||||
UpgradeCode="$(var.VCREDIST_X86_UPGRADE_CODE)"
|
||||
Result="version"
|
||||
Variable="VCREDIST_14_x86" />
|
||||
|
||||
<Chain>
|
||||
<ExePackage Name="Microsoft Visual C++ 2015-2022 Redistributable - x86"
|
||||
Cache="no"
|
||||
Compressed="no"
|
||||
PerMachine="yes"
|
||||
Permanent="yes"
|
||||
Vital="yes"
|
||||
InstallCommand="/install /quiet /norestart"
|
||||
DownloadUrl="$(var.VCREDIST_X86_URL)"
|
||||
DetectCondition="VCREDIST_14_x86 >= v$(var.VCREDIST_VER)">
|
||||
|
||||
<RemotePayload Description="Microsoft Visual C++ 2015-2022 Redistributable - x86"
|
||||
ProductName="Microsoft Visual C++ 2015-2022 Redistributable - x86"
|
||||
Size="$(var.VCREDIST_X86_SIZE)"
|
||||
Version="$(var.VCREDIST_VER)"
|
||||
Hash="$(var.VCREDIST_X86_SHA1)"/>
|
||||
|
||||
<!-- Newer version installed is fine -->
|
||||
<ExitCode Value="1638" Behavior="success" />
|
||||
</ExePackage>
|
||||
<MsiPackage Id="mish" SourceFile="$(var.mish.TargetPath)" />
|
||||
<MsiPackage SourceFile="$(var.GSv6FwdSetup.TargetPath)" />
|
||||
</Chain>
|
||||
|
@ -26,6 +26,10 @@
|
||||
<HintPath>$(WixExtDir)\WixBalExtension.dll</HintPath>
|
||||
<Name>WixBalExtension</Name>
|
||||
</WixExtension>
|
||||
<WixExtension Include="WixUtilExtension">
|
||||
<HintPath>$(WixExtDir)\WixUtilExtension.dll</HintPath>
|
||||
<Name>WixUtilExtension</Name>
|
||||
</WixExtension>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GS-IPv6-Forwarder\GSv6FwdSetup\GSv6FwdSetup.wixproj">
|
||||
|
20
mish.sln
20
mish.sln
@ -17,52 +17,32 @@ Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "GSv6FwdSetup", "GS-IPv6-For
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B71C4E7F-0D92-4E19-BBD2-D33F0EF879B1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B71C4E7F-0D92-4E19-BBD2-D33F0EF879B1}.Debug|x64.Build.0 = Debug|x64
|
||||
{B71C4E7F-0D92-4E19-BBD2-D33F0EF879B1}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B71C4E7F-0D92-4E19-BBD2-D33F0EF879B1}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B71C4E7F-0D92-4E19-BBD2-D33F0EF879B1}.Release|x64.ActiveCfg = Release|x64
|
||||
{B71C4E7F-0D92-4E19-BBD2-D33F0EF879B1}.Release|x64.Build.0 = Release|x64
|
||||
{B71C4E7F-0D92-4E19-BBD2-D33F0EF879B1}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B71C4E7F-0D92-4E19-BBD2-D33F0EF879B1}.Release|x86.Build.0 = Release|Win32
|
||||
{8F78D8D2-A837-489C-BAC5-81494C9CEF7A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8F78D8D2-A837-489C-BAC5-81494C9CEF7A}.Debug|x64.Build.0 = Debug|x64
|
||||
{8F78D8D2-A837-489C-BAC5-81494C9CEF7A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{8F78D8D2-A837-489C-BAC5-81494C9CEF7A}.Debug|x86.Build.0 = Debug|Win32
|
||||
{8F78D8D2-A837-489C-BAC5-81494C9CEF7A}.Release|x64.ActiveCfg = Release|x64
|
||||
{8F78D8D2-A837-489C-BAC5-81494C9CEF7A}.Release|x64.Build.0 = Release|x64
|
||||
{8F78D8D2-A837-489C-BAC5-81494C9CEF7A}.Release|x86.ActiveCfg = Release|Win32
|
||||
{8F78D8D2-A837-489C-BAC5-81494C9CEF7A}.Release|x86.Build.0 = Release|Win32
|
||||
{F0DEE5F3-4B62-47A3-B00B-61C614C924FD}.Debug|x64.ActiveCfg = Debug|x86
|
||||
{F0DEE5F3-4B62-47A3-B00B-61C614C924FD}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{F0DEE5F3-4B62-47A3-B00B-61C614C924FD}.Debug|x86.Build.0 = Debug|x86
|
||||
{F0DEE5F3-4B62-47A3-B00B-61C614C924FD}.Release|x64.ActiveCfg = Release|x86
|
||||
{F0DEE5F3-4B62-47A3-B00B-61C614C924FD}.Release|x86.ActiveCfg = Release|x86
|
||||
{F0DEE5F3-4B62-47A3-B00B-61C614C924FD}.Release|x86.Build.0 = Release|x86
|
||||
{A2CE5056-1114-44B9-B79B-952EF46D3D50}.Debug|x64.ActiveCfg = Debug|x86
|
||||
{A2CE5056-1114-44B9-B79B-952EF46D3D50}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{A2CE5056-1114-44B9-B79B-952EF46D3D50}.Debug|x86.Build.0 = Debug|x86
|
||||
{A2CE5056-1114-44B9-B79B-952EF46D3D50}.Release|x64.ActiveCfg = Release|x86
|
||||
{A2CE5056-1114-44B9-B79B-952EF46D3D50}.Release|x86.ActiveCfg = Release|x86
|
||||
{A2CE5056-1114-44B9-B79B-952EF46D3D50}.Release|x86.Build.0 = Release|x86
|
||||
{87DEAE49-7638-4CDB-88EB-054B1F3CB0D2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{87DEAE49-7638-4CDB-88EB-054B1F3CB0D2}.Debug|x64.Build.0 = Debug|x64
|
||||
{87DEAE49-7638-4CDB-88EB-054B1F3CB0D2}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{87DEAE49-7638-4CDB-88EB-054B1F3CB0D2}.Debug|x86.Build.0 = Debug|Win32
|
||||
{87DEAE49-7638-4CDB-88EB-054B1F3CB0D2}.Release|x64.ActiveCfg = Release|x64
|
||||
{87DEAE49-7638-4CDB-88EB-054B1F3CB0D2}.Release|x64.Build.0 = Release|x64
|
||||
{87DEAE49-7638-4CDB-88EB-054B1F3CB0D2}.Release|x86.ActiveCfg = Release|Win32
|
||||
{87DEAE49-7638-4CDB-88EB-054B1F3CB0D2}.Release|x86.Build.0 = Release|Win32
|
||||
{F8171B99-F5F9-4ABF-9FE5-6753539611AF}.Debug|x64.ActiveCfg = Debug|x86
|
||||
{F8171B99-F5F9-4ABF-9FE5-6753539611AF}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{F8171B99-F5F9-4ABF-9FE5-6753539611AF}.Debug|x86.Build.0 = Debug|x86
|
||||
{F8171B99-F5F9-4ABF-9FE5-6753539611AF}.Release|x64.ActiveCfg = Release|x86
|
||||
{F8171B99-F5F9-4ABF-9FE5-6753539611AF}.Release|x86.ActiveCfg = Release|x86
|
||||
{F8171B99-F5F9-4ABF-9FE5-6753539611AF}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
|
@ -52,6 +52,12 @@
|
||||
|
||||
<Fragment>
|
||||
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
|
||||
<Component Id="MiniupnpcDll">
|
||||
<File Source="$(var.miss.TargetDir)miniupnpc.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Id="LibnatpmpDll">
|
||||
<File Source="$(var.miss.TargetDir)libnatpmp.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Id="MISS">
|
||||
<File Source="$(var.miss.TargetPath)" KeyPath="yes">
|
||||
<fire:FirewallException Id="MISSFwException"
|
||||
@ -117,6 +123,11 @@
|
||||
Port="48010"
|
||||
Protocol="udp"
|
||||
Name="Moonlight - RTSPU"/>
|
||||
<fire:FirewallException Id="MdnsFwException"
|
||||
Scope="any"
|
||||
Port="5353"
|
||||
Protocol="udp"
|
||||
Name="Moonlight - mDNS"/>
|
||||
</Component>
|
||||
<Component Id="Shortcuts" Guid="*">
|
||||
<Shortcut Id="StartMenuShortcut"
|
||||
|
301
miss/miss.cpp
301
miss/miss.cpp
@ -32,8 +32,6 @@ bool getHopsIP4(IN_ADDR* hopAddress, int* hopAddressCount);
|
||||
struct UPNPDev* getUPnPDevicesByAddress(IN_ADDR address);
|
||||
bool PCPMapPort(PSOCKADDR_STORAGE localAddr, int localAddrLen, PSOCKADDR_STORAGE pcpAddr, int pcpAddrLen, int proto, int port, bool enable, bool indefinite);
|
||||
|
||||
#define NL "\n"
|
||||
|
||||
#define SERVICE_NAME "MISS"
|
||||
#define UPNP_SERVICE_NAME "Moonlight"
|
||||
#define POLLING_DELAY_SEC 120
|
||||
@ -57,6 +55,9 @@ static struct port_entry {
|
||||
|
||||
static const int k_WolPorts[] = { 9, 47009 };
|
||||
|
||||
static HANDLE s_StopEvent;
|
||||
static CRITICAL_SECTION s_PortMappingUpdateLock;
|
||||
|
||||
bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const char* myAddr, int port, bool enable, bool indefinite, bool validationPass)
|
||||
{
|
||||
char intClient[16];
|
||||
@ -96,7 +97,7 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
|
||||
intClient, intPort, desc, enabled, leaseDuration);
|
||||
if (err == 714) {
|
||||
// NoSuchEntryInArray
|
||||
printf("NOT FOUND" NL);
|
||||
printf("NOT FOUND\n");
|
||||
|
||||
if (validationPass) {
|
||||
// On validation, we found a missing entry. Convert this entry to indefinite
|
||||
@ -105,7 +106,7 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
|
||||
}
|
||||
}
|
||||
else if (err == 606) {
|
||||
printf("UNAUTHORIZED" NL);
|
||||
printf("UNAUTHORIZED\n");
|
||||
|
||||
// If we're just validating, we're done. We can't know if the entry was
|
||||
// actually applied but we'll return true to avoid false errors if it was.
|
||||
@ -117,7 +118,7 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
|
||||
// Some routers change the description, so we can't check that here
|
||||
if (!strcmp(intClient, myAddr)) {
|
||||
if (atoi(leaseDuration) == 0) {
|
||||
printf("OK (Static, Internal port: %s)" NL, intPort);
|
||||
printf("OK (Static, Internal port: %s)\n", intPort);
|
||||
|
||||
// If we have an existing permanent mapping, we can just leave it alone.
|
||||
if (enable) {
|
||||
@ -125,7 +126,7 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("OK (%s seconds remaining, Internal port: %s)" NL, leaseDuration, intPort);
|
||||
printf("OK (%s seconds remaining, Internal port: %s)\n", leaseDuration, intPort);
|
||||
}
|
||||
|
||||
// If we're just validating, we found an entry, so we're done.
|
||||
@ -138,17 +139,17 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
|
||||
printf("Deleting UPnP mapping for %s %s -> %s...", protoStr, portStr, myAddr);
|
||||
err = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, portStr, protoStr, nullptr);
|
||||
if (err == UPNPCOMMAND_SUCCESS) {
|
||||
printf("OK" NL);
|
||||
printf("OK\n");
|
||||
}
|
||||
else {
|
||||
printf("ERROR %d" NL, err);
|
||||
printf("ERROR %d\n", err);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("CONFLICT: %s %s" NL, intClient, desc);
|
||||
printf("CONFLICT: %s %s\n", intClient, desc);
|
||||
|
||||
// If we're just validating, we found an entry, so we're done.
|
||||
if (validationPass) {
|
||||
@ -163,21 +164,21 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
|
||||
printf("Trying to delete conflicting UPnP mapping for %s %s -> %s...", protoStr, portStr, intClient);
|
||||
err = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, portStr, protoStr, nullptr);
|
||||
if (err == UPNPCOMMAND_SUCCESS) {
|
||||
printf("OK" NL);
|
||||
printf("OK\n");
|
||||
}
|
||||
else if (err == 606) {
|
||||
printf("UNAUTHORIZED" NL);
|
||||
printf("UNAUTHORIZED\n");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
printf("ERROR %d" NL, err);
|
||||
printf("ERROR %d\n", err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("ERROR %d (%s)" NL, err, strupnperror(err));
|
||||
printf("ERROR %d (%s)\n", err, strupnperror(err));
|
||||
|
||||
// If we get a strange error from the router, we'll assume it's some old broken IGDv1
|
||||
// device and only use indefinite lease durations to hopefully avoid confusing it.
|
||||
@ -223,11 +224,11 @@ bool UPnPMapPort(struct UPNPUrls* urls, struct IGDdatas* data, int proto, const
|
||||
printf("ALTERNATE ");
|
||||
}
|
||||
if (err == UPNPCOMMAND_SUCCESS) {
|
||||
printf("OK" NL);
|
||||
printf("OK\n");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
printf("ERROR %d (%s)" NL, err, strupnperror(err));
|
||||
printf("ERROR %d (%s)\n", err, strupnperror(err));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -249,7 +250,7 @@ bool GetIP4OnLinkPrefixLength(char* lanAddressString, int* prefixLength)
|
||||
free(addresses);
|
||||
addresses = (PIP_ADAPTER_ADDRESSES)malloc(length);
|
||||
if (addresses == NULL) {
|
||||
printf("malloc(%u) failed" NL, length);
|
||||
printf("malloc(%u) failed\n", length);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -265,7 +266,7 @@ bool GetIP4OnLinkPrefixLength(char* lanAddressString, int* prefixLength)
|
||||
} while (error == ERROR_BUFFER_OVERFLOW);
|
||||
|
||||
if (error != ERROR_SUCCESS) {
|
||||
printf("GetAdaptersAddresses() failed: %d" NL, error);
|
||||
printf("GetAdaptersAddresses() failed: %d\n", error);
|
||||
free(addresses);
|
||||
return false;
|
||||
}
|
||||
@ -291,7 +292,7 @@ bool GetIP4OnLinkPrefixLength(char* lanAddressString, int* prefixLength)
|
||||
currentAdapter = currentAdapter->Next;
|
||||
}
|
||||
|
||||
printf("No adapter found with IPv4 address: %s" NL, lanAddressString);
|
||||
printf("No adapter found with IPv4 address: %s\n", lanAddressString);
|
||||
free(addresses);
|
||||
return false;
|
||||
}
|
||||
@ -307,31 +308,31 @@ bool UPnPHandleDeviceList(struct UPNPDev* list, bool enable, char* lanAddrOverri
|
||||
|
||||
int ret = UPNP_GetValidIGD(list, &urls, &data, localAddress, sizeof(localAddress));
|
||||
if (ret == 0) {
|
||||
printf("No UPnP device found!" NL);
|
||||
printf("No UPnP device found!\n");
|
||||
return false;
|
||||
}
|
||||
else if (ret == 3) {
|
||||
printf("No UPnP IGD found!" NL);
|
||||
printf("No UPnP IGD found!\n");
|
||||
FreeUPNPUrls(&urls);
|
||||
return false;
|
||||
}
|
||||
else if (ret == 1) {
|
||||
printf("Found a connected UPnP IGD" NL);
|
||||
printf("Found a connected UPnP IGD (%s)\n", urls.rootdescURL);
|
||||
}
|
||||
else if (ret == 2) {
|
||||
printf("Found a disconnected UPnP IGD (!)" NL);
|
||||
printf("Found a disconnected (!) UPnP IGD (%s)\n", urls.rootdescURL);
|
||||
|
||||
// Even if we are able to add forwarding entries, go ahead and try NAT-PMP
|
||||
success = false;
|
||||
}
|
||||
else {
|
||||
printf("UPNP_GetValidIGD() failed: %d" NL, ret);
|
||||
printf("UPNP_GetValidIGD() failed: %d\n", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, wanAddr);
|
||||
if (ret == UPNPCOMMAND_SUCCESS) {
|
||||
printf("UPnP IGD WAN address is: %s" NL, wanAddr);
|
||||
printf("UPnP IGD WAN address is: %s\n", wanAddr);
|
||||
}
|
||||
else {
|
||||
// Empty string
|
||||
@ -384,17 +385,21 @@ bool UPnPHandleDeviceList(struct UPNPDev* list, bool enable, char* lanAddrOverri
|
||||
|
||||
// Validate the rules are present and correct if they claimed to be added successfully
|
||||
if (success && enable) {
|
||||
// Wait 10 seconds for the router state to quiesce
|
||||
// Wait 10 seconds for the router state to quiesce or the stop event to be set
|
||||
printf("Waiting before UPnP port validation...");
|
||||
Sleep(10000);
|
||||
printf("done" NL);
|
||||
if (WaitForSingleObject(s_StopEvent, 10000) == WAIT_TIMEOUT) {
|
||||
printf("done\n");
|
||||
|
||||
// Perform the validation pass (converting any now missing entries to permanent ones)
|
||||
for (int i = 0; i < ARRAYSIZE(k_Ports); i++) {
|
||||
if (!UPnPMapPort(&urls, &data, k_Ports[i].proto, portMappingInternalAddress, k_Ports[i].port, enable, false, true)) {
|
||||
success = false;
|
||||
// Perform the validation pass (converting any now missing entries to permanent ones)
|
||||
for (int i = 0; i < ARRAYSIZE(k_Ports); i++) {
|
||||
if (!UPnPMapPort(&urls, &data, k_Ports[i].proto, portMappingInternalAddress, k_Ports[i].port, enable, false, true)) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("aborted\n");
|
||||
}
|
||||
}
|
||||
|
||||
FreeUPNPUrls(&urls);
|
||||
@ -433,7 +438,7 @@ bool NATPMPMapPort(natpmp_t* natpmp, int proto, int port, bool enable, bool inde
|
||||
printf("Updating NAT-PMP port mapping for %s %d...", proto == IPPROTO_TCP ? "TCP" : "UDP", port);
|
||||
int err = sendnewportmappingrequest(natpmp, natPmpProto, port, enable ? port : 0, lifetime);
|
||||
if (err < 0) {
|
||||
printf("ERROR %d" NL, err);
|
||||
printf("ERROR %d\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -449,7 +454,7 @@ bool NATPMPMapPort(natpmp_t* natpmp, int proto, int port, bool enable, bool inde
|
||||
err = getnatpmprequesttimeout(natpmp, &timeout);
|
||||
if (err != 0) {
|
||||
assert(err == 0);
|
||||
printf("WAIT FAILED: %d" NL, err);
|
||||
printf("WAIT FAILED: %d\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -459,22 +464,22 @@ bool NATPMPMapPort(natpmp_t* natpmp, int proto, int port, bool enable, bool inde
|
||||
} while (err == NATPMP_TRYAGAIN);
|
||||
|
||||
if (err != 0) {
|
||||
printf("FAILED %d" NL, err);
|
||||
printf("FAILED %d\n", err);
|
||||
return false;
|
||||
}
|
||||
else if (response.pnu.newportmapping.lifetime == 0 && !enable) {
|
||||
printf("DELETED" NL);
|
||||
printf("DELETED\n");
|
||||
return true;
|
||||
}
|
||||
else if (response.pnu.newportmapping.mappedpublicport != port) {
|
||||
printf("CONFLICT" NL);
|
||||
printf("CONFLICT\n");
|
||||
|
||||
// It couldn't assign us the external port we requested and gave us an alternate external port.
|
||||
// We can't use this alternate mapping, so immediately release it.
|
||||
printf("Deleting unwanted NAT-PMP mapping for %s %d...", proto == IPPROTO_TCP ? "TCP" : "UDP", response.pnu.newportmapping.mappedpublicport);
|
||||
err = sendnewportmappingrequest(natpmp, natPmpProto, response.pnu.newportmapping.privateport, 0, 0);
|
||||
if (err < 0) {
|
||||
printf("ERROR %d" NL, err);
|
||||
printf("ERROR %d\n", err);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
@ -488,7 +493,7 @@ bool NATPMPMapPort(natpmp_t* natpmp, int proto, int port, bool enable, bool inde
|
||||
err = getnatpmprequesttimeout(natpmp, &timeout);
|
||||
if (err != 0) {
|
||||
assert(err == 0);
|
||||
printf("WAIT FAILED: %d" NL, err);
|
||||
printf("WAIT FAILED: %d\n", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -498,17 +503,17 @@ bool NATPMPMapPort(natpmp_t* natpmp, int proto, int port, bool enable, bool inde
|
||||
} while (err == NATPMP_TRYAGAIN);
|
||||
|
||||
if (err == 0) {
|
||||
printf("OK" NL);
|
||||
printf("OK\n");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
printf("FAILED %d" NL, err);
|
||||
printf("FAILED %d\n", err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("OK (%d seconds remaining)" NL, response.pnu.newportmapping.lifetime);
|
||||
printf("OK (%d seconds remaining)\n", response.pnu.newportmapping.lifetime);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -530,17 +535,47 @@ bool IsGameStreamEnabled()
|
||||
error = RegQueryValueExA(key, "EnableStreaming", nullptr, nullptr, (LPBYTE)&enabled, &len);
|
||||
RegCloseKey(key);
|
||||
if (error != ERROR_SUCCESS) {
|
||||
printf("RegQueryValueExA() failed: %d" NL, error);
|
||||
printf("RegQueryValueExA() failed: %d\n", error);
|
||||
return false;
|
||||
}
|
||||
else if (!enabled) {
|
||||
printf("GameStream is OFF!" NL);
|
||||
|
||||
return enabled != 0;
|
||||
}
|
||||
|
||||
bool IsAlternateHostSoftwareRunning()
|
||||
{
|
||||
int err;
|
||||
PMIB_TCPTABLE tcp_table = nullptr;
|
||||
ULONG table_size = 0;
|
||||
|
||||
do {
|
||||
// Query all open TCPv4 sockets
|
||||
err = GetTcpTable(tcp_table, &table_size, false);
|
||||
if (err == ERROR_INSUFFICIENT_BUFFER) {
|
||||
free(tcp_table);
|
||||
tcp_table = (PMIB_TCPTABLE)malloc(table_size);
|
||||
}
|
||||
} while (err == ERROR_INSUFFICIENT_BUFFER);
|
||||
|
||||
if (!tcp_table || err != NO_ERROR) {
|
||||
printf("GetTcpTable() failed: %d\n", err);
|
||||
free(tcp_table);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
printf("GameStream is ON!" NL);
|
||||
return true;
|
||||
|
||||
bool result = false;
|
||||
for (DWORD i = 0; i < tcp_table->dwNumEntries; i++) {
|
||||
auto& entry = tcp_table->table[i];
|
||||
|
||||
// Look for TCP 47989 port in the listening state
|
||||
if (entry.dwLocalPort == _byteswap_ushort(47989) && entry.dwState == MIB_TCP_STATE_LISTEN) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(tcp_table);
|
||||
return result;
|
||||
}
|
||||
|
||||
void UpdatePortMappingsForTarget(bool enable, char* targetAddressIP4, char* internalAddressIP4, char* upstreamAddressIP4)
|
||||
@ -551,18 +586,18 @@ void UpdatePortMappingsForTarget(bool enable, char* targetAddressIP4, char* inte
|
||||
char upstreamAddrNatPmp[128] = {};
|
||||
char upstreamAddrUPnP[128] = {};
|
||||
|
||||
printf("Starting port mapping update on %s to %s..." NL,
|
||||
printf("Starting port mapping update on %s to %s...\n",
|
||||
targetAddressIP4 ? targetAddressIP4 : "default gateway",
|
||||
internalAddressIP4 ? internalAddressIP4 : "local machine");
|
||||
|
||||
int natPmpErr = initnatpmp(&natpmp, targetAddressIP4 ? 1 : 0, targetAddressIP4 ? inet_addr(targetAddressIP4) : 0);
|
||||
if (natPmpErr != 0) {
|
||||
printf("initnatpmp() failed: %d" NL, natPmpErr);
|
||||
printf("initnatpmp() failed: %d\n", natPmpErr);
|
||||
}
|
||||
else {
|
||||
natPmpErr = sendpublicaddressrequest(&natpmp);
|
||||
if (natPmpErr < 0) {
|
||||
printf("sendpublicaddressrequest() failed: %d" NL, natPmpErr);
|
||||
printf("sendpublicaddressrequest() failed: %d\n", natPmpErr);
|
||||
closenatpmp(&natpmp);
|
||||
}
|
||||
}
|
||||
@ -576,7 +611,7 @@ void UpdatePortMappingsForTarget(bool enable, char* targetAddressIP4, char* inte
|
||||
if (targetAddressIP4 == nullptr) {
|
||||
// If we have no target, use discovery to find the first hop
|
||||
ipv4Devs = upnpDiscoverAll(UPNP_DISCOVERY_DELAY_MS, nullptr, nullptr, UPNP_LOCAL_PORT_ANY, 0, 2, &upnpErr);
|
||||
printf("UPnP IPv4 IGD discovery completed with error code: %d" NL, upnpErr);
|
||||
printf("UPnP IPv4 IGD discovery completed with error code: %d\n", upnpErr);
|
||||
}
|
||||
else {
|
||||
// We have a specified target, so do discovery against that directly (may be outside our subnet in case of double-NAT)
|
||||
@ -585,23 +620,29 @@ void UpdatePortMappingsForTarget(bool enable, char* targetAddressIP4, char* inte
|
||||
ipv4Devs = getUPnPDevicesByAddress(addr);
|
||||
}
|
||||
|
||||
// Abort if this is an add/update request and we're stopping
|
||||
if (enable && WaitForSingleObject(s_StopEvent, 0) == WAIT_OBJECT_0) {
|
||||
printf("Aborting port mapping update due to stop request\n");
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
// Use the delay of discovery to also allow the NAT-PMP endpoint time to respond
|
||||
if (natPmpErr >= 0) {
|
||||
natpmpresp_t response;
|
||||
natPmpErr = readnatpmpresponseorretry(&natpmp, &response);
|
||||
if (natPmpErr == 0) {
|
||||
inet_ntop(AF_INET, &response.pnu.publicaddress.addr, upstreamAddrNatPmp, sizeof(upstreamAddrNatPmp));
|
||||
printf("NAT-PMP upstream address is: %s" NL, upstreamAddrNatPmp);
|
||||
printf("NAT-PMP upstream address is: %s\n", upstreamAddrNatPmp);
|
||||
}
|
||||
else {
|
||||
printf("NAT-PMP public address request failed: %d" NL, natPmpErr);
|
||||
printf("NAT-PMP public address request failed: %d\n", natPmpErr);
|
||||
closenatpmp(&natpmp);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't try NAT-PMP if UPnP succeeds
|
||||
if (UPnPHandleDeviceList(ipv4Devs, enable, internalAddressIP4, upstreamAddrUPnP)) {
|
||||
printf("UPnP IPv4 port mapping successful" NL);
|
||||
printf("UPnP IPv4 port mapping successful\n");
|
||||
if (enable) {
|
||||
// We still want to try NAT-PMP if we're removing
|
||||
// rules to ensure any NAT-PMP rules get cleaned up
|
||||
@ -620,7 +661,7 @@ void UpdatePortMappingsForTarget(bool enable, char* targetAddressIP4, char* inte
|
||||
// if we created the rules we'd be deleting. Since we don't have that, we can't
|
||||
// safely remove mappings that could be shared by another machine behind a double NAT.
|
||||
if (!enable && targetAddressIP4 != nullptr) {
|
||||
printf("Not removing upstream NAT-PMP mappings on non-default gateway device" NL);
|
||||
printf("Not removing upstream NAT-PMP mappings on non-default gateway device\n");
|
||||
tryNatPmp = false;
|
||||
}
|
||||
|
||||
@ -656,7 +697,7 @@ void UpdatePortMappingsForTarget(bool enable, char* targetAddressIP4, char* inte
|
||||
}
|
||||
|
||||
if (success) {
|
||||
printf("NAT-PMP IPv4 port mapping successful" NL);
|
||||
printf("NAT-PMP IPv4 port mapping successful\n");
|
||||
|
||||
// Always try all possibilities when disabling to ensure
|
||||
// we completely clean up
|
||||
@ -688,7 +729,7 @@ void UpdatePortMappingsForTarget(bool enable, char* targetAddressIP4, char* inte
|
||||
targetAddr.sin_addr.S_un.S_addr = route.dwForwardNextHop;
|
||||
}
|
||||
else {
|
||||
printf("GetBestRoute() failed: %d" NL, error);
|
||||
printf("GetBestRoute() failed: %d\n", error);
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
@ -716,22 +757,22 @@ void UpdatePortMappingsForTarget(bool enable, char* targetAddressIP4, char* inte
|
||||
}
|
||||
|
||||
if (success) {
|
||||
printf("PCP IPv4 port mapping successful" NL);
|
||||
printf("PCP IPv4 port mapping successful\n");
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
// Write this at the end to avoid clobbering an input parameter
|
||||
if (upstreamAddrNatPmp[0] != 0 && inet_addr(upstreamAddrNatPmp) != 0) {
|
||||
printf("Using NAT-PMP upstream IPv4 address: %s" NL, upstreamAddrNatPmp);
|
||||
printf("Using NAT-PMP upstream IPv4 address: %s\n", upstreamAddrNatPmp);
|
||||
strcpy(upstreamAddressIP4, upstreamAddrNatPmp);
|
||||
}
|
||||
else if (upstreamAddrUPnP[0] != 0 && inet_addr(upstreamAddrUPnP) != 0) {
|
||||
printf("Using UPnP upstream IPv4 address: %s" NL, upstreamAddrUPnP);
|
||||
printf("Using UPnP upstream IPv4 address: %s\n", upstreamAddrUPnP);
|
||||
strcpy(upstreamAddressIP4, upstreamAddrUPnP);
|
||||
}
|
||||
else {
|
||||
printf("No valid upstream IPv4 address found!" NL);
|
||||
printf("No valid upstream IPv4 address found!\n");
|
||||
upstreamAddressIP4[0] = 0;
|
||||
}
|
||||
}
|
||||
@ -767,12 +808,12 @@ void UpdatePortMappings(bool enable)
|
||||
char upstreamAddrStr[128];
|
||||
unsigned long upstreamAddr;
|
||||
|
||||
printf("Finding upstream IPv4 hops via traceroute..." NL);
|
||||
printf("Finding upstream IPv4 hops via traceroute...\n");
|
||||
if (!getHopsIP4(hops, &hopCount)) {
|
||||
hopCount = 0;
|
||||
}
|
||||
else {
|
||||
printf("Found %d hops" NL, hopCount);
|
||||
printf("Found %d hops\n", hopCount);
|
||||
}
|
||||
|
||||
// getHopsIP4() already skips the default gateway, so 0
|
||||
@ -784,10 +825,10 @@ void UpdatePortMappings(bool enable)
|
||||
while (upstreamAddrStr[0] != 0 && (upstreamAddr = inet_addr(upstreamAddrStr)) != 0) {
|
||||
// We got an upstream address. Let's check if this is a NAT
|
||||
if (IsLikelyNAT(upstreamAddr)) {
|
||||
printf("Upstream address %s is likely a NAT" NL, upstreamAddrStr);
|
||||
printf("Upstream address %s is likely a NAT\n", upstreamAddrStr);
|
||||
|
||||
if (nextHopIndex >= hopCount) {
|
||||
printf("Traceroute didn't reach this hop! Aborting!" NL);
|
||||
printf("Traceroute didn't reach this hop! Aborting!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -801,7 +842,7 @@ void UpdatePortMappings(bool enable)
|
||||
}
|
||||
else {
|
||||
// If we reach a proper public IP address, we're done
|
||||
printf("Reached the Internet at hop %d" NL, nextHopIndex);
|
||||
printf("Reached the Internet at hop %d\n", nextHopIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -837,49 +878,72 @@ void ResetLogFile(bool standaloneExe)
|
||||
MoveFileExA(currentLogFilePath, oldLogFilePath, MOVEFILE_REPLACE_EXISTING);
|
||||
|
||||
// Redirect stdout to this new file
|
||||
freopen(currentLogFilePath, "w", stdout);
|
||||
if (freopen(currentLogFilePath, "w", stdout) == NULL) {
|
||||
// If we couldn't create a log file, just redirect stdout to NUL.
|
||||
// We have to open _something_ or printf() will crash.
|
||||
freopen("NUL", "w", stdout);
|
||||
}
|
||||
}
|
||||
|
||||
// Print a log header
|
||||
printf("Moonlight Internet Streaming Service v" VER_VERSION_STR NL);
|
||||
printf("Moonlight Internet Streaming Service v" VER_VERSION_STR "\n");
|
||||
|
||||
// Print the current time
|
||||
GetSystemTime(&time);
|
||||
GetTimeFormatA(LOCALE_SYSTEM_DEFAULT, 0, &time, "hh':'mm':'ss tt", timeString, ARRAYSIZE(timeString));
|
||||
printf("The current UTC time is: %s" NL, timeString);
|
||||
printf("The current UTC time is: %s\n", timeString);
|
||||
}
|
||||
|
||||
DWORD WINAPI GameStreamStateChangeThread(PVOID Context)
|
||||
{
|
||||
HKEY key;
|
||||
DWORD err;
|
||||
|
||||
// We're watching this key that way we can still detect GameStream turning on
|
||||
// if GFE wasn't even installed when our service started
|
||||
DWORD err = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\NVIDIA Corporation", 0, KEY_READ | KEY_WOW64_64KEY, &key);
|
||||
if (err != ERROR_SUCCESS) {
|
||||
printf("RegOpenKeyExA() failed: %d" NL, err);
|
||||
return err;
|
||||
}
|
||||
do {
|
||||
// We're watching this key that way we can still detect GameStream turning on
|
||||
// if GFE wasn't even installed when our service started
|
||||
do {
|
||||
err = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\NVIDIA Corporation", 0, KEY_READ | KEY_WOW64_64KEY, &key);
|
||||
if (err != ERROR_SUCCESS) {
|
||||
// Wait 10 seconds and try again
|
||||
Sleep(10000);
|
||||
}
|
||||
} while (err != ERROR_SUCCESS);
|
||||
|
||||
// Notify the main thread when the GameStream state changes
|
||||
bool lastGameStreamState = IsGameStreamEnabled();
|
||||
while ((err = RegNotifyChangeKeyValue(key, true, REG_NOTIFY_CHANGE_LAST_SET, nullptr, false)) == ERROR_SUCCESS) {
|
||||
bool currentGameStreamState = IsGameStreamEnabled();
|
||||
if (lastGameStreamState != currentGameStreamState) {
|
||||
SetEvent((HANDLE)Context);
|
||||
// Notify the main thread when the GameStream state changes
|
||||
bool lastGameStreamState = IsGameStreamEnabled();
|
||||
while ((err = RegNotifyChangeKeyValue(key, true, REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, nullptr, false)) == ERROR_SUCCESS) {
|
||||
bool currentGameStreamState = IsGameStreamEnabled();
|
||||
if (lastGameStreamState != currentGameStreamState) {
|
||||
SetEvent((HANDLE)Context);
|
||||
}
|
||||
lastGameStreamState = currentGameStreamState;
|
||||
}
|
||||
lastGameStreamState = currentGameStreamState;
|
||||
|
||||
// If the key is deleted (by DDU or similar), we will hit this code path and poll until it comes back.
|
||||
RegCloseKey(key);
|
||||
} while (err == ERROR_KEY_DELETED);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int Initialize()
|
||||
{
|
||||
// Create the stop event
|
||||
s_StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (s_StopEvent == NULL) {
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
printf("RegNotifyChangeKeyValue() failed: %d" NL, err);
|
||||
return err;
|
||||
InitializeCriticalSection(&s_PortMappingUpdateLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Run(bool standaloneExe)
|
||||
{
|
||||
HANDLE ifaceChangeEvent = CreateEvent(nullptr, true, false, nullptr);
|
||||
HANDLE gsChangeEvent = CreateEvent(nullptr, true, false, nullptr);
|
||||
HANDLE events[2] = { ifaceChangeEvent, gsChangeEvent };
|
||||
HANDLE events[3] = { ifaceChangeEvent, gsChangeEvent, s_StopEvent };
|
||||
|
||||
ResetLogFile(standaloneExe);
|
||||
|
||||
@ -904,11 +968,39 @@ int Run(bool standaloneExe)
|
||||
for (;;) {
|
||||
ResetEvent(gsChangeEvent);
|
||||
ResetEvent(ifaceChangeEvent);
|
||||
UpdatePortMappings(IsGameStreamEnabled());
|
||||
|
||||
bool gameStreamEnabled = IsGameStreamEnabled();
|
||||
|
||||
if (gameStreamEnabled) {
|
||||
printf("GFE GameStream is ON!\n");
|
||||
}
|
||||
else {
|
||||
printf("GFE GameStream is OFF!\n");
|
||||
|
||||
if (IsAlternateHostSoftwareRunning()) {
|
||||
printf("Sunshine is RUNNING!\n");
|
||||
gameStreamEnabled = true;
|
||||
}
|
||||
else {
|
||||
printf("Sunshine is NOT RUNNING!\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Acquire the mapping lock and update port mappings
|
||||
if (TryEnterCriticalSection(&s_PortMappingUpdateLock)) {
|
||||
// If the stop event is set, bail out now
|
||||
if (WaitForSingleObject(s_StopEvent, 0) == WAIT_OBJECT_0) {
|
||||
LeaveCriticalSection(&s_PortMappingUpdateLock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
UpdatePortMappings(gameStreamEnabled);
|
||||
LeaveCriticalSection(&s_PortMappingUpdateLock);
|
||||
}
|
||||
|
||||
// Refresh when half the duration is expired or if an IP interface
|
||||
// change event occurs.
|
||||
printf("Going to sleep..." NL);
|
||||
printf("Going to sleep...\n");
|
||||
fflush(stdout);
|
||||
|
||||
ULONGLONG beforeSleepTime = GetTickCount64();
|
||||
@ -916,7 +1008,7 @@ int Run(bool standaloneExe)
|
||||
if (ret == WAIT_OBJECT_0) {
|
||||
ResetLogFile(standaloneExe);
|
||||
|
||||
printf("Woke up for interface change notification after %lld seconds" NL,
|
||||
printf("Woke up for interface change notification after %lld seconds\n",
|
||||
(GetTickCount64() - beforeSleepTime) / 1000);
|
||||
|
||||
// Wait a little bit for the interface to settle down (DHCP, RA, etc)
|
||||
@ -925,13 +1017,17 @@ int Run(bool standaloneExe)
|
||||
else if (ret == WAIT_OBJECT_0 + 1) {
|
||||
ResetLogFile(standaloneExe);
|
||||
|
||||
printf("Woke up for GameStream state change notification after %lld seconds" NL,
|
||||
printf("Woke up for GameStream state change notification after %lld seconds\n",
|
||||
(GetTickCount64() - beforeSleepTime) / 1000);
|
||||
}
|
||||
else if (ret == WAIT_OBJECT_0 + 2) {
|
||||
printf("Woke up for stop notification\n");
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
ResetLogFile(standaloneExe);
|
||||
|
||||
printf("Woke up for periodic refresh" NL);
|
||||
printf("Woke up for periodic refresh\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -949,14 +1045,21 @@ HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpConte
|
||||
return NO_ERROR;
|
||||
|
||||
case SERVICE_CONTROL_STOP:
|
||||
// Stop future port mapping updates
|
||||
SetEvent(s_StopEvent);
|
||||
|
||||
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||
ServiceStatus.dwControlsAccepted = 0;
|
||||
ServiceStatus.dwWaitHint = 120 * 1000; // 2 minutes
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
|
||||
// Remove existing port mappings
|
||||
EnterCriticalSection(&s_PortMappingUpdateLock);
|
||||
printf("Removing UPnP/NAT-PMP/PCP rules after service stop request\n");
|
||||
UpdatePortMappings(false);
|
||||
LeaveCriticalSection(&s_PortMappingUpdateLock);
|
||||
|
||||
printf("The service is stopping\n");
|
||||
printf("The service is stopping now\n");
|
||||
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
return NO_ERROR;
|
||||
@ -974,7 +1077,15 @@ ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
|
||||
|
||||
ServiceStatusHandle = RegisterServiceCtrlHandlerEx(SERVICE_NAME, HandlerEx, NULL);
|
||||
if (ServiceStatusHandle == NULL) {
|
||||
fprintf(stderr, "RegisterServiceCtrlHandlerEx() failed: %d" NL, GetLastError());
|
||||
fprintf(stderr, "RegisterServiceCtrlHandlerEx() failed: %d\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
err = Initialize();
|
||||
if (err != 0) {
|
||||
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||
ServiceStatus.dwWin32ExitCode = err;
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1013,8 +1124,8 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "exe")) {
|
||||
Run(true);
|
||||
return 0;
|
||||
Initialize();
|
||||
return Run(true);
|
||||
}
|
||||
|
||||
return StartServiceCtrlDispatcher(ServiceTable);
|
||||
|
@ -29,26 +29,26 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@ -93,13 +93,19 @@
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\libs\include;..\libs\include\miniupnpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\libs\x86\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<CETCompat>true</CETCompat>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)libs\x86\Debug\*" "$(TargetDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
@ -111,11 +117,17 @@
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<CETCompat>true</CETCompat>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)libs\x86\Debug\*" "$(TargetDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
@ -130,7 +142,8 @@
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\libs\include;..\libs\include\miniupnpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -138,7 +151,11 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\libs\x86\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<CETCompat>true</CETCompat>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)libs\x86\Release\*" "$(TargetDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@ -152,13 +169,18 @@
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<CETCompat>true</CETCompat>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)libs\x86\Release\*" "$(TargetDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="miss.cpp" />
|
||||
|
@ -118,7 +118,7 @@ bool PCPMapPort(PSOCKADDR_STORAGE localAddr, int localAddrLen, PSOCKADDR_STORAGE
|
||||
int bytesRead;
|
||||
union {
|
||||
PCP_MAP_RESPONSE hdr;
|
||||
char buf[1024];
|
||||
char buf[1100];
|
||||
} resp;
|
||||
int lifetime;
|
||||
|
||||
|
283
mist/mist.cpp
283
mist/mist.cpp
@ -238,7 +238,28 @@ bool ExecuteCommand(PCSTR command, PCHAR outputBuffer, DWORD outputBufferLength)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsGameStreamEnabled()
|
||||
bool IsSunshineRunning()
|
||||
{
|
||||
bool ret = false;
|
||||
HANDLE processSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
|
||||
PROCESSENTRY32 procEntry;
|
||||
procEntry.dwSize = sizeof(procEntry);
|
||||
Process32First(processSnapshot, &procEntry);
|
||||
|
||||
do {
|
||||
if (_stricmp(procEntry.szExeFile, "sunshine.exe") == 0) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
} while (Process32Next(processSnapshot, &procEntry));
|
||||
|
||||
CloseHandle(processSnapshot);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool IsGameStreamEnabled(bool sunshineRunning)
|
||||
{
|
||||
DWORD error;
|
||||
DWORD enabled;
|
||||
@ -248,8 +269,10 @@ bool IsGameStreamEnabled()
|
||||
error = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\NVIDIA Corporation\\NvStream", 0, KEY_READ | KEY_WOW64_64KEY, &key);
|
||||
if (error != ERROR_SUCCESS) {
|
||||
fprintf(LOG_OUT, "RegOpenKeyEx() failed: %d\n", error);
|
||||
DisplayMessage("GeForce Experience was not detected on this PC. Make sure you're installing this utility on your GeForce GameStream-compatible PC, not the device running Moonlight.",
|
||||
"https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide");
|
||||
if (!sunshineRunning) {
|
||||
DisplayMessage("Neither GeForce Experience nor Sunshine are running on this PC. Make sure you're installing this utility on your host PC, not the device running Moonlight.",
|
||||
"https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -261,8 +284,10 @@ bool IsGameStreamEnabled()
|
||||
if (error != ERROR_SUCCESS) {
|
||||
fprintf(LOG_OUT, "RegQueryValueExA() failed: %d\n", error);
|
||||
}
|
||||
DisplayMessage("GameStream is not enabled in GeForce Experience. Please open GeForce Experience settings, navigate to the Shield tab, and turn GameStream on.",
|
||||
"https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide");
|
||||
if (!sunshineRunning) {
|
||||
DisplayMessage("GameStream is not enabled in GeForce Experience. Please open GeForce Experience settings, navigate to the Shield tab, and turn GameStream on.",
|
||||
"https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
@ -402,12 +427,42 @@ bool IsZeroTierInstalled()
|
||||
return true;
|
||||
}
|
||||
|
||||
PIP_ADAPTER_ADDRESSES
|
||||
AllocAndGetAdaptersAddresses(ULONG Family, ULONG Flags)
|
||||
{
|
||||
PIP_ADAPTER_ADDRESSES addresses;
|
||||
ULONG length;
|
||||
ULONG error;
|
||||
|
||||
addresses = NULL;
|
||||
length = GAA_INITIAL_SIZE;
|
||||
do {
|
||||
free(addresses);
|
||||
addresses = (PIP_ADAPTER_ADDRESSES)malloc(length);
|
||||
if (addresses == NULL) {
|
||||
fprintf(LOG_OUT, "malloc(%u) failed\n", length);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
error = GetAdaptersAddresses(Family, Flags, NULL, addresses, &length);
|
||||
} while (error == ERROR_BUFFER_OVERFLOW);
|
||||
|
||||
if (error != ERROR_SUCCESS) {
|
||||
fprintf(LOG_OUT, "GetAdaptersAddresses() failed: %d\n", error);
|
||||
free(addresses);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
|
||||
enum PortTestStatus {
|
||||
PortTestOk,
|
||||
PortTestError,
|
||||
PortTestUnknown
|
||||
};
|
||||
PortTestStatus TestPort(PSOCKADDR_STORAGE addr, int proto, int port, bool withServer, bool isLoopbackRelay)
|
||||
PortTestStatus TestPort(PSOCKADDR_STORAGE addr, PSOCKADDR_STORAGE localBindAddr, int proto, int port, bool withServer, bool isLoopbackRelay, bool mtuTest)
|
||||
{
|
||||
SOCKET clientSock = INVALID_SOCKET, serverSock = INVALID_SOCKET;
|
||||
int err;
|
||||
@ -468,6 +523,21 @@ PortTestStatus TestPort(PSOCKADDR_STORAGE addr, int proto, int port, bool withSe
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the explicit bind if a local address was provided
|
||||
if (localBindAddr != nullptr) {
|
||||
SOCKADDR_IN6 bind6;
|
||||
int addrLen = localBindAddr->ss_family == AF_INET ?
|
||||
sizeof(SOCKADDR_IN) : sizeof(SOCKADDR_IN6);
|
||||
|
||||
RtlCopyMemory(&bind6, localBindAddr, addrLen);
|
||||
bind6.sin6_port = 0;
|
||||
|
||||
err = bind(clientSock, (struct sockaddr*)&bind6, addrLen);
|
||||
if (err == SOCKET_ERROR) {
|
||||
fprintf(LOG_OUT, "bind() failed: %d\n", WSAGetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
ULONG nbIo = 1;
|
||||
err = ioctlsocket(clientSock, FIONBIO, &nbIo);
|
||||
if (err == SOCKET_ERROR) {
|
||||
@ -532,11 +602,14 @@ PortTestStatus TestPort(PSOCKADDR_STORAGE addr, int proto, int port, bool withSe
|
||||
return err == 1 ? PortTestOk : PortTestError;
|
||||
}
|
||||
else {
|
||||
const char testMsg[] = "moonlight-test";
|
||||
// Video packets are up to 1040 bytes.
|
||||
const char testMsg[1040] = "moonlight-test";
|
||||
|
||||
// Send several test packets to ensure a random lost packet doesn't make the test fail
|
||||
for (int i = 0; i < 5; i++) {
|
||||
err = sendto(clientSock, testMsg, sizeof(testMsg), 0, (struct sockaddr*)&sin6, addrLen);
|
||||
// Send the full payload for MTU tests and the truncated payload for other tests.
|
||||
err = sendto(clientSock, testMsg,
|
||||
mtuTest ? sizeof(testMsg) : strlen(testMsg), 0, (struct sockaddr*)&sin6, addrLen);
|
||||
if (err == SOCKET_ERROR) {
|
||||
fprintf(LOG_OUT, "sendto() failed: %d\n", WSAGetLastError());
|
||||
closesocket(clientSock);
|
||||
@ -670,7 +743,7 @@ Exit:
|
||||
return result;
|
||||
}
|
||||
|
||||
bool TestAllPorts(PSOCKADDR_STORAGE addr, char* portMsg, int portMsgLen, bool isLoopbackRelay, bool consolePrint, bool* allPortsFailed = nullptr)
|
||||
bool TestAllPorts(PSOCKADDR_STORAGE addr, PSOCKADDR_STORAGE localBindAddr, char* portMsg, int portMsgLen, bool isLoopbackRelay, bool consolePrint, bool* allPortsFailed = nullptr)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
@ -687,9 +760,12 @@ bool TestAllPorts(PSOCKADDR_STORAGE addr, char* portMsg, int portMsgLen, bool is
|
||||
k_Ports[i].port);
|
||||
}
|
||||
|
||||
if (!k_Ports[i].withServer) {
|
||||
if (!k_Ports[i].withServer && (localBindAddr == nullptr || localBindAddr->ss_family == AF_INET)) {
|
||||
// Test using a real HTTP client if the port wasn't totally dead.
|
||||
// This is required to confirm functionality with the loopback relay.
|
||||
// NB: We can't do this with IPv6 because we're not guaranteed that our outbound traffic
|
||||
// will go out on the correct local IPv6 address, preventing a response from making
|
||||
// it back.
|
||||
assert(k_Ports[i].proto == IPPROTO_TCP);
|
||||
fprintf(LOG_OUT, "Testing TCP %d with HTTP traffic...", k_Ports[i].port);
|
||||
status = TestHttpPort(addr, k_Ports[i].port, isLoopbackRelay);
|
||||
@ -698,7 +774,8 @@ bool TestAllPorts(PSOCKADDR_STORAGE addr, char* portMsg, int portMsgLen, bool is
|
||||
fprintf(LOG_OUT, "Testing %s %d...",
|
||||
k_Ports[i].proto == IPPROTO_TCP ? "TCP" : "UDP",
|
||||
k_Ports[i].port);
|
||||
status = TestPort(addr, k_Ports[i].proto, k_Ports[i].port, k_Ports[i].withServer, isLoopbackRelay);
|
||||
status = TestPort(addr, localBindAddr, k_Ports[i].proto, k_Ports[i].port,
|
||||
k_Ports[i].withServer, isLoopbackRelay, k_Ports[i].port == 47998);
|
||||
}
|
||||
|
||||
if (status != PortTestOk) {
|
||||
@ -857,6 +934,71 @@ bool FindLocalInterfaceIPAddress(int family, PSOCKADDR_STORAGE addr)
|
||||
inet_ntop(AF_INET, &((struct sockaddr_in*)addr)->sin_addr, addrStr, sizeof(addrStr));
|
||||
}
|
||||
else {
|
||||
// There may be multiple IPv6 addresses on this interface, and chances are that the
|
||||
// outbound address is a temporary IPv6 address which is not meant to receive traffic.
|
||||
// Let's look up a suitable address by finding the correct interface and looking for
|
||||
// an address with a non-random suffix.
|
||||
|
||||
PIP_ADAPTER_ADDRESSES addresses;
|
||||
PIP_ADAPTER_ADDRESSES currentAdapter;
|
||||
PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
|
||||
|
||||
addresses = AllocAndGetAdaptersAddresses(AF_UNSPEC,
|
||||
GAA_FLAG_SKIP_ANYCAST |
|
||||
GAA_FLAG_SKIP_MULTICAST |
|
||||
GAA_FLAG_SKIP_DNS_SERVER |
|
||||
GAA_FLAG_SKIP_FRIENDLY_NAME);
|
||||
if (addresses == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// First, find the interface that owns the incoming address
|
||||
currentAdapter = addresses;
|
||||
while (currentAdapter != NULL) {
|
||||
// Check if this interface has the IPv6 address we want
|
||||
currentAddress = currentAdapter->FirstUnicastAddress;
|
||||
while (currentAddress != NULL) {
|
||||
if (currentAddress->Address.lpSockaddr->sa_family == AF_INET6) {
|
||||
PSOCKADDR_IN6 ifaceAddrV6 = (PSOCKADDR_IN6)currentAddress->Address.lpSockaddr;
|
||||
if (RtlEqualMemory(&((struct sockaddr_in6*)addr)->sin6_addr, &ifaceAddrV6->sin6_addr, sizeof(IN6_ADDR))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
currentAddress = currentAddress->Next;
|
||||
}
|
||||
|
||||
if (currentAddress != NULL) {
|
||||
// It does, bail out
|
||||
break;
|
||||
}
|
||||
|
||||
currentAdapter = currentAdapter->Next;
|
||||
}
|
||||
|
||||
// Check if we found the incoming interface. If not, we'll
|
||||
// just return the IP address as given from getsockname().
|
||||
if (currentAdapter != NULL) {
|
||||
// Now find a non-privacy/non-LL IPv6 address on this interface
|
||||
currentAddress = currentAdapter->FirstUnicastAddress;
|
||||
while (currentAddress != NULL) {
|
||||
if (currentAddress->Address.lpSockaddr->sa_family == AF_INET6) {
|
||||
// Exclude link-local and privacy addresses and deprecated addresses
|
||||
PSOCKADDR_IN6 currentAddrV6 = (PSOCKADDR_IN6)currentAddress->Address.lpSockaddr;
|
||||
if (currentAddrV6->sin6_scope_id == 0 &&
|
||||
currentAddress->SuffixOrigin != IpSuffixOriginRandom &&
|
||||
currentAddress->DadState != IpDadStateDeprecated) {
|
||||
RtlCopyMemory(addr, currentAddress->Address.lpSockaddr, currentAddress->Address.iSockaddrLength);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
currentAddress = currentAddress->Next;
|
||||
}
|
||||
}
|
||||
|
||||
free(addresses);
|
||||
|
||||
inet_ntop(AF_INET6, &((struct sockaddr_in6*)addr)->sin6_addr, addrStr, sizeof(addrStr));
|
||||
}
|
||||
fprintf(LOG_OUT, "%s\n", addrStr);
|
||||
@ -867,35 +1009,16 @@ bool FindLocalInterfaceIPAddress(int family, PSOCKADDR_STORAGE addr)
|
||||
bool FindZeroTierInterfaceAddress(PSOCKADDR_STORAGE addr)
|
||||
{
|
||||
PIP_ADAPTER_ADDRESSES addresses;
|
||||
ULONG error;
|
||||
ULONG length;
|
||||
PIP_ADAPTER_ADDRESSES currentAdapter;
|
||||
PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
|
||||
|
||||
addresses = NULL;
|
||||
length = GAA_INITIAL_SIZE;
|
||||
do {
|
||||
free(addresses);
|
||||
addresses = (PIP_ADAPTER_ADDRESSES)malloc(length);
|
||||
if (addresses == NULL) {
|
||||
fprintf(LOG_OUT, "malloc(%u) failed\n", length);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get all IPv4 interfaces
|
||||
error = GetAdaptersAddresses(AF_INET,
|
||||
GAA_FLAG_SKIP_ANYCAST |
|
||||
GAA_FLAG_SKIP_MULTICAST |
|
||||
GAA_FLAG_SKIP_DNS_SERVER |
|
||||
GAA_FLAG_SKIP_FRIENDLY_NAME,
|
||||
NULL,
|
||||
addresses,
|
||||
&length);
|
||||
} while (error == ERROR_BUFFER_OVERFLOW);
|
||||
|
||||
if (error != ERROR_SUCCESS) {
|
||||
fprintf(LOG_OUT, "GetAdaptersAddresses() failed: %d\n", error);
|
||||
free(addresses);
|
||||
// Get all IPv4 interfaces
|
||||
addresses = AllocAndGetAdaptersAddresses(AF_INET,
|
||||
GAA_FLAG_SKIP_ANYCAST |
|
||||
GAA_FLAG_SKIP_MULTICAST |
|
||||
GAA_FLAG_SKIP_DNS_SERVER |
|
||||
GAA_FLAG_SKIP_FRIENDLY_NAME);
|
||||
if (addresses == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -927,7 +1050,6 @@ bool FindDuplicateDefaultInterfaces(void)
|
||||
{
|
||||
PIP_ADAPTER_ADDRESSES addresses;
|
||||
ULONG error;
|
||||
ULONG length;
|
||||
MIB_IPFORWARDROW defaultRoute;
|
||||
PIP_ADAPTER_ADDRESSES currentAdapter;
|
||||
DWORD matchingInterfaces = 0;
|
||||
@ -938,32 +1060,15 @@ bool FindDuplicateDefaultInterfaces(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
addresses = NULL;
|
||||
length = GAA_INITIAL_SIZE;
|
||||
do {
|
||||
free(addresses);
|
||||
addresses = (PIP_ADAPTER_ADDRESSES)malloc(length);
|
||||
if (addresses == NULL) {
|
||||
fprintf(LOG_OUT, "malloc(%u) failed\n", length);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get all IPv4 interfaces
|
||||
error = GetAdaptersAddresses(AF_INET,
|
||||
GAA_FLAG_SKIP_UNICAST |
|
||||
GAA_FLAG_SKIP_ANYCAST |
|
||||
GAA_FLAG_SKIP_MULTICAST |
|
||||
GAA_FLAG_SKIP_DNS_SERVER |
|
||||
GAA_FLAG_INCLUDE_GATEWAYS |
|
||||
GAA_FLAG_SKIP_FRIENDLY_NAME,
|
||||
NULL,
|
||||
addresses,
|
||||
&length);
|
||||
} while (error == ERROR_BUFFER_OVERFLOW);
|
||||
|
||||
if (error != ERROR_SUCCESS) {
|
||||
fprintf(LOG_OUT, "GetAdaptersAddresses() failed: %d\n", error);
|
||||
free(addresses);
|
||||
// Get all IPv4 interfaces
|
||||
addresses = AllocAndGetAdaptersAddresses(AF_INET,
|
||||
GAA_FLAG_SKIP_UNICAST |
|
||||
GAA_FLAG_SKIP_ANYCAST |
|
||||
GAA_FLAG_SKIP_MULTICAST |
|
||||
GAA_FLAG_SKIP_DNS_SERVER |
|
||||
GAA_FLAG_INCLUDE_GATEWAYS |
|
||||
GAA_FLAG_SKIP_FRIENDLY_NAME);
|
||||
if (addresses == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1244,9 +1349,19 @@ int main(int argc, char* argv[])
|
||||
|
||||
fprintf(CONSOLE_OUT, "Checking if GameStream is enabled...\n");
|
||||
|
||||
// First check if GameStream is enabled
|
||||
if (!IsGameStreamEnabled()) {
|
||||
return -1;
|
||||
bool sunshineRunning = IsSunshineRunning();
|
||||
bool gfeGameStreamRunning = true;
|
||||
if (!IsGameStreamEnabled(sunshineRunning)) {
|
||||
if (sunshineRunning) {
|
||||
DisplayMessage("The Moonlight Internet Hosting Tool is not designed for use with Sunshine.\n\n"
|
||||
"To stream over the Internet with Sunshine, simply enable the UPnP option in the Sunshine Web UI.\n\n"
|
||||
"Test results WILL be inaccurate if the Port option in Sunshine has been adjusted from the default value of 47989!",
|
||||
nullptr, MpWarn, false);
|
||||
gfeGameStreamRunning = false;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsCurrentlyStreaming()) {
|
||||
@ -1255,7 +1370,7 @@ int main(int argc, char* argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!IsConsoleSessionActive()) {
|
||||
if (gfeGameStreamRunning && !IsConsoleSessionActive()) {
|
||||
DisplayMessage("The system display is currently locked. You must sign in to your PC again to use GameStream.\n\n"
|
||||
"This is most often due to Microsoft Remote Desktop locking the screen. Use an alternate GameStream-compatible remote desktop solution like Chrome Remote Desktop or TeamViewer to unlock the PC and prevent this error in the future.",
|
||||
"https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#display-locked-error");
|
||||
@ -1322,9 +1437,16 @@ int main(int argc, char* argv[])
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr = in4addr_loopback;
|
||||
fprintf(LOG_OUT, "Testing GameStream ports via loopback\n");
|
||||
if (!TestAllPorts(&ss, portMsgBuf, sizeof(portMsgBuf), false, true)) {
|
||||
snprintf(msgBuf, sizeof(msgBuf),
|
||||
"Local GameStream connectivity check failed.\n\nFirst, try reinstalling GeForce Experience. If that doesn't resolve the problem, try temporarily disabling your antivirus and firewall.");
|
||||
if (!TestAllPorts(&ss, nullptr, portMsgBuf, sizeof(portMsgBuf), false, true)) {
|
||||
if (gfeGameStreamRunning) {
|
||||
snprintf(msgBuf, sizeof(msgBuf),
|
||||
"Local GameStream connectivity check failed.\n\nFirst, try reinstalling GeForce Experience. If that doesn't resolve the problem, try temporarily disabling your antivirus and firewall.");
|
||||
}
|
||||
else {
|
||||
snprintf(msgBuf, sizeof(msgBuf),
|
||||
"Local GameStream connectivity check failed.\n\nFirst, try restarting Sunshine. If that doesn't resolve the problem, try temporarily disabling your antivirus and firewall.\n\nNOTE: Sunshine must be configured to use the default 47989 port to test with this tool.");
|
||||
}
|
||||
|
||||
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting");
|
||||
return -1;
|
||||
}
|
||||
@ -1356,7 +1478,7 @@ int main(int argc, char* argv[])
|
||||
// Try to connect via ZeroTier address
|
||||
fprintf(CONSOLE_OUT, "Testing GameStream connectivity using ZeroTier...\n");
|
||||
fprintf(LOG_OUT, "Testing GameStream ports via ZeroTier\n");
|
||||
if (!TestAllPorts(&ss, portMsgBuf, sizeof(portMsgBuf), false, true)) {
|
||||
if (!TestAllPorts(&ss, nullptr, portMsgBuf, sizeof(portMsgBuf), false, true)) {
|
||||
snprintf(msgBuf, sizeof(msgBuf),
|
||||
"ZeroTier connectivity check failed. This is almost always caused by a firewall on your computer blocking the connection.\n\nTry temporarily disabling your antivirus and firewall.");
|
||||
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting");
|
||||
@ -1373,9 +1495,8 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
bool hasV4Connectivity, hasV6Connectivity;
|
||||
SOCKADDR_STORAGE v4, v6;
|
||||
{
|
||||
SOCKADDR_STORAGE v4, v6;
|
||||
|
||||
hasV4Connectivity = FindLocalInterfaceIPAddress(AF_INET, &v4);
|
||||
hasV6Connectivity = FindLocalInterfaceIPAddress(AF_INET6, &v6);
|
||||
|
||||
@ -1396,7 +1517,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
// Try to connect via LAN address
|
||||
fprintf(LOG_OUT, "Testing GameStream ports via local network\n");
|
||||
if (!TestAllPorts(&ss, portMsgBuf, sizeof(portMsgBuf), false, true)) {
|
||||
if (!TestAllPorts(&ss, nullptr, portMsgBuf, sizeof(portMsgBuf), false, true)) {
|
||||
snprintf(msgBuf, sizeof(msgBuf),
|
||||
"Local network GameStream connectivity check failed. This is almost always caused by a firewall on your computer blocking the connection.\n\nTry temporarily disabling your antivirus and firewall.");
|
||||
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting");
|
||||
@ -1422,7 +1543,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
// We don't actually care about the outcome here but it's nice to have in logs
|
||||
// to determine whether solving the double NAT will actually make Moonlight work.
|
||||
TestAllPorts((PSOCKADDR_STORAGE)&locallyReportedWanAddr, portMsgBuf, sizeof(portMsgBuf), false, false);
|
||||
TestAllPorts((PSOCKADDR_STORAGE)&locallyReportedWanAddr, &ss, portMsgBuf, sizeof(portMsgBuf), false, false);
|
||||
|
||||
fprintf(LOG_OUT, "Detected inconsistency between UPnP/NAT-PMP and STUN reported WAN addresses!\n");
|
||||
}
|
||||
@ -1461,11 +1582,13 @@ int main(int argc, char* argv[])
|
||||
|
||||
testServerWasReachable = true;
|
||||
|
||||
if (TestAllPorts((PSOCKADDR_STORAGE)current->ai_addr, portMsgBuf, sizeof(portMsgBuf), true, true, &allPortsFailedOnV4)) {
|
||||
if (TestAllPorts((PSOCKADDR_STORAGE)current->ai_addr, &v4, portMsgBuf, sizeof(portMsgBuf), true, true, &allPortsFailedOnV4)) {
|
||||
freeaddrinfo(result);
|
||||
snprintf(msgBuf, sizeof(msgBuf), "This PC is ready to host over the Internet!\n\n"
|
||||
"For the easiest setup, you should pair Moonlight to your gaming PC from your home network before trying to stream over the Internet.\n\n"
|
||||
"If you can't, you can type the following address into Moonlight's Add PC dialog: %s", wanAddrStr);
|
||||
"Do not uninstall the Moonlight Internet Hosting Tool, unless you no longer want to stream over the Internet. It needs to remain installed on your PC to maintain the port forwarding entries on your router.\n\n"
|
||||
"For the easiest setup, you can simply pair Moonlight to your gaming PC while they are both on the same network and Internet streaming will work automatically.\n\n"
|
||||
"If your client is not connected to the same network as your gaming PC, you can type the following address into Moonlight's Add PC dialog: %s",
|
||||
wanAddrStr);
|
||||
DisplayMessage(msgBuf, nullptr, MpInfo);
|
||||
return 0;
|
||||
}
|
||||
@ -1491,7 +1614,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
// Pass the portMsgBuf only if we've detected an IPv6-only setup. Otherwise, we want to preserve
|
||||
// the failing ports from the IPv4 to display in the error dialog.
|
||||
if (TestAllPorts((PSOCKADDR_STORAGE)current->ai_addr,
|
||||
if (TestAllPorts((PSOCKADDR_STORAGE)current->ai_addr, &v6,
|
||||
ss.ss_family == AF_INET6 ? portMsgBuf : NULL,
|
||||
ss.ss_family == AF_INET6 ? sizeof(portMsgBuf) : 0, true, true)) {
|
||||
// We will terminate the test at the IPv6 limited connectivity warning in the following cases:
|
||||
|
@ -29,26 +29,26 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@ -93,16 +93,22 @@
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\libs\include;..\libs\include\miniupnpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\libs\x86\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<CETCompat>true</CETCompat>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AdditionalManifestFiles>mist.exe.manifest</AdditionalManifestFiles>
|
||||
</Manifest>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)libs\x86\Debug\*" "$(TargetDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
@ -113,14 +119,20 @@
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<CETCompat>true</CETCompat>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AdditionalManifestFiles>mist.exe.manifest</AdditionalManifestFiles>
|
||||
</Manifest>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)libs\x86\Debug\*" "$(TargetDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
@ -135,7 +147,8 @@
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\libs\include;..\libs\include\miniupnpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -143,10 +156,14 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>..\libs\x86\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<CETCompat>true</CETCompat>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AdditionalManifestFiles>mist.exe.manifest</AdditionalManifestFiles>
|
||||
</Manifest>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)libs\x86\Release\*" "$(TargetDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@ -159,16 +176,21 @@
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<ControlFlowGuard>Guard</ControlFlowGuard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<CETCompat>true</CETCompat>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<AdditionalManifestFiles>mist.exe.manifest</AdditionalManifestFiles>
|
||||
</Manifest>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /Y "$(SolutionDir)libs\x86\Release\*" "$(TargetDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mist.cpp" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user