diff --git a/Installer/Installer.vdproj b/Installer/Installer.vdproj
index bc9e283..57eebb7 100644
--- a/Installer/Installer.vdproj
+++ b/Installer/Installer.vdproj
@@ -76,12 +76,6 @@
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
- "OwnerKey" = "8:_DDDEC90D22B81D6B9D637B1C197520B4"
- "MsmSig" = "8:_UNDEFINED"
- }
- "Entry"
- {
- "MsmKey" = "8:_UNDEFINED"
"OwnerKey" = "8:_9C849F5EE1DB4634B3B8ABAEAD8840E3"
"MsmSig" = "8:_UNDEFINED"
}
@@ -91,6 +85,12 @@
"OwnerKey" = "8:_92E0C26999D59D33D0500624357FF7A1"
"MsmSig" = "8:_UNDEFINED"
}
+ "Entry"
+ {
+ "MsmKey" = "8:_UNDEFINED"
+ "OwnerKey" = "8:_DDDEC90D22B81D6B9D637B1C197520B4"
+ "MsmSig" = "8:_UNDEFINED"
+ }
}
"Configurations"
{
@@ -109,6 +109,27 @@
"PrivateKeyFile" = "8:"
"TimeStampServer" = "8:"
"InstallerBootstrapper" = "3:2"
+ "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
+ {
+ "Enabled" = "11:TRUE"
+ "PromptEnabled" = "11:TRUE"
+ "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 和 x64)"
+ "ProductCode" = "8:.NETFramework,Version=v4.7.2"
+ }
+ "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Visual.C++.14.0.x64"
+ {
+ "Name" = "8:Visual C++ \"14\" Runtime Libraries (x64)"
+ "ProductCode" = "8:Microsoft.Visual.C++.14.0.x64"
+ }
+ }
+ }
}
"Release"
{
@@ -125,6 +146,14 @@
"PrivateKeyFile" = "8:"
"TimeStampServer" = "8:"
"InstallerBootstrapper" = "3:2"
+ "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
+ {
+ "Enabled" = "11:TRUE"
+ "PromptEnabled" = "11:TRUE"
+ "PrerequisitesLocation" = "2:1"
+ "Url" = "8:"
+ "ComponentsUrl" = "8:"
+ }
}
}
"Deployable"
@@ -230,7 +259,7 @@
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
- "Exclude" = "11:FALSE"
+ "Exclude" = "11:TRUE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
diff --git a/NetTunnelSDK/NetTunnelSDK.aps b/NetTunnelSDK/NetTunnelSDK.aps
new file mode 100644
index 0000000..4041241
Binary files /dev/null and b/NetTunnelSDK/NetTunnelSDK.aps differ
diff --git a/NetTunnelSDK/NetTunnelSDK.rc b/NetTunnelSDK/NetTunnelSDK.rc
new file mode 100644
index 0000000..f035925
Binary files /dev/null and b/NetTunnelSDK/NetTunnelSDK.rc differ
diff --git a/NetTunnelSDK/NetTunnelSDK.vcxproj b/NetTunnelSDK/NetTunnelSDK.vcxproj
index c00594a..51422c8 100644
--- a/NetTunnelSDK/NetTunnelSDK.vcxproj
+++ b/NetTunnelSDK/NetTunnelSDK.vcxproj
@@ -152,11 +152,14 @@
+
+
+
@@ -174,6 +177,11 @@
+
+
+
+
+
diff --git a/NetTunnelSDK/NetTunnelSDK.vcxproj.filters b/NetTunnelSDK/NetTunnelSDK.vcxproj.filters
index ddc8895..6239222 100644
--- a/NetTunnelSDK/NetTunnelSDK.vcxproj.filters
+++ b/NetTunnelSDK/NetTunnelSDK.vcxproj.filters
@@ -13,6 +13,9 @@
{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+ {1111b68b-34f2-49fa-8116-de5ae65603b6}
+
@@ -36,6 +39,9 @@
头文件
+
+ 头文件
+
@@ -56,8 +62,23 @@
源文件
+
+ 源文件\crypto
+
+
+ 源文件\crypto
+
+
+ 资源文件
+
+
+
+
+
+ 资源文件
+
\ No newline at end of file
diff --git a/NetTunnelSDK/crypto.cpp b/NetTunnelSDK/crypto.cpp
new file mode 100644
index 0000000..1989e1c
--- /dev/null
+++ b/NetTunnelSDK/crypto.cpp
@@ -0,0 +1,9 @@
+#include "pch.h"
+
+#include "tunnel.h"
+#include "usrerr.h"
+#include "misc.h"
+
+#include
+#include
+#include
diff --git a/NetTunnelSDK/globalcfg.h b/NetTunnelSDK/globalcfg.h
index 6b0c041..1c5305e 100644
--- a/NetTunnelSDK/globalcfg.h
+++ b/NetTunnelSDK/globalcfg.h
@@ -22,6 +22,7 @@ typedef struct {
* @brief SDK 全局配置项
*/
typedef struct {
+ TCHAR systemDirectory[MAX_PATH]; ///< 操作系统目录
TCHAR workDirectory[MAX_PATH]; ///< SDK 当前工作目录
PROTO_CRYPTO_TYPE proCryptoType; ///< 协议加密类型
TCHAR proKeyBuf[256]; ///< 协议加密秘钥
diff --git a/NetTunnelSDK/hashdigest.cpp b/NetTunnelSDK/hashdigest.cpp
new file mode 100644
index 0000000..2ecd91e
--- /dev/null
+++ b/NetTunnelSDK/hashdigest.cpp
@@ -0,0 +1,159 @@
+#include "pch.h"
+#include "tunnel.h"
+#include "usrerr.h"
+#include "misc.h"
+
+#include
+#include
+#include
+
+#pragma comment(lib, "Bcrypt.lib")
+
+//#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
+#define NT_FAILED(s) (((NTSTATUS)(s)) < 0)
+//#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
+
+static const LPCWSTR g_BcryptHash[] = {
+ BCRYPT_MD2_ALGORITHM,
+ BCRYPT_MD4_ALGORITHM,
+ BCRYPT_MD5_ALGORITHM,
+ BCRYPT_SHA1_ALGORITHM,
+ BCRYPT_SHA256_ALGORITHM,
+ BCRYPT_SHA384_ALGORITHM,
+ BCRYPT_SHA512_ALGORITHM,
+};
+
+int CalcFileHash(const HASH_TYPE type, const TCHAR *pPath, TCHAR outHash[]) {
+ HANDLE hFile;
+ BYTE rgbFile[1024];
+ DWORD cbRead = 0;
+ BCRYPT_ALG_HANDLE hAlg = nullptr;
+ BCRYPT_HASH_HANDLE hHash = nullptr;
+ NTSTATUS status;
+ DWORD cbData = 0, cbHash = 0, cbHashObject = 0;
+ PBYTE pbHashObject;
+ PBYTE pbHash;
+
+ if (pPath == nullptr) {
+ SPDLOG_ERROR("Input pPath params error: {0}", pPath);
+ return -ERR_INPUT_PARAMS;
+ }
+
+ if (!PathFileExists(pPath)) {
+ SPDLOG_ERROR("File \'{0}\' not found.", pPath);
+ return -ERR_ITEM_UNEXISTS;
+ }
+
+ hFile = CreateFile(pPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ nullptr,
+ OPEN_EXISTING,
+ FILE_FLAG_SEQUENTIAL_SCAN,
+ nullptr);
+
+ if (INVALID_HANDLE_VALUE == hFile) {
+ SPDLOG_ERROR("Error opening file %s\nError: {0}", pPath, GetLastError());
+ return -ERR_OPEN_FILE;
+ }
+
+ //open an algorithm handle
+ if (NT_FAILED(status = BCryptOpenAlgorithmProvider(&hAlg, g_BcryptHash[type], nullptr, 0))) {
+ SPDLOG_ERROR(TEXT("Error {0} returned by BCryptOpenAlgorithmProvider"), status);
+ CloseHandle(hFile);
+ return -ERR_BCRYPT_OPEN;
+ }
+
+ //calculate the size of the buffer to hold the hash object
+ if (NT_FAILED(status = BCryptGetProperty(hAlg,
+ BCRYPT_OBJECT_LENGTH,
+ reinterpret_cast(&cbHashObject),
+ sizeof(DWORD),
+ &cbData,
+ 0))) {
+ SPDLOG_ERROR(TEXT("Error {0} returned by BCryptGetProperty"), status);
+ CloseHandle(hFile);
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ return -ERR_BCRYPT_GETPROPERTY;
+ }
+
+ //allocate the hash object on the heap
+ pbHashObject = static_cast(HeapAlloc(GetProcessHeap(), 0, cbHashObject));
+ if (nullptr == pbHashObject) {
+ SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), cbHashObject);
+ CloseHandle(hFile);
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ return -ERR_MALLOC_MEMORY;
+ }
+
+ //calculate the length of the hash
+ if (NT_FAILED(status = BCryptGetProperty(hAlg,
+ BCRYPT_HASH_LENGTH,
+ reinterpret_cast(&cbHash),
+ sizeof(DWORD),
+ &cbData,
+ 0))) {
+ SPDLOG_ERROR(TEXT("Error {0} returned by BCryptGetProperty"), status);
+ CloseHandle(hFile);
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ HeapFree(GetProcessHeap(), 0, pbHashObject);
+ return -ERR_BCRYPT_GETPROPERTY;
+ }
+
+ //allocate the hash buffer on the heap
+ pbHash = static_cast(HeapAlloc(GetProcessHeap(), 0, cbHash));
+ if (nullptr == pbHash) {
+ SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), cbHash);
+ CloseHandle(hFile);
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ HeapFree(GetProcessHeap(), 0, pbHashObject);
+ return -ERR_MALLOC_MEMORY;
+ }
+
+ //create a hash
+ if (NT_FAILED(status = BCryptCreateHash(hAlg, &hHash, pbHashObject, cbHashObject, nullptr, 0, 0))) {
+ SPDLOG_ERROR(TEXT("Error {0} returned by BCryptCreateHash"), status);
+ CloseHandle(hFile);
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ HeapFree(GetProcessHeap(), 0, pbHashObject);
+ HeapFree(GetProcessHeap(), 0, pbHash);
+ return -ERR_BCRYPT_CREATEHASH;
+ }
+
+ while (ReadFile(hFile, rgbFile, 1024, &cbRead, nullptr)) {
+ if (0 == cbRead) {
+ break;
+ }
+
+ if (NT_FAILED(status = BCryptHashData(hHash, rgbFile, cbRead, 0))) {
+ SPDLOG_ERROR(TEXT("Error {0} returned by BCryptHashData"), status);
+ CloseHandle(hFile);
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ BCryptDestroyHash(hHash);
+ HeapFree(GetProcessHeap(), 0, pbHashObject);
+ HeapFree(GetProcessHeap(), 0, pbHash);
+ return -ERR_BCRYPT_HASHDATA;
+ }
+ }
+
+ //close the hash
+ if (NT_FAILED(status = BCryptFinishHash(hHash, pbHash, cbHash, 0))) {
+ SPDLOG_ERROR(TEXT("Error {0} returned by BCryptFinishHash"), status);
+ CloseHandle(hFile);
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ BCryptDestroyHash(hHash);
+ HeapFree(GetProcessHeap(), 0, pbHashObject);
+ HeapFree(GetProcessHeap(), 0, pbHash);
+ return -ERR_BCRYPT_FINISHHASH;
+ }
+
+ binToHexString(outHash, pbHash, cbHash);
+
+ BCryptCloseAlgorithmProvider(hAlg, 0);
+ BCryptDestroyHash(hHash);
+ HeapFree(GetProcessHeap(), 0, pbHashObject);
+ HeapFree(GetProcessHeap(), 0, pbHash);
+ CloseHandle(hFile);
+
+ return ERR_SUCCESS;
+}
\ No newline at end of file
diff --git a/NetTunnelSDK/misc.cpp b/NetTunnelSDK/misc.cpp
index 21ade24..1fe2736 100644
--- a/NetTunnelSDK/misc.cpp
+++ b/NetTunnelSDK/misc.cpp
@@ -1,10 +1,24 @@
#include "pch.h"
#include "misc.h"
+
#include "usrerr.h"
#include
#include
+TCHAR *binToHexString(TCHAR *p, const unsigned char *cp, unsigned int count) {
+ static const TCHAR hex_asc[] = TEXT("0123456789abcdef");
+ while (count) {
+ const unsigned char c = *cp++;
+ /* put lowercase hex digits */
+ *p++ = static_cast(0x20 | hex_asc[c >> 4]);
+ *p++ = static_cast(0x20 | hex_asc[c & 0xf]);
+ count--;
+ }
+
+ return p;
+}
+
void RemoveTailLineBreak(TCHAR *pInputStr, int strSize) {
size_t length;
if (pInputStr) {
@@ -25,7 +39,7 @@ int RunCommand(TCHAR *pszCmd, TCHAR *pszResultBuffer, int dwResultBufferSize, un
DWORD retCode;
STARTUPINFO si;
PROCESS_INFORMATION pi;
- SECURITY_ATTRIBUTES securityAttributes = {};
+ SECURITY_ATTRIBUTES securityAttributes;
if (pszCmd == nullptr) {
SPDLOG_ERROR(TEXT("Input params Error: [{0}]"), pszCmd);
diff --git a/NetTunnelSDK/misc.h b/NetTunnelSDK/misc.h
index 255d800..58c99b0 100644
--- a/NetTunnelSDK/misc.h
+++ b/NetTunnelSDK/misc.h
@@ -24,9 +24,10 @@ int __cdecl NetmaskToCIDR(const TCHAR *pNetMask);
*/
const TCHAR *CIDRToNetmask(const UINT8 cidr);
-void ShowWindowsErrorMessage(const TCHAR *pMsgHead);
-void StringReplaceAll(TCHAR *pOrigin, const TCHAR *pOldStr, const TCHAR *pNewStr);
-void StringRemoveAll(TCHAR *pOrigin, const TCHAR *pString);
+void ShowWindowsErrorMessage(const TCHAR *pMsgHead);
+void StringReplaceAll(TCHAR *pOrigin, const TCHAR *pOldStr, const TCHAR *pNewStr);
+void StringRemoveAll(TCHAR *pOrigin, const TCHAR *pString);
+TCHAR *binToHexString(TCHAR *p, const unsigned char *cp, unsigned int count);
#ifdef __cplusplus
}
#endif
\ No newline at end of file
diff --git a/NetTunnelSDK/network.cpp b/NetTunnelSDK/network.cpp
index a07f6bd..991fc5d 100644
--- a/NetTunnelSDK/network.cpp
+++ b/NetTunnelSDK/network.cpp
@@ -423,73 +423,71 @@ int GetAllNICInfo(PNIC_CONTENT pInfo, int *pItemCounts) {
return ERR_SUCCESS;
}
-#if 0
-int GetAllNICInfo(PNIC_CONTENT pInfo, int *pItemCounts) {
- int nRel, id = 0;
- IP_ADDR_STRING *pIpAddrString;
- PIP_ADAPTER_INFO pIpAdapterInfo;
- unsigned long stSize;
+int SetInterfacePrivate(const TCHAR *pInterfaceName, bool isPrivate) {
+ int ret;
+ TCHAR cmdBuf[MAX_PATH];
+ DWORD retCode;
- if (pItemCounts == nullptr || pInfo == nullptr) {
- return -ERR_INPUT_PARAMS;
- }
-
- pIpAdapterInfo = new IP_ADAPTER_INFO[NET_CARD_MAX];
- stSize = sizeof(IP_ADAPTER_INFO) * NET_CARD_MAX;
-
- // WIN32 API get net card information
- nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
-
- if (ERROR_BUFFER_OVERFLOW == nRel) {
- delete[] pIpAdapterInfo;
- return -ERR_MALLOC_MEMORY;
- }
-
- PIP_ADAPTER_INFO cur = pIpAdapterInfo;
-
- while (cur) {
- pInfo[id].InterfaceIndex = cur->Index;
- StringCbCopy(pInfo[id].NetCardUUID, MAX_ADAPTER_NAME_LENGTH, cur->AdapterName);
- StringCbCopy(pInfo[id].NetCardDescription, MAX_ADAPTER_DESCRIPTION_LENGTH, cur->Description);
-
- switch (cur->Type) {
- case MIB_IF_TYPE_ETHERNET:
- pIpAddrString = &(cur->IpAddressList);
- StringCbCopy(pInfo[id].NetCardIpaddr, MAX_IP_LEN - 1, pIpAddrString->IpAddress.String);
- StringCbCopy(pInfo[id].NetCardNetmask, MAX_IP_LEN - 1, pIpAddrString->IpMask.String);
- break;
- case MIB_IF_TYPE_OTHER:
- case MIB_IF_TYPE_TOKENRING:
- case MIB_IF_TYPE_FDDI:
- case MIB_IF_TYPE_PPP:
- case MIB_IF_TYPE_LOOPBACK:
- case MIB_IF_TYPE_SLIP:
- break;
- default: // WIFI ,Unknown type
- pIpAddrString = &(cur->IpAddressList);
- StringCbCopy(pInfo[id].NetCardIpaddr, MAX_IP_LEN - 1, pIpAddrString->IpAddress.String);
- StringCbCopy(pInfo[id].NetCardNetmask, MAX_IP_LEN - 1, pIpAddrString->IpMask.String);
- break;
+ if (isPrivate) {
+ if (FAILED(StringCbPrintf(
+ cmdBuf,
+ MAX_PATH,
+ "PowerShell -Command \"& {Set-NetConnectionProfile -InterfaceAlias %s -NetworkCategory \"Private\"}\"",
+ pInterfaceName))) {
+ SPDLOG_ERROR("Format String Error");
+ return -ERR_MEMORY_STR;
+ }
+ } else {
+ if (FAILED(StringCbPrintf(
+ cmdBuf,
+ MAX_PATH,
+ "PowerShell -Command \"& {Set-NetConnectionProfile -InterfaceAlias %s -NetworkCategory \"Public\"}\"",
+ pInterfaceName))) {
+ SPDLOG_ERROR("Format String Error");
+ return -ERR_MEMORY_STR;
}
-
- StringCbPrintf(pInfo[id].NetCardMacAddr,
- 20 - 1,
- "%02X:%02X:%02X:%02X:%02X:%02X",
- cur->Address[0],
- cur->Address[1],
- cur->Address[2],
- cur->Address[3],
- cur->Address[4],
- cur->Address[5]);
-
- id++;
- cur = cur->Next;
}
- *pItemCounts = id;
+ if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) {
+ SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret);
+ return -ERR_CALL_SHELL;
+ }
- delete[] pIpAdapterInfo;
+ if (retCode != 0) {
+ SPDLOG_ERROR("PowerShell return error({1}): {0}", cmdBuf, retCode);
+ return -ERR_PROCESS_RETURN;
+ }
return ERR_SUCCESS;
}
-#endif
\ No newline at end of file
+
+/**
+ * @brief WireGuard Windows PowerShell ԶǷװ
+ * @return
+ * - TRUE Ѿװ
+ * - FALSE δװ
+ */
+bool CustomNatPSCmdInstalled() {
+ TCHAR psCmdPath[MAX_PATH];
+
+ StringCbPrintf(psCmdPath,
+ MAX_PATH,
+ TEXT("%s\\system32\\WindowsPowerShell\\v1.0\\Modules\\wireguard"),
+ GetGlobalCfgInfo()->systemDirectory);
+
+ // ж WireGuard NAT Ƿװ
+ if (!PathFileExists(psCmdPath)) {
+ if (!CreateDirectory(psCmdPath, nullptr)) {
+ return false;
+ }
+ }
+
+ StringCbCat(psCmdPath, MAX_PATH, "\\wireguard.psm1");
+
+ if (PathFileExists(psCmdPath)) {
+ // ļ˵Ѿװ
+ return true;
+ }
+
+ return false;
+}
\ No newline at end of file
diff --git a/NetTunnelSDK/ps1/wireguard.psm1 b/NetTunnelSDK/ps1/wireguard.psm1
new file mode 100644
index 0000000..15a6f60
--- /dev/null
+++ b/NetTunnelSDK/ps1/wireguard.psm1
@@ -0,0 +1,63 @@
+Function Set-NetConnectionSharing
+{
+ Param
+ (
+ [Parameter(Mandatory=$true)]
+ [string]
+ $LocalConnection,
+
+ [Parameter(Mandatory=$true)]
+ [bool]
+ $Enabled
+ )
+
+ Begin
+ {
+ $netShare = $null
+
+ try
+ {
+ # Create a NetSharingManager object
+ $netShare = New-Object -ComObject HNetCfg.HNetShare
+ }
+ catch
+ {
+ # Register the HNetCfg library (once)
+ regsvr32 /s hnetcfg.dll
+
+ # Create a NetSharingManager object
+ $netShare = New-Object -ComObject HNetCfg.HNetShare
+ }
+ }
+
+ Process
+ {
+ #Clear Existing Share
+ $oldConnections = $netShare.EnumEveryConnection |? { $netShare.INetSharingConfigurationForINetConnection.Invoke($_).SharingEnabled -eq $true}
+ foreach($oldShared in $oldConnections)
+ {
+ $oldConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($oldShared)
+ $oldConfig.DisableSharing()
+ }
+
+ # Find connections
+ $InternetConnection = Get-NetRoute | ? DestinationPrefix -eq '0.0.0.0/0' | Get-NetIPInterface | Where ConnectionState -eq 'Connected'
+ $publicConnection = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq $InternetConnection.InterfaceAlias }
+ $privateConnection = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq $LocalConnection }
+
+ # Get sharing configuration
+ $publicConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($publicConnection)
+ $privateConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($privateConnection)
+
+ if ($Enabled)
+ {
+ $publicConfig.EnableSharing(0)
+ $privateConfig.EnableSharing(1)
+ }
+ else
+ {
+ $publicConfig.DisableSharing()
+ $privateConfig.DisableSharing()
+ }
+ }
+}
\ No newline at end of file
diff --git a/NetTunnelSDK/resource.h b/NetTunnelSDK/resource.h
new file mode 100644
index 0000000..7d61926
--- /dev/null
+++ b/NetTunnelSDK/resource.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ ɵİļ
+// NetTunnelSDK.rc ʹ
+//
+#define IDR_TXT2 102
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 103
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/NetTunnelSDK/tunnel.cpp b/NetTunnelSDK/tunnel.cpp
index 6317e92..0b9f641 100644
--- a/NetTunnelSDK/tunnel.cpp
+++ b/NetTunnelSDK/tunnel.cpp
@@ -1,6 +1,7 @@
#include "pch.h"
#include "tunnel.h"
+#include
#include
#include
#include
@@ -30,6 +31,12 @@ int TunnelSDKInitEnv(const TCHAR *pWorkDir) {
spdlog::set_level(spdlog::level::off);
}
+ if (SUCCEEDED(
+ SHGetFolderPath(NULL, CSIDL_WINDOWS | CSIDL_FLAG_NO_ALIAS, NULL, 0, g_globalConfig.systemDirectory))) {
+ SPDLOG_ERROR(TEXT("Get Windows system directory error."));
+ return -ERR_ITEM_EXISTS;
+ }
+
if (pWorkDir == nullptr) {
// 获取当前文件默认路径
GetCurrentDirectory(MAX_PATH, g_globalConfig.workDirectory);
@@ -121,12 +128,9 @@ void TunnelLogEnable(bool enLog) {
}
}
-int SetProtocolEncryptType(const PROTO_CRYPTO_TYPE type, const TCHAR* pProKey)
-{
- if (type > CRYPTO_BASE64 && type < CRYPTO_MAX)
- {
- if (pProKey == nullptr || strlen(pProKey) < 8)
- {
+int SetProtocolEncryptType(const PROTO_CRYPTO_TYPE type, const TCHAR *pProKey) {
+ if (type > CRYPTO_BASE64 && type < CRYPTO_MAX) {
+ if (pProKey == nullptr || strlen(pProKey) < 8) {
return -ERR_INPUT_PARAMS;
}
}
@@ -134,7 +138,8 @@ int SetProtocolEncryptType(const PROTO_CRYPTO_TYPE type, const TCHAR* pProKey)
g_globalConfig.proCryptoType = type;
StringCbCopy(g_globalConfig.proKeyBuf, 256, pProKey);
- SPDLOG_DEBUG(TEXT("Protocol crypto type: {0} with key [{1}]"), static_cast(type),
+ SPDLOG_DEBUG(TEXT("Protocol crypto type: {0} with key [{1}]"),
+ static_cast(type),
pProKey ? pProKey : TEXT(""));
return ERR_SUCCESS;
diff --git a/NetTunnelSDK/tunnel.h b/NetTunnelSDK/tunnel.h
index 2da8390..fd961d7 100644
--- a/NetTunnelSDK/tunnel.h
+++ b/NetTunnelSDK/tunnel.h
@@ -50,6 +50,20 @@ enum LOG_LEVEL {
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;
+
/**
*
* @brief 本地计算机网卡信息
@@ -168,7 +182,7 @@ TUNNEL_API int __cdecl GenerateWireguardKeyPairs(TCHAR *pPubKey, int pubkeySize,
/**
* @brief 创建 WireGuard 服务端配置文件
- * @param pWgConfig 配置文件相关配置项 @see WGSERVER_CONFIG
+ * @param[in] pWgConfig 配置文件相关配置项 @see WGSERVER_CONFIG
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
* - -ERR_INPUT_PARAMS 输入参数错误
* - -ERR_MALLOC_MEMORY 分配内存失败
@@ -180,7 +194,7 @@ TUNNEL_API int __cdecl WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgCon
/**
* @brief 创建 WireGuard 客户端配置文件
- * @param pWgConfig 配置文件相关配置项 @see WGCLIENT_CONFIG
+ * @param[in] pWgConfig 配置文件相关配置项 @see WGCLIENT_CONFIG
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
* - -ERR_INPUT_PARAMS 输入参数错误
* - -ERR_MALLOC_MEMORY 分配内存失败
@@ -197,13 +211,15 @@ TUNNEL_API int __cdecl WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgCon
*/
TUNNEL_API int __cdecl WireGuardInstallServerService(bool bInstall);
+TUNNEL_API int __cdecl InstallWindowsNATCommand();
+
/**
* @brief 清理 SDK 运行资源
*/
TUNNEL_API void __cdecl TunnelSDKUnInit();
/**
* @brief 获取本机网卡信息
- * @param[in,out] pInfo 网卡信息 @see NIC_CONTENT
+ * @param[out] pInfo 网卡信息 @see NIC_CONTENT
* @param[out] pItemCounts 计算机当前操作系统中网卡总数 最大值 32
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
* - -ERR_INPUT_PARAMS 输入参数错误
@@ -214,8 +230,8 @@ TUNNEL_API int __cdecl GetAllNICInfo(PNIC_CONTENT pInfo, int *pItemCounts);
/**
* @brief 获取网卡接口索引编号
- * @param pInterfaceName 网卡名称
- * @param pIndex 网卡索引
+ * @param[in] pInterfaceName 网卡名称
+ * @param[out] pIndex 网卡索引
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
* - -ERR_INPUT_PARAMS 输入参数错误
* - -ERR_MALLOC_MEMORY 分配内存失败
@@ -289,8 +305,8 @@ TUNNEL_API int __cdecl EnableWindowsHyperV(bool enabled);
/**
* @brief 开启 Windows WireGuard NAT 转发功能
- * @param pInterfaceName 网卡名称
- * @param pCidrIpaddr CIDR 网络接口地址
+ * @param[in] pInterfaceName 网卡名称
+ * @param[in] pCidrIpaddr CIDR 网络接口地址
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
* - -ERR_INPUT_PARAMS 输入参数错误
* - -ERR_MEMORY_STR 字符串处理
@@ -299,6 +315,47 @@ TUNNEL_API int __cdecl EnableWindowsHyperV(bool enabled);
* - ERR_SUCCESS 成功
*/
TUNNEL_API int __cdecl SetNATRule(const TCHAR *pInterfaceName, const TCHAR *pCidrIpaddr);
+
+/**
+ * @brief 设置网卡为 Private/Public 模式
+ * @param[in] pInterfaceName 网卡名称
+ * @param[in] isPrivate
+ * - TRUE Private 模式
+ * - FALSE Public 模式
+ * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
+ * - -ERR_INPUT_PARAMS 输入参数错误
+ * - -ERR_MEMORY_STR 字符串处理
+ * - -ERR_CALL_SHELL 调用系统命令行失败
+ * - -ERR_PROCESS_RETURN 系统调用执行结束返回失败
+ * - ERR_SUCCESS 成功
+ */
+TUNNEL_API int __cdecl SetInterfacePrivate(const TCHAR *pInterfaceName, bool isPrivate);
+
+/**
+ * @brief WireGuard 服务 Windows PowerShell 自定义命令是否安装
+ * @return
+ * - TRUE 已经安装
+ * - FALSE 未安装
+ */
+TUNNEL_API bool __cdecl CustomNatPSCmdInstalled();
+
+/**
+ * @brief 计算文件 Hash
+ * @param[in] type Hash 类型 @see HASH_TYPE
+ * @param[in] pPath 需要计算 Hash 值的文件路径
+ * @param[out] outHash 计算结果
+ * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
+ * - -ERR_INPUT_PARAMS 输入参数错误
+ * - -ERR_ITEM_UNEXISTS 文件不存在
+ * - -ERR_OPEN_FILE 打开文件失败
+ * - -ERR_BCRYPT_OPEN 创建加解密算法失败
+ * - -ERR_BCRYPT_GETPROPERTY 获取加解密算法属性失败
+ * - -ERR_BCRYPT_CREATEHASH 创建 Hash 算法失败
+ * - -ERR_BCRYPT_HASHDATA 计算 Hash 数据失败
+ * - -ERR_BCRYPT_FINISHHASH 计算 Hash 结果失败
+ * - ERR_SUCCESS 成功
+ */
+TUNNEL_API int __cdecl CalcFileHash(const HASH_TYPE type, const TCHAR *pPath, TCHAR outHash[]);
#ifdef __cplusplus
}
#endif
\ No newline at end of file
diff --git a/NetTunnelSDK/usrerr.h b/NetTunnelSDK/usrerr.h
index 5b7b20d..d123411 100644
--- a/NetTunnelSDK/usrerr.h
+++ b/NetTunnelSDK/usrerr.h
@@ -12,6 +12,7 @@ enum USER_ERRNO {
ERR_ITEM_UNEXISTS, ///< 该内容不存在
ERR_SYS_INIT, ///< 系统中断
ERR_SYS_CALL, ///< 系统调用
+ ERR_CREATE_FILE, ///< 创建文件/目录失败
ERR_OPEN_FILE, ///< 打开文件失败
ERR_READ_FILE, ///< 读取文件失败
ERR_WRITE_FILE, ///< 写入文件失败
@@ -23,5 +24,10 @@ enum USER_ERRNO {
ERR_MMAP_MEMORY, ///< 共享内存失败
ERR_MEMORY_STR, ///< 字符串操作失败
ERR_CREATE_PROCESS, ///< 创建进程失败
- ERR_PROCESS_RETURN ///< 进程调用返回失败
+ ERR_PROCESS_RETURN, ///< 进程调用返回失败
+ ERR_BCRYPT_OPEN, ///< 创建加密算法失败
+ ERR_BCRYPT_GETPROPERTY, ///< 获取加密算法属性失败
+ ERR_BCRYPT_CREATEHASH, ///< 创建 Hash 算法失败
+ ERR_BCRYPT_HASHDATA, ///< 计算 Hash 数据失败
+ ERR_BCRYPT_FINISHHASH, ///< 计算 Hash 结果失败
};
\ No newline at end of file
diff --git a/NetTunnelSDK/wireguard.cpp b/NetTunnelSDK/wireguard.cpp
index d6423f9..a0bbe4e 100644
--- a/NetTunnelSDK/wireguard.cpp
+++ b/NetTunnelSDK/wireguard.cpp
@@ -7,6 +7,7 @@
#include "globalcfg.h"
#include "misc.h"
+#include "resource.h"
#pragma comment(lib, "Shlwapi.lib")
@@ -17,6 +18,11 @@ constexpr auto WINENVBUF_SIZE = (4096);
#define CFG_WGCFG_PATH TEXT("WgCfgPath")
#define CFG_WG_PATH TEXT("WgExe")
+/**
+ * @brief 安装/卸载 WireGuard 服务
+ * @param[in] bInstall TRUE 安装服务, FALSE 卸载服务
+ * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
+ */
int WireGuardInstallServerService(bool bInstall) {
TCHAR cfgVal[MAX_PATH];
DWORD retCode;
@@ -29,10 +35,7 @@ int WireGuardInstallServerService(bool bInstall) {
GetGlobalCfgInfo()->cfgPath);
if (lstrlen(cfgVal) > 0) {
- WIN32_FIND_DATA FindFileData;
- const HANDLE hFind = FindFirstFile(cfgVal, &FindFileData);
-
- if (hFind != INVALID_HANDLE_VALUE) {
+ if (PathFileExists(cfgVal)) {
TCHAR cmdBuf[MAX_PATH];
int ret;
@@ -76,6 +79,16 @@ int WireGuardInstallServerService(bool bInstall) {
}
}
+/**
+ * @brief 创建 WireGuard 客户端配置文件
+ * @param[in] pWgConfig 配置文件相关配置项 @see WGCLIENT_CONFIG
+ * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
+ * - -ERR_INPUT_PARAMS 输入参数错误
+ * - -ERR_MALLOC_MEMORY 分配内存失败
+ * - -ERR_OPEN_FILE 打开文件失败
+ * - -ERR_MEMORY_STR 字符串处理失败
+ * - ERR_SUCCESS 成功
+ */
int WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgConfig) {
const size_t bufSize = 4096 * sizeof(TCHAR);
const TCHAR cfgFormat[] = TEXT(
@@ -188,6 +201,16 @@ int WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgConfig) {
return ERR_SUCCESS;
}
+/**
+ * @brief 创建 WireGuard 服务端配置文件
+ * @param[in] pWgConfig 配置文件相关配置项 @see WGSERVER_CONFIG
+ * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
+ * - -ERR_INPUT_PARAMS 输入参数错误
+ * - -ERR_MALLOC_MEMORY 分配内存失败
+ * - -ERR_OPEN_FILE 打开文件失败
+ * - -ERR_MEMORY_STR 字符串处理失败
+ * - ERR_SUCCESS 成功
+ */
int WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgConfig) {
const size_t bufSize = 4096 * sizeof(TCHAR);
const TCHAR cfgFormat[] = TEXT(
@@ -303,6 +326,17 @@ int WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgConfig) {
return ERR_SUCCESS;
}
+/**
+ * @brief 创建 WireGuard 密钥对
+ * @param[out] pPubKey 公钥缓冲区
+ * @param[in] pubkeySize 公钥缓冲区大小(字节数)
+ * @param[out] pPrivKey 私钥缓冲区
+ * @param[in] privKeySize 私钥缓冲区大小(字节数)
+ * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
+ * - -ERR_ITEM_UNEXISTS WireGuard 未配置或未安装
+ * - -ERR_CALL_SHELL 调用操作系统命令行工具失败
+ * - ERR_SUCCESS 成功
+ */
int GenerateWireguardKeyPairs(TCHAR *pPubKey, int pubkeySize, TCHAR *pPrivKey, int privKeySize) {
int ret;
DWORD retCode;
@@ -347,17 +381,20 @@ int GenerateWireguardKeyPairs(TCHAR *pPubKey, int pubkeySize, TCHAR *pPrivKey, i
return ERR_SUCCESS;
}
+/**
+ * @brief 设置 wireguard.exe 程序路径
+ * @param[in] pPath wireguard.exe 程序路径
+ * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
+ * - -ERR_INPUT_PARAMS 输入参数错误
+ * - -ERR_ITEM_UNEXISTS 文件不存在
+ * - ERR_SUCCESS 成功
+ */
int SetWireguardPath(const TCHAR *pPath) {
- WIN32_FIND_DATA FindFileData;
- HANDLE hFind;
-
if (pPath == nullptr) {
return -ERR_INPUT_PARAMS;
}
- hFind = FindFirstFile(pPath, &FindFileData);
-
- if (hFind != INVALID_HANDLE_VALUE) {
+ if (PathFileExists(pPath)) {
TCHAR wgPath[MAX_PATH];
SPDLOG_DEBUG(TEXT("Used configure file:{0}"), GetGlobalCfgInfo()->cfgPath);
@@ -381,50 +418,76 @@ int SetWireguardPath(const TCHAR *pPath) {
}
}
+/**
+ * @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 成功
+ */
int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
- TCHAR path[MAX_PATH];
- TCHAR wrieguardPath[MAX_PATH];
- WIN32_FIND_DATA FindFileData;
- HANDLE hFind;
- DWORD dwRet;
- LPSTR pEnvBuf;
- TCHAR *token, *p = nullptr;
+ TCHAR path[MAX_PATH];
+ TCHAR wireguardPath[MAX_PATH];
+ DWORD dwRet;
+ LPSTR pEnvBuf;
+ TCHAR *token, *p = nullptr;
GetPrivateProfileString(CFG_WIREGUARD_SECTION,
CFG_WIREGUARD_PATH,
TEXT(""),
- wrieguardPath,
+ wireguardPath,
MAX_PATH,
GetGlobalCfgInfo()->cfgPath);
- hFind = FindFirstFile(wrieguardPath, &FindFileData);
- if (hFind != INVALID_HANDLE_VALUE) {
+ if (PathFileExists(wireguardPath)) {
if (pFullPath && maxSize > 0) {
- StringCbCopy(pFullPath, maxSize, wrieguardPath);
+ StringCbCopy(pFullPath, maxSize, wireguardPath);
}
- StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wireguardPath, MAX_PATH, wrieguardPath);
+ StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wireguardPath, MAX_PATH, wireguardPath);
GetGlobalCfgInfo()->wireguardCfg.wireguardExists = TRUE;
- SPDLOG_DEBUG(TEXT("Ini found WireGuard at: {0}"), wrieguardPath);
+ SPDLOG_DEBUG(TEXT("Ini found WireGuard at: {0}"), wireguardPath);
GetPrivateProfileString(CFG_WIREGUARD_SECTION,
CFG_WG_PATH,
TEXT(""),
- wrieguardPath,
+ wireguardPath,
MAX_PATH,
GetGlobalCfgInfo()->cfgPath);
- hFind = FindFirstFile(wrieguardPath, &FindFileData);
- if (hFind != INVALID_HANDLE_VALUE) {
- StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wgPath, MAX_PATH, wrieguardPath);
+ if (PathFileExists(wireguardPath)) {
+ StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wgPath, MAX_PATH, wireguardPath);
GetGlobalCfgInfo()->wireguardCfg.wgExists = TRUE;
- SPDLOG_DEBUG(TEXT("Ini found WireGuard Tools at: {0}"), wrieguardPath);
+ SPDLOG_DEBUG(TEXT("Ini found WireGuard Tools at: {0}"), wireguardPath);
}
return ERR_SUCCESS;
}
+ StringCbCopy(wireguardPath, MAX_PATH, GetGlobalCfgInfo()->systemDirectory);
+ PathStripToRootA(wireguardPath);
+ StringCbCat(wireguardPath, MAX_PATH, TEXT("Program Files\\WireGuard\\wireguard.exe"));
+
+ if (PathFileExists(wireguardPath)) {
+ // 保存路径到配置文件
+ SetWireguardPath(wireguardPath);
+ GetGlobalCfgInfo()->wireguardCfg.wireguardExists = TRUE;
+
+ PathRemoveFileSpec(wireguardPath);
+ StringCbCat(wireguardPath, MAX_PATH, TEXT("\\wg.exe"));
+
+ if (PathFileExists(wireguardPath)) {
+ GetGlobalCfgInfo()->wireguardCfg.wgExists = TRUE;
+ }
+
+ return ERR_SUCCESS;
+ }
+
+ // 从环境变量中查找
pEnvBuf = static_cast(malloc(WINENVBUF_SIZE));
if (nullptr == pEnvBuf) {
SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), WINENVBUF_SIZE);
@@ -442,7 +505,7 @@ int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
return -ERR_FILE_NOT_EXISTS;
}
} else if (WINENVBUF_SIZE < dwRet) {
- LPSTR pBuf = static_cast(realloc(pEnvBuf, dwRet * sizeof(CHAR)));
+ const auto pBuf = static_cast(realloc(pEnvBuf, dwRet * sizeof(CHAR)));
if (nullptr == pBuf) {
SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), dwRet * sizeof(CHAR));
free(pEnvBuf);
@@ -464,9 +527,7 @@ int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
memset(path, 0, MAX_PATH);
StringCbPrintfA(path, MAX_PATH, TEXT("%s\\wireguard.exe"), token);
- hFind = FindFirstFile(path, &FindFileData);
-
- if (hFind != INVALID_HANDLE_VALUE) {
+ if (PathFileExists(path)) {
if (pFullPath && maxSize > 0) {
StringCbCopy(pFullPath, maxSize, path);
}
@@ -475,7 +536,7 @@ int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
SetWireguardPath(path);
SPDLOG_DEBUG(TEXT("Path Environment found WireGuard at: {0}"), path);
- StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wireguardPath, MAX_PATH, wrieguardPath);
+ StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wireguardPath, MAX_PATH, wireguardPath);
GetGlobalCfgInfo()->wireguardCfg.wireguardExists = TRUE;
memset(path, 0, MAX_PATH);
@@ -483,8 +544,7 @@ int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
SPDLOG_DEBUG(TEXT("Find WireGuard tools at: {0}"), path);
- hFind = FindFirstFile(path, &FindFileData);
- if (hFind != INVALID_HANDLE_VALUE) {
+ if (PathFileExists(path)) {
StringCbCopy(GetGlobalCfgInfo()->wireguardCfg.wgPath, MAX_PATH, path);
GetGlobalCfgInfo()->wireguardCfg.wgExists = TRUE;
@@ -501,4 +561,80 @@ int FindWireguardExe(TCHAR *pFullPath, int maxSize) {
free(pEnvBuf);
return -ERR_FILE_NOT_EXISTS;
+}
+
+int InstallWindowsNATCommand() {
+ TCHAR psCmdPath[MAX_PATH];
+
+ // 如果已经安装则退出
+ if (CustomNatPSCmdInstalled()) {
+ return ERR_SUCCESS;
+ }
+
+ StringCbPrintf(psCmdPath,
+ MAX_PATH,
+ TEXT("%s\\system32\\WindowsPowerShell\\v1.0\\Modules\\wireguard\\wireguard.psm1"),
+ GetGlobalCfgInfo()->systemDirectory);
+
+ const HANDLE hFile = CreateFile(psCmdPath,
+ GENERIC_WRITE | GENERIC_READ,
+ FILE_SHARE_READ,
+ nullptr,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ nullptr);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ SPDLOG_ERROR("CreatFile [{0}] error: {1}", psCmdPath, GetLastError());
+ return -ERR_OPEN_FILE;
+ }
+
+ const HMODULE hMod = GetModuleHandle(TEXT("NetTunnelSDK.dll"));
+
+ if (nullptr == hMod) {
+ SPDLOG_ERROR(TEXT("Load NetTunnelSDK.dll module error"));
+ ::CloseHandle(hFile);
+ return -ERR_ITEM_UNEXISTS;
+ }
+
+ const HRSRC hRsrc = FindResource(hMod, MAKEINTRESOURCE(IDR_TXT2), TEXT("TXT"));
+ if (nullptr == hRsrc) {
+ SPDLOG_ERROR(TEXT("Donot found resource {0} of type {1}"), IDR_TXT2, TEXT("TXT"));
+ ::CloseHandle(hFile);
+ return -ERR_ITEM_UNEXISTS;
+ }
+
+ const DWORD resSize = SizeofResource(hMod, hRsrc);
+
+ if (resSize == 0) {
+ SPDLOG_ERROR(TEXT("Resource {0} of type {1} is empty"), IDR_TXT2, TEXT("TXT"));
+ ::CloseHandle(hFile);
+ return -ERR_ITEM_UNEXISTS;
+ }
+
+ const HGLOBAL hGlobal = LoadResource(hMod, hRsrc);
+
+ if (hGlobal == hRsrc) {
+ SPDLOG_ERROR(TEXT("Load resource {0} of type {1} error"), IDR_TXT2, TEXT("TXT"));
+ ::CloseHandle(hFile);
+ return -ERR_ITEM_UNEXISTS;
+ }
+
+ if (const LPVOID pBuffer = LockResource(hGlobal)) {
+ if (!WriteFile(hFile, // open file handle
+ pBuffer, // start of data to write
+ static_cast(resSize), // number of bytes to write
+ nullptr, // number of bytes that were written
+ nullptr)) {
+ SPDLOG_ERROR("WriteFile [{0}] error: {1}", psCmdPath, GetLastError());
+ GlobalUnlock(hGlobal);
+ ::CloseHandle(hFile);
+ return -ERR_OPEN_FILE;
+ }
+ }
+
+ GlobalUnlock(hGlobal);
+ ::CloseHandle(hFile);
+
+ return ERR_SUCCESS;
}
\ No newline at end of file
diff --git a/TestNetTunnelSDK/TestNetTunnelSDK.cpp b/TestNetTunnelSDK/TestNetTunnelSDK.cpp
index e1b2674..6440409 100644
--- a/TestNetTunnelSDK/TestNetTunnelSDK.cpp
+++ b/TestNetTunnelSDK/TestNetTunnelSDK.cpp
@@ -3,6 +3,7 @@
#include "../NetTunnelSDK/tunnel.h"
#include "../NetTunnelSDK/usrerr.h"
#include "../NetTunnelSDK/misc.h"
+#include "../NetTunnelSDK/globalcfg.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
@@ -11,6 +12,7 @@ TEST_MODULE_INITIALIZE(ModuleInitialize) {
Logger::WriteMessage("In Module Initialize");
TunnelSDKInitEnv(
TEXT("C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_windows\\NetTunnelApp\\bin\\Debug"));
+
InitTunnelSDKLog(TEXT("C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_"
"windows\\NetTunnelApp\\bin\\Debug\\utest.log"),
LOG_DEBUG);
@@ -55,15 +57,12 @@ public:
}
TEST_METHOD(TestSetInterfaceIpAddressFromCIDR) {
- Assert::AreEqual(
- RET_OK,
- SetInterfaceIpAddressFromCIDR(TEXT("wg_server"), TEXT("192.168.100.250/24")));
+ Assert::AreEqual(RET_OK, SetInterfaceIpAddressFromCIDR(TEXT("wg_server"), TEXT("192.168.100.250/24")));
}
TEST_METHOD(TestSetInterfaceIpAddress) {
- Assert::AreEqual(
- RET_OK,
- SetInterfaceIpAddress(TEXT("wg_server"), TEXT("192.168.101.250"), TEXT("255.255.0.0")));
+ Assert::AreEqual(RET_OK,
+ SetInterfaceIpAddress(TEXT("wg_server"), TEXT("192.168.101.250"), TEXT("255.255.0.0")));
}
TEST_METHOD(TestGetInterfaceIndexByName) {
@@ -71,7 +70,7 @@ public:
Assert::AreEqual(RET_OK, GetInterfaceIndexByName(TEXT("wg_server"), &index));
}
- TEST_METHOD(TestRemoveInterfaceIpAddress) {
+ TEST_METHOD(TestRemoveInterfaceIpAddress) {
Assert::AreEqual(RET_OK, RemoveInterfaceIpAddress(TEXT("wg_server")));
}
@@ -80,5 +79,16 @@ public:
Assert::AreEqual(RET_OK, GetWindowsHyperVStatus(&enable));
Assert::AreEqual(TRUE, enable);
}
+
+ TEST_METHOD(TestInstallWindowsNATCommand) {
+ Assert::AreEqual(RET_OK, InstallWindowsNATCommand());
+ }
+
+ TEST_METHOD(TestCalcFileHash) {
+ TCHAR outHash[MAX_PATH] = {0};
+
+ Assert::AreEqual(RET_OK, CalcFileHash(HASH_SHA256, TEXT("E:\\wireguard.psm1"), outHash));
+ Assert::AreEqual(TEXT("3ef17a2eb23a148a3fbe14cb4ef38747e0a1e5037b6afa2350a9b18f617bb5db"), outHash);
+ }
};
}
\ No newline at end of file