Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3e4bf608f | ||
|
|
0be2ca51e9 | ||
|
|
3e1ffce16f | ||
|
|
c7813a7a0b | ||
|
|
87fd3ad8e2 | ||
|
|
9d3ef0a215 | ||
|
|
ae83853a27 | ||
|
|
0b8b117cb2 | ||
|
|
0050566124 | ||
|
|
cc24472193 | ||
|
|
4a11ab0f7f | ||
|
|
c1c16edf7d | ||
|
|
ae2647f36e | ||
|
|
8e40ef80bd | ||
|
|
16bb727b99 | ||
|
|
9194b8e22b | ||
|
|
2805464e86 | ||
|
|
20e7374480 | ||
|
|
0fdbee831b | ||
|
|
b37b99e9c3 | ||
|
|
29bbdc5319 |
+1
-1
Submodule GS-IPv6-Forwarder updated: c1d7dbe846...ae5e4aecb6
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-3
@@ -47,9 +47,7 @@
|
||||
Account="NT AUTHORITY\LocalService"
|
||||
ErrorControl="ignore"
|
||||
Interactive="no">
|
||||
<ServiceConfig DelayedAutoStart="no" OnInstall="yes" OnReinstall="yes" ServiceSid="restricted">
|
||||
<RequiredPrivilege>SeChangeNotifyPrivilege</RequiredPrivilege>
|
||||
</ServiceConfig>
|
||||
<ServiceConfig DelayedAutoStart="no" OnInstall="yes" OnReinstall="yes" ServiceSid="unrestricted"/>
|
||||
</ServiceInstall>
|
||||
<ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="MISS" Wait="yes" />
|
||||
</Component>
|
||||
|
||||
@@ -386,15 +386,6 @@ bool NATPMPMapPort(natpmp_t* natpmp, int proto, int port, bool enable, bool inde
|
||||
else if (response.pnu.newportmapping.mappedpublicport != port) {
|
||||
printf("CONFLICT" NL);
|
||||
|
||||
// Some buggy routers (Untangle) will change the *internal* port when
|
||||
// adjusting a port mapping request that collides. This is why we also
|
||||
// pass privateport back from the response and not from the port we originally
|
||||
// asked for. Warn in this case.
|
||||
if (response.pnu.newportmapping.privateport != port) {
|
||||
printf("Buggy router changed the internal port when handling NAT-PMP conflict! (%d -> %d)" NL,
|
||||
port, response.pnu.newportmapping.privateport);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
+254
-2
@@ -6,12 +6,16 @@
|
||||
#include <shellapi.h>
|
||||
#include <objbase.h>
|
||||
#include <WinInet.h>
|
||||
#include <wtsapi32.h>
|
||||
#include <powerbase.h>
|
||||
|
||||
#pragma comment(lib, "miniupnpc.lib")
|
||||
#pragma comment(lib, "libnatpmp.lib")
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#pragma comment(lib, "iphlpapi.lib")
|
||||
#pragma comment(lib, "wininet.lib")
|
||||
#pragma comment(lib, "wtsapi32.lib")
|
||||
#pragma comment(lib, "powrprof.lib")
|
||||
|
||||
#define MINIUPNP_STATICLIB
|
||||
#include <miniupnpc/miniupnpc.h>
|
||||
@@ -178,6 +182,56 @@ void DisplayMessage(const char* message, const char* helpUrl = nullptr, MessageP
|
||||
}
|
||||
}
|
||||
|
||||
bool ExecuteCommand(PCSTR command, PCHAR outputBuffer, DWORD outputBufferLength)
|
||||
{
|
||||
SECURITY_ATTRIBUTES attribs;
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
HANDLE outReadHandle;
|
||||
DWORD bytesRead = 0;
|
||||
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
|
||||
ZeroMemory(&attribs, sizeof(attribs));
|
||||
attribs.nLength = sizeof(attribs);
|
||||
attribs.bInheritHandle = TRUE;
|
||||
|
||||
if (!CreatePipe(&outReadHandle, &si.hStdOutput, &attribs, 0))
|
||||
{
|
||||
fprintf(LOG_OUT, "CreatePipe() failed: %d\n", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
si.hStdError = si.hStdOutput;
|
||||
|
||||
if (!CreateProcess(NULL, (LPSTR)command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
|
||||
{
|
||||
fprintf(LOG_OUT, "CreateProcess() failed: %d\n", GetLastError());
|
||||
CloseHandle(si.hStdOutput);
|
||||
return false;
|
||||
}
|
||||
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
|
||||
CloseHandle(si.hStdOutput);
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
if (!ReadFile(outReadHandle, outputBuffer, outputBufferLength, &bytesRead, NULL))
|
||||
{
|
||||
fprintf(LOG_OUT, "ReadFile() failed: %d\n", GetLastError());
|
||||
CloseHandle(outReadHandle);
|
||||
return false;
|
||||
}
|
||||
|
||||
outputBuffer[bytesRead] = 0;
|
||||
CloseHandle(outReadHandle);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsGameStreamEnabled()
|
||||
{
|
||||
DWORD error;
|
||||
@@ -211,6 +265,101 @@ bool IsGameStreamEnabled()
|
||||
}
|
||||
}
|
||||
|
||||
bool IsConsoleSessionActive()
|
||||
{
|
||||
PWTS_SESSION_INFO_1 sessionInfo;
|
||||
DWORD sessionCount;
|
||||
DWORD level;
|
||||
bool ret;
|
||||
DWORD activeSessionId = WTSGetActiveConsoleSessionId();
|
||||
|
||||
if (activeSessionId == 0xFFFFFFFF) {
|
||||
fprintf(LOG_OUT, "No active console session detected\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
level = 1;
|
||||
if (!WTSEnumerateSessionsEx(WTS_CURRENT_SERVER_HANDLE, &level, 0, &sessionInfo, &sessionCount)) {
|
||||
fprintf(LOG_OUT, "WTSEnumerateSessionsEx() failed: %d\n", GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = false;
|
||||
for (int i = 0; i < sessionCount; i++)
|
||||
{
|
||||
if (sessionInfo[i].SessionId == activeSessionId) {
|
||||
if (sessionInfo[i].pUserName != nullptr) {
|
||||
fprintf(LOG_OUT, "Session %d has active user\n", sessionInfo[i].SessionId);
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WTSFreeMemoryExW(WTSTypeSessionInfoLevel1, sessionInfo, sessionCount);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool IsSleepEnabled()
|
||||
{
|
||||
SYSTEM_POWER_POLICY powerPolicy;
|
||||
|
||||
if (CallNtPowerInformation(SystemPowerPolicyAc, NULL, 0, &powerPolicy, sizeof(powerPolicy)) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return powerPolicy.IdleTimeout != 0 && powerPolicy.Idle.Action == PowerActionSleep;
|
||||
}
|
||||
|
||||
bool IsHibernationEnabled()
|
||||
{
|
||||
SYSTEM_POWER_POLICY powerPolicy;
|
||||
|
||||
if (CallNtPowerInformation(SystemPowerPolicyAc, NULL, 0, &powerPolicy, sizeof(powerPolicy)) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return powerPolicy.DozeS4Timeout != 0 || (powerPolicy.IdleTimeout != 0 && powerPolicy.Idle.Action == PowerActionHibernate);
|
||||
}
|
||||
|
||||
bool IsLocalNetworkAccessBlocked()
|
||||
{
|
||||
MIB_IPFORWARDROW route;
|
||||
DWORD error;
|
||||
SOCKADDR_IN sin;
|
||||
SOCKET s;
|
||||
|
||||
error = GetBestRoute(0, 0, &route);
|
||||
if (error != NO_ERROR) {
|
||||
fprintf(LOG_OUT, "GetBestRoute() failed: %d\n", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (s == INVALID_SOCKET) {
|
||||
fprintf(LOG_OUT, "socket() failed: %d\n", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
RtlZeroMemory(&sin, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.S_un.S_addr = route.dwForwardNextHop;
|
||||
sin.sin_port = htons(80);
|
||||
|
||||
if (connect(s, (PSOCKADDR)&sin, sizeof(sin)) == 0) {
|
||||
error = NO_ERROR;
|
||||
fprintf(LOG_OUT, "connect(%s, %d) successful\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
|
||||
}
|
||||
else {
|
||||
error = WSAGetLastError();
|
||||
fprintf(LOG_OUT, "connect(%s, %d) failed: %d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), error);
|
||||
}
|
||||
|
||||
closesocket(s);
|
||||
|
||||
return error == WSAEACCES;
|
||||
}
|
||||
|
||||
bool IsZeroTierInstalled()
|
||||
{
|
||||
DWORD error;
|
||||
@@ -590,7 +739,7 @@ bool FindZeroTierInterfaceAddress(PSOCKADDR_STORAGE addr)
|
||||
&addresses,
|
||||
&length);
|
||||
if (error != ERROR_SUCCESS) {
|
||||
fprintf(LOG_OUT, "GetAdaptersAddresses() failed: %d\n", WSAGetLastError());
|
||||
fprintf(LOG_OUT, "GetAdaptersAddresses() failed: %d\n", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -616,6 +765,57 @@ bool FindZeroTierInterfaceAddress(PSOCKADDR_STORAGE addr)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FindDuplicateDefaultInterfaces(void)
|
||||
{
|
||||
union {
|
||||
IP_ADAPTER_ADDRESSES addresses;
|
||||
char buffer[8192];
|
||||
};
|
||||
ULONG error;
|
||||
ULONG length;
|
||||
MIB_IPFORWARDROW defaultRoute;
|
||||
PIP_ADAPTER_ADDRESSES currentAdapter;
|
||||
DWORD matchingInterfaces = 0;
|
||||
|
||||
error = GetBestRoute(0, 0, &defaultRoute);
|
||||
if (error != NO_ERROR) {
|
||||
fprintf(LOG_OUT, "GetBestRoute() failed: %d\n", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get all IPv4 interfaces
|
||||
length = sizeof(buffer);
|
||||
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);
|
||||
if (error != ERROR_SUCCESS) {
|
||||
fprintf(LOG_OUT, "GetAdaptersAddresses() failed: %d\n", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
currentAdapter = &addresses;
|
||||
while (currentAdapter != NULL) {
|
||||
if (currentAdapter->OperStatus == IfOperStatusUp &&
|
||||
currentAdapter->FirstGatewayAddress != NULL &&
|
||||
currentAdapter->FirstGatewayAddress->Address.iSockaddrLength == sizeof(SOCKADDR_IN)) {
|
||||
if (((PSOCKADDR_IN)currentAdapter->FirstGatewayAddress->Address.lpSockaddr)->sin_addr.S_un.S_addr == defaultRoute.dwForwardNextHop) {
|
||||
matchingInterfaces++;
|
||||
}
|
||||
}
|
||||
|
||||
currentAdapter = currentAdapter->Next;
|
||||
}
|
||||
|
||||
return matchingInterfaces > 1;
|
||||
}
|
||||
|
||||
enum UPnPPortStatus {
|
||||
NOT_FOUND,
|
||||
OK,
|
||||
@@ -885,6 +1085,58 @@ int main(int argc, char* argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!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");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(CONSOLE_OUT, "Checking power settings...\n");
|
||||
|
||||
if (IsSleepEnabled()) {
|
||||
DisplayMessage("This computer has sleep mode enabled. Sleep mode may prevent this PC from being available for streaming.\n\n"
|
||||
"Please ensure sleep is disabled in Power Options so this PC is always ready for streaming. Click the Help button for more information.",
|
||||
"https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#sleep-mode-enabled-warning", MpWarn, false);
|
||||
}
|
||||
|
||||
if (IsHibernationEnabled()) {
|
||||
DisplayMessage("This computer has hibernation enabled. Hibernation may prevent this PC from being available for streaming.\n\n"
|
||||
"Please ensure hibernation is disabled in Power Options so this PC is always ready for streaming. Click the Help button for more information.",
|
||||
"https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#hibernation-enabled-warning", MpWarn, false);
|
||||
}
|
||||
|
||||
fprintf(CONSOLE_OUT, "Checking network connections...\n");
|
||||
|
||||
if (IsLocalNetworkAccessBlocked()) {
|
||||
DisplayMessage("Local network access appears to be blocked by another application installed on this PC.\n\n"
|
||||
"If you have firewall or VPN software installed, make sure it is configured to allow applications to access the local network. Click the Help button for guidance on fixing this issue.",
|
||||
"https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#local-network-access-blocked-error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (FindDuplicateDefaultInterfaces()) {
|
||||
DisplayMessage("This computer appears to have more than one connection to the same network (like both WiFi and Ethernet, for example).\n\n"
|
||||
"Please disconnect the extra connection(s) to ensure hosting works reliably over the Internet. If you are connected via WiFi and Ethernet, try disabling your WiFi connection.",
|
||||
"https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#multiple-connections-error", MpWarn, false);
|
||||
}
|
||||
|
||||
fprintf(CONSOLE_OUT, "Checking for anti-virus and firewall software...\n");
|
||||
|
||||
char wmicBuf[8192];
|
||||
if (ExecuteCommand("WMIC /Node:localhost /Namespace:\\\\root\\SecurityCenter2 Path AntiVirusProduct Get displayName", wmicBuf, sizeof(wmicBuf))) {
|
||||
fprintf(LOG_OUT, "AV products:\n%s", wmicBuf);
|
||||
}
|
||||
if (ExecuteCommand("WMIC /Node:localhost /Namespace:\\\\root\\SecurityCenter2 Path FirewallProduct Get displayName", wmicBuf, sizeof(wmicBuf))) {
|
||||
fprintf(LOG_OUT, "Firewall products:\n%s", wmicBuf);
|
||||
if (strstr(wmicBuf, "displayName")) {
|
||||
DisplayMessage("Detected anti-virus and/or firewall software installed on this system. This software may interfere with NVIDIA GameStream.\n\n"
|
||||
"Please try temporarily disabling your anti-virus or firewall software if you experience connection issues with Moonlight.",
|
||||
"https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting#known-application-compatibility-issues", MpInfo, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
union {
|
||||
SOCKADDR_STORAGE ss;
|
||||
SOCKADDR_IN sin;
|
||||
@@ -1080,7 +1332,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
else {
|
||||
snprintf(msgBuf, sizeof(msgBuf), "Internet GameStream connectivity check failed.\n\n"
|
||||
"Check that UPnP is enabled in your router settings. For more information and workarounds, click the Help button.\n\n"
|
||||
"First, try restarting your router. If that fails, check that UPnP is enabled in your router settings. For more information and workarounds, click the Help button.\n\n"
|
||||
"The following ports were not forwarded properly:\n%s", portMsgBuf);
|
||||
DisplayMessage(msgBuf, "https://github.com/moonlight-stream/moonlight-docs/wiki/Internet-Streaming-Errors#internet-gamestream-connectivity-check-error");
|
||||
}
|
||||
|
||||
+1
-3
@@ -4,7 +4,7 @@
|
||||
|
||||
#define STUN_PORT 3478
|
||||
|
||||
#define STUN_RECV_TIMEOUT_SEC 3
|
||||
#define STUN_RECV_TIMEOUT_SEC 5
|
||||
|
||||
#define STUN_MESSAGE_BINDING_REQUEST 0x0001
|
||||
#define STUN_MESSAGE_BINDING_SUCCESS 0x0101
|
||||
@@ -44,8 +44,6 @@ bool getExternalAddressPortIP4(unsigned short localPort, PSOCKADDR_IN wanAddr)
|
||||
STUN_MESSAGE reqMsg;
|
||||
int i;
|
||||
int bytesRead;
|
||||
int tries;
|
||||
int timeout;
|
||||
int err;
|
||||
PSTUN_ATTRIBUTE_HEADER attribute;
|
||||
PSTUN_MAPPED_IPV4_ADDRESS_ATTRIBUTE ipv4Attrib;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define VER_VERSION 4,2,0,0
|
||||
#define VER_VERSION_STR "4.2.0.0"
|
||||
#define VER_VERSION 4,4,0,0
|
||||
#define VER_VERSION_STR "4.4.0.0"
|
||||
|
||||
#define VER_COMPANYNAME_STR "Moonlight Game Streaming Project"
|
||||
#define VER_PRODUCTNAME_STR "Moonlight Internet Hosting Tool"
|
||||
|
||||
Reference in New Issue
Block a user