diff --git a/Installer/Installer.vdproj b/Installer/Installer.vdproj deleted file mode 100644 index 57eebb7..0000000 --- a/Installer/Installer.vdproj +++ /dev/null @@ -1,1282 +0,0 @@ -"DeployProject" -{ -"VSVersion" = "3:800" -"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" -"IsWebType" = "8:FALSE" -"ProjectName" = "8:Installer" -"LanguageId" = "3:2052" -"CodePage" = "3:936" -"UILanguageId" = "3:2052" -"SccProjectName" = "8:" -"SccLocalPath" = "8:" -"SccAuxPath" = "8:" -"SccProvider" = "8:" - "Hierarchy" - { - "Entry" - { - "MsmKey" = "8:_32C885830BEA2569BF785ADEDAB54E65" - "OwnerKey" = "8:_7B4AC697FAEC40DE88D57FF770C065C7" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_40DAEDFDD9E6501D6798A1975BA9F207" - "OwnerKey" = "8:_7B4AC697FAEC40DE88D57FF770C065C7" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_45CCE96D5B88A09A1A06825E060313E1" - "OwnerKey" = "8:_7B4AC697FAEC40DE88D57FF770C065C7" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_47C4D32A394F59E2F61A981224D98FE6" - "OwnerKey" = "8:_7B4AC697FAEC40DE88D57FF770C065C7" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7B4AC697FAEC40DE88D57FF770C065C7" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_92E0C26999D59D33D0500624357FF7A1" - "OwnerKey" = "8:_9C849F5EE1DB4634B3B8ABAEAD8840E3" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_9C849F5EE1DB4634B3B8ABAEAD8840E3" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_CE6D8A8A59A289F04E5BB3509A6FB9E4" - "OwnerKey" = "8:_7B4AC697FAEC40DE88D57FF770C065C7" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_D28DB800C44D72D9F1895AE1A3F28136" - "OwnerKey" = "8:_7B4AC697FAEC40DE88D57FF770C065C7" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_DDDEC90D22B81D6B9D637B1C197520B4" - "OwnerKey" = "8:_9C849F5EE1DB4634B3B8ABAEAD8840E3" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_9C849F5EE1DB4634B3B8ABAEAD8840E3" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_92E0C26999D59D33D0500624357FF7A1" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_DDDEC90D22B81D6B9D637B1C197520B4" - "MsmSig" = "8:_UNDEFINED" - } - } - "Configurations" - { - "Debug" - { - "DisplayName" = "8:Debug" - "IsDebugOnly" = "11:TRUE" - "IsReleaseOnly" = "11:FALSE" - "OutputFilename" = "8:Debug\\Installer.msi" - "PackageFilesAs" = "3:2" - "PackageFileSize" = "3:-2147483648" - "CabType" = "3:1" - "Compression" = "3:2" - "SignOutput" = "11:FALSE" - "CertificateFile" = "8:" - "PrivateKeyFile" = "8:" - "TimeStampServer" = "8:" - "InstallerBootstrapper" = "3:2" - "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" - { - "Enabled" = "11:TRUE" - "PromptEnabled" = "11:TRUE" - "PrerequisitesLocation" = "2:1" - "Url" = "8:" - "ComponentsUrl" = "8:" - "Items" - { - "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2" - { - "Name" = "8:Microsoft .NET Framework 4.7.2 (x86 和 x64)" - "ProductCode" = "8:.NETFramework,Version=v4.7.2" - } - "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:Microsoft.Visual.C++.14.0.x64" - { - "Name" = "8:Visual C++ \"14\" Runtime Libraries (x64)" - "ProductCode" = "8:Microsoft.Visual.C++.14.0.x64" - } - } - } - } - "Release" - { - "DisplayName" = "8:Release" - "IsDebugOnly" = "11:FALSE" - "IsReleaseOnly" = "11:TRUE" - "OutputFilename" = "8:Release\\Installer.msi" - "PackageFilesAs" = "3:2" - "PackageFileSize" = "3:-2147483648" - "CabType" = "3:1" - "Compression" = "3:2" - "SignOutput" = "11:FALSE" - "CertificateFile" = "8:" - "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" - { - "CustomAction" - { - } - "DefaultFeature" - { - "Name" = "8:DefaultFeature" - "Title" = "8:" - "Description" = "8:" - } - "ExternalPersistence" - { - "LaunchCondition" - { - "{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_A5BB7E344FA24DEBB7C9609F13DFCE4A" - { - "Name" = "8:.NET Framework" - "Message" = "8:[VSDNETMSG]" - "FrameworkVersion" = "8:.NETFramework,Version=v4.7.2" - "AllowLaterVersions" = "11:FALSE" - "InstallUrl" = "8:http://go.microsoft.com/fwlink/?LinkId=863262" - } - } - } - "File" - { - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_32C885830BEA2569BF785ADEDAB54E65" - { - "SourcePath" = "8:VCRUNTIME140_1D.dll" - "TargetName" = "8:VCRUNTIME140_1D.dll" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_40DAEDFDD9E6501D6798A1975BA9F207" - { - "SourcePath" = "8:VCRUNTIME140D.dll" - "TargetName" = "8:VCRUNTIME140D.dll" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_45CCE96D5B88A09A1A06825E060313E1" - { - "SourcePath" = "8:fmtd.dll" - "TargetName" = "8:fmtd.dll" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_47C4D32A394F59E2F61A981224D98FE6" - { - "SourcePath" = "8:IPHLPAPI.DLL" - "TargetName" = "8:IPHLPAPI.DLL" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:TRUE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_92E0C26999D59D33D0500624357FF7A1" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_92E0C26999D59D33D0500624357FF7A1" - { - "Name" = "8:System.Buffers.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:System.Buffers.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CE6D8A8A59A289F04E5BB3509A6FB9E4" - { - "SourcePath" = "8:ucrtbased.dll" - "TargetName" = "8:ucrtbased.dll" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_D28DB800C44D72D9F1895AE1A3F28136" - { - "SourcePath" = "8:MSVCP140D.dll" - "TargetName" = "8:MSVCP140D.dll" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_DDDEC90D22B81D6B9D637B1C197520B4" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" - "ScatterAssemblies" - { - "_DDDEC90D22B81D6B9D637B1C197520B4" - { - "Name" = "8:System.Net.Http.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:System.Net.Http.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - } - "FileType" - { - } - "Folder" - { - "{1525181F-901A-416C-8A58-119130FE478E}:_3BAF9D8D9CCF4551BCCBD24E49A3EAF6" - { - "Name" = "8:#1919" - "AlwaysCreate" = "11:FALSE" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Property" = "8:ProgramMenuFolder" - "Folders" - { - } - } - "{3C67513D-01DD-4637-8A68-80971EB9504F}:_60BFF23D0A1243198EC9AADE9A2E3765" - { - "DefaultLocation" = "8:[ProgramFiles64Folder][Manufacturer]\\[ProductName]" - "Name" = "8:#1925" - "AlwaysCreate" = "11:FALSE" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Property" = "8:TARGETDIR" - "Folders" - { - } - } - "{1525181F-901A-416C-8A58-119130FE478E}:_D9BCE2BA295B4166B9A030E9E2CB494F" - { - "Name" = "8:#1916" - "AlwaysCreate" = "11:FALSE" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Property" = "8:DesktopFolder" - "Folders" - { - } - } - } - "LaunchCondition" - { - } - "Locator" - { - } - "MsiBootstrapper" - { - "LangId" = "3:2052" - "RequiresElevation" = "11:FALSE" - } - "Product" - { - "Name" = "8:Microsoft Visual Studio" - "ProductName" = "8:NetTunnel" - "ProductCode" = "8:{CEFC493D-863B-44B7-A4C6-6F5E02824525}" - "PackageCode" = "8:{3A11741F-9E9C-4A84-BE93-441FCB50342D}" - "UpgradeCode" = "8:{2DB7D8E8-1615-4D99-AECB-0F80A3D22E38}" - "AspNetVersion" = "8:" - "RestartWWWService" = "11:FALSE" - "RemovePreviousVersions" = "11:TRUE" - "DetectNewerInstalledVersion" = "11:TRUE" - "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.0.0" - "Manufacturer" = "8:CMHI" - "ARPHELPTELEPHONE" = "8:" - "ARPHELPLINK" = "8:" - "Title" = "8:NetTunnel Installer" - "Subject" = "8:" - "ARPCONTACT" = "8:cmhi" - "Keywords" = "8:NetTunnel" - "ARPCOMMENTS" = "8:" - "ARPURLINFOABOUT" = "8:" - "ARPPRODUCTICON" = "8:" - "ARPIconIndex" = "3:0" - "SearchPath" = "8:" - "UseSystemSearchPath" = "11:TRUE" - "TargetPlatform" = "3:1" - "PreBuildEvent" = "8:" - "PostBuildEvent" = "8:" - "RunPostBuildEvent" = "3:0" - } - "Registry" - { - "HKLM" - { - "Keys" - { - "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_27535BF731634CDA9618E42CFF3E49F9" - { - "Name" = "8:Software" - "Condition" = "8:" - "AlwaysCreate" = "11:FALSE" - "DeleteAtUninstall" = "11:FALSE" - "Transitive" = "11:FALSE" - "Keys" - { - "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_45B07657BD31432C8B81C0ED36D87965" - { - "Name" = "8:[Manufacturer]" - "Condition" = "8:" - "AlwaysCreate" = "11:FALSE" - "DeleteAtUninstall" = "11:FALSE" - "Transitive" = "11:FALSE" - "Keys" - { - } - "Values" - { - } - } - } - "Values" - { - } - } - } - } - "HKCU" - { - "Keys" - { - "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_68D7CD0FB57C4FB0918E7F7AE825171F" - { - "Name" = "8:Software" - "Condition" = "8:" - "AlwaysCreate" = "11:FALSE" - "DeleteAtUninstall" = "11:FALSE" - "Transitive" = "11:FALSE" - "Keys" - { - "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_98922D05A0DF4903A09E2A7BE3327CF6" - { - "Name" = "8:[Manufacturer]" - "Condition" = "8:" - "AlwaysCreate" = "11:FALSE" - "DeleteAtUninstall" = "11:FALSE" - "Transitive" = "11:FALSE" - "Keys" - { - } - "Values" - { - } - } - } - "Values" - { - } - } - } - } - "HKCR" - { - "Keys" - { - } - } - "HKU" - { - "Keys" - { - } - } - "HKPU" - { - "Keys" - { - } - } - } - "Sequences" - { - } - "Shortcut" - { - } - "UserInterface" - { - "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_03EEDED1C94342FA979B85B557E123A9" - { - "UseDynamicProperties" = "11:FALSE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdBasicDialogs.wim" - } - "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_24173ED8845E4425B2E93DDF4E6C200B" - { - "Name" = "8:#1902" - "Sequence" = "3:1" - "Attributes" = "3:3" - "Dialogs" - { - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_21CCA095C7674E539510AAF67FE70162" - { - "Sequence" = "3:100" - "DisplayName" = "8:已完成" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdFinishedDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - "UpdateText" - { - "Name" = "8:UpdateText" - "DisplayName" = "8:#1058" - "Description" = "8:#1158" - "Type" = "3:15" - "ContextData" = "8:" - "Attributes" = "3:0" - "Setting" = "3:1" - "Value" = "8:#1258" - "DefaultValue" = "8:#1258" - "UsePlugInResources" = "11:TRUE" - } - } - } - } - } - "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_2472925F3E314BB189A25ABDF1D89E2A" - { - "Name" = "8:#1901" - "Sequence" = "3:2" - "Attributes" = "3:2" - "Dialogs" - { - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_E3B87FC2F1704EC6B074CD7057B7CF07" - { - "Sequence" = "3:100" - "DisplayName" = "8:进度" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdAdminProgressDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - "ShowProgress" - { - "Name" = "8:ShowProgress" - "DisplayName" = "8:#1009" - "Description" = "8:#1109" - "Type" = "3:5" - "ContextData" = "8:1;True=1;False=0" - "Attributes" = "3:0" - "Setting" = "3:0" - "Value" = "3:1" - "DefaultValue" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - } - } - } - } - "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_7415493D045044228DD00CA2AD697B8A" - { - "Name" = "8:#1900" - "Sequence" = "3:2" - "Attributes" = "3:1" - "Dialogs" - { - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_2E40F9E3891C4180B15443F9817B644B" - { - "Sequence" = "3:100" - "DisplayName" = "8:欢迎使用" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdAdminWelcomeDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - "CopyrightWarning" - { - "Name" = "8:CopyrightWarning" - "DisplayName" = "8:#1002" - "Description" = "8:#1102" - "Type" = "3:3" - "ContextData" = "8:" - "Attributes" = "3:0" - "Setting" = "3:1" - "Value" = "8:#1202" - "DefaultValue" = "8:#1202" - "UsePlugInResources" = "11:TRUE" - } - "Welcome" - { - "Name" = "8:Welcome" - "DisplayName" = "8:#1003" - "Description" = "8:#1103" - "Type" = "3:3" - "ContextData" = "8:" - "Attributes" = "3:0" - "Setting" = "3:1" - "Value" = "8:#1203" - "DefaultValue" = "8:#1203" - "UsePlugInResources" = "11:TRUE" - } - } - } - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_4A030CA83E704D609EFD739AD4905B76" - { - "Sequence" = "3:300" - "DisplayName" = "8:确认安装" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdAdminConfirmDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - } - } - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_71889A31603546EA8BF63B29C6F22F01" - { - "Sequence" = "3:200" - "DisplayName" = "8:安装文件夹" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdAdminFolderDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - } - } - } - } - "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_74E3444A87284C98A38994098C384985" - { - "Name" = "8:#1901" - "Sequence" = "3:1" - "Attributes" = "3:2" - "Dialogs" - { - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_B1089C98093F4905813CD4F008D39666" - { - "Sequence" = "3:100" - "DisplayName" = "8:进度" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdProgressDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - "ShowProgress" - { - "Name" = "8:ShowProgress" - "DisplayName" = "8:#1009" - "Description" = "8:#1109" - "Type" = "3:5" - "ContextData" = "8:1;True=1;False=0" - "Attributes" = "3:0" - "Setting" = "3:0" - "Value" = "3:1" - "DefaultValue" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - } - } - } - } - "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_C5097ED9B8CC4D2A9092371F716B993B" - { - "UseDynamicProperties" = "11:FALSE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdUserInterface.wim" - } - "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_E8EE8A90426D43D9BB9EA2148D8858FB" - { - "Name" = "8:#1902" - "Sequence" = "3:2" - "Attributes" = "3:3" - "Dialogs" - { - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_FF5B91300E3C476D93A4C205AB744ABA" - { - "Sequence" = "3:100" - "DisplayName" = "8:已完成" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdAdminFinishedDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - } - } - } - } - "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_EB1977F7500A43F9967B0AAAB1603D82" - { - "Name" = "8:#1900" - "Sequence" = "3:1" - "Attributes" = "3:1" - "Dialogs" - { - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_20082099F9E54149BCE5C453EF50FBCD" - { - "Sequence" = "3:300" - "DisplayName" = "8:确认安装" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdConfirmDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - } - } - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_87D3C97C06AE4FAEB0938EAB3466D19A" - { - "Sequence" = "3:200" - "DisplayName" = "8:安装文件夹" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdFolderDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - "InstallAllUsersVisible" - { - "Name" = "8:InstallAllUsersVisible" - "DisplayName" = "8:#1059" - "Description" = "8:#1159" - "Type" = "3:5" - "ContextData" = "8:1;True=1;False=0" - "Attributes" = "3:0" - "Setting" = "3:0" - "Value" = "3:1" - "DefaultValue" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - } - } - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_ABDAD826A9854B6696F53E1CFFC874D0" - { - "Sequence" = "3:100" - "DisplayName" = "8:欢迎使用" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdWelcomeDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - "CopyrightWarning" - { - "Name" = "8:CopyrightWarning" - "DisplayName" = "8:#1002" - "Description" = "8:#1102" - "Type" = "3:3" - "ContextData" = "8:" - "Attributes" = "3:0" - "Setting" = "3:1" - "Value" = "8:#1202" - "DefaultValue" = "8:#1202" - "UsePlugInResources" = "11:TRUE" - } - "Welcome" - { - "Name" = "8:Welcome" - "DisplayName" = "8:#1003" - "Description" = "8:#1103" - "Type" = "3:3" - "ContextData" = "8:" - "Attributes" = "3:0" - "Setting" = "3:1" - "Value" = "8:#1203" - "DefaultValue" = "8:#1203" - "UsePlugInResources" = "11:TRUE" - } - } - } - } - } - } - "MergeModule" - { - } - "ProjectOutput" - { - "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_03737E22A5C34E229120295C99D58006" - { - "SourcePath" = "8:" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:" - "ProjectOutputGroupRegister" = "3:1" - "OutputConfiguration" = "8:" - "OutputGroupCanonicalName" = "8:LocalizedResourceDlls" - "OutputProjectGuid" = "8:{79995848-FD05-46F5-A7FE-46265E540E32}" - "ShowKeyOutput" = "11:TRUE" - "ExcludeFilters" - { - } - } - "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_0EDB704F25DF49F2A0D4EB3EDE27B117" - { - "SourcePath" = "8:" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:" - "ProjectOutputGroupRegister" = "3:1" - "OutputConfiguration" = "8:" - "OutputGroupCanonicalName" = "8:RuntimeImplementation" - "OutputProjectGuid" = "8:{79995848-FD05-46F5-A7FE-46265E540E32}" - "ShowKeyOutput" = "11:TRUE" - "ExcludeFilters" - { - } - } - "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_16C46B2422D14439BB7BB8E78FAD3382" - { - "SourcePath" = "8:" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:" - "ProjectOutputGroupRegister" = "3:1" - "OutputConfiguration" = "8:" - "OutputGroupCanonicalName" = "8:ContentFiles" - "OutputProjectGuid" = "8:{79995848-FD05-46F5-A7FE-46265E540E32}" - "ShowKeyOutput" = "11:TRUE" - "ExcludeFilters" - { - } - } - "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_5DD617B10B03466D827B266F34049F87" - { - "SourcePath" = "8:" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:" - "ProjectOutputGroupRegister" = "3:1" - "OutputConfiguration" = "8:" - "OutputGroupCanonicalName" = "8:Symbols" - "OutputProjectGuid" = "8:{79995848-FD05-46F5-A7FE-46265E540E32}" - "ShowKeyOutput" = "11:TRUE" - "ExcludeFilters" - { - } - } - "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_636047C91CCE400E9A0B91CD3655A399" - { - "SourcePath" = "8:" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:" - "ProjectOutputGroupRegister" = "3:1" - "OutputConfiguration" = "8:" - "OutputGroupCanonicalName" = "8:Documentation" - "OutputProjectGuid" = "8:{1584BAD4-DBEC-43D2-BC06-08C23F02489A}" - "ShowKeyOutput" = "11:TRUE" - "ExcludeFilters" - { - } - } - "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_640AD94D93714A32ADF2435FDA40BA85" - { - "SourcePath" = "8:" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:" - "ProjectOutputGroupRegister" = "3:1" - "OutputConfiguration" = "8:" - "OutputGroupCanonicalName" = "8:LocalizedResourceDlls" - "OutputProjectGuid" = "8:{1584BAD4-DBEC-43D2-BC06-08C23F02489A}" - "ShowKeyOutput" = "11:TRUE" - "ExcludeFilters" - { - } - } - "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_69EF57E47A1846F1BF1FEF0303DDE76B" - { - "SourcePath" = "8:" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:" - "ProjectOutputGroupRegister" = "3:1" - "OutputConfiguration" = "8:" - "OutputGroupCanonicalName" = "8:ReferenceCopyLocalPaths" - "OutputProjectGuid" = "8:{79995848-FD05-46F5-A7FE-46265E540E32}" - "ShowKeyOutput" = "11:TRUE" - "ExcludeFilters" - { - } - } - "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_7B4AC697FAEC40DE88D57FF770C065C7" - { - "SourcePath" = "8:..\\x64\\Debug\\NetTunnelSDK.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:" - "ProjectOutputGroupRegister" = "3:1" - "OutputConfiguration" = "8:" - "OutputGroupCanonicalName" = "8:Built" - "OutputProjectGuid" = "8:{1584BAD4-DBEC-43D2-BC06-08C23F02489A}" - "ShowKeyOutput" = "11:TRUE" - "ExcludeFilters" - { - } - } - "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_9C849F5EE1DB4634B3B8ABAEAD8840E3" - { - "SourcePath" = "8:..\\NetTunnelApp\\obj\\Debug\\NetTunnelApp.exe" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:" - "ProjectOutputGroupRegister" = "3:1" - "OutputConfiguration" = "8:" - "OutputGroupCanonicalName" = "8:Built" - "OutputProjectGuid" = "8:{79995848-FD05-46F5-A7FE-46265E540E32}" - "ShowKeyOutput" = "11:TRUE" - "ExcludeFilters" - { - } - } - "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_BE8F4A686B3340DD910C5715B5FBC288" - { - "SourcePath" = "8:" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:" - "ProjectOutputGroupRegister" = "3:1" - "OutputConfiguration" = "8:" - "OutputGroupCanonicalName" = "8:ContentFiles" - "OutputProjectGuid" = "8:{1584BAD4-DBEC-43D2-BC06-08C23F02489A}" - "ShowKeyOutput" = "11:TRUE" - "ExcludeFilters" - { - } - } - "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_CC88BEEDF08D406E8CE6557E2E1985A6" - { - "SourcePath" = "8:" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:" - "ProjectOutputGroupRegister" = "3:1" - "OutputConfiguration" = "8:" - "OutputGroupCanonicalName" = "8:Symbols" - "OutputProjectGuid" = "8:{1584BAD4-DBEC-43D2-BC06-08C23F02489A}" - "ShowKeyOutput" = "11:TRUE" - "ExcludeFilters" - { - } - } - "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_EAE067E73F3D47F7B0D5FA1C0818699A" - { - "SourcePath" = "8:" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_60BFF23D0A1243198EC9AADE9A2E3765" - "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:" - "ProjectOutputGroupRegister" = "3:1" - "OutputConfiguration" = "8:" - "OutputGroupCanonicalName" = "8:XmlSerializer" - "OutputProjectGuid" = "8:{79995848-FD05-46F5-A7FE-46265E540E32}" - "ShowKeyOutput" = "11:TRUE" - "ExcludeFilters" - { - } - } - } - } -} diff --git a/NetTunnelApp/MainForm.Designer.cs b/NetTunnelApp/MainForm.Designer.cs index a6cd653..79b6582 100644 --- a/NetTunnelApp/MainForm.Designer.cs +++ b/NetTunnelApp/MainForm.Designer.cs @@ -41,12 +41,14 @@ this.menuControl = new System.Windows.Forms.ToolStripMenuItem(); this.menuControlRefInterface = new System.Windows.Forms.ToolStripMenuItem(); this.menuControlEnv = new System.Windows.Forms.ToolStripMenuItem(); + this.menuControlSetCliParams = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); this.menuControlService = new System.Windows.Forms.ToolStripMenuItem(); this.menuControlSvrStart = new System.Windows.Forms.ToolStripMenuItem(); this.menuControlSvrStop = 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(); @@ -68,7 +70,9 @@ this.trapMenuSysInterface = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); this.trapMenuExit = new System.Windows.Forms.ToolStripMenuItem(); - this.menuSetModeShareServer = new System.Windows.Forms.ToolStripMenuItem(); + this.menuControlHeart = new System.Windows.Forms.ToolStripMenuItem(); + this.menuControlHeartStart = new System.Windows.Forms.ToolStripMenuItem(); + this.menuControlHeartStop = new System.Windows.Forms.ToolStripMenuItem(); this.menuMain.SuspendLayout(); this.trapMenuMain.SuspendLayout(); this.SuspendLayout(); @@ -129,19 +133,19 @@ // menuFileLogin // this.menuFileLogin.Name = "menuFileLogin"; - this.menuFileLogin.Size = new System.Drawing.Size(180, 22); + this.menuFileLogin.Size = new System.Drawing.Size(116, 22); this.menuFileLogin.Text = "登录(&L)"; this.menuFileLogin.Click += new System.EventHandler(this.menuFileLogin_Click); // // toolStripSeparator4 // this.toolStripSeparator4.Name = "toolStripSeparator4"; - this.toolStripSeparator4.Size = new System.Drawing.Size(177, 6); + this.toolStripSeparator4.Size = new System.Drawing.Size(113, 6); // // menuFileExit // this.menuFileExit.Name = "menuFileExit"; - this.menuFileExit.Size = new System.Drawing.Size(180, 22); + this.menuFileExit.Size = new System.Drawing.Size(116, 22); this.menuFileExit.Text = "退出(&X)"; // // menuControl @@ -149,8 +153,10 @@ this.menuControl.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.menuControlRefInterface, this.menuControlEnv, + this.menuControlSetCliParams, this.toolStripSeparator2, - this.menuControlService}); + this.menuControlService, + this.menuControlHeart}); this.menuControl.Name = "menuControl"; this.menuControl.Size = new System.Drawing.Size(60, 21); this.menuControl.Text = "操作(&C)"; @@ -168,6 +174,13 @@ 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(180, 22); + this.menuControlSetCliParams.Text = "设置客户端参数"; + this.menuControlSetCliParams.Click += new System.EventHandler(this.menuControlSetCliParams_Click); + // // toolStripSeparator2 // this.toolStripSeparator2.Name = "toolStripSeparator2"; @@ -180,19 +193,21 @@ this.menuControlSvrStop}); this.menuControlService.Name = "menuControlService"; this.menuControlService.Size = new System.Drawing.Size(180, 22); - this.menuControlService.Text = "服务管理(&V)"; + this.menuControlService.Text = "隧道服务管理(&V)"; // // menuControlSvrStart // this.menuControlSvrStart.Name = "menuControlSvrStart"; - this.menuControlSvrStart.Size = new System.Drawing.Size(124, 22); + this.menuControlSvrStart.Size = new System.Drawing.Size(180, 22); this.menuControlSvrStart.Text = "启动服务"; + this.menuControlSvrStart.Click += new System.EventHandler(this.menuControlSvrStart_Click); // // menuControlSvrStop // this.menuControlSvrStop.Name = "menuControlSvrStop"; - this.menuControlSvrStop.Size = new System.Drawing.Size(124, 22); + this.menuControlSvrStop.Size = new System.Drawing.Size(180, 22); this.menuControlSvrStop.Text = "停止服务"; + this.menuControlSvrStop.Click += new System.EventHandler(this.menuControlSvrStop_Click); // // menuMainSet // @@ -213,6 +228,12 @@ 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[] { @@ -255,14 +276,14 @@ // menuSetVPNPath // this.menuSetVPNPath.Name = "menuSetVPNPath"; - this.menuSetVPNPath.Size = new System.Drawing.Size(180, 22); + this.menuSetVPNPath.Size = new System.Drawing.Size(153, 22); this.menuSetVPNPath.Text = "安装路径"; this.menuSetVPNPath.Click += new System.EventHandler(this.menuSetVPNPath_Click); // // menuSetVPNCfgFiles // this.menuSetVPNCfgFiles.Name = "menuSetVPNCfgFiles"; - this.menuSetVPNCfgFiles.Size = new System.Drawing.Size(180, 22); + this.menuSetVPNCfgFiles.Size = new System.Drawing.Size(153, 22); this.menuSetVPNCfgFiles.Text = "VPN 配置文件"; // // menuSetExitToTray @@ -366,11 +387,28 @@ this.trapMenuExit.Text = "退出程序"; this.trapMenuExit.Click += new System.EventHandler(this.trapMenuExit_Click); // - // menuSetModeShareServer + // menuControlHeart // - this.menuSetModeShareServer.Name = "menuSetModeShareServer"; - this.menuSetModeShareServer.Size = new System.Drawing.Size(180, 22); - this.menuSetModeShareServer.Text = "云电脑服务器"; + this.menuControlHeart.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.menuControlHeartStart, + this.menuControlHeartStop}); + this.menuControlHeart.Name = "menuControlHeart"; + this.menuControlHeart.Size = new System.Drawing.Size(180, 22); + this.menuControlHeart.Text = "心跳服务管理"; + // + // menuControlHeartStart + // + this.menuControlHeartStart.Name = "menuControlHeartStart"; + this.menuControlHeartStart.Size = new System.Drawing.Size(180, 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.Text = "停止心跳服务"; + this.menuControlHeartStop.Click += new System.EventHandler(this.menuControlHeartStop_Click); // // MainForm // @@ -437,6 +475,10 @@ private System.Windows.Forms.ToolStripMenuItem menuSetVPNCfgFiles; private System.Windows.Forms.ToolStripMenuItem trapMenuCfgFiles; private System.Windows.Forms.ToolStripMenuItem menuSetModeShareServer; + private System.Windows.Forms.ToolStripMenuItem menuControlSetCliParams; + private System.Windows.Forms.ToolStripMenuItem menuControlHeart; + private System.Windows.Forms.ToolStripMenuItem menuControlHeartStart; + private System.Windows.Forms.ToolStripMenuItem menuControlHeartStop; } } diff --git a/NetTunnelApp/MainForm.cs b/NetTunnelApp/MainForm.cs index 9292cba..f7c0300 100644 --- a/NetTunnelApp/MainForm.cs +++ b/NetTunnelApp/MainForm.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Net; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; @@ -199,6 +200,9 @@ public partial class MainForm : Form NetCardMenuItems menuItems = new NetCardMenuItems(_curNetCard); NetCardMenuItems ctxMenu = new NetCardMenuItems(_curNetCard); + menuSetModeShareNet.DropDownItems.Clear(); + trapMenuSysInterface.DropDownItems.Clear(); + foreach (var item in menuItems.GetMenuItems()) { menuSetModeShareNet.DropDownItems.Add(item); @@ -274,7 +278,8 @@ public partial class MainForm : Form { IntPtr pt = new IntPtr(); - if (NetTunnelLib.UserLogin(args.HashArgs["UserName"] as string, args.HashArgs["Password"] as string, + if (NetTunnelLib.GetUserClientConfigure(args.HashArgs["UserName"] as string, + args.HashArgs["Password"] as string, out pt) == 0) { IntPtr p = new IntPtr(pt.ToInt64()); @@ -282,15 +287,17 @@ public partial class MainForm : Form //Console.WriteLine("scgCtrlAppId:{0}", cfg.scgCtrlAppId); //Console.WriteLine("scgTunnelAppId:{0}", cfg.scgTunnelAppId); - //Console.WriteLine("ClientPublicKey:{0}", cfg.cliPrivateKey); + //Console.WriteLine("ClientPrivateKey:{0}", cfg.cliPrivateKey); + //Console.WriteLine("ClientPublicKey:{0}", cfg.cliPublicKey); //Console.WriteLine("ClientAddress:{0}", cfg.cliAddress); _userConfig.scgCtrlAppId = cfg.scgCtrlAppId; _userConfig.scgTunnelAppId = cfg.scgTunnelAppId; _userConfig.cliPrivateKey = cfg.cliPrivateKey; - _userConfig.cliPrivateKey = cfg.cliAddress; + _userConfig.cliPublicKey = cfg.cliPublicKey; + _userConfig.cliAddress = cfg.cliAddress; _userConfig.vmList.Clear(); - + for (int i = 0; i < cfg.tolVM; i++) { IntPtr ptr = new IntPtr(cfg.pVMConfig.ToInt64() + Marshal.SizeOf(typeof(VirtualMathineConfig)) * i); @@ -305,8 +312,9 @@ public partial class MainForm : Form _userConfig.vmList.Add(vm); } - Marshal.FreeCoTaskMem(cfg.pVMConfig); - Marshal.FreeCoTaskMem(pt); + // Don't free any memory + //Marshal.FreeCoTaskMem(cfg.pVMConfig); + //Marshal.FreeCoTaskMem(pt); GetCurrentWgCfgs(args.HashArgs["UserName"] as string); @@ -314,6 +322,10 @@ public partial class MainForm : Form WgCfgMenuItems wgPopMenu = new WgCfgMenuItems(_curFilePaths); ServerMenuItems svrMenu = new ServerMenuItems(_userConfig.vmList); + menuSetVPNCfgFiles.DropDownItems.Clear(); + trapMenuCfgFiles.DropDownItems.Clear(); + menuSetModeShareServer.DropDownItems.Clear(); + foreach (var item in wgMenu.GetMenuItems()) { menuSetVPNCfgFiles.DropDownItems.Add(item); @@ -355,4 +367,80 @@ public partial class MainForm : Form { System.Environment.Exit(0); } + + private void menuControlSetCliParams_Click(object sender, EventArgs e) + { + var v = ServerMenuItems.GetSelectItemData(); + var c = NetCardMenuItems.GetSelectItemData(); + + //Console.WriteLine(v?.scgGateWay); + //Console.WriteLine(c?.Name); + + if (v?.scgGateWay.Length == 0) + { + MessageBox.Show("未选择需要连接的用户虚拟机"); + return; + } + else + { + NetTunnelLib.ConnectServerControlService("http://" + v?.scgGateWay); + } + + if (c?.UUID.Length == 0) + { + MessageBox.Show("未选择需要共享的本地网络"); + return; + } + else + { + IPNetwork ipnetwork = IPNetwork.Parse(c?.IpAddr, c?.NetMask); + IPNetwork cliNetwork = IPNetwork.Parse(_userConfig.cliAddress); + NetTunnelLib.SetClientConfige(_userConfig.cliPublicKey, ipnetwork.Value, cliNetwork.Network.ToString()); + } + } + + private void menuControlSvrStart_Click(object sender, EventArgs e) + { + var ret = NetTunnelLib.RemoteWireGuardControl(true); + + if (ret != 0) + { + MessageBox.Show("Error: " + ret.ToString()); + } + } + + private void menuControlSvrStop_Click(object sender, EventArgs e) + { + var ret = NetTunnelLib.RemoteWireGuardControl(false); + + if (ret != 0) + { + MessageBox.Show("Error: " + ret.ToString()); + } + } + + private void menuControlHeartStart_Click(object sender, EventArgs e) + { + HeartCallBack cb = new HeartCallBack((string msg, uint tm) => + { + Console.WriteLine(msg + tm.ToString()); + }); + + var ret = NetTunnelLib.RemoteHeartControl(true, cb); + + if (ret != 0) + { + MessageBox.Show("Error: " + ret.ToString()); + } + } + + private void menuControlHeartStop_Click(object sender, EventArgs e) + { + var ret = NetTunnelLib.RemoteHeartControl(false, null); + + if (ret != 0) + { + MessageBox.Show("Error: " + ret.ToString()); + } + } } \ No newline at end of file diff --git a/NetTunnelApp/NetCardMenuItems.cs b/NetTunnelApp/NetCardMenuItems.cs index 03c2f5e..3bc8445 100644 --- a/NetTunnelApp/NetCardMenuItems.cs +++ b/NetTunnelApp/NetCardMenuItems.cs @@ -14,6 +14,8 @@ namespace NetTunnelApp private List _menuItems = new List(); + private static List _menuDataItems = new List(); + public NetCardMenuItems(List netCardArray) { if (_menuItems.Count > 0) @@ -26,6 +28,9 @@ namespace NetTunnelApp _selItems = netCardArray[0].UUID; } + _menuDataItems.Clear(); + _menuDataItems.AddRange(netCardArray); + foreach (var netCard in netCardArray) { IPNetwork ipnetwork = IPNetwork.Parse(netCard.IpAddr, netCard.NetMask); @@ -59,5 +64,18 @@ namespace NetTunnelApp { return _menuItems; } + + public static NetCard? GetSelectItemData() + { + foreach (var k in _menuDataItems) + { + if (_selItems == k.UUID) + { + return k; + } + } + + return null; + } } } \ No newline at end of file diff --git a/NetTunnelApp/NetTunnelLib.cs b/NetTunnelApp/NetTunnelLib.cs index 94d2a6f..c6541e2 100644 --- a/NetTunnelApp/NetTunnelLib.cs +++ b/NetTunnelApp/NetTunnelLib.cs @@ -4,6 +4,8 @@ using System.Text; namespace NetTunnelApp; +public delegate void HeartCallBack(string msg, uint timeStamp); + public enum ProtoCryptoType { CRYPTO_NONE = 0, @@ -56,10 +58,14 @@ public struct UserClientConfig ///< 用户接入网关隧道 ID public int scgTunnelAppId; - ///< 用户客户端公钥 + ///< 用户客户端私钥 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string cliPrivateKey; + ///< 用户客户端公钥 + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string cliPublicKey; + ///< 用户客户端隧道IP地址 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 48)] public string cliAddress; @@ -188,11 +194,23 @@ public class NetTunnelLib public static extern int WireGuardInstallServerService(bool install); [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int UserLogin(String UserName, String token, out IntPtr userCfg); + public static extern int GetUserClientConfigure(String UserName, String token, out IntPtr userCfg); [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)] public static extern int GetUserConfigFiles(String UserName, out IntPtr path, ref int size); + [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void ConnectServerControlService(String svrUrl); + + [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern int SetClientConfige(String cliPublicKey, String cliNetwork, String cliTunnelAddr); + + [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern int RemoteWireGuardControl(bool startOrStop); + + [DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern int RemoteHeartControl(bool startOrStop, HeartCallBack cb); + //[DllImport("NetTunnelSDK.dll", CallingConvention = CallingConvention.Cdecl)] //public static extern int RunPipeCmd(String pszCmd, StringBuilder pszResultBuffer, int dwResultBufferSize); } \ No newline at end of file diff --git a/NetTunnelApp/ServerMenuItems.cs b/NetTunnelApp/ServerMenuItems.cs index 8ef8224..cc80cd3 100644 --- a/NetTunnelApp/ServerMenuItems.cs +++ b/NetTunnelApp/ServerMenuItems.cs @@ -10,6 +10,8 @@ public class ServerMenuItems private List _menuItems = new List(); + private static List _menuDataItems = new List(); + public ServerMenuItems(List vmList) { if (_menuItems.Count > 0) @@ -17,12 +19,16 @@ public class ServerMenuItems _menuItems.Clear(); } + _menuDataItems.Clear(); + _menuDataItems.AddRange(vmList); + foreach (var cfg in vmList) { ToolStripMenuItem item = new ToolStripMenuItem(); item.Text = cfg.vmName; - item.Name = cfg.vmId.ToString(); + item.Name = "svrMenu_" + cfg.vmId.ToString() + "_" + cfg.vmName; + item.Click += delegate(object sender, EventArgs e) { var control = (ToolStripMenuItem)sender; @@ -41,6 +47,19 @@ public class ServerMenuItems { return _menuItems; } + + public static VirtualMathineConfig? GetSelectItemData() + { + foreach (var k in _menuDataItems) + { + if (_selItems == "svrMenu_" + k.vmId.ToString() + "_" + k.vmName) + { + return k; + } + } + + return null; + } } public class UserClientCfg @@ -52,6 +71,9 @@ public class UserClientCfg public int scgTunnelAppId; ///< 用户客户端公钥 + public string cliPublicKey; + + ///< 用户客户端私钥 public string cliPrivateKey; ///< 用户客户端隧道IP地址 diff --git a/NetTunnelApp/WgCfgMenuItems.cs b/NetTunnelApp/WgCfgMenuItems.cs index 07f7f4f..01d952d 100644 --- a/NetTunnelApp/WgCfgMenuItems.cs +++ b/NetTunnelApp/WgCfgMenuItems.cs @@ -15,19 +15,23 @@ namespace NetTunnelApp private List _menuItems = new List(); + private static List _menuDataItems = new List(); + public WgCfgMenuItems(List wgCfgArrays) { if (_menuItems.Count > 0) { _menuItems.Clear(); } - + _menuDataItems.Clear(); + _menuDataItems.AddRange(wgCfgArrays); + foreach (var cfg in wgCfgArrays) { ToolStripMenuItem item = new ToolStripMenuItem(); - item.Text = Path.GetFileName(cfg.CfgPath); - item.Name = cfg.CfgPath; + item.Text = Path.GetFileName(cfg.CfgPath); + item.Name = "filePath_" + cfg.CfgPath; item.Click += delegate(object sender, EventArgs e) { var control = (ToolStripMenuItem)sender; @@ -38,7 +42,7 @@ namespace NetTunnelApp v.Checked = (_selItems == v.Name); } }; - + item.Checked = cfg.curUsed > 0; _menuItems.Add(item); } @@ -48,5 +52,18 @@ namespace NetTunnelApp { return _menuItems; } + + public static FilePath? GetSelectItemData() + { + foreach (var k in _menuDataItems) + { + if (_selItems == "filePath_" + k.CfgPath) + { + return k; + } + } + + return null; + } } -} +} \ No newline at end of file diff --git a/NetTunnelSDK/ControlService.cpp b/NetTunnelSDK/ControlService.cpp new file mode 100644 index 0000000..2dc354e --- /dev/null +++ b/NetTunnelSDK/ControlService.cpp @@ -0,0 +1,290 @@ +#include "pch.h" +#include "tunnel.h" +#include +#include + +#include "globalcfg.h" +#include "httplib.h" +#include "misc.h" +#include "protocol.h" +#include "usrerr.h" +#include "user.h" + +#include + +static HANDLE g_ControlSvrThread = nullptr; +static httplib::Server g_httpServer; +static USER_SERVER_CONFIG g_UserSvrCfg; + +/** + * @brief 连接到服务端控制服务 + * @param pUserSvrUrl 服务端控制服务 URL 地址 + */ +void ConnectServerControlService(const TCHAR *pUserSvrUrl) { + InitControlServer(pUserSvrUrl); +} + +static void HttpResponseError(httplib::Response &pRes, int errCode, const TCHAR *pErrMessage) { + ProtocolResponse rsp; + std::string json; + + if (errCode != ERR_SUCCESS) { + rsp.msgContent.errCode = errCode; + } + + if (pErrMessage && lstrlen(pErrMessage) > 0) { + rsp.msgContent.errMessage = pErrMessage; + } else { + if (errCode == ERR_SUCCESS) { + rsp.msgContent.errMessage = TEXT("OK"); + } + } + + if (aigc::JsonHelper::ObjectToJson(rsp, json)) { + pRes.set_content(json, TEXT("application/json")); + } else { + SPDLOG_ERROR(TEXT("ProtocolResponse to json error")); + } +} + +int CreateControlService(PUSER_SERVER_CONFIG pSvr) { + static WGSERVER_CONFIG g_curCliConfig = {}; + static std::mutex g_InterfaceMutex; + DWORD dwStatus = 0; + + // HTTP 服务已经运行 + if (g_httpServer.is_running()) { + return ERR_SUCCESS; + } + + // 线程已经运行 + if (g_ControlSvrThread && GetExitCodeThread(g_ControlSvrThread, &dwStatus) && dwStatus == STILL_ACTIVE) { + return -ERR_ITEM_EXISTS; + } + + if (pSvr == nullptr) { + SPDLOG_ERROR(TEXT("Input pSvr params error")); + return -ERR_INPUT_PARAMS; + } + + if (pSvr->svrListenPort <= 0 || pSvr->svrListenPort >= 65535) { + SPDLOG_ERROR(TEXT("Input svrListenPort params error {0}"), pSvr->svrListenPort); + return -ERR_INPUT_PARAMS; + } + + if (lstrlen(pSvr->svrPrivateKey) != lstrlen(TEXT("4PPcnW3wYewNpoXjNoY3hQuCnzTNq/E9hhfU9/U6QmY="))) { + SPDLOG_ERROR(TEXT("Input svrPrivateKey params length error {0}"), pSvr->svrPrivateKey); + return -ERR_INPUT_PARAMS; + } + + if (lstrlen(pSvr->svrAddress) == 0) { + SPDLOG_ERROR(TEXT("Input svrAddress params error {0}"), pSvr->svrAddress); + return -ERR_INPUT_PARAMS; + } + + // 保存参数 + memcpy(&g_UserSvrCfg, pSvr, sizeof(USER_SERVER_CONFIG)); + + g_httpServer.set_exception_handler([](const auto &req, auto &res, std::exception_ptr ep) { + const auto fmt = TEXT("

Error 500

%s

"); + char buf[BUFSIZ]; + try { + std::rethrow_exception(ep); + } + catch (std::exception &e) { + StringCbPrintf(buf, BUFSIZ, fmt, e.what()); + } + catch (...) { // See the following NOTE + StringCbPrintf(buf, BUFSIZ, fmt, TEXT("Unknown Exception")); + } + res.set_content(buf, TEXT("text/html")); + res.status = 500; + }); + + g_httpServer.set_error_handler([](const auto &req, auto &res) { + const auto fmt = TEXT("

Error Status: %d

"); + char buf[BUFSIZ]; + StringCbPrintf(buf, BUFSIZ, fmt, res.status); + res.set_content(buf, TEXT("text/html")); + }); + + g_httpServer.Post(SET_CLIENTHEART_PATH, [](const httplib::Request &req, httplib::Response &res) { + ProtocolResponse rsp; + std::string json; + + rsp.msgContent.errCode = ERR_SUCCESS; + rsp.msgContent.errMessage = TEXT("OK"); + + if (aigc::JsonHelper::ObjectToJson(rsp, json)) { + res.set_content(json, TEXT("application/json")); + } else { + SPDLOG_ERROR(TEXT("ProtocolResponse to json error")); + } + }); + + g_httpServer.Post(SET_CLIENTSTART_TUNNEL, [](const httplib::Request &req, httplib::Response &res) { + ProtocolRequest reqData; + + if (aigc::JsonHelper::JsonToObject(reqData, req.body)) { + int ret; + bool isSvrStart = false; + + g_InterfaceMutex.lock(); + // Because of COM return CO_E_FIRST + CoInitialize(nullptr); + + // 判断先前是否启动过服务 + if ((ret = IsWireGuardServerRunning(GetGlobalCfgInfo()->userCfg.userName, &isSvrStart)) != ERR_SUCCESS) { + // 返回获取系统服务错误,是否未安装 + HttpResponseError(res, ret, TEXT("Not found WireGuard application in system")); + SPDLOG_ERROR(TEXT("IsWireGuardServerInstalled error: {0}"), ret); + g_InterfaceMutex.unlock(); + return; + } + + // 当前服务状态和需要执行的操作不同 + if (isSvrStart != reqData.msgContent.isStart) { + if (reqData.msgContent.isStart) { + // 启动服务 + ret = WireGuardInstallDefaultServerService(true); + if (ret != ERR_SUCCESS) { + // 返回启动服务失败 + SPDLOG_ERROR(TEXT("WireGuardInstallDefaultServerService error: {0}"), ret); + HttpResponseError(res, ret, TEXT("Start WireGuard Tunnel Service error.")); + g_InterfaceMutex.unlock(); + return; + } + } else { + if ((ret = WireGuardUnInstallServerService(GetGlobalCfgInfo()->userCfg.userName)) != ERR_SUCCESS) { + // 返回停止服务失败 + HttpResponseError(res, ret, TEXT("Stop pre running WireGuard service error")); + SPDLOG_ERROR(TEXT("WireGuardUnInstallServerService error: {0}"), ret); + g_InterfaceMutex.unlock(); + return; + } + } + } + + HttpResponseError(res, ERR_SUCCESS, nullptr); + g_InterfaceMutex.unlock(); + } + }); + + g_httpServer.Post(SET_CLIENTCFG_PATH, [](const httplib::Request &req, httplib::Response &res) { + ProtocolRequest reqData; + + if (aigc::JsonHelper::JsonToObject(reqData, req.body)) { + int ret; + bool isSvrStart = false; + + g_InterfaceMutex.lock(); + // Because of COM return CO_E_FIRST + CoInitialize(nullptr); + + // 判断先前是否启动过服务 + if ((ret = IsWireGuardServerRunning(GetGlobalCfgInfo()->userCfg.userName, &isSvrStart)) != ERR_SUCCESS) { + // 返回获取系统服务错误,是否未安装 + HttpResponseError(res, ret, TEXT("Not found WireGuard application in system")); + SPDLOG_ERROR(TEXT("IsWireGuardServerInstalled error: {0}"), ret); + g_InterfaceMutex.unlock(); + return; + } + + if (isSvrStart) { + SPDLOG_DEBUG(TEXT("WireGuardUnInstallServerService: {0}"), GetGlobalCfgInfo()->userCfg.userName); + if ((ret = WireGuardUnInstallServerService(GetGlobalCfgInfo()->userCfg.userName)) != ERR_SUCCESS) { + // 返回停止服务失败 + HttpResponseError(res, ret, TEXT("Stop pre running WireGuard service error")); + SPDLOG_ERROR(TEXT("WireGuardUnInstallServerService error: {0}"), ret); + g_InterfaceMutex.unlock(); + return; + } + } + + memset(&g_curCliConfig, 0, sizeof(WGSERVER_CONFIG)); + g_curCliConfig.ListenPort = g_UserSvrCfg.svrListenPort - 1; + StringCbCopy(g_curCliConfig.Name, 64, GetGlobalCfgInfo()->userCfg.userName); + 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()); + StringCbPrintf(g_curCliConfig.AllowNet, + 256, + TEXT("%s,%s"), + reqData.msgContent.cliNetwork.c_str(), + reqData.msgContent.cliTunnelAddr.c_str()); + + // 创建 WireGuard 配置文件 + ret = WireGuardCreateServerConfig(&g_curCliConfig); + if (ret != ERR_SUCCESS) { + // 返回写入 WireGuard 配置文件错误 + HttpResponseError(res, ret, TEXT("Create WireGuard service configure file error")); + SPDLOG_ERROR(TEXT("WireGuardCreateServerConfig error: {0}"), ret); + g_InterfaceMutex.unlock(); + return; + } +#if 0 + // 启动服务 + ret = WireGuardInstallDefaultServerService(true); + if (ret != ERR_SUCCESS) { + // 返回启动服务失败 + return; + } + + // 设置路由表 +#endif + // 返回成功 + HttpResponseError(res, ERR_SUCCESS, nullptr); + g_InterfaceMutex.unlock(); + } + }); + + SPDLOG_DEBUG(TEXT("Start HTTP Service at {0}"), pSvr->svrListenPort); + if (!g_httpServer.bind_to_port(TEXT("localhost"), pSvr->svrListenPort)) { + SPDLOG_ERROR(TEXT("Start HTTP Service at {0} error"), pSvr->svrListenPort); + return -ERR_SOCKET_BIND_PORT; + } + + g_ControlSvrThread = CreateThread( + nullptr, // Thread attributes + 0, // Stack size (0 = use default) + [](LPVOID lpParameter) { + if (!g_httpServer.listen_after_bind()) { + SPDLOG_ERROR(TEXT("Start HTTP Service at {0} error")); + } + + SPDLOG_DEBUG(TEXT("Http service exit.....")); + + return static_cast(0); + }, // Thread start address + nullptr, // Parameter to pass to the thread + 0, // Creation flags + nullptr); // Thread id + + if (g_ControlSvrThread == nullptr) { + // Thread creation failed. + // More details can be retrieved by calling GetLastError() + return -ERR_CREATE_THREAD; + } + + g_httpServer.wait_until_ready(); + + return ERR_SUCCESS; +} + +int StopControlService() { + if (g_httpServer.is_running()) { + g_httpServer.stop(); + } + + if (g_ControlSvrThread) { + // Wait for thread to finish execution + if (WaitForSingleObject(g_ControlSvrThread, 10 * 1000) == WAIT_TIMEOUT) { + SPDLOG_ERROR(TEXT("Waitting HTTP Service clost timeout")); + return -ERROR_TIMEOUT; + } + CloseHandle(g_ControlSvrThread); + g_ControlSvrThread = nullptr; + } + + return ERR_SUCCESS; +} \ No newline at end of file diff --git a/NetTunnelSDK/NetTunnelSDK.aps b/NetTunnelSDK/NetTunnelSDK.aps deleted file mode 100644 index 5fa1e1c..0000000 Binary files a/NetTunnelSDK/NetTunnelSDK.aps and /dev/null differ diff --git a/NetTunnelSDK/NetTunnelSDK.rc b/NetTunnelSDK/NetTunnelSDK.rc deleted file mode 100644 index 1bdc8b7..0000000 Binary files a/NetTunnelSDK/NetTunnelSDK.rc and /dev/null differ diff --git a/NetTunnelSDK/NetTunnelSDK.vcxproj b/NetTunnelSDK/NetTunnelSDK.vcxproj index 4cdf999..87aa23e 100644 --- a/NetTunnelSDK/NetTunnelSDK.vcxproj +++ b/NetTunnelSDK/NetTunnelSDK.vcxproj @@ -162,9 +162,11 @@ + + @@ -184,13 +186,7 @@ - - - - - - diff --git a/NetTunnelSDK/NetTunnelSDK.vcxproj.filters b/NetTunnelSDK/NetTunnelSDK.vcxproj.filters index cf6e0bd..60d6eb2 100644 --- a/NetTunnelSDK/NetTunnelSDK.vcxproj.filters +++ b/NetTunnelSDK/NetTunnelSDK.vcxproj.filters @@ -113,18 +113,14 @@ 源文件\protocol + + 源文件\network + + + 源文件 + - - 资源文件 - - - - - - - 资源文件 - \ No newline at end of file diff --git a/NetTunnelSDK/ProtocolBase.h b/NetTunnelSDK/ProtocolBase.h index 6de7ab5..b9beaea 100644 --- a/NetTunnelSDK/ProtocolBase.h +++ b/NetTunnelSDK/ProtocolBase.h @@ -28,7 +28,15 @@ public: } }; -template class ProtocolRequest : ProtocolBase { +class ResponseStatus { +public: + int errCode; + std::string errMessage; + + AIGC_JSON_HELPER(errCode, errMessage) +}; + +template class ProtocolRequest : public ProtocolBase { public: T msgContent; @@ -36,7 +44,7 @@ public: AIGC_JSON_HELPER_BASE((ProtocolBase *)this) }; -template class ProtocolResponse : ProtocolBase { +template class ProtocolResponse : public ProtocolBase { public: int code; T msgContent; diff --git a/NetTunnelSDK/UserManager.cpp b/NetTunnelSDK/UserManager.cpp index 35e739c..9f17d56 100644 --- a/NetTunnelSDK/UserManager.cpp +++ b/NetTunnelSDK/UserManager.cpp @@ -10,19 +10,128 @@ #include #include -int UserLogin(const TCHAR *pUserName, const TCHAR *pToken, PUSER_CLIENT_CONFIG *pCliCfg) { - PUSER_CLIENT_CONFIG pCfg; - PVM_CFG pVm; - PUSER_CONFIG pUser = &GetGlobalCfgInfo()->userCfg; - TCHAR userPath[MAX_PATH]; +static HANDLE g_HeartTimerQueue = nullptr; +static LPTUNNEL_HEART_ROUTINE g_lpHeartCb = nullptr; + +/** + * @brief 启动/停止 隧道控制服务心跳 + * @param isStart 启动/停止服务 TRUE 启动服务, FALSE 停止服务 + * @param lpHeartCbAddress 心跳服务回调函数 @see PTUNNEL_HEART_ROUTINE + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_CREATE_TIMER 创建定时器失败 + * - -ERR_DELETE_TIMER 删除定时器失败 + * - ERR_SUCCESS 成功 + */ +int RemoteHeartControl(bool isStart, LPTUNNEL_HEART_ROUTINE lpHeartCbAddress) { + if (isStart && lpHeartCbAddress == nullptr) { + SPDLOG_ERROR(TEXT("Input lpHeartCbAddress params nullptr")); + return -ERR_INPUT_PARAMS; + } + + g_lpHeartCb = lpHeartCbAddress; + + if (isStart) { + if (!g_HeartTimerQueue) { + HANDLE hTimer = nullptr; + // Create the timer queue. + g_HeartTimerQueue = CreateTimerQueue(); + if (nullptr == g_HeartTimerQueue) { + SPDLOG_ERROR(TEXT("CreateTimerQueue failed ({0})"), GetLastError()); + return -ERR_CREATE_TIMER; + } + + // Set a timer to call the timer routine in 10 seconds. + if (!CreateTimerQueueTimer( + &hTimer, + g_HeartTimerQueue, + [](PVOID lpParam, BOOLEAN TimerOrWaitFired) { + int ret; + ProtocolRequest req; + ProtocolResponse rsp; + + ret = ProtolPostMessage(SET_CLIENTHEART_PATH, &req, &rsp, false); + if (g_lpHeartCb && ret) { + g_lpHeartCb(rsp.msgContent.message.c_str(), rsp.timeStamp); + } + }, + nullptr, + 0, + HEART_PERIOD_MS, + WT_EXECUTEDEFAULT)) { + SPDLOG_ERROR(TEXT("CreateTimerQueueTimer failed ({0})"), GetLastError()); + return -ERR_CREATE_TIMER; + } + } + } else { + if (g_HeartTimerQueue) { + if (!DeleteTimerQueue(g_HeartTimerQueue)) { + SPDLOG_ERROR(TEXT("DeleteTimerQueue failed ({0})"), GetLastError()); + g_HeartTimerQueue = nullptr; + return -ERR_DELETE_TIMER; + } + + g_HeartTimerQueue = nullptr; + } + } + + return ERR_SUCCESS; +} + +int RemoteWireGuardControl(bool isStart) { + int ret; + ProtocolRequest req; + ProtocolResponse rsp; + + req.msgContent.isStart = isStart; + + ret = ProtolPostMessage(SET_CLIENTSTART_TUNNEL, &req, &rsp, false); + + if (ret != ERR_SUCCESS) { + return ret; + } + + if (rsp.msgContent.errCode != ERR_SUCCESS) { + SPDLOG_ERROR(TEXT("Service Response error({0}): {1}"), rsp.msgContent.errCode, rsp.msgContent.errMessage); + return rsp.msgContent.errCode; + } + + return ERR_SUCCESS; +} + +int SetClientConfige(const TCHAR *pCliPublicKey, const TCHAR *pCliNetwork, const TCHAR *pCliTunnelAddr) { + int ret; + ProtocolRequest req; + ProtocolResponse rsp; + + req.msgContent.cliPublicKey = pCliPublicKey; + req.msgContent.cliNetwork = pCliNetwork; + req.msgContent.cliTunnelAddr = pCliTunnelAddr; + + ret = ProtolPostMessage(SET_CLIENTCFG_PATH, &req, &rsp, false); + + if (ret != ERR_SUCCESS) { + return ret; + } + + if (rsp.msgContent.errCode != ERR_SUCCESS) { + SPDLOG_ERROR(TEXT("Service Response error({0}): {1}"), rsp.msgContent.errCode, rsp.msgContent.errMessage); + return rsp.msgContent.errCode; + } + + return ERR_SUCCESS; +} + +int GetUserServerConfigure(const TCHAR *pUserName, const TCHAR *pToken, PUSER_SERVER_CONFIG *pSvrCfg) { int ret; - unsigned int memSize; + PUSER_CONFIG pUser = &GetGlobalCfgInfo()->userCfg; + PUSER_SERVER_CONFIG pUserCfg = &pUser->svrConfig; - ProtocolRequest req; - ProtocolResponse rsp; + ProtocolRequest req; + ProtocolResponse rsp; - if (pUserName == nullptr || lstrlen(pUserName) == 0) { - SPDLOG_ERROR(TEXT("Input pUserName params error: {0}"), pUserName); + if (pSvrCfg == nullptr) { + SPDLOG_ERROR(TEXT("Input pSvrCfg params error")); return -ERR_INPUT_PARAMS; } @@ -31,6 +140,51 @@ int UserLogin(const TCHAR *pUserName, const TCHAR *pToken, PUSER_CLIENT_CONFIG * return -ERR_INPUT_PARAMS; } + if (pUserName && lstrlen(pUserName) > 0) { + memset(pUser->userName, 0, MAX_PATH); + StringCbCopy(pUser->userName, MAX_PATH, pUserName); + } + + StringCbCopy(pUser->userToken, MAX_PATH, pToken); + + req.msgContent.token = pToken; + req.msgContent.user = pUserName; + + ret = ProtolPostMessage(GET_SERVERCFG_PATH, &req, &rsp); + + if (ret != ERR_SUCCESS) { + return ret; + } + + pUserCfg->svrListenPort = rsp.msgContent.svrListenPort; + StringCbCopy(pUserCfg->svrPrivateKey, 64, rsp.msgContent.svrPrivateKey.c_str()); + StringCbCopy(pUserCfg->svrAddress, MAX_IP_LEN, rsp.msgContent.svrAddress.c_str()); + + *pSvrCfg = pUserCfg; + return ERR_SUCCESS; +} + +int GetUserClientConfigure(const TCHAR *pUserName, const TCHAR *pToken, PUSER_CLIENT_CONFIG *pCliCfg) { + PVM_CFG pVm; + PUSER_CONFIG pUser = &GetGlobalCfgInfo()->userCfg; + PUSER_CLIENT_CONFIG pUserCfg = &pUser->cliConfig; + TCHAR userPath[MAX_PATH]; + int ret; + unsigned int memSize; + + ProtocolRequest req; + ProtocolResponse rsp; + + if (pToken == nullptr || lstrlen(pToken) == 0) { + SPDLOG_ERROR(TEXT("Input pToken params error: {0}"), pToken); + return -ERR_INPUT_PARAMS; + } + + if (pCliCfg == nullptr) { + SPDLOG_ERROR(TEXT("Input pCliCfg params error")); + return -ERR_INPUT_PARAMS; + } + StringCbPrintf(userPath, MAX_PATH, "%s\\%s", GetGlobalCfgInfo()->configDirectory, pUserName); // 如果配置目录不存在则自动创建 if (!PathFileExists(userPath)) { @@ -41,45 +195,37 @@ int UserLogin(const TCHAR *pUserName, const TCHAR *pToken, PUSER_CLIENT_CONFIG * } memset(pUser->userName, 0, MAX_PATH); - StringCbCopy(pUser->userName, MAX_PATH, pUserName); + if (pUserName && lstrlen(pUserName) > 0) { + StringCbCopy(pUser->userName, MAX_PATH, pUserName); + } StringCbCopy(pUser->userToken, MAX_PATH, pToken); req.msgContent.token = pToken; req.msgContent.user = pUserName; - ret = ProtolPostMessage(&req, &rsp); + ret = ProtolPostMessage(GET_CLIENTCFG_PATH, &req, &rsp); if (ret != ERR_SUCCESS) { return ret; } - pCfg = static_cast(CoTaskMemAlloc(sizeof(USER_CLIENT_CONFIG))); - - if (pCfg == nullptr) { - SPDLOG_ERROR(TEXT("Error allocating memory {0} bytes"), sizeof(USER_CLIENT_CONFIG)); - return -ERR_MALLOC_MEMORY; - } - - memset(pCfg, 0, sizeof(USER_CLIENT_CONFIG)); - - memSize = sizeof(VM_CFG) * static_cast(rsp.msgContent.vmConfig.size()); - pCfg->pVMConfig = static_cast(CoTaskMemAlloc(memSize)); - - if (pCfg->pVMConfig == nullptr) { + memSize = sizeof(VM_CFG) * static_cast(rsp.msgContent.vmConfig.size()); + pUserCfg->pVMConfig = static_cast(CoTaskMemAlloc(memSize)); + if (pUserCfg->pVMConfig == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory {0} bytes"), memSize); - CoTaskMemFree(pCfg); return -ERR_MALLOC_MEMORY; } - memset(pCfg->pVMConfig, 0, memSize); + memset(pUserCfg->pVMConfig, 0, memSize); - pCfg->scgCtrlAppId = rsp.msgContent.scgCtrlAppId; - pCfg->scgTunnelAppId = rsp.msgContent.scgTunnelAppId; - StringCbCopy(pCfg->cliPrivateKey, 64, rsp.msgContent.cliPrivateKey.c_str()); - StringCbCopy(pCfg->cliAddress, MAX_IP_LEN, rsp.msgContent.cliAddress.c_str()); - pCfg->tolVM = static_cast(rsp.msgContent.vmConfig.size()); + pUserCfg->scgCtrlAppId = rsp.msgContent.scgCtrlAppId; + pUserCfg->scgTunnelAppId = rsp.msgContent.scgTunnelAppId; + StringCbCopy(pUserCfg->cliPrivateKey, 64, rsp.msgContent.cliPrivateKey.c_str()); + StringCbCopy(pUserCfg->cliPublicKey, 64, rsp.msgContent.cliPublicKey.c_str()); + StringCbCopy(pUserCfg->cliAddress, MAX_IP_LEN, rsp.msgContent.cliAddress.c_str()); + pUserCfg->tolVM = static_cast(rsp.msgContent.vmConfig.size()); - pVm = pCfg->pVMConfig; + pVm = pUserCfg->pVMConfig; for (auto vm : rsp.msgContent.vmConfig) { pVm->vmId = vm.vmId; StringCbCopy(pVm->vmName, MAX_PATH, vm.vmName.c_str()); @@ -89,7 +235,7 @@ int UserLogin(const TCHAR *pUserName, const TCHAR *pToken, PUSER_CLIENT_CONFIG * pVm++; } - *pCliCfg = pCfg; + *pCliCfg = pUserCfg; return ERR_SUCCESS; } diff --git a/NetTunnelSDK/globalcfg.h b/NetTunnelSDK/globalcfg.h index ab48194..6cadf0d 100644 --- a/NetTunnelSDK/globalcfg.h +++ b/NetTunnelSDK/globalcfg.h @@ -1,5 +1,6 @@ #pragma once #include +#include "tunnel.h" /** * @brief WireGuard 配置项 @@ -40,12 +41,19 @@ typedef struct { typedef struct { int scgCtrlAppId; ///< 用户接入网关控制 ID int scgTunnelAppId; ///< 用户接入网关隧道 ID - TCHAR cliPrivateKey[64]; ///< 用户客户端公钥 + TCHAR cliPrivateKey[64]; ///< 用户客户端私钥 + TCHAR cliPublicKey[64]; ///< 用户客户端公钥 TCHAR cliAddress[MAX_IP_LEN]; ///< 用户客户端隧道IP地址 PVM_CFG pVMConfig; ///< 用户虚拟机配置列表 int tolVM; ///< 用户虚拟机配置最大数 } USER_CLIENT_CONFIG, *PUSER_CLIENT_CONFIG; +typedef struct { + int svrListenPort; ///< 用户服务端监听端口 + TCHAR svrPrivateKey[64]; ///< 用户服务端公钥 + TCHAR svrAddress[MAX_IP_LEN]; ///< 用户服务端隧道IP地址 +} USER_SERVER_CONFIG, *PUSER_SERVER_CONFIG; + /** * @brief 用户信息配置 */ @@ -53,6 +61,7 @@ typedef struct { TCHAR userName[MAX_PATH]; ///< 用户名 TCHAR userToken[MAX_PATH]; ///< 用户访问令牌 USER_CLIENT_CONFIG cliConfig; ///< 用户客户端配置 + USER_SERVER_CONFIG svrConfig; ///< 用户服务端配置 } USER_CONFIG, *PUSER_CONFIG; /** diff --git a/NetTunnelSDK/hashdigest.cpp b/NetTunnelSDK/hashdigest.cpp index 2ecd91e..ad32e34 100644 --- a/NetTunnelSDK/hashdigest.cpp +++ b/NetTunnelSDK/hashdigest.cpp @@ -35,12 +35,12 @@ int CalcFileHash(const HASH_TYPE type, const TCHAR *pPath, TCHAR outHash[]) { PBYTE pbHash; if (pPath == nullptr) { - SPDLOG_ERROR("Input pPath params error: {0}", pPath); + SPDLOG_ERROR(TEXT("Input pPath params error: {0}"), pPath); return -ERR_INPUT_PARAMS; } if (!PathFileExists(pPath)) { - SPDLOG_ERROR("File \'{0}\' not found.", pPath); + SPDLOG_ERROR(TEXT("File \'{0}\' not found."), pPath); return -ERR_ITEM_UNEXISTS; } @@ -53,7 +53,7 @@ int CalcFileHash(const HASH_TYPE type, const TCHAR *pPath, TCHAR outHash[]) { nullptr); if (INVALID_HANDLE_VALUE == hFile) { - SPDLOG_ERROR("Error opening file %s\nError: {0}", pPath, GetLastError()); + SPDLOG_ERROR(TEXT("Error opening file %s\nError: {0}"), pPath, GetLastError()); return -ERR_OPEN_FILE; } diff --git a/NetTunnelSDK/ipcalc.cpp b/NetTunnelSDK/ipcalc.cpp new file mode 100644 index 0000000..e154034 --- /dev/null +++ b/NetTunnelSDK/ipcalc.cpp @@ -0,0 +1,518 @@ +#include "pch.h" +#include +#include +#include +#include +#include + +#include "usrerr.h" +#include "misc.h" + +static const TCHAR *p2_table(unsigned pow) { + static const TCHAR *pow2[] = { + TEXT("1"), + TEXT("2"), + TEXT("4"), + TEXT("8"), + TEXT("16"), + TEXT("32"), + TEXT("64"), + TEXT("128"), + TEXT("256"), + TEXT("512"), + TEXT("1024"), + TEXT("2048"), + TEXT("4096"), + TEXT("8192"), + TEXT("16384"), + TEXT("32768"), + TEXT("65536"), + TEXT("131072"), + TEXT("262144"), + TEXT("524288"), + TEXT("1048576"), + TEXT("2097152"), + TEXT("4194304"), + TEXT("8388608"), + TEXT("16777216"), + TEXT("33554432"), + TEXT("67108864"), + TEXT("134217728"), + TEXT("268435456"), + TEXT("536870912"), + TEXT("1073741824"), + TEXT("2147483648"), + TEXT("4294967296"), + TEXT("8589934592"), + TEXT("17179869184"), + TEXT("34359738368"), + TEXT("68719476736"), + TEXT("137438953472"), + TEXT("274877906944"), + TEXT("549755813888"), + TEXT("1099511627776"), + TEXT("2199023255552"), + TEXT("4398046511104"), + TEXT("8796093022208"), + TEXT("17592186044416"), + TEXT("35184372088832"), + TEXT("70368744177664"), + TEXT("140737488355328"), + TEXT("281474976710656"), + TEXT("562949953421312"), + TEXT("1125899906842624"), + TEXT("2251799813685248"), + TEXT("4503599627370496"), + TEXT("9007199254740992"), + TEXT("18014398509481984"), + TEXT("36028797018963968"), + TEXT("72057594037927936"), + TEXT("144115188075855872"), + TEXT("288230376151711744"), + TEXT("576460752303423488"), + TEXT("1152921504606846976"), + TEXT("2305843009213693952"), + TEXT("4611686018427387904"), + TEXT("9223372036854775808"), + TEXT("18446744073709551616"), + TEXT("36893488147419103232"), + TEXT("73786976294838206464"), + TEXT("147573952589676412928"), + TEXT("295147905179352825856"), + TEXT("590295810358705651712"), + TEXT("1180591620717411303424"), + TEXT("2361183241434822606848"), + TEXT("4722366482869645213696"), + TEXT("9444732965739290427392"), + TEXT("18889465931478580854784"), + TEXT("37778931862957161709568"), + TEXT("75557863725914323419136"), + TEXT("151115727451828646838272"), + TEXT("302231454903657293676544"), + TEXT("604462909807314587353088"), + TEXT("1208925819614629174706176"), + TEXT("2417851639229258349412352"), + TEXT("4835703278458516698824704"), + TEXT("9671406556917033397649408"), + TEXT("19342813113834066795298816"), + TEXT("38685626227668133590597632"), + TEXT("77371252455336267181195264"), + TEXT("154742504910672534362390528"), + TEXT("309485009821345068724781056"), + TEXT("618970019642690137449562112"), + TEXT("1237940039285380274899124224"), + TEXT("2475880078570760549798248448"), + TEXT("4951760157141521099596496896"), + TEXT("9903520314283042199192993792"), + TEXT("19807040628566084398385987584"), + TEXT("39614081257132168796771975168"), + TEXT("79228162514264337593543950336"), + TEXT("158456325028528675187087900672"), + TEXT("316912650057057350374175801344"), + TEXT("633825300114114700748351602688"), + TEXT("1267650600228229401496703205376"), + TEXT("2535301200456458802993406410752"), + TEXT("5070602400912917605986812821504"), + TEXT("10141204801825835211973625643008"), + TEXT("20282409603651670423947251286016"), + TEXT("40564819207303340847894502572032"), + TEXT("81129638414606681695789005144064"), + TEXT("162259276829213363391578010288128"), + TEXT("324518553658426726783156020576256"), + TEXT("649037107316853453566312041152512"), + TEXT("1298074214633706907132624082305024"), + TEXT("2596148429267413814265248164610048"), + TEXT("5192296858534827628530496329220096"), + TEXT("10384593717069655257060992658440192"), + TEXT("20769187434139310514121985316880384"), + TEXT("41538374868278621028243970633760768"), + TEXT("83076749736557242056487941267521536"), + TEXT("166153499473114484112975882535043072"), + TEXT("332306998946228968225951765070086144"), + TEXT("664613997892457936451903530140172288"), + TEXT("1329227995784915872903807060280344576"), + TEXT("2658455991569831745807614120560689152"), + TEXT("5316911983139663491615228241121378304"), + TEXT("10633823966279326983230456482242756608"), + TEXT("21267647932558653966460912964485513216"), + TEXT("42535295865117307932921825928971026432"), + TEXT("85070591730234615865843651857942052864"), + TEXT("170141183460469231731687303715884105728"), + }; + if (pow <= 127) { + return pow2[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); + if (len == -1) { + return -1; + } + const size_t size = static_cast(len) + 1; + const auto str = static_cast(malloc(size)); + if (!str) { + return -1; + } + // _vsprintf_s is the "secure" version of vsprintf + const int r = vsprintf_s(str, len + 1, fmt, ap); + if (r == -1) { + free(str); + return -1; + } + *strp = str; + return r; +} + +static int asprintf(TCHAR **strp, const TCHAR *fmt, ...) { + va_list ap; + va_start(ap, fmt); + const int r = vasprintf(strp, fmt, ap); + va_end(ap); + return r; +} + +static int bit_count(unsigned int i) { + int c = 0; + unsigned int seen_one = 0; + + while (i > 0) { + if (i & 1) { + seen_one = 1; + c++; + } else { + if (seen_one) { + return -1; + } + } + i >>= 1; + } + + return c; +} + +/** + * @brief creates a netmask from a specified number of bits + * This function converts a prefix length to a netmask. As CIDR (classless + * internet domain internet domain routing) has taken off, more an more IP + * addresses are being specified in the format address/prefix + * (i.e. 192.168.2.3/24, with a corresponding netmask 255.255.255.0). If you + * need to see what netmask corresponds to the prefix part of the address, this + * is the function. See also @ref mask2prefix. + * @param prefix prefix is the number of bits to create a mask for. + * @return a network mask, in network byte order. + */ +unsigned int prefix2mask(int prefix) { + if (prefix) { + return htonl(~((1 << (32 - prefix)) - 1)); + } else { + return htonl(0); + } +} + +/** +* @brief calculates the number of bits masked off by a netmask. +* This function calculates the significant bits in an IP address as specified by +* a netmask. See also @ref prefix2mask. +* @param mask is the netmask, specified as an struct in_addr in network byte order. +* @return the number of significant bits. +*/ +int mask2prefix(IN_ADDR mask) { + return bit_count(ntohl(mask.s_addr)); +} + +static int ipv4_mask_to_int(const char *prefix) { + int ret; + IN_ADDR in; + + ret = inet_pton(AF_INET, prefix, &in); + if (ret == 0) { + return -1; + } + + return mask2prefix(in); +} + +/** +* @brief calculate broadcast address given an IP address and a prefix length. +* @param addr an IP address in network byte order. +* @param prefix a prefix length. +* @return the calculated broadcast address for the network, in network byte order. +*/ +static IN_ADDR calc_broadcast(IN_ADDR addr, int prefix) { + IN_ADDR mask; + IN_ADDR broadcast; + + mask.s_addr = prefix2mask(prefix); + + memset(&broadcast, 0, sizeof(broadcast)); + broadcast.s_addr = (addr.s_addr & mask.s_addr) | ~mask.s_addr; + return broadcast; +} + +/** +* @brief calculates the network address for a specified address and prefix. +* @param addr an IP address, in network byte order +* @param prefix the network prefix +* @return the base address of the network that addr is associated with, in +* network byte order. +*/ +static IN_ADDR calc_network(IN_ADDR addr, int prefix) { + IN_ADDR mask; + IN_ADDR network; + + mask.s_addr = prefix2mask(prefix); + + memset(&network, 0, sizeof(network)); + network.s_addr = addr.s_addr & mask.s_addr; + return network; +} + +static TCHAR *ipv4_prefix_to_hosts(TCHAR *hosts, unsigned hosts_size, unsigned prefix) { + if (prefix >= 31) { + StringCbPrintf(hosts, hosts_size, TEXT("%s"), p2_table(32 - prefix)); + } else { + unsigned int tmp; + tmp = (1 << (32 - prefix)) - 2; + StringCbPrintf(hosts, hosts_size, TEXT("%u"), tmp); + } + return hosts; +} + +static int str_to_prefix(int *ipv6, const char *prefixStr, unsigned fix) { + int prefix; + + if (!(*ipv6) && strchr(prefixStr, '.')) { /* prefix is 255.x.x.x */ + prefix = ipv4_mask_to_int(prefixStr); + } else { + prefix = strtol(prefixStr, nullptr, 10); + } + + if (fix && (prefix > 32 && !(*ipv6))) { + *ipv6 = 1; + } + + if (prefix < 0 || (((*ipv6) && prefix > 128) || (!(*ipv6) && prefix > 32))) { + return -1; + } + return prefix; +} + +static int GetIpV4Info(const TCHAR *pIpStr, int prefix, PIP_INFO pInfo, unsigned int flags) { + IN_ADDR ip, netmask, network, broadcast, minhost, maxhost; + TCHAR namebuf[INET_ADDRSTRLEN + 1]; + TCHAR *ipStr = _strdup(pIpStr); + + memset(pInfo, 0, sizeof(*pInfo)); + + if (inet_pton(AF_INET, ipStr, &ip) <= 0) { + SPDLOG_ERROR(TEXT("ipcalc: bad IPv4 address: {0}"), ipStr); + free(ipStr); + return -ERR_UN_SUPPORT; + } + + /* Handle CIDR entries such as 172/8 */ + if (prefix >= 0) { + auto tmp = const_cast(ipStr); + int i; + + for (i = 3; i > 0; i--) { + tmp = strchr(tmp, '.'); + if (!tmp) { + break; + } else { + tmp++; + } + } + + tmp = nullptr; + for (; i > 0; i--) { + if (asprintf(&tmp, "%s.0", ipStr) == -1) { + SPDLOG_ERROR(TEXT("Memory allocation failure")); + free(ipStr); + return -ERR_MALLOC_MEMORY; + } + ipStr = tmp; + } + } else { // assume good old days classful Internet + prefix = 32; + } + + if (prefix > 32) { + SPDLOG_ERROR(TEXT("ipcalc: bad IPv4 prefix: {0}"), prefix); + free(ipStr); + return -ERR_UN_SUPPORT; + } + + if (inet_ntop(AF_INET, &ip, namebuf, sizeof(namebuf)) == 0) { + SPDLOG_ERROR(TEXT("ipcalc: error calculating the IPv4 network")); + free(ipStr); + return -ERR_UN_SUPPORT; + } + pInfo->ip = safe_strdup(namebuf); + + netmask.s_addr = prefix2mask(prefix); + memset(namebuf, '\0', sizeof(namebuf)); + + if (inet_ntop(AF_INET, &netmask, namebuf, INET_ADDRSTRLEN) == nullptr) { + SPDLOG_ERROR(TEXT("inet_ntop error")); + free(ipStr); + return -ERR_UN_SUPPORT; + } + pInfo->netmask = safe_strdup(namebuf); + pInfo->prefix = prefix; + + broadcast = calc_broadcast(ip, prefix); + + memset(namebuf, '\0', sizeof(namebuf)); + if (inet_ntop(AF_INET, &broadcast, namebuf, INET_ADDRSTRLEN) == nullptr) { + SPDLOG_ERROR(TEXT("inet_ntop error")); + free(ipStr); + return -ERR_UN_SUPPORT; + } + pInfo->broadcast = safe_strdup(namebuf); + + network = calc_network(ip, prefix); + + memset(namebuf, '\0', sizeof(namebuf)); + if (inet_ntop(AF_INET, &network, namebuf, INET_ADDRSTRLEN) == nullptr) { + SPDLOG_ERROR(TEXT("inet_ntop error")); + free(ipStr); + return -ERR_UN_SUPPORT; + } + + pInfo->network = safe_strdup(namebuf); + + if (prefix < 32) { + memcpy(&minhost, &network, sizeof(minhost)); + + if (prefix <= 30) { + minhost.s_addr = htonl(ntohl(minhost.s_addr) | 1); + } + if (inet_ntop(AF_INET, &minhost, namebuf, INET_ADDRSTRLEN) == nullptr) { + SPDLOG_ERROR(TEXT("inet_ntop error")); + free(ipStr); + return -ERR_UN_SUPPORT; + } + pInfo->hostmin = safe_strdup(namebuf); + + memcpy(&maxhost, &network, sizeof(minhost)); + maxhost.s_addr |= ~netmask.s_addr; + if (prefix <= 30) { + maxhost.s_addr = htonl(ntohl(maxhost.s_addr) - 1); + } + if (inet_ntop(AF_INET, &maxhost, namebuf, sizeof(namebuf)) == 0) { + SPDLOG_ERROR(TEXT("ipcalc: error calculating the IPv4 network")); + free(ipStr); + return -ERR_UN_SUPPORT; + } + + pInfo->hostmax = safe_strdup(namebuf); + } else { + pInfo->hostmin = pInfo->network; + pInfo->hostmax = pInfo->network; + } + + ipv4_prefix_to_hosts(pInfo->hosts, sizeof(pInfo->hosts), prefix); + + free(ipStr); + return ERR_SUCCESS; +} + +/** + * @brief 计算 IPv4 网络信息 + * @param[in] pIpStr IPv4 网络信息 '/' 分割,支持CIDR以及子网掩码 example: 192.168.1.32/24, 192.168.1.32/255.255.255.0 + * @param[out] pInfo 计算结果 + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_UN_SUPPORT 不支持的格式转换 + * - -ERR_MALLOC_MEMORY 分配内存失败 + * - ERR_SUCCESS 成功 + */ +int GetIpV4InfoFromCIDR(const TCHAR *pIpStr, PIP_INFO pInfo) { + int ret, prefix, familyIPv6 = 0; + TCHAR *prefixStr; + TCHAR *ipStr = _strdup(pIpStr); + + if (pIpStr == nullptr || lstrlen(pIpStr) < 8) { + SPDLOG_ERROR(TEXT("Input pIpStr format error: {}."), pIpStr); + return -ERR_INPUT_PARAMS; + } + + if (pInfo == nullptr) { + SPDLOG_ERROR(TEXT("Input pInfo is NULL.")); + return -ERR_INPUT_PARAMS; + } + + if (strchr(ipStr, '/') != nullptr) { + prefixStr = static_cast(strchr(ipStr, '/')); + *prefixStr = '\0'; /* fix up ipStr */ + prefixStr++; + } else { + SPDLOG_ERROR(TEXT("Input pIpStr isn't CIDR format: {}."), pIpStr); + free(ipStr); + return -ERR_INPUT_PARAMS; + } + + if (strchr(prefixStr, '.') != nullptr) { + prefix = ipv4_mask_to_int(prefixStr); + } else { + prefix = str_to_prefix(&familyIPv6, prefixStr, 0); + } + + ret = GetIpV4Info(ipStr, prefix, pInfo, 0); + + free(ipStr); + return ret; +} + +/** + * @brief 计算 IPv4 网络信息 + * @param[in] pIpStr IPv4 地址 + * @param[in] pNetmask IPv4子网掩码 + * @param[out] pInfo 计算结果 + * @return 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_UN_SUPPORT 不支持的格式转换 + * - -ERR_MALLOC_MEMORY 分配内存失败 + * - ERR_SUCCESS 成功 + */ +int GetIpV4InfoFromNetmask(const TCHAR *pIpStr, const TCHAR *pNetmask, PIP_INFO pInfo) { + int prefix; + + if (pIpStr == nullptr || lstrlen(pIpStr) < 8) { + SPDLOG_ERROR(TEXT("Input pIpStr format error: {}."), pIpStr); + return -ERR_INPUT_PARAMS; + } + + if (pNetmask == nullptr || lstrlen(pNetmask) < 8) { + SPDLOG_ERROR(TEXT("Input pNetmask format error: {}."), pNetmask); + return -ERR_INPUT_PARAMS; + } + + if (pInfo == nullptr) { + SPDLOG_ERROR(TEXT("Input pInfo is NULL.")); + return -ERR_INPUT_PARAMS; + } + + prefix = ipv4_mask_to_int(pNetmask); + return GetIpV4Info(pIpStr, prefix, pInfo, 0); +} \ No newline at end of file diff --git a/NetTunnelSDK/misc.cpp b/NetTunnelSDK/misc.cpp index 8ce8556..616ddbc 100644 --- a/NetTunnelSDK/misc.cpp +++ b/NetTunnelSDK/misc.cpp @@ -120,10 +120,10 @@ void ShowWindowsErrorMessage(const TCHAR *pMsgHead) { (LPSTR)&buf, 0, nullptr)) { - SPDLOG_ERROR("{0} Error({1}): {2}", pMsgHead, GetLastError(), buf); + SPDLOG_ERROR(TEXT("{0} Error({1}): {2}"), pMsgHead, GetLastError(), buf); LocalFree(buf); } else { - SPDLOG_ERROR("{0} Unknown Error{1}.", pMsgHead, GetLastError()); + SPDLOG_ERROR(TEXT("{0} Unknown Error{1}."), pMsgHead, GetLastError()); } } @@ -187,7 +187,7 @@ int FindFile(const TCHAR *pPath, PFILE_LIST pFileList, const bool exitWhenMatchO pFileList->pFilePath = static_cast(HeapAlloc(GetProcessHeap(), 0, pathList.size() * sizeof(FILE_PATH))); if (pFileList->pFilePath == nullptr) { - SPDLOG_ERROR("Malloc {0} bytes memory error", pathList.size() * sizeof(FILE_PATH)); + SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), pathList.size() * sizeof(FILE_PATH)); return -ERR_MALLOC_MEMORY; } @@ -220,12 +220,12 @@ int GetWindowsServiceStatus(const TCHAR *pSvrName, PDWORD pStatus) { DWORD dwBytesNeeded = 0; if (pSvrName == nullptr || lstrlen(pSvrName) == 0) { - SPDLOG_ERROR("Input pSvrName params error"); + SPDLOG_ERROR(TEXT("Input pSvrName params error")); return -ERR_INPUT_PARAMS; } if (pStatus == nullptr) { - SPDLOG_ERROR("Input pStatus params error"); + SPDLOG_ERROR(TEXT("Input pStatus params error")); return -ERR_INPUT_PARAMS; } diff --git a/NetTunnelSDK/misc.h b/NetTunnelSDK/misc.h index 7ef2b05..9712767 100644 --- a/NetTunnelSDK/misc.h +++ b/NetTunnelSDK/misc.h @@ -16,6 +16,20 @@ typedef struct { unsigned int nItems; } FILE_LIST, *PFILE_LIST; +/** + * @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 +} IP_INFO, *PIP_INFO; + #ifdef __cplusplus // If used by C++ code, extern "C" { // we need to export the C interface @@ -54,6 +68,29 @@ int GetWindowsServiceStatus(const TCHAR *pSvrName, PDWORD pStatus); */ int WideCharToTChar(const WCHAR *pWStr, TCHAR *pOutStr, int maxOutLen); int FindFile(const TCHAR *pPath, PFILE_LIST pFileList, const bool exitWhenMatchOne); +/** + * @brief 计算 IPv4 网络信息 + * @param[in] pIpStr IPv4 地址 + * @param[in] pNetmask IPv4子网掩码 + * @param[out] pInfo 计算结果 + * @return 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_UN_SUPPORT 不支持的格式转换 + * - -ERR_MALLOC_MEMORY 分配内存失败 + * - ERR_SUCCESS 成功 + */ +int GetIpV4InfoFromNetmask(const TCHAR *pIpStr, const TCHAR *pNetmask, PIP_INFO pInfo); +/** + * @brief 计算 IPv4 网络信息 + * @param[in] pIpStr IPv4 网络信息 '/' 分割,支持CIDR以及子网掩码 example: 192.168.1.32/24, 192.168.1.32/255.255.255.0 + * @param[out] pInfo 计算结果 + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_UN_SUPPORT 不支持的格式转换 + * - -ERR_MALLOC_MEMORY 分配内存失败 + * - ERR_SUCCESS 成功 + */ +int GetIpV4InfoFromCIDR(const TCHAR *pIpStr, PIP_INFO pInfo); #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/NetTunnelSDK/network.cpp b/NetTunnelSDK/network.cpp index 58ec2ea..ce4f15a 100644 --- a/NetTunnelSDK/network.cpp +++ b/NetTunnelSDK/network.cpp @@ -55,12 +55,12 @@ int GetInterfaceIfIndexByGUID(const TCHAR *pGUID, int *pIfIndex) { DWORD dwRetVal; if (pGUID == nullptr || lstrlen(pGUID) == 0) { - SPDLOG_ERROR("Input pGUID error: {0}", pGUID); + SPDLOG_ERROR(TEXT("Input pGUID error: {0}"), pGUID); return -ERR_INPUT_PARAMS; } if (pIfIndex == nullptr) { - SPDLOG_ERROR("Input pIfIndex params error"); + SPDLOG_ERROR(TEXT("Input pIfIndex params error")); return -ERR_INPUT_PARAMS; } @@ -68,7 +68,7 @@ int GetInterfaceIfIndexByGUID(const TCHAR *pGUID, int *pIfIndex) { pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO))); if (pAdapterInfo == nullptr) { - SPDLOG_ERROR("Error allocating memory needed to call GetAdaptersinfo"); + SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo")); return -ERR_MALLOC_MEMORY; } @@ -76,7 +76,7 @@ int GetInterfaceIfIndexByGUID(const TCHAR *pGUID, int *pIfIndex) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen)); if (pAdapterInfo == nullptr) { - SPDLOG_ERROR("Error allocating memory needed to call GetAdaptersinfo\n"); + SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n")); return -ERR_MALLOC_MEMORY; } } @@ -95,7 +95,7 @@ int GetInterfaceIfIndexByGUID(const TCHAR *pGUID, int *pIfIndex) { pAdapter = pAdapter->Next; } } else { - SPDLOG_ERROR("GetAdaptersInfo failed with error: {0}\n", dwRetVal); + SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal); HeapFree(GetProcessHeap(), 0, pAdapterInfo); return -ERR_SYS_CALL; } @@ -235,7 +235,7 @@ int GetAllNICInfo(PNIC_CONTENT *pInfo, int *pItemCounts) { pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO))); if (pAdapterInfo == nullptr) { - SPDLOG_ERROR("Error allocating memory needed to call GetAdaptersinfo"); + SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo")); return -ERR_MALLOC_MEMORY; } @@ -243,7 +243,7 @@ int GetAllNICInfo(PNIC_CONTENT *pInfo, int *pItemCounts) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen)); if (pAdapterInfo == nullptr) { - SPDLOG_ERROR("Error allocating memory needed to call GetAdaptersinfo\n"); + SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n")); return -ERR_MALLOC_MEMORY; } } @@ -269,7 +269,7 @@ int GetAllNICInfo(PNIC_CONTENT *pInfo, int *pItemCounts) { // MAC ַ StringCbPrintf(g_NetAdapterInfo[id].NetCardMacAddr, 20 - 1, - "%02X:%02X:%02X:%02X:%02X:%02X", + TEXT("%02X:%02X:%02X:%02X:%02X:%02X"), pAdapter->Address[0], pAdapter->Address[1], pAdapter->Address[2], @@ -285,7 +285,7 @@ int GetAllNICInfo(PNIC_CONTENT *pInfo, int *pItemCounts) { *pItemCounts = id; } else { - SPDLOG_ERROR("GetAdaptersInfo failed with error: {0}\n", dwRetVal); + SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal); HeapFree(GetProcessHeap(), 0, pAdapterInfo); return -ERR_SYS_CALL; } @@ -674,6 +674,72 @@ 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; + + if (pIP == nullptr || lstrlen(pIP) < 8) { + SPDLOG_ERROR(TEXT("Input pIP params error: {0}"), pIP); + return -ERR_INPUT_PARAMS; + } + + if (pMask == nullptr || lstrlen(pMask) < 8) { + SPDLOG_ERROR(TEXT("Input pMask params error: {0}"), pMask); + return -ERR_INPUT_PARAMS; + } + + if (pGateway == nullptr || lstrlen(pGateway) < 8) { + SPDLOG_ERROR(TEXT("Input pGateway params error: {0}"), pGateway); + return -ERR_INPUT_PARAMS; + } + + ZeroMemory(&IpForwardTable, sizeof(MIB_IPFORWARDROW)); + + if (inet_pton(AF_INET, pIP, &IpForwardTable.dwForwardDest) <= 0) { + SPDLOG_ERROR(TEXT("Convert {0} to network ipaddress error."), pIP); + return -ERR_UN_SUPPORT; + } + + if (inet_pton(AF_INET, pMask, &IpForwardTable.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) { + SPDLOG_ERROR(TEXT("Convert {0} to network ipaddress error."), pGateway); + 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 (CreateIpForwardEntry(&IpForwardTable) != NO_ERROR) { + return -ERR_NET_ADD_ROUTE; + } + + return ERR_SUCCESS; +} + #if 0 int GetWindowsHyperVStatus(int *pEnabled) { int ret; diff --git a/NetTunnelSDK/network.h b/NetTunnelSDK/network.h index e545956..10882c7 100644 --- a/NetTunnelSDK/network.h +++ b/NetTunnelSDK/network.h @@ -123,6 +123,20 @@ NETWORK_API int __cdecl GetNetConnectionSharing(const TCHAR *pInterfaceName, boo */ NETWORK_API int __cdecl SetNetConnectionNetworkCategory(const TCHAR *pInterfaceName, const bool isPrivate); +/** + * @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 成功 + */ +NETWORK_API int __cdecl AddRouteTable(int ifIndex, const char *pIP, const char *pMask, const char *pGateway); + diff --git a/NetTunnelSDK/protocol.cpp b/NetTunnelSDK/protocol.cpp index 6f9c044..d8fbc9e 100644 --- a/NetTunnelSDK/protocol.cpp +++ b/NetTunnelSDK/protocol.cpp @@ -8,9 +8,14 @@ #include "usrerr.h" #define HTTP_JSON_CONTENT TEXT("application/json") -#define GET_USR_CFG_PATH TEXT("/tunnel/getuserconfig") -static httplib::Client *g_httpCtx = nullptr; +static httplib::Client *g_httpCtx = nullptr; +static httplib::Client *g_tunnelHttpCtx = nullptr; + +int InitControlServer(const TCHAR *pUserSvrUrl) { + g_tunnelHttpCtx = new httplib::Client(pUserSvrUrl); + return ERR_SUCCESS; +} template int CreateProtocolRequest(T *pReqParams, TCHAR **pOutJson) { std::string json; @@ -40,9 +45,14 @@ template int DecodeProtocolResponse(T *pResponse, const TCHAR *pJson) { return -ERR_JSON_DECODE; } -template int ProtolPostMessage(ProtocolRequest *pReq, ProtocolResponse *pRsp) { - int ret; - TCHAR *pJson = nullptr; +template +int ProtolPostMessage(const TCHAR *pUrlPath, + ProtocolRequest *pReq, + ProtocolResponse *pRsp, + bool platformServer) { + int ret; + httplib::Result res; + TCHAR *pJson = nullptr; if (lstrlen(GetGlobalCfgInfo()->platformServerUrl) == 0) { SPDLOG_ERROR(TEXT("Platform Server URL uninitialize.")); @@ -50,13 +60,13 @@ template int ProtolPostMessage(ProtocolRequest *pReq, Pr } if (pReq == nullptr) { - SPDLOG_ERROR("Input pToken params error"); - SPDLOG_ERROR("Input ProtocolRequest *pReq params error"); + SPDLOG_ERROR(TEXT("Input pToken params error")); + SPDLOG_ERROR(TEXT("Input ProtocolRequest *pReq params error")); return -ERR_INPUT_PARAMS; } if (pRsp == nullptr) { - SPDLOG_ERROR("Input ProtocolResponse *pRsp params error"); + SPDLOG_ERROR(TEXT("Input ProtocolResponse *pRsp params error")); return -ERR_INPUT_PARAMS; } @@ -69,22 +79,40 @@ template int ProtolPostMessage(ProtocolRequest *pReq, Pr return ret; } - const auto res = g_httpCtx->Post(GET_USR_CFG_PATH, pJson, HTTP_JSON_CONTENT); - - free(pJson); + if (platformServer) { + res = g_httpCtx->Post(pUrlPath, pJson, HTTP_JSON_CONTENT); + } else { + if (g_tunnelHttpCtx == nullptr) { + free(pJson); + SPDLOG_ERROR(TEXT("Server Control Service don't connected(g_tunnelHttpCtx is not initialize).")); + return -ERR_SYSTEM_UNINITIALIZE; + } + res = g_tunnelHttpCtx->Post(pUrlPath, pJson, HTTP_JSON_CONTENT); + } if (res.error() != httplib::Error::Success) { - SPDLOG_ERROR(TEXT("[{0}]:Post Data {1} error: {2}"), GET_USR_CFG_PATH, pJson, httplib::to_string(res.error())); + SPDLOG_ERROR(TEXT("[{0}]:Post Data {1} error: {2}"), pUrlPath, pJson, httplib::to_string(res.error())); + free(pJson); return -ERR_HTTP_POST_DATA; } if (res->status != 200) { - SPDLOG_ERROR(TEXT("[{0}]:Post Data {1} server return HTTP error: {2}"), GET_USR_CFG_PATH, pJson, res->status); + SPDLOG_ERROR(TEXT("[{0}]:Post Data {1} server return HTTP error: {2}"), pUrlPath, pJson, res->status); + free(pJson); return -ERR_HTTP_SERVER_RSP; } + SPDLOG_DEBUG(TEXT("+++++ Http Request {0}\n---- Http Response {1}"), pJson, res->body.c_str()); + + free(pJson); + + if (lstrlen(res->body.c_str()) == 0) { + SPDLOG_ERROR(TEXT("Server response empty message")); + return -ERR_READ_FILE; + } + if (DecodeProtocolResponse(pRsp, res->body.c_str()) != ERR_SUCCESS) { - SPDLOG_ERROR(TEXT("Decode JSON {0} to UserClientConfigParams error"), res->body); + SPDLOG_ERROR(TEXT("Decode JSON {0} to ProtocolResponse<{1}> error"), res->body, typeid(T2).name()); return -ERR_JSON_DECODE; } @@ -92,12 +120,36 @@ template int ProtolPostMessage(ProtocolRequest *pReq, Pr } int ProtoGetUserConfigure(const TCHAR *pUser, const TCHAR *pToken) { - int ret; - TCHAR *pJson = nullptr; - ProtocolRequest req; - ProtocolResponse rsp; + int ret; + ProtocolRequest req; + ProtocolResponse rsp; - ret = ProtolPostMessage(&req, &rsp); + ret = ProtolPostMessage(GET_SERVERCFG_PATH, &req, &rsp); return ret; -} \ No newline at end of file +} + +template int ProtolPostMessage(const TCHAR *pUrlPath, + ProtocolRequest *pReq, + ProtocolResponse *pRsp, + bool platformServer); + +template int ProtolPostMessage(const TCHAR *pUrlPath, + ProtocolRequest *pReq, + ProtocolResponse *pRsp, + bool platformServer); + +template int ProtolPostMessage(const TCHAR *pUrlPath, + ProtocolRequest *pReq, + ProtocolResponse *pRsp, + bool platformServer); + +template int ProtolPostMessage(const TCHAR *pUrlPath, + ProtocolRequest *pReq, + ProtocolResponse *pRsp, + bool platformServer); + +template int ProtolPostMessage(const TCHAR *pUrlPath, + ProtocolRequest *pReq, + ProtocolResponse *pRsp, + bool platformServer); \ No newline at end of file diff --git a/NetTunnelSDK/protocol.h b/NetTunnelSDK/protocol.h index 3ec1bb1..d9cb2de 100644 --- a/NetTunnelSDK/protocol.h +++ b/NetTunnelSDK/protocol.h @@ -13,7 +13,16 @@ public: std::string message; AIGC_JSON_HELPER(message) - AIGC_JSON_HELPER_DEFAULT(message = "PING") + AIGC_JSON_HELPER_DEFAULT(message = TEXT("PING")) +}; + +class RspHeartParams : public ResponseStatus { +public: + std::string message; + + AIGC_JSON_HELPER(message) + AIGC_JSON_HELPER_BASE((ResponseStatus *)this) + AIGC_JSON_HELPER_DEFAULT(message = TEXT("PONG")) }; class ReqGetUserCfgParams { @@ -24,6 +33,30 @@ public: AIGC_JSON_HELPER(user, token) }; +class RspUserSevrCfgParams { +public: + int svrListenPort; + std::string svrPrivateKey; + std::string svrAddress; + + AIGC_JSON_HELPER(svrListenPort, svrPrivateKey, svrAddress) +}; + +class ReqStartTunnelParams { +public: + bool isStart; + AIGC_JSON_HELPER(isStart) +}; + +class ReqUserSetCliCfgParams { +public: + std::string cliPublicKey; + std::string cliNetwork; + std::string cliTunnelAddr; + + AIGC_JSON_HELPER(cliPublicKey, cliNetwork, cliTunnelAddr) +}; + class VitrualMathineCfg { public: int vmId; @@ -35,15 +68,54 @@ public: AIGC_JSON_HELPER(vmId, vmName, svrPublicKey, vmNetwork, scgGateway) }; -class UserClientConfigParams { +class RspUsrCliConfigParams { public: int scgCtrlAppId; int scgTunnelAppId; std::string cliPrivateKey; + std::string cliPublicKey; std::string cliAddress; std::list vmConfig; - AIGC_JSON_HELPER(scgCtrlAppId, scgTunnelAppId, cliPrivateKey, cliAddress, vmConfig) + AIGC_JSON_HELPER(scgCtrlAppId, scgTunnelAppId, cliPrivateKey, cliPublicKey, cliAddress, vmConfig) }; -template int ProtolPostMessage(ProtocolRequest *pReq, ProtocolResponse *pRsp); \ No newline at end of file +#define GET_CLIENTCFG_PATH TEXT("/tunnel/getuserconfig") +#define GET_SERVERCFG_PATH TEXT("/tunnel/getserverconfig") + +#define SET_CLIENTCFG_PATH TEXT("/tunnel/setconfig") +#define SET_CLIENTSTART_TUNNEL TEXT("/tunnel/start") +#define SET_CLIENTHEART_PATH TEXT("/tunnel/heart") + +int InitControlServer(const TCHAR *pUserSvrUrl); + +template +int ProtolPostMessage(const TCHAR *pUrlPath, + ProtocolRequest *pReq, + ProtocolResponse *pRsp, + bool platformServer = true); + +extern template int ProtolPostMessage(const TCHAR *pUrlPath, + ProtocolRequest *pReq, + ProtocolResponse *pRsp, + bool platformServer); + +extern template int ProtolPostMessage(const TCHAR *pUrlPath, + ProtocolRequest *pReq, + ProtocolResponse *pRsp, + bool platformServer); + +extern template int ProtolPostMessage(const TCHAR *pUrlPath, + ProtocolRequest *pReq, + ProtocolResponse *pRsp, + bool platformServer); + +extern template int ProtolPostMessage(const TCHAR *pUrlPath, + ProtocolRequest *pReq, + ProtocolResponse *pRsp, + bool platformServer); + +extern template int ProtolPostMessage(const TCHAR *pUrlPath, + ProtocolRequest *pReq, + ProtocolResponse *pRsp, + bool platformServer); \ No newline at end of file diff --git a/NetTunnelSDK/ps1/wireguard.psm1 b/NetTunnelSDK/ps1/wireguard.psm1 deleted file mode 100644 index 15a6f60..0000000 --- a/NetTunnelSDK/ps1/wireguard.psm1 +++ /dev/null @@ -1,63 +0,0 @@ -Function Set-NetConnectionSharing -{ - Param - ( - [Parameter(Mandatory=$true)] - [string] - $LocalConnection, - - [Parameter(Mandatory=$true)] - [bool] - $Enabled - ) - - Begin - { - $netShare = $null - - try - { - # Create a NetSharingManager object - $netShare = New-Object -ComObject HNetCfg.HNetShare - } - catch - { - # Register the HNetCfg library (once) - regsvr32 /s hnetcfg.dll - - # Create a NetSharingManager object - $netShare = New-Object -ComObject HNetCfg.HNetShare - } - } - - Process - { - #Clear Existing Share - $oldConnections = $netShare.EnumEveryConnection |? { $netShare.INetSharingConfigurationForINetConnection.Invoke($_).SharingEnabled -eq $true} - foreach($oldShared in $oldConnections) - { - $oldConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($oldShared) - $oldConfig.DisableSharing() - } - - # Find connections - $InternetConnection = Get-NetRoute | ? DestinationPrefix -eq '0.0.0.0/0' | Get-NetIPInterface | Where ConnectionState -eq 'Connected' - $publicConnection = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq $InternetConnection.InterfaceAlias } - $privateConnection = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq $LocalConnection } - - # Get sharing configuration - $publicConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($publicConnection) - $privateConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($privateConnection) - - if ($Enabled) - { - $publicConfig.EnableSharing(0) - $privateConfig.EnableSharing(1) - } - else - { - $publicConfig.DisableSharing() - $privateConfig.DisableSharing() - } - } -} \ No newline at end of file diff --git a/NetTunnelSDK/tunnel.cpp b/NetTunnelSDK/tunnel.cpp index cbaeafa..3428533 100644 --- a/NetTunnelSDK/tunnel.cpp +++ b/NetTunnelSDK/tunnel.cpp @@ -169,6 +169,8 @@ int SetProtocolEncryptType(const PROTO_CRYPTO_TYPE type, const TCHAR *pProKey) { return ERR_SUCCESS; } +//int CheckSystemMinDepend(CHECK_FUNCTION chkItem, TCHAR* pErrMsg, errMsg[MAX_PATH], ); + int CheckSystemMinRequired(CHK_RESULT chkResult[CHK_MAX]) { for (int i = 0; i < CHK_MAX; i++) { const PCHK_RESULT pChk = &chkResult[i]; diff --git a/NetTunnelSDK/tunnel.h b/NetTunnelSDK/tunnel.h index 92a7c58..f4b6207 100644 --- a/NetTunnelSDK/tunnel.h +++ b/NetTunnelSDK/tunnel.h @@ -220,7 +220,29 @@ TUNNEL_API int __cdecl WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgCon * @param[in] bInstall TRUE 安装服务, FALSE 卸载服务 * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO */ -TUNNEL_API int __cdecl WireGuardInstallServerService(bool bInstall); +TUNNEL_API int __cdecl WireGuardInstallDefaultServerService(bool bInstall); + +/** + * @brief 通过 WireGuard 配置文件安装隧道服务 + * @param[in] pTunnelCfgPath 配置文件完整路径 + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_ITEM_UNEXISTS 配置文件不存在 + * - -ERR_CALL_SHELL 调用 WireGuard 外部服务失败 + * - ERR_SUCCESS 成功 + */ +TUNNEL_API int __cdecl WireGuardInstallServerService(const TCHAR *pTunnelCfgPath); + +/** + * @brief 卸载 WireGuard 隧道服务 + * @param[in] pTunnelName 隧道服务名 + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_ITEM_UNEXISTS 配置文件不存在 + * - -ERR_CALL_SHELL 调用 WireGuard 外部服务失败 + * - ERR_SUCCESS 成功 + */ +TUNNEL_API int __cdecl WireGuardUnInstallServerService(const TCHAR *pTunnelName); /** * @brief 判断当前网络服务工作模式 客户端/服务端 @@ -247,6 +269,19 @@ TUNNEL_API int __cdecl GetWireGuardWorkMode(bool *pIsWorkServer); */ TUNNEL_API int __cdecl IsWireGuardServerInstalled(bool *pIsInstalled); +/** + * @brief 获取当前 WireGuard 服务隧道是否正则运行 + * @param[in] pIfName WireGuard 隧道网络接口名称 + * @param[out] pIsRunning WireGuard 服务隧道运行状态 + * - TRUE 已经安装 + * - FALSE 未安装 + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_MALLOC_MEMORY 分配内存失败 + * - ERR_SUCCESS 成功 + */ +TUNNEL_API int __cdecl IsWireGuardServerRunning(const TCHAR *pIfName, bool *pIsRunning); + /** * @brief 清理 SDK 运行资源 */ @@ -272,7 +307,7 @@ TUNNEL_API int __cdecl CalcFileHash(const HASH_TYPE type, const TCHAR *pPath, TC //+++++++++++++++++++++++++++++++++++++++++Temp Interface -TUNNEL_API int __cdecl ProtoGetUserConfigure(const TCHAR *pUser, const TCHAR *pToken); +TUNNEL_API int __cdecl ProtoGetUserConfigure(const TCHAR *pUser, const TCHAR *pToken); //------------------------------------------End Temp Interface #if 0 /** diff --git a/NetTunnelSDK/txt1.bin b/NetTunnelSDK/txt1.bin deleted file mode 100644 index ff57adf..0000000 --- a/NetTunnelSDK/txt1.bin +++ /dev/null @@ -1,126 +0,0 @@ -Function Test-Administrator -{ - [OutputType([bool])] - param() - process { - [Security.Principal.WindowsPrincipal]$user = [Security.Principal.WindowsIdentity]::GetCurrent(); - return $user.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator); - } -} - -Function Set-NetConnectionSharing -{ - Param - ( - [Parameter(Mandatory=$true)] - [string] - $LocalConnection, - - [Parameter(Mandatory=$true)] - [bool] - $Enabled - ) - - Begin - { - $netShare = $null - - try - { - # Create a NetSharingManager object - $netShare = New-Object -ComObject HNetCfg.HNetShare - } - catch - { - # Register the HNetCfg library (once) - regsvr32 /s hnetcfg.dll - - # Create a NetSharingManager object - $netShare = New-Object -ComObject HNetCfg.HNetShare - } - } - - Process - { - if(-not (Test-Administrator)) - { - # TODO: define proper exit codes for the given errors - Write-Error "Error This script must be executed as Administrator." - } else { - #Clear Existing Share - $oldConnections = $netShare.EnumEveryConnection |? { $netShare.INetSharingConfigurationForINetConnection.Invoke($_).SharingEnabled -eq $true} - foreach($oldShared in $oldConnections) - { - $oldConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($oldShared) - $oldConfig.DisableSharing() - } - - # Find connections - $InternetConnection = Get-NetRoute | ? DestinationPrefix -eq '0.0.0.0/0' | Get-NetIPInterface | Where ConnectionState -eq 'Connected' - $publicConnection = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq $InternetConnection.InterfaceAlias } - $privateConnection = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq $LocalConnection } - - # Get sharing configuration - $publicConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($publicConnection) - $privateConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($privateConnection) - - if ($Enabled) - { - $publicConfig.EnableSharing(0) - $privateConfig.EnableSharing(1) - } - else - { - $publicConfig.DisableSharing() - $privateConfig.DisableSharing() - } - } - } -} - -Function Get-NetConnectionSharing -{ - Param - ( - [Parameter(Mandatory=$true)] - [string] - $LocalConnection - ) - - Begin - { - $netShare = $null - - try - { - # Create a NetSharingManager object - $netShare = New-Object -ComObject HNetCfg.HNetShare - } - catch - { - # Register the HNetCfg library (once) - regsvr32 /s hnetcfg.dll - - # Create a NetSharingManager object - $netShare = New-Object -ComObject HNetCfg.HNetShare - } - } - - Process - { - if(-not (Test-Administrator)) - { - # TODO: define proper exit codes for the given errors - Write-Error "Error This script must be executed as Administrator." - } else { - # Find connections - $privateConnection = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name -eq $LocalConnection } - # Get sharing configuration - $privateConfig = $netShare.INetSharingConfigurationForINetConnection.Invoke($privateConnection) - Write-Output $privateConfig - } - - } -} - -Export-ModuleMember -function Get-NetConnectionSharing, Set-NetConnectionSharing \ No newline at end of file diff --git a/NetTunnelSDK/user.h b/NetTunnelSDK/user.h index 11a744a..a931f1f 100644 --- a/NetTunnelSDK/user.h +++ b/NetTunnelSDK/user.h @@ -6,6 +6,11 @@ #define USERMANAGER_API __declspec(dllimport) #endif + +#define HEART_PERIOD_MS (3000) +typedef void (*PTUNNEL_HEART_ROUTINE)(const TCHAR *pMessage, unsigned int timeStampOfSeconds); +typedef PTUNNEL_HEART_ROUTINE LPTUNNEL_HEART_ROUTINE; + /** * * @brief 本地计算机网卡信息 @@ -15,13 +20,99 @@ typedef struct { TCHAR CfgPath[260]; ///< 配置文件路径 } USER_CFGFILE, *PUSER_CFGFILE; + #ifdef __cplusplus // If used by C++ code, extern "C" { // we need to export the C interface #endif +/** + * @brief 连接到服务端控制服务 + * @param pUserSvrUrl 服务端控制服务 URL 地址 + */ +USERMANAGER_API void __cdecl ConnectServerControlService(const TCHAR *pUserSvrUrl); /** - * @brief 用户登录接口 + * @brief 云电脑服务端创建控制服务 + * @param pSvr 服务端配置信息 + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_CREATE_THREAD 创建线程失败 + * - -ERR_SOCKET_BIND_PORT 绑定端口失败 + * - -ERR_ITEM_EXISTS 服务线程状态异常 + * - ERR_SUCCESS 成功 + */ +USERMANAGER_API int __cdecl CreateControlService(PUSER_SERVER_CONFIG pSvr); + +/** + * @brief 停止云电脑服务端服务 + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERROR_TIMEOUT 等待超时 + * - ERR_SUCCESS 成功 + */ +USERMANAGER_API int __cdecl StopControlService(); + +/** + * @brief 设置远程云电脑中的 WireGuard 隧道客户端相关配置 + * @param[in] pCliPublicKey 客户端公钥 + * @param[in] pCliNetwork 客户端共享网络 + * @param[in] pCliTunnelAddr 客户端隧道 IP 地址 + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_SYSTEM_UNINITIALIZE 未初始化远程服务 URL 地址 + * - -ERR_CREATE_FILE 创建用户配置目录失败 + * - -ERR_HTTP_POST_DATA POST 数据到服务端失败 + * - -ERR_HTTP_SERVER_RSP HTTP 服务器返回错误 + * - -ERR_READ_FILE 服务端未返回正确的消息 + * - -ERR_JSON_DECODE JSON 字符串解码失败 + * - ERR_SUCCESS 成功 + */ +USERMANAGER_API int __cdecl SetClientConfige(const TCHAR *pCliPublicKey, + const TCHAR *pCliNetwork, + const TCHAR *pCliTunnelAddr); + +/** + * @brief 启动/停止 隧道控制服务心跳 + * @param isStart 启动/停止服务 TRUE 启动服务, FALSE 停止服务 + * @param lpHeartCbAddress 心跳服务回调函数 @see PTUNNEL_HEART_ROUTINE + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_CREATE_TIMER 创建定时器失败 + * - -ERR_DELETE_TIMER 删除定时器失败 + * - ERR_SUCCESS 成功 + */ +USERMANAGER_API int __cdecl RemoteHeartControl(bool isStart, LPTUNNEL_HEART_ROUTINE lpHeartCbAddress); + +/** + * @brief 启动/停止远程云电脑中的 WireGuard 隧道服务 + * @param[in] isStart 启动/停止服务 TRUE 启动服务, FALSE 停止服务 + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_SYSTEM_UNINITIALIZE 未初始化远程服务 URL 地址 + * - -ERR_CREATE_FILE 创建用户配置目录失败 + * - -ERR_HTTP_POST_DATA POST 数据到服务端失败 + * - -ERR_HTTP_SERVER_RSP HTTP 服务器返回错误 + * - -ERR_READ_FILE 服务端未返回正确的消息 + * - -ERR_JSON_DECODE JSON 字符串解码失败 + * - ERR_SUCCESS 成功 + */ +USERMANAGER_API int __cdecl RemoteWireGuardControl(bool isStart); + +/** + * @brief 获取用户服务端配置信息 + * @param[in] pUserName 用户名 + * @param[in] pToken 用户访问令牌 + * @param[out] pSvrCfg 服务端用户配置信息 + * @return 0: 成功, 小于0 失败 @see USER_ERRNO + * - -ERR_INPUT_PARAMS 输入参数错误 + * - -ERR_MEMORY_STR 字符串处理 + * - -ERR_CREATE_FILE 创建用户配置目录失败 + * - ERR_SUCCESS 成功 + */ +USERMANAGER_API int __cdecl GetUserServerConfigure(const TCHAR *pUserName, + const TCHAR *pToken, + PUSER_SERVER_CONFIG *pSvrCfg); +/** + * @brief 获取用户客户端配置信息 * @param[in] pUserName 用户名 * @param[in] pToken 用户访问令牌 * @param[out] pCliCfg 客户端用户配置信息 @@ -31,8 +122,11 @@ extern "C" { * - -ERR_CREATE_FILE 创建用户配置目录失败 * - ERR_SUCCESS 成功 */ -USERMANAGER_API int __cdecl UserLogin(const TCHAR *pUserName, const TCHAR *pToken, PUSER_CLIENT_CONFIG *pCliCfg); +USERMANAGER_API int __cdecl GetUserClientConfigure(const TCHAR *pUserName, + const TCHAR *pToken, + PUSER_CLIENT_CONFIG *pCliCfg); USERMANAGER_API int __cdecl GetUserConfigFiles(const TCHAR *pUserName, PUSER_CFGFILE* pCfgFile, int *pItems); + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/NetTunnelSDK/usrerr.h b/NetTunnelSDK/usrerr.h index 642c487..5042fda 100644 --- a/NetTunnelSDK/usrerr.h +++ b/NetTunnelSDK/usrerr.h @@ -30,6 +30,10 @@ enum USER_ERRNO { ERR_MEMORY_STR, ///< 字符串操作失败 ERR_CREATE_PROCESS, ///< 创建进程失败 ERR_PROCESS_RETURN, ///< 进程调用返回失败 + ERR_CREATE_THREAD, ///< 创建线程失败 + ERR_CREATE_TIMER, ///< 创建定时器失败 + ERR_DELETE_TIMER, ///< 销毁定时器失败 + ERR_SOCKET_BIND_PORT, ///< 绑定端口失败 ERR_BCRYPT_OPEN = 100, ///< 创建加密算法失败 ERR_BCRYPT_GETPROPERTY, ///< 获取加密算法属性失败 ERR_BCRYPT_CREATEHASH, ///< 创建 Hash 算法失败 @@ -42,4 +46,5 @@ enum USER_ERRNO { ERR_JSON_DECODE, ///< 从 JSON 反序列化对象失败 ERR_HTTP_SERVER_RSP = 500, ///< HTTP 服务端返回错误 ERR_HTTP_POST_DATA, ///< 发送 POST 请求失败 + ERR_NET_ADD_ROUTE, ///< 添加路由失败 }; \ No newline at end of file diff --git a/NetTunnelSDK/wireguard.cpp b/NetTunnelSDK/wireguard.cpp index b030c02..773a59c 100644 --- a/NetTunnelSDK/wireguard.cpp +++ b/NetTunnelSDK/wireguard.cpp @@ -7,26 +7,17 @@ #include "globalcfg.h" #include "misc.h" -//#include "resource.h" +#include "network.h" #pragma comment(lib, "Shlwapi.lib") -//#define PSCMD_RES_ID (IDR_TXT1) +#define WG_NIC_DISCRIPT TEXT("WireGuard Tunnel") constexpr auto WINENVBUF_SIZE = (4096); -/** - * @brief 判断当前网络服务工作模式 客户端/服务端 - * @param[out] pIsWorkServer 工作模式 - * - TRUE 服务端 - * - FALSE 客户端 - * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO - * - -ERR_INPUT_PARAMS 输入参数错误 - * - ERR_SUCCESS 成功 - */ int GetWireGuardWorkMode(bool *pIsWorkServer) { if (pIsWorkServer == nullptr) { - SPDLOG_ERROR("Input pIsWorkServer params error"); + SPDLOG_ERROR(TEXT("Input pIsWorkServer params error")); return -ERR_INPUT_PARAMS; } @@ -35,12 +26,7 @@ int GetWireGuardWorkMode(bool *pIsWorkServer) { return ERR_SUCCESS; } -/** - * @brief 安装/卸载 WireGuard 服务 - * @param[in] bInstall TRUE 安装服务, FALSE 卸载服务 - * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO - */ -int WireGuardInstallServerService(bool bInstall) { +int WireGuardInstallDefaultServerService(bool bInstall) { TCHAR cfgVal[MAX_PATH]; DWORD retCode; @@ -79,41 +65,93 @@ int WireGuardInstallServerService(bool bInstall) { } if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) { - SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret); + SPDLOG_ERROR(TEXT("Run command [{0}] error: {1}"), cmdBuf, ret); return -ERR_CALL_SHELL; } - SPDLOG_DEBUG("Run command [{0}]", cmdBuf); + SPDLOG_DEBUG(TEXT("Run command [{0}]"), cmdBuf); return ERR_SUCCESS; } else { - SPDLOG_ERROR("WireGuard configure file [{0}] not found", cfgVal); + SPDLOG_ERROR(TEXT("WireGuard configure file [{0}] not found"), cfgVal); return -ERR_FILE_NOT_EXISTS; } } else { - SPDLOG_ERROR("Configure [{0}] not found", CFG_WGCFG_PATH); + SPDLOG_ERROR(TEXT("Configure [{0}] = {1} not found"), CFG_WGCFG_PATH, cfgVal); return -ERR_ITEM_UNEXISTS; } } -/** - * @brief 获取当前 WireGuard 服务是否安装 - * @param[out] pIsInstalled WireGuard 服务安装状态 - * - TRUE 已经安装 - * - FALSE 未安装 - * @return 0: 成功, 小于0 失败 @see USER_ERRNO - * - -ERR_INPUT_PARAMS 输入参数错误 - * - -ERR_OPEN_SCM, 打开服务管理器设备 - * - -ERR_OPEN_SERVICE, 打开服务失败 - * - -ERR_GET_SERVICESSTATUS, 获取服务状态失败 - * - ERR_SUCCESS 成功 - */ +int WireGuardInstallServerService(const TCHAR *pTunnelCfgPath) { + // 卸载服务 + TCHAR cmdBuf[MAX_PATH]; + int ret; + DWORD retCode; + + if (pTunnelCfgPath == nullptr || lstrlen(pTunnelCfgPath) == 0) { + SPDLOG_ERROR(TEXT("Input pTunnelCfgPath params error")); + return -ERR_INPUT_PARAMS; + } + if (!PathFileExists(pTunnelCfgPath)) { + SPDLOG_ERROR(TEXT("WireGuard configure file {0} unexists."), pTunnelCfgPath); + return -ERR_ITEM_UNEXISTS; + } + + // 安装服务 + StringCbPrintf(cmdBuf, + MAX_PATH, + TEXT("\"%s\" /installtunnelservice \"%s\""), + GetGlobalCfgInfo()->wireguardCfg.wireguardPath, + pTunnelCfgPath); + + if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) { + SPDLOG_ERROR(TEXT("Run command [{0}] error: {1}"), cmdBuf, ret); + return -ERR_CALL_SHELL; + } + + SPDLOG_DEBUG(TEXT("Run command [{0}]"), cmdBuf); + + return ERR_SUCCESS; +} + +int WireGuardUnInstallServerService(const TCHAR *pTunnelName) { + // 卸载服务 + TCHAR cmdBuf[MAX_PATH]; + TCHAR svrName[MAX_PATH]; + int ret; + DWORD retCode; + + if (pTunnelName == nullptr || lstrlen(pTunnelName) == 0) { + SPDLOG_ERROR(TEXT("Input pTunnelName params error")); + return -ERR_INPUT_PARAMS; + } + + StringCbCopy(svrName, MAX_PATH, pTunnelName); + PathStripPath(svrName); + PathRemoveExtension(svrName); + + StringCbPrintf(cmdBuf, + MAX_PATH, + TEXT("\"%s\" /uninstalltunnelservice %s"), + GetGlobalCfgInfo()->wireguardCfg.wireguardPath, + svrName); + + if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) { + SPDLOG_ERROR(TEXT("Run command [{0}] error: {1}"), cmdBuf, ret); + return -ERR_CALL_SHELL; + } + + SPDLOG_DEBUG(TEXT("Run command [{0}]"), cmdBuf); + + return ERR_SUCCESS; +} + int IsWireGuardServerInstalled(bool *pIsInstalled) { DWORD dwStatus; int ret; if (pIsInstalled == nullptr) { - SPDLOG_ERROR("Input pIsInstalled params error"); + SPDLOG_ERROR(TEXT("Input pIsInstalled params error")); return -ERR_INPUT_PARAMS; } @@ -137,16 +175,38 @@ int IsWireGuardServerInstalled(bool *pIsInstalled) { return ret; } -/** - * @brief 创建 WireGuard 客户端配置文件 - * @param[in] pWgConfig 配置文件相关配置项 @see WGCLIENT_CONFIG - * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO - * - -ERR_INPUT_PARAMS 输入参数错误 - * - -ERR_MALLOC_MEMORY 分配内存失败 - * - -ERR_OPEN_FILE 打开文件失败 - * - -ERR_MEMORY_STR 字符串处理失败 - * - ERR_SUCCESS 成功 - */ +int IsWireGuardServerRunning(const TCHAR *pIfName, bool *pIsRunning) { + int ret; + PNIC_CONTENT pInfo = nullptr; + int size = 0; + + if (pIfName == nullptr || lstrlen(pIfName) == 0) { + SPDLOG_ERROR(TEXT("Input pIfName params error")); + return -ERR_INPUT_PARAMS; + } + + if (pIsRunning == nullptr) { + SPDLOG_ERROR(TEXT("Input pIsRunning params error")); + return -ERR_INPUT_PARAMS; + } + + *pIsRunning = false; + + ret = GetAllNICInfo(&pInfo, &size); + if (ret != ERR_SUCCESS) { + return ret; + } + + for (int i = 0; i < size; i++) { + if (StrNCmp(pInfo[i].NetCardDescription, WG_NIC_DISCRIPT, lstrlen(WG_NIC_DISCRIPT)) == 0 && + StrCmp(pInfo[i].NetCardName, pIfName) == 0) { + *pIsRunning = true; + } + } + + return ret; +} + int WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgConfig) { const size_t bufSize = 4096 * sizeof(TCHAR); const TCHAR cfgFormat[] = TEXT( @@ -163,32 +223,32 @@ int WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgConfig) { } if (FAILED(StringCbLength(pWgConfig->Name, 64, &length)) || 0 == length) { - SPDLOG_ERROR("WireGuard Name error: {0}", pWgConfig->Name); + SPDLOG_ERROR(TEXT("WireGuard Name error: {0}"), pWgConfig->Name); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbLength(pWgConfig->Address, 32, &length)) || 0 == length) { - SPDLOG_ERROR("WireGuard Address error: {0}", pWgConfig->Address); + SPDLOG_ERROR(TEXT("WireGuard Address error: {0}"), pWgConfig->Address); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbLength(pWgConfig->PrivateKey, 64, &length)) || 0 == length) { - SPDLOG_ERROR("WireGuard Private key error: {0}", pWgConfig->PrivateKey); + SPDLOG_ERROR(TEXT("WireGuard Private key error: {0}"), pWgConfig->PrivateKey); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbLength(pWgConfig->SvrPubKey, 64, &length)) || 0 == length) { - SPDLOG_ERROR("WireGuard Server Public key error: {0}", pWgConfig->SvrPubKey); + SPDLOG_ERROR(TEXT("WireGuard Server Public key error: {0}"), pWgConfig->SvrPubKey); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbLength(pWgConfig->AllowNet, 256, &length)) || 0 == length) { - SPDLOG_ERROR("WireGuard Allow Client Network error: {0}", pWgConfig->AllowNet); + SPDLOG_ERROR(TEXT("WireGuard Allow Client Network error: {0}"), pWgConfig->AllowNet); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbLength(pWgConfig->ServerURL, 256, &length)) || 0 == length) { - SPDLOG_ERROR("WireGuard Server Network error: {0}", pWgConfig->ServerURL); + SPDLOG_ERROR(TEXT("WireGuard Server Network error: {0}"), pWgConfig->ServerURL); return -ERR_INPUT_PARAMS; } #pragma endregion 参数检查 @@ -196,7 +256,7 @@ int WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgConfig) { pBuf = static_cast(malloc(bufSize)); if (pBuf == nullptr) { - SPDLOG_ERROR("Malloc {1} bytes memory error: {0}", GetLastError(), bufSize); + SPDLOG_ERROR(TEXT("Malloc {1} bytes memory error: {0}"), GetLastError(), bufSize); return -ERR_MALLOC_MEMORY; } @@ -232,7 +292,7 @@ int WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgConfig) { nullptr); // no attr. template if (hFile == INVALID_HANDLE_VALUE) { - SPDLOG_ERROR("CreatFile [{0}] error: {1}", cfgPath, GetLastError()); + SPDLOG_ERROR(TEXT("CreatFile [{0}] error: {1}"), cfgPath, GetLastError()); free(pBuf); return -ERR_OPEN_FILE; } @@ -248,50 +308,40 @@ int WireGuardCreateClientConfig(const PWGCLIENT_CONFIG pWgConfig) { pWgConfig->SvrPubKey, pWgConfig->AllowNet, pWgConfig->ServerURL))) { - SPDLOG_ERROR("Format string error: {0}", GetLastError()); + SPDLOG_ERROR(TEXT("Format string error: {0}"), GetLastError()); free(pBuf); ::CloseHandle(hFile); return -ERR_MEMORY_STR; } if (FAILED(StringCbLength(pBuf, bufSize, &length))) { - SPDLOG_ERROR("Get string \'{0}\' length error: {1}", pBuf, GetLastError()); + SPDLOG_ERROR(TEXT("Get string \'{0}\' length error: {1}"), pBuf, GetLastError()); free(pBuf); ::CloseHandle(hFile); return -ERR_MEMORY_STR; } - SPDLOG_DEBUG("WG Client Configure:\n{0}", pBuf); + SPDLOG_DEBUG(TEXT("WG Client Configure:\n{0}"), pBuf); if (!WriteFile(hFile, // open file handle pBuf, // start of data to write static_cast(length), // number of bytes to write nullptr, // number of bytes that were written nullptr)) { - SPDLOG_ERROR("WriteFile [{0}] error: {1}", cfgPath, GetLastError()); + SPDLOG_ERROR(TEXT("WriteFile [{0}] error: {1}"), cfgPath, GetLastError()); free(pBuf); ::CloseHandle(hFile); return -ERR_OPEN_FILE; } StringCbCopy(GetGlobalCfgInfo()->wgClientCfg.wgName, 260, pWgConfig->Name); - StringCbCopy(GetGlobalCfgInfo()->wgClientCfg.wgIpaddr, MAX_IP_LEN, pWgConfig->Address); + StringCbCopy(GetGlobalCfgInfo()->wgClientCfg.wgIpaddr, MAX_IP_LEN, pWgConfig->Address); StringCbCopy(GetGlobalCfgInfo()->wgClientCfg.wgCfgPath, MAX_PATH, cfgPath); ::CloseHandle(hFile); return ERR_SUCCESS; } -/** - * @brief 创建 WireGuard 服务端配置文件 - * @param[in] pWgConfig 配置文件相关配置项 @see WGSERVER_CONFIG - * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO - * - -ERR_INPUT_PARAMS 输入参数错误 - * - -ERR_MALLOC_MEMORY 分配内存失败 - * - -ERR_OPEN_FILE 打开文件失败 - * - -ERR_MEMORY_STR 字符串处理失败 - * - ERR_SUCCESS 成功 - */ int WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgConfig) { const size_t bufSize = 4096 * sizeof(TCHAR); const TCHAR cfgFormat[] = TEXT( @@ -307,32 +357,33 @@ int WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgConfig) { } if (FAILED(StringCbLength(pWgConfig->Name, 64, &length)) || 0 == length) { - SPDLOG_ERROR("WireGuard Name error: {0}", pWgConfig->Name); + SPDLOG_ERROR(TEXT("WireGuard Name error: {0}"), pWgConfig->Name); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbLength(pWgConfig->Address, 32, &length)) || 0 == length) { - SPDLOG_ERROR("WireGuard Address error: {0}", pWgConfig->Address); + SPDLOG_ERROR(TEXT("WireGuard Address error: {0}"), pWgConfig->Address); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbLength(pWgConfig->PrivateKey, 64, &length)) || 0 == length) { - SPDLOG_ERROR("WireGuard Private key error: {0}", pWgConfig->PrivateKey); + SPDLOG_ERROR(TEXT("WireGuard Private key error: {0}"), pWgConfig->PrivateKey); return -ERR_INPUT_PARAMS; } if (pWgConfig->ListenPort <= 1024 || pWgConfig->ListenPort >= 65535) { - SPDLOG_ERROR("WireGuard Listen port error: {0}, should be in arrange (1024, 65535)", pWgConfig->ListenPort); + SPDLOG_ERROR(TEXT("WireGuard Listen port error: {0}, should be in arrange (1024, 65535)"), + pWgConfig->ListenPort); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbLength(pWgConfig->CliPubKey, 64, &length)) || 0 == length) { - SPDLOG_ERROR("WireGuard Client Public key error: {0}", pWgConfig->CliPubKey); + SPDLOG_ERROR(TEXT("WireGuard Client Public key error: {0}"), pWgConfig->CliPubKey); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbLength(pWgConfig->AllowNet, 256, &length)) || 0 == length) { - SPDLOG_ERROR("WireGuard Allow Client Network error: {0}", pWgConfig->AllowNet); + SPDLOG_ERROR(TEXT("WireGuard Allow Client Network error: {0}"), pWgConfig->AllowNet); return -ERR_INPUT_PARAMS; } #pragma endregion 参数检查 @@ -340,7 +391,7 @@ int WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgConfig) { pBuf = static_cast(malloc(bufSize)); if (pBuf == nullptr) { - SPDLOG_ERROR("Malloc {1} bytes memory error: {0}", GetLastError(), bufSize); + SPDLOG_ERROR(TEXT("Malloc {1} bytes memory error: {0}"), GetLastError(), bufSize); return -ERR_MALLOC_MEMORY; } @@ -376,11 +427,15 @@ int WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgConfig) { nullptr); // no attr. template if (hFile == INVALID_HANDLE_VALUE) { - SPDLOG_ERROR("CreatFile [{0}] error: {1}", cfgPath, GetLastError()); + SPDLOG_ERROR(TEXT("CreatFile [{0}] error: {1}"), cfgPath, GetLastError()); free(pBuf); return -ERR_OPEN_FILE; } + // 清空文件 + SetFilePointer(hFile, 0, nullptr, FILE_BEGIN); + SetEndOfFile(hFile); + WritePrivateProfileString(CFG_WIREGUARD_SECTION, CFG_WGCFG_PATH, cfgPath, GetGlobalCfgInfo()->cfgPath); if (FAILED(StringCbPrintf(pBuf, @@ -391,20 +446,20 @@ int WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgConfig) { pWgConfig->PrivateKey, pWgConfig->CliPubKey, pWgConfig->AllowNet))) { - SPDLOG_ERROR("Format string error: {0}", GetLastError()); + SPDLOG_ERROR(TEXT("Format string error: {0}"), GetLastError()); free(pBuf); ::CloseHandle(hFile); return -ERR_MEMORY_STR; } if (FAILED(StringCbLength(pBuf, bufSize, &length))) { - SPDLOG_ERROR("Get string \'{0}\' length error: {1}", pBuf, GetLastError()); + SPDLOG_ERROR(TEXT("Get string \'{0}\' length error: {1}"), pBuf, GetLastError()); free(pBuf); ::CloseHandle(hFile); return -ERR_MEMORY_STR; } - SPDLOG_DEBUG("WG Server Configure:\n{0}", pBuf); + SPDLOG_DEBUG(TEXT("WG Server Configure:\n{0}"), pBuf); if (FALSE == WriteFile(hFile, // open file handle @@ -413,7 +468,7 @@ int WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgConfig) { nullptr, // number of bytes that were written nullptr)) // no overlapped structure) { - SPDLOG_ERROR("WriteFile [{0}] error: {1}", cfgPath, GetLastError()); + SPDLOG_ERROR(TEXT("WriteFile [{0}] error: {1}"), cfgPath, GetLastError()); free(pBuf); ::CloseHandle(hFile); return -ERR_OPEN_FILE; @@ -427,17 +482,6 @@ int WireGuardCreateServerConfig(const PWGSERVER_CONFIG pWgConfig) { return ERR_SUCCESS; } -/** - * @brief 创建 WireGuard 密钥对 - * @param[out] pPubKey 公钥缓冲区 - * @param[in] pubkeySize 公钥缓冲区大小(字节数) - * @param[out] pPrivKey 私钥缓冲区 - * @param[in] privKeySize 私钥缓冲区大小(字节数) - * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO - * - -ERR_ITEM_UNEXISTS WireGuard 未配置或未安装 - * - -ERR_CALL_SHELL 调用操作系统命令行工具失败 - * - ERR_SUCCESS 成功 - */ int GenerateWireguardKeyPairs(TCHAR *pPubKey, int pubkeySize, TCHAR *pPrivKey, int privKeySize) { int ret; DWORD retCode; @@ -456,11 +500,11 @@ int GenerateWireguardKeyPairs(TCHAR *pPubKey, int pubkeySize, TCHAR *pPrivKey, i StringCbPrintf(cmdBuffer, MAX_PATH, TEXT("cmd.exe /C \"%s\" genkey"), pCfg->wireguardCfg.wgPath); if ((ret = RunCommand(cmdBuffer, cmdResult, MAX_PATH, &retCode)) != ERR_SUCCESS) { - SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuffer, ret); + SPDLOG_ERROR(TEXT("Run command [{0}] error: {1}"), cmdBuffer, ret); return -ERR_CALL_SHELL; } - SPDLOG_DEBUG("Run command [{0}] resutl \'{1}\'", cmdBuffer, cmdResult); + SPDLOG_DEBUG(TEXT("Run command [{0}] resutl \'{1}\'"), cmdBuffer, cmdResult); StringCbCopy(pPrivKey, privKeySize, cmdResult); memset(cmdBuffer, 0, MAX_PATH); @@ -472,24 +516,16 @@ int GenerateWireguardKeyPairs(TCHAR *pPubKey, int pubkeySize, TCHAR *pPrivKey, i memset(cmdResult, 0, MAX_PATH); if ((ret = RunCommand(cmdBuffer, cmdResult, MAX_PATH, &retCode)) != ERR_SUCCESS) { - SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuffer, ret); + SPDLOG_ERROR(TEXT("Run command [{0}] error: {1}"), cmdBuffer, ret); return -ERR_CALL_SHELL; } StringCbCopy(pPubKey, pubkeySize, cmdResult); - SPDLOG_DEBUG("Run command [{0}] resutl \'{1}\'", cmdBuffer, cmdResult); + SPDLOG_DEBUG(TEXT("Run command [{0}] resutl \'{1}\'"), cmdBuffer, cmdResult); return ERR_SUCCESS; } -/** - * @brief 设置 wireguard.exe 程序路径 - * @param[in] pPath wireguard.exe 程序路径 - * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO - * - -ERR_INPUT_PARAMS 输入参数错误 - * - -ERR_ITEM_UNEXISTS 文件不存在 - * - ERR_SUCCESS 成功 - */ int SetWireguardPath(const TCHAR *pPath) { if (pPath == nullptr) { return -ERR_INPUT_PARAMS; @@ -519,16 +555,6 @@ int SetWireguardPath(const TCHAR *pPath) { } } -/** - * @brief 查找 WireGuard 运行环境 - * @param[out] pFullPath wireguard.exe 程序路径 - * @param[in] maxSize pFullPath 缓冲区最大字节数 - * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO - * - -ERR_INPUT_PARAMS 输入参数错误 - * - -ERR_MALLOC_MEMORY 分配内存失败 - * - -ERR_FILE_NOT_EXISTS 文件不存在 - * - ERR_SUCCESS 成功 - */ int FindWireguardExe(TCHAR *pFullPath, int maxSize) { TCHAR path[MAX_PATH]; TCHAR wireguardPath[MAX_PATH]; diff --git a/NetTunnelSDKTestApp/NetTunnelSDKTestApp.cpp b/NetTunnelSDKTestApp/NetTunnelSDKTestApp.cpp index 6a87e69..391cbde 100644 --- a/NetTunnelSDKTestApp/NetTunnelSDKTestApp.cpp +++ b/NetTunnelSDKTestApp/NetTunnelSDKTestApp.cpp @@ -1,16 +1,20 @@ // NetTunnelSDKTestApp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // +#include + #include "common.h" +#include "tunnel.h" +#include "globalcfg.h" +#include "user.h" +#include "usrerr.h" -#include -#include - -#include -using namespace std; - +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://localhost:9276"); +#if 0 int service_test() { TCHAR szSvcName[] = _T("WireGuard"); SC_HANDLE schSCManager = nullptr; @@ -79,12 +83,43 @@ int service_test() { cin.get(); return 0; } +#endif + +int tunnel_service() { + PUSER_SERVER_CONFIG pSvrCfg; + TCHAR logPath[MAX_PATH]; + + TunnelSDKInitEnv(g_AppPath, g_PlatformURL, true); + + StringCbPrintf(logPath, MAX_PATH, TEXT("%s\\TestApp.log"), g_AppPath); + InitTunnelSDKLog(logPath, LOG_DEBUG); + + // Server 端用户名建议固定为一个字符串,因为每个云电脑上有且只有一个用户名, 长度不要超过32字符 + int ret = GetUserServerConfigure(g_SvrUserName, "asfdafdafdaf", &pSvrCfg); + if (ERR_SUCCESS != ret) { + SPDLOG_ERROR(TEXT("GetUserServerConfigure Error: {0}"), ret); + return 0; + } + + CreateControlService(pSvrCfg); + return 0; +} int main() { + bool bRet; + IsWireGuardServerRunning(TEXT("tunnel_svr"), &bRet); + SPDLOG_INFO(TEXT("IsWireGuardServerRunning tunnel_svr: {0}"), bRet); //ShowRouteTable(); //NetShare(); //GetInterface(); - CryptoExample(); + //CryptoExample(); + //SetRouteTable(); + tunnel_service(); + + while (true) { + Sleep(100); + } + return 0; } // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 diff --git a/NetTunnelSDKTestApp/NetTunnelSDKTestApp.vcxproj b/NetTunnelSDKTestApp/NetTunnelSDKTestApp.vcxproj index 3fd6e5e..2123aa1 100644 --- a/NetTunnelSDKTestApp/NetTunnelSDKTestApp.vcxproj +++ b/NetTunnelSDKTestApp/NetTunnelSDKTestApp.vcxproj @@ -104,10 +104,12 @@ false _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true + ../NetTunnelSDK;%(AdditionalIncludeDirectories) Console true + RequireAdministrator @@ -136,6 +138,11 @@ + + + {1584bad4-dbec-43d2-bc06-08c23f02489a} + + diff --git a/NetTunnelSDKTestApp/RouteTable.cpp b/NetTunnelSDKTestApp/RouteTable.cpp index ed10fd7..3495aa0 100644 --- a/NetTunnelSDKTestApp/RouteTable.cpp +++ b/NetTunnelSDKTestApp/RouteTable.cpp @@ -150,4 +150,93 @@ int ShowRouteTable() { FREE(pIpForwardTable); return 1; } +} + +int SetRouteTable() { + + // Declare and initialize variables. + + /* variables used for SetIfForwardEntry */ + + PMIB_IPFORWARDTABLE pIpForwardTable = NULL; + PMIB_IPFORWARDROW pRow = NULL; + DWORD dwSize = 0; + BOOL bOrder = FALSE; + DWORD dwStatus = 0; + DWORD NewGateway = 0xDDBBCCAA; // this is in host order Ip Address AA.BB.CC.DD is DDCCBBAA + DWORD i; + + // Find out how big our buffer needs to be. + dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder); + if (dwStatus == ERROR_INSUFFICIENT_BUFFER) { + // Allocate the memory for the table + pIpForwardTable = (PMIB_IPFORWARDTABLE)malloc(dwSize); + if (pIpForwardTable == NULL) { + printf("Unable to allocate memory for the IPFORWARDTALE\n"); + exit(1); + } + // Now get the table. + dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder); + } + + if (dwStatus != ERROR_SUCCESS) { + printf("getIpForwardTable failed.\n"); + if (pIpForwardTable) { + free(pIpForwardTable); + } + exit(1); + } + // Search for the row in the table we want. The default gateway has a destination + // of 0.0.0.0. Notice that we continue looking through the table, but copy only + // one row. This is so that if there happen to be multiple default gateways, we can + // be sure to delete them all. + for (i = 0; i < pIpForwardTable->dwNumEntries; i++) { + if (pIpForwardTable->table[i].dwForwardDest == 0) { + // We have found the default gateway. + if (!pRow) { + // Allocate some memory to store the row in. This is easier than filling + // in the row structure ourselves, and we can be sure to change only the + // gateway address. + pRow = (PMIB_IPFORWARDROW)malloc(sizeof(MIB_IPFORWARDROW)); + if (!pRow) { + printf("Malloc failed. Out of memory.\n"); + exit(1); + } + // Copy the row. + memcpy(pRow, &(pIpForwardTable->table[i]), sizeof(MIB_IPFORWARDROW)); + } + // Delete the old default gateway entry. + dwStatus = DeleteIpForwardEntry(&(pIpForwardTable->table[i])); + + if (dwStatus != ERROR_SUCCESS) { + printf("Could not delete old gateway\n"); + exit(1); + } + } + } + + // Set the nexthop field to our new gateway. All the other properties of the route will + // be the same as they were previously. + pRow->dwForwardNextHop = NewGateway; + + // Create a new route entry for the default gateway. + dwStatus = SetIpForwardEntry(pRow); + + if (dwStatus == NO_ERROR) { + printf("Gateway changed successfully\n"); + } else if (dwStatus == ERROR_INVALID_PARAMETER) { + printf("Invalid parameter.\n"); + } else { + printf("Error: %d\n", dwStatus); + } + + // Free resources. + if (pIpForwardTable) { + free(pIpForwardTable); + } + if (pRow) { + free(pRow); + } + + return 0; } \ No newline at end of file diff --git a/NetTunnelSDKTestApp/common.h b/NetTunnelSDKTestApp/common.h index 7bcafef..7fead9d 100644 --- a/NetTunnelSDKTestApp/common.h +++ b/NetTunnelSDKTestApp/common.h @@ -2,4 +2,5 @@ int ShowRouteTable(); int NetShare(); int GetInterface(); -void CryptoExample(); \ No newline at end of file +void CryptoExample(); +int SetRouteTable(); \ No newline at end of file diff --git a/NetTunnelSDKTestApp/x64/Debug/CryptoExample.obj b/NetTunnelSDKTestApp/x64/Debug/CryptoExample.obj index 049743d..963520f 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/CryptoExample.obj and b/NetTunnelSDKTestApp/x64/Debug/CryptoExample.obj differ diff --git a/NetTunnelSDKTestApp/x64/Debug/NetInterface.obj b/NetTunnelSDKTestApp/x64/Debug/NetInterface.obj index 3709954..b86762a 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/NetInterface.obj and b/NetTunnelSDKTestApp/x64/Debug/NetInterface.obj differ diff --git a/NetTunnelSDKTestApp/x64/Debug/NetShare.obj b/NetTunnelSDKTestApp/x64/Debug/NetShare.obj index 3ebaaed..3c43dee 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/NetShare.obj and b/NetTunnelSDKTestApp/x64/Debug/NetShare.obj differ diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/CL.command.1.tlog b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/CL.command.1.tlog index 636a754..1049f93 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/CL.command.1.tlog and b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/CL.command.1.tlog differ diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/CL.read.1.tlog b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/CL.read.1.tlog index 8b0dd18..7335a97 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/CL.read.1.tlog and b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/CL.read.1.tlog differ diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/CL.write.1.tlog b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/CL.write.1.tlog index fc7e4e5..ca22603 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/CL.write.1.tlog and b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/CL.write.1.tlog differ diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/NetTunnelSDKTestApp.write.1u.tlog b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/NetTunnelSDKTestApp.write.1u.tlog new file mode 100644 index 0000000..9d7cfab Binary files /dev/null and b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/NetTunnelSDKTestApp.write.1u.tlog differ diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/link.command.1.tlog b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/link.command.1.tlog index bc39cb8..0c1e5c2 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/link.command.1.tlog and b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/link.command.1.tlog differ diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/link.read.1.tlog b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/link.read.1.tlog index fda8364..ee64512 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/link.read.1.tlog and b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/link.read.1.tlog differ diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/link.write.1.tlog b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/link.write.1.tlog index 8364951..7019bb1 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/link.write.1.tlog and b/NetTunnelSDKTestApp/x64/Debug/NetTunne.9f44f41e.tlog/link.write.1.tlog differ diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.Build.CppClean.log b/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.Build.CppClean.log index fdb6316..fbfebf5 100644 --- a/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.Build.CppClean.log +++ b/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.Build.CppClean.log @@ -4,9 +4,11 @@ c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsd c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsdktestapp\x64\debug\nettunnelsdktestapp.obj c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsdktestapp\x64\debug\netshare.obj c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsdktestapp\x64\debug\netinterface.obj +c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsdktestapp\x64\debug\cryptoexample.obj c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsdktestapp\x64\debug\nettunnelsdktestapp.ilk c:\users\huangxin\documents\development\visual_studio\tunnel_windows\x64\debug\nettunnelsdktestapp.exe c:\users\huangxin\documents\development\visual_studio\tunnel_windows\x64\debug\nettunnelsdktestapp.pdb +c:\users\huangxin\documents\development\visual_studio\tunnel_windows\x64\debug\fmtd.dll c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsdktestapp\x64\debug\nettunne.9f44f41e.tlog\cl.command.1.tlog c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsdktestapp\x64\debug\nettunne.9f44f41e.tlog\cl.items.tlog c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsdktestapp\x64\debug\nettunne.9f44f41e.tlog\cl.read.1.tlog @@ -14,3 +16,4 @@ c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsd c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsdktestapp\x64\debug\nettunne.9f44f41e.tlog\link.command.1.tlog c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsdktestapp\x64\debug\nettunne.9f44f41e.tlog\link.read.1.tlog c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsdktestapp\x64\debug\nettunne.9f44f41e.tlog\link.write.1.tlog +c:\users\huangxin\documents\development\visual_studio\tunnel_windows\nettunnelsdktestapp\x64\debug\nettunne.9f44f41e.tlog\nettunnelsdktestapp.write.1u.tlog diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.exe.recipe b/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.exe.recipe index bbcc6a2..21bb5de 100644 --- a/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.exe.recipe +++ b/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.exe.recipe @@ -1,6 +1,9 @@  + + C:\Users\HuangXin\Documents\development\visual_studio\tunnel_windows\x64\Debug\NetTunnelSDK.dll + C:\Users\HuangXin\Documents\development\visual_studio\tunnel_windows\x64\Debug\NetTunnelSDKTestApp.exe diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.ilk b/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.ilk index 8ccb35a..c2c88bd 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.ilk and b/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.ilk differ diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.log b/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.log index c3d3c58..5faa23c 100644 --- a/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.log +++ b/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.log @@ -1,2 +1,2 @@ - CryptoExample.cpp + NetTunnelSDKTestApp.cpp NetTunnelSDKTestApp.vcxproj -> C:\Users\HuangXin\Documents\development\visual_studio\tunnel_windows\x64\Debug\NetTunnelSDKTestApp.exe diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.obj b/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.obj index 2e8e51b..cad8364 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.obj and b/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.obj differ diff --git a/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.vcxproj.FileListAbsolute.txt b/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.vcxproj.FileListAbsolute.txt index e69de29..6d818c5 100644 --- a/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.vcxproj.FileListAbsolute.txt +++ b/NetTunnelSDKTestApp/x64/Debug/NetTunnelSDKTestApp.vcxproj.FileListAbsolute.txt @@ -0,0 +1 @@ +C:\Users\HuangXin\Documents\development\visual_studio\tunnel_windows\NetTunnelSDKTestApp\x64\Debug\NetTunnelSDKTestApp.vcxproj.CopyComplete diff --git a/NetTunnelSDKTestApp/x64/Debug/RouteTable.obj b/NetTunnelSDKTestApp/x64/Debug/RouteTable.obj index 3495cb4..3f74e75 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/RouteTable.obj and b/NetTunnelSDKTestApp/x64/Debug/RouteTable.obj differ diff --git a/NetTunnelSDKTestApp/x64/Debug/vc143.idb b/NetTunnelSDKTestApp/x64/Debug/vc143.idb index 2e04e8b..717d953 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/vc143.idb and b/NetTunnelSDKTestApp/x64/Debug/vc143.idb differ diff --git a/NetTunnelSDKTestApp/x64/Debug/vc143.pdb b/NetTunnelSDKTestApp/x64/Debug/vc143.pdb index 9e5df43..ce4baba 100644 Binary files a/NetTunnelSDKTestApp/x64/Debug/vc143.pdb and b/NetTunnelSDKTestApp/x64/Debug/vc143.pdb differ diff --git a/NetTunnelSDKTestApp/x64/Debug/vcpkg.applocal.log b/NetTunnelSDKTestApp/x64/Debug/vcpkg.applocal.log index e02abfc..b1521ea 100644 --- a/NetTunnelSDKTestApp/x64/Debug/vcpkg.applocal.log +++ b/NetTunnelSDKTestApp/x64/Debug/vcpkg.applocal.log @@ -1 +1,2 @@  +C:\Users\HuangXin\Documents\development\visual_studio\tunnel_windows\x64\Debug\fmtd.dll diff --git a/TestNetTunnelSDK/TestNetTunnelSDK.cpp b/TestNetTunnelSDK/TestNetTunnelSDK.cpp index ea5b0e1..e72c951 100644 --- a/TestNetTunnelSDK/TestNetTunnelSDK.cpp +++ b/TestNetTunnelSDK/TestNetTunnelSDK.cpp @@ -109,17 +109,19 @@ public: TEST_METHOD(TestSetInterfacePrivate) { Assert::AreEqual(RET_OK, SetInterfacePrivate(TEXT("wg_cli_435"), true)); } - TEST_METHOD(TestIsWireGuardServerInstalled) { - bool bRet; - Assert::AreEqual(RET_OK, IsWireGuardServerInstalled(&bRet)); - Assert::AreEqual(true, bRet); - } + TEST_METHOD(TestWireGuardNetConnectionSharingEnable) { Assert::AreEqual(RET_OK, WireGuardNetConnectionSharingEnable()); } #endif + TEST_METHOD(TestIsWireGuardServerRunning) { + bool bRet; + Assert::AreEqual(RET_OK, IsWireGuardServerRunning(TEXT("tunnel_svr"), &bRet)); + Assert::AreEqual(false, bRet); + } + TEST_METHOD(TestCalcFileHash) { TCHAR outHash[MAX_PATH] = {0}; @@ -128,7 +130,7 @@ public: } TEST_METHOD(TestWireGuardInstallServerService) { - Assert::AreEqual(RET_OK, WireGuardInstallServerService(true)); + Assert::AreEqual(RET_OK, WireGuardInstallDefaultServerService(true)); } TEST_METHOD(TestGetInternetConnectAdaptersIndex) { @@ -150,11 +152,18 @@ public: } TEST_METHOD(TestUserLogin) { - Assert::AreEqual(RET_OK, UserLogin(TEXT("admin"), TEXT("123455"))); + //Assert::AreEqual(RET_OK, GetUserClientConfigure(TEXT("admin"), TEXT("123455"))); + } TEST_METHOD(TestProtoGetUserConfigure) { Assert::AreEqual(RET_OK, ProtoGetUserConfigure("admin", "asfdsafdladf083asldf+=")); } + + TEST_METHOD(TestSetClientConfige) { + Assert::AreEqual(RET_OK, + SetClientConfige("6BWnmkCJqJC5iNoCEZWTxwGNG7qwkxFoVgAk4DoIKCk=", + "192.168.100.210/24", "10.10.10.1")); + } }; } \ No newline at end of file diff --git a/tunnel_windows.sln b/tunnel_windows.sln index b8f3e1f..f884f4e 100644 --- a/tunnel_windows.sln +++ b/tunnel_windows.sln @@ -15,8 +15,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestNetTunnelSDK", "TestNet {1584BAD4-DBEC-43D2-BC06-08C23F02489A} = {1584BAD4-DBEC-43D2-BC06-08C23F02489A} EndProjectSection EndProject -Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Installer", "Installer\Installer.vdproj", "{94DDED89-37AA-4CC2-8B3B-9562854DAAE8}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NetTunnelSDKTestApp", "NetTunnelSDKTestApp\NetTunnelSDKTestApp.vcxproj", "{9F44F41E-FACF-472D-A382-A40D0A84DB2C}" ProjectSection(ProjectDependencies) = postProject {1584BAD4-DBEC-43D2-BC06-08C23F02489A} = {1584BAD4-DBEC-43D2-BC06-08C23F02489A} @@ -68,12 +66,6 @@ Global {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 - {94DDED89-37AA-4CC2-8B3B-9562854DAAE8}.Debug|Any CPU.ActiveCfg = Debug - {94DDED89-37AA-4CC2-8B3B-9562854DAAE8}.Debug|x64.ActiveCfg = Debug - {94DDED89-37AA-4CC2-8B3B-9562854DAAE8}.Debug|x86.ActiveCfg = Debug - {94DDED89-37AA-4CC2-8B3B-9562854DAAE8}.Release|Any CPU.ActiveCfg = Release - {94DDED89-37AA-4CC2-8B3B-9562854DAAE8}.Release|x64.ActiveCfg = Release - {94DDED89-37AA-4CC2-8B3B-9562854DAAE8}.Release|x86.ActiveCfg = Release {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