OCT 1. 移除 Wireguard Windows 程序依赖

This commit is contained in:
黄昕 2023-07-31 14:07:11 +08:00
parent d2a981746d
commit 1a4c76d333
32 changed files with 2240 additions and 467 deletions

View File

@ -58,12 +58,6 @@
"Entry"
{
"MsmKey" = "8:_3853091F559CDFEDEBC0DE9767664FD8"
"OwnerKey" = "8:_00EB5BF3E5624995855CCF580A8AD1D5"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_3853091F559CDFEDEBC0DE9767664FD8"
"OwnerKey" = "8:_A2B46765ECF148F6B3BD76DC027D3B06"
"MsmSig" = "8:_UNDEFINED"
}
@ -82,12 +76,6 @@
"Entry"
{
"MsmKey" = "8:_4709F8F14ABE7B5983245A0461485A18"
"OwnerKey" = "8:_00EB5BF3E5624995855CCF580A8AD1D5"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_4709F8F14ABE7B5983245A0461485A18"
"OwnerKey" = "8:_A2B46765ECF148F6B3BD76DC027D3B06"
"MsmSig" = "8:_UNDEFINED"
}
@ -106,19 +94,13 @@
"Entry"
{
"MsmKey" = "8:_6A8B2CA20D527217332BB0170E559DB9"
"OwnerKey" = "8:_00EB5BF3E5624995855CCF580A8AD1D5"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_6A8B2CA20D527217332BB0170E559DB9"
"OwnerKey" = "8:_A2B46765ECF148F6B3BD76DC027D3B06"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_8A5EF688505390205390D3ABE7EC7364"
"OwnerKey" = "8:_00EB5BF3E5624995855CCF580A8AD1D5"
"MsmKey" = "8:_84BB8455EE8B1AB05AA45633B9D70FD7"
"OwnerKey" = "8:_A2B46765ECF148F6B3BD76DC027D3B06"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
@ -171,6 +153,12 @@
}
"Entry"
{
"MsmKey" = "8:_CEE2F747DF77425F8F8416259F5A60C6"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_CF70965F768635AE40F5A4648E193482"
"OwnerKey" = "8:_451417C63FD78D938C6E04BB65EAA006"
"MsmSig" = "8:_UNDEFINED"
@ -183,12 +171,30 @@
}
"Entry"
{
"MsmKey" = "8:_DC143071B1794733B7955D905E8F722D"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_E128C35F6AE09A19D4BFECA45A1271B7"
"OwnerKey" = "8:_10E071CF096B417C925C5E27E36CE39A"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_E68F9AF277DA30F367774B24D4F4A4B0"
"OwnerKey" = "8:_00EB5BF3E5624995855CCF580A8AD1D5"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_FAA1AF88F72C4C469E6B4CE67FCCB8CB"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
"OwnerKey" = "8:_10E071CF096B417C925C5E27E36CE39A"
"MsmSig" = "8:_UNDEFINED"
@ -286,6 +292,14 @@
"PrerequisitesLocation" = "2:1"
"Url" = "8:"
"ComponentsUrl" = "8:"
"Items"
{
"{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2"
{
"Name" = "8:Microsoft .NET Framework 4.7.2 (x86 and x64)"
"ProductCode" = "8:.NETFramework,Version=v4.7.2"
}
}
}
}
}
@ -529,6 +543,26 @@
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_84BB8455EE8B1AB05AA45633B9D70FD7"
{
"SourcePath" = "8:CRYPT32.dll"
"TargetName" = "8:CRYPT32.dll"
"Tag" = "8:"
"Folder" = "8:_A69AEF7ED77C4BB28FA87F3D7B5FF39A"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_8A5EF688505390205390D3ABE7EC7364"
{
"SourcePath" = "8:MSVCP140D.dll"
@ -620,6 +654,26 @@
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CEE2F747DF77425F8F8416259F5A60C6"
{
"SourcePath" = "8:..\\x64\\Debug\\NetTunnelSvr.exe"
"TargetName" = "8:NetTunnelSvr.exe"
"Tag" = "8:"
"Folder" = "8:_A69AEF7ED77C4BB28FA87F3D7B5FF39A"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_CF70965F768635AE40F5A4648E193482"
{
"AssemblyRegister" = "3:1"
@ -651,6 +705,26 @@
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_DC143071B1794733B7955D905E8F722D"
{
"SourcePath" = "8:..\\x64\\Debug\\wireguard.dll"
"TargetName" = "8:wireguard.dll"
"Tag" = "8:"
"Folder" = "8:_A69AEF7ED77C4BB28FA87F3D7B5FF39A"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
"{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_E128C35F6AE09A19D4BFECA45A1271B7"
{
"AssemblyRegister" = "3:1"
@ -682,6 +756,46 @@
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E68F9AF277DA30F367774B24D4F4A4B0"
{
"SourcePath" = "8:WinDivert.dll"
"TargetName" = "8:WinDivert.dll"
"Tag" = "8:"
"Folder" = "8:_A69AEF7ED77C4BB28FA87F3D7B5FF39A"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_FAA1AF88F72C4C469E6B4CE67FCCB8CB"
{
"SourcePath" = "8:..\\x64\\Debug\\tunnel.dll"
"TargetName" = "8:tunnel.dll"
"Tag" = "8:"
"Folder" = "8:_A69AEF7ED77C4BB28FA87F3D7B5FF39A"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:FALSE"
"IsolateTo" = "8:"
}
}
"FileType"
{

View File

@ -216,13 +216,14 @@ public partial class MainForm : Form
private void menuSetVPNPath_Click(object sender, EventArgs e)
{
DialogResult result = ofDlgWireGuard.ShowDialog();
//DialogResult result = ofDlgWireGuard.ShowDialog();
if (result == DialogResult.OK)
{
_wireguardPath = ofDlgWireGuard.FileName;
NetTunnelLib.SetWireguardPath(_wireguardPath);
}
//if (result == DialogResult.OK)
//{
// _wireguardPath = ofDlgWireGuard.FileName;
// NetTunnelLib.SetWireguardPath(_wireguardPath);
//}
MessageBox.Show("Not Support");
}
private void menuSetModeClient_Click(object sender, EventArgs e)

View File

@ -181,13 +181,7 @@ public class NetTunnelLib
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int SetProtocolEncryptType(ProtoCryptoType type, String pProKey);
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int FindWireguardExe(StringBuilder lpString, int maxSize);
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int SetWireguardPath(String path);
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int GenerateWireguardKeyPairs(StringBuilder wgPubKey, int maxPubKey, StringBuilder wgPrivKey,
int MaxPrivKey);

View File

@ -204,6 +204,12 @@ int CreateControlService(PUSER_SERVER_CONFIG pSvr) {
}
}
if (isSvrStart) {
SPDLOG_INFO(TEXT("Tunnel Service Start Now: {0}"), GetGlobalCfgInfo()->userCfg.userName);
} else {
SPDLOG_INFO(TEXT("Tunnel Service Stoped: {0}"), GetGlobalCfgInfo()->userCfg.userName);
}
HttpResponseError(res, ERR_SUCCESS, nullptr);
g_InterfaceMutex.unlock();
}

View File

@ -114,6 +114,7 @@
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -149,6 +150,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="AIGCJson.hpp" />
<ClInclude Include="common.h" />
<ClInclude Include="framework.h" />
<ClInclude Include="globalcfg.h" />
<ClInclude Include="httplib.h" />
@ -187,6 +189,7 @@
<ClCompile Include="wireguard.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Use</PrecompiledHeader>
</ClCompile>
<ClCompile Include="WireguardService.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View File

@ -81,6 +81,9 @@
<ClInclude Include="WinDivert\include\windivert.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="common.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
@ -125,6 +128,9 @@
<ClCompile Include="ProxyService.cpp">
<Filter>源文件\network</Filter>
</ClCompile>
<ClCompile Include="WireguardService.cpp">
<Filter>源文件\wireguard</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View File

@ -6,15 +6,8 @@
#include "globalcfg.h"
#include "usrerr.h"
#include <winsock2.h>
#pragma comment(lib, "WinDivert.lib")
typedef enum {
PROXY_TCP = 1 << 0,
PROXY_UDP = 1 << 1,
} PROXY_PORTO_TYPE;
typedef struct {
bool isRunning;
HANDLE proxyThread;
@ -23,223 +16,21 @@ typedef struct {
} UDP_PROXY_CTX, *PUDP_PROXY_CTX;
typedef struct {
SOCKET proxySock;
SOCKET reservePortSock;
SOCKET altSock;
bool isRunning;
UINT16 proxyPort;
UINT16 altPort;
HANDLE proxyThread;
HANDLE proxyHandle;
bool isExitSvr;
} TCP_PROXY_CTX, *PTCP_PORXY_CTX;
typedef struct {
int proType;
TCHAR streamFilter[1024];
TCHAR targetIp[MAX_IP_LEN];
UINT16 targetPort;
int vmId;
int svrId;
TCP_PROXY_CTX tcpCtx;
UDP_PROXY_CTX udpCtx;
} PROXY_INFO, *PPROXY_INFO;
typedef struct {
SOCKET s;
PPROXY_INFO pCtx;
bool inbound;
in_addr dest;
} PROXY_CONNECTION_CONFIG, *PPROXY_CONNECTION_CONFIG;
static std::unordered_map<std::string, PPROXY_INFO> g_ProxyColleagues;
static int NewAvaliableSocket(SOCKET *pSock, UINT16 *pPort) {
const int reusedAddr = 1;
sockaddr_in proxySvrAddr {};
sockaddr_in bindAddr {};
int ret;
int addrSize = sizeof(sockaddr_in);
const SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
SPDLOG_ERROR(TEXT("Cretate TCP Socket error: {0}"), WSAGetLastError());
return -ERR_SOCKET_BIND_PORT;
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char *>(&reusedAddr), sizeof(int)) ==
SOCKET_ERROR) {
SPDLOG_ERROR(TEXT("Failed to set socket optino SO_REUSEADDR ({0}})"), WSAGetLastError());
closesocket(sock);
return -ERR_SOCKET_SET_OPT;
}
proxySvrAddr.sin_family = AF_INET;
proxySvrAddr.sin_addr.s_addr = htonl(INADDR_ANY);
proxySvrAddr.sin_port = htons(0);
if (bind(sock, reinterpret_cast<SOCKADDR *>(&proxySvrAddr), sizeof(proxySvrAddr)) == SOCKET_ERROR) {
SPDLOG_ERROR(TEXT("Failed to bind socket ({0})"), WSAGetLastError());
closesocket(sock);
return -ERR_SOCKET_BIND;
}
if (getsockname(sock, reinterpret_cast<struct sockaddr *>(&bindAddr), &addrSize) != 0) {
SPDLOG_ERROR(TEXT("Failed to get socket bind port ({0})"), WSAGetLastError());
closesocket(sock);
return -ERR_SOCKET_GET_OPT;
}
*pSock = sock;
*pPort = ntohs(bindAddr.sin_port);
return ERR_SUCCESS;
}
static DWORD proxyForwardCb(LPVOID lpParameter) {
return 0;
}
static DWORD proxyConnCb(LPVOID lpParameter) {
const auto p = static_cast<PPROXY_CONNECTION_CONFIG>(lpParameter);
sockaddr_in altAddr {};
SOCKET altSock;
HANDLE thread;
SOCKET connSock = p->s;
in_addr dest = p->dest;
PPROXY_INFO pInfo = p->pCtx;
PPROXY_CONNECTION_CONFIG pCfgProxySvr, pCfgAltSvr;
HeapFree(GetProcessHeap(), 0, p);
altSock = socket(AF_INET, SOCK_STREAM, 0);
if (altSock == INVALID_SOCKET) {
SPDLOG_ERROR(TEXT("Cretate TCP Socket error: {0}"), WSAGetLastError());
closesocket(connSock);
return 0;
}
memset(&altAddr, 0, sizeof(altAddr));
altAddr.sin_family = AF_INET;
altAddr.sin_port = htons(pInfo->tcpCtx.altPort);
altAddr.sin_addr = dest;
if (connect(altSock, reinterpret_cast<SOCKADDR *>(&altAddr), sizeof(altAddr)) == SOCKET_ERROR) {
SPDLOG_ERROR(TEXT("Failed to connect socket ({0})"), WSAGetLastError());
closesocket(connSock);
closesocket(altSock);
return 0;
}
pInfo->tcpCtx.altSock = altSock;
pCfgProxySvr = static_cast<PPROXY_CONNECTION_CONFIG>(
HeapAlloc(GetProcessHeap(), 0, sizeof(PROXY_CONNECTION_CONFIG)));
if (pCfgProxySvr == nullptr) {
SPDLOG_ERROR(TEXT("Malloc {0} bytes error."), sizeof(PROXY_CONNECTION_CONFIG));
closesocket(connSock);
closesocket(altSock);
return 0;
}
pCfgAltSvr = static_cast<PPROXY_CONNECTION_CONFIG>(HeapAlloc(GetProcessHeap(), 0, sizeof(PROXY_CONNECTION_CONFIG)));
if (pCfgAltSvr == nullptr) {
SPDLOG_ERROR(TEXT("Malloc {0} bytes error."), sizeof(PROXY_CONNECTION_CONFIG));
closesocket(connSock);
closesocket(altSock);
free(pCfgProxySvr);
return 0;
}
thread = CreateThread(nullptr, // Thread attributes
0, // Stack size (0 = use default)
proxyForwardCb, // Thread start address
pCfgProxySvr, // Parameter to pass to the thread
0, // Creation flags
nullptr); // Thread id
if (thread == nullptr) {
SPDLOG_ERROR(TEXT("Failed to create thread ({0})"), GetLastError());
closesocket(connSock);
closesocket(altSock);
free(pCfgProxySvr);
free(pCfgAltSvr);
return 0;
}
return 0;
}
static int StartTcpProxyService(PPROXY_INFO pInfo) {
pInfo->tcpCtx.isExitSvr = false;
if (listen(pInfo->tcpCtx.proxySock, SOMAXCONN) == SOCKET_ERROR) {
SPDLOG_ERROR(TEXT("Failed to listen socket ({0})"), WSAGetLastError());
closesocket(pInfo->tcpCtx.proxySock);
return -ERR_SOCKET_LISTEN;
}
pInfo->tcpCtx.proxyThread = CreateThread(
nullptr, // Thread attributes
0, // Stack size (0 = use default)
[](LPVOID lpParameter) {
const auto p = static_cast<PPROXY_INFO>(lpParameter);
while (!p->tcpCtx.isExitSvr) {
PPROXY_CONNECTION_CONFIG pCfg;
sockaddr_in connAddr {};
int size = sizeof(connAddr);
SOCKET s = accept(p->tcpCtx.proxySock, reinterpret_cast<struct sockaddr *>(&connAddr), &size);
if (s == INVALID_SOCKET) {
continue;
}
pCfg = static_cast<PPROXY_CONNECTION_CONFIG>(
HeapAlloc(GetProcessHeap(), 0, sizeof(PROXY_CONNECTION_CONFIG)));
if (pCfg) {
HANDLE thread;
pCfg->s = s;
pCfg->dest = connAddr.sin_addr;
pCfg->pCtx = p;
thread = CreateThread(nullptr,
0,
proxyConnCb, // Thread start address
pCfg, // Parameter to pass to the thread
0,
nullptr);
if (thread == nullptr) {
closesocket(s);
HeapFree(GetProcessHeap(), 0, pCfg);
continue;
}
CloseHandle(thread);
}
}
return static_cast<DWORD>(0);
}, // Thread start address
pInfo, // Parameter to pass to the thread
0, // Creation flags
nullptr); // Thread id
if (pInfo->tcpCtx.proxyThread == nullptr) {
SPDLOG_ERROR(TEXT("Create TCP Listen Thread Error ({0})"), GetLastError());
return -ERR_CREATE_THREAD;
}
}
int CreatePorxyService(int proType, const TCHAR *pTargetIp, int targetPort, int vmId, int svrId) {
int CreatePorxyService(const TCHAR *pTargetIp, int targetPort, int vmId, int svrId) {
//int CreatePorxyService() {
int ret;
//int ret;
static HANDLE hDriver;
PPROXY_INFO pInfo;
std::string key;
@ -251,12 +42,11 @@ int CreatePorxyService(int proType, const TCHAR *pTargetIp, int targetPort, int
if ((iter = g_ProxyColleagues.find(key)) != g_ProxyColleagues.end()) {
pInfo = iter->second;
// 如果配置完全相同则直接返回
if (pInfo->vmId == vmId && pInfo->svrId == svrId && pInfo->proType == proType) {
if (pInfo->vmId == vmId && pInfo->svrId == svrId) {
return ERR_SUCCESS;
} else {
pInfo->vmId = vmId;
pInfo->svrId = svrId;
pInfo->proType = proType;
}
} else {
// 创建新的代理配置
@ -272,48 +62,7 @@ int CreatePorxyService(int proType, const TCHAR *pTargetIp, int targetPort, int
memset(pInfo->streamFilter, 0, 1024);
// 重构过滤器
if (pInfo->proType & PROXY_UDP) {
StringCbPrintf(pInfo->streamFilter, 1024, TEXT("(udp.DstPort == %d)"), targetPort);
//StringCbPrintf(pFilter, 1024, TEXT("tcp && remotePort == 9276"));
}
if (pInfo->proType & PROXY_TCP) {
TCHAR tmpFilter[1024];
// 预先分配代理和转发 Socket
if ((ret = NewAvaliableSocket(&pInfo->tcpCtx.proxySock, &pInfo->tcpCtx.proxyPort)) != ERR_SUCCESS) {
return ret;
}
if ((ret = NewAvaliableSocket(&pInfo->tcpCtx.reservePortSock, &pInfo->tcpCtx.altPort)) != ERR_SUCCESS) {
return ret;
}
// 构建过滤器
StringCbPrintf(tmpFilter,
1024,
TEXT("(tcp.DstPort == %d or tcp.DstPort == %d or tcp.DstPort == %d or tcp.SrcPort == %d or "
"tcp.SrcPort == %d or tcp.SrcPort == %d)"),
targetPort,
pInfo->tcpCtx.proxyPort,
pInfo->tcpCtx.altPort,
targetPort,
pInfo->tcpCtx.proxyPort,
pInfo->tcpCtx.altPort);
if (lstrlen(pInfo->streamFilter) > 0) {
StringCbCat(pInfo->streamFilter, 1024, TEXT(" or "));
StringCbCat(pInfo->streamFilter, 1024, tmpFilter);
} else {
StringCbCopy(pInfo->streamFilter, 1024, tmpFilter);
}
}
// 启动代理服务
if ((ret = StartTcpProxyService(pInfo)) != ERR_SUCCESS) {
return ret;
}
StringCbPrintf(pInfo->streamFilter, 1024, TEXT("(udp.DstPort == %d and )"), targetPort);
hDriver = WinDivertOpen(pInfo->streamFilter, WINDIVERT_LAYER_NETWORK, 0, 0);
@ -328,7 +77,7 @@ int CreatePorxyService(int proType, const TCHAR *pTargetIp, int targetPort, int
0, // Stack size (0 = use default)
[](LPVOID lpParameter) {
const HANDLE h = lpParameter;
unsigned char packet[0xFFFF];
unsigned char packet[2048];
UINT packet_len;
WINDIVERT_ADDRESS addr;

View File

@ -423,12 +423,14 @@ int GetUserServerConfigure(const TCHAR *pUserName, const TCHAR *pToken, PUSER_SE
if (pUserName && lstrlen(pUserName) > 0) {
memset(pUser->userName, 0, MAX_PATH);
StringCbCopy(pUser->userName, MAX_PATH, pUserName);
} else {
StringCbCopy(pUser->userName, MAX_PATH, TEXT("tunnel_svr"));
}
StringCbCopy(pUser->userToken, MAX_PATH, pToken);
req.msgContent.token = pToken;
req.msgContent.user = pUserName;
req.msgContent.user = pUser->userName;
ret = ProtolPostMessage(GET_SERVERCFG_PATH, &req, &rsp);
@ -453,6 +455,11 @@ int GetUserClientConfigure(const TCHAR *pUserName, const TCHAR *pToken, PUSER_CL
ProtocolRequest<ReqGetUserCfgParams> req;
ProtocolResponse<RspUsrCliConfigParams> rsp;
if (pUserName == nullptr || lstrlen(pUserName) == 0) {
SPDLOG_ERROR(TEXT("Input pUserName params error: {0}"), pUserName);
return -ERR_INPUT_PARAMS;
}
if (pToken == nullptr || lstrlen(pToken) == 0) {
SPDLOG_ERROR(TEXT("Input pToken params error: {0}"), pToken);
return -ERR_INPUT_PARAMS;

View File

@ -0,0 +1,251 @@
#include "pch.h"
#include "usrerr.h"
#include "globalcfg.h"
#include "tunnel.h"
#include <shlwapi.h>
#include <strsafe.h>
#include <spdlog/spdlog.h>
int GetWireGuardServiceStatus(const TCHAR *pTunnelName, bool *pIsRunning) {
SC_HANDLE schSCManager;
SC_HANDLE schService;
TCHAR svrName[MAX_PATH];
if (pTunnelName == nullptr || lstrlen(pTunnelName) == 0) {
SPDLOG_ERROR(TEXT("Input pTunnelName error: {0}"), pTunnelName);
return -ERR_INPUT_PARAMS;
}
if (pIsRunning == nullptr) {
SPDLOG_ERROR(TEXT("Input pIsRunning params error"));
return -ERR_INPUT_PARAMS;
}
*pIsRunning = false;
StringCbPrintf(svrName, MAX_PATH, TEXT("WireGuardTunnel$%s"), pTunnelName);
// Get a handle to the SCM database.
schSCManager = OpenSCManager(nullptr, // local computer
nullptr, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (nullptr == schSCManager) {
SPDLOG_ERROR(TEXT("OpenSCManager failed ({0})"), GetLastError());
return -ERR_OPEN_SCM;
}
// Get a handle to the service.
schService = OpenService(schSCManager, // SCM database
svrName, // name of service
SERVICE_ALL_ACCESS); // full access
CloseServiceHandle(schService);
// 如果服务不存在则直接返回
if (schService != nullptr) {
*pIsRunning = true;
}
return ERR_SUCCESS;
}
int RemoveGuardService(const TCHAR *pTunnelName, bool bIsWaitStop) {
SC_HANDLE schSCManager;
SC_HANDLE schService;
TCHAR svrName[MAX_PATH];
SERVICE_STATUS svrStatus;
if (pTunnelName == nullptr || lstrlen(pTunnelName) == 0) {
SPDLOG_ERROR(TEXT("Input pTunnelName error: {0}"), pTunnelName);
return -ERR_INPUT_PARAMS;
}
StringCbPrintf(svrName, MAX_PATH, TEXT("WireGuardTunnel$%s"), pTunnelName);
// Get a handle to the SCM database.
schSCManager = OpenSCManager(nullptr, // local computer
nullptr, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (nullptr == schSCManager) {
SPDLOG_ERROR(TEXT("OpenSCManager failed ({0})"), GetLastError());
return -ERR_OPEN_SCM;
}
// Get a handle to the service.
schService = OpenService(schSCManager, // SCM database
svrName, // name of service
SERVICE_ALL_ACCESS); // full access
// 如果服务不存在则直接返回
if (schService == nullptr) {
CloseServiceHandle(schSCManager);
return ERR_SUCCESS;
}
if (ControlService(schService, SERVICE_CONTROL_STOP, &svrStatus) == 0) {
DWORD errCode = GetLastError();
if (errCode != ERROR_SERVICE_CANNOT_ACCEPT_CTRL && errCode != ERROR_SERVICE_NOT_ACTIVE) {
SPDLOG_ERROR(TEXT("Stop Service {1} failed ({0})"), errCode, svrName);
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return -ERR_STOP_SERVICE;
}
}
for (int i = 0; bIsWaitStop && i < 10; i++) {
SERVICE_STATUS_PROCESS ssStatus;
DWORD dwBytesNeeded = 0;
if (QueryServiceStatusEx(schService, // handle to service
SC_STATUS_PROCESS_INFO, // information level
reinterpret_cast<LPBYTE>(&ssStatus), // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded)) // size needed if buffer is too small
{
// 服务已经停止
if (ssStatus.dwCurrentState == SERVICE_STOPPED) {
break;
}
}
//SPDLOG_ERROR(TEXT("Stop Service {1} retry times ({0})"), i + 1, svrName);
Sleep(1000);
}
if (!DeleteService(schService) && GetLastError() != ERROR_SERVICE_MARKED_FOR_DELETE) {
SPDLOG_ERROR(TEXT("Delete Service {1} failed ({0})"), GetLastError(), svrName);
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return -ERR_DELETE_SERVICE;
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return ERR_SUCCESS;
}
int CreateWireGuardService(const TCHAR *pInterfaceName, const TCHAR *pWGConfigFilePath) {
//Service Name: "WireGuardTunnel$SomeTunnelName"
//Display Name: "Some Service Name"
//Service Type: SERVICE_WIN32_OWN_PROCESS
//Start Type: StartAutomatic
//Error Control: ErrorNormal,
//Dependencies: [ "Nsi", "TcpIp" ]
//Sid Type: SERVICE_SID_TYPE_UNRESTRICTED
//Executable: "C:\path\to\example\vpnclient.exe /service configfile.conf"
SC_HANDLE schSCManager;
SC_HANDLE schService;
TCHAR svrName[MAX_PATH];
TCHAR displayName[MAX_PATH];
TCHAR svrPath[MAX_PATH];
TCHAR execParams[MAX_PATH * 2];
if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) {
SPDLOG_ERROR(TEXT("Input pInterfaceName error: {0}"), pInterfaceName);
return -ERR_INPUT_PARAMS;
}
if (pWGConfigFilePath == nullptr || lstrlen(pWGConfigFilePath) == 0) {
SPDLOG_ERROR(TEXT("Input pGUID error: {0}"), pWGConfigFilePath);
return -ERR_INPUT_PARAMS;
}
if (!PathFileExists(pWGConfigFilePath)) {
SPDLOG_ERROR(TEXT("WireGuard Configure File Not Exist: {0}"), pWGConfigFilePath);
return -ERR_ITEM_UNEXISTS;
}
StringCbPrintf(svrName, MAX_PATH, TEXT("WireGuardTunnel$%s"), pInterfaceName);
StringCbPrintf(displayName, MAX_PATH, TEXT("WireGuard Tunnel Service %s"), pInterfaceName);
StringCbPrintf(svrPath, MAX_PATH, TEXT("%s\\NetTunnelSvr.exe"), GetGlobalCfgInfo()->workDirectory);
StringCbPrintf(execParams, MAX_PATH * 2, TEXT("\"%s\" /service \"%s\""), svrPath, pWGConfigFilePath);
//SPDLOG_DEBUG(TEXT("Params: {0}"), execParams);
if (!PathFileExists(svrPath)) {
SPDLOG_ERROR(TEXT("WireGuard Service Not Exist: {0}"), svrPath);
return -ERR_ITEM_UNEXISTS;
}
// Get a handle to the SCM database.
schSCManager = OpenSCManager(nullptr, // local computer
nullptr, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (nullptr == schSCManager) {
SPDLOG_ERROR(TEXT("OpenSCManager failed ({0})"), GetLastError());
return -ERR_OPEN_SCM;
}
// Get a handle to the service.
schService = OpenService(schSCManager, // SCM database
svrName, // name of service
SERVICE_ALL_ACCESS); // full access
// 如果服务已经存在则关闭
if (schService != nullptr) {
int ret;
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
ret = RemoveGuardService(pInterfaceName, true);
if (ret != ERR_SUCCESS) {
return ret;
}
}
schService = CreateService(schSCManager,
svrName,
displayName,
SC_MANAGER_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
execParams,
nullptr,
nullptr,
TEXT("Nsi\0TcpIp"),
nullptr,
nullptr);
if (schService == nullptr) {
SPDLOG_ERROR(TEXT("Create Service {1} failed ({0})"), GetLastError(), svrName);
CloseServiceHandle(schSCManager);
return -ERR_CREATE_SERVICE;
} else {
SERVICE_SID_INFO info;
SERVICE_DESCRIPTIONA desc;
info.dwServiceSidType = SERVICE_SID_TYPE_UNRESTRICTED;
if (!ChangeServiceConfig2(schService, SERVICE_CONFIG_SERVICE_SID_INFO, &info)) {
SPDLOG_ERROR(TEXT("Change Service {1} SERVICE_CONFIG_SERVICE_SID_INFO Configure failed ({0})"),
GetLastError(),
svrName);
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return -ERR_CONFIG_SERVICE;
}
desc.lpDescription = TEXT(const_cast<LPSTR>("SCC Tunnel Service over WireGuard"));
if (!ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &desc)) {
SPDLOG_ERROR(TEXT("Change Service {1} SERVICE_CONFIG_DESCRIPTION Configure failed ({0})"),
GetLastError(),
svrName);
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return -ERR_CONFIG_SERVICE;
}
if (!StartService(schService, 0, nullptr)) {
SPDLOG_ERROR(TEXT("Start Service {1} failed ({0})"), GetLastError(), svrName);
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return -ERR_START_SERVICE;
}
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return ERR_SUCCESS;
}

75
NetTunnelSDK/common.h Normal file
View File

@ -0,0 +1,75 @@
#pragma once
/**
* @brief WireGuard key
*/
constexpr auto WG_KEY_MAX = (64);
/**
* @brief
*/
#define NET_CARD_MAX (32)
/**
* @brief IP (IPv6)
*/
#define MAX_IP_LEN (48)
/**
* @brief IP
*/
#define MIN_IP_LEN (7)
/**
* @brief (IPv6)
*/
#define MAX_NETCARD_NAME (64)
/**
* @brief
*
*/
typedef enum {
CRYPTO_NONE = 0, ///< 不加密
CRYPTO_BASE64 = 1, ///< BASE64 字符串编码
CRYPTO_AES128 = 2, ///< AES 128位秘钥 加密
CRYPTO_3DES = 3, ///< 3DES 加密
CRYPTO_AES256 = 4, ///< AES 256 位秘钥加密
CRYPTO_MAX,
} PROTO_CRYPTO_TYPE;
/**
* @brief
*
*/
enum LOG_LEVEL {
LOG_TRACE = 0, ///< TRACE 日志等级
LOG_DEBUG, ///< DEBUG 日志等级
LOG_INFO, ///< INFO 日志等级
LOG_WARN, ///< WARN 日志等级
LOG_ERROR, ///< ERROR 日志等级
LOG_CRITICAL, ///< CRITICAL 日志等级
LOG_OFF ///< 关闭日志
};
/**
* @brief Hash
*
*/
typedef enum {
HASH_MD2 = 0, ///< MD2 HASH 算法
HASH_MD4, ///< MD4 HASH 算法
HASH_MD5, ///< MD5 HASH 算法
HASH_SHA1, ///< SHA1 HASH 算法
HASH_SHA256, ///< SHA256 HASH 算法
HASH_SHA384, ///< SHA384 HASH 算法
HASH_SHA512 ///< SHA512 HASH 算法
} HASH_TYPE;
typedef enum {
CHK_SYSTEM_INIT,
CHK_WIREGUARD_CONFIG,
CHK_WIREGUARD_SERVICE,
CHK_WG_INTERFACE_PRIVATE,
CHK_MAX
} CHECK_FUNCTION;

View File

@ -6,21 +6,9 @@
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
CoInitialize(nullptr);
CoInitializeSecurity(nullptr,
-1,
nullptr,
nullptr,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE,
nullptr,
EOAC_NONE,
nullptr);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
CoFreeUnusedLibraries();
case DLL_PROCESS_DETACH:
break;
default:
break;

View File

@ -1,7 +1,8 @@
#pragma once
#include <spdlog/spdlog.h>
#include "tunnel.h"
#include "common.h"
#if 0
/**
* @brief WireGuard
*/
@ -11,6 +12,7 @@ typedef struct {
TCHAR wgPath[MAX_PATH]; ///< wg.exe 路径
BOOL wgExists; ///< wg.exe 是否存在
} WIREGUARD_CFG, *PWIREGUARD_CFG;
#endif
/**
* @brief WireGuard
@ -80,7 +82,7 @@ typedef struct {
BOOL enableLog; ///< 是否启用日志
spdlog::level::level_enum logLevel; ///< 日志等级
TCHAR cfgPath[MAX_PATH]; ///< 配置文件路径
WIREGUARD_CFG wireguardCfg; ///< wireguard 配置项 @see WIREGUARD_CFG
//WIREGUARD_CFG wireguardCfg; ///< wireguard 配置项 @see WIREGUARD_CFG
WGINTERFACE_CFG wgServerCfg; ///< wireguard 服务端网络接口配置
WGINTERFACE_CFG wgClientCfg; ///< wireguard 客户端网络接口配置
USER_CONFIG userCfg; ///< 用户配置项

View File

@ -1,6 +1,6 @@
#pragma once
#include "tunnel.h"
#include "common.h"
#include <windows.h>

View File

@ -1241,6 +1241,52 @@ int RemoveNATRule(const TCHAR *pInterfaceName) {
return ERR_SUCCESS;
}
int SetInterfaceIpAddress(const TCHAR *pInterfaceName, const TCHAR *pIpaddr, const TCHAR *pNetmask) {
int ret;
TCHAR cmdBuf[MAX_PATH];
//int cidr;
DWORD retCode;
IP_INFO ipInfo {};
if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) {
SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName);
return -ERR_INPUT_PARAMS;
}
if (pIpaddr == nullptr || lstrlen(pIpaddr) == 0) {
SPDLOG_ERROR("Input pIpaddr params error: {0}", pIpaddr);
return -ERR_INPUT_PARAMS;
}
if (pNetmask == nullptr || lstrlen(pNetmask) == 0) {
SPDLOG_WARN("Input pNetmask params error: {0}", pNetmask);
return -ERR_INPUT_PARAMS;
}
GetIpV4InfoFromNetmask(pIpaddr, pNetmask, &ipInfo);
//cidr = NetmaskToCIDR(pNetmask);
if (FAILED(StringCbPrintf(
cmdBuf,
MAX_PATH,
"PowerShell -Command \"& {New-NetIPAddress -InterfaceAlias %s -AddressFamily IPv4 -IPAddress %s -PrefixLength %d}\"",
pInterfaceName,
pIpaddr,
ipInfo.prefix))) {
SPDLOG_ERROR("Format String Error");
return -ERR_MEMORY_STR;
}
if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) {
SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret);
return -ERR_CALL_SHELL;
}
SPDLOG_DEBUG("Run Set IP Command({1}): {0}", cmdBuf, retCode);
return ERR_SUCCESS;
}
#if 0
int GetWindowsHyperVStatus(int *pEnabled) {
int ret;

View File

@ -234,7 +234,19 @@ TUNNEL_API int __cdecl SetNATRule(const TCHAR *pInterfaceName, const TCHAR *pCid
*/
TUNNEL_API int __cdecl RemoveNATRule(const TCHAR *pInterfaceName);
/**
* @brief IP地址
* @param[in] pInterfaceName
* @param[in] pIpaddr IP
* @param[in] pNetmask
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_MALLOC_MEMORY
* - -ERR_MEMORY_STR
* - -ERR_CALL_SHELL
* - ERR_SUCCESS
*/
TUNNEL_API int __cdecl SetInterfaceIpAddress(const TCHAR *pInterfaceName, const TCHAR *pIpaddr, const TCHAR *pNetmask);
TUNNEL_API int __cdecl CreatePorxyService();
#if 0
/**

View File

@ -95,7 +95,18 @@ int TunnelSDKInitEnv(const TCHAR *pWorkDir,
LOG_LEVEL level,
bool isWorkServer) {
size_t length;
CoInitialize(nullptr);
CoInitializeSecurity(nullptr,
-1,
nullptr,
nullptr,
RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE,
nullptr,
EOAC_NONE,
nullptr);
memset(&g_globalConfig, 0, sizeof(SDK_CONFIG));
g_globalConfig.isWorkServer = isWorkServer;
@ -145,10 +156,12 @@ int TunnelSDKInitEnv(const TCHAR *pWorkDir,
StringCbPrintf(g_globalConfig.cfgPath, MAX_PATH, TEXT("%s\\%s"), g_globalConfig.workDirectory, CONFIG_FILE_NAME);
#if 0
if (FindWireguardExe(nullptr, 0) != ERR_SUCCESS) {
SPDLOG_ERROR(TEXT("WireGuard not found, Please install WireGuard first or set the WireGuard Path."));
return -ERR_ITEM_EXISTS;
return -ERR_ITEM_UNEXISTS;
}
#endif
return ERR_SUCCESS;
}
@ -156,6 +169,7 @@ int TunnelSDKInitEnv(const TCHAR *pWorkDir,
void TunnelSDKUnInit() {
RemoteWireGuardControl(false);
LocalWireGuardControl(false, false);
CoFreeUnusedLibraries();
}
void EnableSCGProxy(bool isEnable) {
@ -210,26 +224,6 @@ int CheckSystemMinRequired(CHK_RESULT chkResult[CHK_MAX]) {
SPDLOG_ERROR(pChk->errMsg);
}
break;
case CHK_WIREGUARD_INSTALL:
if (!g_globalConfig.wireguardCfg.wireguardExists) {
pChk->result = false;
StringCbCopy(
pChk->errMsg,
MAX_PATH,
TEXT("错误: 系统未检测到 wireguard.exe 程序,请先下载并安装 WireGuard 最新版本,或者调用 "
"SetWireguardPath 接口设置 WireGuard 程序路径。"));
SPDLOG_ERROR(pChk->errMsg);
}
break;
case CHK_WG_INSTALL:
if (!g_globalConfig.wireguardCfg.wgExists) {
pChk->result = false;
StringCbCopy(pChk->errMsg,
MAX_PATH,
TEXT("错误: 系统未检测到 wg.exe 程序,请重新安装 WireGuard 或者修复 wg.exe 程序。"));
SPDLOG_ERROR(pChk->errMsg);
}
break;
case CHK_WIREGUARD_CONFIG: {
TCHAR cfgVal[MAX_PATH];
GetPrivateProfileString(CFG_WIREGUARD_SECTION,

View File

@ -1,5 +1,6 @@
#pragma once
#include "common.h"
#include <Windows.h>
#ifdef NETTUNNELSDK_EXPORTS
@ -8,82 +9,6 @@
#define TUNNEL_API __declspec(dllimport)
#endif
/**
* @brief WireGuard key
*/
constexpr auto WG_KEY_MAX = (64);
/**
* @brief
*/
#define NET_CARD_MAX (32)
/**
* @brief IP (IPv6)
*/
#define MAX_IP_LEN (48)
/**
* @brief IP
*/
#define MIN_IP_LEN (7)
/**
* @brief (IPv6)
*/
#define MAX_NETCARD_NAME (64)
/**
* @brief
*
*/
typedef enum {
CRYPTO_NONE = 0, ///< 不加密
CRYPTO_BASE64 = 1, ///< BASE64 字符串编码
CRYPTO_AES128 = 2, ///< AES 128位秘钥 加密
CRYPTO_3DES = 3, ///< 3DES 加密
CRYPTO_AES256 = 4, ///< AES 256 位秘钥加密
CRYPTO_MAX,
} PROTO_CRYPTO_TYPE;
/**
* @brief
*
*/
enum LOG_LEVEL {
LOG_TRACE = 0, ///< TRACE 日志等级
LOG_DEBUG, ///< DEBUG 日志等级
LOG_INFO, ///< INFO 日志等级
LOG_WARN, ///< WARN 日志等级
LOG_ERROR, ///< ERROR 日志等级
LOG_CRITICAL, ///< CRITICAL 日志等级
LOG_OFF ///< 关闭日志
};
/**
* @brief Hash
*
*/
typedef enum {
HASH_MD2 = 0, ///< MD2 HASH 算法
HASH_MD4, ///< MD4 HASH 算法
HASH_MD5, ///< MD5 HASH 算法
HASH_SHA1, ///< SHA1 HASH 算法
HASH_SHA256, ///< SHA256 HASH 算法
HASH_SHA384, ///< SHA384 HASH 算法
HASH_SHA512 ///< SHA512 HASH 算法
} HASH_TYPE;
typedef enum {
CHK_SYSTEM_INIT,
CHK_WIREGUARD_INSTALL,
CHK_WG_INSTALL,
CHK_WIREGUARD_CONFIG,
CHK_WIREGUARD_SERVICE,
CHK_WG_INTERFACE_PRIVATE,
CHK_MAX
} CHECK_FUNCTION;
/**
* @brief
*
@ -156,7 +81,8 @@ TUNNEL_API void __cdecl SetCurrentNetShareMode(NET_SHARE_MODE shareMode);
* @return 0: 0 @see USER_ERRNO
* - -ERR_ITEM_EXISTS WireGuard
* - -ERR_SYS_CALL
* - -ERR_CREATE_FILE
* - -ERR_CREATE_FILE
* - -ERR_ITEM_UNEXISTS WireGuard
* - ERR_SUCCESS
*/
TUNNEL_API int __cdecl TunnelSDKInitEnv(const TCHAR *pWorkDir,
@ -183,28 +109,6 @@ TUNNEL_API int __cdecl SetProtocolEncryptType(const PROTO_CRYPTO_TYPE type, cons
*/
TUNNEL_API void __cdecl TunnelLogEnable(bool enLog);
/**
* @brief WireGuard
* @param[out] pFullPath wireguard.exe
* @param[in] maxSize pFullPath
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_MALLOC_MEMORY
* - -ERR_FILE_NOT_EXISTS
* - ERR_SUCCESS
*/
TUNNEL_API int __cdecl FindWireguardExe(TCHAR *pFullPath, int maxSize);
/**
* @brief wireguard.exe
* @param[in] pPath wireguard.exe
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_ITEM_UNEXISTS
* - ERR_SUCCESS
*/
TUNNEL_API int __cdecl SetWireguardPath(const TCHAR *pPath);
/**
* @brief WireGuard
* @param[out] pPubKey
@ -242,6 +146,49 @@ TUNNEL_API int __cdecl WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgCon
*/
TUNNEL_API int __cdecl WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgConfig);
/**
* @brief WireGuard
* @param pInterfaceName
* @param pWGConfigFilePath
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_ITEM_UNEXISTS
* - -ERR_OPEN_SCM
* - -ERR_OPEN_SERVICE
* - -ERR_CREATE_SERVICE
* - -ERR_CONFIG_SERVICE
* - -ERR_START_SERVICE
* - ERR_SUCCESS
*/
TUNNEL_API int __cdecl CreateWireGuardService(const TCHAR *pInterfaceName, const TCHAR *pWGConfigFilePath);
/**
* @brief WireGuard
* @param pTunnelName
* @param pIsRunning pIsRunning WireGuard
* - TRUE
* - FALSE
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_OPEN_SCM
* - ERR_SUCCESS
*/
TUNNEL_API int __cdecl GetWireGuardServiceStatus(const TCHAR *pTunnelName, bool *pIsRunning);
/**
* @brief WireGuard
* @param pTunnelName
* @param bIsWaitStop TRUE: , FALSE:
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_OPEN_SCM
* - -ERR_OPEN_SERVICE
* - -ERR_STOP_SERVICE
* - -ERR_DELETE_SERVICE
* - ERR_SUCCESS
*/
TUNNEL_API int __cdecl RemoveGuardService(const TCHAR *pTunnelName, bool bIsWaitStop);
/**
* @brief / WireGuard
* @param[in] bInstall TRUE , FALSE
@ -362,6 +309,29 @@ TUNNEL_API int __cdecl CalcFileHash(const HASH_TYPE type, const TCHAR *pPath, TC
*/
TUNNEL_API int __cdecl InstallWindowsNATCommand();
TUNNEL_API int __cdecl WireGuardNetConnectionSharingEnable();
/**
* @brief WireGuard
* @param[out] pFullPath wireguard.exe
* @param[in] maxSize pFullPath
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_MALLOC_MEMORY
* - -ERR_FILE_NOT_EXISTS
* - ERR_SUCCESS
*/
TUNNEL_API int __cdecl FindWireguardExe(TCHAR *pFullPath, int maxSize);
/**
* @brief wireguard.exe
* @param[in] pPath wireguard.exe
* @return 0: 0 @see USER_ERRNO
* - -ERR_INPUT_PARAMS
* - -ERR_ITEM_UNEXISTS
* - ERR_SUCCESS
*/
TUNNEL_API int __cdecl SetWireguardPath(const TCHAR *pPath);
#endif
#ifdef __cplusplus
}

View File

@ -23,8 +23,13 @@ enum USER_ERRNO {
ERR_GET_FILE_SIZE, ///< 获取文件大小失败
ERR_FIND_FILE, ///< 查找文件失败
ERR_COPY_FILE, ///< 复制文件失败
ERR_OPEN_SCM, ///< 打开服务管理器设备
ERR_OPEN_SCM, ///< 打开服务管理器设备失败
ERR_OPEN_SERVICE, ///< 打开服务失败
ERR_CREATE_SERVICE, ///< 创建服务失败
ERR_START_SERVICE, ///< 启动服务失败
ERR_STOP_SERVICE, ///< 停止服务失败
ERR_DELETE_SERVICE, ///< 删除服务失败
ERR_CONFIG_SERVICE, ///< 修改服务配置失败
ERR_GET_SERVICESSTATUS, ///< 获取服务状态失败
ERR_MALLOC_MEMORY, ///< 分配内存失败
ERR_MMAP_MEMORY, ///< 共享内存失败
@ -46,7 +51,7 @@ enum USER_ERRNO {
ERR_BCRYPT_CREATEHASH, ///< 创建 Hash 算法失败
ERR_BCRYPT_HASHDATA, ///< 计算 Hash 数据失败
ERR_BCRYPT_FINISHHASH, ///< 计算 Hash 结果失败
ERR_NET_UNCONNECT = 200, ///< 网络未连接
ERR_NET_UNCONNECT = 200, ///< 网络未连接
ERR_NET_CATEGORY_MODE, ///< 网络工作模式
ERR_NET_INTELNEL_ICS, ///< 共享 Intelnet 网络 ICS 共享失败
ERR_NET_WIREGUARD_ICS, ///< 共享 WireGuard 网络 ICS 共享失败

View File

@ -9,15 +9,13 @@
#include "misc.h"
#include "network.h"
#define USED_EMBEDDED_WG (1)
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "Winmm.lib")
#define WG_NIC_DISCRIPT TEXT("WireGuard Tunnel")
static NET_SHARE_MODE g_CurShareMode = ICS_SHARE_MODE;
constexpr auto WINENVBUF_SIZE = (4096);
NET_SHARE_MODE GetCurrentNetShareMode() {
return g_CurShareMode;
}
@ -39,8 +37,7 @@ int GetWireGuardWorkMode(bool *pIsWorkServer) {
int WireGuardInstallDefaultServerService(bool bInstall) {
TCHAR cfgVal[MAX_PATH];
DWORD retCode;
GetPrivateProfileString(CFG_WIREGUARD_SECTION,
CFG_WGCFG_PATH,
TEXT(""),
@ -50,14 +47,20 @@ int WireGuardInstallDefaultServerService(bool bInstall) {
if (lstrlen(cfgVal) > 0) {
if (PathFileExists(cfgVal)) {
TCHAR cmdBuf[MAX_PATH];
TCHAR svrName[MAX_PATH];
int ret;
TCHAR svrName[MAX_PATH];
StringCbCopy(svrName, MAX_PATH, cfgVal);
PathStripPath(svrName);
PathRemoveExtension(svrName);
#if USED_EMBEDDED_WG
if (bInstall) {
ret = WireGuardInstallServerService(cfgVal); //CreateWireGuardService(svrName, cfgVal);
} else {
ret = RemoveGuardService(svrName, true);
}
#else
if (bInstall) {
// 安装服务
StringCbPrintf(cmdBuf,
@ -81,8 +84,9 @@ int WireGuardInstallDefaultServerService(bool bInstall) {
}
SPDLOG_DEBUG(TEXT("Run command [{0}]"), cmdBuf);
#endif
if (bInstall) {
if (bInstall && ret == ERR_SUCCESS) {
int retry = 10;
do {
ret = WaitNetAdapterConnected(svrName, 1000);
@ -102,9 +106,12 @@ int WireGuardInstallDefaultServerService(bool bInstall) {
int WireGuardInstallServerService(const TCHAR *pTunnelCfgPath) {
// 卸载服务
TCHAR cmdBuf[MAX_PATH];
TCHAR svrName[MAX_PATH];
int ret;
DWORD retCode;
StringCbCopy(svrName, MAX_PATH, pTunnelCfgPath);
PathStripPath(svrName);
PathRemoveExtension(svrName);
if (pTunnelCfgPath == nullptr || lstrlen(pTunnelCfgPath) == 0) {
SPDLOG_ERROR(TEXT("Input pTunnelCfgPath params error"));
@ -115,6 +122,13 @@ int WireGuardInstallServerService(const TCHAR *pTunnelCfgPath) {
return -ERR_ITEM_UNEXISTS;
}
if ((ret = CreateWireGuardService(svrName, pTunnelCfgPath)) != ERR_SUCCESS) {
SPDLOG_ERROR(TEXT("Create WireGuard Service Error({0}): {1}, {2} "), ret, svrName, pTunnelCfgPath);
return ret;
}
#if 0
// 安装服务
StringCbPrintf(cmdBuf,
MAX_PATH,
@ -128,26 +142,31 @@ int WireGuardInstallServerService(const TCHAR *pTunnelCfgPath) {
}
SPDLOG_DEBUG(TEXT("Run command [{0}]"), cmdBuf);
#endif
return ERR_SUCCESS;
}
int WireGuardUnInstallServerService(const TCHAR *pTunnelName) {
// 卸载服务
TCHAR cmdBuf[MAX_PATH];
TCHAR svrName[MAX_PATH];
// 卸载服务
int ret;
DWORD retCode;
if (pTunnelName == nullptr || lstrlen(pTunnelName) == 0) {
SPDLOG_ERROR(TEXT("Input pTunnelName params error"));
return -ERR_INPUT_PARAMS;
}
#if 0
StringCbCopy(svrName, MAX_PATH, pTunnelName);
PathStripPath(svrName);
PathRemoveExtension(svrName);
#endif
#if USED_EMBEDDED_WG
if ((ret = RemoveGuardService(pTunnelName, true)) != ERR_SUCCESS) {
SPDLOG_ERROR(TEXT("Stop WireGuard Service Error: {0}"), ret);
return ret;
}
#else
StringCbPrintf(cmdBuf,
MAX_PATH,
TEXT("\"%s\" /uninstalltunnelservice %s"),
@ -160,7 +179,7 @@ int WireGuardUnInstallServerService(const TCHAR *pTunnelName) {
}
SPDLOG_DEBUG(TEXT("Run command [{0}]"), cmdBuf);
#endif
return ERR_SUCCESS;
}
@ -194,9 +213,12 @@ int IsWireGuardServerInstalled(bool *pIsInstalled) {
}
int IsWireGuardServerRunning(const TCHAR *pIfName, bool *pIsRunning) {
int ret;
#if USED_EMBEDDED_WG
return GetWireGuardServiceStatus(pIfName, pIsRunning);
#else
int ret;
PNIC_CONTENT pInfo = nullptr;
int size = 0;
int size = 0;
if (pIfName == nullptr || lstrlen(pIfName) == 0) {
SPDLOG_ERROR(TEXT("Input pIfName params error"));
@ -223,6 +245,7 @@ int IsWireGuardServerRunning(const TCHAR *pIfName, bool *pIsRunning) {
}
return ret;
#endif
}
int WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgConfig) {
@ -500,7 +523,9 @@ int WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgConfig) {
return ERR_SUCCESS;
}
// TODO: Change implement
int GenerateWireguardKeyPairs(TCHAR *pPubKey, int pubkeySize, TCHAR *pPrivKey, int privKeySize) {
#if 0
int ret;
DWORD retCode;
TCHAR cmdBuffer[MAX_PATH];
@ -540,10 +565,11 @@ int GenerateWireguardKeyPairs(TCHAR *pPubKey, int pubkeySize, TCHAR *pPrivKey, i
StringCbCopy(pPubKey, pubkeySize, cmdResult);
SPDLOG_DEBUG(TEXT("Run command [{0}] resutl \'{1}\'"), cmdBuffer, cmdResult);
#endif
return ERR_SUCCESS;
}
#if 0
int SetWireguardPath(const TCHAR *pPath) {
if (pPath == nullptr) {
return -ERR_INPUT_PARAMS;
@ -573,6 +599,7 @@ int SetWireguardPath(const TCHAR *pPath) {
}
}
int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
TCHAR path[MAX_PATH];
TCHAR wireguardPath[MAX_PATH];
@ -708,7 +735,6 @@ int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
return -ERR_FILE_NOT_EXISTS;
}
#if 0
int InstallWindowsNATCommand() {
TCHAR psCmdPath[MAX_PATH];

View File

@ -0,0 +1,145 @@
#include <Windows.h>
#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
int net_nat() {
HRESULT hr;
// Initialize COM
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (FAILED(hr)) {
std::cout << "Failed to initialize COM" << std::endl;
return 1;
}
// Initialize security
hr = CoInitializeSecurity(NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL);
if (FAILED(hr)) {
std::cout << "Failed to initialize security" << std::endl;
CoUninitialize();
return 1;
}
// Obtain the initial locator to WMI
IWbemLocator *pLocator = NULL;
hr = CoCreateInstance(CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
reinterpret_cast<LPVOID *>(&pLocator));
if (FAILED(hr)) {
std::cout << "Failed to create IWbemLocator object" << std::endl;
CoUninitialize();
return 1;
}
// Connect to the root\StandardCimv2 namespace with the current user
IWbemServices *pServices = NULL;
hr = pLocator->ConnectServer(_bstr_t(L"ROOT\\StandardCimv2"), NULL, NULL, 0, NULL, 0, 0, &pServices);
if (FAILED(hr)) {
std::cout << "Failed to connect to WMI namespace" << std::endl;
pLocator->Release();
CoUninitialize();
return 1;
}
// Set the authentication information to the current user
hr = CoSetProxyBlanket(pServices,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE);
if (FAILED(hr)) {
std::cout << "Failed to set proxy blanket" << std::endl;
pServices->Release();
pLocator->Release();
CoUninitialize();
return 1;
}
// Get the NAT class object
IWbemClassObject *pClass = NULL;
hr = pServices->GetObject(_bstr_t("MSFT_NetNat"), 0, NULL, &pClass, NULL);
if (FAILED(hr)) {
std::cout << "Failed to get NAT class object" << std::endl;
pServices->Release();
pLocator->Release();
CoUninitialize();
return 1;
}
// Spawn an instance of the NAT class
IWbemClassObject *pInstance = NULL;
hr = pClass->SpawnInstance(0, &pInstance);
if (FAILED(hr)) {
std::cout << "Failed to spawn NAT instance" << std::endl;
pClass->Release();
pServices->Release();
pLocator->Release();
CoUninitialize();
return 1;
}
// Set the properties of the NAT instance
VARIANT var;
VariantInit(&var);
// Set the name of the NAT instance
var.vt = VT_BSTR;
var.bstrVal = SysAllocString(L"MyNATRule");
hr = pInstance->Put(L"Name", 0, &var, 0);
if (FAILED(hr)) {
std::cout << "Failed to set NAT instance name" << std::endl;
VariantClear(&var);
pInstance->Release();
pClass->Release();
pServices->Release();
pLocator->Release();
CoUninitialize();
return 1;
}
// Set other properties as needed
// ...
// Create the NAT instance
IWbemCallResult *pResult = NULL;
hr = pServices->PutInstance(pInstance, WBEM_FLAG_CREATE_ONLY, NULL, &pResult);
if (FAILED(hr)) {
std::cout << "Failed to create NAT instance" << std::endl;
VariantClear(&var);
pInstance->Release();
pClass->Release();
pServices->Release();
pLocator->Release();
CoUninitialize();
return 1;
}
// Cleanup
VariantClear(&var);
pResult->Release();
pInstance->Release();
pClass->Release();
pServices->Release();
pLocator->Release();
CoUninitialize();
std::cout << "NAT rule created successfully" << std::endl;
return 0;
}

View File

@ -44,7 +44,7 @@ void test_socket() {
#if 0
int service_test() {
TCHAR szSvcName[] = _T("WireGuard");
TCHAR szSvcName[] = TEXT("WireGuard");
SC_HANDLE schSCManager = nullptr;
SC_HANDLE schService = nullptr;
@ -55,7 +55,6 @@ int service_test() {
DWORD dwBytesNeeded = 0;
// Get a handle to the SCM database.
schSCManager = OpenSCManager(nullptr, // local computer
nullptr, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
@ -111,13 +110,47 @@ int service_test() {
cin.get();
return 0;
}
bool test_code() {
char temp_path[MAX_PATH + 1] = { 0 };
if (!::GetTempPathA(MAX_PATH, temp_path))
{
//LOG_ERROR("GetTempPathA failed! we use the default logger!");
strcpy_s(temp_path, MAX_PATH, "c:\\windows\\temp\\");
}
char log_file[MAX_PATH + 1] = { 0 };
sprintf_s(log_file, MAX_PATH, "%s%s", temp_path, "tunnel.log");
#ifdef _DEBUG
LOG_LEVEL log_level = LOG_DEBUG;
#else
LOG_LEVEL log_level = TUNNEL_LOG_INFO;
#endif
int ret = TunnelSDKInitEnv(NULL, g_PlatformURL, log_file, log_level, true);
if (ret != ERR_SUCCESS)
{
//LOG_ERROR("TunnelSDKInitEnv failed! err=%d!", ret);
return false;
}
std::string local_ip = "127.0.0.1";
PUSER_SERVER_CONFIG server_config = NULL;
ret = GetUserServerConfigure(NULL, local_ip.c_str(), &server_config);
if (ret != ERR_SUCCESS)
{
//LOG_ERROR("GetUserServerConfigure failed! err=%d!", ret);
return false;
}
}
#endif
int tunnel_service() {
PUSER_SERVER_CONFIG pSvrCfg;
//TCHAR logPath[MAX_PATH];
TunnelSDKInitEnv(g_AppPath, g_PlatformURL, nullptr, LOG_DEBUG, true);
TunnelSDKInitEnv(nullptr, g_PlatformURL, nullptr, LOG_DEBUG, true);
//StringCbPrintf(logPath, MAX_PATH, TEXT("%s\\TestApp.log"), g_AppPath);
//InitTunnelSDKLog(nullptr, LOG_DEBUG);
@ -144,8 +177,13 @@ int main() {
//SetRouteTable();
//CreatePorxyService();
//tunnel_service();
test_socket();
//test_code();
//test_socket();
tunnel_service();
//net_nat();
//main_wireguard(true);
//main_wireguard_getinfo();
while (true) {
Sleep(100);

View File

@ -105,6 +105,7 @@
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>../NetTunnelSDK;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>Default</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -132,6 +133,7 @@
<ClCompile Include="CryptoExample.cpp" />
<ClCompile Include="firewall.cpp" />
<ClCompile Include="NetInterface.cpp" />
<ClCompile Include="NetNat.cpp" />
<ClCompile Include="NetShare.cpp" />
<ClCompile Include="NetTunnelSDKTestApp.cpp" />
<ClCompile Include="RouteTable.cpp" />

View File

@ -33,6 +33,9 @@
<ClCompile Include="firewall.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="NetNat.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="common.h">

View File

@ -0,0 +1,718 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018-2021 WireGuard LLC. All Rights Reserved.
*/
#include <winsock2.h>
#include <Windows.h>
#include <ws2ipdef.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <bcrypt.h>
#include <wincrypt.h>
#include <sysinfoapi.h>
#include <winternl.h>
#include <stdio.h>
#include <wbemcli.h>
#include "wireguard.h"
#include "common.h"
#include "tunnel.h"
#include "network.h"
#include <strsafe.h>
#include <spdlog/spdlog.h>
#pragma comment(lib, "Crypt32.lib")
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
static WIREGUARD_CREATE_ADAPTER_FUNC *WireGuardCreateAdapter;
static WIREGUARD_OPEN_ADAPTER_FUNC *WireGuardOpenAdapter;
static WIREGUARD_CLOSE_ADAPTER_FUNC *WireGuardCloseAdapter;
static WIREGUARD_GET_ADAPTER_LUID_FUNC *WireGuardGetAdapterLUID;
static WIREGUARD_GET_RUNNING_DRIVER_VERSION_FUNC *WireGuardGetRunningDriverVersion;
static WIREGUARD_DELETE_DRIVER_FUNC *WireGuardDeleteDriver;
static WIREGUARD_SET_LOGGER_FUNC *WireGuardSetLogger;
static WIREGUARD_SET_ADAPTER_LOGGING_FUNC *WireGuardSetAdapterLogging;
static WIREGUARD_GET_ADAPTER_STATE_FUNC *WireGuardGetAdapterState;
static WIREGUARD_SET_ADAPTER_STATE_FUNC *WireGuardSetAdapterState;
static WIREGUARD_GET_CONFIGURATION_FUNC *WireGuardGetConfiguration;
static WIREGUARD_SET_CONFIGURATION_FUNC *WireGuardSetConfiguration;
#if 0
static int InitializeWMI()
{
IWbemLocator* p_instance_ = nullptr;
IWbemServices* p_service_ = nullptr;
IEnumWbemClassObject* p_enum_ = nullptr;
IWbemClassObject *p_obj_ = nullptr;
IWbemClassObject *p_config = nullptr;
// Step 1: Initialize COM.
HRESULT hres = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (FAILED(hres)) {
SPDLOG_ERROR("CoInitializeEx Error: {0}", GetLastError());
return false;
}
// Step 3: Obtain the initial locator to WMI
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID*)&p_instance_);
if (FAILED(hres)) {
SPDLOG_ERROR("CoCreateInstance Error: {0}", GetLastError());
return false;
}
// Step 4: Connect to the local root\cimv2 namespace and obtain pointer pSvc to make IWbemServices calls.
hres = p_instance_->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"),
NULL,
NULL,
0,
NULL,
0,
0,
&p_service_
);
//ASSERT_THROW(SUCCEEDED(hres), "ConnectServer failed");
if (FAILED(hres)) {
#ifdef _DEBUG
cout << "ConnectServer failed: " << hres << endl;
#endif
return false;
}
// Step 5: Set security levels for the proxy
hres = CoSetProxyBlanket(
p_service_, // Indicates the proxy to set
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Server principal name
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // client identity
EOAC_NONE // proxy capabilities
);
//ASSERT_THROW(SUCCEEDED(hres), "CoSetProxyBlanket failed");
if (FAILED(hres)) {
#ifdef _DEBUG
cout << "CoSetProxyBlanket failed: " << hres << endl;
#endif
return false;
}
// 通过适配器名称来找到指定的适配器对象.
CComBSTR TheQuery = L"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE SettingID = \"";
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> conversion;
TheQuery += conversion.from_bytes(key_).c_str();
TheQuery += L"\"";
// const BSTR lang = L"WQL";
hres = p_service_->ExecQuery(
SysAllocString(L"WQL"),
// L"WQL",
TheQuery,
WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
NULL,
&p_enum_);
//ASSERT_THROW(SUCCEEDED(hres), "ExecQuery failed");
if (FAILED(hres)) {
#ifdef _DEBUG
cout << "ExecQuery failed: " << hres << endl;
#endif
return false;
}
// Get the adapter object.
ULONG num = 0;
hres = p_enum_->Next(WBEM_INFINITE, 1, &p_obj_, &num);
//ASSERT_THROW(SUCCEEDED(hres), "Next failed");
if (FAILED(hres)) {
#ifdef _DEBUG
cout << "Next failed: " << hres << endl;
#endif
return false;
}
//ASSERT_THROW(0 < num, "Next failed");
if (num < 1) {
#ifdef _DEBUG
cout << "Next failed num < 1" << endl;
#endif
return false;
}
VariantInit(&path_);
hres = p_obj_->Get(L"__PATH", 0, &path_, NULL, NULL);
//ASSERT_THROW(SUCCEEDED(hres), "Get path failed");
if (FAILED(hres)) {
#ifdef _DEBUG
cout << "Get failed: " << hres << endl;
#endif
return false;
}
hres = p_service_->GetObject(_bstr_t(L"Win32_NetworkAdapterConfiguration"), 0, NULL, &p_config, NULL);
//ASSERT_THROW(SUCCEEDED(hres), "GetObject Win32_NetworkAdapterConfiguration failed");
if (FAILED(hres)) {
#ifdef _DEBUG
cout << "GetObject failed: " << hres << endl;
#endif
return false;
}
is_init_ = true;
return true;
}
#endif
static HMODULE InitializeWireGuardNT(void) {
HMODULE WireGuardDll = LoadLibraryExW(L"wireguard.dll",
nullptr,
LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!WireGuardDll) {
return nullptr;
}
#define X(Name) ((*(FARPROC *)&Name = GetProcAddress(WireGuardDll, #Name)) == nullptr)
if (X(WireGuardCreateAdapter) || X(WireGuardOpenAdapter) || X(WireGuardCloseAdapter) ||
X(WireGuardGetAdapterLUID) || X(WireGuardGetRunningDriverVersion) || X(WireGuardDeleteDriver) ||
X(WireGuardSetLogger) || X(WireGuardSetAdapterLogging) || X(WireGuardGetAdapterState) ||
X(WireGuardSetAdapterState) || X(WireGuardGetConfiguration) || X(WireGuardSetConfiguration))
#undef X
{
DWORD LastError = GetLastError();
FreeLibrary(WireGuardDll);
SetLastError(LastError);
return nullptr;
}
return WireGuardDll;
}
//
//static void CALLBACK ConsoleLogger(_In_ WIREGUARD_LOGGER_LEVEL Level,
// _In_ DWORD64 Timestamp,
// _In_z_ const WCHAR *LogLine) {
// SYSTEMTIME SystemTime;
// GetSystemTime(&SystemTime);
// //FileTimeToSystemTime((FILETIME *)&Timestamp, &SystemTime);
// WCHAR LevelMarker;
// switch (Level) {
// case WIREGUARD_LOG_INFO:
// LevelMarker = L'+';
// break;
// case WIREGUARD_LOG_WARN:
// LevelMarker = L'-';
// break;
// case WIREGUARD_LOG_ERR:
// LevelMarker = L'!';
// break;
// default:
// return;
// }
// fwprintf(stderr,
// L"%04u-%02u-%02u %02u:%02u:%02u.%04u [%c] %s\n",
// SystemTime.wYear,
// SystemTime.wMonth,
// SystemTime.wDay,
// SystemTime.wHour,
// SystemTime.wMinute,
// SystemTime.wSecond,
// SystemTime.wMilliseconds,
// LevelMarker,
// LogLine);
//}
static DWORD64 Now() {
return 0;
}
#if 0
static DWORD LogError(_In_z_ const WCHAR *Prefix, _In_ DWORD Error) {
WCHAR tMsg[MAX_PATH];
StringCbPrintfW(tMsg, MAX_PATH, L"Error: %d", Error);
ConsoleLogger(WIREGUARD_LOG_ERR, Now(), tMsg);
return Error;
}
static DWORD LogLastError(_In_z_ const WCHAR *Prefix) {
DWORD LastError = GetLastError();
LogError(Prefix, LastError);
SetLastError(LastError);
return LastError;
}
static void Log(_In_ WIREGUARD_LOGGER_LEVEL Level, _In_z_ const WCHAR *Format, ...) {
WCHAR LogLine[0x200];
va_list args;
va_start(args, Format);
_vsnwprintf_s(LogLine, _countof(LogLine), _TRUNCATE, Format, args);
va_end(args);
ConsoleLogger(Level, Now(), LogLine);
}
#endif
_Must_inspect_result_ _Return_type_success_(return != FALSE) static BOOL
GenerateKeyPair(_Out_writes_bytes_all_(WIREGUARD_KEY_LENGTH) BYTE PublicKey[WIREGUARD_KEY_LENGTH],
_Out_writes_bytes_all_(WIREGUARD_KEY_LENGTH) BYTE PrivateKey[WIREGUARD_KEY_LENGTH]) {
BCRYPT_ALG_HANDLE Algorithm;
BCRYPT_KEY_HANDLE Key;
NTSTATUS Status;
struct {
BCRYPT_ECCKEY_BLOB Header;
BYTE Public[32];
BYTE Unused[32];
BYTE Private[32];
} ExportedKey;
ULONG Bytes;
Status = BCryptOpenAlgorithmProvider(&Algorithm, BCRYPT_ECDH_ALGORITHM, nullptr, 0);
if (!NT_SUCCESS(Status)) {
goto out;
}
Status = BCryptSetProperty(Algorithm,
BCRYPT_ECC_CURVE_NAME,
(PUCHAR)BCRYPT_ECC_CURVE_25519,
sizeof(BCRYPT_ECC_CURVE_25519),
0);
if (!NT_SUCCESS(Status)) {
goto cleanupProvider;
}
Status = BCryptGenerateKeyPair(Algorithm, &Key, 255, 0);
if (!NT_SUCCESS(Status)) {
goto cleanupProvider;
}
Status = BCryptFinalizeKeyPair(Key, 0);
if (!NT_SUCCESS(Status)) {
goto cleanupKey;
}
Status = BCryptExportKey(Key,
nullptr,
BCRYPT_ECCPRIVATE_BLOB,
(PUCHAR)&ExportedKey,
sizeof(ExportedKey),
&Bytes,
0);
if (!NT_SUCCESS(Status)) {
goto cleanupKey;
}
memcpy(PublicKey, ExportedKey.Public, WIREGUARD_KEY_LENGTH);
memcpy(PrivateKey, ExportedKey.Private, WIREGUARD_KEY_LENGTH);
SecureZeroMemory(&ExportedKey, sizeof(ExportedKey));
cleanupKey:
BCryptDestroyKey(Key);
cleanupProvider:
BCryptCloseAlgorithmProvider(Algorithm, 0);
out:
SetLastError(RtlNtStatusToDosError(Status));
return NT_SUCCESS(Status);
}
static HANDLE QuitEvent;
//static BOOL WINAPI CtrlHandler(_In_ DWORD CtrlType) {
// switch (CtrlType) {
// case CTRL_C_EVENT:
// case CTRL_BREAK_EVENT:
// case CTRL_CLOSE_EVENT:
// case CTRL_LOGOFF_EVENT:
// case CTRL_SHUTDOWN_EVENT:
// SPDLOG_INFO("Cleaning up and shutting down");
// SetEvent(QuitEvent);
// return TRUE;
// }
// return FALSE;
//}
static BOOL GetEndPoint(const TCHAR *Input, _Out_ SOCKADDR_INET *ResolvedDemoServer) {
SOCKET Socket = INVALID_SOCKET;
TCHAR name[MAX_PATH];
ADDRINFOA Hints = {};
ADDRINFOA *Resolution;
StringCbCopy(name, MAX_PATH, Input);
TCHAR *Colon1 = strchr(name, ':');
*Colon1 = '\0';
Hints.ai_family = AF_UNSPEC;
Hints.ai_socktype = SOCK_STREAM;
Hints.ai_protocol = IPPROTO_TCP;
if (GetAddrInfo(name, Colon1 + 1, &Hints, &Resolution)) {
return FALSE;
}
for (const ADDRINFOA *Candidate = Resolution; Candidate; Candidate = Candidate->ai_next) {
UINT16 port;
if (Candidate->ai_family != AF_INET && Candidate->ai_family != AF_INET6) {
continue;
}
memcpy(ResolvedDemoServer, Candidate->ai_addr, Candidate->ai_addrlen);
port = static_cast<UINT16>(strtoul(Colon1 + 1, nullptr, 10));
if (ResolvedDemoServer->si_family == AF_INET) {
ResolvedDemoServer->Ipv4.sin_port = htons(port);
} else if (ResolvedDemoServer->si_family == AF_INET6) {
ResolvedDemoServer->Ipv6.sin6_port = htons(port);
}
closesocket(Socket);
FreeAddrInfo(Resolution);
return TRUE;
}
closesocket(Socket);
FreeAddrInfo(Resolution);
return FALSE;
}
_Return_type_success_(return != FALSE) static BOOL TalkToDemoServer(_In_reads_bytes_(InputLength) const CHAR *Input,
_In_ DWORD InputLength,
_Out_writes_bytes_(*OutputLength) CHAR *Output,
_Inout_ DWORD *OutputLength,
_Out_ SOCKADDR_INET *ResolvedDemoServer) {
SOCKET Socket = INVALID_SOCKET;
ADDRINFOW Hints = {};
ADDRINFOW *Resolution;
BOOL Ret = FALSE;
Hints.ai_family = AF_UNSPEC;
Hints.ai_socktype = SOCK_STREAM;
Hints.ai_protocol = IPPROTO_TCP;
if (GetAddrInfoW(L"demo.wireguard.com", L"42912", &Hints, &Resolution)) {
return FALSE;
}
for (ADDRINFOW *Candidate = Resolution; Candidate; Candidate = Candidate->ai_next) {
if (Candidate->ai_family != AF_INET && Candidate->ai_family != AF_INET6) {
continue;
}
Socket = socket(Candidate->ai_family, Candidate->ai_socktype, Candidate->ai_protocol);
if (Socket == INVALID_SOCKET) {
goto cleanupResolution;
}
if (connect(Socket, Candidate->ai_addr, (int)Candidate->ai_addrlen) == SOCKET_ERROR) {
closesocket(Socket);
Socket = INVALID_SOCKET;
}
memcpy(ResolvedDemoServer, Candidate->ai_addr, Candidate->ai_addrlen);
break;
}
if (Socket == INVALID_SOCKET) {
goto cleanupResolution;
}
if (send(Socket, Input, InputLength, 0) == SOCKET_ERROR) {
goto cleanupSocket;
}
if ((*OutputLength = recv(Socket, Output, *OutputLength, 0)) == SOCKET_ERROR) {
goto cleanupSocket;
}
Ret = TRUE;
cleanupSocket:
closesocket(Socket);
cleanupResolution:
FreeAddrInfoW(Resolution);
return Ret;
}
typedef struct {
WIREGUARD_INTERFACE Interface;
WIREGUARD_PEER RemoteServer;
WIREGUARD_ALLOWED_IP AllV4;
WIREGUARD_ALLOWED_IP AllV4_2;
} WG_CONFIG_INFO;
int main_wireguard_getinfo() {
DWORD Bytes;
WG_CONFIG_INFO Config {};
HMODULE WireGuard = InitializeWireGuardNT();
if (!WireGuard) {
SPDLOG_ERROR("Failed to initialize WireGuardNT: {0}", GetLastError());
return -1;
}
/* CryptStringToBinary(TEXT("WGAlqvys3O83VmWug6Z8NzUrxGr/PNHSeOVFnKLSe2k="),
0,
CRYPT_STRING_BASE64,
Config.Interface.PublicKey,
&Bytes,
nullptr,
nullptr);*/
WIREGUARD_ADAPTER_HANDLE Adapter = WireGuardOpenAdapter(L"admin");
if (!Adapter) {
SPDLOG_ERROR("Failed to create adapter: {0}", GetLastError());
return -1;
}
Bytes = sizeof(Config);
if (!WireGuardGetConfiguration(Adapter, &Config.Interface, &Bytes)) {
SPDLOG_ERROR("Failed to get configuration: {0}", GetLastError());
//WireGuardCloseAdapter(Adapter);
return -3;
}
//WireGuardCloseAdapter(Adapter);
return 0;
}
int main_wireguard(bool isDelete) {
WG_CONFIG_INFO Config {};
DWORD LastError;
WSADATA WsaData;
MIB_IPINTERFACE_ROW IpInterface = {};
DWORD Bytes;
MIB_UNICASTIPADDRESS_ROW AddressRow;
GUID ExampleGuid = {
0xdeadc001,
0xbeef,
0xbabe,
{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}
};
WIREGUARD_ADAPTER_HANDLE Adapter;
DWORD Version;
if (WSAStartup(MAKEWORD(2, 2), &WsaData)) {
SPDLOG_ERROR("Failed to initialize Winsock: {0}", GetLastError());
return -1;
}
HMODULE WireGuard = InitializeWireGuardNT();
if (!WireGuard) {
SPDLOG_ERROR("Failed to initialize WireGuardNT: {0}", GetLastError());
return -2;
}
SPDLOG_INFO("WireGuardNT library loaded");
// 配置本地隧道接口
Config.Interface.Flags = WIREGUARD_INTERFACE_HAS_PRIVATE_KEY;
Config.Interface.PeersCount = 1;
CryptStringToBinary(TEXT("WGAlqvys3O83VmWug6Z8NzUrxGr/PNHSeOVFnKLSe2k="),
0,
CRYPT_STRING_BASE64,
Config.Interface.PrivateKey,
&Bytes,
nullptr,
nullptr);
// 配置远程隧道接口
Config.RemoteServer.Flags = static_cast<WIREGUARD_PEER_FLAG>(
WIREGUARD_PEER_HAS_PUBLIC_KEY | WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE | WIREGUARD_PEER_HAS_ENDPOINT);
Config.RemoteServer.AllowedIPsCount = 2;
Config.RemoteServer.PersistentKeepalive = 30;
CryptStringToBinary(TEXT("q3ep8hN2v3VpHbcru+rTmvyBt13iH0DkEsVAyT2LpVo="),
0,
CRYPT_STRING_BASE64,
Config.RemoteServer.PublicKey,
&Bytes,
nullptr,
nullptr);
if (!GetEndPoint(TEXT("efc.xajhuang.com:10000"), &Config.RemoteServer.Endpoint)) {
SPDLOG_ERROR("Failed to talk to demo server: {0}", GetLastError());
goto cleanupWireGuard;
}
Config.AllV4.AddressFamily = AF_INET;
Config.AllV4.Cidr = 24;
InetPtonA(AF_INET, TEXT("10.10.10.0"), &Config.AllV4.Address.V4.S_un.S_addr);
Config.AllV4_2.AddressFamily = AF_INET;
Config.AllV4_2.Cidr = 24;
InetPtonA(AF_INET, TEXT("192.168.100.0"), &Config.AllV4.Address.V4.S_un.S_addr);
InitializeUnicastIpAddressEntry(&AddressRow);
AddressRow.Address.Ipv4.sin_family = AF_INET;
AddressRow.OnLinkPrefixLength = 24; /* This is a /24 network */
AddressRow.DadState = IpDadStatePreferred;
InetPtonA(AF_INET, TEXT("10.10.10.1"), &AddressRow.Address.Ipv4.sin_addr);
#if 0
Log(WIREGUARD_LOG_INFO, L"Generating keypair");
if (!GenerateKeyPair(PublicKey, Config.Interface.PrivateKey)) {
LastError = LogError(L"Failed to generate keypair", GetLastError());
goto cleanupWireGuard;
}
Bytes = sizeof(PublicKeyString);
CryptBinaryToStringA(PublicKey,
sizeof(PublicKey),
CRYPT_STRING_BASE64 | CRYPT_STRING_NOCR,
PublicKeyString,
&Bytes);
Log(WIREGUARD_LOG_INFO, L"Talking to demo server");
Bytes = sizeof(ServerResponse) - 1;
if (!TalkToDemoServer(PublicKeyString,
(DWORD)strlen(PublicKeyString),
ServerResponse,
&Bytes,
&Config.RemoteServer.Endpoint)) {
LastError = LogError(L"Failed to talk to demo server", GetLastError());
goto cleanupWireGuard;
}
Colon1 = strchr(ServerResponse, ':');
Colon2 = Colon1 ? strchr(Colon1 + 1, ':') : nullptr;
Colon3 = Colon2 ? strchr(Colon2 + 1, ':') : nullptr;
if (!Colon1 || !Colon2 || !Colon3) {
LastError = LogError(L"Failed to parse demo server response", ERROR_UNDEFINED_CHARACTER);
goto cleanupWireGuard;
}
if (Bytes && ServerResponse[--Bytes] == '\n') {
ServerResponse[Bytes] = '\0';
}
*Colon1 = *Colon2 = *Colon3 = '\0';
Bytes = sizeof(Config.RemoteServer.PublicKey);
if (strcmp(ServerResponse, "OK") || != 1 ||
!CryptStringToBinaryA(Colon1 + 1,
0,
CRYPT_STRING_BASE64,
Config.RemoteServer.PublicKey,
&Bytes,
nullptr,
nullptr)) {
LastError = LogError(L"Failed to parse demo server response", ERROR_UNDEFINED_CHARACTER);
goto cleanupWireGuard;
}
if (Config.RemoteServer.Endpoint.si_family == AF_INET) {
Config.RemoteServer.Endpoint.Ipv4.sin_port = htons((u_short)atoi(Colon2 + 1));
} else if (Config.RemoteServer.Endpoint.si_family == AF_INET6) {
Config.RemoteServer.Endpoint.Ipv6.sin6_port = htons((u_short)atoi(Colon2 + 1));
}
#endif
QuitEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr);
if (!QuitEvent) {
SPDLOG_ERROR("Failed to create event:{0}", GetLastError());
goto cleanupWireGuard;
}
//if (!SetConsoleCtrlHandler(CtrlHandler, TRUE)) {
// SPDLOG_ERROR("Failed to set console handler: {0}", GetLastError());
// goto cleanupQuit;
//}
Adapter = WireGuardOpenAdapter(L"Demo");
if (isDelete) {
SPDLOG_INFO("Remove adapter: {0}", "Demo");
WireGuardCloseAdapter(Adapter);
return 0;
}
if (!Adapter) {
Adapter = WireGuardCreateAdapter(L"Demo", L"Example", &ExampleGuid);
if (!Adapter) {
SPDLOG_ERROR("Failed to create adapter: {0}", LastError);
goto cleanupQuit;
}
}
if (!WireGuardSetAdapterLogging(Adapter, WIREGUARD_ADAPTER_LOG_ON)) {
SPDLOG_ERROR("Failed to enable adapter logging: {0}", GetLastError());
}
Version = WireGuardGetRunningDriverVersion();
SPDLOG_INFO("WireGuardNT v{0}.{1} loaded", (Version >> 16) & 0xff, (Version >> 0) & 0xff);
WireGuardGetAdapterLUID(Adapter, &AddressRow.InterfaceLuid);
SetInterfaceIpAddress("Demo", "10.10.10.1", "255.255.255.0");
#if 0
InitializeIpForwardEntry(&DefaultRoute);
DefaultRoute.InterfaceLuid = AddressRow.InterfaceLuid;
DefaultRoute.DestinationPrefix.Prefix.si_family = AF_INET;
DefaultRoute.NextHop.si_family = AF_INET;
DefaultRoute.Metric = 0;
LastError = CreateIpForwardEntry2(&DefaultRoute);
if (LastError != ERROR_SUCCESS && LastError != ERROR_OBJECT_ALREADY_EXISTS) {
SPDLOG_ERROR("Failed to set default route: {0}", LastError);
goto cleanupAdapter;
}
LastError = CreateUnicastIpAddressEntry(&AddressRow);
if (LastError != ERROR_SUCCESS && LastError != ERROR_OBJECT_ALREADY_EXISTS) {
SPDLOG_ERROR("Failed to set IP address: {0}", LastError);
goto cleanupAdapter;
}
#endif
#if 1
InitializeIpInterfaceEntry(&IpInterface);
IpInterface.InterfaceLuid = AddressRow.InterfaceLuid;
IpInterface.Family = AF_INET;
LastError = GetIpInterfaceEntry(&IpInterface);
if (LastError != ERROR_SUCCESS) {
SPDLOG_ERROR("Failed to get IP interface: {0}", LastError);
goto cleanupAdapter;
}
/*if ((LastError = AddIpAddress(IpInterface.InterfaceIndex)) != 0) {
SPDLOG_ERROR("Set interface IP Error: {0}", LastError);
goto cleanupAdapter;
}*/
IpInterface.UseAutomaticMetric = FALSE;
IpInterface.Metric = 0;
IpInterface.NlMtu = 1420;
IpInterface.SitePrefixLength = 0;
LastError = SetIpInterfaceEntry(&IpInterface);
if (LastError != ERROR_SUCCESS) {
SPDLOG_ERROR("Failed to set metric and MTU: {0}", LastError);
goto cleanupAdapter;
}
#endif
SPDLOG_INFO("Setting configuration and adapter up");
if (!WireGuardSetConfiguration(Adapter, &Config.Interface, sizeof(Config)) ||
!WireGuardSetAdapterState(Adapter, WIREGUARD_ADAPTER_STATE_UP)) {
SPDLOG_ERROR("Failed to set configuration and adapter up: {0}", GetLastError());
goto cleanupAdapter;
}
do {
Bytes = sizeof(Config);
if (!WireGuardGetConfiguration(Adapter, &Config.Interface, &Bytes) || !Config.Interface.PeersCount) {
SPDLOG_ERROR("Failed to get configuration: {0}", GetLastError());
goto cleanupAdapter;
}
DWORD64 Timestamp = Now();
SYSTEMTIME SystemTime;
FileTimeToSystemTime((FILETIME *)&Timestamp, &SystemTime);
fwprintf(stderr,
L"%04u-%02u-%02u %02u:%02u:%02u.%04u [#] RX: %llu, TX: %llu\r",
SystemTime.wYear,
SystemTime.wMonth,
SystemTime.wDay,
SystemTime.wHour,
SystemTime.wMinute,
SystemTime.wSecond,
SystemTime.wMilliseconds,
Config.RemoteServer.RxBytes,
Config.RemoteServer.TxBytes);
} while (WaitForSingleObject(QuitEvent, 1000) == WAIT_TIMEOUT);
cleanupAdapter:
WireGuardCloseAdapter(Adapter);
cleanupQuit:
//SetConsoleCtrlHandler(CtrlHandler, FALSE);
CloseHandle(QuitEvent);
cleanupWireGuard:
FreeLibrary(WireGuard);
cleanupWinsock:
WSACleanup();
return 0;
}

View File

@ -3,4 +3,7 @@ int ShowRouteTable();
int NetShare();
int GetInterface();
void CryptoExample();
int SetRouteTable();
int SetRouteTable();
int main_wireguard(bool isDelete);
int main_wireguard_getinfo();
int net_nat();

View File

@ -0,0 +1,308 @@
/* SPDX-License-Identifier: GPL-2.0 OR MIT
*
* Copyright (C) 2018-2021 WireGuard LLC. All Rights Reserved.
*/
#pragma once
#include <winsock2.h>
#include <windows.h>
#include <ipexport.h>
#include <ifdef.h>
#include <ws2ipdef.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef ALIGNED
# if defined(_MSC_VER)
# define ALIGNED(n) __declspec(align(n))
# elif defined(__GNUC__)
# define ALIGNED(n) __attribute__((aligned(n)))
# else
# error "Unable to define ALIGNED"
# endif
#endif
/* MinGW is missing this one, unfortunately. */
#ifndef _Post_maybenull_
# define _Post_maybenull_
#endif
#pragma warning(push)
#pragma warning(disable : 4324) /* structure was padded due to alignment specifier */
/**
* A handle representing WireGuard adapter
*/
typedef struct _WIREGUARD_ADAPTER *WIREGUARD_ADAPTER_HANDLE;
/**
* Creates a new WireGuard adapter.
*
* @param Name The requested name of the adapter. Zero-terminated string of up to MAX_ADAPTER_NAME-1
* characters.
*
* @param TunnelType Name of the adapter tunnel type. Zero-terminated string of up to MAX_ADAPTER_NAME-1
* characters.
*
* @param RequestedGUID The GUID of the created network adapter, which then influences NLA generation deterministically.
* If it is set to NULL, the GUID is chosen by the system at random, and hence a new NLA entry is
* created for each new adapter. It is called "requested" GUID because the API it uses is
* completely undocumented, and so there could be minor interesting complications with its usage.
*
* @return If the function succeeds, the return value is the adapter handle. Must be released with
* WireGuardCloseAdapter. If the function fails, the return value is NULL. To get extended error information, call
* GetLastError.
*/
typedef _Must_inspect_result_
_Return_type_success_(return != NULL)
_Post_maybenull_
WIREGUARD_ADAPTER_HANDLE(WINAPI WIREGUARD_CREATE_ADAPTER_FUNC)
(_In_z_ LPCWSTR Name, _In_z_ LPCWSTR TunnelType, _In_opt_ const GUID *RequestedGUID);
/**
* Opens an existing WireGuard adapter.
*
* @param Name The requested name of the adapter. Zero-terminated string of up to MAX_ADAPTER_NAME-1
* characters.
*
* @return If the function succeeds, the return value is the adapter handle. Must be released with
* WireGuardCloseAdapter. If the function fails, the return value is NULL. To get extended error information, call
* GetLastError.
*/
typedef _Must_inspect_result_
_Return_type_success_(return != NULL)
_Post_maybenull_
WIREGUARD_ADAPTER_HANDLE(WINAPI WIREGUARD_OPEN_ADAPTER_FUNC)(_In_z_ LPCWSTR Name);
/**
* Releases WireGuard adapter resources and, if adapter was created with WireGuardCreateAdapter, removes adapter.
*
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter.
*/
typedef VOID(WINAPI WIREGUARD_CLOSE_ADAPTER_FUNC)(_In_opt_ WIREGUARD_ADAPTER_HANDLE Adapter);
/**
* Deletes the WireGuard driver if there are no more adapters in use.
*
* @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
* get extended error information, call GetLastError.
*/
typedef _Return_type_success_(return != FALSE)
BOOL(WINAPI WIREGUARD_DELETE_DRIVER_FUNC)(VOID);
/**
* Returns the LUID of the adapter.
*
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter
*
* @param Luid Pointer to LUID to receive adapter LUID.
*/
typedef VOID(WINAPI WIREGUARD_GET_ADAPTER_LUID_FUNC)(_In_ WIREGUARD_ADAPTER_HANDLE Adapter, _Out_ NET_LUID *Luid);
/**
* Determines the version of the WireGuard driver currently loaded.
*
* @return If the function succeeds, the return value is the version number. If the function fails, the return value is
* zero. To get extended error information, call GetLastError. Possible errors include the following:
* ERROR_FILE_NOT_FOUND WireGuard not loaded
*/
typedef _Return_type_success_(return != 0)
DWORD(WINAPI WIREGUARD_GET_RUNNING_DRIVER_VERSION_FUNC)(VOID);
/**
* Determines the level of logging, passed to WIREGUARD_LOGGER_CALLBACK.
*/
typedef enum
{
WIREGUARD_LOG_INFO, /**< Informational */
WIREGUARD_LOG_WARN, /**< Warning */
WIREGUARD_LOG_ERR /**< Error */
} WIREGUARD_LOGGER_LEVEL;
/**
* Called by internal logger to report diagnostic messages
*
* @param Level Message level.
*
* @param Timestamp Message timestamp in in 100ns intervals since 1601-01-01 UTC.
*
* @param Message Message text.
*/
typedef VOID(CALLBACK *WIREGUARD_LOGGER_CALLBACK)(
_In_ WIREGUARD_LOGGER_LEVEL Level,
_In_ DWORD64 Timestamp,
_In_z_ LPCWSTR Message);
/**
* Sets logger callback function.
*
* @param NewLogger Pointer to callback function to use as a new global logger. NewLogger may be called from various
* threads concurrently. Should the logging require serialization, you must handle serialization in
* NewLogger. Set to NULL to disable.
*/
typedef VOID(WINAPI WIREGUARD_SET_LOGGER_FUNC)(_In_ WIREGUARD_LOGGER_CALLBACK NewLogger);
/**
* Whether and how logs from the driver are collected for the callback function.
*/
typedef enum
{
WIREGUARD_ADAPTER_LOG_OFF, /**< No logs are generated from the driver. */
WIREGUARD_ADAPTER_LOG_ON, /**< Logs are generated from the driver. */
WIREGUARD_ADAPTER_LOG_ON_WITH_PREFIX /**< Logs are generated from the driver, index-prefixed. */
} WIREGUARD_ADAPTER_LOG_STATE;
/**
* Sets whether and how the adapter logs to the logger previously set up with WireGuardSetLogger.
*
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter
*
* @param LogState Adapter logging state.
*
* @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
* get extended error information, call GetLastError.
*/
typedef _Return_type_success_(return != FALSE)
BOOL(WINAPI WIREGUARD_SET_ADAPTER_LOGGING_FUNC)
(_In_ WIREGUARD_ADAPTER_HANDLE Adapter, _In_ WIREGUARD_ADAPTER_LOG_STATE LogState);
/**
* Determines the state of the adapter.
*/
typedef enum
{
WIREGUARD_ADAPTER_STATE_DOWN, /**< Down */
WIREGUARD_ADAPTER_STATE_UP, /**< Up */
} WIREGUARD_ADAPTER_STATE;
/**
* Sets the adapter state of the WireGuard adapter. Note: sockets are owned by the process that sets the state to up.
*
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter
*
* @param State Adapter state.
*
* @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
* get extended error information, call GetLastError.
*/
typedef _Return_type_success_(return != FALSE)
BOOL(WINAPI WIREGUARD_SET_ADAPTER_STATE_FUNC)
(_In_ WIREGUARD_ADAPTER_HANDLE Adapter, _In_ WIREGUARD_ADAPTER_STATE State);
/**
* Gets the adapter state of the WireGuard adapter.
*
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter
*
* @param State Pointer to adapter state.
*
* @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
* get extended error information, call GetLastError.
*/
typedef _Must_inspect_result_
_Return_type_success_(return != FALSE)
BOOL(WINAPI WIREGUARD_GET_ADAPTER_STATE_FUNC)
(_In_ WIREGUARD_ADAPTER_HANDLE Adapter, _Out_ WIREGUARD_ADAPTER_STATE *State);
#define WIREGUARD_KEY_LENGTH 32
typedef struct _WIREGUARD_ALLOWED_IP WIREGUARD_ALLOWED_IP;
struct ALIGNED(8) _WIREGUARD_ALLOWED_IP
{
union
{
IN_ADDR V4;
IN6_ADDR V6;
} Address; /**< IP address */
ADDRESS_FAMILY AddressFamily; /**< Address family, either AF_INET or AF_INET6 */
BYTE Cidr; /**< CIDR of allowed IPs */
};
typedef enum
{
WIREGUARD_PEER_HAS_PUBLIC_KEY = 1 << 0, /**< The PublicKey field is set */
WIREGUARD_PEER_HAS_PRESHARED_KEY = 1 << 1, /**< The PresharedKey field is set */
WIREGUARD_PEER_HAS_PERSISTENT_KEEPALIVE = 1 << 2, /**< The PersistentKeepAlive field is set */
WIREGUARD_PEER_HAS_ENDPOINT = 1 << 3, /**< The Endpoint field is set */
WIREGUARD_PEER_REPLACE_ALLOWED_IPS = 1 << 5, /**< Remove all allowed IPs before adding new ones */
WIREGUARD_PEER_REMOVE = 1 << 6, /**< Remove specified peer */
WIREGUARD_PEER_UPDATE = 1 << 7 /**< Do not add a new peer */
} WIREGUARD_PEER_FLAG;
typedef struct _WIREGUARD_PEER WIREGUARD_PEER;
struct ALIGNED(8) _WIREGUARD_PEER
{
WIREGUARD_PEER_FLAG Flags; /**< Bitwise combination of flags */
DWORD Reserved; /**< Reserved; must be zero */
BYTE PublicKey[WIREGUARD_KEY_LENGTH]; /**< Public key, the peer's primary identifier */
BYTE PresharedKey[WIREGUARD_KEY_LENGTH]; /**< Preshared key for additional layer of post-quantum resistance */
WORD PersistentKeepalive; /**< Seconds interval, or 0 to disable */
SOCKADDR_INET Endpoint; /**< Endpoint, with IP address and UDP port number*/
DWORD64 TxBytes; /**< Number of bytes transmitted */
DWORD64 RxBytes; /**< Number of bytes received */
DWORD64 LastHandshake; /**< Time of the last handshake, in 100ns intervals since 1601-01-01 UTC */
DWORD AllowedIPsCount; /**< Number of allowed IP structs following this struct */
};
typedef enum
{
WIREGUARD_INTERFACE_HAS_PUBLIC_KEY = (1 << 0), /**< The PublicKey field is set */
WIREGUARD_INTERFACE_HAS_PRIVATE_KEY = (1 << 1), /**< The PrivateKey field is set */
WIREGUARD_INTERFACE_HAS_LISTEN_PORT = (1 << 2), /**< The ListenPort field is set */
WIREGUARD_INTERFACE_REPLACE_PEERS = (1 << 3) /**< Remove all peers before adding new ones */
} WIREGUARD_INTERFACE_FLAG;
typedef struct _WIREGUARD_INTERFACE WIREGUARD_INTERFACE;
struct ALIGNED(8) _WIREGUARD_INTERFACE
{
WIREGUARD_INTERFACE_FLAG Flags; /**< Bitwise combination of flags */
WORD ListenPort; /**< Port for UDP listen socket, or 0 to choose randomly */
BYTE PrivateKey[WIREGUARD_KEY_LENGTH]; /**< Private key of interface */
BYTE PublicKey[WIREGUARD_KEY_LENGTH]; /**< Corresponding public key of private key */
DWORD PeersCount; /**< Number of peer structs following this struct */
};
/**
* Sets the configuration of the WireGuard adapter.
*
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter
*
* @param Config Configuration for the adapter.
*
* @param Bytes Number of bytes in Config allocation.
*
* @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
* get extended error information, call GetLastError.
*/
typedef _Return_type_success_(return != FALSE)
BOOL(WINAPI WIREGUARD_SET_CONFIGURATION_FUNC)
(_In_ WIREGUARD_ADAPTER_HANDLE Adapter, _In_reads_bytes_(Bytes) const WIREGUARD_INTERFACE *Config, _In_ DWORD Bytes);
/**
* Gets the configuration of the WireGuard adapter.
*
* @param Adapter Adapter handle obtained with WireGuardCreateAdapter or WireGuardOpenAdapter
*
* @param Config Configuration for the adapter.
*
* @param Bytes Pointer to number of bytes in Config allocation.
*
* @return If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To
* get extended error information, call GetLastError, which if ERROR_MORE_DATA, Bytes is updated with the
* required size.
*/
typedef _Must_inspect_result_
_Return_type_success_(return != FALSE)
BOOL(WINAPI WIREGUARD_GET_CONFIGURATION_FUNC)
(_In_ WIREGUARD_ADAPTER_HANDLE Adapter,
_Out_writes_bytes_all_(*Bytes) WIREGUARD_INTERFACE *Config,
_Inout_ DWORD *Bytes);
#pragma warning(pop)
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,120 @@
// NetTunnelSvr.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <Windows.h>
#include <strsafe.h>
#include <tchar.h>
#define WG_TUNNEL_SVR_NAME TEXT("WireGuard_DLL_SVR")
typedef BOOL(WINAPI WIREGUARD_TUNNEL_SERVICE_FUNC)(_In_z_ LPCWSTR Name);
static WIREGUARD_TUNNEL_SERVICE_FUNC *WireGuardTunnelService;
static void LogToSystemEventLog(int wErrorType, int wCustumerCode, const TCHAR *szMsg) {
HANDLE hEventSource;
DWORD dwEventIdentifer;
switch (wErrorType) {
case EVENTLOG_SUCCESS:
case EVENTLOG_AUDIT_SUCCESS:
dwEventIdentifer = 0x00;
break;
case EVENTLOG_INFORMATION_TYPE:
dwEventIdentifer = 0x01;
break;
case EVENTLOG_WARNING_TYPE:
dwEventIdentifer = 0x02;
break;
case EVENTLOG_ERROR_TYPE:
case EVENTLOG_AUDIT_FAILURE:
dwEventIdentifer = 0x03;
break;
default:
dwEventIdentifer = 0;
break;
}
// 移位获得Sev前面给出的 wErrorType 为 EVENTLOG_ERROR_TYPE对应着下图 “级别” 一列显示“错误”图标
dwEventIdentifer <<= 30;
dwEventIdentifer |= static_cast<WORD>(wCustumerCode); // 前面自定义了Code对应着下图中 事件ID 20
hEventSource = RegisterEventSource(nullptr, WG_TUNNEL_SVR_NAME);
if (nullptr != hEventSource) {
LPCTSTR lpszStrings[2] = {
WG_TUNNEL_SVR_NAME,
szMsg}; //要写入日志的信息有两行,分别是 服务名和前面给出的szMsg对应着下图“以下是包含在事件中的信息”
ReportEvent(hEventSource, // event log handle
wErrorType, // event type
0, // event category
dwEventIdentifer, // event identifier
nullptr, // no security identifier
2, // size of lpszStrings array
0, // no binary data
lpszStrings, // array of strings
nullptr); // no binary data
DeregisterEventSource(hEventSource);
}
}
static HMODULE InitializeWireGuardNT(void) {
const HMODULE tunnel = LoadLibraryExW(L"tunnel.dll",
nullptr,
LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!tunnel) {
TCHAR tMsg[MAX_PATH * sizeof(TCHAR)];
StringCbPrintf(tMsg, MAX_PATH * sizeof(TCHAR), TEXT("LoadLibraryExW Error: %d\n"), GetLastError());
LogToSystemEventLog(EVENTLOG_ERROR_TYPE, 0x01, tMsg);
return nullptr;
}
#define X(Name) ((*(FARPROC *)&(Name) = GetProcAddress(tunnel, #Name)) == nullptr)
if (X(WireGuardTunnelService))
#undef X
{
const DWORD LastError = GetLastError();
FreeLibrary(tunnel);
SetLastError(LastError);
return nullptr;
}
return tunnel;
}
int _tmain(int wargc, _TCHAR *wargv[]) {
TCHAR tMsg[MAX_PATH] = {};
if (wargc == 3 && !wcscmp(wargv[1], L"/service")) {
BOOL ret;
const HMODULE hModule = InitializeWireGuardNT();
if (!hModule || !WireGuardTunnelService) {
StringCbPrintf(tMsg, MAX_PATH, TEXT("Init WireGuardTunnelService Service Error: %d\n"), GetLastError());
LogToSystemEventLog(EVENTLOG_ERROR_TYPE, 0x01, tMsg);
return -1;
}
ret = WireGuardTunnelService(wargv[2]);
if (ret) {
StringCbPrintf(tMsg, MAX_PATH, TEXT("Start WireGuardTunnelService Service Successed\n"));
LogToSystemEventLog(EVENTLOG_INFORMATION_TYPE, 0x00, tMsg);
} else {
StringCbPrintf(tMsg, MAX_PATH, TEXT("Start WireGuardTunnelService Service failed: %d\n"), GetLastError());
LogToSystemEventLog(EVENTLOG_ERROR_TYPE, 0x02, tMsg);
}
return ret;
}
return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

View File

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" 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>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{0a2eedaf-f4a8-41e0-a874-2f30d1eeb55e}</ProjectGuid>
<RootNamespace>NetTunnelSvr</RootNamespace>
<WindowsTargetPlatformVersion>10.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>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</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" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<PostBuildEvent>
<Command>copy /y $(TargetDir)*.exe $(SolutionDir)\NetTunnelApp\bin\$(ConfigurationName)\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="NetTunnelSvr.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="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<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="NetTunnelSvr.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View File

@ -35,15 +35,7 @@ TEST_MODULE_CLEANUP(ModuleCleanup) {
TEST_CLASS(TestNetTunnelSDK) {
public:
const int RET_OK = ERR_SUCCESS;
TEST_METHOD(TestFindWireguardExe) {
Assert::AreEqual(RET_OK, FindWireguardExe(nullptr, 0));
}
TEST_METHOD(TestSetWireguardPath) {
Assert::AreEqual(RET_OK, SetWireguardPath(TEXT("C:\\Program Files\\WireGuard\\wireguard.exe")));
}
TEST_METHOD(TestRunPipeCmd) {
#if 0
TCHAR buf[1024];
@ -208,8 +200,12 @@ public:
Assert::IsNotNull(pCfg);
Assert::AreEqual(RET_OK, RemoteCtrlSvrCfgUserTunnel(2, TEXT("172.18.2.0/24")));
Assert::AreEqual(RET_OK, RemoteWireGuardControl(true));
Assert::AreEqual(RET_OK, LocalWireGuardControl(true, true));
Assert::AreEqual(RET_OK, RemoteWireGuardControl(false));
Assert::AreEqual(RET_OK, LocalWireGuardControl(false, false));
}
};
}

View File

@ -7,6 +7,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NetTunnelSDK", "NetTunnelSD
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetTunnelApp", "NetTunnelApp\NetTunnelApp.csproj", "{79995848-FD05-46F5-A7FE-46265E540E32}"
ProjectSection(ProjectDependencies) = postProject
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E} = {0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}
{1584BAD4-DBEC-43D2-BC06-08C23F02489A} = {1584BAD4-DBEC-43D2-BC06-08C23F02489A}
EndProjectSection
EndProject
@ -22,6 +23,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NetTunnelSDKTestApp", "NetT
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "InstallTunnelSDK", "InstallTunnelSDK\InstallTunnelSDK.vdproj", "{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NetTunnelSvr", "NetTunnelSvr\NetTunnelSvr.vcxproj", "{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug DLL|Any CPU = Debug DLL|Any CPU
@ -152,6 +155,30 @@ Global
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Release|Any CPU.ActiveCfg = Release
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Release|x64.ActiveCfg = Release
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Release|x86.ActiveCfg = Release
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Debug DLL|Any CPU.ActiveCfg = Debug|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Debug DLL|Any CPU.Build.0 = Debug|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Debug DLL|x64.ActiveCfg = Debug|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Debug DLL|x64.Build.0 = Debug|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Debug DLL|x86.ActiveCfg = Debug|Win32
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Debug DLL|x86.Build.0 = Debug|Win32
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Debug|Any CPU.ActiveCfg = Debug|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Debug|Any CPU.Build.0 = Debug|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Debug|x64.ActiveCfg = Debug|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Debug|x64.Build.0 = Debug|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Debug|x86.ActiveCfg = Debug|Win32
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Debug|x86.Build.0 = Debug|Win32
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Release DLL|Any CPU.ActiveCfg = Release|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Release DLL|Any CPU.Build.0 = Release|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Release DLL|x64.ActiveCfg = Release|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Release DLL|x64.Build.0 = Release|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Release DLL|x86.ActiveCfg = Release|Win32
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Release DLL|x86.Build.0 = Release|Win32
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Release|Any CPU.ActiveCfg = Release|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Release|Any CPU.Build.0 = Release|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Release|x64.ActiveCfg = Release|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Release|x64.Build.0 = Release|x64
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Release|x86.ActiveCfg = Release|Win32
{0A2EEDAF-F4A8-41E0-A874-2F30D1EEB55E}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE