Initial code drop

This commit is contained in:
Cameron Gutman 2017-08-26 23:38:58 -07:00
parent 3c6a83a514
commit 8bec741daf
6 changed files with 860 additions and 0 deletions

39
GSv6Fwd.sln Normal file
View File

@ -0,0 +1,39 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.10
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GSv6Fwd", "GSv6Fwd\GSv6Fwd.vcxproj", "{87DEAE49-7638-4CDB-88EB-054B1F3CB0D2}"
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "GSv6FwdSetup", "GSv6FwdSetup\GSv6FwdSetup.wixproj", "{F8171B99-F5F9-4ABF-9FE5-6753539611AF}"
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
{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
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9C375CA2-3B67-4C23-B946-B3A5C8A79190}
EndGlobalSection
EndGlobal

557
GSv6Fwd/GSv6Fwd.cpp Normal file
View File

@ -0,0 +1,557 @@
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "ws2_32")
#include <WinSock2.h>
#include <Ws2ipdef.h>
#pragma comment(lib, "iphlpapi")
#include <Iphlpapi.h>
#define SERVICE_NAME L"GSv6FwdSvc"
static const unsigned short UDP_PORTS[] = {
47998, 47999, 48000, 48010
};
static const unsigned short TCP_PORTS[] = {
47984, 47989
};
typedef struct _SOCKET_TUPLE {
SOCKET s1;
SOCKET s2;
} SOCKET_TUPLE, *PSOCKET_TUPLE;
typedef struct _LISTENER_TUPLE {
SOCKET listener;
unsigned short port;
} LISTENER_TUPLE, *PLISTENER_TUPLE;
typedef struct _UDP_TUPLE {
SOCKET ipv6Socket;
SOCKET ipv4Socket;
unsigned short port;
} UDP_TUPLE, *PUDP_TUPLE;
int
ForwardSocketData(SOCKET from, SOCKET to)
{
char buffer[4096];
int len;
len = recv(from, buffer, sizeof(buffer), 0);
if (len <= 0) {
return len;
}
if (send(to, buffer, len, 0) != len) {
return SOCKET_ERROR;
}
return len;
}
DWORD
WINAPI
TcpRelayThreadProc(LPVOID Context)
{
PSOCKET_TUPLE tuple = (PSOCKET_TUPLE)Context;
fd_set fds;
int err;
bool s1ReadShutdown = false;
bool s2ReadShutdown = false;
for (;;) {
FD_ZERO(&fds);
if (!s1ReadShutdown) {
FD_SET(tuple->s1, &fds);
}
if (!s2ReadShutdown) {
FD_SET(tuple->s2, &fds);
}
if (s1ReadShutdown && s2ReadShutdown) {
// Both sides gracefully closed
break;
}
err = select(0, &fds, NULL, NULL, NULL);
if (err <= 0) {
break;
}
else if (FD_ISSET(tuple->s1, &fds)) {
err = ForwardSocketData(tuple->s1, tuple->s2);
if (err == 0) {
// Graceful closure from s1. Propagate to s2.
shutdown(tuple->s2, SD_SEND);
s1ReadShutdown = true;
}
else if (err < 0) {
// Forceful closure. Tear down the whole connection.
break;
}
}
else if (FD_ISSET(tuple->s2, &fds)) {
err = ForwardSocketData(tuple->s2, tuple->s1);
if (err == 0) {
// Graceful closure from s2. Propagate to s1.
shutdown(tuple->s1, SD_SEND);
s2ReadShutdown = true;
}
else if (err < 0) {
// Forceful closure. Tear down the whole connection.
break;
}
}
}
closesocket(tuple->s1);
closesocket(tuple->s2);
free(tuple);
return 0;
}
int
FindLocalAddressBySocket(SOCKET s, PIN_ADDR targetAddress)
{
union {
IP_ADAPTER_ADDRESSES addresses;
char buffer[8192];
};
ULONG error;
ULONG length;
PIP_ADAPTER_ADDRESSES currentAdapter;
PIP_ADAPTER_UNICAST_ADDRESS currentAddress;
SOCKADDR_IN6 localSockAddr;
int localSockAddrLen;
// Get local address of the accepted socket so we can find the interface
localSockAddrLen = sizeof(localSockAddr);
if (getsockname(s, (PSOCKADDR)&localSockAddr, &localSockAddrLen) == SOCKET_ERROR) {
fprintf(stderr, "getsockname() failed: %d\n", WSAGetLastError());
return WSAGetLastError();
}
// Get a list of all interfaces and addresses on the system
length = sizeof(buffer);
error = GetAdaptersAddresses(AF_UNSPEC,
GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_MULTICAST |
GAA_FLAG_SKIP_DNS_SERVER |
GAA_FLAG_SKIP_FRIENDLY_NAME,
NULL,
&addresses,
&length);
if (error != ERROR_SUCCESS) {
fprintf(stderr, "GetAdaptersAddresses() failed: %d\n", error);
return error;
}
// First, find the interface that owns the incoming address
currentAdapter = &addresses;
while (currentAdapter != NULL) {
// Check if this interface has the IP 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(&localSockAddr.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 (currentAdapter == NULL) {
// Hopefully the error is caused by transient interface reconfiguration
fprintf(stderr, "Unable to find incoming interface\n");
return WSAENETDOWN;
}
// Now find an IPv4 address on this interface
currentAddress = currentAdapter->FirstUnicastAddress;
while (currentAddress != NULL) {
if (currentAddress->Address.lpSockaddr->sa_family == AF_INET) {
PSOCKADDR_IN ifaceAddrV4 = (PSOCKADDR_IN)currentAddress->Address.lpSockaddr;
*targetAddress = ifaceAddrV4->sin_addr;
return 0;
}
currentAddress = currentAddress->Next;
}
// If we get here, there was no IPv4 address on this interface.
// This is a valid situation, for example if the IPv6 interface
// has no IPv4 connectivity. In this case, we can preserve most
// functionality by forwarding via localhost. WoL won't work but
// the basic stuff will.
fprintf(stderr, "WARNING: No IPv4 connectivity on incoming interface\n");
targetAddress->S_un.S_addr = htonl(INADDR_LOOPBACK);
return 0;
}
DWORD
WINAPI
TcpListenerThreadProc(LPVOID Context)
{
PLISTENER_TUPLE tuple = (PLISTENER_TUPLE)Context;
SOCKET acceptedSocket, targetSocket;
SOCKADDR_IN targetAddress;
PSOCKET_TUPLE relayTuple;
HANDLE thread;
printf("TCP relay running for port %d\n", tuple->port);
for (;;) {
acceptedSocket = accept(tuple->listener, NULL, 0);
if (acceptedSocket == INVALID_SOCKET) {
fprintf(stderr, "accept() failed: %d\n", WSAGetLastError());
break;
}
targetSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (targetSocket == INVALID_SOCKET) {
fprintf(stderr, "socket() failed: %d\n", WSAGetLastError());
closesocket(acceptedSocket);
continue;
}
RtlZeroMemory(&targetAddress, sizeof(targetAddress));
targetAddress.sin_family = AF_INET;
targetAddress.sin_port = htons(tuple->port);
if (FindLocalAddressBySocket(acceptedSocket, &targetAddress.sin_addr) != 0) {
continue;
}
if (connect(targetSocket, (PSOCKADDR)&targetAddress, sizeof(targetAddress)) == SOCKET_ERROR) {
fprintf(stderr, "connect() failed: %d\n", WSAGetLastError());
closesocket(acceptedSocket);
closesocket(targetSocket);
continue;
}
relayTuple = (PSOCKET_TUPLE)malloc(sizeof(*relayTuple));
if (relayTuple == NULL) {
closesocket(acceptedSocket);
closesocket(targetSocket);
break;
}
relayTuple->s1 = acceptedSocket;
relayTuple->s2 = targetSocket;
thread = CreateThread(NULL, 0, TcpRelayThreadProc, relayTuple, 0, NULL);
if (thread == INVALID_HANDLE_VALUE) {
fprintf(stderr, "CreateThread() failed: %d\n", GetLastError());
closesocket(acceptedSocket);
closesocket(targetSocket);
free(relayTuple);
break;
}
CloseHandle(thread);
}
closesocket(tuple->listener);
free(tuple);
return 0;
}
int StartTcpRelay(unsigned short Port)
{
SOCKET listeningSocket;
SOCKADDR_IN6 addr6;
HANDLE thread;
PLISTENER_TUPLE tuple;
listeningSocket = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (listeningSocket == INVALID_SOCKET) {
fprintf(stderr, "socket() failed: %d\n", WSAGetLastError());
return WSAGetLastError();
}
RtlZeroMemory(&addr6, sizeof(addr6));
addr6.sin6_family = AF_INET6;
addr6.sin6_port = htons(Port);
if (bind(listeningSocket, (PSOCKADDR)&addr6, sizeof(addr6)) == SOCKET_ERROR) {
fprintf(stderr, "bind() failed: %d\n", WSAGetLastError());
return WSAGetLastError();
}
if (listen(listeningSocket, SOMAXCONN) == SOCKET_ERROR) {
fprintf(stderr, "listen() failed: %d\n", WSAGetLastError());
return WSAGetLastError();
}
tuple = (PLISTENER_TUPLE)malloc(sizeof(*tuple));
if (tuple == NULL) {
return ERROR_OUTOFMEMORY;
}
tuple->listener = listeningSocket;
tuple->port = Port;
thread = CreateThread(NULL, 0, TcpListenerThreadProc, tuple, 0, NULL);
if (thread == INVALID_HANDLE_VALUE) {
fprintf(stderr, "CreateThread() failed: %d\n", GetLastError());
return GetLastError();
}
CloseHandle(thread);
return 0;
}
int
ForwardUdpPacket(SOCKET from, SOCKET to,
PSOCKADDR target, int targetLen,
PSOCKADDR source, int sourceLen)
{
int len;
char buffer[4096];
len = recvfrom(from, buffer, sizeof(buffer), 0, source, &sourceLen);
if (len < 0) {
fprintf(stderr, "recvfrom() failed: %d\n", WSAGetLastError());
return WSAGetLastError();
}
if (sendto(to, buffer, len, 0, target, targetLen) != len) {
fprintf(stderr, "sendto() failed: %d\n", WSAGetLastError());
// Fake success, since we may just be waiting for a target address
}
return 0;
}
DWORD
WINAPI
UdpRelayThreadProc(LPVOID Context)
{
PUDP_TUPLE tuple = (PUDP_TUPLE)Context;
fd_set fds;
int err;
SOCKADDR_IN6 lastRemote;
SOCKADDR_IN localTarget;
printf("UDP relay running for port %d\n", tuple->port);
RtlZeroMemory(&localTarget, sizeof(localTarget));
localTarget.sin_family = AF_INET;
localTarget.sin_port = htons(tuple->port);
localTarget.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK);
RtlZeroMemory(&lastRemote, sizeof(lastRemote));
for (;;) {
FD_ZERO(&fds);
FD_SET(tuple->ipv6Socket, &fds);
FD_SET(tuple->ipv4Socket, &fds);
err = select(0, &fds, NULL, NULL, NULL);
if (err <= 0) {
break;
}
else if (FD_ISSET(tuple->ipv6Socket, &fds)) {
// Forwarding incoming IPv6 packets to the IPv4 port
// and storing the source address as our current remote
// target for sending IPv4 data back.
err = ForwardUdpPacket(tuple->ipv6Socket, tuple->ipv4Socket,
(PSOCKADDR)&localTarget, sizeof(localTarget),
(PSOCKADDR)&lastRemote, sizeof(lastRemote));
if (err < 0) {
break;
}
}
else if (FD_ISSET(tuple->ipv4Socket, &fds)) {
// Forwarding incoming IPv4 packets to the last known
// address IPv6 address we've heard from. Discard the source.
SOCKADDR_STORAGE unused;
err = ForwardUdpPacket(tuple->ipv4Socket, tuple->ipv6Socket,
(PSOCKADDR)&lastRemote, sizeof(lastRemote),
(PSOCKADDR)&unused, sizeof(unused));
if (err < 0) {
break;
}
}
}
closesocket(tuple->ipv6Socket);
closesocket(tuple->ipv4Socket);
free(tuple);
return 0;
}
int StartUdpRelay(unsigned short Port)
{
SOCKET ipv6Socket;
SOCKET ipv4Socket;
SOCKADDR_IN6 addr6;
SOCKADDR_IN addr;
PUDP_TUPLE tuple;
HANDLE thread;
ipv6Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (ipv6Socket == INVALID_SOCKET) {
fprintf(stderr, "socket() failed: %d\n", WSAGetLastError());
return WSAGetLastError();
}
RtlZeroMemory(&addr6, sizeof(addr6));
addr6.sin6_family = AF_INET6;
addr6.sin6_port = htons(Port);
if (bind(ipv6Socket, (PSOCKADDR)&addr6, sizeof(addr6)) == SOCKET_ERROR) {
fprintf(stderr, "bind() failed: %d\n", WSAGetLastError());
return WSAGetLastError();
}
ipv4Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ipv4Socket == INVALID_SOCKET) {
fprintf(stderr, "socket() failed: %d\n", WSAGetLastError());
return WSAGetLastError();
}
RtlZeroMemory(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK);
if (bind(ipv4Socket, (PSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR) {
fprintf(stderr, "bind() failed: %d\n", WSAGetLastError());
return WSAGetLastError();
}
tuple = (PUDP_TUPLE)malloc(sizeof(*tuple));
if (tuple == NULL) {
return ERROR_OUTOFMEMORY;
}
tuple->ipv4Socket = ipv4Socket;
tuple->ipv6Socket = ipv6Socket;
tuple->port = Port;
thread = CreateThread(NULL, 0, UdpRelayThreadProc, tuple, 0, NULL);
if (thread == INVALID_HANDLE_VALUE) {
fprintf(stderr, "CreateThread() failed: %d\n", GetLastError());
return GetLastError();
}
CloseHandle(thread);
return 0;
}
int Run(void)
{
int err;
WSADATA data;
err = WSAStartup(MAKEWORD(2, 0), &data);
if (err == SOCKET_ERROR) {
fprintf(stderr, "WSAStartup() failed: %d\n", err);
return err;
}
for (int i = 0; i < ARRAYSIZE(TCP_PORTS); i++) {
err = StartTcpRelay(TCP_PORTS[i]);
if (err != 0) {
fprintf(stderr, "Failed to start relay on TCP %d: %d\n", TCP_PORTS[i], err);
return err;
}
}
for (int i = 0; i < ARRAYSIZE(UDP_PORTS); i++) {
err = StartUdpRelay(UDP_PORTS[i]);
if (err != 0) {
fprintf(stderr, "Failed to start relay on UDP %d: %d\n", UDP_PORTS[i], err);
return err;
}
}
return 0;
}
static SERVICE_STATUS_HANDLE ServiceStatusHandle;
static SERVICE_STATUS ServiceStatus;
DWORD
WINAPI
HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
{
switch (dwControl)
{
case SERVICE_CONTROL_INTERROGATE:
return NO_ERROR;
case SERVICE_CONTROL_STOP:
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
return NO_ERROR;
default:
return NO_ERROR;
}
}
VOID
WINAPI
ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
int err;
ServiceStatusHandle = RegisterServiceCtrlHandlerEx(SERVICE_NAME, HandlerEx, NULL);
if (ServiceStatusHandle == NULL) {
fprintf(stderr, "RegisterServiceCtrlHandlerEx() failed: %d\n", GetLastError());
return;
}
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwWin32ExitCode = NO_ERROR;
ServiceStatus.dwWaitHint = 0;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
ServiceStatus.dwCheckPoint = 0;
// Start the relay
err = Run();
if (err != 0) {
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = err;
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
return;
}
// Tell SCM we're running
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
}
static const SERVICE_TABLE_ENTRY ServiceTable[] = {
{ SERVICE_NAME, ServiceMain },
{ NULL, NULL }
};
int main(int argc, char* argv[])
{
if (argc == 2 && !strcmp(argv[1], "exe")) {
Run();
SuspendThread(GetCurrentThread());
return 0;
}
return StartServiceCtrlDispatcher(ServiceTable);
}

155
GSv6Fwd/GSv6Fwd.vcxproj Normal file
View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{87DEAE49-7638-4CDB-88EB-054B1F3CB0D2}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>GSv6Fwd</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="GSv6Fwd.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="GSv6Fwd.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>3.10</ProductVersion>
<ProjectGuid>f8171b99-f5f9-4abf-9fe5-6753539611af</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>GSv6FwdSetup</OutputName>
<OutputType>Package</OutputType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Include="Product.wxs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GSv6Fwd\GSv6Fwd.vcxproj">
<Name>GSv6Fwd</Name>
<Project>{87deae49-7638-4cdb-88eb-054b1f3cb0d2}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
</ItemGroup>
<Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets') " />
<Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
<Error Text="The WiX Toolset v3.11 (or newer) build tools must be installed to build this project. To download the WiX Toolset, see http://wixtoolset.org/releases/" />
</Target>
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Wix.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

40
GSv6FwdSetup/Product.wxs Normal file
View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="IPv6 Forwarder for GS Protocol" Language="1033" Version="1.0.0.0" Manufacturer="Cameron Gutman" UpgradeCode="cae27153-26ed-4da2-8dd5-8cddc7126a05">
<Package InstallerVersion="500" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<Feature Id="ProductFeature" Title="GSv6FwdSetup" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="GSv6FwdSetup" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="ProductComponent">
<File Source="$(var.GSv6Fwd.TargetPath)" KeyPath="yes"/>
<ServiceInstall Type="ownProcess"
Name="GSv6FwdSvc"
DisplayName="IPv6 Forwarder for GS Protocol"
Description="Provides access to GameStream servers over IPv6 networks"
Start="auto"
Account="LocalSystem"
ErrorControl="ignore"
Interactive="no">
<ServiceConfig DelayedAutoStart="yes" OnInstall="yes" OnReinstall="yes" />
</ServiceInstall>
<ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="GSv6FwdSvc" Wait="yes" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>