OCT 1. 增加 WinDivert 库
2. 增加 UTHASH 库 3. 增加部分 SCG 代理代码 4. 备份代码
This commit is contained in:
parent
f20c234af7
commit
6930c948a5
|
@ -3,11 +3,10 @@
|
|||
################################################################################
|
||||
|
||||
/.vs
|
||||
/NetTunnelApp/bin
|
||||
/NetTunnelApp/obj/
|
||||
/NetTunnelSDK/x64/
|
||||
bin/
|
||||
obj/
|
||||
x64/
|
||||
/x64/
|
||||
/TestNetTunnelSDK/x64/Debug
|
||||
Debug/
|
||||
/packages/System.Buffers.4.5.1
|
||||
/Installer/Debug
|
||||
/InstallTunnelSDK/Debug
|
||||
/packages/DllExport.1.6.4
|
||||
|
|
|
@ -99,6 +99,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_6A1A279D341B4A5D87C6D56C726E2979"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_6A8B2CA20D527217332BB0170E559DB9"
|
||||
"OwnerKey" = "8:_00EB5BF3E5624995855CCF580A8AD1D5"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -184,12 +190,6 @@
|
|||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_UNDEFINED"
|
||||
"OwnerKey" = "8:_513E5CF8D0F56603CEA37562D0DCB474"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_UNDEFINED"
|
||||
"OwnerKey" = "8:_10E071CF096B417C925C5E27E36CE39A"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
|
@ -223,6 +223,12 @@
|
|||
"OwnerKey" = "8:_061110FCF275ABD7AB2CF878EE47397D"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_UNDEFINED"
|
||||
"OwnerKey" = "8:_513E5CF8D0F56603CEA37562D0DCB474"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
}
|
||||
"Configurations"
|
||||
{
|
||||
|
@ -241,6 +247,22 @@
|
|||
"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 and x64)"
|
||||
"ProductCode" = "8:.NETFramework,Version=v4.7.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"Release"
|
||||
{
|
||||
|
@ -257,6 +279,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"
|
||||
|
@ -459,6 +489,26 @@
|
|||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6A1A279D341B4A5D87C6D56C726E2979"
|
||||
{
|
||||
"SourcePath" = "8:..\\NetTunnelSDK\\resource\\iconsTray.ico"
|
||||
"TargetName" = "8:iconsTray.ico"
|
||||
"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:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_6A8B2CA20D527217332BB0170E559DB9"
|
||||
{
|
||||
"SourcePath" = "8:ucrtbased.dll"
|
||||
|
@ -515,7 +565,7 @@
|
|||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"Exclude" = "11:TRUE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
|
@ -535,7 +585,7 @@
|
|||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"Exclude" = "11:TRUE"
|
||||
"IsDependency" = "11:TRUE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
|
@ -689,7 +739,7 @@
|
|||
"Name" = "8:Microsoft Visual Studio"
|
||||
"ProductName" = "8:SCC"
|
||||
"ProductCode" = "8:{FC04A2D1-FDD4-485A-88CC-67543D0B07FC}"
|
||||
"PackageCode" = "8:{18F34BAE-0E72-485B-A6EB-9A62761CD03B}"
|
||||
"PackageCode" = "8:{E72A3533-046D-464B-A2A8-C1326AC51F4F}"
|
||||
"UpgradeCode" = "8:{E4E3F1C5-78D9-4F56-AA5F-2C68C839E21E}"
|
||||
"AspNetVersion" = "8:"
|
||||
"RestartWWWService" = "11:FALSE"
|
||||
|
@ -706,7 +756,7 @@
|
|||
"Keywords" = "8:"
|
||||
"ARPCOMMENTS" = "8:"
|
||||
"ARPURLINFOABOUT" = "8:"
|
||||
"ARPPRODUCTICON" = "8:"
|
||||
"ARPPRODUCTICON" = "8:_6A1A279D341B4A5D87C6D56C726E2979"
|
||||
"ARPIconIndex" = "3:0"
|
||||
"SearchPath" = "8:"
|
||||
"UseSystemSearchPath" = "11:TRUE"
|
||||
|
|
|
@ -50,15 +50,18 @@
|
|||
this.menuControlHeartStart = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuControlHeartStop = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuMainSet = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuSetModeShareNet = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuSetModeShareServer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuSetMode = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuSetModeClient = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuSetModeServer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuSetModeShareNet = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuSetModeShareServer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.menuSetVPN = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuSetVPNPath = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuSetExitToTray = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuSetShareMode = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuSetShareModeICS = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuSetShareModeNAT = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuMainHelp = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.statusMain = new System.Windows.Forms.StatusStrip();
|
||||
this.tbMain = new System.Windows.Forms.ToolStrip();
|
||||
|
@ -71,9 +74,6 @@
|
|||
this.trapMenuSysInterface = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.trapMenuExit = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuControlNetMode = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuControlNetModePrivate = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuControlNetModePublic = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuMain.SuspendLayout();
|
||||
this.trapMenuMain.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
|
@ -157,8 +157,7 @@
|
|||
this.menuControlSetCliParams,
|
||||
this.toolStripSeparator2,
|
||||
this.menuControlService,
|
||||
this.menuControlHeart,
|
||||
this.menuControlNetMode});
|
||||
this.menuControlHeart});
|
||||
this.menuControl.Name = "menuControl";
|
||||
this.menuControl.Size = new System.Drawing.Size(60, 21);
|
||||
this.menuControl.Text = "操作(&C)";
|
||||
|
@ -166,27 +165,27 @@
|
|||
// menuControlRefInterface
|
||||
//
|
||||
this.menuControlRefInterface.Name = "menuControlRefInterface";
|
||||
this.menuControlRefInterface.Size = new System.Drawing.Size(192, 22);
|
||||
this.menuControlRefInterface.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuControlRefInterface.Text = "获取网络接口(&I)";
|
||||
this.menuControlRefInterface.Click += new System.EventHandler(this.menuControlRefInterface_Click);
|
||||
//
|
||||
// menuControlEnv
|
||||
//
|
||||
this.menuControlEnv.Name = "menuControlEnv";
|
||||
this.menuControlEnv.Size = new System.Drawing.Size(192, 22);
|
||||
this.menuControlEnv.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuControlEnv.Text = "运行环境检测(&T)";
|
||||
//
|
||||
// menuControlSetCliParams
|
||||
//
|
||||
this.menuControlSetCliParams.Name = "menuControlSetCliParams";
|
||||
this.menuControlSetCliParams.Size = new System.Drawing.Size(192, 22);
|
||||
this.menuControlSetCliParams.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuControlSetCliParams.Text = "设置隧道参数(&N)";
|
||||
this.menuControlSetCliParams.Click += new System.EventHandler(this.menuControlSetCliParams_Click);
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
this.toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
this.toolStripSeparator2.Size = new System.Drawing.Size(189, 6);
|
||||
this.toolStripSeparator2.Size = new System.Drawing.Size(177, 6);
|
||||
//
|
||||
// menuControlService
|
||||
//
|
||||
|
@ -194,7 +193,7 @@
|
|||
this.menuControlSvrStart,
|
||||
this.menuControlSvrStop});
|
||||
this.menuControlService.Name = "menuControlService";
|
||||
this.menuControlService.Size = new System.Drawing.Size(192, 22);
|
||||
this.menuControlService.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuControlService.Text = "隧道服务管理(&V)";
|
||||
//
|
||||
// menuControlSvrStart
|
||||
|
@ -217,20 +216,20 @@
|
|||
this.menuControlHeartStart,
|
||||
this.menuControlHeartStop});
|
||||
this.menuControlHeart.Name = "menuControlHeart";
|
||||
this.menuControlHeart.Size = new System.Drawing.Size(192, 22);
|
||||
this.menuControlHeart.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuControlHeart.Text = "心跳服务管理(&H)";
|
||||
//
|
||||
// menuControlHeartStart
|
||||
//
|
||||
this.menuControlHeartStart.Name = "menuControlHeartStart";
|
||||
this.menuControlHeartStart.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuControlHeartStart.Size = new System.Drawing.Size(148, 22);
|
||||
this.menuControlHeartStart.Text = "启动心跳服务";
|
||||
this.menuControlHeartStart.Click += new System.EventHandler(this.menuControlHeartStart_Click);
|
||||
//
|
||||
// menuControlHeartStop
|
||||
//
|
||||
this.menuControlHeartStop.Name = "menuControlHeartStop";
|
||||
this.menuControlHeartStop.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuControlHeartStop.Size = new System.Drawing.Size(148, 22);
|
||||
this.menuControlHeartStop.Text = "停止心跳服务";
|
||||
this.menuControlHeartStop.Click += new System.EventHandler(this.menuControlHeartStop_Click);
|
||||
//
|
||||
|
@ -242,23 +241,12 @@
|
|||
this.menuSetModeShareServer,
|
||||
this.toolStripSeparator1,
|
||||
this.menuSetVPN,
|
||||
this.menuSetExitToTray});
|
||||
this.menuSetExitToTray,
|
||||
this.menuSetShareMode});
|
||||
this.menuMainSet.Name = "menuMainSet";
|
||||
this.menuMainSet.Size = new System.Drawing.Size(59, 21);
|
||||
this.menuMainSet.Text = "设置(&S)";
|
||||
//
|
||||
// menuSetModeShareNet
|
||||
//
|
||||
this.menuSetModeShareNet.Name = "menuSetModeShareNet";
|
||||
this.menuSetModeShareNet.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuSetModeShareNet.Text = "共享网络";
|
||||
//
|
||||
// menuSetModeShareServer
|
||||
//
|
||||
this.menuSetModeShareServer.Name = "menuSetModeShareServer";
|
||||
this.menuSetModeShareServer.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuSetModeShareServer.Text = "云电脑服务器";
|
||||
//
|
||||
// menuSetMode
|
||||
//
|
||||
this.menuSetMode.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
|
@ -284,6 +272,18 @@
|
|||
this.menuSetModeServer.Text = "服务端";
|
||||
this.menuSetModeServer.Click += new System.EventHandler(this.menuSetModeServer_Click);
|
||||
//
|
||||
// menuSetModeShareNet
|
||||
//
|
||||
this.menuSetModeShareNet.Name = "menuSetModeShareNet";
|
||||
this.menuSetModeShareNet.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuSetModeShareNet.Text = "共享网络";
|
||||
//
|
||||
// menuSetModeShareServer
|
||||
//
|
||||
this.menuSetModeShareServer.Name = "menuSetModeShareServer";
|
||||
this.menuSetModeShareServer.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuSetModeShareServer.Text = "云电脑服务器";
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
this.toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
|
@ -300,7 +300,7 @@
|
|||
// menuSetVPNPath
|
||||
//
|
||||
this.menuSetVPNPath.Name = "menuSetVPNPath";
|
||||
this.menuSetVPNPath.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuSetVPNPath.Size = new System.Drawing.Size(124, 22);
|
||||
this.menuSetVPNPath.Text = "安装路径";
|
||||
this.menuSetVPNPath.Click += new System.EventHandler(this.menuSetVPNPath_Click);
|
||||
//
|
||||
|
@ -312,6 +312,31 @@
|
|||
this.menuSetExitToTray.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuSetExitToTray.Text = "退出时最小化(&M)";
|
||||
//
|
||||
// menuSetShareMode
|
||||
//
|
||||
this.menuSetShareMode.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.menuSetShareModeICS,
|
||||
this.menuSetShareModeNAT});
|
||||
this.menuSetShareMode.Name = "menuSetShareMode";
|
||||
this.menuSetShareMode.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuSetShareMode.Text = "网络共享模式";
|
||||
//
|
||||
// menuSetShareModeICS
|
||||
//
|
||||
this.menuSetShareModeICS.Checked = true;
|
||||
this.menuSetShareModeICS.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.menuSetShareModeICS.Name = "menuSetShareModeICS";
|
||||
this.menuSetShareModeICS.Size = new System.Drawing.Size(194, 22);
|
||||
this.menuSetShareModeICS.Text = "Intelnet连接共享(ICS)";
|
||||
this.menuSetShareModeICS.Click += new System.EventHandler(this.menuSetShareModeICS_Click);
|
||||
//
|
||||
// menuSetShareModeNAT
|
||||
//
|
||||
this.menuSetShareModeNAT.Name = "menuSetShareModeNAT";
|
||||
this.menuSetShareModeNAT.Size = new System.Drawing.Size(194, 22);
|
||||
this.menuSetShareModeNAT.Text = "网络地址转换(NAT)";
|
||||
this.menuSetShareModeNAT.Click += new System.EventHandler(this.menuSetShareModeNAT_Click);
|
||||
//
|
||||
// menuMainHelp
|
||||
//
|
||||
this.menuMainHelp.Name = "menuMainHelp";
|
||||
|
@ -358,67 +383,46 @@
|
|||
this.toolStripSeparator3,
|
||||
this.trapMenuExit});
|
||||
this.trapMenuMain.Name = "trapMenuMain";
|
||||
this.trapMenuMain.Size = new System.Drawing.Size(181, 126);
|
||||
this.trapMenuMain.Size = new System.Drawing.Size(137, 104);
|
||||
this.trapMenuMain.UseWaitCursor = true;
|
||||
//
|
||||
// trapMenuShowMainWnd
|
||||
//
|
||||
this.trapMenuShowMainWnd.Name = "trapMenuShowMainWnd";
|
||||
this.trapMenuShowMainWnd.Size = new System.Drawing.Size(180, 22);
|
||||
this.trapMenuShowMainWnd.Size = new System.Drawing.Size(136, 22);
|
||||
this.trapMenuShowMainWnd.Text = "显示主界面";
|
||||
this.trapMenuShowMainWnd.Click += new System.EventHandler(this.trapMenuShowMainWnd_Click);
|
||||
//
|
||||
// trapMenuHideMain
|
||||
//
|
||||
this.trapMenuHideMain.Name = "trapMenuHideMain";
|
||||
this.trapMenuHideMain.Size = new System.Drawing.Size(180, 22);
|
||||
this.trapMenuHideMain.Size = new System.Drawing.Size(136, 22);
|
||||
this.trapMenuHideMain.Text = "隐藏主界面";
|
||||
this.trapMenuHideMain.Click += new System.EventHandler(this.trapMenuHideMain_Click);
|
||||
//
|
||||
// toolStripSeparator5
|
||||
//
|
||||
this.toolStripSeparator5.Name = "toolStripSeparator5";
|
||||
this.toolStripSeparator5.Size = new System.Drawing.Size(177, 6);
|
||||
this.toolStripSeparator5.Size = new System.Drawing.Size(133, 6);
|
||||
//
|
||||
// trapMenuSysInterface
|
||||
//
|
||||
this.trapMenuSysInterface.Name = "trapMenuSysInterface";
|
||||
this.trapMenuSysInterface.Size = new System.Drawing.Size(180, 22);
|
||||
this.trapMenuSysInterface.Size = new System.Drawing.Size(136, 22);
|
||||
this.trapMenuSysInterface.Text = "共享网络";
|
||||
//
|
||||
// toolStripSeparator3
|
||||
//
|
||||
this.toolStripSeparator3.Name = "toolStripSeparator3";
|
||||
this.toolStripSeparator3.Size = new System.Drawing.Size(177, 6);
|
||||
this.toolStripSeparator3.Size = new System.Drawing.Size(133, 6);
|
||||
//
|
||||
// trapMenuExit
|
||||
//
|
||||
this.trapMenuExit.Name = "trapMenuExit";
|
||||
this.trapMenuExit.Size = new System.Drawing.Size(180, 22);
|
||||
this.trapMenuExit.Size = new System.Drawing.Size(136, 22);
|
||||
this.trapMenuExit.Text = "退出程序";
|
||||
this.trapMenuExit.Click += new System.EventHandler(this.trapMenuExit_Click);
|
||||
//
|
||||
// menuControlNetMode
|
||||
//
|
||||
this.menuControlNetMode.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.menuControlNetModePrivate,
|
||||
this.menuControlNetModePublic});
|
||||
this.menuControlNetMode.Name = "menuControlNetMode";
|
||||
this.menuControlNetMode.Size = new System.Drawing.Size(192, 22);
|
||||
this.menuControlNetMode.Text = "隧道网络模式设置(&M)";
|
||||
//
|
||||
// menuControlNetModePrivate
|
||||
//
|
||||
this.menuControlNetModePrivate.Name = "menuControlNetModePrivate";
|
||||
this.menuControlNetModePrivate.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuControlNetModePrivate.Text = "专用网络 (Private)";
|
||||
//
|
||||
// menuControlNetModePublic
|
||||
//
|
||||
this.menuControlNetModePublic.Name = "menuControlNetModePublic";
|
||||
this.menuControlNetModePublic.Size = new System.Drawing.Size(180, 22);
|
||||
this.menuControlNetModePublic.Text = "公共网络 (Public)";
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
|
@ -486,9 +490,9 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem menuControlHeart;
|
||||
private System.Windows.Forms.ToolStripMenuItem menuControlHeartStart;
|
||||
private System.Windows.Forms.ToolStripMenuItem menuControlHeartStop;
|
||||
private System.Windows.Forms.ToolStripMenuItem menuControlNetMode;
|
||||
private System.Windows.Forms.ToolStripMenuItem menuControlNetModePrivate;
|
||||
private System.Windows.Forms.ToolStripMenuItem menuControlNetModePublic;
|
||||
private System.Windows.Forms.ToolStripMenuItem menuSetShareMode;
|
||||
private System.Windows.Forms.ToolStripMenuItem menuSetShareModeICS;
|
||||
private System.Windows.Forms.ToolStripMenuItem menuSetShareModeNAT;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,8 +63,8 @@ public partial class MainForm : Form
|
|||
|
||||
var path = Environment.CurrentDirectory + "\\tunnelsdk_" +
|
||||
string.Format("{0:yyyyMMdd}", DateTime.Now) + ".log";
|
||||
NetTunnelLib.InitTunnelSDKLog(path, LogLevel.LOG_DEBUG);
|
||||
NetTunnelLib.TunnelSDKInitEnv(Environment.CurrentDirectory, "http://xajhuang.com:9276", menuSetModeServer.Checked);
|
||||
//NetTunnelLib.InitTunnelSDKLog(path, LogLevel.LOG_DEBUG);
|
||||
NetTunnelLib.TunnelSDKInitEnv(Environment.CurrentDirectory, "http://xajhuang.com:9276", path, LogLevel.LOG_DEBUG, menuSetModeServer.Checked);
|
||||
|
||||
GetCurrentNetCard();
|
||||
|
||||
|
@ -227,32 +227,14 @@ public partial class MainForm : Form
|
|||
|
||||
private void menuSetModeClient_Click(object sender, EventArgs e)
|
||||
{
|
||||
var o = (ToolStripMenuItem)sender;
|
||||
if (o.Checked)
|
||||
{
|
||||
o.Checked = false;
|
||||
menuSetModeServer.Checked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
o.Checked = true;
|
||||
menuSetModeServer.Checked = false;
|
||||
}
|
||||
menuSetModeClient.Checked = true;
|
||||
menuSetModeServer.Checked = false;
|
||||
}
|
||||
|
||||
private void menuSetModeServer_Click(object sender, EventArgs e)
|
||||
{
|
||||
var o = (ToolStripMenuItem)sender;
|
||||
if (o.Checked)
|
||||
{
|
||||
o.Checked = false;
|
||||
menuSetModeClient.Checked = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
o.Checked = true;
|
||||
menuSetModeClient.Checked = false;
|
||||
}
|
||||
menuSetModeServer.Checked = true;
|
||||
menuSetModeClient.Checked = false;
|
||||
}
|
||||
|
||||
private void MainForm_SizeChanged(object sender, EventArgs e)
|
||||
|
@ -375,7 +357,7 @@ public partial class MainForm : Form
|
|||
return;
|
||||
}
|
||||
|
||||
IPNetwork ipnetwork = IPNetwork.Parse(c?.IpAddr, c?.NetMask);
|
||||
IPNetwork ipnetwork = IPNetwork.Parse("172.18.2.152", "255.255.255.0");
|
||||
//IPNetwork cliNetwork = IPNetwork.Parse(_userConfig.cliAddress);
|
||||
|
||||
//MessageBox.Show(ipnetwork.Value);
|
||||
|
@ -462,4 +444,18 @@ public partial class MainForm : Form
|
|||
MessageBox.Show("Error: " + ret.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void menuSetShareModeICS_Click(object sender, EventArgs e)
|
||||
{
|
||||
menuSetShareModeNAT.Checked = false;
|
||||
menuSetShareModeICS.Checked = true;
|
||||
NetTunnelLib.SetCurrentNetShareMode(NET_SHARE_MODE.ICS_SHARE_MODE);
|
||||
}
|
||||
|
||||
private void menuSetShareModeNAT_Click(object sender, EventArgs e)
|
||||
{
|
||||
menuSetShareModeICS.Checked = false;
|
||||
menuSetShareModeNAT.Checked = true;
|
||||
NetTunnelLib.SetCurrentNetShareMode(NET_SHARE_MODE.NAT_SHARE_MODE);
|
||||
}
|
||||
}
|
|
@ -26,6 +26,15 @@ public enum LogLevel
|
|||
LOG_OFF
|
||||
}
|
||||
|
||||
public enum NET_SHARE_MODE
|
||||
{
|
||||
///< Internet Share Mode(ICS) 模式
|
||||
ICS_SHARE_MODE = 0,
|
||||
|
||||
///< Net Address Translation(NAT) 模式
|
||||
NAT_SHARE_MODE = 1
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public struct VirtualMathineConfig
|
||||
{
|
||||
|
@ -164,7 +173,8 @@ public struct WgCliConfig
|
|||
public class NetTunnelLib
|
||||
{
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int TunnelSDKInitEnv(String workDir, String svrUrl, bool isWorkServer);
|
||||
public static extern int TunnelSDKInitEnv(String workDir, String svrUrl, String pLogFile, LogLevel level,
|
||||
bool isWorkServer);
|
||||
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void TunnelSDKUnInit();
|
||||
|
@ -172,9 +182,6 @@ 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 void InitTunnelSDKLog(String pProKey, LogLevel level);
|
||||
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int FindWireguardExe(StringBuilder lpString, int maxSize);
|
||||
|
||||
|
@ -210,7 +217,8 @@ public class NetTunnelLib
|
|||
public static extern int RemoteCtrlSvrCfgUserTunnel(int vmid, String cliNetwork);
|
||||
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int SetTunnelConfigure(String cliPrivateKey, String svrPublicKey, String svrNetwork, String cliNetwork, String svrAddr);
|
||||
public static extern int SetTunnelConfigure(String cliPrivateKey, String svrPublicKey, String svrNetwork,
|
||||
String cliNetwork, String svrAddr);
|
||||
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int RemoteWireGuardControl(bool startOrStop);
|
||||
|
@ -221,6 +229,12 @@ public class NetTunnelLib
|
|||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int RemoteHeartControl(bool startOrStop, HeartCallBack cb);
|
||||
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern NET_SHARE_MODE GetCurrentNetShareMode();
|
||||
|
||||
[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void SetCurrentNetShareMode(NET_SHARE_MODE shareMode);
|
||||
|
||||
//[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
//public static extern int RunPipeCmd(String pszCmd, StringBuilder pszResultBuffer, int dwResultBufferSize);
|
||||
}
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include "globalcfg.h"
|
||||
#include "httplib.h"
|
||||
#include "misc.h"
|
||||
#include "network.h"
|
||||
#include "protocol.h"
|
||||
#include "usrerr.h"
|
||||
#include "user.h"
|
||||
|
@ -47,7 +49,8 @@ static void HttpResponseError(httplib::Response &pRes, int errCode, const TCHAR
|
|||
}
|
||||
|
||||
int CreateControlService(PUSER_SERVER_CONFIG pSvr) {
|
||||
static WGSERVER_CONFIG g_curCliConfig = {};
|
||||
static TCHAR g_CliNetwork[MAX_IP_LEN] = {};
|
||||
static WGSERVER_CONFIG g_curCliConfig = {};
|
||||
static std::mutex g_InterfaceMutex;
|
||||
DWORD dwStatus = 0;
|
||||
|
||||
|
@ -144,6 +147,10 @@ int CreateControlService(PUSER_SERVER_CONFIG pSvr) {
|
|||
// 当前服务状态和需要执行的操作不同
|
||||
if (isSvrStart != reqData.msgContent.isStart) {
|
||||
if (reqData.msgContent.isStart) {
|
||||
IP_INFO cliInfo;
|
||||
IP_INFO tunnelInfo;
|
||||
int retry = 3;
|
||||
|
||||
// 启动服务
|
||||
ret = WireGuardInstallDefaultServerService(true);
|
||||
if (ret != ERR_SUCCESS) {
|
||||
|
@ -153,6 +160,39 @@ int CreateControlService(PUSER_SERVER_CONFIG pSvr) {
|
|||
g_InterfaceMutex.unlock();
|
||||
return;
|
||||
}
|
||||
// 添加路由
|
||||
if ((ret = GetIpV4InfoFromCIDR(g_CliNetwork, &cliInfo)) != ERR_SUCCESS) {
|
||||
// 返回启动服务失败
|
||||
SPDLOG_ERROR(TEXT("GetIpV4InfoFromCIDR ({1}) error: {0}"), ret, g_CliNetwork);
|
||||
HttpResponseError(res, ret, TEXT("Parse IpAddress error."));
|
||||
g_InterfaceMutex.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ret = GetIpV4InfoFromCIDR(g_UserSvrCfg.svrAddress, &tunnelInfo)) != ERR_SUCCESS) {
|
||||
// 返回启动服务失败
|
||||
SPDLOG_ERROR(TEXT("GetIpV4InfoFromCIDR ({1}) error: {0}"), ret, g_UserSvrCfg.svrAddress);
|
||||
HttpResponseError(res, ret, TEXT("Parse tunnel ip address error."));
|
||||
g_InterfaceMutex.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = AddRouteTable(cliInfo.ip, cliInfo.netmask, tunnelInfo.ip);
|
||||
Sleep(1000);
|
||||
} while (ret != ERR_SUCCESS && retry--);
|
||||
|
||||
if (ret != ERR_SUCCESS) {
|
||||
// 返回启动服务失败
|
||||
SPDLOG_ERROR(TEXT("Add Route {1}/{2} gateway {3} error: {0}"),
|
||||
ret,
|
||||
cliInfo.ip,
|
||||
cliInfo.netmask,
|
||||
tunnelInfo.ip);
|
||||
HttpResponseError(res, ret, TEXT("Parse tunnel ip address error."));
|
||||
g_InterfaceMutex.unlock();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if ((ret = WireGuardUnInstallServerService(GetGlobalCfgInfo()->userCfg.userName)) != ERR_SUCCESS) {
|
||||
// 返回停止服务失败
|
||||
|
@ -208,6 +248,7 @@ int CreateControlService(PUSER_SERVER_CONFIG pSvr) {
|
|||
StringCbCopy(g_curCliConfig.Address, 32, g_UserSvrCfg.svrAddress);
|
||||
StringCbCopy(g_curCliConfig.PrivateKey, 64, g_UserSvrCfg.svrPrivateKey);
|
||||
StringCbCopy(g_curCliConfig.CliPubKey, 64, reqData.msgContent.cliPublicKey.c_str());
|
||||
StringCbCopy(g_CliNetwork, MAX_IP_LEN, reqData.msgContent.cliNetwork.c_str());
|
||||
StringCbPrintf(g_curCliConfig.AllowNet,
|
||||
256,
|
||||
TEXT("%s,%s"),
|
||||
|
|
|
@ -119,6 +119,7 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>.\WinDivert\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>copy /y $(TargetDir)*.dll $(SolutionDir)\NetTunnelApp\bin\$(ConfigurationName)\
|
||||
|
@ -160,6 +161,7 @@
|
|||
<ClInclude Include="tunnel.h" />
|
||||
<ClInclude Include="user.h" />
|
||||
<ClInclude Include="usrerr.h" />
|
||||
<ClInclude Include="WinDivert\include\windivert.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ControlService.cpp" />
|
||||
|
@ -177,6 +179,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="protocol.cpp" />
|
||||
<ClCompile Include="ProtocolBase.cpp" />
|
||||
<ClCompile Include="ProxyService.cpp" />
|
||||
<ClCompile Include="tunnel.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
|
|
|
@ -78,6 +78,9 @@
|
|||
<ClInclude Include="httplib.h">
|
||||
<Filter>头文件\http</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WinDivert\include\windivert.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
|
@ -119,6 +122,9 @@
|
|||
<ClCompile Include="ipcalc.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ProxyService.cpp">
|
||||
<Filter>源文件\network</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
|
|
@ -0,0 +1,377 @@
|
|||
#include "pch.h"
|
||||
#include "WinDivert/include/windivert.h"
|
||||
|
||||
#include <strsafe.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#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;
|
||||
HANDLE proxyHandle;
|
||||
bool isExitSvr;
|
||||
} 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() {
|
||||
int ret;
|
||||
static HANDLE hDriver;
|
||||
PPROXY_INFO pInfo;
|
||||
std::string key;
|
||||
std::unordered_map<std::string, PPROXY_INFO>::iterator iter;
|
||||
|
||||
// 查找先前代理是否存在
|
||||
key = std::string(pTargetIp) + ":" + std::to_string(targetPort);
|
||||
|
||||
if ((iter = g_ProxyColleagues.find(key)) != g_ProxyColleagues.end()) {
|
||||
pInfo = iter->second;
|
||||
// 如果配置完全相同则直接返回
|
||||
if (pInfo->vmId == vmId && pInfo->svrId == svrId && pInfo->proType == proType) {
|
||||
return ERR_SUCCESS;
|
||||
} else {
|
||||
pInfo->vmId = vmId;
|
||||
pInfo->svrId = svrId;
|
||||
pInfo->proType = proType;
|
||||
}
|
||||
} else {
|
||||
// 创建新的代理配置
|
||||
pInfo = static_cast<PPROXY_INFO>(HeapAlloc(GetProcessHeap(), 0, sizeof(PROXY_INFO)));
|
||||
|
||||
if (pInfo == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Error allocating {0} bytes memory "), sizeof(PROXY_INFO));
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
|
||||
memset(pInfo, 0, sizeof(PROXY_INFO));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
hDriver = WinDivertOpen(pInfo->streamFilter, WINDIVERT_LAYER_NETWORK, 0, 0);
|
||||
|
||||
if (hDriver == INVALID_HANDLE_VALUE) {
|
||||
//ERROR_INSUFFICIENT_BUFFER
|
||||
SPDLOG_ERROR(TEXT("Open Driver With Filter \"{1}\" Error: {0}"), GetLastError(), pInfo->streamFilter);
|
||||
return -ERR_SYS_CALL;
|
||||
}
|
||||
|
||||
CreateThread(
|
||||
nullptr, // Thread attributes
|
||||
0, // Stack size (0 = use default)
|
||||
[](LPVOID lpParameter) {
|
||||
const HANDLE h = lpParameter;
|
||||
unsigned char packet[0xFFFF];
|
||||
UINT packet_len;
|
||||
WINDIVERT_ADDRESS addr;
|
||||
|
||||
while (true) {
|
||||
if (!WinDivertRecv(h, packet, 0xFFFF, &packet_len, &addr)) {
|
||||
SPDLOG_ERROR(TEXT("failed to read packet ({0})"), GetLastError());
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (addr.Event) {
|
||||
case WINDIVERT_EVENT_SOCKET_BIND:
|
||||
SPDLOG_ERROR("BIND");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_LISTEN:
|
||||
|
||||
SPDLOG_ERROR("LISTEN");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_CONNECT:
|
||||
|
||||
SPDLOG_ERROR("CONNECT: {0:x}, {1:x}", addr.Socket.EndpointId, addr.Socket.ParentEndpointId);
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_ACCEPT:
|
||||
|
||||
SPDLOG_ERROR("ACCEPT");
|
||||
break;
|
||||
case WINDIVERT_EVENT_SOCKET_CLOSE:
|
||||
|
||||
SPDLOG_ERROR("CLOSE: {0:x}, {1:x}", addr.Socket.EndpointId, addr.Socket.ParentEndpointId);
|
||||
break;
|
||||
default:
|
||||
SPDLOG_ERROR(TEXT("***({0})"), static_cast<int>(addr.Event));
|
||||
break;
|
||||
}
|
||||
|
||||
/*if (!WinDivertSendEx(h, packet, packet_len, nullptr, 0, &addr, sizeof(WINDIVERT_ADDRESS), nullptr)) {
|
||||
SPDLOG_ERROR(TEXT("warning: failed to reinject packet ({0})\n"), GetLastError());
|
||||
}*/
|
||||
}
|
||||
|
||||
return static_cast<DWORD>(0);
|
||||
}, // Thread start address
|
||||
hDriver, // Parameter to pass to the thread
|
||||
0, // Creation flags
|
||||
nullptr); // Thread id
|
||||
return 0;
|
||||
}
|
|
@ -94,6 +94,13 @@ int RemoteWireGuardControl(bool isStart) {
|
|||
int LocalWireGuardControl(bool isStart, bool setPrivateMode) {
|
||||
int ret;
|
||||
bool chkStatus = false;
|
||||
int ifInetlnetIndex, ifWireGuardIndex;
|
||||
|
||||
// 获取 Intelnet 网络网卡 Index
|
||||
if ((ret = GetInternetIfIndex(&ifInetlnetIndex)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call GetInternetIfIndex error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 判断先前是否启动过服务
|
||||
if ((ret = IsWireGuardServerRunning(GetGlobalCfgInfo()->userCfg.userName, &chkStatus)) != ERR_SUCCESS) {
|
||||
|
@ -101,6 +108,7 @@ int LocalWireGuardControl(bool isStart, bool setPrivateMode) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
// 先停止以前启动的隧道服务
|
||||
if (chkStatus) {
|
||||
if ((ret = WireGuardUnInstallServerService(GetGlobalCfgInfo()->userCfg.userName)) != ERR_SUCCESS) {
|
||||
// 返回停止服务失败
|
||||
|
@ -109,6 +117,20 @@ int LocalWireGuardControl(bool isStart, bool setPrivateMode) {
|
|||
}
|
||||
}
|
||||
|
||||
// 检查 Internet 网络共享状态
|
||||
if ((ret = GetNetIntelnetConnectionSharing(ifInetlnetIndex, &chkStatus)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call GetNetIntelnetConnectionSharing error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 关闭 Intelnet 网络连接共享
|
||||
if (chkStatus) {
|
||||
if ((ret = SetNetIntelnetConnectionSharing(ifInetlnetIndex, false, false)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call SetNetIntelnetConnectionSharing error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (isStart) {
|
||||
// 启动服务
|
||||
ret = WireGuardInstallDefaultServerService(true);
|
||||
|
@ -118,19 +140,78 @@ int LocalWireGuardControl(bool isStart, bool setPrivateMode) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = GetNetConnectionNetworkCategory(GetGlobalCfgInfo()->userCfg.userName, &chkStatus)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call GetNetConnectionNetworkCategory error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 检查网卡模式是否和设定值一致
|
||||
if (setPrivateMode != chkStatus) {
|
||||
if ((ret = SetNetConnectionNetworkCategory(GetGlobalCfgInfo()->userCfg.userName, setPrivateMode)) !=
|
||||
if (GetCurrentNetShareMode() == ICS_SHARE_MODE) {
|
||||
// 获取 WireGuard 隧道网络网卡 Index
|
||||
if ((ret = GetInterfaceIfIndexByName(GetGlobalCfgInfo()->userCfg.userName, &ifWireGuardIndex)) !=
|
||||
ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call SetNetConnectionNetworkCategory error: {0}"), ret);
|
||||
SPDLOG_ERROR(TEXT("Call GetInterfaceIfIndexByName error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 启动 WireGard 网络 ICS 服务为私有网络
|
||||
if ((ret = SetNetIntelnetConnectionSharing(ifWireGuardIndex, true, true)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call SetNetIntelnetConnectionSharing error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 启动 Intelnet 网络 ICS 服务为公共网络
|
||||
if ((ret = SetNetIntelnetConnectionSharing(ifInetlnetIndex, true, false)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call SetNetIntelnetConnectionSharing error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 校验 ICS 共享状态
|
||||
// 检查 WireGuard 网络共享状态
|
||||
if ((ret = GetNetIntelnetConnectionSharing(ifWireGuardIndex, &chkStatus)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call GetNetIntelnetConnectionSharing error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!chkStatus) {
|
||||
SPDLOG_ERROR(TEXT("WireGuard network ICS error"));
|
||||
return -ERR_NET_WIREGUARD_ICS;
|
||||
}
|
||||
|
||||
// 检查 WireGuard 网络共享状态
|
||||
if ((ret = GetNetIntelnetConnectionSharing(ifInetlnetIndex, &chkStatus)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call GetNetIntelnetConnectionSharing error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!chkStatus) {
|
||||
SPDLOG_ERROR(TEXT("Internet network ICS error"));
|
||||
return -ERR_NET_WIREGUARD_ICS;
|
||||
}
|
||||
|
||||
SPDLOG_INFO(TEXT("Net Share Service Work now on ICS mode: {0}"), GetGlobalCfgInfo()->userCfg.userName);
|
||||
} else if (GetCurrentNetShareMode() == NAT_SHARE_MODE) {
|
||||
IP_INFO ipInfo;
|
||||
TCHAR ipNat[MAX_IP_LEN];
|
||||
GetIpV4InfoFromCIDR(GetGlobalCfgInfo()->userCfg.cliConfig.cliAddress, &ipInfo);
|
||||
StringCbPrintf(ipNat, MAX_IP_LEN, TEXT("%s/%d"), ipInfo.hostmax, ipInfo.prefix);
|
||||
|
||||
// 检查 WireGuard 网络共享状态
|
||||
if ((ret = SetNATRule(GetGlobalCfgInfo()->userCfg.userName, ipNat)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call GetNetIntelnetConnectionSharing error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SPDLOG_INFO(TEXT("Net Share Service Work now on NAT mode: {0}_nat --> {1}"),
|
||||
GetGlobalCfgInfo()->userCfg.userName,
|
||||
ipNat);
|
||||
} else {
|
||||
SPDLOG_ERROR(TEXT("Not support Net Share Type: {0}"), static_cast<int>(GetCurrentNetShareMode()));
|
||||
return -ERR_UN_SUPPORT;
|
||||
}
|
||||
} else {
|
||||
if (GetCurrentNetShareMode() == NAT_SHARE_MODE) {
|
||||
// 检查 WireGuard 网络共享状态
|
||||
if ((ret = RemoveNATRule(GetGlobalCfgInfo()->userCfg.userName)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call RemoveNATRule error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
SPDLOG_INFO(TEXT("Net Share Service Stoped: {0}"), GetGlobalCfgInfo()->userCfg.userName);
|
||||
}
|
||||
|
||||
return ERR_SUCCESS;
|
||||
|
@ -176,6 +257,13 @@ int RemoteCtrlSvrCfgUserTunnel(int vmId, const TCHAR *pCliNetwork) {
|
|||
pUserCfg->cliAddress,
|
||||
rsp.msgContent.svrNetwork.c_str(),
|
||||
pUserCfg->pVMConfig[i].scgTunnelGw);
|
||||
|
||||
if (ret != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("SetTunnelConfigure Error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GetGlobalCfgInfo()->curConnVmId = vmId;
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -191,6 +279,7 @@ int SetTunnelConfigure(const TCHAR *pCliPrivateKey,
|
|||
const TCHAR *pSvrEndPoint) {
|
||||
int ret;
|
||||
bool isSvrStart = false;
|
||||
int ifInetlnetIndex;
|
||||
IP_INFO tunnelInfo = {};
|
||||
IP_INFO svrInfo = {};
|
||||
WGCLIENT_CONFIG cliCfg = {};
|
||||
|
@ -245,6 +334,38 @@ int SetTunnelConfigure(const TCHAR *pCliPrivateKey,
|
|||
}
|
||||
}
|
||||
|
||||
// 获取 Intelnet 网络网卡 Index
|
||||
if ((ret = GetInternetIfIndex(&ifInetlnetIndex)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call GetInternetIfIndex error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (GetCurrentNetShareMode() == ICS_SHARE_MODE) {
|
||||
// 检查 Internet 网络共享状态
|
||||
if ((ret = GetNetIntelnetConnectionSharing(ifInetlnetIndex, &isSvrStart)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call GetNetIntelnetConnectionSharing error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// 关闭 Intelnet 网络连接共享
|
||||
if (isSvrStart) {
|
||||
if ((ret = SetNetIntelnetConnectionSharing(ifInetlnetIndex, false, false)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call SetNetIntelnetConnectionSharing error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (GetCurrentNetShareMode() == NAT_SHARE_MODE) {
|
||||
// 清理旧的 NAT 配置
|
||||
if ((ret = RemoveNATRule(GetGlobalCfgInfo()->userCfg.userName)) != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Call GetNetIntelnetConnectionSharing error: {0}"), ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = GetIpV4InfoFromCIDR(pSvrTunnelAddr, &tunnelInfo);
|
||||
|
||||
if (ret != ERR_SUCCESS) {
|
||||
|
|
|
@ -0,0 +1,630 @@
|
|||
/*
|
||||
* windivert.h
|
||||
* (C) 2019, all rights reserved,
|
||||
*
|
||||
* This file is part of WinDivert.
|
||||
*
|
||||
* WinDivert is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* WinDivert is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __WINDIVERT_H
|
||||
#define __WINDIVERT_H
|
||||
|
||||
#ifndef WINDIVERT_KERNEL
|
||||
#include <windows.h>
|
||||
#endif /* WINDIVERT_KERNEL */
|
||||
|
||||
#ifndef WINDIVERTEXPORT
|
||||
#define WINDIVERTEXPORT extern __declspec(dllimport)
|
||||
#endif /* WINDIVERTEXPORT */
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#define __in
|
||||
#define __in_opt
|
||||
#define __out
|
||||
#define __out_opt
|
||||
#define __inout
|
||||
#define __inout_opt
|
||||
#include <stdint.h>
|
||||
#define INT8 int8_t
|
||||
#define UINT8 uint8_t
|
||||
#define INT16 int16_t
|
||||
#define UINT16 uint16_t
|
||||
#define INT32 int32_t
|
||||
#define UINT32 uint32_t
|
||||
#define INT64 int64_t
|
||||
#define UINT64 uint64_t
|
||||
#endif /* __MINGW32__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/* WINDIVERT API */
|
||||
/****************************************************************************/
|
||||
|
||||
/*
|
||||
* WinDivert layers.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
WINDIVERT_LAYER_NETWORK = 0, /* Network layer. */
|
||||
WINDIVERT_LAYER_NETWORK_FORWARD = 1,/* Network layer (forwarded packets) */
|
||||
WINDIVERT_LAYER_FLOW = 2, /* Flow layer. */
|
||||
WINDIVERT_LAYER_SOCKET = 3, /* Socket layer. */
|
||||
WINDIVERT_LAYER_REFLECT = 4, /* Reflect layer. */
|
||||
} WINDIVERT_LAYER, *PWINDIVERT_LAYER;
|
||||
|
||||
/*
|
||||
* WinDivert NETWORK and NETWORK_FORWARD layer data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT32 IfIdx; /* Packet's interface index. */
|
||||
UINT32 SubIfIdx; /* Packet's sub-interface index. */
|
||||
} WINDIVERT_DATA_NETWORK, *PWINDIVERT_DATA_NETWORK;
|
||||
|
||||
/*
|
||||
* WinDivert FLOW layer data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT64 EndpointId; /* Endpoint ID. */
|
||||
UINT64 ParentEndpointId; /* Parent endpoint ID. */
|
||||
UINT32 ProcessId; /* Process ID. */
|
||||
UINT32 LocalAddr[4]; /* Local address. */
|
||||
UINT32 RemoteAddr[4]; /* Remote address. */
|
||||
UINT16 LocalPort; /* Local port. */
|
||||
UINT16 RemotePort; /* Remote port. */
|
||||
UINT8 Protocol; /* Protocol. */
|
||||
} WINDIVERT_DATA_FLOW, *PWINDIVERT_DATA_FLOW;
|
||||
|
||||
/*
|
||||
* WinDivert SOCKET layer data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT64 EndpointId; /* Endpoint ID. */
|
||||
UINT64 ParentEndpointId; /* Parent Endpoint ID. */
|
||||
UINT32 ProcessId; /* Process ID. */
|
||||
UINT32 LocalAddr[4]; /* Local address. */
|
||||
UINT32 RemoteAddr[4]; /* Remote address. */
|
||||
UINT16 LocalPort; /* Local port. */
|
||||
UINT16 RemotePort; /* Remote port. */
|
||||
UINT8 Protocol; /* Protocol. */
|
||||
} WINDIVERT_DATA_SOCKET, *PWINDIVERT_DATA_SOCKET;
|
||||
|
||||
/*
|
||||
* WinDivert REFLECTION layer data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
INT64 Timestamp; /* Handle open time. */
|
||||
UINT32 ProcessId; /* Handle process ID. */
|
||||
WINDIVERT_LAYER Layer; /* Handle layer. */
|
||||
UINT64 Flags; /* Handle flags. */
|
||||
INT16 Priority; /* Handle priority. */
|
||||
} WINDIVERT_DATA_REFLECT, *PWINDIVERT_DATA_REFLECT;
|
||||
|
||||
/*
|
||||
* WinDivert address.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4201)
|
||||
#endif
|
||||
typedef struct
|
||||
{
|
||||
INT64 Timestamp; /* Packet's timestamp. */
|
||||
UINT32 Layer:8; /* Packet's layer. */
|
||||
UINT32 Event:8; /* Packet event. */
|
||||
UINT32 Sniffed:1; /* Packet was sniffed? */
|
||||
UINT32 Outbound:1; /* Packet is outound? */
|
||||
UINT32 Loopback:1; /* Packet is loopback? */
|
||||
UINT32 Impostor:1; /* Packet is impostor? */
|
||||
UINT32 IPv6:1; /* Packet is IPv6? */
|
||||
UINT32 IPChecksum:1; /* Packet has valid IPv4 checksum? */
|
||||
UINT32 TCPChecksum:1; /* Packet has valid TCP checksum? */
|
||||
UINT32 UDPChecksum:1; /* Packet has valid UDP checksum? */
|
||||
UINT32 Reserved1:8;
|
||||
UINT32 Reserved2;
|
||||
union
|
||||
{
|
||||
WINDIVERT_DATA_NETWORK Network; /* Network layer data. */
|
||||
WINDIVERT_DATA_FLOW Flow; /* Flow layer data. */
|
||||
WINDIVERT_DATA_SOCKET Socket; /* Socket layer data. */
|
||||
WINDIVERT_DATA_REFLECT Reflect; /* Reflect layer data. */
|
||||
UINT8 Reserved3[64];
|
||||
};
|
||||
} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS;
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* WinDivert events.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
WINDIVERT_EVENT_NETWORK_PACKET = 0, /* Network packet. */
|
||||
WINDIVERT_EVENT_FLOW_ESTABLISHED = 1,
|
||||
/* Flow established. */
|
||||
WINDIVERT_EVENT_FLOW_DELETED = 2, /* Flow deleted. */
|
||||
WINDIVERT_EVENT_SOCKET_BIND = 3, /* Socket bind. */
|
||||
WINDIVERT_EVENT_SOCKET_CONNECT = 4, /* Socket connect. */
|
||||
WINDIVERT_EVENT_SOCKET_LISTEN = 5, /* Socket listen. */
|
||||
WINDIVERT_EVENT_SOCKET_ACCEPT = 6, /* Socket accept. */
|
||||
WINDIVERT_EVENT_SOCKET_CLOSE = 7, /* Socket close. */
|
||||
WINDIVERT_EVENT_REFLECT_OPEN = 8, /* WinDivert handle opened. */
|
||||
WINDIVERT_EVENT_REFLECT_CLOSE = 9, /* WinDivert handle closed. */
|
||||
} WINDIVERT_EVENT, *PWINDIVERT_EVENT;
|
||||
|
||||
/*
|
||||
* WinDivert flags.
|
||||
*/
|
||||
#define WINDIVERT_FLAG_SNIFF 0x0001
|
||||
#define WINDIVERT_FLAG_DROP 0x0002
|
||||
#define WINDIVERT_FLAG_RECV_ONLY 0x0004
|
||||
#define WINDIVERT_FLAG_READ_ONLY WINDIVERT_FLAG_RECV_ONLY
|
||||
#define WINDIVERT_FLAG_SEND_ONLY 0x0008
|
||||
#define WINDIVERT_FLAG_WRITE_ONLY WINDIVERT_FLAG_SEND_ONLY
|
||||
#define WINDIVERT_FLAG_NO_INSTALL 0x0010
|
||||
#define WINDIVERT_FLAG_FRAGMENTS 0x0020
|
||||
|
||||
/*
|
||||
* WinDivert parameters.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
WINDIVERT_PARAM_QUEUE_LENGTH = 0, /* Packet queue length. */
|
||||
WINDIVERT_PARAM_QUEUE_TIME = 1, /* Packet queue time. */
|
||||
WINDIVERT_PARAM_QUEUE_SIZE = 2, /* Packet queue size. */
|
||||
WINDIVERT_PARAM_VERSION_MAJOR = 3, /* Driver version (major). */
|
||||
WINDIVERT_PARAM_VERSION_MINOR = 4, /* Driver version (minor). */
|
||||
} WINDIVERT_PARAM, *PWINDIVERT_PARAM;
|
||||
#define WINDIVERT_PARAM_MAX WINDIVERT_PARAM_VERSION_MINOR
|
||||
|
||||
/*
|
||||
* WinDivert shutdown parameter.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
WINDIVERT_SHUTDOWN_RECV = 0x1, /* Shutdown recv. */
|
||||
WINDIVERT_SHUTDOWN_SEND = 0x2, /* Shutdown send. */
|
||||
WINDIVERT_SHUTDOWN_BOTH = 0x3, /* Shutdown recv and send. */
|
||||
} WINDIVERT_SHUTDOWN, *PWINDIVERT_SHUTDOWN;
|
||||
#define WINDIVERT_SHUTDOWN_MAX WINDIVERT_SHUTDOWN_BOTH
|
||||
|
||||
#ifndef WINDIVERT_KERNEL
|
||||
|
||||
/*
|
||||
* Open a WinDivert handle.
|
||||
*/
|
||||
WINDIVERTEXPORT HANDLE WinDivertOpen(
|
||||
__in const char *filter,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__in INT16 priority,
|
||||
__in UINT64 flags);
|
||||
|
||||
/*
|
||||
* Receive (read) a packet from a WinDivert handle.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertRecv(
|
||||
__in HANDLE handle,
|
||||
__out_opt VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt UINT *pRecvLen,
|
||||
__out_opt WINDIVERT_ADDRESS *pAddr);
|
||||
|
||||
/*
|
||||
* Receive (read) a packet from a WinDivert handle.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertRecvEx(
|
||||
__in HANDLE handle,
|
||||
__out_opt VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt UINT *pRecvLen,
|
||||
__in UINT64 flags,
|
||||
__out WINDIVERT_ADDRESS *pAddr,
|
||||
__inout_opt UINT *pAddrLen,
|
||||
__inout_opt LPOVERLAPPED lpOverlapped);
|
||||
|
||||
/*
|
||||
* Send (write/inject) a packet to a WinDivert handle.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertSend(
|
||||
__in HANDLE handle,
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt UINT *pSendLen,
|
||||
__in const WINDIVERT_ADDRESS *pAddr);
|
||||
|
||||
/*
|
||||
* Send (write/inject) a packet to a WinDivert handle.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertSendEx(
|
||||
__in HANDLE handle,
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt UINT *pSendLen,
|
||||
__in UINT64 flags,
|
||||
__in const WINDIVERT_ADDRESS *pAddr,
|
||||
__in UINT addrLen,
|
||||
__inout_opt LPOVERLAPPED lpOverlapped);
|
||||
|
||||
/*
|
||||
* Shutdown a WinDivert handle.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertShutdown(
|
||||
__in HANDLE handle,
|
||||
__in WINDIVERT_SHUTDOWN how);
|
||||
|
||||
/*
|
||||
* Close a WinDivert handle.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertClose(
|
||||
__in HANDLE handle);
|
||||
|
||||
/*
|
||||
* Set a WinDivert handle parameter.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertSetParam(
|
||||
__in HANDLE handle,
|
||||
__in WINDIVERT_PARAM param,
|
||||
__in UINT64 value);
|
||||
|
||||
/*
|
||||
* Get a WinDivert handle parameter.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertGetParam(
|
||||
__in HANDLE handle,
|
||||
__in WINDIVERT_PARAM param,
|
||||
__out UINT64 *pValue);
|
||||
|
||||
#endif /* WINDIVERT_KERNEL */
|
||||
|
||||
/*
|
||||
* WinDivert constants.
|
||||
*/
|
||||
#define WINDIVERT_PRIORITY_HIGHEST 30000
|
||||
#define WINDIVERT_PRIORITY_LOWEST (-WINDIVERT_PRIORITY_HIGHEST)
|
||||
#define WINDIVERT_PARAM_QUEUE_LENGTH_DEFAULT 4096
|
||||
#define WINDIVERT_PARAM_QUEUE_LENGTH_MIN 32
|
||||
#define WINDIVERT_PARAM_QUEUE_LENGTH_MAX 16384
|
||||
#define WINDIVERT_PARAM_QUEUE_TIME_DEFAULT 2000 /* 2s */
|
||||
#define WINDIVERT_PARAM_QUEUE_TIME_MIN 100 /* 100ms */
|
||||
#define WINDIVERT_PARAM_QUEUE_TIME_MAX 16000 /* 16s */
|
||||
#define WINDIVERT_PARAM_QUEUE_SIZE_DEFAULT 4194304 /* 4MB */
|
||||
#define WINDIVERT_PARAM_QUEUE_SIZE_MIN 65535 /* 64KB */
|
||||
#define WINDIVERT_PARAM_QUEUE_SIZE_MAX 33554432 /* 32MB */
|
||||
#define WINDIVERT_BATCH_MAX 0xFF /* 255 */
|
||||
#define WINDIVERT_MTU_MAX (40 + 0xFFFF)
|
||||
|
||||
/****************************************************************************/
|
||||
/* WINDIVERT HELPER API */
|
||||
/****************************************************************************/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4214)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
UINT8 HdrLength:4;
|
||||
UINT8 Version:4;
|
||||
UINT8 TOS;
|
||||
UINT16 Length;
|
||||
UINT16 Id;
|
||||
UINT16 FragOff0;
|
||||
UINT8 TTL;
|
||||
UINT8 Protocol;
|
||||
UINT16 Checksum;
|
||||
UINT32 SrcAddr;
|
||||
UINT32 DstAddr;
|
||||
} WINDIVERT_IPHDR, *PWINDIVERT_IPHDR;
|
||||
|
||||
#define WINDIVERT_IPHDR_GET_FRAGOFF(hdr) \
|
||||
(((hdr)->FragOff0) & 0xFF1F)
|
||||
#define WINDIVERT_IPHDR_GET_MF(hdr) \
|
||||
((((hdr)->FragOff0) & 0x0020) != 0)
|
||||
#define WINDIVERT_IPHDR_GET_DF(hdr) \
|
||||
((((hdr)->FragOff0) & 0x0040) != 0)
|
||||
#define WINDIVERT_IPHDR_GET_RESERVED(hdr) \
|
||||
((((hdr)->FragOff0) & 0x0080) != 0)
|
||||
|
||||
#define WINDIVERT_IPHDR_SET_FRAGOFF(hdr, val) \
|
||||
do \
|
||||
{ \
|
||||
(hdr)->FragOff0 = (((hdr)->FragOff0) & 0x00E0) | \
|
||||
((val) & 0xFF1F); \
|
||||
} \
|
||||
while (FALSE)
|
||||
#define WINDIVERT_IPHDR_SET_MF(hdr, val) \
|
||||
do \
|
||||
{ \
|
||||
(hdr)->FragOff0 = (((hdr)->FragOff0) & 0xFFDF) | \
|
||||
(((val) & 0x0001) << 5); \
|
||||
} \
|
||||
while (FALSE)
|
||||
#define WINDIVERT_IPHDR_SET_DF(hdr, val) \
|
||||
do \
|
||||
{ \
|
||||
(hdr)->FragOff0 = (((hdr)->FragOff0) & 0xFFBF) | \
|
||||
(((val) & 0x0001) << 6); \
|
||||
} \
|
||||
while (FALSE)
|
||||
#define WINDIVERT_IPHDR_SET_RESERVED(hdr, val) \
|
||||
do \
|
||||
{ \
|
||||
(hdr)->FragOff0 = (((hdr)->FragOff0) & 0xFF7F) | \
|
||||
(((val) & 0x0001) << 7); \
|
||||
} \
|
||||
while (FALSE)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 TrafficClass0:4;
|
||||
UINT8 Version:4;
|
||||
UINT8 FlowLabel0:4;
|
||||
UINT8 TrafficClass1:4;
|
||||
UINT16 FlowLabel1;
|
||||
UINT16 Length;
|
||||
UINT8 NextHdr;
|
||||
UINT8 HopLimit;
|
||||
UINT32 SrcAddr[4];
|
||||
UINT32 DstAddr[4];
|
||||
} WINDIVERT_IPV6HDR, *PWINDIVERT_IPV6HDR;
|
||||
|
||||
#define WINDIVERT_IPV6HDR_GET_TRAFFICCLASS(hdr) \
|
||||
((((hdr)->TrafficClass0) << 4) | ((hdr)->TrafficClass1))
|
||||
#define WINDIVERT_IPV6HDR_GET_FLOWLABEL(hdr) \
|
||||
((((UINT32)(hdr)->FlowLabel0) << 16) | ((UINT32)(hdr)->FlowLabel1))
|
||||
|
||||
#define WINDIVERT_IPV6HDR_SET_TRAFFICCLASS(hdr, val) \
|
||||
do \
|
||||
{ \
|
||||
(hdr)->TrafficClass0 = ((UINT8)(val) >> 4); \
|
||||
(hdr)->TrafficClass1 = (UINT8)(val); \
|
||||
} \
|
||||
while (FALSE)
|
||||
#define WINDIVERT_IPV6HDR_SET_FLOWLABEL(hdr, val) \
|
||||
do \
|
||||
{ \
|
||||
(hdr)->FlowLabel0 = (UINT8)((val) >> 16); \
|
||||
(hdr)->FlowLabel1 = (UINT16)(val); \
|
||||
} \
|
||||
while (FALSE)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 Type;
|
||||
UINT8 Code;
|
||||
UINT16 Checksum;
|
||||
UINT32 Body;
|
||||
} WINDIVERT_ICMPHDR, *PWINDIVERT_ICMPHDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 Type;
|
||||
UINT8 Code;
|
||||
UINT16 Checksum;
|
||||
UINT32 Body;
|
||||
} WINDIVERT_ICMPV6HDR, *PWINDIVERT_ICMPV6HDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT16 SrcPort;
|
||||
UINT16 DstPort;
|
||||
UINT32 SeqNum;
|
||||
UINT32 AckNum;
|
||||
UINT16 Reserved1:4;
|
||||
UINT16 HdrLength:4;
|
||||
UINT16 Fin:1;
|
||||
UINT16 Syn:1;
|
||||
UINT16 Rst:1;
|
||||
UINT16 Psh:1;
|
||||
UINT16 Ack:1;
|
||||
UINT16 Urg:1;
|
||||
UINT16 Reserved2:2;
|
||||
UINT16 Window;
|
||||
UINT16 Checksum;
|
||||
UINT16 UrgPtr;
|
||||
} WINDIVERT_TCPHDR, *PWINDIVERT_TCPHDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT16 SrcPort;
|
||||
UINT16 DstPort;
|
||||
UINT16 Length;
|
||||
UINT16 Checksum;
|
||||
} WINDIVERT_UDPHDR, *PWINDIVERT_UDPHDR;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Flags for WinDivertHelperCalcChecksums()
|
||||
*/
|
||||
#define WINDIVERT_HELPER_NO_IP_CHECKSUM 1
|
||||
#define WINDIVERT_HELPER_NO_ICMP_CHECKSUM 2
|
||||
#define WINDIVERT_HELPER_NO_ICMPV6_CHECKSUM 4
|
||||
#define WINDIVERT_HELPER_NO_TCP_CHECKSUM 8
|
||||
#define WINDIVERT_HELPER_NO_UDP_CHECKSUM 16
|
||||
|
||||
#ifndef WINDIVERT_KERNEL
|
||||
|
||||
/*
|
||||
* Hash a packet.
|
||||
*/
|
||||
WINDIVERTEXPORT UINT64 WinDivertHelperHashPacket(
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in UINT64 seed
|
||||
#ifdef __cplusplus
|
||||
= 0
|
||||
#endif
|
||||
);
|
||||
|
||||
/*
|
||||
* Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperParsePacket(
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt PWINDIVERT_IPHDR *ppIpHdr,
|
||||
__out_opt PWINDIVERT_IPV6HDR *ppIpv6Hdr,
|
||||
__out_opt UINT8 *pProtocol,
|
||||
__out_opt PWINDIVERT_ICMPHDR *ppIcmpHdr,
|
||||
__out_opt PWINDIVERT_ICMPV6HDR *ppIcmpv6Hdr,
|
||||
__out_opt PWINDIVERT_TCPHDR *ppTcpHdr,
|
||||
__out_opt PWINDIVERT_UDPHDR *ppUdpHdr,
|
||||
__out_opt PVOID *ppData,
|
||||
__out_opt UINT *pDataLen,
|
||||
__out_opt PVOID *ppNext,
|
||||
__out_opt UINT *pNextLen);
|
||||
|
||||
/*
|
||||
* Parse an IPv4 address.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperParseIPv4Address(
|
||||
__in const char *addrStr,
|
||||
__out_opt UINT32 *pAddr);
|
||||
|
||||
/*
|
||||
* Parse an IPv6 address.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperParseIPv6Address(
|
||||
__in const char *addrStr,
|
||||
__out_opt UINT32 *pAddr);
|
||||
|
||||
/*
|
||||
* Format an IPv4 address.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv4Address(
|
||||
__in UINT32 addr,
|
||||
__out char *buffer,
|
||||
__in UINT bufLen);
|
||||
|
||||
/*
|
||||
* Format an IPv6 address.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperFormatIPv6Address(
|
||||
__in const UINT32 *pAddr,
|
||||
__out char *buffer,
|
||||
__in UINT bufLen);
|
||||
|
||||
/*
|
||||
* Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperCalcChecksums(
|
||||
__inout VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__out_opt WINDIVERT_ADDRESS *pAddr,
|
||||
__in UINT64 flags);
|
||||
|
||||
/*
|
||||
* Decrement the TTL/HopLimit.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperDecrementTTL(
|
||||
__inout VOID *pPacket,
|
||||
__in UINT packetLen);
|
||||
|
||||
/*
|
||||
* Compile the given filter string.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperCompileFilter(
|
||||
__in const char *filter,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__out_opt char *object,
|
||||
__in UINT objLen,
|
||||
__out_opt const char **errorStr,
|
||||
__out_opt UINT *errorPos);
|
||||
|
||||
/*
|
||||
* Evaluate the given filter string.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperEvalFilter(
|
||||
__in const char *filter,
|
||||
__in const VOID *pPacket,
|
||||
__in UINT packetLen,
|
||||
__in const WINDIVERT_ADDRESS *pAddr);
|
||||
|
||||
/*
|
||||
* Format the given filter string.
|
||||
*/
|
||||
WINDIVERTEXPORT BOOL WinDivertHelperFormatFilter(
|
||||
__in const char *filter,
|
||||
__in WINDIVERT_LAYER layer,
|
||||
__out char *buffer,
|
||||
__in UINT bufLen);
|
||||
|
||||
/*
|
||||
* Byte ordering.
|
||||
*/
|
||||
WINDIVERTEXPORT UINT16 WinDivertHelperNtohs(
|
||||
__in UINT16 x);
|
||||
WINDIVERTEXPORT UINT16 WinDivertHelperHtons(
|
||||
__in UINT16 x);
|
||||
WINDIVERTEXPORT UINT32 WinDivertHelperNtohl(
|
||||
__in UINT32 x);
|
||||
WINDIVERTEXPORT UINT32 WinDivertHelperHtonl(
|
||||
__in UINT32 x);
|
||||
WINDIVERTEXPORT UINT64 WinDivertHelperNtohll(
|
||||
__in UINT64 x);
|
||||
WINDIVERTEXPORT UINT64 WinDivertHelperHtonll(
|
||||
__in UINT64 x);
|
||||
WINDIVERTEXPORT void WinDivertHelperNtohIPv6Address(
|
||||
__in const UINT *inAddr,
|
||||
__out UINT *outAddr);
|
||||
WINDIVERTEXPORT void WinDivertHelperHtonIPv6Address(
|
||||
__in const UINT *inAddr,
|
||||
__out UINT *outAddr);
|
||||
|
||||
/*
|
||||
* Old names to be removed in the next version.
|
||||
*/
|
||||
WINDIVERTEXPORT void WinDivertHelperNtohIpv6Address(
|
||||
__in const UINT *inAddr,
|
||||
__out UINT *outAddr);
|
||||
WINDIVERTEXPORT void WinDivertHelperHtonIpv6Address(
|
||||
__in const UINT *inAddr,
|
||||
__out UINT *outAddr);
|
||||
|
||||
#endif /* WINDIVERT_KERNEL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __WINDIVERT_H */
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -20,7 +20,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
|||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
TunnelSDKUnInit();
|
||||
CoFreeUnusedLibraries();
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -74,6 +74,7 @@ typedef struct {
|
|||
TCHAR systemDirectory[MAX_PATH]; ///< 操作系统目录
|
||||
TCHAR workDirectory[MAX_PATH]; ///< SDK 当前工作目录
|
||||
bool isWorkServer; ///< SDK 当前模式 客户端/服务端
|
||||
bool usedSCGProxy; ///< 是否启动 SCG 代理
|
||||
PROTO_CRYPTO_TYPE proCryptoType; ///< 协议加密类型
|
||||
TCHAR proKeyBuf[256]; ///< 协议加密秘钥
|
||||
BOOL enableLog; ///< 是否启用日志
|
||||
|
@ -83,6 +84,7 @@ typedef struct {
|
|||
WGINTERFACE_CFG wgServerCfg; ///< wireguard 服务端网络接口配置
|
||||
WGINTERFACE_CFG wgClientCfg; ///< wireguard 客户端网络接口配置
|
||||
USER_CONFIG userCfg; ///< 用户配置项
|
||||
int curConnVmId; ///< 当前连接的VM
|
||||
} SDK_CONFIG, *PSDK_CONFIG;
|
||||
|
||||
#ifdef __cplusplus // If used by C++ code,
|
||||
|
|
13216
NetTunnelSDK/httplib.h
13216
NetTunnelSDK/httplib.h
File diff suppressed because it is too large
Load Diff
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "usrerr.h"
|
||||
#include "misc.h"
|
||||
#include "tunnel.h"
|
||||
|
||||
static const TCHAR *p2_table(unsigned pow) {
|
||||
static const TCHAR *pow2[] = {
|
||||
|
@ -145,22 +146,6 @@ static const TCHAR *p2_table(unsigned pow) {
|
|||
return TEXT("");
|
||||
}
|
||||
|
||||
TCHAR *safe_strdup(const TCHAR *str) {
|
||||
TCHAR *ret;
|
||||
|
||||
if (!str) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ret = _strdup(str);
|
||||
if (!ret) {
|
||||
SPDLOG_ERROR(TEXT("Memory allocation string failure:{0}"), str);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vasprintf(TCHAR **strp, const TCHAR *fmt, va_list ap) {
|
||||
// _vscprintf tells you how big the buffer needs to be
|
||||
const int len = _vscprintf(fmt, ap);
|
||||
|
@ -331,8 +316,8 @@ static int GetIpV4Info(const TCHAR *pIpStr, int prefix, PIP_INFO pInfo, unsigned
|
|||
|
||||
/* Handle CIDR entries such as 172/8 */
|
||||
if (prefix >= 0) {
|
||||
auto tmp = const_cast<TCHAR *>(ipStr);
|
||||
int i;
|
||||
auto tmp = const_cast<TCHAR *>(ipStr);
|
||||
int i;
|
||||
|
||||
for (i = 3; i > 0; i--) {
|
||||
tmp = strchr(tmp, '.');
|
||||
|
@ -367,7 +352,7 @@ static int GetIpV4Info(const TCHAR *pIpStr, int prefix, PIP_INFO pInfo, unsigned
|
|||
free(ipStr);
|
||||
return -ERR_UN_SUPPORT;
|
||||
}
|
||||
pInfo->ip = safe_strdup(namebuf);
|
||||
StringCbCopy(pInfo->ip, MAX_IP_LEN, namebuf);
|
||||
|
||||
netmask.s_addr = prefix2mask(prefix);
|
||||
memset(namebuf, '\0', sizeof(namebuf));
|
||||
|
@ -377,8 +362,9 @@ static int GetIpV4Info(const TCHAR *pIpStr, int prefix, PIP_INFO pInfo, unsigned
|
|||
free(ipStr);
|
||||
return -ERR_UN_SUPPORT;
|
||||
}
|
||||
pInfo->netmask = safe_strdup(namebuf);
|
||||
pInfo->prefix = prefix;
|
||||
StringCbCopy(pInfo->netmask, MAX_IP_LEN, namebuf);
|
||||
|
||||
pInfo->prefix = prefix;
|
||||
|
||||
broadcast = calc_broadcast(ip, prefix);
|
||||
|
||||
|
@ -388,7 +374,8 @@ static int GetIpV4Info(const TCHAR *pIpStr, int prefix, PIP_INFO pInfo, unsigned
|
|||
free(ipStr);
|
||||
return -ERR_UN_SUPPORT;
|
||||
}
|
||||
pInfo->broadcast = safe_strdup(namebuf);
|
||||
|
||||
StringCbCopy(pInfo->broadcast, MAX_IP_LEN, namebuf);
|
||||
|
||||
network = calc_network(ip, prefix);
|
||||
|
||||
|
@ -399,7 +386,7 @@ static int GetIpV4Info(const TCHAR *pIpStr, int prefix, PIP_INFO pInfo, unsigned
|
|||
return -ERR_UN_SUPPORT;
|
||||
}
|
||||
|
||||
pInfo->network = safe_strdup(namebuf);
|
||||
StringCbCopy(pInfo->network, MAX_IP_LEN, namebuf);
|
||||
|
||||
if (prefix < 32) {
|
||||
memcpy(&minhost, &network, sizeof(minhost));
|
||||
|
@ -412,7 +399,7 @@ static int GetIpV4Info(const TCHAR *pIpStr, int prefix, PIP_INFO pInfo, unsigned
|
|||
free(ipStr);
|
||||
return -ERR_UN_SUPPORT;
|
||||
}
|
||||
pInfo->hostmin = safe_strdup(namebuf);
|
||||
StringCbCopy(pInfo->hostmin, MAX_IP_LEN, namebuf);
|
||||
|
||||
memcpy(&maxhost, &network, sizeof(minhost));
|
||||
maxhost.s_addr |= ~netmask.s_addr;
|
||||
|
@ -425,10 +412,10 @@ static int GetIpV4Info(const TCHAR *pIpStr, int prefix, PIP_INFO pInfo, unsigned
|
|||
return -ERR_UN_SUPPORT;
|
||||
}
|
||||
|
||||
pInfo->hostmax = safe_strdup(namebuf);
|
||||
StringCbCopy(pInfo->hostmax, MAX_IP_LEN, namebuf);
|
||||
} else {
|
||||
pInfo->hostmin = pInfo->network;
|
||||
pInfo->hostmax = pInfo->network;
|
||||
StringCbCopy(pInfo->hostmin, MAX_IP_LEN, pInfo->network);
|
||||
StringCbCopy(pInfo->hostmax, MAX_IP_LEN, pInfo->network);
|
||||
}
|
||||
|
||||
ipv4_prefix_to_hosts(pInfo->hosts, sizeof(pInfo->hosts), prefix);
|
||||
|
@ -452,7 +439,7 @@ int GetIpV4InfoFromCIDR(const TCHAR *pIpStr, PIP_INFO pInfo) {
|
|||
TCHAR *prefixStr;
|
||||
TCHAR *ipStr = _strdup(pIpStr);
|
||||
|
||||
if (pIpStr == nullptr || lstrlen(pIpStr) < 8) {
|
||||
if (pIpStr == nullptr || lstrlen(pIpStr) < MIN_IP_LEN) {
|
||||
SPDLOG_ERROR(TEXT("Input pIpStr format error: {}."), pIpStr);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
@ -498,12 +485,12 @@ int GetIpV4InfoFromCIDR(const TCHAR *pIpStr, PIP_INFO pInfo) {
|
|||
int GetIpV4InfoFromNetmask(const TCHAR *pIpStr, const TCHAR *pNetmask, PIP_INFO pInfo) {
|
||||
int prefix;
|
||||
|
||||
if (pIpStr == nullptr || lstrlen(pIpStr) < 8) {
|
||||
if (pIpStr == nullptr || lstrlen(pIpStr) < MIN_IP_LEN) {
|
||||
SPDLOG_ERROR(TEXT("Input pIpStr format error: {}."), pIpStr);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if (pNetmask == nullptr || lstrlen(pNetmask) < 8) {
|
||||
if (pNetmask == nullptr || lstrlen(pNetmask) < MIN_IP_LEN) {
|
||||
SPDLOG_ERROR(TEXT("Input pNetmask format error: {}."), pNetmask);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
@ -516,3 +503,36 @@ int GetIpV4InfoFromNetmask(const TCHAR *pIpStr, const TCHAR *pNetmask, PIP_INFO
|
|||
prefix = ipv4_mask_to_int(pNetmask);
|
||||
return GetIpV4Info(pIpStr, prefix, pInfo, 0);
|
||||
}
|
||||
|
||||
int GetIpV4InfoFromHostname(int family, const char *host, PIP_INFO pInfo) {
|
||||
addrinfo *res, *rp;
|
||||
addrinfo hints {};
|
||||
int err;
|
||||
static char ipname[64];
|
||||
void *addr;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = family;
|
||||
|
||||
err = getaddrinfo(host, nullptr, &hints, &res);
|
||||
if (err != 0) {
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
for (rp = res; rp != nullptr; rp = rp->ai_next) {
|
||||
if (rp->ai_family == AF_INET) {
|
||||
addr = (&reinterpret_cast<sockaddr_in *>(rp->ai_addr)->sin_addr);
|
||||
} else {
|
||||
addr = (&reinterpret_cast<sockaddr_in6 *>(rp->ai_addr)->sin6_addr);
|
||||
}
|
||||
|
||||
if (inet_ntop(rp->ai_family, addr, ipname, sizeof(ipname)) != nullptr) {
|
||||
freeaddrinfo(res);
|
||||
StringCbCopy(pInfo->hostip, MAX_IP_LEN, ipname);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
return ERR_ITEM_EXISTS;
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "tunnel.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define CFG_WIREGUARD_SECTION TEXT("WireGuard")
|
||||
|
@ -20,14 +22,15 @@ typedef struct {
|
|||
* @brief IPv4 网络信息
|
||||
*/
|
||||
typedef struct {
|
||||
TCHAR *ip; ///< IP 地址
|
||||
TCHAR *network; ///< 网络地址
|
||||
TCHAR *broadcast; ///< 网络广播地址
|
||||
TCHAR *netmask; ///< 网络子网掩码
|
||||
TCHAR hosts[64]; ///< number of hosts in text
|
||||
unsigned int prefix; ///< 网络前缀
|
||||
TCHAR *hostmin; ///< 最小网络主机 IP
|
||||
TCHAR *hostmax; ///< 最大网络主机 IP
|
||||
unsigned int prefix; ///< 网络前缀
|
||||
TCHAR hostip[MAX_IP_LEN]; ///< IP 地址
|
||||
TCHAR ip[MAX_IP_LEN]; ///< IP 地址
|
||||
TCHAR network[MAX_IP_LEN]; ///< 网络地址
|
||||
TCHAR broadcast[MAX_IP_LEN]; ///< 网络广播地址
|
||||
TCHAR netmask[MAX_IP_LEN]; ///< 网络子网掩码
|
||||
TCHAR hosts[64]; ///< number of hosts in text
|
||||
TCHAR hostmin[MAX_IP_LEN]; ///< 最小网络主机 IP
|
||||
TCHAR hostmax[MAX_IP_LEN]; ///< 最大网络主机 IP
|
||||
} IP_INFO, *PIP_INFO;
|
||||
|
||||
#ifdef __cplusplus // If used by C++ code,
|
||||
|
@ -103,6 +106,8 @@ int GetIpV4InfoFromNetmask(const TCHAR *pIpStr, const TCHAR *pNetmask, PIP_INFO
|
|||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
int GetIpV4InfoFromCIDR(const TCHAR *pIpStr, PIP_INFO pInfo);
|
||||
|
||||
int GetIpV4InfoFromHostname(int family, const char *host, PIP_INFO pInfo);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -21,34 +21,67 @@
|
|||
|
||||
static NIC_CONTENT g_NetAdapterInfo[NET_CARD_MAX];
|
||||
|
||||
static const TCHAR *g_TabCIDR[] = {
|
||||
TEXT("128.0.0.0"), TEXT("192.0.0.0"), TEXT("224.0.0.0"), TEXT("240.0.0.0"),
|
||||
TEXT("248.0.0.0"), TEXT("252.0.0.0"), TEXT("254.0.0.0"), TEXT("255.0.0.0"),
|
||||
TEXT("255.128.0.0"), TEXT("255.192.0.0"), TEXT("255.224.0.0"), TEXT("255.240.0.0"),
|
||||
TEXT("255.248.0.0"), TEXT("255.252.0.0"), TEXT("255.254.0.0"), TEXT("255.255.0.0"),
|
||||
TEXT("255.255.128.0"), TEXT("255.255.192.0"), TEXT("255.255.224.0"), TEXT("255.255.240.0"),
|
||||
TEXT("255.255.248.0"), TEXT("255.255.252.0"), TEXT("255.255.254.0"), TEXT("255.255.255.0"),
|
||||
TEXT("255.255.255.128"), TEXT("255.255.255.192"), TEXT("255.255.255.224"), TEXT("255.255.255.240"),
|
||||
TEXT("255.255.255.248"), TEXT("255.255.255.252"), TEXT("255.255.255.254"), TEXT("255.255.255.255")};
|
||||
int GetInterfaceIfIndexByIpAddr(const TCHAR *pIpAddr, ULONG *pIfIndex) {
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
DWORD dwRetVal;
|
||||
ULONG ulOutBufLen;
|
||||
|
||||
int NetmaskToCIDR(const TCHAR *pNetMask) {
|
||||
if (pIpAddr == nullptr || lstrlen(pIpAddr) == 0) {
|
||||
SPDLOG_ERROR(TEXT("Input pIpAddr error: {0}"), pIpAddr);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
for (int i = 0; i < static_cast<int>(std::size(g_TabCIDR)); i++) {
|
||||
if (lstrcmp(g_TabCIDR[i], pNetMask) == 0) {
|
||||
return i + 1;
|
||||
if (pIfIndex == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Input pIfIndex params error"));
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||
pAdapterInfo = static_cast<IP_ADAPTER_INFO *>(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO)));
|
||||
|
||||
if (pAdapterInfo == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo"));
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
|
||||
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
pAdapterInfo = static_cast<IP_ADAPTER_INFO *>(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen));
|
||||
if (pAdapterInfo == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n"));
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
*pIfIndex = -1;
|
||||
|
||||
const TCHAR *CIDRToNetmask(const UINT8 cidr) {
|
||||
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
|
||||
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
|
||||
while (pAdapter) {
|
||||
PIP_ADDR_STRING ipAddressListPointer = &(pAdapter->IpAddressList);
|
||||
|
||||
if (cidr >= 1 && cidr <= std::size(g_TabCIDR)) {
|
||||
return g_TabCIDR[cidr - 1];
|
||||
while (ipAddressListPointer != nullptr) {
|
||||
if (StrCmp((ipAddressListPointer->IpAddress).String, pIpAddr) == 0) {
|
||||
*pIfIndex = pAdapter->Index;
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return ERR_SUCCESS;
|
||||
} else {
|
||||
ipAddressListPointer = ipAddressListPointer->Next;
|
||||
}
|
||||
}
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
} else {
|
||||
SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal);
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return -ERR_SYS_CALL;
|
||||
}
|
||||
|
||||
return TEXT("");
|
||||
if (pAdapterInfo) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
}
|
||||
|
||||
return -ERR_ITEM_UNEXISTS;
|
||||
}
|
||||
|
||||
int GetInterfaceIfIndexByGUID(const TCHAR *pGUID, int *pIfIndex) {
|
||||
|
@ -87,7 +120,6 @@ int GetInterfaceIfIndexByGUID(const TCHAR *pGUID, int *pIfIndex) {
|
|||
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
|
||||
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
|
||||
while (pAdapter) {
|
||||
|
||||
if (StrCmp(pAdapter->AdapterName, pGUID) == 0) {
|
||||
*pIfIndex = static_cast<int>(pAdapter->Index);
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
|
@ -202,52 +234,266 @@ int GetInterfaceNameByGUID(const TCHAR *pGUID, TCHAR ifName[MAX_NETCARD_NAME]) {
|
|||
return ERR_ITEM_UNEXISTS;
|
||||
}
|
||||
|
||||
int GetInternetIfName(TCHAR ifName[MAX_NETCARD_NAME]) {
|
||||
for (int i = 0; i < NET_CARD_MAX; i++) {
|
||||
const PNIC_CONTENT pNic = &g_NetAdapterInfo[i];
|
||||
int GetInternetIfIndex(int *pIfIndex) {
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
DWORD dwRetVal;
|
||||
ULONG ulOutBufLen;
|
||||
|
||||
bool bIsInternel;
|
||||
if (pIfIndex == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Input pIfIndex params error"));
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if (ERR_SUCCESS == IsInternetConnectAdapter(pNic->InterfaceIndex, &bIsInternel) && bIsInternel) {
|
||||
StringCbCopy(ifName, MAX_NETCARD_NAME, pNic->NetCardName);
|
||||
return ERR_SUCCESS;
|
||||
ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||
pAdapterInfo = static_cast<IP_ADAPTER_INFO *>(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO)));
|
||||
|
||||
if (pAdapterInfo == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo"));
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
|
||||
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
pAdapterInfo = static_cast<IP_ADAPTER_INFO *>(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen));
|
||||
if (pAdapterInfo == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n"));
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
*pIfIndex = -1;
|
||||
|
||||
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
|
||||
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
|
||||
while (pAdapter) {
|
||||
bool bIsInternel;
|
||||
int index = static_cast<int>(pAdapter->Index);
|
||||
|
||||
int ret = IsInternetConnectAdapter(index, &bIsInternel);
|
||||
|
||||
if (ret != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("IsInternetConnectAdapter {0} : {1}\n"), index, ret);
|
||||
}
|
||||
|
||||
if (ret == ERR_SUCCESS && bIsInternel) {
|
||||
*pIfIndex = index;
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
} else {
|
||||
SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal);
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return -ERR_SYS_CALL;
|
||||
}
|
||||
|
||||
if (pAdapterInfo) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
}
|
||||
|
||||
return -ERR_ITEM_UNEXISTS;
|
||||
}
|
||||
|
||||
int GetInterfaceGUIDByIfIndex(const int ifIndex, GUID *pGuid) {
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
DWORD dwRetVal;
|
||||
ULONG ulOutBufLen;
|
||||
if (pGuid == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Input pGuid error."));
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||
pAdapterInfo = static_cast<IP_ADAPTER_INFO *>(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO)));
|
||||
|
||||
if (pAdapterInfo == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo"));
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
|
||||
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
pAdapterInfo = static_cast<IP_ADAPTER_INFO *>(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen));
|
||||
if (pAdapterInfo == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo"));
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
|
||||
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
|
||||
while (pAdapter) {
|
||||
if (ifIndex == static_cast<int>(pAdapter->Index)) {
|
||||
int ret;
|
||||
WCHAR strGuid[MAX_PATH];
|
||||
|
||||
if ((ret = TCharToWideChar(pAdapter->AdapterName, strGuid, MAX_PATH)) != ERR_SUCCESS) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (CLSIDFromString(strGuid, pGuid) != NOERROR) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return -ERR_MEMORY_STR;
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
} else {
|
||||
SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}"), dwRetVal);
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return -ERR_SYS_CALL;
|
||||
}
|
||||
|
||||
if (pAdapterInfo) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
}
|
||||
|
||||
return -ERR_ITEM_UNEXISTS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 根据网卡名获取网卡索引
|
||||
* @param[in] pInterfaceName 网卡名称
|
||||
* @param[out] pIfIndex 网卡 Index
|
||||
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
|
||||
* - -ERR_INPUT_PARAMS 输入参数错误
|
||||
* - -ERR_ITEM_UNEXISTS 网卡不存在
|
||||
* - -ERR_SYS_CALL 获取操作系统网卡适配器失败
|
||||
* - -ERR_MALLOC_MEMORY 分配内存失败
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
int GetInterfaceIfIndexByName(const TCHAR *pInterfaceName, int *pIfIndex) {
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
DWORD dwRetVal;
|
||||
ULONG ulOutBufLen;
|
||||
|
||||
if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) {
|
||||
SPDLOG_ERROR(TEXT("Input pInterfaceName error: {0}"), pInterfaceName);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if (pIfIndex == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Input pIfIndex params error."));
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||
pAdapterInfo = static_cast<IP_ADAPTER_INFO *>(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO)));
|
||||
|
||||
if (pAdapterInfo == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo"));
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
|
||||
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
pAdapterInfo = static_cast<IP_ADAPTER_INFO *>(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen));
|
||||
if (pAdapterInfo == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n"));
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
*pIfIndex = -1;
|
||||
|
||||
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
|
||||
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
|
||||
while (pAdapter) {
|
||||
TCHAR NetCardName[MAX_NETCARD_NAME] = {};
|
||||
GetInterfaceNameByGUID(pAdapter->AdapterName, NetCardName);
|
||||
|
||||
if (StrCmp(pInterfaceName, NetCardName) == 0) {
|
||||
*pIfIndex = static_cast<int>(pAdapter->Index);
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
} else {
|
||||
SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal);
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return -ERR_SYS_CALL;
|
||||
}
|
||||
|
||||
if (pAdapterInfo) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
}
|
||||
|
||||
return -ERR_ITEM_UNEXISTS;
|
||||
}
|
||||
|
||||
int GetInterfaceGUIDByName(const TCHAR *pInterfaceName, GUID *pGuid) {
|
||||
int ret;
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
DWORD dwRetVal;
|
||||
ULONG ulOutBufLen;
|
||||
|
||||
if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) {
|
||||
SPDLOG_ERROR(TEXT("Input pInterfaceName params error: {0}"), pInterfaceName);
|
||||
SPDLOG_ERROR(TEXT("Input pInterfaceName error: {0}"), pInterfaceName);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if (lstrlen(g_NetAdapterInfo[0].NetCardUUID) == 0) {
|
||||
PNIC_CONTENT nic;
|
||||
int nItem;
|
||||
if (pGuid == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Input pGuid params error"));
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if ((ret = GetAllNICInfo(&nic, &nItem)) != ERR_SUCCESS) {
|
||||
return ret;
|
||||
ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
||||
pAdapterInfo = static_cast<IP_ADAPTER_INFO *>(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO)));
|
||||
|
||||
if (pAdapterInfo == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo"));
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
|
||||
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
pAdapterInfo = static_cast<IP_ADAPTER_INFO *>(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen));
|
||||
if (pAdapterInfo == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n"));
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &v : g_NetAdapterInfo) {
|
||||
if (StrCmp(pInterfaceName, v.NetCardName) == 0) {
|
||||
WCHAR strGuid[MAX_PATH];
|
||||
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
|
||||
PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
|
||||
while (pAdapter) {
|
||||
int ret;
|
||||
TCHAR NetCardName[MAX_NETCARD_NAME] = {};
|
||||
GetInterfaceNameByGUID(pAdapter->AdapterName, NetCardName);
|
||||
|
||||
if ((ret = TCharToWideChar(v.NetCardUUID, strGuid, MAX_PATH)) != ERR_SUCCESS) {
|
||||
return ret;
|
||||
if (StrCmp(pInterfaceName, NetCardName) == 0) {
|
||||
WCHAR strGuid[MAX_PATH];
|
||||
|
||||
if ((ret = TCharToWideChar(pAdapter->AdapterName, strGuid, MAX_PATH)) != ERR_SUCCESS) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (CLSIDFromString(strGuid, pGuid) != NOERROR) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return -ERR_MEMORY_STR;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
if (CLSIDFromString(strGuid, pGuid) != NOERROR) {
|
||||
return -ERR_MEMORY_STR;
|
||||
}
|
||||
|
||||
return ERR_SUCCESS;
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
} else {
|
||||
SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal);
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
return -ERR_SYS_CALL;
|
||||
}
|
||||
|
||||
if (pAdapterInfo) {
|
||||
HeapFree(GetProcessHeap(), 0, pAdapterInfo);
|
||||
}
|
||||
|
||||
return -ERR_ITEM_UNEXISTS;
|
||||
|
@ -289,8 +535,8 @@ int WaitNetAdapterConnected(const TCHAR *pInterfaceName, int timeOutOfMs) {
|
|||
|
||||
while (S_OK == pEnumConns->Next(1, &pIConn, nullptr)) {
|
||||
GUID adpterGuid;
|
||||
pIConn->GetAdapterId(&adpterGuid);
|
||||
|
||||
pIConn->GetAdapterId(&adpterGuid);
|
||||
pIConn->GetNetwork(&pINet);
|
||||
|
||||
if (pINet) {
|
||||
|
@ -307,10 +553,19 @@ int WaitNetAdapterConnected(const TCHAR *pInterfaceName, int timeOutOfMs) {
|
|||
SysFreeString(sName);
|
||||
|
||||
if (StrNCmp(pInterfaceName, ifName, lstrlen(pInterfaceName)) == 0) {
|
||||
if (GetInterfaceGUIDByName(pInterfaceName, &guid) != ERR_SUCCESS) {
|
||||
|
||||
int ret = GetInterfaceGUIDByName(pInterfaceName, &guid);
|
||||
if (ret != ERR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Get Interface {0} GUID error: {1}"), pInterfaceName, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*SPDLOG_DEBUG(TEXT("Match Interface {0} --> {1}, Guid {2:x} --> {3:x}"),
|
||||
ifName,
|
||||
pInterfaceName,
|
||||
adpterGuid.Data1,
|
||||
guid.Data1);*/
|
||||
|
||||
if (memcmp(&adpterGuid, &guid, sizeof(GUID)) == 0) {
|
||||
SPDLOG_DEBUG(TEXT("Interface {0}({1}) network connected now..."), ifName, pInterfaceName);
|
||||
return ERR_SUCCESS;
|
||||
|
@ -468,7 +723,7 @@ int IsInternetConnectAdapter(int ifIndex, bool *pRet) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (StrCmp(ipStr, TEXT("0.0.0.0")) == 0 && StrCmp(maskStr, TEXT("0.0.0.0"))) {
|
||||
if (StrCmp(ipStr, TEXT("0.0.0.0")) == 0 && StrCmp(maskStr, TEXT("0.0.0.0")) == 0) {
|
||||
*pRet = true;
|
||||
break;
|
||||
}
|
||||
|
@ -595,7 +850,7 @@ int GetNetConnectionNetworkCategory(const TCHAR *pInterfaceName, bool *pIsPrivat
|
|||
return -ERR_ITEM_UNEXISTS;
|
||||
}
|
||||
|
||||
int SetNetConnectionSharing(const TCHAR *pInterfaceName, bool isEnable, bool isSetPrivate) {
|
||||
int SetNetIntelnetConnectionSharing(int ifIndex, bool isEnable, bool isSetPrivate) {
|
||||
VARIANT v;
|
||||
INetConnection *pNC = nullptr;
|
||||
INetSharingConfiguration *pNSC = nullptr;
|
||||
|
@ -604,10 +859,11 @@ int SetNetConnectionSharing(const TCHAR *pInterfaceName, bool isEnable, bool isS
|
|||
INetSharingEveryConnectionCollection *pNSECC = nullptr;
|
||||
INetSharingManager *pNSM;
|
||||
HRESULT hr;
|
||||
GUID ifGuid;
|
||||
int ret;
|
||||
|
||||
if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) {
|
||||
SPDLOG_ERROR(TEXT("Input pInterfaceName params error: {0}"), pInterfaceName);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
if ((ret = GetInterfaceGUIDByIfIndex(ifIndex, &ifGuid)) != ERR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
hr = ::CoCreateInstance(CLSID_NetSharingManager,
|
||||
|
@ -648,17 +904,11 @@ int SetNetConnectionSharing(const TCHAR *pInterfaceName, bool isEnable, bool isS
|
|||
if (V_VT(&v) == VT_UNKNOWN) {
|
||||
V_UNKNOWN(&v)->QueryInterface(IID_INetConnection, reinterpret_cast<void **>(&pNC));
|
||||
if (pNC) {
|
||||
TCHAR ifName[MAX_PATH];
|
||||
NETCON_PROPERTIES *pNP;
|
||||
pNC->GetProperties(&pNP);
|
||||
|
||||
// 执行字符串转换
|
||||
if (WideCharToTChar(pNP->pszwName, ifName, MAX_PATH) != ERR_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 找到对应的网卡进行处理
|
||||
if (StrCmp(pInterfaceName, ifName) != 0) {
|
||||
if (memcmp(&ifGuid, &pNP->guidId, sizeof(GUID)) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -675,15 +925,32 @@ int SetNetConnectionSharing(const TCHAR *pInterfaceName, bool isEnable, bool isS
|
|||
|
||||
if (pNSC) {
|
||||
if (isEnable) {
|
||||
pNSC->DisableSharing();
|
||||
hr = pNSC->DisableSharing();
|
||||
|
||||
if (hr != S_OK) {
|
||||
SPDLOG_ERROR(TEXT("INetSharingManager DisableSharing failed: {0}."), hr);
|
||||
pNSC->Release();
|
||||
return -ERR_CALL_COMMOBJECT;
|
||||
}
|
||||
Sleep(500);
|
||||
pNSC->EnableSharing(isSetPrivate ? ICSSHARINGTYPE_PRIVATE : ICSSHARINGTYPE_PUBLIC);
|
||||
hr = pNSC->EnableSharing(isSetPrivate ? ICSSHARINGTYPE_PRIVATE : ICSSHARINGTYPE_PUBLIC);
|
||||
|
||||
if (hr != S_OK) {
|
||||
SPDLOG_ERROR(TEXT("INetSharingManager EnableSharing failed: {0}."), hr);
|
||||
pNSC->Release();
|
||||
return -ERR_CALL_COMMOBJECT;
|
||||
}
|
||||
} else {
|
||||
pNSC->DisableSharing();
|
||||
hr = pNSC->DisableSharing();
|
||||
|
||||
if (hr != S_OK) {
|
||||
SPDLOG_ERROR(TEXT("INetSharingManager DisableSharing failed: {0}."), hr);
|
||||
pNSC->Release();
|
||||
return -ERR_CALL_COMMOBJECT;
|
||||
}
|
||||
}
|
||||
|
||||
pNSC->Release();
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -693,7 +960,7 @@ int SetNetConnectionSharing(const TCHAR *pInterfaceName, bool isEnable, bool isS
|
|||
return ERR_ITEM_UNEXISTS;
|
||||
}
|
||||
|
||||
int GetNetConnectionSharing(const TCHAR *pInterfaceName, bool *pIsEnable) {
|
||||
int GetNetIntelnetConnectionSharing(int ifIndex, bool *pIsEnable) {
|
||||
VARIANT v;
|
||||
INetConnection *pNC = nullptr;
|
||||
INetSharingConfiguration *pNSC = nullptr;
|
||||
|
@ -702,17 +969,19 @@ int GetNetConnectionSharing(const TCHAR *pInterfaceName, bool *pIsEnable) {
|
|||
INetSharingEveryConnectionCollection *pNSECC = nullptr;
|
||||
INetSharingManager *pNSM;
|
||||
HRESULT hr;
|
||||
|
||||
if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) {
|
||||
SPDLOG_ERROR(TEXT("Input pInterfaceName params error: {0}"), pInterfaceName);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
GUID ifGuid;
|
||||
int ret;
|
||||
|
||||
if (pIsEnable == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Input pIsEnable params error"));
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
// 根据网卡索引获取网卡GUID
|
||||
if ((ret = GetInterfaceGUIDByIfIndex(ifIndex, &ifGuid)) != ERR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
hr = ::CoCreateInstance(CLSID_NetSharingManager,
|
||||
nullptr,
|
||||
CLSCTX_ALL,
|
||||
|
@ -751,19 +1020,17 @@ int GetNetConnectionSharing(const TCHAR *pInterfaceName, bool *pIsEnable) {
|
|||
if (V_VT(&v) == VT_UNKNOWN) {
|
||||
V_UNKNOWN(&v)->QueryInterface(IID_INetConnection, reinterpret_cast<void **>(&pNC));
|
||||
if (pNC) {
|
||||
TCHAR ifName[MAX_PATH];
|
||||
NETCON_PROPERTIES *pNP;
|
||||
pNC->GetProperties(&pNP);
|
||||
|
||||
// 执行字符串转换
|
||||
if (WideCharToTChar(pNP->pszwName, ifName, MAX_PATH) != ERR_SUCCESS) {
|
||||
// 找到对应的网卡进行处理
|
||||
if (memcmp(&ifGuid, &pNP->guidId, sizeof(GUID)) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 找到对应的网卡进行处理
|
||||
if (StrCmp(pInterfaceName, ifName) != 0) {
|
||||
continue;
|
||||
}
|
||||
//if (StrCmp(pInterfaceName, ifName) != 0) {
|
||||
// continue;
|
||||
//}
|
||||
|
||||
hr = pNSM->get_INetSharingConfigurationForINetConnection(pNC, &pNSC);
|
||||
|
||||
|
@ -773,10 +1040,16 @@ int GetNetConnectionSharing(const TCHAR *pInterfaceName, bool *pIsEnable) {
|
|||
|
||||
if (pNSC) {
|
||||
VARIANT_BOOL bRet = false;
|
||||
pNSC->get_SharingEnabled(&bRet);
|
||||
*pIsEnable = bRet;
|
||||
hr = pNSC->get_SharingEnabled(&bRet);
|
||||
pNSC->Release();
|
||||
|
||||
if (hr != S_OK) {
|
||||
SPDLOG_ERROR(TEXT("INetSharingManager DisableSharing failed: {0}."), hr);
|
||||
return -ERR_CALL_COMMOBJECT;
|
||||
}
|
||||
|
||||
*pIsEnable = bRet;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -786,69 +1059,185 @@ int GetNetConnectionSharing(const TCHAR *pInterfaceName, bool *pIsEnable) {
|
|||
return ERR_ITEM_UNEXISTS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 添加系统路由表项
|
||||
* @param[in] ifIndex 网卡 Index
|
||||
* @param[in] pIP 目的 IP 地址
|
||||
* @param[in] pMask 目的子网掩码
|
||||
* @param[in] pGateway 路由网关
|
||||
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
|
||||
* - -ERR_INPUT_PARAMS 输入参数错误
|
||||
* - -ERR_UN_SUPPORT IP地址转网络字节序网络地址失败
|
||||
* - -ERR_NET_ADD_ROUTE 添加路由表项失败
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
int AddRouteTable(int ifIndex, const char *pIP, const char *pMask, const char *pGateway) {
|
||||
MIB_IPFORWARDROW IpForwardTable;
|
||||
int AddRouteTable(const char *pIP, const char *pMask, const char *pGateway) {
|
||||
PMIB_IPFORWARDTABLE pIpForwardTable = nullptr;
|
||||
PMIB_IPFORWARDROW pRow = nullptr;
|
||||
DWORD dwSize = 0;
|
||||
DWORD dwStatus;
|
||||
DWORD dwDestIp;
|
||||
int ret;
|
||||
IP_INFO ipInfo;
|
||||
|
||||
if (pIP == nullptr || lstrlen(pIP) < 8) {
|
||||
if (pIP == nullptr || lstrlen(pIP) < MIN_IP_LEN) {
|
||||
SPDLOG_ERROR(TEXT("Input pIP params error: {0}"), pIP);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if (pMask == nullptr || lstrlen(pMask) < 8) {
|
||||
if (pMask == nullptr || lstrlen(pMask) < MIN_IP_LEN) {
|
||||
SPDLOG_ERROR(TEXT("Input pMask params error: {0}"), pMask);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if (pGateway == nullptr || lstrlen(pGateway) < 8) {
|
||||
if (pGateway == nullptr || lstrlen(pGateway) < MIN_IP_LEN) {
|
||||
SPDLOG_ERROR(TEXT("Input pGateway params error: {0}"), pGateway);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
ZeroMemory(&IpForwardTable, sizeof(MIB_IPFORWARDROW));
|
||||
if ((ret = GetIpV4InfoFromNetmask(pIP, pMask, &ipInfo)) != ERR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (inet_pton(AF_INET, pIP, &IpForwardTable.dwForwardDest) <= 0) {
|
||||
if (inet_pton(AF_INET, ipInfo.network, &dwDestIp) <= 0) {
|
||||
SPDLOG_ERROR(TEXT("Convert {0} to network ipaddress error."), pIP);
|
||||
return -ERR_UN_SUPPORT;
|
||||
}
|
||||
|
||||
if (inet_pton(AF_INET, pMask, &IpForwardTable.dwForwardMask) <= 0) {
|
||||
// Find out how big our buffer needs to be.
|
||||
dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, FALSE);
|
||||
if (dwStatus == ERROR_INSUFFICIENT_BUFFER) {
|
||||
// Allocate the memory for the table
|
||||
pIpForwardTable = static_cast<PMIB_IPFORWARDTABLE>(malloc(dwSize));
|
||||
if (!pIpForwardTable) {
|
||||
SPDLOG_ERROR(TEXT("Malloc failed. Out of memory."));
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
// Now get the table.
|
||||
dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, FALSE);
|
||||
}
|
||||
|
||||
if (dwStatus != ERROR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("getIpForwardTable failed."));
|
||||
if (pIpForwardTable) {
|
||||
free(pIpForwardTable);
|
||||
}
|
||||
return -ERR_SYS_CALL;
|
||||
}
|
||||
|
||||
for (DWORD i = 0; i < pIpForwardTable->dwNumEntries; i++) {
|
||||
if (pIpForwardTable->table[i].dwForwardDest == 0) {
|
||||
if (!pRow) {
|
||||
pRow = static_cast<PMIB_IPFORWARDROW>(malloc(sizeof(MIB_IPFORWARDROW)));
|
||||
if (!pRow) {
|
||||
SPDLOG_ERROR(TEXT("Malloc failed. Out of memory."));
|
||||
free(pIpForwardTable);
|
||||
free(pRow);
|
||||
return -ERR_MALLOC_MEMORY;
|
||||
}
|
||||
// Copy the row
|
||||
memcpy(pRow, &(pIpForwardTable->table[i]), sizeof(MIB_IPFORWARDROW));
|
||||
}
|
||||
} else if (pIpForwardTable->table[i].dwForwardDest == dwDestIp) {
|
||||
// 删除可能存在的旧的路由信息
|
||||
dwStatus = DeleteIpForwardEntry(&(pIpForwardTable->table[i]));
|
||||
|
||||
if (dwStatus != ERROR_SUCCESS) {
|
||||
SPDLOG_ERROR(TEXT("Could not delete old gateway"));
|
||||
return -ERR_NET_REMOVE_ROUTE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(pIpForwardTable);
|
||||
|
||||
pRow->dwForwardDest = dwDestIp;
|
||||
|
||||
if (inet_pton(AF_INET, ipInfo.netmask, &pRow->dwForwardMask) <= 0) {
|
||||
SPDLOG_ERROR(TEXT("Convert {0} to network ipaddress error."), pMask);
|
||||
return -ERR_UN_SUPPORT;
|
||||
}
|
||||
|
||||
if (inet_pton(AF_INET, pGateway, &IpForwardTable.dwForwardNextHop) <= 0) {
|
||||
if (inet_pton(AF_INET, pGateway, &pRow->dwForwardNextHop) <= 0) {
|
||||
SPDLOG_ERROR(TEXT("Convert {0} to network ipaddress error."), pGateway);
|
||||
free(pRow);
|
||||
return -ERR_UN_SUPPORT;
|
||||
}
|
||||
|
||||
IpForwardTable.dwForwardIfIndex = ifIndex;
|
||||
IpForwardTable.dwForwardType = MIB_IPROUTE_TYPE_DIRECT;
|
||||
IpForwardTable.dwForwardProto = MIB_IPPROTO_LOCAL;
|
||||
IpForwardTable.dwForwardPolicy = 0;
|
||||
IpForwardTable.dwForwardAge = 0;
|
||||
IpForwardTable.dwForwardNextHopAS = 0;
|
||||
IpForwardTable.dwForwardMetric1 = 0xFFFFFFFF;
|
||||
IpForwardTable.dwForwardMetric2 = 0xFFFFFFFF;
|
||||
IpForwardTable.dwForwardMetric3 = 0xFFFFFFFF;
|
||||
IpForwardTable.dwForwardMetric4 = 0xFFFFFFFF;
|
||||
IpForwardTable.dwForwardMetric5 = 0xFFFFFFFF;
|
||||
if ((ret = GetInterfaceIfIndexByIpAddr(pGateway, &pRow->dwForwardIfIndex)) != ERR_SUCCESS) {
|
||||
free(pRow);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (CreateIpForwardEntry(&IpForwardTable) != NO_ERROR) {
|
||||
if ((dwStatus = CreateIpForwardEntry(pRow)) != NO_ERROR) {
|
||||
SPDLOG_ERROR(TEXT("Add Route {1} netmask {2} gateway {3} error: {0}."), dwStatus, pIP, pMask, pGateway);
|
||||
free(pRow);
|
||||
return -ERR_NET_ADD_ROUTE;
|
||||
}
|
||||
|
||||
free(pRow);
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
int SetNATRule(const TCHAR *pInterfaceName, const TCHAR *pCidrIpaddr) {
|
||||
int ret;
|
||||
TCHAR cmdBuf[1024];
|
||||
DWORD retCode;
|
||||
|
||||
if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) {
|
||||
SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if (pCidrIpaddr == nullptr || lstrlen(pCidrIpaddr) == 0) {
|
||||
SPDLOG_ERROR("Input pCidrIpaddr params error: {0}", pCidrIpaddr);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if (FAILED(StringCbPrintf(
|
||||
cmdBuf,
|
||||
1024,
|
||||
TEXT("PowerShell -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass Invoke-Command "
|
||||
"-ScriptBlock { Get-NetNat -Name %s_nat -ErrorAction Ignore | Remove-NetNat -Confirm:$false; "
|
||||
"New-NetNat -Name %s_nat -InternalIPInterfaceAddressPrefix %s }"),
|
||||
pInterfaceName,
|
||||
pInterfaceName,
|
||||
pCidrIpaddr))) {
|
||||
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 Command({1}): {0}", cmdBuf, retCode);
|
||||
|
||||
if (retCode != 0) {
|
||||
SPDLOG_ERROR("PowerShell return error({1}): {0}", cmdBuf, retCode);
|
||||
return -ERR_PROCESS_RETURN;
|
||||
}
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
int RemoveNATRule(const TCHAR *pInterfaceName) {
|
||||
int ret;
|
||||
TCHAR cmdBuf[1024];
|
||||
DWORD retCode;
|
||||
|
||||
if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) {
|
||||
SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if (FAILED(StringCbPrintf(
|
||||
cmdBuf,
|
||||
1024,
|
||||
TEXT("PowerShell -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass Invoke-Command "
|
||||
"-ScriptBlock { Get-NetNat -Name %s_nat -ErrorAction Ignore | Remove-NetNat -Confirm:$false}"),
|
||||
pInterfaceName))) {
|
||||
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 Command({1}): {0}", cmdBuf, retCode);
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -966,74 +1355,6 @@ int GetInterfaceIndexByName(const TCHAR *pInterfaceName, int *pIndex) {
|
|||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
int SetNATRule(const TCHAR *pInterfaceName, const TCHAR *pCidrIpaddr) {
|
||||
int ret;
|
||||
TCHAR cmdBuf[MAX_PATH];
|
||||
DWORD retCode;
|
||||
|
||||
if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) {
|
||||
SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if (pCidrIpaddr == nullptr || lstrlen(pCidrIpaddr) == 0) {
|
||||
SPDLOG_ERROR("Input pCidrIpaddr params error: {0}", pCidrIpaddr);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if (FAILED(
|
||||
StringCbPrintf(cmdBuf,
|
||||
MAX_PATH,
|
||||
"PowerShell -Command \"& {New-NetNat -Name %s_nat -InternalIPInterfaceAddressPrefix %s}\"",
|
||||
pInterfaceName,
|
||||
pCidrIpaddr))) {
|
||||
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);
|
||||
|
||||
if (retCode != 0) {
|
||||
SPDLOG_ERROR("PowerShell return error({1}): {0}", cmdBuf, retCode);
|
||||
return -ERR_PROCESS_RETURN;
|
||||
}
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
int RemoveNATRule(const TCHAR *pInterfaceName) {
|
||||
int ret;
|
||||
TCHAR cmdBuf[MAX_PATH];
|
||||
DWORD retCode;
|
||||
|
||||
if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) {
|
||||
SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName);
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
|
||||
if (FAILED(StringCbPrintf(cmdBuf,
|
||||
MAX_PATH,
|
||||
"PowerShell -Command \"& {Remove-NetNat -Name %s_nat -Confirm:$false}\"",
|
||||
pInterfaceName))) {
|
||||
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;
|
||||
}
|
||||
|
||||
int RemoveInterfaceIpAddress(const TCHAR *pInterfaceName) {
|
||||
int ret;
|
||||
TCHAR cmdBuf[MAX_PATH];
|
||||
|
|
|
@ -40,12 +40,26 @@ TUNNEL_API int __cdecl GetAllNICInfo(PNIC_CONTENT *pInfo, int *pItemCounts);
|
|||
|
||||
/**
|
||||
* @brief 获取当前 Internet 网卡名
|
||||
* @param ifName 网卡名称
|
||||
* @param[out] pIfIndex 网卡索引
|
||||
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
|
||||
* - -ERR_INPUT_PARAMS 输入参数错误
|
||||
* - -ERR_ITEM_UNEXISTS 未找到具有 Internet 连接的网卡
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
TUNNEL_API int __cdecl GetInternetIfName(TCHAR ifName[MAX_NETCARD_NAME]);
|
||||
TUNNEL_API int __cdecl GetInternetIfIndex(int *pIfIndex);
|
||||
|
||||
/**
|
||||
* @brief 根据网卡 IP地址 获取网卡索引
|
||||
* @param[in] pIpAddr 网卡IP地址
|
||||
* @param[out] pIfIndex 网卡索引编号
|
||||
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
|
||||
* - -ERR_INPUT_PARAMS 输入参数错误
|
||||
* - -ERR_MALLOC_MEMORY 分配内存失败
|
||||
* - -ERR_ITEM_UNEXISTS 找不到合适的网卡
|
||||
* - -ERR_UN_SUPPORT 系统不支持该操作
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
TUNNEL_API int __cdecl GetInterfaceIfIndexByIpAddr(const TCHAR *pIpAddr, ULONG *pIfIndex);
|
||||
|
||||
/**
|
||||
* @brief 根据网卡 GUDI 获取网卡名称
|
||||
|
@ -61,6 +75,32 @@ TUNNEL_API int __cdecl GetInternetIfName(TCHAR ifName[MAX_NETCARD_NAME]);
|
|||
*/
|
||||
TUNNEL_API int __cdecl GetInterfaceNameByGUID(const TCHAR *pGUID, TCHAR ifName[MAX_NETCARD_NAME]);
|
||||
|
||||
/**
|
||||
* @brief 根据网卡名获取网卡索引
|
||||
* @param[in] pInterfaceName 网卡名称
|
||||
* @param[out] pIfIndex 网卡 Index
|
||||
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
|
||||
* - -ERR_INPUT_PARAMS 输入参数错误
|
||||
* - -ERR_ITEM_UNEXISTS 网卡不存在
|
||||
* - -ERR_SYS_CALL 获取操作系统网卡适配器失败
|
||||
* - -ERR_MALLOC_MEMORY 分配内存失败
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
TUNNEL_API int __cdecl GetInterfaceIfIndexByName(const TCHAR *pInterfaceName, int *pIfIndex);
|
||||
|
||||
/**
|
||||
* @brief 根据网卡名获取网卡 GUID
|
||||
* @param[in] ifIndex 网卡索引
|
||||
* @param[out] pGuid 网卡 GUID
|
||||
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
|
||||
* - -ERR_INPUT_PARAMS 输入参数错误
|
||||
* - -ERR_ITEM_UNEXISTS 网卡不存在
|
||||
* - -ERR_MEMORY_STR 字符串转 GUID 结构体失败
|
||||
* - -ERR_MALLOC_MEMORY 分配内存失败
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
TUNNEL_API int __cdecl GetInterfaceGUIDByIfIndex(const int ifIndex, GUID *pGuid);
|
||||
|
||||
/**
|
||||
* @brief 根据网卡名获取网卡 GUID
|
||||
* @param[in] pInterfaceName 网卡名称
|
||||
|
@ -107,7 +147,7 @@ TUNNEL_API int __cdecl GetNetConnectionNetworkCategory(const TCHAR *pInterfaceNa
|
|||
|
||||
/**
|
||||
* @brief 启动/停止 Windows 网络共享服务
|
||||
* @param[in] pInterfaceName pInterfaceName 网卡名称
|
||||
* @param[in] ifIndex 网卡索引
|
||||
* @param[in] isEnable 启动/停止 Windows 网络共享服务
|
||||
* - TRUE 启动服务
|
||||
* - FALSE 停止服务
|
||||
|
@ -122,11 +162,11 @@ TUNNEL_API int __cdecl GetNetConnectionNetworkCategory(const TCHAR *pInterfaceNa
|
|||
* - -ERR_NET_UNCONNECT 网络未连接
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
NETWORK_API int __cdecl SetNetConnectionSharing(const TCHAR *pInterfaceName, bool isEnable, bool isSetPrivate);
|
||||
NETWORK_API int __cdecl SetNetIntelnetConnectionSharing(int ifIndex, bool isEnable, bool isSetPrivate);
|
||||
|
||||
/**
|
||||
* @brief 获取当前网络共享服务状态
|
||||
* @param[in] pInterfaceName pInterfaceName 网卡名称
|
||||
* @param[in] ifIndex 网卡名称索引
|
||||
* @param[out] pIsEnable 当前网络共享服务状态
|
||||
* - TRUE 启动
|
||||
* - FALSE 停止
|
||||
|
@ -136,9 +176,10 @@ NETWORK_API int __cdecl SetNetConnectionSharing(const TCHAR *pInterfaceName, boo
|
|||
* - -ERR_SYS_CALL 调用 COM 接口失败
|
||||
* - -ERR_ITEM_UNEXISTS GUID 不存在
|
||||
* - -ERR_NET_UNCONNECT 网络未连接
|
||||
* - -ERR_CALL_COMMOBJECT 获取网络共享状态失败
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
NETWORK_API int __cdecl GetNetConnectionSharing(const TCHAR *pInterfaceName, bool *pIsEnable);
|
||||
NETWORK_API int __cdecl GetNetIntelnetConnectionSharing(int ifIndex, bool *pIsEnable);
|
||||
/**
|
||||
* @brief 设置网卡为 Private/Public 模式
|
||||
* @param[in] pInterfaceName pInterfaceName 网卡名称
|
||||
|
@ -156,7 +197,6 @@ NETWORK_API int __cdecl SetNetConnectionNetworkCategory(const TCHAR *pInterfaceN
|
|||
|
||||
/**
|
||||
* @brief 添加系统路由表项
|
||||
* @param[in] ifIndex 网卡 Index
|
||||
* @param[in] pIP 目的 IP 地址
|
||||
* @param[in] pMask 目的子网掩码
|
||||
* @param[in] pGateway 路由网关
|
||||
|
@ -164,10 +204,38 @@ NETWORK_API int __cdecl SetNetConnectionNetworkCategory(const TCHAR *pInterfaceN
|
|||
* - -ERR_INPUT_PARAMS 输入参数错误
|
||||
* - -ERR_UN_SUPPORT IP地址转网络字节序网络地址失败
|
||||
* - -ERR_NET_ADD_ROUTE 添加路由表项失败
|
||||
* - -ERR_NET_REMOVE_ROUTE 删除路由表项失败
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
NETWORK_API int __cdecl AddRouteTable(int ifIndex, const char *pIP, const char *pMask, const char *pGateway);
|
||||
NETWORK_API int __cdecl AddRouteTable(const char *pIP, const char *pMask, const char *pGateway);
|
||||
|
||||
/**
|
||||
* @brief 开启 Windows WireGuard NAT 转发功能
|
||||
* @param[in] pInterfaceName 网卡名称
|
||||
* @param[in] pCidrIpaddr CIDR 网络接口地址
|
||||
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
|
||||
* - -ERR_INPUT_PARAMS 输入参数错误
|
||||
* - -ERR_MEMORY_STR 字符串处理
|
||||
* - -ERR_CALL_SHELL 调用系统命令行失败
|
||||
* - -ERR_PROCESS_RETURN 系统调用执行结束返回失败
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
TUNNEL_API int __cdecl SetNATRule(const TCHAR *pInterfaceName, const TCHAR *pCidrIpaddr);
|
||||
|
||||
/**
|
||||
* @brief 关闭 Windows WireGuard NAT 转发功能
|
||||
* @param pInterfaceName 网卡名称
|
||||
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
|
||||
* - -ERR_INPUT_PARAMS 输入参数错误
|
||||
* - -ERR_MEMORY_STR 字符串处理
|
||||
* - -ERR_CALL_SHELL 调用系统命令行失败
|
||||
* - -ERR_PROCESS_RETURN 系统调用执行结束返回失败
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
TUNNEL_API int __cdecl RemoveNATRule(const TCHAR *pInterfaceName);
|
||||
|
||||
|
||||
TUNNEL_API int __cdecl CreatePorxyService();
|
||||
#if 0
|
||||
/**
|
||||
* @brief 获取Windows Hyper-V 虚拟机状态, 必须开启后才能开启NAT转发功能
|
||||
|
@ -192,19 +260,6 @@ TUNNEL_API int __cdecl GetWindowsHyperVStatus(int *pEnabled);
|
|||
*/
|
||||
TUNNEL_API int __cdecl EnableWindowsHyperV(bool enabled);
|
||||
|
||||
/**
|
||||
* @brief 开启 Windows WireGuard NAT 转发功能
|
||||
* @param[in] pInterfaceName 网卡名称
|
||||
* @param[in] pCidrIpaddr CIDR 网络接口地址
|
||||
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
|
||||
* - -ERR_INPUT_PARAMS 输入参数错误
|
||||
* - -ERR_MEMORY_STR 字符串处理
|
||||
* - -ERR_CALL_SHELL 调用系统命令行失败
|
||||
* - -ERR_PROCESS_RETURN 系统调用执行结束返回失败
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
TUNNEL_API int __cdecl SetNATRule(const TCHAR *pInterfaceName, const TCHAR *pCidrIpaddr);
|
||||
|
||||
/**
|
||||
* @brief 设置网卡为 Private/Public 模式
|
||||
* @param[in] pInterfaceName 网卡名称
|
||||
|
|
|
@ -25,6 +25,18 @@ int InitControlServer(const TCHAR *pUserSvrUrl) {
|
|||
|
||||
g_tunnelHttpCtx = new httplib::Client(pUserSvrUrl);
|
||||
|
||||
if (g_tunnelHttpCtx) {
|
||||
g_tunnelHttpCtx->set_connection_timeout(0, 1000000); // 1 second
|
||||
g_tunnelHttpCtx->set_read_timeout(5, 0); // 5 seconds
|
||||
g_tunnelHttpCtx->set_write_timeout(5, 0); // 5 seconds
|
||||
g_tunnelHttpCtx->set_post_connect_cb([](socket_t sock) {
|
||||
SPDLOG_DEBUG(TEXT("Service Connected: {0}"), sock);
|
||||
|
||||
// TODO Send SCG Message
|
||||
// send(sock, ..... GetGlobalCfgInfo()->curConnVmId
|
||||
});
|
||||
}
|
||||
|
||||
SPDLOG_DEBUG(TEXT("Connect to Tunnel Control Service: {0}"), pUserSvrUrl);
|
||||
|
||||
return ERR_SUCCESS;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 159 KiB |
|
@ -6,12 +6,17 @@
|
|||
#include <spdlog/sinks/wincolor_sink.h>
|
||||
#include <spdlog/sinks/rotating_file_sink.h>
|
||||
#include <spdlog/sinks/dup_filter_sink.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include "usrerr.h"
|
||||
#include "globalcfg.h"
|
||||
#include "misc.h"
|
||||
#include "user.h"
|
||||
|
||||
#include <shlwapi.h>
|
||||
#include <ws2def.h>
|
||||
|
||||
#pragma comment(lib, "Dbghelp.lib")
|
||||
|
||||
#define CONFIG_FILE_NAME TEXT("tunnelsdk.ini")
|
||||
|
||||
|
@ -21,70 +26,6 @@ PSDK_CONFIG GetGlobalCfgInfo() {
|
|||
return &g_globalConfig;
|
||||
}
|
||||
|
||||
int TunnelSDKInitEnv(const TCHAR *pWorkDir, const TCHAR *pSvrUrl, bool isWorkServer) {
|
||||
size_t length;
|
||||
const BOOL logEnable = g_globalConfig.enableLog;
|
||||
const spdlog::level::level_enum lv = g_globalConfig.logLevel;
|
||||
|
||||
memset(&g_globalConfig, 0, sizeof(SDK_CONFIG));
|
||||
|
||||
g_globalConfig.isWorkServer = isWorkServer;
|
||||
|
||||
// 创建配置文件存储目录
|
||||
if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_NO_ALIAS, NULL, 0, g_globalConfig.configDirectory))) {
|
||||
SPDLOG_ERROR(TEXT("Get Windows system directory error."));
|
||||
return -ERR_SYS_CALL;
|
||||
}
|
||||
|
||||
StringCbCat(g_globalConfig.configDirectory, MAX_PATH, "\\NetTunnel");
|
||||
SPDLOG_DEBUG(TEXT("Configure directory: {0}."), g_globalConfig.configDirectory);
|
||||
|
||||
// 如果配置目录不存在则自动创建
|
||||
if (!PathFileExists(g_globalConfig.configDirectory)) {
|
||||
if (!CreateDirectory(g_globalConfig.configDirectory, nullptr)) {
|
||||
SPDLOG_ERROR(TEXT("Create configure directory '{0}' error."), g_globalConfig.configDirectory);
|
||||
return -ERR_CREATE_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
StringCbCopy(g_globalConfig.platformServerUrl, MAX_IP_LEN, pSvrUrl);
|
||||
|
||||
g_globalConfig.logLevel = lv;
|
||||
g_globalConfig.enableLog = logEnable;
|
||||
|
||||
if (!logEnable) {
|
||||
spdlog::set_level(spdlog::level::off);
|
||||
}
|
||||
|
||||
if (FAILED(SHGetFolderPath(NULL, CSIDL_WINDOWS | CSIDL_FLAG_NO_ALIAS, NULL, 0, g_globalConfig.systemDirectory))) {
|
||||
SPDLOG_ERROR(TEXT("Get Windows system directory error."));
|
||||
return -ERR_SYS_CALL;
|
||||
}
|
||||
|
||||
if (pWorkDir == nullptr) {
|
||||
// 获取当前文件默认路径
|
||||
GetCurrentDirectory(MAX_PATH, g_globalConfig.workDirectory);
|
||||
} else {
|
||||
if (StringCbLengthA(pWorkDir, MAX_PATH, &length) == S_OK && length == 0) {
|
||||
GetCurrentDirectory(MAX_PATH, g_globalConfig.workDirectory);
|
||||
} else {
|
||||
StringCbCopy(g_globalConfig.workDirectory, MAX_PATH, pWorkDir);
|
||||
}
|
||||
}
|
||||
|
||||
StringCbPrintf(g_globalConfig.cfgPath, MAX_PATH, TEXT("%s\\%s"), g_globalConfig.workDirectory, CONFIG_FILE_NAME);
|
||||
|
||||
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_SUCCESS;
|
||||
}
|
||||
|
||||
void TunnelSDKUnInit() {
|
||||
}
|
||||
|
||||
static spdlog::level::level_enum logLevelToSpdlogLevel(LOG_LEVEL level) {
|
||||
switch (level) {
|
||||
case LOG_TRACE:
|
||||
|
@ -106,13 +47,17 @@ static spdlog::level::level_enum logLevelToSpdlogLevel(LOG_LEVEL level) {
|
|||
return spdlog::level::level_enum::info;
|
||||
}
|
||||
|
||||
void InitTunnelSDKLog(const TCHAR *pLogFile, LOG_LEVEL level) {
|
||||
static void InitTunnelSDKLog(const TCHAR *pLogFile, LOG_LEVEL level) {
|
||||
TCHAR buf[MAX_PATH] = {0};
|
||||
|
||||
if (pLogFile && strlen(pLogFile) > 0) {
|
||||
if (pLogFile && strlen(pLogFile) > 0 && !PathIsRelative(pLogFile)) {
|
||||
TCHAR tmpPath[MAX_PATH];
|
||||
StringCbCopy(tmpPath, MAX_PATH, pLogFile);
|
||||
PathRemoveFileSpec(tmpPath);
|
||||
MakeSureDirectoryPathExists(tmpPath);
|
||||
StringCbCopy(buf, MAX_PATH, pLogFile);
|
||||
} else {
|
||||
StringCbCopy(buf, MAX_PATH, TEXT("tunnelsdk.log"));
|
||||
StringCbPrintf(buf, MAX_PATH, TEXT("%s\\tunnelsdklog.log"), g_globalConfig.workDirectory);
|
||||
}
|
||||
|
||||
g_globalConfig.enableLog = TRUE;
|
||||
|
@ -144,6 +89,83 @@ void InitTunnelSDKLog(const TCHAR *pLogFile, LOG_LEVEL level) {
|
|||
SPDLOG_INFO(TEXT("Log({1}): {0}"), buf, static_cast<int>(level));
|
||||
}
|
||||
|
||||
int TunnelSDKInitEnv(const TCHAR *pWorkDir,
|
||||
const TCHAR *pSvrUrl,
|
||||
const TCHAR *pLogFile,
|
||||
LOG_LEVEL level,
|
||||
bool isWorkServer) {
|
||||
size_t length;
|
||||
|
||||
memset(&g_globalConfig, 0, sizeof(SDK_CONFIG));
|
||||
|
||||
g_globalConfig.isWorkServer = isWorkServer;
|
||||
g_globalConfig.usedSCGProxy = false;
|
||||
|
||||
if (pWorkDir == nullptr) {
|
||||
// 获取当前文件默认路径
|
||||
GetModuleFileName(nullptr, g_globalConfig.workDirectory, MAX_PATH);
|
||||
PathRemoveFileSpec(g_globalConfig.workDirectory);
|
||||
} else {
|
||||
if (StringCbLength(pWorkDir, MAX_PATH, &length) == S_OK && length == 0 || PathIsRelative(pWorkDir)) {
|
||||
// 获取当前文件默认路径
|
||||
GetModuleFileName(nullptr, g_globalConfig.workDirectory, MAX_PATH);
|
||||
PathRemoveFileSpec(g_globalConfig.workDirectory);
|
||||
} else {
|
||||
MakeSureDirectoryPathExists(pWorkDir);
|
||||
StringCbCopy(g_globalConfig.workDirectory, MAX_PATH, pWorkDir);
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化日志
|
||||
InitTunnelSDKLog(pLogFile, level);
|
||||
|
||||
// 创建配置文件存储目录
|
||||
if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_NO_ALIAS, NULL, 0, g_globalConfig.configDirectory))) {
|
||||
SPDLOG_ERROR(TEXT("Get Windows system directory error."));
|
||||
return -ERR_SYS_CALL;
|
||||
}
|
||||
|
||||
StringCbCat(g_globalConfig.configDirectory, MAX_PATH, "\\NetTunnel");
|
||||
SPDLOG_DEBUG(TEXT("Configure directory: {0}."), g_globalConfig.configDirectory);
|
||||
|
||||
// 如果配置目录不存在则自动创建
|
||||
if (!PathFileExists(g_globalConfig.configDirectory)) {
|
||||
if (!CreateDirectory(g_globalConfig.configDirectory, nullptr)) {
|
||||
SPDLOG_ERROR(TEXT("Create configure directory '{0}' error."), g_globalConfig.configDirectory);
|
||||
return -ERR_CREATE_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
StringCbCopy(g_globalConfig.platformServerUrl, MAX_IP_LEN, pSvrUrl);
|
||||
|
||||
if (FAILED(SHGetFolderPath(NULL, CSIDL_WINDOWS | CSIDL_FLAG_NO_ALIAS, NULL, 0, g_globalConfig.systemDirectory))) {
|
||||
SPDLOG_ERROR(TEXT("Get Windows system directory error."));
|
||||
return -ERR_SYS_CALL;
|
||||
}
|
||||
|
||||
StringCbPrintf(g_globalConfig.cfgPath, MAX_PATH, TEXT("%s\\%s"), g_globalConfig.workDirectory, CONFIG_FILE_NAME);
|
||||
|
||||
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_SUCCESS;
|
||||
}
|
||||
|
||||
void TunnelSDKUnInit() {
|
||||
RemoteWireGuardControl(false);
|
||||
LocalWireGuardControl(false, false);
|
||||
}
|
||||
|
||||
void EnableSCGProxy(bool isEnable) {
|
||||
g_globalConfig.usedSCGProxy = isEnable;
|
||||
}
|
||||
|
||||
bool GetSCGProxyStatus() {
|
||||
return g_globalConfig.usedSCGProxy;
|
||||
}
|
||||
|
||||
void TunnelLogEnable(bool enLog) {
|
||||
if (enLog) {
|
||||
spdlog::set_level(g_globalConfig.logLevel);
|
||||
|
@ -154,7 +176,7 @@ 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) {
|
||||
if (pProKey == nullptr || strlen(pProKey) < MIN_IP_LEN) {
|
||||
return -ERR_INPUT_PARAMS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ constexpr auto WG_KEY_MAX = (64);
|
|||
*/
|
||||
#define MAX_IP_LEN (48)
|
||||
|
||||
/**
|
||||
* @brief IP 字符串最小长度
|
||||
*/
|
||||
#define MIN_IP_LEN (7)
|
||||
|
||||
/**
|
||||
* @brief 网卡名称字符串最大长度(支持IPv6)
|
||||
*/
|
||||
|
@ -79,6 +84,15 @@ typedef enum {
|
|||
CHK_MAX
|
||||
} CHECK_FUNCTION;
|
||||
|
||||
/**
|
||||
* @brief 网络共享模式
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
ICS_SHARE_MODE = 0, ///< Internet Share Mode(ICS) 模式
|
||||
NAT_SHARE_MODE = 1 ///< Net Address Translation(NAT) 模式
|
||||
} NET_SHARE_MODE;
|
||||
|
||||
typedef struct {
|
||||
CHECK_FUNCTION chk;
|
||||
bool result;
|
||||
|
@ -118,18 +132,38 @@ extern "C" {
|
|||
// we need to export the C interface
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief 获取当前网络共享模式
|
||||
* @return 当前网络共享模式 @see NET_SHARE_MODE
|
||||
*/
|
||||
TUNNEL_API NET_SHARE_MODE __cdecl GetCurrentNetShareMode();
|
||||
|
||||
/**
|
||||
* @brief 设置获取当前网络共享模式
|
||||
* @param shareMode 网络共享模式 @see NET_SHARE_MODE
|
||||
*/
|
||||
TUNNEL_API void __cdecl SetCurrentNetShareMode(NET_SHARE_MODE shareMode);
|
||||
|
||||
/**
|
||||
* @brief 初始化 SDK 运行环境
|
||||
* @param[in] pWorkDir 程序工作路径,如果不设置系统自动获取
|
||||
* @param[in] pSvrUrl 管理平台 URL 地址 example: http://localhost:2313, https://localhost:2313
|
||||
* @param[in] pLogFile 日志文件名称/完整路径
|
||||
* @param[in] level 日志最低有效等级
|
||||
* @param[in] isWorkServer SDK 工作模式
|
||||
* - TRUE 服务端
|
||||
* - FALSE 客户端
|
||||
* @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO
|
||||
* - -ERR_ITEM_EXISTS 未找到 WireGuard 程序
|
||||
* - -ERR_SYS_CALL 获取配置本地配置文件存储目录失败
|
||||
* - -ERR_CREATE_FILE 创建用户配置文件目录失败
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
TUNNEL_API int __cdecl TunnelSDKInitEnv(const TCHAR *pWorkDir, const TCHAR *pSvrUrl, bool isWorkServer);
|
||||
TUNNEL_API int __cdecl TunnelSDKInitEnv(const TCHAR *pWorkDir,
|
||||
const TCHAR *pSvrUrl,
|
||||
const TCHAR *pLogFile,
|
||||
LOG_LEVEL level,
|
||||
bool isWorkServer);
|
||||
|
||||
/**
|
||||
* @brief 设置传输协议加密方式,默认 CRYPTO_NONE
|
||||
|
@ -141,13 +175,6 @@ TUNNEL_API int __cdecl TunnelSDKInitEnv(const TCHAR *pWorkDir, const TCHAR *pSvr
|
|||
*/
|
||||
TUNNEL_API int __cdecl SetProtocolEncryptType(const PROTO_CRYPTO_TYPE type, const TCHAR *pProKey);
|
||||
|
||||
/**
|
||||
* @brief 初始化 SDK 日志
|
||||
* @param[in] pLogFile 日志文件名称/完整路径
|
||||
* @param[in] level 日志最低有效等级
|
||||
*/
|
||||
TUNNEL_API void __cdecl InitTunnelSDKLog(const TCHAR *pLogFile, LOG_LEVEL level);
|
||||
|
||||
/**
|
||||
* @brief 打开/关闭 SDK 日志开关
|
||||
* @param enLog 日志开关
|
||||
|
@ -287,6 +314,18 @@ TUNNEL_API int __cdecl IsWireGuardServerRunning(const TCHAR *pIfName, bool *pIsR
|
|||
*/
|
||||
TUNNEL_API void __cdecl TunnelSDKUnInit();
|
||||
|
||||
/**
|
||||
* @brief SCG 代理服务开关
|
||||
* @param isEnable TRUE: 启动 SCG 代理, FALSE: 禁用 SCG 代理
|
||||
*/
|
||||
TUNNEL_API void __cdecl EnableSCGProxy(bool isEnable);
|
||||
|
||||
/**
|
||||
* @brief 获取当前 SCG 代理服务状态
|
||||
* @return TRUE: SCG 代理启动, FALSE: SCG 代理禁用
|
||||
*/
|
||||
TUNNEL_API bool __cdecl GetSCGProxyStatus();
|
||||
|
||||
/**
|
||||
* @brief 计算文件 Hash
|
||||
* @param[in] type Hash 类型 @see HASH_TYPE
|
||||
|
|
|
@ -128,6 +128,7 @@ USERMANAGER_API int __cdecl RemoteWireGuardControl(bool isStart);
|
|||
* @return 0: 成功, 小于0 失败 @see USER_ERRNO
|
||||
* - -ERR_INPUT_PARAMS 输入参数错误
|
||||
* - -ERR_NET_CATEGORY_MODE 网卡工作模式错误
|
||||
* - -ERR_UN_SUPPORT 不支持的网络共享类型
|
||||
* - ERR_SUCCESS 成功
|
||||
*/
|
||||
USERMANAGER_API int __cdecl LocalWireGuardControl(bool isStart, bool setPrivateMode);
|
||||
|
|
|
@ -34,19 +34,29 @@ enum USER_ERRNO {
|
|||
ERR_CREATE_THREAD, ///< 创建线程失败
|
||||
ERR_CREATE_TIMER, ///< 创建定时器失败
|
||||
ERR_DELETE_TIMER, ///< 销毁定时器失败
|
||||
ERR_SOCKET_CREATE, ///< 创建 SOCKET 失败
|
||||
ERR_SOCKET_BIND, ///< 绑定 SOCKET 端口失败
|
||||
ERR_SOCKET_CONNECT, ///< 连接 TCP SOCKET 服务器失败
|
||||
ERR_SOCKET_LISTEN, ///< TCP SOCKET 服务监听失败
|
||||
ERR_SOCKET_BIND_PORT, ///< 绑定端口失败
|
||||
ERR_SOCKET_SET_OPT, ///< 设置 SOCKET 参数失败
|
||||
ERR_SOCKET_GET_OPT, ///< 读取 SOCKET 参数失败
|
||||
ERR_BCRYPT_OPEN = 100, ///< 创建加密算法失败
|
||||
ERR_BCRYPT_GETPROPERTY, ///< 获取加密算法属性失败
|
||||
ERR_BCRYPT_CREATEHASH, ///< 创建 Hash 算法失败
|
||||
ERR_BCRYPT_HASHDATA, ///< 计算 Hash 数据失败
|
||||
ERR_BCRYPT_FINISHHASH, ///< 计算 Hash 结果失败
|
||||
ERR_NET_UNCONNECT = 100, ///< 网络未连接
|
||||
ERR_NET_UNCONNECT = 200, ///< 网络未连接
|
||||
ERR_NET_CATEGORY_MODE, ///< 网络工作模式
|
||||
ERR_GET_IPFOWARDTBL = 200, ///< 获取系统 IP 转发表失败
|
||||
ERR_CREATE_COMMOBJECT = 300, ///< 创建 COM 对象失败
|
||||
ERR_JSON_CREATE = 400, ///< 创建 JSON 对象失败
|
||||
ERR_NET_INTELNEL_ICS, ///< 共享 Intelnet 网络 ICS 共享失败
|
||||
ERR_NET_WIREGUARD_ICS, ///< 共享 WireGuard 网络 ICS 共享失败
|
||||
ERR_GET_IPFOWARDTBL = 300, ///< 获取系统 IP 转发表失败
|
||||
ERR_CREATE_COMMOBJECT = 400, ///< 创建 COM 对象失败
|
||||
ERR_CALL_COMMOBJECT, ///< 调用 COM 对象失败
|
||||
ERR_JSON_CREATE = 500, ///< 创建 JSON 对象失败
|
||||
ERR_JSON_DECODE, ///< 从 JSON 反序列化对象失败
|
||||
ERR_HTTP_SERVER_RSP = 500, ///< HTTP 服务端返回错误
|
||||
ERR_HTTP_SERVER_RSP = 600, ///< HTTP 服务端返回错误
|
||||
ERR_HTTP_POST_DATA, ///< 发送 POST 请求失败
|
||||
ERR_NET_ADD_ROUTE, ///< 添加路由失败
|
||||
ERR_NET_REMOVE_ROUTE, ///< 删除路由失败
|
||||
};
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
Copyright (c) 2008-2021, Troy D. Hanson http://troydhanson.github.com/uthash/
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* a dynamic array implementation using macros
|
||||
*/
|
||||
#ifndef UTARRAY_H
|
||||
#define UTARRAY_H
|
||||
|
||||
#define UTARRAY_VERSION 2.3.0
|
||||
|
||||
#include <stddef.h> /* size_t */
|
||||
#include <string.h> /* memset, etc */
|
||||
#include <stdlib.h> /* exit */
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define UTARRAY_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
#define UTARRAY_UNUSED
|
||||
#endif
|
||||
|
||||
#ifdef oom
|
||||
#error "The name of macro 'oom' has been changed to 'utarray_oom'. Please update your code."
|
||||
#define utarray_oom() oom()
|
||||
#endif
|
||||
|
||||
#ifndef utarray_oom
|
||||
#define utarray_oom() exit(-1)
|
||||
#endif
|
||||
|
||||
typedef void(ctor_f)(void *dst, const void *src);
|
||||
typedef void(dtor_f)(void *elt);
|
||||
typedef void(init_f)(void *elt);
|
||||
typedef struct {
|
||||
size_t sz;
|
||||
init_f *init;
|
||||
ctor_f *copy;
|
||||
dtor_f *dtor;
|
||||
} UT_icd;
|
||||
|
||||
typedef struct {
|
||||
unsigned i, n; /* i: index of next available slot, n: num slots */
|
||||
UT_icd icd; /* initializer, copy and destructor functions */
|
||||
char *d; /* n slots of size icd->sz*/
|
||||
} UT_array;
|
||||
|
||||
#define utarray_init(a, _icd) \
|
||||
do { \
|
||||
memset(a, 0, sizeof(UT_array)); \
|
||||
(a)->icd = *(_icd); \
|
||||
} while (0)
|
||||
|
||||
#define utarray_done(a) \
|
||||
do { \
|
||||
if ((a)->n) { \
|
||||
if ((a)->icd.dtor) { \
|
||||
unsigned _ut_i; \
|
||||
for (_ut_i = 0; _ut_i < (a)->i; _ut_i++) { \
|
||||
(a)->icd.dtor(utarray_eltptr(a, _ut_i)); \
|
||||
} \
|
||||
} \
|
||||
free((a)->d); \
|
||||
} \
|
||||
(a)->n = 0; \
|
||||
} while (0)
|
||||
|
||||
#define utarray_new(a, _icd) \
|
||||
do { \
|
||||
(a) = (UT_array *)malloc(sizeof(UT_array)); \
|
||||
if ((a) == NULL) { \
|
||||
utarray_oom(); \
|
||||
} \
|
||||
utarray_init(a, _icd); \
|
||||
} while (0)
|
||||
|
||||
#define utarray_free(a) \
|
||||
do { \
|
||||
utarray_done(a); \
|
||||
free(a); \
|
||||
} while (0)
|
||||
|
||||
#define utarray_reserve(a, by) \
|
||||
do { \
|
||||
if (((a)->i + (by)) > (a)->n) { \
|
||||
char *utarray_tmp; \
|
||||
while (((a)->i + (by)) > (a)->n) { \
|
||||
(a)->n = ((a)->n ? (2 * (a)->n) : 8); \
|
||||
} \
|
||||
utarray_tmp = (char *)realloc((a)->d, (a)->n * (a)->icd.sz); \
|
||||
if (utarray_tmp == NULL) { \
|
||||
utarray_oom(); \
|
||||
} \
|
||||
(a)->d = utarray_tmp; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define utarray_push_back(a, p) \
|
||||
do { \
|
||||
utarray_reserve(a, 1); \
|
||||
if ((a)->icd.copy) { \
|
||||
(a)->icd.copy(_utarray_eltptr(a, (a)->i++), p); \
|
||||
} else { \
|
||||
memcpy(_utarray_eltptr(a, (a)->i++), p, (a)->icd.sz); \
|
||||
}; \
|
||||
} while (0)
|
||||
|
||||
#define utarray_pop_back(a) \
|
||||
do { \
|
||||
if ((a)->icd.dtor) { \
|
||||
(a)->icd.dtor(_utarray_eltptr(a, --((a)->i))); \
|
||||
} else { \
|
||||
(a)->i--; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define utarray_extend_back(a) \
|
||||
do { \
|
||||
utarray_reserve(a, 1); \
|
||||
if ((a)->icd.init) { \
|
||||
(a)->icd.init(_utarray_eltptr(a, (a)->i)); \
|
||||
} else { \
|
||||
memset(_utarray_eltptr(a, (a)->i), 0, (a)->icd.sz); \
|
||||
} \
|
||||
(a)->i++; \
|
||||
} while (0)
|
||||
|
||||
#define utarray_len(a) ((a)->i)
|
||||
|
||||
#define utarray_eltptr(a, j) (((j) < (a)->i) ? _utarray_eltptr(a, j) : NULL)
|
||||
#define _utarray_eltptr(a, j) ((void *)((a)->d + ((a)->icd.sz * (j))))
|
||||
|
||||
#define utarray_insert(a, p, j) \
|
||||
do { \
|
||||
if ((j) > (a)->i) \
|
||||
utarray_resize(a, j); \
|
||||
utarray_reserve(a, 1); \
|
||||
if ((j) < (a)->i) { \
|
||||
memmove(_utarray_eltptr(a, (j) + 1), _utarray_eltptr(a, j), ((a)->i - (j)) * ((a)->icd.sz)); \
|
||||
} \
|
||||
if ((a)->icd.copy) { \
|
||||
(a)->icd.copy(_utarray_eltptr(a, j), p); \
|
||||
} else { \
|
||||
memcpy(_utarray_eltptr(a, j), p, (a)->icd.sz); \
|
||||
}; \
|
||||
(a)->i++; \
|
||||
} while (0)
|
||||
|
||||
#define utarray_inserta(a, w, j) \
|
||||
do { \
|
||||
if (utarray_len(w) == 0) \
|
||||
break; \
|
||||
if ((j) > (a)->i) \
|
||||
utarray_resize(a, j); \
|
||||
utarray_reserve(a, utarray_len(w)); \
|
||||
if ((j) < (a)->i) { \
|
||||
memmove(_utarray_eltptr(a, (j) + utarray_len(w)), _utarray_eltptr(a, j), ((a)->i - (j)) * ((a)->icd.sz)); \
|
||||
} \
|
||||
if ((a)->icd.copy) { \
|
||||
unsigned _ut_i; \
|
||||
for (_ut_i = 0; _ut_i < (w)->i; _ut_i++) { \
|
||||
(a)->icd.copy(_utarray_eltptr(a, (j) + _ut_i), _utarray_eltptr(w, _ut_i)); \
|
||||
} \
|
||||
} else { \
|
||||
memcpy(_utarray_eltptr(a, j), _utarray_eltptr(w, 0), utarray_len(w) * ((a)->icd.sz)); \
|
||||
} \
|
||||
(a)->i += utarray_len(w); \
|
||||
} while (0)
|
||||
|
||||
#define utarray_resize(dst, num) \
|
||||
do { \
|
||||
unsigned _ut_i; \
|
||||
if ((dst)->i > (unsigned)(num)) { \
|
||||
if ((dst)->icd.dtor) { \
|
||||
for (_ut_i = (num); _ut_i < (dst)->i; ++_ut_i) { \
|
||||
(dst)->icd.dtor(_utarray_eltptr(dst, _ut_i)); \
|
||||
} \
|
||||
} \
|
||||
} else if ((dst)->i < (unsigned)(num)) { \
|
||||
utarray_reserve(dst, (num) - (dst)->i); \
|
||||
if ((dst)->icd.init) { \
|
||||
for (_ut_i = (dst)->i; _ut_i < (unsigned)(num); ++_ut_i) { \
|
||||
(dst)->icd.init(_utarray_eltptr(dst, _ut_i)); \
|
||||
} \
|
||||
} else { \
|
||||
memset(_utarray_eltptr(dst, (dst)->i), 0, (dst)->icd.sz *((num) - (dst)->i)); \
|
||||
} \
|
||||
} \
|
||||
(dst)->i = (num); \
|
||||
} while (0)
|
||||
|
||||
#define utarray_concat(dst, src) \
|
||||
do { \
|
||||
utarray_inserta(dst, src, utarray_len(dst)); \
|
||||
} while (0)
|
||||
|
||||
#define utarray_erase(a, pos, len) \
|
||||
do { \
|
||||
if ((a)->icd.dtor) { \
|
||||
unsigned _ut_i; \
|
||||
for (_ut_i = 0; _ut_i < (len); _ut_i++) { \
|
||||
(a)->icd.dtor(utarray_eltptr(a, (pos) + _ut_i)); \
|
||||
} \
|
||||
} \
|
||||
if ((a)->i > ((pos) + (len))) { \
|
||||
memmove(_utarray_eltptr(a, pos), \
|
||||
_utarray_eltptr(a, (pos) + (len)), \
|
||||
((a)->i - ((pos) + (len))) * (a)->icd.sz); \
|
||||
} \
|
||||
(a)->i -= (len); \
|
||||
} while (0)
|
||||
|
||||
#define utarray_renew(a, u) \
|
||||
do { \
|
||||
if (a) \
|
||||
utarray_clear(a); \
|
||||
else \
|
||||
utarray_new(a, u); \
|
||||
} while (0)
|
||||
|
||||
#define utarray_clear(a) \
|
||||
do { \
|
||||
if ((a)->i > 0) { \
|
||||
if ((a)->icd.dtor) { \
|
||||
unsigned _ut_i; \
|
||||
for (_ut_i = 0; _ut_i < (a)->i; _ut_i++) { \
|
||||
(a)->icd.dtor(_utarray_eltptr(a, _ut_i)); \
|
||||
} \
|
||||
} \
|
||||
(a)->i = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define utarray_sort(a, cmp) \
|
||||
do { \
|
||||
qsort((a)->d, (a)->i, (a)->icd.sz, cmp); \
|
||||
} while (0)
|
||||
|
||||
#define utarray_find(a, v, cmp) bsearch((v), (a)->d, (a)->i, (a)->icd.sz, cmp)
|
||||
|
||||
#define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a, 0)) : NULL)
|
||||
#define utarray_next(a, e) \
|
||||
(((e) == NULL) ? utarray_front(a) \
|
||||
: (((a)->i != utarray_eltidx(a, e) + 1) ? _utarray_eltptr(a, utarray_eltidx(a, e) + 1) : NULL))
|
||||
#define utarray_prev(a, e) \
|
||||
(((e) == NULL) ? utarray_back(a) \
|
||||
: ((utarray_eltidx(a, e) != 0) ? _utarray_eltptr(a, utarray_eltidx(a, e) - 1) : NULL))
|
||||
#define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a, (a)->i - 1)) : NULL)
|
||||
#define utarray_eltidx(a, e) (((char *)(e) - (a)->d) / (a)->icd.sz)
|
||||
|
||||
/* last we pre-define a few icd for common utarrays of ints and strings */
|
||||
static void utarray_str_cpy(void *dst, const void *src) {
|
||||
char *const *srcc = (char *const *)src;
|
||||
char **dstc = (char **)dst;
|
||||
*dstc = (*srcc == NULL) ? NULL : strdup(*srcc);
|
||||
}
|
||||
static void utarray_str_dtor(void *elt) {
|
||||
char **eltc = (char **)elt;
|
||||
if (*eltc != NULL) {
|
||||
free(*eltc);
|
||||
}
|
||||
}
|
||||
static const UT_icd ut_str_icd UTARRAY_UNUSED = {sizeof(char *), NULL, utarray_str_cpy, utarray_str_dtor};
|
||||
static const UT_icd ut_int_icd UTARRAY_UNUSED = {sizeof(int), NULL, NULL, NULL};
|
||||
static const UT_icd ut_ptr_icd UTARRAY_UNUSED = {sizeof(void *), NULL, NULL, NULL};
|
||||
|
||||
#endif /* UTARRAY_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
Copyright (c) 2015-2021, Troy D. Hanson http://troydhanson.github.com/uthash/
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* a ring-buffer implementation using macros
|
||||
*/
|
||||
#ifndef UTRINGBUFFER_H
|
||||
#define UTRINGBUFFER_H
|
||||
|
||||
#define UTRINGBUFFER_VERSION 2.3.0
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "utarray.h" // for "UT_icd"
|
||||
|
||||
typedef struct {
|
||||
unsigned i; /* index of next available slot; wraps at n */
|
||||
unsigned n; /* capacity */
|
||||
unsigned char f; /* full */
|
||||
UT_icd icd; /* initializer, copy and destructor functions */
|
||||
char *d; /* n slots of size icd->sz */
|
||||
} UT_ringbuffer;
|
||||
|
||||
#define utringbuffer_init(a, _n, _icd) \
|
||||
do { \
|
||||
memset(a, 0, sizeof(UT_ringbuffer)); \
|
||||
(a)->icd = *(_icd); \
|
||||
(a)->n = (_n); \
|
||||
if ((a)->n) { \
|
||||
(a)->d = (char *)malloc((a)->n * (_icd)->sz); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define utringbuffer_clear(a) \
|
||||
do { \
|
||||
if ((a)->icd.dtor) { \
|
||||
if ((a)->f) { \
|
||||
unsigned _ut_i; \
|
||||
for (_ut_i = 0; _ut_i < (a)->n; ++_ut_i) { \
|
||||
(a)->icd.dtor(utringbuffer_eltptr(a, _ut_i)); \
|
||||
} \
|
||||
} else { \
|
||||
unsigned _ut_i; \
|
||||
for (_ut_i = 0; _ut_i < (a)->i; ++_ut_i) { \
|
||||
(a)->icd.dtor(utringbuffer_eltptr(a, _ut_i)); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
(a)->i = 0; \
|
||||
(a)->f = 0; \
|
||||
} while (0)
|
||||
|
||||
#define utringbuffer_done(a) \
|
||||
do { \
|
||||
utringbuffer_clear(a); \
|
||||
free((a)->d); \
|
||||
(a)->d = NULL; \
|
||||
(a)->n = 0; \
|
||||
} while (0)
|
||||
|
||||
#define utringbuffer_new(a, n, _icd) \
|
||||
do { \
|
||||
a = (UT_ringbuffer *)malloc(sizeof(UT_ringbuffer)); \
|
||||
utringbuffer_init(a, n, _icd); \
|
||||
} while (0)
|
||||
|
||||
#define utringbuffer_free(a) \
|
||||
do { \
|
||||
utringbuffer_done(a); \
|
||||
free(a); \
|
||||
} while (0)
|
||||
|
||||
#define utringbuffer_push_back(a, p) \
|
||||
do { \
|
||||
if ((a)->icd.dtor && (a)->f) { \
|
||||
(a)->icd.dtor(_utringbuffer_internalptr(a, (a)->i)); \
|
||||
} \
|
||||
if ((a)->icd.copy) { \
|
||||
(a)->icd.copy(_utringbuffer_internalptr(a, (a)->i), p); \
|
||||
} else { \
|
||||
memcpy(_utringbuffer_internalptr(a, (a)->i), p, (a)->icd.sz); \
|
||||
}; \
|
||||
if (++(a)->i == (a)->n) { \
|
||||
(a)->i = 0; \
|
||||
(a)->f = 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define utringbuffer_len(a) ((a)->f ? (a)->n : (a)->i)
|
||||
#define utringbuffer_empty(a) ((a)->i == 0 && !(a)->f)
|
||||
#define utringbuffer_full(a) ((a)->f != 0)
|
||||
|
||||
#define _utringbuffer_real_idx(a, j) ((a)->f ? ((j) + (a)->i) % (a)->n : (j))
|
||||
#define _utringbuffer_internalptr(a, j) ((void *)((a)->d + ((a)->icd.sz * (j))))
|
||||
#define utringbuffer_eltptr(a, j) \
|
||||
((0 <= (j) && (j) < utringbuffer_len(a)) ? _utringbuffer_internalptr(a, _utringbuffer_real_idx(a, j)) : NULL)
|
||||
|
||||
#define _utringbuffer_fake_idx(a, j) ((a)->f ? ((j) + (a)->n - (a)->i) % (a)->n : (j))
|
||||
#define _utringbuffer_internalidx(a, e) (((char *)(e) >= (a)->d) ? (((char *)(e) - (a)->d) / (a)->icd.sz) : -1)
|
||||
#define utringbuffer_eltidx(a, e) _utringbuffer_fake_idx(a, _utringbuffer_internalidx(a, e))
|
||||
|
||||
#define utringbuffer_front(a) utringbuffer_eltptr(a, 0)
|
||||
#define utringbuffer_next(a, e) \
|
||||
((e) == NULL ? utringbuffer_front(a) : utringbuffer_eltptr(a, utringbuffer_eltidx(a, e) + 1))
|
||||
#define utringbuffer_prev(a, e) \
|
||||
((e) == NULL ? utringbuffer_back(a) : utringbuffer_eltptr(a, utringbuffer_eltidx(a, e) - 1))
|
||||
#define utringbuffer_back(a) (utringbuffer_empty(a) ? NULL : utringbuffer_eltptr(a, utringbuffer_len(a) - 1))
|
||||
|
||||
#endif /* UTRINGBUFFER_H */
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
Copyright (c) 2018-2021, Troy D. Hanson http://troydhanson.github.com/uthash/
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef UTSTACK_H
|
||||
#define UTSTACK_H
|
||||
|
||||
#define UTSTACK_VERSION 2.3.0
|
||||
|
||||
/*
|
||||
* This file contains macros to manipulate a singly-linked list as a stack.
|
||||
*
|
||||
* To use utstack, your structure must have a "next" pointer.
|
||||
*
|
||||
* ----------------.EXAMPLE -------------------------
|
||||
* struct item {
|
||||
* int id;
|
||||
* struct item *next;
|
||||
* }
|
||||
*
|
||||
* struct item *stack = NULL:
|
||||
*
|
||||
* int main() {
|
||||
* int count;
|
||||
* struct item *tmp;
|
||||
* struct item *item = malloc(sizeof *item);
|
||||
* item->id = 42;
|
||||
* STACK_COUNT(stack, tmp, count); assert(count == 0);
|
||||
* STACK_PUSH(stack, item);
|
||||
* STACK_COUNT(stack, tmp, count); assert(count == 1);
|
||||
* STACK_POP(stack, item);
|
||||
* free(item);
|
||||
* STACK_COUNT(stack, tmp, count); assert(count == 0);
|
||||
* }
|
||||
* --------------------------------------------------
|
||||
*/
|
||||
|
||||
#define STACK_TOP(head) (head)
|
||||
|
||||
#define STACK_EMPTY(head) (!(head))
|
||||
|
||||
#define STACK_PUSH(head, add) STACK_PUSH2(head, add, next)
|
||||
|
||||
#define STACK_PUSH2(head, add, next) \
|
||||
do { \
|
||||
(add)->next = (head); \
|
||||
(head) = (add); \
|
||||
} while (0)
|
||||
|
||||
#define STACK_POP(head, result) STACK_POP2(head, result, next)
|
||||
|
||||
#define STACK_POP2(head, result, next) \
|
||||
do { \
|
||||
(result) = (head); \
|
||||
(head) = (head)->next; \
|
||||
} while (0)
|
||||
|
||||
#define STACK_COUNT(head, el, counter) STACK_COUNT2(head, el, counter, next)
|
||||
|
||||
#define STACK_COUNT2(head, el, counter, next) \
|
||||
do { \
|
||||
(counter) = 0; \
|
||||
for ((el) = (head); el; (el) = (el)->next) { \
|
||||
++(counter); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* UTSTACK_H */
|
|
@ -0,0 +1,351 @@
|
|||
/*
|
||||
Copyright (c) 2008-2021, Troy D. Hanson http://troydhanson.github.com/uthash/
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* a dynamic string implementation using macros
|
||||
*/
|
||||
#ifndef UTSTRING_H
|
||||
#define UTSTRING_H
|
||||
|
||||
#define UTSTRING_VERSION 2.3.0
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define UTSTRING_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
#define UTSTRING_UNUSED
|
||||
#endif
|
||||
|
||||
#ifdef oom
|
||||
#error "The name of macro 'oom' has been changed to 'utstring_oom'. Please update your code."
|
||||
#define utstring_oom() oom()
|
||||
#endif
|
||||
|
||||
#ifndef utstring_oom
|
||||
#define utstring_oom() exit(-1)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *d; /* pointer to allocated buffer */
|
||||
size_t n; /* allocated capacity */
|
||||
size_t i; /* index of first unused byte */
|
||||
} UT_string;
|
||||
|
||||
#define utstring_reserve(s, amt) \
|
||||
do { \
|
||||
if (((s)->n - (s)->i) < (size_t)(amt)) { \
|
||||
char *utstring_tmp = (char *)realloc((s)->d, (s)->n + (amt)); \
|
||||
if (!utstring_tmp) { \
|
||||
utstring_oom(); \
|
||||
} \
|
||||
(s)->d = utstring_tmp; \
|
||||
(s)->n += (amt); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define utstring_init(s) \
|
||||
do { \
|
||||
(s)->n = 0; \
|
||||
(s)->i = 0; \
|
||||
(s)->d = NULL; \
|
||||
utstring_reserve(s, 100); \
|
||||
(s)->d[0] = '\0'; \
|
||||
} while (0)
|
||||
|
||||
#define utstring_done(s) \
|
||||
do { \
|
||||
if ((s)->d != NULL) \
|
||||
free((s)->d); \
|
||||
(s)->n = 0; \
|
||||
} while (0)
|
||||
|
||||
#define utstring_free(s) \
|
||||
do { \
|
||||
utstring_done(s); \
|
||||
free(s); \
|
||||
} while (0)
|
||||
|
||||
#define utstring_new(s) \
|
||||
do { \
|
||||
(s) = (UT_string *)malloc(sizeof(UT_string)); \
|
||||
if (!(s)) { \
|
||||
utstring_oom(); \
|
||||
} \
|
||||
utstring_init(s); \
|
||||
} while (0)
|
||||
|
||||
#define utstring_renew(s) \
|
||||
do { \
|
||||
if (s) { \
|
||||
utstring_clear(s); \
|
||||
} else { \
|
||||
utstring_new(s); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define utstring_clear(s) \
|
||||
do { \
|
||||
(s)->i = 0; \
|
||||
(s)->d[0] = '\0'; \
|
||||
} while (0)
|
||||
|
||||
#define utstring_bincpy(s, b, l) \
|
||||
do { \
|
||||
utstring_reserve((s), (l) + 1); \
|
||||
if (l) \
|
||||
memcpy(&(s)->d[(s)->i], b, l); \
|
||||
(s)->i += (l); \
|
||||
(s)->d[(s)->i] = '\0'; \
|
||||
} while (0)
|
||||
|
||||
#define utstring_concat(dst, src) \
|
||||
do { \
|
||||
utstring_reserve((dst), ((src)->i) + 1); \
|
||||
if ((src)->i) \
|
||||
memcpy(&(dst)->d[(dst)->i], (src)->d, (src)->i); \
|
||||
(dst)->i += (src)->i; \
|
||||
(dst)->d[(dst)->i] = '\0'; \
|
||||
} while (0)
|
||||
|
||||
#define utstring_len(s) ((s)->i)
|
||||
|
||||
#define utstring_body(s) ((s)->d)
|
||||
|
||||
UTSTRING_UNUSED static void utstring_printf_va(UT_string *s, const char *fmt, va_list ap) {
|
||||
int n;
|
||||
va_list cp;
|
||||
for (;;) {
|
||||
#ifdef _WIN32
|
||||
cp = ap;
|
||||
#else
|
||||
va_copy(cp, ap);
|
||||
#endif
|
||||
n = vsnprintf(&s->d[s->i], s->n - s->i, fmt, cp);
|
||||
va_end(cp);
|
||||
|
||||
if ((n > -1) && ((size_t)n < (s->n - s->i))) {
|
||||
s->i += n;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Else try again with more space. */
|
||||
if (n > -1) {
|
||||
utstring_reserve(s, n + 1); /* exact */
|
||||
} else {
|
||||
utstring_reserve(s, (s->n) * 2); /* 2x */
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef __GNUC__
|
||||
/* support printf format checking (2=the format string, 3=start of varargs) */
|
||||
static void utstring_printf(UT_string *s, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
|
||||
#endif
|
||||
UTSTRING_UNUSED static void utstring_printf(UT_string *s, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
utstring_printf_va(s, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* begin substring search functions *
|
||||
******************************************************************************/
|
||||
/* Build KMP table from left to right. */
|
||||
UTSTRING_UNUSED static void _utstring_BuildTable(const char *P_Needle, size_t P_NeedleLen, long *P_KMP_Table) {
|
||||
long i, j;
|
||||
|
||||
i = 0;
|
||||
j = i - 1;
|
||||
P_KMP_Table[i] = j;
|
||||
while (i < (long)P_NeedleLen) {
|
||||
while ((j > -1) && (P_Needle[i] != P_Needle[j])) {
|
||||
j = P_KMP_Table[j];
|
||||
}
|
||||
i++;
|
||||
j++;
|
||||
if (i < (long)P_NeedleLen) {
|
||||
if (P_Needle[i] == P_Needle[j]) {
|
||||
P_KMP_Table[i] = P_KMP_Table[j];
|
||||
} else {
|
||||
P_KMP_Table[i] = j;
|
||||
}
|
||||
} else {
|
||||
P_KMP_Table[i] = j;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Build KMP table from right to left. */
|
||||
UTSTRING_UNUSED static void _utstring_BuildTableR(const char *P_Needle, size_t P_NeedleLen, long *P_KMP_Table) {
|
||||
long i, j;
|
||||
|
||||
i = P_NeedleLen - 1;
|
||||
j = i + 1;
|
||||
P_KMP_Table[i + 1] = j;
|
||||
while (i >= 0) {
|
||||
while ((j < (long)P_NeedleLen) && (P_Needle[i] != P_Needle[j])) {
|
||||
j = P_KMP_Table[j + 1];
|
||||
}
|
||||
i--;
|
||||
j--;
|
||||
if (i >= 0) {
|
||||
if (P_Needle[i] == P_Needle[j]) {
|
||||
P_KMP_Table[i + 1] = P_KMP_Table[j + 1];
|
||||
} else {
|
||||
P_KMP_Table[i + 1] = j;
|
||||
}
|
||||
} else {
|
||||
P_KMP_Table[i + 1] = j;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Search data from left to right. ( Multiple search mode. ) */
|
||||
UTSTRING_UNUSED static long _utstring_find(const char *P_Haystack,
|
||||
size_t P_HaystackLen,
|
||||
const char *P_Needle,
|
||||
size_t P_NeedleLen,
|
||||
long *P_KMP_Table) {
|
||||
long i, j;
|
||||
long V_FindPosition = -1;
|
||||
|
||||
/* Search from left to right. */
|
||||
i = j = 0;
|
||||
while ((j < (int)P_HaystackLen) && (((P_HaystackLen - j) + i) >= P_NeedleLen)) {
|
||||
while ((i > -1) && (P_Needle[i] != P_Haystack[j])) {
|
||||
i = P_KMP_Table[i];
|
||||
}
|
||||
i++;
|
||||
j++;
|
||||
if (i >= (int)P_NeedleLen) {
|
||||
/* Found. */
|
||||
V_FindPosition = j - i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return V_FindPosition;
|
||||
}
|
||||
|
||||
/* Search data from right to left. ( Multiple search mode. ) */
|
||||
UTSTRING_UNUSED static long _utstring_findR(const char *P_Haystack,
|
||||
size_t P_HaystackLen,
|
||||
const char *P_Needle,
|
||||
size_t P_NeedleLen,
|
||||
long *P_KMP_Table) {
|
||||
long i, j;
|
||||
long V_FindPosition = -1;
|
||||
|
||||
/* Search from right to left. */
|
||||
j = (P_HaystackLen - 1);
|
||||
i = (P_NeedleLen - 1);
|
||||
while ((j >= 0) && (j >= i)) {
|
||||
while ((i < (int)P_NeedleLen) && (P_Needle[i] != P_Haystack[j])) {
|
||||
i = P_KMP_Table[i + 1];
|
||||
}
|
||||
i--;
|
||||
j--;
|
||||
if (i < 0) {
|
||||
/* Found. */
|
||||
V_FindPosition = j + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return V_FindPosition;
|
||||
}
|
||||
|
||||
/* Search data from left to right. ( One time search mode. ) */
|
||||
UTSTRING_UNUSED static long utstring_find(UT_string *s,
|
||||
long P_StartPosition, /* Start from 0. -1 means last position. */
|
||||
const char *P_Needle,
|
||||
size_t P_NeedleLen) {
|
||||
long V_StartPosition;
|
||||
long V_HaystackLen;
|
||||
long *V_KMP_Table;
|
||||
long V_FindPosition = -1;
|
||||
|
||||
if (P_StartPosition < 0) {
|
||||
V_StartPosition = s->i + P_StartPosition;
|
||||
} else {
|
||||
V_StartPosition = P_StartPosition;
|
||||
}
|
||||
V_HaystackLen = s->i - V_StartPosition;
|
||||
if ((V_HaystackLen >= (long)P_NeedleLen) && (P_NeedleLen > 0)) {
|
||||
V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1));
|
||||
if (V_KMP_Table != NULL) {
|
||||
_utstring_BuildTable(P_Needle, P_NeedleLen, V_KMP_Table);
|
||||
|
||||
V_FindPosition = _utstring_find(s->d + V_StartPosition, V_HaystackLen, P_Needle, P_NeedleLen, V_KMP_Table);
|
||||
if (V_FindPosition >= 0) {
|
||||
V_FindPosition += V_StartPosition;
|
||||
}
|
||||
|
||||
free(V_KMP_Table);
|
||||
}
|
||||
}
|
||||
|
||||
return V_FindPosition;
|
||||
}
|
||||
|
||||
/* Search data from right to left. ( One time search mode. ) */
|
||||
UTSTRING_UNUSED static long utstring_findR(UT_string *s,
|
||||
long P_StartPosition, /* Start from 0. -1 means last position. */
|
||||
const char *P_Needle,
|
||||
size_t P_NeedleLen) {
|
||||
long V_StartPosition;
|
||||
long V_HaystackLen;
|
||||
long *V_KMP_Table;
|
||||
long V_FindPosition = -1;
|
||||
|
||||
if (P_StartPosition < 0) {
|
||||
V_StartPosition = s->i + P_StartPosition;
|
||||
} else {
|
||||
V_StartPosition = P_StartPosition;
|
||||
}
|
||||
V_HaystackLen = V_StartPosition + 1;
|
||||
if ((V_HaystackLen >= (long)P_NeedleLen) && (P_NeedleLen > 0)) {
|
||||
V_KMP_Table = (long *)malloc(sizeof(long) * (P_NeedleLen + 1));
|
||||
if (V_KMP_Table != NULL) {
|
||||
_utstring_BuildTableR(P_Needle, P_NeedleLen, V_KMP_Table);
|
||||
|
||||
V_FindPosition = _utstring_findR(s->d, V_HaystackLen, P_Needle, P_NeedleLen, V_KMP_Table);
|
||||
|
||||
free(V_KMP_Table);
|
||||
}
|
||||
}
|
||||
|
||||
return V_FindPosition;
|
||||
}
|
||||
/*******************************************************************************
|
||||
* end substring search functions *
|
||||
******************************************************************************/
|
||||
|
||||
#endif /* UTSTRING_H */
|
|
@ -14,8 +14,18 @@
|
|||
|
||||
#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;
|
||||
}
|
||||
|
||||
void SetCurrentNetShareMode(NET_SHARE_MODE shareMode) {
|
||||
g_CurShareMode = shareMode;
|
||||
}
|
||||
|
||||
int GetWireGuardWorkMode(bool *pIsWorkServer) {
|
||||
if (pIsWorkServer == nullptr) {
|
||||
SPDLOG_ERROR(TEXT("Input pIsWorkServer params error"));
|
||||
|
@ -73,7 +83,10 @@ int WireGuardInstallDefaultServerService(bool bInstall) {
|
|||
SPDLOG_DEBUG(TEXT("Run command [{0}]"), cmdBuf);
|
||||
|
||||
if (bInstall) {
|
||||
ret = WaitNetAdapterConnected(svrName, 10 * 1000);
|
||||
int retry = 10;
|
||||
do {
|
||||
ret = WaitNetAdapterConnected(svrName, 1000);
|
||||
} while (ret != ERR_SUCCESS && retry--);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -1,10 +1,129 @@
|
|||
|
||||
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdio>
|
||||
#include <netcon.h>
|
||||
#include <atlstr.h>
|
||||
|
||||
static int WideCharToTChar2(const WCHAR *pWStr, TCHAR *pOutStr, int maxOutLen) {
|
||||
if (sizeof(TCHAR) == sizeof(WCHAR)) {
|
||||
if (wcslen(pWStr) * sizeof(WCHAR) >= maxOutLen) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(pOutStr, pWStr, wcslen(pWStr));
|
||||
} else {
|
||||
int len = WideCharToMultiByte(CP_ACP, 0, pWStr, static_cast<int>(wcslen(pWStr)), nullptr, 0, nullptr, nullptr);
|
||||
|
||||
if (len >= maxOutLen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, pWStr, static_cast<int>(wcslen(pWStr)), pOutStr, len, nullptr, nullptr);
|
||||
pOutStr[len] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT shareNet2(INetSharingManager *pNSM) { // this is done in 2 parts:
|
||||
// 1: enum connections until we get one that we can convert into an INetSharingConfiguration
|
||||
// 2: then, enum portmappings, and delete if we find a match.
|
||||
|
||||
// PART 1: find a valid connection
|
||||
INetConnection *pNC = nullptr; // fill this out for part 2 below
|
||||
|
||||
INetSharingEveryConnectionCollection *pNSECC = nullptr;
|
||||
HRESULT hr = pNSM->get_EnumEveryConnection(&pNSECC);
|
||||
if (!pNSECC) {
|
||||
printf("failed to get EveryConnectionCollection!\r\n");
|
||||
} else {
|
||||
// enumerate connections
|
||||
IEnumVARIANT *pEV = nullptr;
|
||||
IUnknown *pUnk = nullptr;
|
||||
hr = pNSECC->get__NewEnum(&pUnk);
|
||||
if (pUnk) {
|
||||
hr = pUnk->QueryInterface(__uuidof(IEnumVARIANT), (void **)&pEV);
|
||||
pUnk->Release();
|
||||
}
|
||||
if (pEV) {
|
||||
VARIANT v;
|
||||
VariantInit(&v);
|
||||
BOOL bFoundIt = FALSE;
|
||||
while (S_OK == pEV->Next(1, &v, nullptr)) {
|
||||
if (V_VT(&v) == VT_UNKNOWN) {
|
||||
V_UNKNOWN(&v)->QueryInterface(__uuidof(INetConnection), (void **)&pNC);
|
||||
if (pNC) {
|
||||
INetConnectionProps *pNCP = nullptr;
|
||||
pNSM->get_NetConnectionProps(pNC, &pNCP);
|
||||
if (!pNCP) {
|
||||
printf("failed to get NetConnectionProps!\r\n");
|
||||
} else {
|
||||
// check properties for firewalled or shared connection
|
||||
DWORD dwCharacteristics = 0;
|
||||
pNCP->get_Characteristics(&dwCharacteristics);
|
||||
if (dwCharacteristics & (NCCF_SHARED | NCCF_FIREWALLED)) {
|
||||
NETCON_MEDIATYPE MediaType = NCM_NONE;
|
||||
pNCP->get_MediaType(&MediaType);
|
||||
if ((MediaType != NCM_SHAREDACCESSHOST_LAN) &&
|
||||
(MediaType != NCM_SHAREDACCESSHOST_RAS)) {
|
||||
// got a shared/firewalled connection
|
||||
bFoundIt = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
BSTR sName = {};
|
||||
TCHAR ifName[MAX_PATH];
|
||||
|
||||
pNCP->get_Name(&sName);
|
||||
|
||||
WideCharToTChar2(sName, ifName, MAX_PATH);
|
||||
SysFreeString(sName);
|
||||
|
||||
printf("Get NC Name %s\r\n", ifName);
|
||||
if(strcmp(ifName, "admin") == 0) {
|
||||
bFoundIt = TRUE;
|
||||
}
|
||||
pNCP->Release();
|
||||
}
|
||||
if (bFoundIt == FALSE) {
|
||||
pNC->Release();
|
||||
pNC = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
VariantClear(&v);
|
||||
if (bFoundIt == TRUE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
pEV->Release();
|
||||
}
|
||||
pNSECC->Release();
|
||||
}
|
||||
if (pNC == nullptr) {
|
||||
printf("failed to find a valid connection!\r\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
INetSharingConfiguration *pNSC = nullptr;
|
||||
hr = pNSM->get_INetSharingConfigurationForINetConnection(pNC, &pNSC);
|
||||
|
||||
if (!pNSC) {
|
||||
printf("can't make INetSharingConfiguration object!\r\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
NETCON_PROPERTIES *pNP = nullptr;
|
||||
pNC->GetProperties(&pNP);
|
||||
|
||||
hr = pNSM->get_INetSharingConfigurationForINetConnection(pNC, &pNSC);
|
||||
printf("**************find nic srcName : %s\r\n", static_cast<const char *>(CW2A(pNP->pszwName)));
|
||||
//hr = pNSC->DisableSharing();
|
||||
Sleep(500);
|
||||
//getchar();
|
||||
hr = pNSC->EnableSharing(ICSSHARINGTYPE_PUBLIC);
|
||||
|
||||
pNC->Release(); // don't need this anymore
|
||||
pNSC->Release();
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT shareNet(INetSharingManager *pNSM, const char *srcName, const char *dstName) {
|
||||
INetConnection *pNC = nullptr;
|
||||
INetSharingConfiguration *pNSC = nullptr;
|
||||
|
@ -33,7 +152,7 @@ HRESULT shareNet(INetSharingManager *pNSM, const char *srcName, const char *dstN
|
|||
if (V_VT(&v) == VT_UNKNOWN) {
|
||||
V_UNKNOWN(&v)->QueryInterface(__uuidof(INetConnection), (void **)&pNC);
|
||||
if (pNC) {
|
||||
WCHAR guid[256];
|
||||
WCHAR guid[256];
|
||||
NETCON_PROPERTIES *pNP = nullptr;
|
||||
pNC->GetProperties(&pNP);
|
||||
//setlocale(LC_ALL, "chs");
|
||||
|
@ -49,27 +168,29 @@ HRESULT shareNet(INetSharingManager *pNSM, const char *srcName, const char *dstN
|
|||
if (pNP->Status != NCS_CONNECTED) {
|
||||
continue;
|
||||
}
|
||||
TCHAR* tmpName = CW2A(pNP->pszwName);
|
||||
// printf("###### |%s| : |%s|\r\n", tmpName, "");
|
||||
TCHAR *tmpName = CW2A(pNP->pszwName);
|
||||
// printf("###### |%s| : |%s|\r\n", tmpName, "");
|
||||
|
||||
hr = pNSM->get_INetSharingConfigurationForINetConnection(pNC, &pNSC);
|
||||
if (!strcmp(tmpName, (char *)srcName)) {
|
||||
printf("**************find nic srcName : %s\r\n", (char *)srcName);
|
||||
if (i == 2) {
|
||||
hr = pNSM->get_INetSharingConfigurationForINetConnection(pNC, &pNSC);
|
||||
printf("**************find nic srcName : %s\r\n", static_cast<const char *>(CW2A(pNP->pszwName)));
|
||||
//hr = pNSC->DisableSharing();
|
||||
Sleep(500);
|
||||
//getchar();
|
||||
hr = pNSC->EnableSharing(ICSSHARINGTYPE_PUBLIC);
|
||||
pNSC->Release();
|
||||
}
|
||||
pNSC->Release();
|
||||
#if 0
|
||||
hr = pNSM->get_INetSharingConfigurationForINetConnection(pNC, &pNSC);
|
||||
if (!strcmp(tmpName.c_str(), (char *)dstName)) {
|
||||
printf("**************find nic dstName : %s\r\n", (char *)dstName);
|
||||
|
||||
#if 1
|
||||
|
||||
if (i == 5) {
|
||||
hr = pNSM->get_INetSharingConfigurationForINetConnection(pNC, &pNSC);
|
||||
printf("**************find nic dstName : %s\r\n", static_cast<const char *>(CW2A(pNP->pszwName)));
|
||||
//hr = pNSC->DisableSharing();
|
||||
Sleep(500);
|
||||
hr = pNSC->EnableSharing(ICSSHARINGTYPE_PRIVATE);
|
||||
pNSC->Release();
|
||||
}
|
||||
pNSC->Release();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +221,7 @@ int NetShare() {
|
|||
printf(TEXT("failed to create NetSharingManager object\r\n"));
|
||||
} else {
|
||||
//shareNet(pNSM, "WLAN", "мн╠Ф═Э 4");
|
||||
shareNet(pNSM, "", "");
|
||||
shareNet2(pNSM);
|
||||
//StartHostednetwork();
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -7,14 +7,41 @@
|
|||
#include "tunnel.h"
|
||||
|
||||
#include "globalcfg.h"
|
||||
#include "network.h"
|
||||
#include "user.h"
|
||||
#include "usrerr.h"
|
||||
|
||||
const TCHAR *g_AppPath = TEXT("C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_windows\\x64\\Debug");
|
||||
const TCHAR *g_SvrUserName = TEXT("tunnel_svr");
|
||||
const TCHAR *g_PlatformURL = TEXT("http://xajhuang.com:9276");
|
||||
|
||||
//const TCHAR *g_PlatformURL = TEXT("http://localhost:9276");
|
||||
|
||||
void test_socket() {
|
||||
/*WSADATA wsa_data;
|
||||
WORD wsa_version = MAKEWORD(2, 2);
|
||||
WSAStartup(wsa_version, &wsa_data);*/
|
||||
const SOCKET sd = socket(AF_INET, SOCK_STREAM, 0); //server descriptor
|
||||
sockaddr_in server {};
|
||||
int addrSize = sizeof(sockaddr_in);
|
||||
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = inet_addr (TEXT("127.0.0.1"));
|
||||
server.sin_port = htons(0);
|
||||
|
||||
if (bind(sd, reinterpret_cast<struct sockaddr *>(&server), sizeof(struct sockaddr)) == -1) {
|
||||
printf("error....\n");
|
||||
}
|
||||
|
||||
printf("Set Bind Port: %d\n", ntohs(server.sin_port)); //is still 0
|
||||
|
||||
sockaddr_in bindAddr {};
|
||||
|
||||
int ret = getsockname(sd, reinterpret_cast<struct sockaddr *>(&bindAddr), &addrSize);
|
||||
|
||||
printf("Bind port %d ret: %d\n", ntohs(bindAddr.sin_port), WSAGetLastError());
|
||||
}
|
||||
|
||||
#if 0
|
||||
int service_test() {
|
||||
TCHAR szSvcName[] = _T("WireGuard");
|
||||
|
@ -88,12 +115,12 @@ int service_test() {
|
|||
|
||||
int tunnel_service() {
|
||||
PUSER_SERVER_CONFIG pSvrCfg;
|
||||
TCHAR logPath[MAX_PATH];
|
||||
//TCHAR logPath[MAX_PATH];
|
||||
|
||||
TunnelSDKInitEnv(g_AppPath, g_PlatformURL, true);
|
||||
TunnelSDKInitEnv(g_AppPath, g_PlatformURL, nullptr, LOG_DEBUG, true);
|
||||
|
||||
StringCbPrintf(logPath, MAX_PATH, TEXT("%s\\TestApp.log"), g_AppPath);
|
||||
InitTunnelSDKLog(logPath, LOG_DEBUG);
|
||||
//StringCbPrintf(logPath, MAX_PATH, TEXT("%s\\TestApp.log"), g_AppPath);
|
||||
//InitTunnelSDKLog(nullptr, LOG_DEBUG);
|
||||
|
||||
// Server 端用户名建议固定为一个字符串,因为每个云电脑上有且只有一个用户名, 长度不要超过32字符
|
||||
int ret = GetUserServerConfigure(g_SvrUserName, "asfdafdafdaf", &pSvrCfg);
|
||||
|
@ -115,7 +142,10 @@ int main() {
|
|||
//GetInterface();
|
||||
//CryptoExample();
|
||||
//SetRouteTable();
|
||||
tunnel_service();
|
||||
|
||||
//CreatePorxyService();
|
||||
//tunnel_service();
|
||||
test_socket();
|
||||
|
||||
while (true) {
|
||||
Sleep(100);
|
||||
|
|
|
@ -130,6 +130,7 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CryptoExample.cpp" />
|
||||
<ClCompile Include="firewall.cpp" />
|
||||
<ClCompile Include="NetInterface.cpp" />
|
||||
<ClCompile Include="NetShare.cpp" />
|
||||
<ClCompile Include="NetTunnelSDKTestApp.cpp" />
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
<ClCompile Include="CryptoExample.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="firewall.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="common.h">
|
||||
|
|
|
@ -0,0 +1,292 @@
|
|||
// Copyright (C) Microsoft. All rights reserved.
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
#include <netcon.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#pragma comment(lib, "ole32.lib")
|
||||
#pragma comment(lib, "oleaut32.lib")
|
||||
|
||||
// as in winsock.h
|
||||
#define NAT_PROTOCOL_TCP 6
|
||||
|
||||
HRESULT DeletePortMapping(INetSharingManager *pNSM,
|
||||
UCHAR ucIPProtocol,
|
||||
short usExternalPort) { // this is done in 2 parts:
|
||||
// 1: enum connections until we get one that we can convert into an INetSharingConfiguration
|
||||
// 2: then, enum portmappings, and delete if we find a match.
|
||||
|
||||
// PART 1: find a valid connection
|
||||
INetConnection *pNC = nullptr; // fill this out for part 2 below
|
||||
|
||||
INetSharingEveryConnectionCollection *pNSECC = nullptr;
|
||||
HRESULT hr = pNSM->get_EnumEveryConnection(&pNSECC);
|
||||
if (!pNSECC) {
|
||||
wprintf(L"failed to get EveryConnectionCollection!\r\n");
|
||||
} else {
|
||||
// enumerate connections
|
||||
IEnumVARIANT *pEV = nullptr;
|
||||
IUnknown *pUnk = nullptr;
|
||||
hr = pNSECC->get__NewEnum(&pUnk);
|
||||
if (pUnk) {
|
||||
hr = pUnk->QueryInterface(__uuidof(IEnumVARIANT), (void **)&pEV);
|
||||
pUnk->Release();
|
||||
}
|
||||
if (pEV) {
|
||||
VARIANT v;
|
||||
VariantInit(&v);
|
||||
BOOL bFoundIt = FALSE;
|
||||
while (S_OK == pEV->Next(1, &v, nullptr)) {
|
||||
if (V_VT(&v) == VT_UNKNOWN) {
|
||||
V_UNKNOWN(&v)->QueryInterface(__uuidof(INetConnection), (void **)&pNC);
|
||||
if (pNC) {
|
||||
INetConnectionProps *pNCP = nullptr;
|
||||
pNSM->get_NetConnectionProps(pNC, &pNCP);
|
||||
if (!pNCP) {
|
||||
wprintf(L"failed to get NetConnectionProps!\r\n");
|
||||
} else {
|
||||
// check properties for firewalled or shared connection
|
||||
DWORD dwCharacteristics = 0;
|
||||
pNCP->get_Characteristics(&dwCharacteristics);
|
||||
if (dwCharacteristics & (NCCF_SHARED | NCCF_FIREWALLED)) {
|
||||
NETCON_MEDIATYPE MediaType = NCM_NONE;
|
||||
pNCP->get_MediaType(&MediaType);
|
||||
if ((MediaType != NCM_SHAREDACCESSHOST_LAN) &&(MediaType != NCM_SHAREDACCESSHOST_RAS)) {
|
||||
// got a shared/firewalled connection
|
||||
bFoundIt = TRUE;
|
||||
}
|
||||
}
|
||||
pNCP->Release();
|
||||
}
|
||||
if (bFoundIt == FALSE) {
|
||||
pNC->Release();
|
||||
pNC = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
VariantClear(&v);
|
||||
if (bFoundIt == TRUE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
pEV->Release();
|
||||
}
|
||||
pNSECC->Release();
|
||||
}
|
||||
if (pNC == nullptr) {
|
||||
wprintf(L"failed to find a valid connection!\r\n");
|
||||
return E_FAIL;
|
||||
}
|
||||
INetSharingConfiguration *pNSC = nullptr;
|
||||
hr = pNSM->get_INetSharingConfigurationForINetConnection(pNC, &pNSC);
|
||||
pNC->Release(); // don't need this anymore
|
||||
if (!pNSC) {
|
||||
wprintf(L"can't make INetSharingConfiguration object!\r\n");
|
||||
return hr;
|
||||
}
|
||||
|
||||
// PART 2: enum port mappings, deleting match, if any
|
||||
INetSharingPortMappingCollection *pNSPMC = nullptr;
|
||||
hr = pNSC->get_EnumPortMappings(ICSSC_DEFAULT, &pNSPMC);
|
||||
if (!pNSPMC) {
|
||||
wprintf(L"can't get PortMapping collection!\r\n");
|
||||
} else {
|
||||
|
||||
// this is the interface to be filled out by the code below
|
||||
INetSharingPortMapping *pNSPM = nullptr;
|
||||
|
||||
IEnumVARIANT *pEV = nullptr;
|
||||
IUnknown *pUnk = nullptr;
|
||||
hr = pNSPMC->get__NewEnum(&pUnk);
|
||||
if (pUnk) {
|
||||
hr = pUnk->QueryInterface(__uuidof(IEnumVARIANT), (void **)&pEV);
|
||||
pUnk->Release();
|
||||
}
|
||||
if (pEV) {
|
||||
VARIANT v;
|
||||
VariantInit(&v);
|
||||
BOOL bFoundIt = FALSE;
|
||||
while (S_OK == pEV->Next(1, &v, nullptr)) {
|
||||
if (V_VT(&v) == VT_DISPATCH) {
|
||||
V_DISPATCH(&v)->QueryInterface(__uuidof(INetSharingPortMapping), (void **)&pNSPM);
|
||||
if (pNSPM) {
|
||||
INetSharingPortMappingProps *pNSPMP = nullptr;
|
||||
hr = pNSPM->get_Properties(&pNSPMP);
|
||||
if (pNSPMP) {
|
||||
UCHAR uc = 0;
|
||||
pNSPMP->get_IPProtocol(&uc);
|
||||
long usExternal = 0;
|
||||
pNSPMP->get_ExternalPort(&usExternal);
|
||||
if ((uc == ucIPProtocol) &&(usExternal == usExternalPort)) {
|
||||
bFoundIt = TRUE;
|
||||
}
|
||||
|
||||
pNSPMP->Release();
|
||||
}
|
||||
if (bFoundIt == FALSE) { // hang onto reference to pNSPM iff found (used below)
|
||||
pNSPM->Release();
|
||||
pNSPM = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
VariantClear(&v);
|
||||
if (bFoundIt == TRUE) {
|
||||
break; // bail out if we've found one
|
||||
}
|
||||
}
|
||||
pEV->Release();
|
||||
}
|
||||
|
||||
if (pNSPM) {
|
||||
hr = pNSPM->Delete(); // or pNSC->RemovePortMapping (pNSPM);
|
||||
wprintf(L"just deleted a port mapping!\r\n");
|
||||
|
||||
pNSPM->Release();
|
||||
}
|
||||
pNSPMC->Release();
|
||||
}
|
||||
pNSC->Release();
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT AddAsymmetricPortMapping(INetSharingConfiguration *pNSC) {
|
||||
HRESULT hr = S_OK;
|
||||
#if 0
|
||||
VARIANT_BOOL vb1 = VARIANT_FALSE;
|
||||
VARIANT_BOOL vb2 = VARIANT_FALSE;
|
||||
pNSC->get_SharingEnabled(&vb1);
|
||||
pNSC->get_InternetFirewallEnabled(&vb2);
|
||||
if ((vb1 == VARIANT_FALSE) &&(vb2 == VARIANT_FALSE)) {
|
||||
wprintf(L"sharing and/or firewall not enabled on this connection!\r\n");
|
||||
} else {
|
||||
INetSharingPortMapping *pNSPM = nullptr;
|
||||
hr = pNSC->AddPortMapping("Ben's Port Mapping",
|
||||
NAT_PROTOCOL_TCP,
|
||||
555,
|
||||
444,
|
||||
0,
|
||||
"192.168.0.2",
|
||||
ICSTT_IPADDRESS,
|
||||
&pNSPM);
|
||||
if (pNSPM) {
|
||||
wprintf(L"just added NAT_PROTOCOL_TCP, 555, 444!\r\n");
|
||||
|
||||
hr = pNSPM->Enable();
|
||||
wprintf(L"just enabled port mapping!\r\n");
|
||||
|
||||
pNSPM->Release();
|
||||
} else {
|
||||
wprintf(L"failed to add asymmetric port mapping!\r\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT DoTheWork(INetSharingManager *pNSM) { // add a port mapping to every firewalled or shared connection
|
||||
|
||||
INetSharingEveryConnectionCollection *pNSECC = nullptr;
|
||||
HRESULT hr = pNSM->get_EnumEveryConnection(&pNSECC);
|
||||
if (!pNSECC) {
|
||||
wprintf(L"failed to get EveryConnectionCollection!\r\n");
|
||||
} else {
|
||||
|
||||
// enumerate connections
|
||||
IEnumVARIANT *pEV = nullptr;
|
||||
IUnknown *pUnk = nullptr;
|
||||
hr = pNSECC->get__NewEnum(&pUnk);
|
||||
if (pUnk) {
|
||||
hr = pUnk->QueryInterface(__uuidof(IEnumVARIANT), (void **)&pEV);
|
||||
pUnk->Release();
|
||||
}
|
||||
if (pEV) {
|
||||
VARIANT v;
|
||||
VariantInit(&v);
|
||||
while (S_OK == pEV->Next(1, &v, nullptr)) {
|
||||
if (V_VT(&v) == VT_UNKNOWN) {
|
||||
INetConnection *pNC = nullptr;
|
||||
V_UNKNOWN(&v)->QueryInterface(__uuidof(INetConnection), (void **)&pNC);
|
||||
if (pNC) {
|
||||
INetConnectionProps *pNCP = nullptr;
|
||||
pNSM->get_NetConnectionProps(pNC, &pNCP);
|
||||
if (!pNCP) {
|
||||
wprintf(L"failed to get NetConnectionProps!\r\n");
|
||||
} else {
|
||||
// check properties for firewalled or shared connection
|
||||
DWORD dwCharacteristics = 0;
|
||||
pNCP->get_Characteristics(&dwCharacteristics);
|
||||
if (dwCharacteristics & (NCCF_SHARED | NCCF_FIREWALLED)) {
|
||||
NETCON_MEDIATYPE MediaType = NCM_NONE;
|
||||
pNCP->get_MediaType(&MediaType);
|
||||
if ((MediaType != NCM_SHAREDACCESSHOST_LAN) &&
|
||||
(MediaType != NCM_SHAREDACCESSHOST_RAS)) {
|
||||
// got a shared/firewalled connection
|
||||
INetSharingConfiguration *pNSC = nullptr;
|
||||
hr = pNSM->get_INetSharingConfigurationForINetConnection(pNC, &pNSC);
|
||||
if (!pNSC) {
|
||||
wprintf(L"can't make INetSharingConfiguration object!\r\n");
|
||||
} else {
|
||||
hr = AddAsymmetricPortMapping(pNSC);
|
||||
pNSC->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
pNCP->Release();
|
||||
}
|
||||
pNC->Release();
|
||||
}
|
||||
}
|
||||
VariantClear(&v);
|
||||
}
|
||||
pEV->Release();
|
||||
}
|
||||
pNSECC->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
int main3() {
|
||||
CoInitialize(nullptr);
|
||||
|
||||
// init security to enum RAS connections
|
||||
CoInitializeSecurity(nullptr,
|
||||
-1,
|
||||
nullptr,
|
||||
nullptr,
|
||||
RPC_C_AUTHN_LEVEL_PKT,
|
||||
RPC_C_IMP_LEVEL_IMPERSONATE,
|
||||
nullptr,
|
||||
EOAC_NONE,
|
||||
nullptr);
|
||||
|
||||
INetSharingManager *pNSM = nullptr;
|
||||
HRESULT hr = ::CoCreateInstance(CLSID_NetSharingManager,
|
||||
nullptr,
|
||||
CLSCTX_ALL,
|
||||
IID_INetSharingManager,
|
||||
reinterpret_cast<void **>(&pNSM));
|
||||
if (!pNSM) {
|
||||
wprintf(L"failed to create NetSharingManager object\r\n");
|
||||
} else {
|
||||
// in case it exists already
|
||||
DeletePortMapping(pNSM, NAT_PROTOCOL_TCP, 555);
|
||||
|
||||
// add a port mapping to every shared or firewalled connection.
|
||||
hr = DoTheWork(pNSM);
|
||||
if (SUCCEEDED(hr)) {
|
||||
|
||||
// do other work here.
|
||||
// when you're done,
|
||||
// clean up port mapping
|
||||
|
||||
hr = DeletePortMapping(pNSM, NAT_PROTOCOL_TCP, 555);
|
||||
}
|
||||
|
||||
pNSM->Release();
|
||||
}
|
||||
|
||||
CoUninitialize();
|
||||
return (int)hr;
|
||||
}
|
|
@ -18,11 +18,13 @@ TEST_MODULE_INITIALIZE(ModuleInitialize) {
|
|||
"C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_windows\\NetTunnelApp\\bin\\Debug");
|
||||
|
||||
Logger::WriteMessage("In Module Initialize");
|
||||
Assert::AreEqual(0, TunnelSDKInitEnv(path, "http://xajhuang.com:9276", false));
|
||||
|
||||
InitTunnelSDKLog(TEXT("C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_"
|
||||
"windows\\NetTunnelApp\\bin\\Debug\\utest.log"),
|
||||
LOG_DEBUG);
|
||||
Assert::AreEqual(0,
|
||||
TunnelSDKInitEnv(path,
|
||||
"http://xajhuang.com:9276",
|
||||
TEXT("C:\\Users\\HuangXin\\Documents\\development\\visual_studio\\tunnel_"
|
||||
"windows\\NetTunnelApp\\bin\\Debug\\utest.log"),
|
||||
LOG_DEBUG,
|
||||
false));
|
||||
}
|
||||
|
||||
TEST_MODULE_CLEANUP(ModuleCleanup) {
|
||||
|
@ -137,16 +139,17 @@ public:
|
|||
|
||||
TEST_METHOD(TestGetInternetConnectAdaptersIndex) {
|
||||
bool bRet;
|
||||
Assert::AreEqual(RET_OK, IsInternetConnectAdapter(10, &bRet));
|
||||
Assert::AreEqual(RET_OK, IsInternetConnectAdapter(9, &bRet));
|
||||
Assert::AreEqual(true, bRet);
|
||||
|
||||
Assert::AreEqual(RET_OK, IsInternetConnectAdapter(1, &bRet));
|
||||
Assert::AreEqual(RET_OK, IsInternetConnectAdapter(44, &bRet));
|
||||
Assert::AreEqual(false, bRet);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestEnableNetConnectionSharing) {
|
||||
Assert::AreEqual(RET_OK, SetNetConnectionSharing(TEXT("wg_cli"), true, true));
|
||||
Assert::AreEqual(RET_OK, SetNetConnectionSharing(TEXT("wg_cli"), false, true));
|
||||
TEST_METHOD(TestGetNetConnectionSharing) {
|
||||
//bool chkStatus;
|
||||
//Assert::AreEqual(RET_OK, GetNetIntelnetConnectionSharing(TEXT("admin"), &chkStatus));
|
||||
//Assert::IsTrue(chkStatus);
|
||||
}
|
||||
|
||||
TEST_METHOD(TestSetNetConnectionNetworkCategory) {
|
||||
|
@ -164,28 +167,47 @@ public:
|
|||
}
|
||||
|
||||
TEST_METHOD(TestWaitNetAdapterConnected) {
|
||||
Assert::AreEqual(RET_OK, WaitNetAdapterConnected(TEXT("admin"), 10* 1000));
|
||||
Assert::AreEqual(RET_OK, WaitNetAdapterConnected(TEXT("admin"), 10 * 1000));
|
||||
}
|
||||
|
||||
TEST_METHOD(TestProtoGetUserConfigure) {
|
||||
//Assert::AreEqual(RET_OK, ProtoGetUserConfigure("admin", "asfdsafdladf083asldf+="));
|
||||
}
|
||||
|
||||
TEST_METHOD(TestAddRouteTable) {
|
||||
Assert::AreEqual(RET_OK, AddRouteTable(TEXT("1.1.1.1"), TEXT("255.255.255.0"), TEXT("10.10.10.1")));
|
||||
}
|
||||
|
||||
TEST_METHOD(TestGetInterfaceGUIDByName) {
|
||||
GUID guid;
|
||||
;
|
||||
|
||||
Assert::AreEqual(RET_OK, GetInterfaceGUIDByName(TEXT("admin"), &guid));
|
||||
Assert::AreNotEqual(0, static_cast<int>(guid.Data1));
|
||||
|
||||
//Assert::AreEqual(RET_OK, ProtoGetUserConfigure("admin", "asfdsafdladf083asldf+="));
|
||||
}
|
||||
|
||||
TEST_METHOD(TestSetNATRule) {
|
||||
Assert::AreEqual(RET_OK, SetNATRule(TEXT("admin"), TEXT("10.10.10.250/24")));
|
||||
}
|
||||
|
||||
TEST_METHOD(TestRemoveNATRule) {
|
||||
Assert::AreEqual(RET_OK, RemoveNATRule(TEXT("admin")));
|
||||
}
|
||||
|
||||
|
||||
TEST_METHOD(TestGetInterfaceIfIndexByIpAddr) {
|
||||
ULONG index = -1;
|
||||
Assert::AreEqual(RET_OK, GetInterfaceIfIndexByIpAddr(TEXT("10.10.10.1"), &index));
|
||||
Assert::AreNotEqual(-1, static_cast<int>(index));
|
||||
}
|
||||
|
||||
TEST_METHOD(TestClientProgress) {
|
||||
PUSER_CLIENT_CONFIG pCfg = nullptr;
|
||||
Assert::AreEqual(RET_OK, GetUserClientConfigure(TEXT("admin"), TEXT("1323245235"), &pCfg));
|
||||
Assert::IsNotNull(pCfg);
|
||||
|
||||
Assert::AreEqual(RET_OK, RemoteCtrlSvrCfgUserTunnel(2, TEXT("172.18.2.128/26")));
|
||||
Assert::AreEqual(RET_OK, RemoteCtrlSvrCfgUserTunnel(2, TEXT("172.18.2.0/24")));
|
||||
|
||||
Assert::AreEqual(RET_OK, LocalWireGuardControl(true, true));
|
||||
}
|
||||
|
|
|
@ -24,65 +24,131 @@ Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "InstallTunnelSDK", "Install
|
|||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug DLL|Any CPU = Debug DLL|Any CPU
|
||||
Debug DLL|x64 = Debug DLL|x64
|
||||
Debug DLL|x86 = Debug DLL|x86
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release DLL|Any CPU = Release DLL|Any CPU
|
||||
Release DLL|x64 = Release DLL|x64
|
||||
Release DLL|x86 = Release DLL|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Debug DLL|Any CPU.ActiveCfg = Debug|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Debug DLL|Any CPU.Build.0 = Debug|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Debug DLL|x64.ActiveCfg = Debug|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Debug DLL|x64.Build.0 = Debug|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Debug DLL|x86.ActiveCfg = Debug|Win32
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Debug DLL|x86.Build.0 = Debug|Win32
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Debug|x64.Build.0 = Debug|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Debug|x86.Build.0 = Debug|Win32
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Release DLL|Any CPU.ActiveCfg = Release|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Release DLL|Any CPU.Build.0 = Release|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Release DLL|x64.ActiveCfg = Release|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Release DLL|x64.Build.0 = Release|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Release DLL|x86.ActiveCfg = Release|Win32
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Release DLL|x86.Build.0 = Release|Win32
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Release|Any CPU.Build.0 = Release|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Release|x64.ActiveCfg = Release|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Release|x64.Build.0 = Release|x64
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Release|x86.ActiveCfg = Release|Win32
|
||||
{1584BAD4-DBEC-43D2-BC06-08C23F02489A}.Release|x86.Build.0 = Release|Win32
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Debug DLL|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Debug DLL|Any CPU.Build.0 = Debug|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Debug DLL|x64.ActiveCfg = Debug|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Debug DLL|x64.Build.0 = Debug|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Debug DLL|x86.ActiveCfg = Debug|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Debug DLL|x86.Build.0 = Debug|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Release DLL|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Release DLL|Any CPU.Build.0 = Release|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Release DLL|x64.ActiveCfg = Release|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Release DLL|x64.Build.0 = Release|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Release DLL|x86.ActiveCfg = Release|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Release DLL|x86.Build.0 = Release|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Release|x64.Build.0 = Release|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{79995848-FD05-46F5-A7FE-46265E540E32}.Release|x86.Build.0 = Release|Any CPU
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Debug DLL|Any CPU.ActiveCfg = Debug|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Debug DLL|Any CPU.Build.0 = Debug|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Debug DLL|x64.ActiveCfg = Debug|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Debug DLL|x64.Build.0 = Debug|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Debug DLL|x86.ActiveCfg = Debug|Win32
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Debug DLL|x86.Build.0 = Debug|Win32
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Debug|x64.Build.0 = Debug|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Debug|x86.Build.0 = Debug|Win32
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Release DLL|Any CPU.ActiveCfg = Release|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Release DLL|Any CPU.Build.0 = Release|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Release DLL|x64.ActiveCfg = Release|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Release DLL|x64.Build.0 = Release|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Release DLL|x86.ActiveCfg = Release|Win32
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Release DLL|x86.Build.0 = Release|Win32
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Release|Any CPU.Build.0 = Release|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Release|x64.ActiveCfg = Release|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Release|x64.Build.0 = Release|x64
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Release|x86.ActiveCfg = Release|Win32
|
||||
{61FE87EB-A3BA-4A7E-971C-69CB05F5C81C}.Release|x86.Build.0 = Release|Win32
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Debug DLL|Any CPU.ActiveCfg = Debug|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Debug DLL|Any CPU.Build.0 = Debug|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Debug DLL|x64.ActiveCfg = Debug|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Debug DLL|x64.Build.0 = Debug|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Debug DLL|x86.ActiveCfg = Debug|Win32
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Debug DLL|x86.Build.0 = Debug|Win32
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Debug|Any CPU.Build.0 = Debug|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Debug|x64.Build.0 = Debug|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Debug|x86.Build.0 = Debug|Win32
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Release DLL|Any CPU.ActiveCfg = Release|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Release DLL|Any CPU.Build.0 = Release|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Release DLL|x64.ActiveCfg = Release|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Release DLL|x64.Build.0 = Release|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Release DLL|x86.ActiveCfg = Release|Win32
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Release DLL|x86.Build.0 = Release|Win32
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Release|Any CPU.ActiveCfg = Release|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Release|Any CPU.Build.0 = Release|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Release|x64.ActiveCfg = Release|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Release|x64.Build.0 = Release|x64
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Release|x86.ActiveCfg = Release|Win32
|
||||
{9F44F41E-FACF-472D-A382-A40D0A84DB2C}.Release|x86.Build.0 = Release|Win32
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Debug DLL|Any CPU.ActiveCfg = Debug
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Debug DLL|Any CPU.Build.0 = Debug
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Debug DLL|x64.ActiveCfg = Debug
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Debug DLL|x64.Build.0 = Debug
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Debug DLL|x86.ActiveCfg = Debug
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Debug DLL|x86.Build.0 = Debug
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Debug|Any CPU.ActiveCfg = Debug
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Debug|x64.ActiveCfg = Debug
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Debug|x86.ActiveCfg = Debug
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Release DLL|Any CPU.ActiveCfg = Release
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Release DLL|Any CPU.Build.0 = Release
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Release DLL|x64.ActiveCfg = Release
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Release DLL|x64.Build.0 = Release
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Release DLL|x86.ActiveCfg = Release
|
||||
{FE91D4D0-29A6-4C58-874F-11F6AC1D50CD}.Release DLL|x86.Build.0 = Release
|
||||
{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
|
||||
|
|
Loading…
Reference in New Issue