├── LICENSE
├── README.md
├── local-server-apps
├── Web.config
├── rule.ashx
├── transmit.ashx
└── url-info.html
├── release
├── iss
│ ├── scripts
│ │ ├── isxdl
│ │ │ ├── chinese.ini
│ │ │ ├── english.ini
│ │ │ ├── isxdl.dll
│ │ │ └── isxdl.iss
│ │ ├── products.iss
│ │ └── products
│ │ │ ├── dotnetfx45full.iss
│ │ │ ├── dotnetfxversion.iss
│ │ │ ├── fileversion.iss
│ │ │ ├── msi31.iss
│ │ │ ├── stringversion.iss
│ │ │ └── winversion.iss
│ ├── x-wall-full.iss
│ └── x-wall.iss
├── plonk.exe
├── version
├── version(suggest).js
├── version-v2.xml
├── version.js
├── version_nogoa.js
├── x-wall-setup-full.exe
├── x-wall-setup.exe
└── x-wall-setup.zip
├── rules
├── gfwlist.action
├── gfwlist2privoxy.js
├── rules
├── rules-v2
├── updater.js
└── x-list.txt
└── src
├── App.xaml
├── App.xaml.cs
├── Classes
├── AppSetting.cs
├── GAESimulator.cs
├── GoAgent.cs
├── NotificationController.cs
├── Operation.cs
├── Plink.cs
├── Privoxy.cs
├── Profiles.cs
├── Rules.cs
├── Settings.cs
└── UIBinding.cs
├── CustomRulesEditor.xaml
├── CustomRulesEditor.xaml.cs
├── GAEWizard.xaml
├── GAEWizard.xaml.cs
├── Icons
├── main.ico
├── tray.error.ico
├── tray.ok.ico
├── tray.processing.ico
└── tray.stopped.ico
├── Langs
├── Default.xaml
└── zh.xaml
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
├── Settings.settings
└── app.manifest
├── ShowUpdateLog.xaml
├── ShowUpdateLog.xaml.cs
├── X-Wall.csproj
├── X-Wall.csproj.user
├── X-Wall.sln
├── X-Wall.suo
├── X-Wall.v12.suo
├── app.config
├── copy.bat
├── mgwz.dll
├── plink.exe
├── plonk.exe
├── post-build.txt
├── privoxy.exe
└── resources
├── about-logo.png
├── icon-error.ico
├── icon.ico
├── logo-error.png
├── logo.png
├── privoxy-templates
├── connect-failed
├── connection-timeout
├── default
├── forwarding-failed
├── lang-helper.js
├── mod-content-begin
├── mod-content-end
├── mod-gfw-operation
├── mod-head
├── mod-head-error
├── mod-header
├── mod-header-error
├── mod-lang-helper
├── no-server-data
├── no-such-domain
└── show-url-info
├── spirits.png
└── style.css
/LICENSE:
--------------------------------------------------------------------------------
1 | The Artistic License 2.0
2 |
3 | Copyright (c) 2015 LunaDream
4 |
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | This license establishes the terms under which a given free software
11 | Package may be copied, modified, distributed, and/or redistributed.
12 | The intent is that the Copyright Holder maintains some artistic
13 | control over the development of that Package while still keeping the
14 | Package available as open source and free software.
15 |
16 | You are always permitted to make arrangements wholly outside of this
17 | license directly with the Copyright Holder of a given Package. If the
18 | terms of this license do not permit the full use that you propose to
19 | make of the Package, you should contact the Copyright Holder and seek
20 | a different licensing arrangement.
21 |
22 | Definitions
23 |
24 | "Copyright Holder" means the individual(s) or organization(s)
25 | named in the copyright notice for the entire Package.
26 |
27 | "Contributor" means any party that has contributed code or other
28 | material to the Package, in accordance with the Copyright Holder's
29 | procedures.
30 |
31 | "You" and "your" means any person who would like to copy,
32 | distribute, or modify the Package.
33 |
34 | "Package" means the collection of files distributed by the
35 | Copyright Holder, and derivatives of that collection and/or of
36 | those files. A given Package may consist of either the Standard
37 | Version, or a Modified Version.
38 |
39 | "Distribute" means providing a copy of the Package or making it
40 | accessible to anyone else, or in the case of a company or
41 | organization, to others outside of your company or organization.
42 |
43 | "Distributor Fee" means any fee that you charge for Distributing
44 | this Package or providing support for this Package to another
45 | party. It does not mean licensing fees.
46 |
47 | "Standard Version" refers to the Package if it has not been
48 | modified, or has been modified only in ways explicitly requested
49 | by the Copyright Holder.
50 |
51 | "Modified Version" means the Package, if it has been changed, and
52 | such changes were not explicitly requested by the Copyright
53 | Holder.
54 |
55 | "Original License" means this Artistic License as Distributed with
56 | the Standard Version of the Package, in its current version or as
57 | it may be modified by The Perl Foundation in the future.
58 |
59 | "Source" form means the source code, documentation source, and
60 | configuration files for the Package.
61 |
62 | "Compiled" form means the compiled bytecode, object code, binary,
63 | or any other form resulting from mechanical transformation or
64 | translation of the Source form.
65 |
66 |
67 | Permission for Use and Modification Without Distribution
68 |
69 | (1) You are permitted to use the Standard Version and create and use
70 | Modified Versions for any purpose without restriction, provided that
71 | you do not Distribute the Modified Version.
72 |
73 |
74 | Permissions for Redistribution of the Standard Version
75 |
76 | (2) You may Distribute verbatim copies of the Source form of the
77 | Standard Version of this Package in any medium without restriction,
78 | either gratis or for a Distributor Fee, provided that you duplicate
79 | all of the original copyright notices and associated disclaimers. At
80 | your discretion, such verbatim copies may or may not include a
81 | Compiled form of the Package.
82 |
83 | (3) You may apply any bug fixes, portability changes, and other
84 | modifications made available from the Copyright Holder. The resulting
85 | Package will still be considered the Standard Version, and as such
86 | will be subject to the Original License.
87 |
88 |
89 | Distribution of Modified Versions of the Package as Source
90 |
91 | (4) You may Distribute your Modified Version as Source (either gratis
92 | or for a Distributor Fee, and with or without a Compiled form of the
93 | Modified Version) provided that you clearly document how it differs
94 | from the Standard Version, including, but not limited to, documenting
95 | any non-standard features, executables, or modules, and provided that
96 | you do at least ONE of the following:
97 |
98 | (a) make the Modified Version available to the Copyright Holder
99 | of the Standard Version, under the Original License, so that the
100 | Copyright Holder may include your modifications in the Standard
101 | Version.
102 |
103 | (b) ensure that installation of your Modified Version does not
104 | prevent the user installing or running the Standard Version. In
105 | addition, the Modified Version must bear a name that is different
106 | from the name of the Standard Version.
107 |
108 | (c) allow anyone who receives a copy of the Modified Version to
109 | make the Source form of the Modified Version available to others
110 | under
111 |
112 | (i) the Original License or
113 |
114 | (ii) a license that permits the licensee to freely copy,
115 | modify and redistribute the Modified Version using the same
116 | licensing terms that apply to the copy that the licensee
117 | received, and requires that the Source form of the Modified
118 | Version, and of any works derived from it, be made freely
119 | available in that license fees are prohibited but Distributor
120 | Fees are allowed.
121 |
122 |
123 | Distribution of Compiled Forms of the Standard Version
124 | or Modified Versions without the Source
125 |
126 | (5) You may Distribute Compiled forms of the Standard Version without
127 | the Source, provided that you include complete instructions on how to
128 | get the Source of the Standard Version. Such instructions must be
129 | valid at the time of your distribution. If these instructions, at any
130 | time while you are carrying out such distribution, become invalid, you
131 | must provide new instructions on demand or cease further distribution.
132 | If you provide valid instructions or cease distribution within thirty
133 | days after you become aware that the instructions are invalid, then
134 | you do not forfeit any of your rights under this license.
135 |
136 | (6) You may Distribute a Modified Version in Compiled form without
137 | the Source, provided that you comply with Section 4 with respect to
138 | the Source of the Modified Version.
139 |
140 |
141 | Aggregating or Linking the Package
142 |
143 | (7) You may aggregate the Package (either the Standard Version or
144 | Modified Version) with other packages and Distribute the resulting
145 | aggregation provided that you do not charge a licensing fee for the
146 | Package. Distributor Fees are permitted, and licensing fees for other
147 | components in the aggregation are permitted. The terms of this license
148 | apply to the use and Distribution of the Standard or Modified Versions
149 | as included in the aggregation.
150 |
151 | (8) You are permitted to link Modified and Standard Versions with
152 | other works, to embed the Package in a larger work of your own, or to
153 | build stand-alone binary or bytecode versions of applications that
154 | include the Package, and Distribute the result without restriction,
155 | provided the result does not expose a direct interface to the Package.
156 |
157 |
158 | Items That are Not Considered Part of a Modified Version
159 |
160 | (9) Works (including, but not limited to, modules and scripts) that
161 | merely extend or make use of the Package, do not, by themselves, cause
162 | the Package to be a Modified Version. In addition, such works are not
163 | considered parts of the Package itself, and are not subject to the
164 | terms of this license.
165 |
166 |
167 | General Provisions
168 |
169 | (10) Any use, modification, and distribution of the Standard or
170 | Modified Versions is governed by this Artistic License. By using,
171 | modifying or distributing the Package, you accept this license. Do not
172 | use, modify, or distribute the Package, if you do not accept this
173 | license.
174 |
175 | (11) If your Modified Version has been derived from a Modified
176 | Version made by someone other than you, you are nevertheless required
177 | to ensure that your Modified Version complies with the requirements of
178 | this license.
179 |
180 | (12) This license does not grant you the right to use any trademark,
181 | service mark, tradename, or logo of the Copyright Holder.
182 |
183 | (13) This license includes the non-exclusive, worldwide,
184 | free-of-charge patent license to make, have made, use, offer to sell,
185 | sell, import and otherwise transfer the Package with respect to any
186 | patent claims licensable by the Copyright Holder that are necessarily
187 | infringed by the Package. If you institute patent litigation
188 | (including a cross-claim or counterclaim) against any party alleging
189 | that the Package constitutes direct or contributory patent
190 | infringement, then this Artistic License to you shall terminate on the
191 | date that such litigation is filed.
192 |
193 | (14) Disclaimer of Warranty:
194 | THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
195 | IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
196 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
197 | NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
198 | LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
199 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
200 | DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
201 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #XWall
2 |
3 | ~~Please visit [xwall.im/en-US/](http://xwall.im/en-US/) for more information.~~
4 | ~~请访问 [xwall.im](http://xwall.im) 了解更多.~~
5 |
6 | 使用说明请见[这里](https://github.com/lunarlove/XWall/wiki/%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E).
7 |
8 | XWall 目前估计只有几百用户, 大家如果觉得好用的话, 欢迎在博客 (服务器在墙外要考虑被墙的风险) 或者 SNS 上推荐, 有原创教程尤佳.
9 |
10 | 
11 |
12 | 另外顺便维护了供 Privoxy 使用的 GFWList (action 文件), 需要的同学可以下载, 默认是转发 1080 端口的 SOCKSv5 代理, 其他请参照 Privoxy 的手册自行修改了.
13 | [Privoxy GFWList Action File](https://raw.github.com/lunarlove/XWall/master/rules/gfwlist.action)
14 |
--------------------------------------------------------------------------------
/local-server-apps/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
46 |
47 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/local-server-apps/rule.ashx:
--------------------------------------------------------------------------------
1 | <%@ WebHandler Language="C#" Class="Rule" %>
2 |
3 | using System;
4 | using System.Web;
5 | using System.IO;
6 |
7 | public class Rule : IHttpHandler {
8 |
9 | public void ProcessRequest (HttpContext context) {
10 | var req = context.Request;
11 | var res = context.Response;
12 | var query = req.QueryString;
13 |
14 | var root = context.Server.MapPath("~/") + @"..\configs\";
15 | string file = "";
16 | string rule = "";
17 |
18 | if (query["new"] != null) {
19 | file = root + "new-rule-cmd";
20 | rule = query["new"];
21 | }
22 | else if (query["del"] != null) {
23 | file = root + "del-rule-cmd";
24 | rule = query["del"];
25 | }
26 |
27 | var ruleCommandWatcher = new FileSystemWatcher(Path.GetDirectoryName(file), Path.GetFileName(file));
28 | File.WriteAllText(file, rule);
29 | var result = (!ruleCommandWatcher.WaitForChanged(WatcherChangeTypes.Deleted, 10000).TimedOut).ToString().ToLower();
30 |
31 | string text;
32 | if (query["callback"] != null) {
33 | res.ContentType = "text/javascript";
34 | text = query["callback"] + "(" + result + ");";
35 | }
36 | else {
37 | if (query["type"] != null) {
38 | res.ContentType = query["type"];
39 | }
40 | text = result.ToString();
41 | }
42 | res.Write(text);
43 | }
44 |
45 | public bool IsReusable {
46 | get {
47 | return false;
48 | }
49 | }
50 |
51 | }
--------------------------------------------------------------------------------
/local-server-apps/transmit.ashx:
--------------------------------------------------------------------------------
1 | <%@ WebHandler Language="C#" Class="Transmit" %>
2 |
3 | using System;
4 | using System.Web;
5 |
6 | public class Transmit : IHttpHandler {
7 |
8 | public void ProcessRequest (HttpContext context) {
9 | var req = context.Request;
10 | var res = context.Response;
11 | var query = req.QueryString;
12 |
13 | if (query["file"] != null) {
14 | if (query["type"] != null) {
15 | res.ContentType = query["type"];
16 | }
17 | if (query["nocache"] != null) {
18 | res.Cache.SetCacheability(HttpCacheability.NoCache);
19 | res.Cache.SetNoStore();
20 | }
21 | res.BinaryWrite(System.IO.File.ReadAllBytes(context.Server.MapPath("~/") + @"..\resources\" + query["file"]));
22 | }
23 | else if (query["config"] != null) {
24 | string text;
25 | var config = System.IO.File.ReadAllText(context.Server.MapPath("~/") + @"..\configs\" + query["config"]);
26 | if (query["callback"] != null) {
27 | res.ContentType = "text/javascript";
28 | text = query["callback"] + "(" + config + ");";
29 | }
30 | else {
31 | if (query["type"] != null) {
32 | res.ContentType = query["type"];
33 | }
34 | text = config;
35 | }
36 | res.Cache.SetCacheability(HttpCacheability.NoCache);
37 | res.Cache.SetNoStore();
38 | res.Write(text);
39 | }
40 | }
41 |
42 | public bool IsReusable {
43 | get {
44 | return false;
45 | }
46 | }
47 |
48 | }
--------------------------------------------------------------------------------
/local-server-apps/url-info.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
26 |
27 |
28 |
29 |
30 |
View Whether a URL Will Be Forwarded
31 |
32 |
Forward Settings:
33 |
Fetching...
34 |
35 |
Please enter a URL:
36 |
42 |
43 |
44 |
查看 URL 是否会被转发
45 |
46 |
转发设置:
47 |
获取中...
48 |
49 |
请输入一个 URL:
50 |
56 |
57 |
58 |
76 |
77 |
80 |
81 |
153 |
154 |
155 |
156 |
--------------------------------------------------------------------------------
/release/iss/scripts/isxdl/chinese.ini:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/release/iss/scripts/isxdl/chinese.ini
--------------------------------------------------------------------------------
/release/iss/scripts/isxdl/english.ini:
--------------------------------------------------------------------------------
1 | [strings]
2 | ; General
3 | 100=File Download
4 | 101=Do you want to cancel the download?
5 | 102=%1 (%2 of %3)
6 | 103=%1 KB
7 | 104=%1 KB of %2 KB (%3%)
8 |
9 | ; Status information
10 | 110=Getting file information...
11 | 111=Redirecting to %1
12 | 112=Sending request...
13 | 113=Resolving %1
14 | 114=Connected to %1
15 | 115=Receiving...
16 | 116=Connecting to %1
17 |
18 | ; Error messages
19 | 120=Error connecting to Internet.\n\n%1
20 | 121=Error opening %1.\n\nThe server returned status code %2.
21 | 122=Error reading URL.\n\n%1
22 | 123=Error writing file %1.\n\n%2
23 | 124=Error opening file %1.\n\n%2
24 | 125='%1' is an invalid URL.
25 | 126=Error opening %1.\n\n%2
26 | 127=Error sending request.\n\n%1
27 | 128=Unsupported protocol. Only HTTP and FTP protocols are supported.
28 | 129=Failed to connect to %1.\n\n%2
29 | 130=Failed to query status code.\n\n%1
30 | 131=Error requesting file.\n\n%1
31 |
32 | ; Other
33 | 144=About...
34 | 146=Download
35 | 147=Setup is now downloading additional files to your computer.
36 |
37 | ; labels
38 | 160=File:
39 | 161=Speed:
40 | 162=Status:
41 | 163=Elapsed Time:
42 | 164=Remaining Time:
43 | 165=Current File:
44 | 166=Overall Progress:
45 | 167=Cancel
46 | 168=OK
47 | 169=User Name and Password
48 | 170=User Name:
49 | 171=Password:
50 |
--------------------------------------------------------------------------------
/release/iss/scripts/isxdl/isxdl.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/release/iss/scripts/isxdl/isxdl.dll
--------------------------------------------------------------------------------
/release/iss/scripts/isxdl/isxdl.iss:
--------------------------------------------------------------------------------
1 | [Files]
2 | Source: "scripts\isxdl\isxdl.dll"; Flags: dontcopy
3 |
4 | [Code]
5 | //replace PAnsiChar with PChar on non-unicode Inno Setup
6 | procedure isxdl_AddFile(URL, Filename: PAnsiChar);
7 | external 'isxdl_AddFile@files:isxdl.dll stdcall';
8 |
9 | function isxdl_DownloadFiles(hWnd: Integer): Integer;
10 | external 'isxdl_DownloadFiles@files:isxdl.dll stdcall';
11 |
12 | //replace PAnsiChar with PChar on non-unicode Inno Setup
13 | function isxdl_SetOption(Option, Value: PAnsiChar): Integer;
14 | external 'isxdl_SetOption@files:isxdl.dll stdcall';
15 |
--------------------------------------------------------------------------------
/release/iss/scripts/products.iss:
--------------------------------------------------------------------------------
1 | #include "isxdl\isxdl.iss"
2 |
3 | [CustomMessages]
4 | DependenciesDir=MyProgramDependencies
5 |
6 | en.depdownload_msg=The following applications are required before setup can continue:%n%n%1%nDownload and install now?
7 |
8 | en.depdownload_memo_title=Download dependencies
9 |
10 | en.depinstall_memo_title=Install dependencies
11 |
12 |
13 | en.depinstall_title=Installing dependencies
14 |
15 | en.depinstall_description=Please wait while Setup installs dependencies on your computer.
16 |
17 | en.depinstall_status=Installing %1...
18 |
19 | en.depinstall_missing=%1 must be installed before setup can continue. Please install %1 and run Setup again.
20 |
21 | en.depinstall_error=An error occured while installing the dependencies. Please restart the computer and run the setup again or install the following dependencies manually:%n
22 |
23 | en.isxdl_langfile=
24 |
25 | [Files]
26 | Source: "scripts\isxdl\chinese.ini"; Flags: dontcopy
27 |
28 | [Code]
29 | type
30 | TProduct = record
31 | File: String;
32 | Title: String;
33 | Parameters: String;
34 | InstallClean : boolean;
35 | MustRebootAfter : boolean;
36 | end;
37 |
38 | InstallResult = (InstallSuccessful, InstallRebootRequired, InstallError);
39 |
40 | var
41 | installMemo, downloadMemo, downloadMessage: string;
42 | products: array of TProduct;
43 | delayedReboot: boolean;
44 | DependencyPage: TOutputProgressWizardPage;
45 |
46 |
47 | procedure AddProduct(FileName, Parameters, Title, Size, URL: string; InstallClean : boolean; MustRebootAfter : boolean);
48 | var
49 | path: string;
50 | i: Integer;
51 | begin
52 | installMemo := installMemo + '%1' + Title + #13;
53 |
54 | path := ExpandConstant('{src}{\}') + CustomMessage('DependenciesDir') + '\' + FileName;
55 | if not FileExists(path) then begin
56 | path := ExpandConstant('{tmp}{\}') + FileName;
57 |
58 | isxdl_AddFile(URL, path);
59 |
60 | downloadMemo := downloadMemo + '%1' + Title + #13;
61 | downloadMessage := downloadMessage + ' ' + Title + ' (' + Size + ')' + #13;
62 | end;
63 |
64 | i := GetArrayLength(products);
65 | SetArrayLength(products, i + 1);
66 | products[i].File := path;
67 | products[i].Title := Title;
68 | products[i].Parameters := Parameters;
69 | products[i].InstallClean := InstallClean;
70 | products[i].MustRebootAfter := MustRebootAfter;
71 | end;
72 |
73 | function SmartExec(prod : TProduct; var ResultCode : Integer) : boolean;
74 | begin
75 | if (LowerCase(Copy(prod.File,Length(prod.File)-2,3)) = 'exe') then begin
76 | Result := Exec(prod.File, prod.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
77 | end else begin
78 | Result := ShellExec('', prod.File, prod.Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
79 | end;
80 | end;
81 |
82 | function PendingReboot : boolean;
83 | var names: String;
84 | begin
85 | if (RegQueryMultiStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager', 'PendingFileRenameOperations', names)) then begin
86 | Result := true;
87 | end else if ((RegQueryMultiStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager', 'SetupExecute', names)) and (names <> '')) then begin
88 | Result := true;
89 | end else begin
90 | Result := false;
91 | end;
92 | end;
93 |
94 | function InstallProducts: InstallResult;
95 | var
96 | ResultCode, i, productCount, finishCount: Integer;
97 | begin
98 | Result := InstallSuccessful;
99 | productCount := GetArrayLength(products);
100 |
101 | if productCount > 0 then begin
102 | DependencyPage := CreateOutputProgressPage(CustomMessage('depinstall_title'), CustomMessage('depinstall_description'));
103 | DependencyPage.Show;
104 |
105 | for i := 0 to productCount - 1 do begin
106 | if (products[i].InstallClean and (delayedReboot or PendingReboot())) then begin
107 | Result := InstallRebootRequired;
108 | break;
109 | end;
110 |
111 | DependencyPage.SetText(FmtMessage(CustomMessage('depinstall_status'), [products[i].Title]), '');
112 | DependencyPage.SetProgress(i, productCount);
113 |
114 | if SmartExec(products[i], ResultCode) then begin
115 | //setup executed; ResultCode contains the exit code
116 | //MsgBox(products[i].Title + ' install executed. Result Code: ' + IntToStr(ResultCode), mbInformation, MB_OK);
117 | if (products[i].MustRebootAfter) then begin
118 | //delay reboot after install if we installed the last dependency anyways
119 | if (i = productCount - 1) then begin
120 | delayedReboot := true;
121 | end else begin
122 | Result := InstallRebootRequired;
123 | end;
124 | break;
125 | end else if (ResultCode = 0) then begin
126 | finishCount := finishCount + 1;
127 | end else if (ResultCode = 3010) then begin
128 | //ResultCode 3010: A restart is required to complete the installation. This message indicates success.
129 | delayedReboot := true;
130 | finishCount := finishCount + 1;
131 | end else begin
132 | Result := InstallError;
133 | break;
134 | end;
135 | end else begin
136 | //MsgBox(products[i].Title + ' install failed. Result Code: ' + IntToStr(ResultCode), mbInformation, MB_OK);
137 | Result := InstallError;
138 | break;
139 | end;
140 | end;
141 |
142 | //only leave not installed products for error message
143 | for i := 0 to productCount - finishCount - 1 do begin
144 | products[i] := products[i+finishCount];
145 | end;
146 | SetArrayLength(products, productCount - finishCount);
147 |
148 | DependencyPage.Hide;
149 | end;
150 | end;
151 |
152 | function PrepareToInstall(var NeedsRestart: boolean): String;
153 | var
154 | i: Integer;
155 | s: string;
156 | begin
157 | delayedReboot := false;
158 |
159 | //DelTree(ExpandConstant('{app}\templates'), True, True, True);
160 |
161 | case InstallProducts() of
162 | InstallError: begin
163 | s := CustomMessage('depinstall_error');
164 |
165 | for i := 0 to GetArrayLength(products) - 1 do begin
166 | s := s + #13 + ' ' + products[i].Title;
167 | end;
168 |
169 | Result := s;
170 | end;
171 | InstallRebootRequired: begin
172 | Result := products[0].Title;
173 | NeedsRestart := true;
174 |
175 | //write into the registry that the installer needs to be executed again after restart
176 | RegWriteStringValue(HKEY_CURRENT_USER, 'SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce', 'InstallBootstrap', ExpandConstant('{srcexe}'));
177 | end;
178 | end;
179 | end;
180 |
181 | function NeedRestart : boolean;
182 | begin
183 | if (delayedReboot) then
184 | Result := true;
185 | end;
186 |
187 | function UpdateReadyMemo(Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
188 | var
189 | s: string;
190 | begin
191 | if downloadMemo <> '' then
192 | s := s + CustomMessage('depdownload_memo_title') + ':' + NewLine + FmtMessage(downloadMemo, [Space]) + NewLine;
193 | if installMemo <> '' then
194 | s := s + CustomMessage('depinstall_memo_title') + ':' + NewLine + FmtMessage(installMemo, [Space]) + NewLine;
195 |
196 | s := s + MemoDirInfo + NewLine + NewLine + MemoGroupInfo
197 |
198 | if MemoTasksInfo <> '' then
199 | s := s + NewLine + NewLine + MemoTasksInfo;
200 |
201 | Result := s
202 | end;
203 |
204 | function NextButtonClick(CurPageID: Integer): boolean;
205 | begin
206 | Result := true;
207 |
208 | if CurPageID = wpReady then begin
209 | if downloadMemo <> '' then begin
210 | //change isxdl language only if it is not english because isxdl default language is already english
211 | if (ActiveLanguage() <> 'en') then begin
212 | ExtractTemporaryFile(CustomMessage('isxdl_langfile'));
213 | isxdl_SetOption('language', ExpandConstant('{tmp}{\}') + CustomMessage('isxdl_langfile'));
214 | end;
215 | //isxdl_SetOption('title', FmtMessage(SetupMessage(msgSetupWindowTitle), [CustomMessage('appname')]));
216 |
217 | if SuppressibleMsgBox(FmtMessage(CustomMessage('depdownload_msg'), [downloadMessage]), mbConfirmation, MB_YESNO, IDYES) = IDNO then
218 | Result := false
219 | else if isxdl_DownloadFiles(StrToInt(ExpandConstant('{wizardhwnd}'))) = 0 then
220 | Result := false;
221 | end;
222 | end;
223 | end;
224 |
225 | function IsX86: boolean;
226 | begin
227 | Result := (ProcessorArchitecture = paX86) or (ProcessorArchitecture = paUnknown);
228 | end;
229 |
230 | function IsX64: boolean;
231 | begin
232 | Result := Is64BitInstallMode and (ProcessorArchitecture = paX64);
233 | end;
234 |
235 | function IsIA64: boolean;
236 | begin
237 | Result := Is64BitInstallMode and (ProcessorArchitecture = paIA64);
238 | end;
239 |
240 | function GetString(x86, x64, ia64: String): String;
241 | begin
242 | if IsX64() and (x64 <> '') then begin
243 | Result := x64;
244 | end else if IsIA64() and (ia64 <> '') then begin
245 | Result := ia64;
246 | end else begin
247 | Result := x86;
248 | end;
249 | end;
250 |
251 | function GetArchitectureString(): String;
252 | begin
253 | if IsX64() then begin
254 | Result := '_x64';
255 | end else if IsIA64() then begin
256 | Result := '_ia64';
257 | end else begin
258 | Result := '';
259 | end;
260 | end;
--------------------------------------------------------------------------------
/release/iss/scripts/products/dotnetfx45full.iss:
--------------------------------------------------------------------------------
1 | // requires Windows Vista SP2, Windows 7 SP1, Windows 8, Windows 8.1, Windows Server 2008 SP2, Windows Server 2008 R2 SP1, Windows Server 2012 and Windows Server 2012 R2
2 | // requires Windows Installer 3.1
3 | // WARNING: express setup (downloads and installs the components depending on your OS) if you want to deploy it on cd or network download the full bootsrapper on website below
4 | // http://www.microsoft.com/downloads/details.aspx?FamilyID=ab99342f-5d1a-413d-8319-81da479ab0d7
5 |
6 | [CustomMessages]
7 | dotnetfx4full_title=.NET Framework 4.5.2
8 | dotnetfx4full_size=66.8MB
9 |
10 | [Code]
11 | const
12 | dotnetfx4full_url = 'http://download.microsoft.com/download/E/2/1/E21644B5-2DF2-47C2-91BD-63C560427900/NDP452-KB2901907-x86-x64-AllOS-ENU.exe';
13 |
14 | procedure dotnetfx45(MinVersion: integer);
15 | begin
16 | if (not netfxinstalled(NetFx45, '') or (netfxspversion(NetFx45, '') < MinVersion)) then
17 | AddProduct('dotnetfx4full' + GetArchitectureString() + '.exe',
18 | '/lang:enu /passive /norestart',
19 | CustomMessage('dotnetfx4full_title'),
20 | CustomMessage('dotnetfx4full_size'),
21 | dotnetfx4full_url,
22 | false, false);
23 | end;
--------------------------------------------------------------------------------
/release/iss/scripts/products/dotnetfxversion.iss:
--------------------------------------------------------------------------------
1 | [Code]
2 | type
3 | NetFXType = (NetFx10, NetFx11, NetFx20, NetFx30, NetFx35, NetFx40Client, NetFx40Full, NetFx45);
4 |
5 | const
6 | netfx11plus_reg = 'Software\Microsoft\NET Framework Setup\NDP\';
7 |
8 | function netfxinstalled(version: NetFXType; lcid: string): boolean;
9 | var
10 | regVersion: cardinal;
11 | regVersionString: string;
12 | begin
13 | if (lcid <> '') then
14 | lcid := '\' + lcid;
15 |
16 | if (version = NetFx10) then begin
17 | RegQueryStringValue(HKLM, 'Software\Microsoft\.NETFramework\Policy\v1.0\3705', 'Install', regVersionString);
18 | Result := regVersionString <> '';
19 | end else begin
20 | case version of
21 | NetFx11:
22 | RegQueryDWordValue(HKLM, netfx11plus_reg + 'v1.1.4322' + lcid, 'Install', regVersion);
23 | NetFx20:
24 | RegQueryDWordValue(HKLM, netfx11plus_reg + 'v2.0.50727' + lcid, 'Install', regVersion);
25 | NetFx30:
26 | RegQueryDWordValue(HKLM, netfx11plus_reg + 'v3.0\Setup' + lcid, 'InstallSuccess', regVersion);
27 | NetFx35:
28 | RegQueryDWordValue(HKLM, netfx11plus_reg + 'v3.5' + lcid, 'Install', regVersion);
29 | NetFx40Client:
30 | RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Client' + lcid, 'Install', regVersion);
31 | NetFx40Full:
32 | RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Full' + lcid, 'Install', regVersion);
33 | NetFx45:
34 | begin
35 | RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Full' + lcid, 'Release', regVersion);
36 | // >= 4.5.0 and <= 4.5.?(Win10)
37 | Result := (regVersion >= 378389);
38 | Exit;
39 | end;
40 | end;
41 | Result := (regVersion <> 0);
42 | end;
43 | end;
44 |
45 | function netfxspversion(version: NetFXType; lcid: string): integer;
46 | var
47 | regVersion: cardinal;
48 | begin
49 | if (lcid <> '') then
50 | lcid := '\' + lcid;
51 |
52 | case version of
53 | NetFx10:
54 | //not supported
55 | regVersion := -1;
56 | NetFx11:
57 | if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v1.1.4322' + lcid, 'SP', regVersion)) then
58 | regVersion := -1;
59 | NetFx20:
60 | if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v2.0.50727' + lcid, 'SP', regVersion)) then
61 | regVersion := -1;
62 | NetFx30:
63 | if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v3.0' + lcid, 'SP', regVersion)) then
64 | regVersion := -1;
65 | NetFx35:
66 | if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v3.5' + lcid, 'SP', regVersion)) then
67 | regVersion := -1;
68 | NetFx40Client:
69 | if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Client' + lcid, 'Servicing', regVersion)) then
70 | regVersion := -1;
71 | NetFx40Full:
72 | if (not RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Full' + lcid, 'Servicing', regVersion)) then
73 | regVersion := -1;
74 | NetFx45:
75 | if (RegQueryDWordValue(HKLM, netfx11plus_reg + 'v4\Full' + lcid, 'Release', regVersion)) then begin
76 | if (regVersion >= 381029) then
77 | regVersion := 9 //4.5.?(Win10)
78 | else if (regVersion = 379893) then
79 | regVersion := 2 // 4.5.2
80 | else if (regVersion = 378675) or (regVersion = 378758) then
81 | regVersion := 1 // 4.5.1
82 | else if (regVersion = 378389) then
83 | regVersion := 0 // 4.5.0
84 | else
85 | regVersion := -1;
86 | end;
87 | end;
88 | Result := regVersion;
89 | end;
90 |
--------------------------------------------------------------------------------
/release/iss/scripts/products/fileversion.iss:
--------------------------------------------------------------------------------
1 | [Code]
2 | function GetFullVersion(VersionMS, VersionLS: cardinal): string;
3 | var
4 | version: string;
5 | begin
6 | version := IntToStr(word(VersionMS shr 16));
7 | version := version + '.' + IntToStr(word(VersionMS and not $ffff0000));
8 |
9 | version := version + '.' + IntToStr(word(VersionLS shr 16));
10 | version := version + '.' + IntToStr(word(VersionLS and not $ffff0000));
11 |
12 | Result := version;
13 | end;
14 |
15 | function fileversion(file: string): string;
16 | var
17 | versionMS, versionLS: cardinal;
18 | begin
19 | if GetVersionNumbers(file, versionMS, versionLS) then
20 | Result := GetFullVersion(versionMS, versionLS)
21 | else
22 | Result := '0';
23 | end;
24 |
--------------------------------------------------------------------------------
/release/iss/scripts/products/msi31.iss:
--------------------------------------------------------------------------------
1 | [CustomMessages]
2 | msi31_title=Windows Installer 3.1
3 | msi31_size=2.5 MB
4 |
5 | [Code]
6 | const
7 | msi31_url = 'http://download.microsoft.com/download/1/4/7/147ded26-931c-4daf-9095-ec7baf996f46/WindowsInstaller-KB893803-v2-x86.exe';
8 |
9 | procedure msi31(MinVersion: string);
10 | begin
11 | // Check for required Windows Installer 3.0 on Windows 2000 or higher
12 | if (IsX86() and minwinversion(5, 0) and (compareversion(fileversion(ExpandConstant('{sys}{\}msi.dll')), MinVersion) < 0)) then
13 | AddProduct('msi31.exe',
14 | '/passive /norestart',
15 | CustomMessage('msi31_title'),
16 | CustomMessage('msi31_size'),
17 | msi31_url,
18 | false, false);
19 | end;
--------------------------------------------------------------------------------
/release/iss/scripts/products/stringversion.iss:
--------------------------------------------------------------------------------
1 | function stringtoversion(var temp: String): Integer;
2 | var
3 | part: String;
4 | pos1: Integer;
5 |
6 | begin
7 | if (Length(temp) = 0) then begin
8 | Result := -1;
9 | Exit;
10 | end;
11 |
12 | pos1 := Pos('.', temp);
13 | if (pos1 = 0) then begin
14 | Result := StrToInt(temp);
15 | temp := '';
16 | end else begin
17 | part := Copy(temp, 1, pos1 - 1);
18 | temp := Copy(temp, pos1 + 1, Length(temp));
19 | Result := StrToInt(part);
20 | end;
21 | end;
22 |
23 | function compareinnerversion(var x, y: String): Integer;
24 | var
25 | num1, num2: Integer;
26 |
27 | begin
28 | num1 := stringtoversion(x);
29 | num2 := stringtoversion(y);
30 | if (num1 = -1) or (num2 = -1) then begin
31 | Result := 0;
32 | Exit;
33 | end;
34 |
35 | if (num1 < num2) then begin
36 | Result := -1;
37 | end else if (num1 > num2) then begin
38 | Result := 1;
39 | end else begin
40 | Result := compareinnerversion(x, y);
41 | end;
42 | end;
43 |
44 | function compareversion(versionA, versionB: String): Integer;
45 | var
46 | temp1, temp2: String;
47 |
48 | begin
49 | temp1 := versionA;
50 | temp2 := versionB;
51 | Result := compareinnerversion(temp1, temp2);
52 | end;
53 |
--------------------------------------------------------------------------------
/release/iss/scripts/products/winversion.iss:
--------------------------------------------------------------------------------
1 | [Code]
2 | var
3 | WindowsVersion: TWindowsVersion;
4 |
5 | procedure initwinversion();
6 | begin
7 | GetWindowsVersionEx(WindowsVersion);
8 | end;
9 |
10 | function exactwinversion(MajorVersion, MinorVersion: integer): boolean;
11 | begin
12 | Result := (WindowsVersion.Major = MajorVersion) and (WindowsVersion.Minor = MinorVersion);
13 | end;
14 |
15 | function minwinversion(MajorVersion, MinorVersion: integer): boolean;
16 | begin
17 | Result := (WindowsVersion.Major > MajorVersion) or ((WindowsVersion.Major = MajorVersion) and (WindowsVersion.Minor >= MinorVersion));
18 | end;
19 |
20 | function maxwinversion(MajorVersion, MinorVersion: integer): boolean;
21 | begin
22 | Result := (WindowsVersion.Major < MajorVersion) or ((WindowsVersion.Major = MajorVersion) and (WindowsVersion.Minor <= MinorVersion));
23 | end;
24 |
25 | function exactwinspversion(MajorVersion, MinorVersion, SpVersion: integer): boolean;
26 | begin
27 | if exactwinversion(MajorVersion, MinorVersion) then
28 | Result := WindowsVersion.ServicePackMajor = SpVersion
29 | else
30 | Result := true;
31 | end;
32 |
33 | function minwinspversion(MajorVersion, MinorVersion, SpVersion: integer): boolean;
34 | begin
35 | if exactwinversion(MajorVersion, MinorVersion) then
36 | Result := WindowsVersion.ServicePackMajor >= SpVersion
37 | else
38 | Result := true;
39 | end;
40 |
41 | function maxwinspversion(MajorVersion, MinorVersion, SpVersion: integer): boolean;
42 | begin
43 | if exactwinversion(MajorVersion, MinorVersion) then
44 | Result := WindowsVersion.ServicePackMajor <= SpVersion
45 | else
46 | Result := true;
47 | end;
--------------------------------------------------------------------------------
/release/iss/x-wall-full.iss:
--------------------------------------------------------------------------------
1 | ; Script generated by the Inno Setup Script Wizard.
2 | ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
3 |
4 | #define MyAppName "X-Wall"
5 | #define MyAppExeName "x-wall.exe"
6 | #define MyAppVersion GetFileVersion("E:\WorkSpace\XWall\src\bin\Release\x-wall.exe")
7 | #define MyAppPublisher "Groinup Studio"
8 | #define MyAppURL "http://x-wall.org"
9 |
10 | [Setup]
11 | ; NOTE: The value of AppId uniquely identifies this application.
12 | ; Do not use the same AppId value in installers for other applications.
13 | ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
14 | AppID={{CEE80EAA-3CD9-425B-8119-F3ECBCB5DB52}
15 | AppName={#MyAppName}
16 | AppVerName={#MyAppName}
17 | AppPublisher={#MyAppPublisher}
18 | AppPublisherURL={#MyAppURL}
19 | AppVersion={#MyAppVersion}
20 | VersionInfoVersion={#MyAppVersion}
21 | VersionInfoTextVersion={#MyAppVersion}
22 | VersionInfoCompany={#MyAppPublisher}
23 | VersionInfoCopyright={#MyAppPublisher}
24 | DefaultDirName={pf}\{#MyAppName}
25 | DefaultGroupName={#MyAppName}
26 | OutputDir=E:\WorkSpace\XWall\release
27 | OutputBaseFilename=x-wall-setup-full
28 | SetupIconFile=E:\WorkSpace\XWall\src\Icons\main.ico
29 | UninstallDisplayIcon=E:\WorkSpace\XWall\src\Icons\main.ico
30 | Compression=lzma/Max
31 | SolidCompression=true
32 |
33 | [Languages]
34 | Name: "en"; MessagesFile: "compiler:Default.isl"
35 |
36 | [Tasks]
37 | Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
38 |
39 | [Files]
40 | Source: "E:\WorkSpace\XWall\src\bin\Release\x-wall.exe"; DestDir: "{app}"; Flags: ignoreversion
41 | Source: "E:\WorkSpace\XWall\src\bin\Release\x-wall.exe.config"; DestDir: "{app}"; Flags: ignoreversion
42 | Source: "E:\WorkSpace\XWall\src\bin\Release\WebDev.WebHost20.dll"; DestDir: "{app}"; Flags: ignoreversion
43 | Source: "E:\WorkSpace\XWall\src\bin\Release\mgwz.dll"; DestDir: "{app}"; Flags: ignoreversion
44 | Source: "E:\WorkSpace\XWall\src\bin\Release\plink.exe"; DestDir: "{app}"; Flags: ignoreversion
45 | Source: "E:\WorkSpace\XWall\src\bin\Release\plonk.exe"; DestDir: "{app}"; Flags: ignoreversion
46 | Source: "E:\WorkSpace\XWall\src\bin\Release\privoxy.exe"; DestDir: "{app}"; Flags: ignoreversion
47 | Source: "E:\WorkSpace\XWall\local-server-apps\*"; DestDir: "{commonappdata}\{#MyAppName}\local-server-apps"; Flags: ignoreversion recursesubdirs
48 | Source: "E:\WorkSpace\XWall\src\resources\*"; DestDir: "{commonappdata}\{#MyAppName}\resources"; Flags: ignoreversion recursesubdirs
49 | Source: "E:\WorkSpace\XWall\rules\rules-v2"; DestDir: "{commonappdata}\{#MyAppName}\configs"; DestName: "online-rules"; Flags: ignoreversion; Permissions: authusers-full
50 | Source: "E:\WorkSpace\XWall\goagent\*"; DestDir: "{commonappdata}\X-Wall\goagent"; Flags: ignoreversion recursesubdirs; Permissions: authusers-full
51 |
52 | [Icons]
53 | Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
54 | Name: "{userdesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
55 |
56 | [Run]
57 | Filename: "{commonappdata}\{#MyAppName}\goagent\local\python27.exe"; Parameters: """{commonappdata}\{#MyAppName}\goagent\local\import-ca.py"""; Flags: runhidden
58 | Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}"; Flags: nowait postinstall runascurrentuser
59 |
60 | #include "scripts\products.iss"
61 |
62 | #include "scripts\products\stringversion.iss"
63 | #include "scripts\products\winversion.iss"
64 | #include "scripts\products\fileversion.iss"
65 | #include "scripts\products\dotnetfxversion.iss"
66 |
67 | #include "scripts\products\msi31.iss"
68 | #include "scripts\products\dotnetfx45full.iss"
69 |
70 | [Registry]
71 | Root: "HKCR"; Subkey: "xwall"; Flags: deletekey
72 |
73 | [InstallDelete]
74 | Type: files; Name: "{commondesktop}\{#MyAppName}.lnk"
75 | Type: filesandordirs; Name: "{app}\templates"
76 | Type: filesandordirs; Name: "{app}\local-server-apps"
77 | Type: filesandordirs; Name: "{app}\configs"
78 | Type: filesandordirs; Name: "{app}\resources"
79 | Type: files; Name: "{app}\online-rules"
80 | Type: files; Name: "{app}\update-mark"
81 | Type: files; Name: "{app}\privoxy.config"
82 | Type: files; Name: "{app}\privoxy.action"
83 | Type: filesandordirs; Name: "{commonappdata}\{#MyAppName}\goagent"
84 |
85 | [CustomMessages]
86 | win_sp_title=Windows %1 Service Pack %2
87 |
88 | [UninstallDelete]
89 | Type: filesandordirs; Name: "{app}"
90 | Type: filesandordirs; Name: "{commonappdata}\{#MyAppName}"
91 |
92 | [Dirs]
93 |
94 | [Code]
95 | Function InitializeSetup : Boolean;
96 | var
97 | ResultCode : Integer;
98 | begin
99 | initwinversion();
100 | msi31('3.1');
101 | dotnetfx45(2);
102 | Result := true;
103 | end;
104 |
105 | Function InitializeUninstall : Boolean;
106 | var
107 | ResultCode : Integer;
108 | begin
109 | Exec(ExpandConstant('{app}\x-wall.exe'),'uninstall', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
110 | Result := true;
111 | end;
112 |
--------------------------------------------------------------------------------
/release/iss/x-wall.iss:
--------------------------------------------------------------------------------
1 | ; Script generated by the Inno Setup Script Wizard.
2 | ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
3 |
4 | #define MyAppName "X-Wall"
5 | #define MyAppExeName "x-wall.exe"
6 | #define MyAppVersion GetFileVersion("E:\WorkSpace\XWall\src\bin\Release\x-wall.exe")
7 | #define MyAppPublisher "LunaTech Inc."
8 | #define MyAppURL "https://github.com/lunarlove/XWall"
9 |
10 | [Setup]
11 | ; NOTE: The value of AppId uniquely identifies this application.
12 | ; Do not use the same AppId value in installers for other applications.
13 | ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
14 | AppID={{CEE80EAA-3CD9-425B-8119-F3ECBCB5DB52}
15 | AppName={#MyAppName}
16 | AppVerName={#MyAppName}
17 | AppPublisher={#MyAppPublisher}
18 | AppPublisherURL={#MyAppURL}
19 | AppVersion={#MyAppVersion}
20 | VersionInfoVersion={#MyAppVersion}
21 | VersionInfoTextVersion={#MyAppVersion}
22 | VersionInfoCompany={#MyAppPublisher}
23 | VersionInfoCopyright={#MyAppPublisher}
24 | DefaultDirName={pf}\{#MyAppName}
25 | DefaultGroupName={#MyAppName}
26 | OutputDir=E:\WorkSpace\XWall\release
27 | OutputBaseFilename=x-wall-setup
28 | SetupIconFile=E:\WorkSpace\XWall\src\Icons\main.ico
29 | UninstallDisplayIcon=E:\WorkSpace\XWall\src\Icons\main.ico
30 | Compression=lzma/Max
31 | SolidCompression=true
32 | MinVersion=6.0
33 |
34 | [Languages]
35 | Name: "en"; MessagesFile: "compiler:Default.isl"
36 |
37 | [Tasks]
38 | Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
39 |
40 | [Files]
41 | Source: "E:\WorkSpace\XWall\src\bin\Release\x-wall.exe"; DestDir: "{app}"; Flags: ignoreversion
42 | Source: "E:\WorkSpace\XWall\src\bin\Release\x-wall.exe.config"; DestDir: "{app}"; Flags: ignoreversion
43 | Source: "E:\WorkSpace\XWall\src\bin\Release\WebDev.WebHost20.dll"; DestDir: "{app}"; Flags: ignoreversion
44 | Source: "E:\WorkSpace\XWall\src\bin\Release\mgwz.dll"; DestDir: "{app}"; Flags: ignoreversion
45 | Source: "E:\WorkSpace\XWall\src\bin\Release\plink.exe"; DestDir: "{app}"; Flags: ignoreversion
46 | Source: "E:\WorkSpace\XWall\src\bin\Release\plonk.exe"; DestDir: "{app}"; Flags: ignoreversion
47 | Source: "E:\WorkSpace\XWall\src\bin\Release\privoxy.exe"; DestDir: "{app}"; Flags: ignoreversion
48 | Source: "E:\WorkSpace\XWall\local-server-apps\*"; DestDir: "{commonappdata}\{#MyAppName}\local-server-apps"; Flags: ignoreversion recursesubdirs
49 | Source: "E:\WorkSpace\XWall\src\resources\*"; DestDir: "{commonappdata}\{#MyAppName}\resources"; Flags: ignoreversion recursesubdirs
50 | Source: "E:\WorkSpace\XWall\rules\rules-v2"; DestDir: "{commonappdata}\{#MyAppName}\configs"; DestName: "online-rules"; Flags: ignoreversion; Permissions: authusers-full
51 |
52 | [Icons]
53 | Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
54 | Name: "{userdesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
55 |
56 | [Run]
57 | Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}"; Flags: nowait postinstall runascurrentuser
58 |
59 | #include "scripts\products.iss"
60 |
61 | #include "scripts\products\stringversion.iss"
62 | #include "scripts\products\winversion.iss"
63 | #include "scripts\products\fileversion.iss"
64 | #include "scripts\products\dotnetfxversion.iss"
65 |
66 | #include "scripts\products\msi31.iss"
67 | #include "scripts\products\dotnetfx45full.iss"
68 |
69 | [Registry]
70 | Root: "HKCR"; Subkey: "xwall"; Flags: deletekey
71 |
72 | [InstallDelete]
73 | Type: files; Name: "{commondesktop}\{#MyAppName}.lnk"
74 | Type: filesandordirs; Name: "{app}\templates"
75 | Type: filesandordirs; Name: "{app}\local-server-apps"
76 | Type: filesandordirs; Name: "{app}\configs"
77 | Type: filesandordirs; Name: "{app}\resources"
78 | Type: files; Name: "{app}\online-rules"
79 | Type: files; Name: "{app}\update-mark"
80 | Type: files; Name: "{app}\privoxy.config"
81 | Type: files; Name: "{app}\privoxy.action"
82 |
83 | [CustomMessages]
84 | win_sp_title=Windows %1 Service Pack %2
85 |
86 | [UninstallDelete]
87 | Type: filesandordirs; Name: "{app}"
88 | Type: filesandordirs; Name: "{commonappdata}\{#MyAppName}"
89 |
90 | [Dirs]
91 |
92 | [Code]
93 | Function InitializeSetup : Boolean;
94 | var
95 | ResultCode : Integer;
96 | begin
97 | initwinversion();
98 | msi31('3.1');
99 | dotnetfx45(2);
100 | Result := true;
101 | end;
102 |
103 | Function InitializeUninstall : Boolean;
104 | var
105 | ResultCode : Integer;
106 | begin
107 | Exec(ExpandConstant('{app}\x-wall.exe'),'uninstall', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
108 | Result := true;
109 | end;
110 |
--------------------------------------------------------------------------------
/release/plonk.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/release/plonk.exe
--------------------------------------------------------------------------------
/release/version:
--------------------------------------------------------------------------------
1 | 1.3.5592.39489
2 | 1.3.5553.35642
3 | XWall 1.3.5592.39489 更新日志 \newline-- 基于 1.3.5553.35642 --\newline1.增加了使用私钥连接SSH服务器的功能
--------------------------------------------------------------------------------
/release/version(suggest).js:
--------------------------------------------------------------------------------
1 | var fso = new ActiveXObject("Scripting.FileSystemObject");
2 |
3 | var version = fso.getFileVersion("x-wall-setup.exe");
4 |
5 | var file = fso.openTextFile("version");
6 | var info = file.readAll();
7 | file.close();
8 |
9 | var versions = info.split("\r\n");
10 | versions[0] = versions[1] = version;
11 |
12 | file = fso.createTextFile("version");
13 | file.write(versions.join("\r\n"));
14 | file.close();
15 |
16 | //file = fso.createTextFile("..\\..\\gh-pages\\release\\version");
17 | //file.write(version);
18 | //file.close();
--------------------------------------------------------------------------------
/release/version-v2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.3.5553.35642
4 | 1.3.5592.39489
5 | false
6 | https://github.com/lunarlove/XWall/raw/master/release/x-wall-setup.exe
7 | https://github.com/lunarlove/XWall/raw/master/release/x-wall-setup-full.exe
8 | XWall 1.3.5592.39489 更新日志\newline\newline-- 基于1.3.5553.35642\newline1.增加了使用私钥连接SSH服务器的功能
9 |
--------------------------------------------------------------------------------
/release/version.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | var shell = new ActiveXObject("WScript.Shell");
3 | var result = shell.run('"C:\\Program Files (x86)\\Inno Setup 5\\ISCC.exe" "E:\\WorkSpace\\XWall\\release\\iss\\x-wall.iss"', 1, true);
4 | result = result || shell.run('"C:\\Program Files (x86)\\Inno Setup 5\\ISCC.exe" "E:\\WorkSpace\\XWall\\release\\iss\\x-wall-full.iss"', 1, true);
5 |
6 | if (result != 0) {
7 | WScript.echo("Build installer failed.");
8 | return;
9 | }
10 |
11 | var fso = new ActiveXObject("Scripting.FileSystemObject");
12 | try {
13 | fso.deleteFile("x-wall-setup-with-plonk.exe");
14 | }
15 | catch (e) { }
16 |
17 | //shell.run("cmd /c mklink /h x-wall-setup-with-plonk.exe x-wall-setup.exe");
18 |
19 | var version = fso.getFileVersion("x-wall-setup.exe");
20 |
21 | var file = fso.openTextFile("version");
22 | var info = file.readAll();
23 | file.close();
24 |
25 | var versions = info.split("\r\n");
26 | versions[0] = version;
27 |
28 | file = fso.createTextFile("version");
29 | file.write(versions.join("\r\n"));
30 | file.close();
31 |
32 | //file = fso.createTextFile("..\\..\\gh-pages\\release\\version");
33 | //file.write(version);
34 | //file.close();
35 | })();
--------------------------------------------------------------------------------
/release/version_nogoa.js:
--------------------------------------------------------------------------------
1 | var fso = new ActiveXObject("Scripting.FileSystemObject");
2 |
3 | var version = fso.getFileVersion("x-wall-setup.exe");
4 |
5 | var file = fso.openTextFile("version");
6 | var info = file.readAll();
7 | file.close();
8 |
9 | var versions = info.split("\r\n");
10 | versions[0] = version;
11 |
12 | file = fso.createTextFile("version");
13 | file.write(versions.join("\r\n"));
14 | file.close();
15 |
16 | //file = fso.createTextFile("..\\..\\gh-pages\\release\\version");
17 | //file.write(version);
18 | //file.close();
--------------------------------------------------------------------------------
/release/x-wall-setup-full.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/release/x-wall-setup-full.exe
--------------------------------------------------------------------------------
/release/x-wall-setup.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/release/x-wall-setup.exe
--------------------------------------------------------------------------------
/release/x-wall-setup.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/release/x-wall-setup.zip
--------------------------------------------------------------------------------
/rules/gfwlist2privoxy.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/rules/gfwlist2privoxy.js
--------------------------------------------------------------------------------
/rules/updater.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/rules/updater.js
--------------------------------------------------------------------------------
/rules/x-list.txt:
--------------------------------------------------------------------------------
1 | ! GFW Related Sites
2 | x-wall.org
3 |
4 | ! Contents
5 | ||zh.wikipedia.org
6 | ||wikipedia.org/search-redirect.php?*language=zh
7 |
8 | ! Google Related
9 | ||google.
10 | ||googleusercontent.com
11 | ||googleapis.com
12 | ||g.doubleclick.net
13 | ||adsense.com
14 |
15 | ! Others
16 | @@||baidu.com
17 | @@||xunlei.com
18 | @@||youdao.com
19 | @@||weibo.com
20 | @@||renren.com
21 | @@||youku.com
22 | @@||sina.com.cn
23 | @@||163.com
24 | @@||126.com
25 | @@||qq.com
26 | @@||taobao.com
27 | @@||tmall.com
28 | @@||jd.com
--------------------------------------------------------------------------------
/src/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Diagnostics;
6 | using System.IO;
7 | using System.Linq;
8 | using System.Windows;
9 | using System.Deployment;
10 | using XWall.Properties;
11 | using System.Globalization;
12 | using System.Text.RegularExpressions;
13 | using System.Reflection;
14 | using Microsoft.Win32;
15 | using System.Net;
16 | using System.Web;
17 |
18 | namespace XWall {
19 | ///
20 | /// Interaction logic for App.xaml
21 | ///
22 | public partial class App : Application {
23 | public static bool IsShutDown = false;
24 | public static string AppDataDirectory = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\X-Wall\";
25 | public static bool Updated = false;
26 | public static bool FirstRun = false;
27 |
28 | protected override void OnStartup(StartupEventArgs eventArgs) {
29 | base.OnStartup(eventArgs);
30 | LoadLanguage();
31 | var resources = App.Current.Resources;
32 |
33 | var executablePath = System.Windows.Forms.Application.ExecutablePath;
34 | Environment.CurrentDirectory = Path.GetDirectoryName(executablePath);
35 | Microsoft.Win32.SystemEvents.SessionEnding += (sender, e) => {
36 | try {
37 | IsShutDown = true;
38 | App.Current.Shutdown();
39 | }
40 | catch { }
41 | };
42 |
43 | var settings = Settings.Default;
44 |
45 | Directory.CreateDirectory(AppDataDirectory);
46 | Directory.CreateDirectory(AppDataDirectory + settings.ConfigsFolderName);
47 | Directory.CreateDirectory(AppDataDirectory + settings.ResourcesFolderName);
48 |
49 | var ignoreRunningInstance = false;
50 |
51 | if (eventArgs.Args.Length > 0) {
52 | var commandStr = eventArgs.Args[0];
53 | var match = new Regex(@"^(.*?)(?:/(.*))?$").Match(commandStr);
54 | var command = match.Groups[1].Value;
55 | var commandArg = match.Groups[2].Value;
56 |
57 | switch (command) {
58 | case "uninstall":
59 | Operation.KillProcess(executablePath);
60 | Operation.KillProcess(settings.PrivoxyFileName);
61 | Operation.KillProcess(settings.PlinkFileName);
62 | if (settings.SetProxyAutomatically) {
63 | Operation.Proxies.RestoreProxy();
64 | }
65 | Operation.SetAutoStart(false);
66 | //Operation.RegisterXWallProtocol(false);
67 | IsShutDown = true;
68 | App.Current.Shutdown();
69 | return;
70 | case "restart":
71 | ignoreRunningInstance = true;
72 | break;
73 | //case "xwall:new-rule":
74 | // File.WriteAllText(settings.ConfigsFolderName + settings.NewRuleFileName, commandArg);
75 | // IsShutDown = true;
76 | // App.Current.Shutdown();
77 | // return;
78 | //case "xwall:del-rule":
79 | // File.WriteAllText(settings.ConfigsFolderName + settings.DeleteRuleFileName, commandArg);
80 | // IsShutDown = true;
81 | // App.Current.Shutdown();
82 | // return;
83 | default:
84 | break;
85 | }
86 | }
87 |
88 | if (!ignoreRunningInstance) {
89 | Process current = Process.GetCurrentProcess();
90 | MessageBoxResult? result = null;
91 | foreach (Process process in Process.GetProcessesByName(current.ProcessName)) {
92 | if (process.Id != current.Id) {
93 | if (result == null)
94 | result = MessageBox.Show(resources["XWallAlreadyStartedDescription"] as string, resources["XWallTitle"] as string, MessageBoxButton.OKCancel);
95 | if (result == MessageBoxResult.OK) {
96 | try {
97 | process.Kill();
98 | }
99 | catch { }
100 | }
101 | else {
102 | IsShutDown = true;
103 | App.Current.Shutdown();
104 | return;
105 | }
106 | }
107 | }
108 | }
109 |
110 | if (settings.UpgradeRequired) {
111 | settings.Upgrade();
112 | settings.UpgradeRequired = false;
113 |
114 | if (!settings.FirstRun) {
115 | Updated = true;
116 | }
117 | }
118 |
119 | if (settings.FirstRun || settings.ToUseGoAgent) {
120 | if (settings.ToUseGoAgent) {
121 | settings.ToUseGoAgent = false;
122 | }
123 |
124 | if (Directory.Exists(AppDataDirectory + settings.GaFolderName)) {
125 | settings.ProxyType = "GA";
126 | }
127 | }
128 |
129 | if (settings.ProxyType == "GA" && !Directory.Exists(AppDataDirectory + settings.GaFolderName)) {
130 | settings.ProxyType = "SSH";
131 | }
132 |
133 | if (settings.FirstRun) {
134 | settings.FirstRun = false;
135 | FirstRun = true;
136 |
137 | //first time stuffs.
138 | Operation.SetAvailablePorts();
139 | }
140 |
141 | //* DEBUG CODE
142 | var autoStart = Operation.SetAutoStart(settings.AutoStart);
143 | if (autoStart != settings.AutoStart)
144 | settings.AutoStart = autoStart;
145 |
146 | if (settings.SetProxyAutomatically) {
147 | Operation.Proxies.SetXWallProxy();
148 | }
149 | //Operation.RegisterXWallProtocol(true);
150 |
151 | settings.PropertyChanged += (sender, e) => {
152 | switch (e.PropertyName) {
153 | case "ProxyPort": break;
154 | default: return;
155 | }
156 |
157 | if (settings.SetProxyAutomatically) {
158 | Operation.Proxies.SetXWallProxy();
159 | }
160 | };
161 |
162 | settings.PropertyChanged += (sender, e) => {
163 | switch (e.PropertyName) {
164 | case "AutoStart": break;
165 | default: return;
166 | }
167 |
168 | var rst = Operation.SetAutoStart(settings.AutoStart);
169 | if (rst != settings.AutoStart)
170 | settings.AutoStart = rst;
171 | };
172 |
173 | //Operation.SetAvailablePorts();
174 |
175 | App.Current.Exit += (sender, e) => {
176 | if (settings.SetProxyAutomatically) {
177 | Operation.Proxies.RestoreProxy();
178 | }
179 | };
180 |
181 | SystemEvents.SessionEnded += (sender, e) => {
182 | try {
183 | App.Current.Shutdown();
184 | }
185 | catch { }
186 | };
187 |
188 | Dispatcher.UnhandledException += (sender, e) => {
189 | var query = HttpUtility.ParseQueryString("");
190 | query["data"] = Assembly.GetExecutingAssembly().GetName().Version.ToString() + "\r\n" + e.Exception.ToString();
191 |
192 | var client = new WebClient();
193 | client.UploadValuesAsync(new Uri(settings.ErrorReportUrl), query);
194 |
195 | var msg = (resources["UnhandledExceptionMessage"] as string).Replace("%n", Environment.NewLine);
196 | MessageBox.Show(msg+e.Exception.ToString(), resources["XWall"] as string, MessageBoxButton.OK, MessageBoxImage.Error);
197 |
198 | e.Handled = true;
199 | };
200 | //*/
201 | }
202 |
203 | private void LoadLanguage() {
204 | CultureInfo currentCultureInfo = CultureInfo.CurrentCulture;
205 |
206 | var files = new string[] {
207 | //@"Langs\zh.xaml",
208 | @"Langs\" + currentCultureInfo.TwoLetterISOLanguageName + ".xaml",
209 | @"Langs\" + currentCultureInfo.Name + ".xaml"
210 | };
211 |
212 | foreach (var file in files) {
213 | try {
214 | var uri = new Uri(file, UriKind.Relative);
215 | var dictionary = Application.LoadComponent(uri) as ResourceDictionary;
216 | this.Resources.MergedDictionaries.Add(dictionary);
217 | } catch { }
218 | }
219 | }
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/src/Classes/AppSetting.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Configuration;
7 | using XWall.Properties;
8 | using System.IO;
9 | using System.Xml.Linq;
10 | using System.Xml;
11 | using System.Windows;
12 | using System.Diagnostics;
13 |
14 | namespace XWall
15 | {
16 | public class AppSetting
17 | {
18 | static Settings mysettings = XWall.Properties.Settings.Default;
19 | static string[] userSettings = {"ProxyType","SshServer","SshPort","SshUsername","SshPassword","HttpServer","HttpPort","AutoStart","ListenToLocalOnly","ProxyPort","SshCompression","SshSocksPort","CustomRulesAddSubdomains","UpgradeRequired","SshAutoReconnect","OnlineRulesLastUpdateTime","UseOnlineRules","CustomRules","FirstRun","OriginalProxies","DismissedUpdateVersion","SshNotification","SubmitNewRule","SubmitNewRuleAsked","SshUsePlonk","SshPlonkKeyword","SshReconnectAnyCondition","SshProfiles","SshSelectedProfileIndex","ForwardAll","SetProxyAutomatically","SocksServer","SocksPort","UseIntranetProxy","IntranetProxyServer","IntranetProxyPort","GaAppIds","GaPort","GaProfile","ToUseGoAgent","GaLastServerVersion" };
20 | readonly static string confFile = Environment.CurrentDirectory + "\\Application.conf";
21 | public static void SettingUpgrade(){
22 | XElement xElement = new XElement(new XElement("XWall.SettingsXML"));
23 | foreach (string sp in userSettings)
24 | {
25 | xElement.Add(new XElement(sp, Settings.Default[sp].ToString()));
26 | }
27 | XmlWriterSettings settings = new XmlWriterSettings();
28 | settings.Encoding = ASCIIEncoding.UTF8;
29 | settings.Indent = true;
30 | XmlWriter writer = XmlWriter.Create(confFile, settings);
31 | xElement.Save(writer);
32 | writer.Flush();
33 | writer.Close();
34 | Process.Start(System.Windows.Forms.Application.ExecutablePath, "restart");
35 | App.Current.Shutdown();
36 | }
37 | public static string ReadSetting(string settingName)
38 | {
39 | if (IsFileExist())
40 | {
41 | XmlDocument xmlDoc = new XmlDocument();
42 | xmlDoc.Load(confFile);
43 | try
44 | {
45 | return xmlDoc.SelectSingleNode("Xwall.SettingsXML//" + settingName).InnerText;
46 | }
47 | catch
48 | {
49 | return null;
50 | }
51 | }
52 | else
53 | {
54 | return null;
55 | }
56 |
57 | }
58 | public static bool IsFileExist()
59 | {
60 | if (System.IO.File.Exists(confFile))
61 | {
62 | return true;
63 | }
64 | else
65 | {
66 | return false;
67 | }
68 | }
69 | public static bool WriteSetting(string settingName, string settingValue)
70 | {
71 | if (IsFileExist())
72 | {
73 | try
74 | {
75 | XmlDocument xmlDoc = new XmlDocument();
76 | xmlDoc.Load(confFile);
77 | XmlElement element = (XmlElement)xmlDoc.SelectSingleNode("Xwall.SettingsXML//" + settingName);
78 | element.InnerText = settingValue;
79 | xmlDoc.Save(confFile);
80 | }
81 | catch
82 | {
83 | return false;
84 | }
85 | return true;
86 | }
87 | else
88 | {
89 | return false;
90 | }
91 | }
92 | public static void MoveOldConfig()
93 | {
94 | string groinupDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Groinup";
95 | if (System.IO.Directory.Exists(groinupDir))
96 | {
97 | if (!File.Exists(groinupDir + "\\Updated"))
98 | {
99 | DirectoryInfo directoryInfo = new DirectoryInfo(groinupDir);
100 | DirectoryInfo[] arrayDir = directoryInfo.GetDirectories();
101 | SortAsFolderModifyTime(ref arrayDir);
102 | string lastversionAppdir = groinupDir + "\\" + arrayDir[0].Name;
103 | directoryInfo = new DirectoryInfo(lastversionAppdir);
104 | arrayDir = directoryInfo.GetDirectories();
105 | SortAsFolderModifyTime(ref arrayDir);
106 | string lastversionCFGdir = lastversionAppdir + "\\" + arrayDir[0].Name;
107 | var result = mysettings.Import(lastversionCFGdir + "\\user.config");
108 | if (!result)
109 | {
110 | MessageBox.Show(App.Current.Resources["FailedImportSettings"] as string);
111 | }
112 | else
113 | {
114 | File.WriteAllText(groinupDir + "\\Updated", null);
115 | MessageBox.Show(App.Current.Resources["UpdateSuccessDetails"] as string, App.Current.Resources["UpdateSuccessTitle"] as string, MessageBoxButton.OK, MessageBoxImage.Information);
116 | Process.Start(System.Windows.Forms.Application.ExecutablePath, "restart");
117 | App.Current.Shutdown();
118 | }
119 | }
120 | }
121 | }
122 | private static void SortAsFolderModifyTime(ref DirectoryInfo[] dirs)
123 | {
124 | Array.Sort(dirs, delegate(DirectoryInfo x, DirectoryInfo y) { return y.LastWriteTime.CompareTo(x.LastWriteTime); });
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/Classes/GoAgent.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Security.Principal;
7 | using System.Text;
8 | using System.Threading;
9 | using System.Windows;
10 | using XWall.Properties;
11 |
12 | namespace XWall {
13 | class GoAgent {
14 | static Settings settings = Settings.Default;
15 | static ResourceDictionary resources = App.Current.Resources;
16 | Process process;
17 | bool stop;
18 | static string configTpl;
19 | bool startPending = false;
20 |
21 | public GoAgent() {
22 | Operation.KillProcess(App.AppDataDirectory + settings.GaPython27FileName);
23 | App.Current.Exit += (sender, e) => {
24 | Stop();
25 | };
26 |
27 | settings.PropertyChanged += (sender, e) => {
28 | switch (e.PropertyName) {
29 | case "ProxyType": break;
30 | case "GaPort": break;
31 | case "GaProfile": break;
32 | case "GaAppIds": break;
33 | default: return;
34 | }
35 |
36 | if (settings.ProxyType == "GA") {
37 | GenerateConfigFile();
38 | }
39 | };
40 |
41 | if (settings.ProxyType == "GA") {
42 | GenerateConfigFile();
43 | }
44 | }
45 |
46 | public static void GenerateConfigFile() {
47 | if (String.IsNullOrEmpty(configTpl)) {
48 | configTpl = File.ReadAllText(App.AppDataDirectory + settings.GaConfigTemplateFileName);
49 | }
50 |
51 | var configText =
52 | configTpl.Replace("$port$", settings.GaPort.ToString())
53 | .Replace("$profile$", settings.GaProfile)
54 | .Replace("$app-ids$", settings.GaAppIds);
55 |
56 | File.WriteAllText(App.AppDataDirectory + settings.GaConfigFileName, configText);
57 | Operation.GrantAccessControl(App.AppDataDirectory + settings.GaConfigFileName);
58 | }
59 |
60 | public event Action Started = () => { };
61 | public event Action Stopped = () => { };
62 | public event Action RequireRunas = () => { };
63 |
64 | void startProcess() {
65 | if (Environment.HasShutdownStarted) return;
66 |
67 | stop = false;
68 | process = new Process();
69 |
70 | var si = process.StartInfo;
71 |
72 | si.FileName = App.AppDataDirectory + settings.GaPython27FileName;
73 | si.Arguments = '"' + App.AppDataDirectory + settings.GaScriptFileName + '"';
74 | si.CreateNoWindow = true;
75 | si.UseShellExecute = false;
76 |
77 | process.Start();
78 |
79 | Started();
80 |
81 | process.WaitForExit();
82 |
83 | Stopped();
84 |
85 | if (!stop) {
86 | new Action(() => {
87 | Thread.Sleep(2000);
88 | if ((process == null || process.HasExited) && !startPending) {
89 | startProcess();
90 | }
91 | }).BeginInvoke(null, null);
92 | }
93 | }
94 |
95 | public void Start() {
96 | Stop();
97 | if (settings.GaAppIds != "" && settings.GaAppIds != "goagent") {
98 | new Action(() => {
99 | startPending = true;
100 | Thread.Sleep(100);
101 | startProcess();
102 | startPending = false;
103 | }).BeginInvoke(null, null);
104 | }
105 | }
106 |
107 | public void Stop() {
108 | stop = true;
109 | try {
110 | process.Kill();
111 | }
112 | catch { }
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/Classes/NotificationController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Windows.Forms;
6 | using System.Drawing;
7 | using System.Diagnostics;
8 |
9 | namespace XWall {
10 | partial class MainWindow {
11 | class NotificationController {
12 | NotifyIcon icon;
13 | MainWindow window;
14 | public enum Status { Stopped = 0, Processing = 1, OK = 2, Error = 3 }
15 | public NotifyIcon Tray { get { return icon; } }
16 |
17 | static Icon[] statusIcons = new Icon[] {
18 | resourceManager.GetObject("TrayStoppedIcon") as Icon,
19 | resourceManager.GetObject("TrayProcessingIcon") as Icon,
20 | resourceManager.GetObject("TrayOKIcon") as Icon,
21 | resourceManager.GetObject("TrayErrorIcon") as Icon
22 | };
23 |
24 | public NotificationController(MainWindow window) {
25 | this.window = window;
26 | icon = new NotifyIcon();
27 | icon.Visible = true;
28 |
29 | icon.DoubleClick += (sender, e) => {
30 | window.WindowState = System.Windows.WindowState.Normal;
31 | window.Activate();
32 | };
33 |
34 | icon.BalloonTipClicked += (sender, e) => {
35 | window.WindowState = System.Windows.WindowState.Normal;
36 | window.Activate();
37 | };
38 |
39 | var menu = new ContextMenu();
40 |
41 | // Add Rules
42 |
43 | menu.MenuItems.Add(resources["AddRules"] as string, (sender, e) => {
44 | Rules.OpenEditor(false);
45 | });
46 |
47 | // Proxy Type
48 |
49 | menu.MenuItems.Add(window.proxyTypeContextMenu);
50 |
51 | // Proxy Mode
52 |
53 | var proxyModeNormalItem = new MenuItem(resources["Normal"] as string);
54 | var proxyModeForwardAllItem=new MenuItem(resources["ForwardAll"] as string);
55 |
56 | var proxyModeCheckSwitcher = new Action(() => {
57 | proxyModeNormalItem.Checked = !settings.ForwardAll;
58 | proxyModeForwardAllItem.Checked = settings.ForwardAll;
59 | });
60 |
61 | proxyModeCheckSwitcher();
62 |
63 | settings.PropertyChanged += (sender, e) => {
64 | if (e.PropertyName == "ForwardAll") {
65 | proxyModeCheckSwitcher();
66 | }
67 | };
68 |
69 | proxyModeNormalItem.Click += (sender, e) => {
70 | if (settings.ForwardAll) {
71 | settings.ForwardAll = false;
72 | }
73 | };
74 |
75 | proxyModeForwardAllItem.Click += (sender, e) => {
76 | if (!settings.ForwardAll) {
77 | settings.ForwardAll = true;
78 | }
79 | };
80 |
81 | proxyModeNormalItem.RadioCheck = true;
82 | proxyModeForwardAllItem.RadioCheck = true;
83 |
84 | var proxyModeMenuItem = new MenuItem(resources["ProxyMode"] as string, new MenuItem[]{ proxyModeNormalItem, proxyModeForwardAllItem });
85 |
86 | menu.MenuItems.Add(proxyModeMenuItem);
87 |
88 | // Profiles
89 |
90 | menu.MenuItems.Add(window.profileContextMenu);
91 |
92 | // Restart Application
93 | menu.MenuItems.Add(resources["Restart_Text"] as string, (sender, e) =>
94 | {
95 | Process.Start(System.Windows.Forms.Application.ExecutablePath, "restart");
96 | App.Current.Shutdown();
97 | });
98 |
99 | // Exit
100 |
101 | menu.MenuItems.Add(resources["Exit"] as string, (sender, e) => {
102 | System.Windows.Application.Current.Shutdown();
103 | });
104 |
105 |
106 | // End
107 |
108 | icon.ContextMenu = menu;
109 |
110 | SetStatus(settings.ProxyType, Status.Stopped, resources["NotConnected"] as string);
111 | System.Windows.Application.Current.Exit += (sender, e) => {
112 | icon.Dispose();
113 | };
114 | }
115 |
116 | public void SendMessage(string title, string details, ToolTipIcon tipIcon = ToolTipIcon.Info) {
117 | icon.ShowBalloonTip(0, title, details, tipIcon);
118 | }
119 |
120 | public void SetStatus(string type, Status status, string message = null, string tip = null, ToolTipIcon tipIcon = ToolTipIcon.Info) {
121 | try {
122 | if (message != null) {
123 | window.sshStatusTextBlock.Text = message;
124 | }
125 |
126 | if (type == settings.ProxyType) {
127 | icon.Icon = statusIcons[(int)status];
128 | icon.Text = settings.ProxyType == "SSH" && message != null ? resources["XWall"] as string + " - " + message : resources["XWall"] as string;
129 | }
130 |
131 | if (tip != null)
132 | icon.ShowBalloonTip(0, message, tip, tipIcon);
133 | }
134 | catch { }
135 | }
136 | }
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/src/Classes/Plink.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Net;
7 | using System.Text;
8 | using System.Text.RegularExpressions;
9 | using System.Threading;
10 | using System.Windows;
11 | using XWall.Properties;
12 |
13 | namespace XWall {
14 | class Plink {
15 | static Settings settings = Settings.Default;
16 | static ResourceDictionary resources = App.Current.Resources;
17 | Process process;
18 | int reconnectPeriod;
19 | bool isLastSuccess;
20 | bool toReconnect;
21 | int portCloseCount;
22 | Timer processCheckTimer;
23 | public bool IsReconnecting = false;
24 | public bool IsConnecting = false;
25 | public bool IsConnected = false;
26 | public bool IsNormallyStopped = false;
27 | Action stopReconnect;
28 |
29 | public Plink() {
30 | Operation.KillProcess(settings.PlinkFileName);
31 | App.Current.Exit += (sender, e) => {
32 | Stop();
33 | };
34 | }
35 |
36 | void startProcess() {
37 | startProcess(false);
38 | }
39 |
40 | public static bool CheckSettings() {
41 | return
42 | settings.SshServer != "" &&
43 | settings.SshPort > 0 &&
44 | settings.SshUsername != "" &&
45 | settings.SshPassword != "" &&
46 | settings.SshSocksPort > 0;
47 | }
48 |
49 | void startProcess(bool isReconnect) {
50 | if (Environment.HasShutdownStarted) return;
51 |
52 | Thread.Sleep(10);
53 |
54 | isLastSuccess = false;
55 | toReconnect = true;
56 | IsConnecting = true;
57 | IsNormallyStopped = false;
58 | portCloseCount = 0;
59 |
60 | Started();
61 | process = new Process();
62 |
63 | var si = process.StartInfo;
64 | si.FileName = settings.SshUsePlonk ? settings.PlonkFileName : settings.PlinkFileName;
65 | if (settings.SshUsePrivateKeyLogin == true){
66 | si.Arguments = String.Format(
67 | "-v -x -a -T -N{0}{1} -l {2} -i {3} -P {4} -D {5} {6}",
68 | settings.SshCompression ? " -C" : "",
69 | settings.SshUsePlonk ? " -z" + (settings.SshPlonkKeyword.Trim() != "" ? " -Z " + settings.SshPlonkKeyword : "") : "",
70 | settings.SshUsername,
71 | settings.SshPassword,
72 | settings.SshPort,
73 | "127.0.0.1:" + settings.SshSocksPort,
74 | settings.SshServer
75 | );
76 | }
77 | else
78 | {
79 | si.Arguments = String.Format(
80 | "-v -x -a -T -N{0}{1} -l {2} -pw {3} -P {4} -D {5} {6}",
81 | settings.SshCompression ? " -C" : "",
82 | settings.SshUsePlonk ? " -z" + (settings.SshPlonkKeyword.Trim() != "" ? " -Z " + settings.SshPlonkKeyword : "") : "",
83 | settings.SshUsername,
84 | settings.SshPassword,
85 | settings.SshPort,
86 | "127.0.0.1:" + settings.SshSocksPort,
87 | settings.SshServer
88 | );
89 | }
90 |
91 |
92 | si.RedirectStandardOutput = true;
93 | si.RedirectStandardInput = true;
94 | si.RedirectStandardError = true;
95 | si.CreateNoWindow = true;
96 | si.UseShellExecute = false;
97 |
98 | process.OutputDataReceived += onOutputDataReceived;
99 | process.ErrorDataReceived += onErrorDataReceived;
100 |
101 | Error = null;
102 | try {
103 | process.Start();
104 | process.BeginOutputReadLine();
105 | process.BeginErrorReadLine();
106 |
107 | processCheckTimer = new Timer((o) => {
108 | if (process == null || process.HasExited) {
109 | IsConnected = false;
110 | IsConnecting = false;
111 | Disconnected(isLastSuccess, isReconnect);
112 | disposeProcessCheckTimer();
113 | }
114 | }, null, 0, 1000);
115 |
116 | process.WaitForExit(settings.PlinkConnectTimeout * 1000);
117 | if (process != null && !process.HasExited) {
118 | if (IsConnected) {
119 | process.WaitForExit();
120 | }
121 | else {
122 | try {
123 | process.Kill();
124 | }
125 | catch { }
126 | }
127 | }
128 | }
129 | catch { }
130 |
131 | IsConnected = false;
132 | IsConnecting = false;
133 | Disconnected(isLastSuccess, isReconnect);
134 | processCheckTimer.Dispose();
135 |
136 | if (toReconnect) {
137 | var stopReconnectingHandler = reconnect();
138 | if (stopReconnectingHandler != null) {
139 | stopReconnect = stopReconnectingHandler;
140 | }
141 | }
142 | }
143 |
144 | void disposeProcessCheckTimer() {
145 | if (processCheckTimer != null) {
146 | processCheckTimer.Dispose();
147 | }
148 | }
149 |
150 | public void Start() {
151 | reconnectPeriod = 1;
152 | Stop();
153 | if (!CheckSettings()) return;
154 | new Action(() => {
155 | Thread.Sleep(100);
156 | startProcess();
157 | }).BeginInvoke(null, null);
158 | }
159 |
160 | public void Stop(bool toReconnect = false) {
161 | IsNormallyStopped = true;
162 | this.toReconnect = toReconnect;
163 |
164 | if (IsReconnecting) {
165 | stopReconnect();
166 | }
167 |
168 | try {
169 | process.Kill();
170 | }
171 | catch { }
172 | }
173 |
174 | Action reconnect() {
175 | if (IsReconnecting) {
176 | //new Action(() => {
177 | // Thread.Sleep(1000);
178 | // reconnect();
179 | //}).BeginInvoke(null, null);
180 | return null;
181 | }
182 |
183 |
184 | if (settings.SshAutoReconnect && (settings.SshReconnectAnyCondition || Error == null)) {
185 | var stopReconnect = false;
186 | IsReconnecting = true;
187 | //StopReconnect = false;
188 |
189 | new Action(() => {
190 | Thread.Sleep(500);
191 |
192 | if (stopReconnect) {
193 | return;
194 | }
195 |
196 | var time = reconnectPeriod;
197 |
198 | if (reconnectPeriod < settings.MaxReconnectPeriod)
199 | reconnectPeriod *= 2;
200 |
201 | while (time > 0) {
202 | ReconnectCountingDown(time--);
203 | Thread.Sleep(1000);
204 | if (stopReconnect) {
205 | return;
206 | }
207 | //if started by user or something elses while counting.
208 | if (process != null && !process.HasExited || !toReconnect) {
209 | IsReconnecting = false;
210 | return;
211 | }
212 | }
213 |
214 | IsReconnecting = false;
215 |
216 | if (!CheckSettings()) {
217 | Disconnected(false, true);
218 | return;
219 | }
220 |
221 | startProcess(true);
222 | }).BeginInvoke(null, null);
223 |
224 | return () => {
225 | stopReconnect = true;
226 | IsReconnecting = false;
227 | Disconnected(false, true);
228 | };
229 | }
230 | else {
231 | return null;
232 | }
233 | }
234 |
235 | void onOutputDataReceived(object sender, DataReceivedEventArgs e) {
236 | //Console.WriteLine("D: " + e.Data);
237 | }
238 |
239 | DateTime lastPortCloseTime;
240 |
241 | void onErrorDataReceived(object sender, DataReceivedEventArgs e) {
242 | var line = e.Data;
243 | if (line == null) return;
244 |
245 | Console.WriteLine("E: " + line);
246 |
247 | if (new Regex(@"^Local port .+ SOCKS dynamic forwarding").IsMatch(line)) {
248 | reconnectPeriod = 1;
249 | isLastSuccess = true;
250 | IsConnected = true;
251 | IsConnecting = false;
252 | Connected();
253 | }
254 | else if (line.StartsWith("Nothing left to send, closing channel")) {
255 | portCloseCount = Math.Min(1, portCloseCount + 1);
256 | }
257 | else if (line.StartsWith("Forwarded port closed")) {
258 | var now = DateTime.Now;
259 |
260 | if (lastPortCloseTime == null || now - lastPortCloseTime >= new TimeSpan(2000000)) {
261 | lastPortCloseTime = now;
262 | if (--portCloseCount < -settings.SshAbortionBeforeReconnect && settings.SshAutoReconnect) {
263 | Stop(true);
264 | }
265 | }
266 | }
267 | else if (line.StartsWith("The server's host key is not cached in the registry.")) {
268 | process.StandardInput.WriteLine("y");
269 | }
270 | else if (line.StartsWith("Password authentication failed")) {
271 | Error = resources["PlinkAuthFailed"] as string;
272 | Stop(settings.SshReconnectAnyCondition);
273 | }
274 | else if (line.StartsWith("Server refused our key"))
275 | {
276 | Error = resources["SshPrivKeyRefused"] as string;
277 | Stop(settings.SshReconnectAnyCondition);
278 |
279 | }
280 | else {
281 | var match = new Regex(@"Failed to connect to (.+?): Network error: No route to host").Match(line);
282 | if (match.Success) {
283 | var ip = match.Groups[1].Value;
284 | var si = new ProcessStartInfo("arp", "-d " + ip);
285 | si.CreateNoWindow = true;
286 | si.UseShellExecute = false;
287 | Process.Start(si);
288 | }
289 | match = new Regex(@"Unable to use key file (.+?)").Match(line);
290 | if (match.Success)
291 | {
292 | Error = resources["SshPrivKeyFormatError"] as string;
293 | Stop(settings.SshReconnectAnyCondition);
294 | }
295 | }
296 | //else if (line.StartsWith("FATAL ERROR:")) {
297 | // Stop(settings.SshReconnectAnyCondition);
298 | //}
299 | }
300 |
301 | public string Error;
302 |
303 | public event Action Started = () => { };
304 | public event Action Connected = () => { };
305 |
306 | public delegate void DisconnectHandler(bool isLastSuccess, bool isReconnect);
307 | public event DisconnectHandler Disconnected = (isLastSuccess, isReconnect) => { };
308 |
309 | public delegate void CountingDownHandler(int seconds);
310 | public event CountingDownHandler ReconnectCountingDown = (seconds) => { };
311 | }
312 | }
313 |
--------------------------------------------------------------------------------
/src/Classes/Privoxy.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading;
8 | using System.Windows;
9 | using XWall.Properties;
10 |
11 | namespace XWall {
12 | class Privoxy {
13 | static Settings settings = Settings.Default;
14 | static ResourceDictionary resources = App.Current.Resources;
15 | Process process;
16 | bool stop;
17 | bool lastStopWithError = false;
18 |
19 | public Privoxy() {
20 | Operation.KillProcess(settings.PrivoxyFileName);
21 | App.Current.Exit += (sender, e) => {
22 | Stop();
23 | };
24 |
25 | settings.PropertyChanged += (sender, e) => {
26 | switch (e.PropertyName) {
27 | case "ProxyPort": break;
28 | case "ListenToLocalOnly": break;
29 | case "UseIntranetProxy": break;
30 | case "IntranetProxyServer": break;
31 | case "IntranetProxyPort": break;
32 | default: return;
33 | }
34 |
35 | GenerateConfigFile();
36 | };
37 |
38 | //if (!File.Exists(settings.PrivoxyConfigFileName))
39 | GenerateConfigFile();
40 | }
41 |
42 | public static void GenerateConfigFile() {
43 | /* !DEBUG CODE
44 | return;
45 | //*/
46 | //var defaultProxy = Operation.Proxies.DefaultProxy;
47 | var text =
48 | "listen-address " + (settings.ListenToLocalOnly ? "127.0.0.1:" : ":") + settings.ProxyPort + "\r\n" +
49 | "forwarded-connect-retries " + settings.ForwardConnectionRetries + "\r\n" +
50 | "forward / " + (settings.UseIntranetProxy ? (String.IsNullOrEmpty(settings.IntranetProxyServer) ? "127.0.0.1" : settings.IntranetProxyServer) + ":" + settings.IntranetProxyPort : ".") + "\r\n" +
51 | "keep-alive-timeout " + settings.PrivoxyKeepAliveTimeout + "\r\n" +
52 | "actionsfile " + App.AppDataDirectory + settings.ConfigsFolderName + settings.PrivoxyOnlineForwardActionFileName + "\r\n" +
53 | "actionsfile " + App.AppDataDirectory + settings.ConfigsFolderName + settings.PrivoxyOnlineDefaultActionFileName + "\r\n" +
54 | "actionsfile " + App.AppDataDirectory + settings.ConfigsFolderName + settings.PrivoxyCustomForwardActionFileName + "\r\n" +
55 | "actionsfile " + App.AppDataDirectory + settings.ConfigsFolderName + settings.PrivoxyCustomDefaultActionFileName + "\r\n" +
56 | "templdir " + App.AppDataDirectory + settings.ResourcesFolderName + settings.PrivoxyTemplatesFolderName + "\r\n";
57 | File.WriteAllText(App.AppDataDirectory + settings.ConfigsFolderName + settings.PrivoxyConfigFileName, text);
58 | Operation.GrantAccessControl(App.AppDataDirectory + settings.ConfigsFolderName + settings.PrivoxyConfigFileName);
59 | }
60 |
61 | void startProcess() {
62 | if (Environment.HasShutdownStarted) return;
63 |
64 | stop = false;
65 | process = new Process();
66 |
67 | var si = process.StartInfo;
68 | si.FileName = settings.PrivoxyFileName;
69 | si.Arguments = '"' + App.AppDataDirectory + settings.ConfigsFolderName + settings.PrivoxyConfigFileName + '"';
70 | si.CreateNoWindow = true;
71 | si.UseShellExecute = false;
72 | process.Start();
73 | process.WaitForExit();
74 |
75 | var code = process.HasExited ? process.ExitCode : 0;
76 | if (code == 1) {
77 | if (!lastStopWithError) {
78 | lastStopWithError = true;
79 | new Action(() => {
80 | Thread.Sleep(1000);
81 | MessageBox.Show(resources["PrivoxyErrorExitMessage"] as string);
82 | }).BeginInvoke(null, null);
83 | }
84 | }
85 | else lastStopWithError = false;
86 |
87 | if (!stop) {
88 | new Action(() => {
89 | Thread.Sleep(2000);
90 | if (process == null || process.HasExited)
91 | startProcess();
92 | }).BeginInvoke(null, null);
93 | }
94 | }
95 |
96 | public void Start() {
97 | Stop();
98 | new Action(startProcess).BeginInvoke(null, null);
99 | }
100 |
101 | public void Stop() {
102 | stop = true;
103 | try {
104 | process.Kill();
105 | }
106 | catch { }
107 | }
108 |
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/Classes/Profiles.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Linq;
5 | using System.Text;
6 | using XWall.Properties;
7 |
8 | namespace XWall {
9 | class Profile {
10 | static Settings settings = Settings.Default;
11 |
12 | public abstract class DefaultProfile {
13 | public string Name;
14 | public override string ToString() {
15 | return Name;
16 | }
17 | public abstract string ToSettingString();
18 | }
19 |
20 | public class SshProfilesCollection {
21 | public BindingList Items;
22 |
23 | public SshProfilesCollection(string settingName) {
24 | Items = new BindingList();
25 |
26 | var str = settings[settingName] as string;
27 |
28 | if (str != "") {
29 | var profileStrs = str.Split('\n');
30 | for (int i = 0; i < profileStrs.Length; i++) {
31 | var profile = new SshProfile(profileStrs[i]);
32 | Items.Add(profile);
33 | }
34 | }
35 |
36 | Items.ListChanged += (sender, e) => {
37 | var profileStrs = new List();
38 | for (int i = 0; i < Items.Count; i++) {
39 | profileStrs.Add(Items[i].ToSettingString());
40 | }
41 | var newSetting = String.Join("\n", profileStrs.ToArray());
42 |
43 | if (settings[settingName] as string != newSetting) {
44 | settings[settingName] = newSetting;
45 | }
46 | };
47 | }
48 | }
49 |
50 | public class SshProfile : DefaultProfile {
51 | public string Server;
52 | public int Port;
53 | public string Username;
54 | public string Password;
55 | public SshProfile(string info = "") {
56 | if (String.IsNullOrEmpty(info)) {
57 | Name = "";
58 | Server = "";
59 | Port = 22;
60 | Username = "";
61 | Password = "";
62 | }
63 | else {
64 | var infos = info.Split('\t');
65 | Name = infos[0];
66 | Server = infos[1];
67 | Port = int.Parse(infos[2]);
68 | Username = infos[3];
69 | Password = infos[4];
70 | }
71 | }
72 | public SshProfile(SshProfile profile) {
73 | Name = profile.Name;
74 | Server = profile.Server;
75 | Port = profile.Port;
76 | Username = profile.Username;
77 | Password = profile.Password;
78 | }
79 | public override string ToSettingString() {
80 | return String.Join("\t", new string[] { Name, Server, Port.ToString(), Username, Password });
81 | }
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/Classes/Settings.cs:
--------------------------------------------------------------------------------
1 | using System.Configuration;
2 | using System.Diagnostics;
3 | using System.IO;
4 | using System.Text.RegularExpressions;
5 | using System.Windows;
6 | namespace XWall.Properties {
7 |
8 |
9 | // This class allows you to handle specific events on the settings class:
10 | // The SettingChanging event is raised before a setting's value is changed.
11 | // The PropertyChanged event is raised after a setting's value is changed.
12 | // The SettingsLoaded event is raised after the setting values are loaded.
13 | // The SettingsSaving event is raised before the setting values are saved.
14 | internal sealed partial class Settings {
15 |
16 | public bool AutoSave { get; set; }
17 |
18 | public Settings() {
19 | // // To add event handlers for saving and changing settings, uncomment the lines below:
20 | //
21 | // this.SettingChanging += this.SettingChangingEventHandler;
22 | //
23 | // this.SettingsSaving += this.SettingsSavingEventHandler;
24 | //
25 |
26 | AutoSave = true;
27 |
28 | this.PropertyChanged += (sender, e) => {
29 | if (AutoSave) {
30 | Settings.Default.Save();
31 | }
32 | };
33 | }
34 |
35 | public bool Export(string path) {
36 | try {
37 | File.Copy(GetDefaultExeConfigPath(ConfigurationUserLevel.PerUserRoamingAndLocal), path, true);
38 | return true;
39 | }
40 | catch {
41 | return false;
42 | }
43 | }
44 |
45 | public bool Import(string path) {
46 | AutoSave = false;
47 | try {
48 | File.Copy(path, GetDefaultExeConfigPath(ConfigurationUserLevel.PerUserRoamingAndLocal), true);
49 | return true;
50 | }
51 | catch {
52 | return false;
53 | }
54 | }
55 |
56 | public static string GetDefaultExeConfigPath(ConfigurationUserLevel userLevel) {
57 | try {
58 | var UserConfig = ConfigurationManager.OpenExeConfiguration(userLevel);
59 | return UserConfig.FilePath;
60 | }
61 | catch (ConfigurationException e) {
62 | return e.Filename;
63 | }
64 | }
65 |
66 | private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
67 | // Add code to handle the SettingChangingEvent event here.
68 | }
69 |
70 | private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
71 | // Add code to handle the SettingsSaving event here.
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/CustomRulesEditor.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/src/CustomRulesEditor.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Text.RegularExpressions;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 | using XWall.Properties;
15 |
16 | namespace XWall {
17 | ///
18 | /// Interaction logic for CustomRulesEditor.xaml
19 | ///
20 | public partial class CustomRulesEditor : Window {
21 | static Settings settings = Settings.Default;
22 | static ResourceDictionary resources = App.Current.Resources;
23 | string lastCopied;
24 | Regex urlRe = new Regex(@"(?:[a-z0-9-]+://)?((?:(?:[a-z0-9-]+\.)+[a-z]{2,}|\d{1,3}(?:\.\d{1,3}){3})(?::\d+)?)(?:[/\s]|$)", RegexOptions.IgnoreCase);
25 | Regex domainRe = new Regex(@"^(?:[a-z0-9-]+\.)+[a-z]{2,}$");
26 | Regex ruleRe = new Regex(@"^(?:(?:www\.)?([a-z0-9-.\*\?]+))?((?::\d+)?(?:/(.*))?)$", RegexOptions.IgnoreCase);
27 |
28 | public CustomRulesEditor() {
29 | InitializeComponent();
30 | InitializeBinding();
31 |
32 | //context menu
33 | customRulesListBox.ContextMenu = new ContextMenu();
34 | var deleteMenuItem = new MenuItem();
35 | deleteMenuItem.Header = resources["DeleteSelected"] as string;
36 | deleteMenuItem.Click += (sender, e) => {
37 | var rules = Rules.CustomRules.Rules;
38 | var items = new List();
39 | foreach (var item in customRulesListBox.SelectedItems)
40 | items.Add(item);
41 | foreach (var item in items)
42 | rules.Remove(item as string);
43 | };
44 | customRulesListBox.ContextMenu.Items.Add(deleteMenuItem);
45 |
46 | deleteMenuItem.IsEnabled = false;
47 |
48 | customRulesListBox.SelectionChanged += (sender, e) => {
49 | deleteMenuItem.IsEnabled = customRulesListBox.SelectedItems.Count > 0;
50 | };
51 | }
52 |
53 | private void onWindowActivated(object sender, EventArgs e) {
54 | var copied = Clipboard.GetText();
55 |
56 | if (!String.IsNullOrEmpty(copied) && copied != lastCopied) {
57 | lastCopied = copied;
58 | var match = urlRe.Match(copied);
59 | if (match.Success)
60 | newRuleTextBox.Text = match.Groups[1].Value;
61 | }
62 |
63 | newRuleTextBox.SelectAll();
64 | newRuleTextBox.Focus();
65 | }
66 |
67 | private void onAddClick(object sender, RoutedEventArgs e) {
68 | addNewRule();
69 | }
70 |
71 | private void onClosing(object sender, System.ComponentModel.CancelEventArgs e) {
72 | e.Cancel = true;
73 | Hide();
74 | }
75 |
76 | private void onNewRuleTextBoxKeyDown(object sender, KeyEventArgs e) {
77 | if (e.Key == Key.Enter)
78 | addNewRule();
79 | }
80 |
81 | private void addNewRule() {
82 | var rule = newRuleTextBox.Text.Trim();
83 | var withExc = rule.StartsWith("!");
84 | if (withExc) {
85 | rule = rule.Substring(1);
86 | }
87 |
88 | if (rule == "" && !withExc) {
89 | MessageBox.Show(resources["EnterRuleMessage"] as string, resources["CustomRulesEditorTitle"] as string, MessageBoxButton.OK, MessageBoxImage.Warning);
90 | newRuleTextBox.Text = "";
91 | newRuleTextBox.Focus();
92 | return;
93 | }
94 |
95 | var match = ruleRe.Match(rule);
96 |
97 | if (rule == "" || !match.Success) {
98 | MessageBox.Show(resources["InvalidRuleMessage"] as string, resources["CustomRulesEditorTitle"] as string, MessageBoxButton.OK, MessageBoxImage.Error);
99 | newRuleTextBox.SelectAll();
100 | newRuleTextBox.Focus();
101 | return;
102 | }
103 | else {
104 | var pathReStr = match.Groups[3].Value;
105 |
106 | try {
107 | new Regex(pathReStr);
108 | }
109 | catch {
110 | MessageBox.Show(resources["InvalidRulePathMessage"] as string, resources["CustomRulesEditorTitle"] as string, MessageBoxButton.OK, MessageBoxImage.Error);
111 | newRuleTextBox.SelectAll();
112 | newRuleTextBox.Focus();
113 | return;
114 | }
115 | }
116 |
117 | if (settings.CustomRulesAddSubdomains) {
118 | var domain = match.Groups[1].Value.ToLower();
119 | var other = match.Groups[2].Value;
120 |
121 | if (String.IsNullOrEmpty(other) && domainRe.IsMatch(domain))
122 | rule = "." + domain;
123 | }
124 |
125 | if (withExc)
126 | rule = "!" + rule;
127 |
128 | var result = Rules.CustomRules.Add(rule);
129 |
130 | if (!result) {
131 | MessageBox.Show(resources["RuleExistsMessage"] as string, resources["CustomRulesEditorTitle"] as string, MessageBoxButton.OK, MessageBoxImage.Warning);
132 | newRuleTextBox.SelectAll();
133 | newRuleTextBox.Focus();
134 | return;
135 | }
136 |
137 | newRuleTextBox.Text = "";
138 |
139 | if (customRulesExpander.IsExpanded) {
140 | var lastIndex = customRulesListBox.Items.Count - 1;
141 | customRulesListBox.SelectedIndex = lastIndex;
142 | customRulesListBox.ScrollIntoView(customRulesListBox.SelectedItem);
143 | }
144 | else Hide();
145 | }
146 |
147 | private void onWindowLoaded(object sender, RoutedEventArgs e) {
148 | customRulesListBox.ItemsSource = Rules.CustomRules.Rules;
149 | }
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/src/GAEWizard.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | 1-10
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | China (中国)
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/src/GAEWizard.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Text;
7 | using System.Text.RegularExpressions;
8 | using System.Threading;
9 | using System.Web;
10 | using System.Windows;
11 | using System.Windows.Controls;
12 | using System.Windows.Data;
13 | using System.Windows.Documents;
14 | using System.Windows.Input;
15 | using System.Windows.Media;
16 | using System.Windows.Media.Animation;
17 | using System.Windows.Media.Imaging;
18 | using System.Windows.Navigation;
19 | using System.Windows.Shapes;
20 | using XWall.Properties;
21 |
22 | namespace XWall {
23 | ///
24 | /// Interaction logic for MainWindow.xaml
25 | ///
26 | public partial class GAEWizard : Window {
27 | static Settings settings = Settings.Default;
28 | static ResourceDictionary resources = App.Current.Resources;
29 |
30 | GAESimulator gaeSimulator = new GAESimulator();
31 | Action gaeSimulatorVerifyCallback;
32 |
33 | public GAEWizard() {
34 | InitializeComponent();
35 |
36 | prefixTextBox.Text = "ga-" + randomString();
37 | appsNumberTextBox.Text = Math.Max(settings.GaDefaultAppsNumber, settings.GaAppIds.Split('|').Length).ToString();
38 | currentState = homePanel;
39 | Loaded += (sender, e) => {
40 | Rules.Enabled = false;
41 | };
42 |
43 | Closed += (sender, e) => {
44 | Rules.Enabled = true;
45 | gaeSimulator.Stop();
46 | };
47 | }
48 |
49 | UIElement currentState;
50 |
51 | void showStage(UIElement ele) {
52 | if (ele != currentState) {
53 | currentState.Visibility = Visibility.Collapsed;
54 | currentState = ele;
55 | currentState.Visibility = Visibility.Visible;
56 | }
57 | }
58 |
59 | private void processButton_Click(object sender, RoutedEventArgs e) {
60 | var prefix = prefixTextBox.Text.Trim().ToLower();
61 |
62 | if (!new Regex(@"^[0-9a-z\-]{1,28}$").IsMatch(prefix)) {
63 | MessageBox.Show(resources["InvalidGaeAppIdPrefixMessage"] as string);
64 | return;
65 | }
66 |
67 | var email = emailTextBox.Text.Trim();
68 |
69 | if (!new Regex(@"^[0-9a-zA-Z\-.]+@[0-9a-zA-Z\-.]+$").IsMatch(email)) {
70 | MessageBox.Show(resources["InvalidGaeEmailMessage"] as string);
71 | return;
72 | }
73 |
74 | var password = passwordBox.Password;
75 |
76 | if (password.Length == 0) {
77 | MessageBox.Show(resources["EmptyGaePasswordMessage"] as string);
78 | return;
79 | }
80 |
81 | int appsNumber;
82 |
83 | var appsNumberParsed = int.TryParse(appsNumberTextBox.Text, out appsNumber);
84 |
85 | if (!(appsNumberParsed && appsNumber < 11 && appsNumber > 0)) {
86 | MessageBox.Show(resources["InvalidGaeAppsNumberMessage"] as string);
87 | return;
88 | }
89 |
90 | showStage(processingPanel);
91 |
92 | processingProgressBar.IsIndeterminate = true;
93 | processingStatusTextBlock.Text = resources["LoggingIn"] as string;
94 |
95 | gaeSimulator = new GAESimulator();
96 |
97 | gaeSimulator.Login(email, password, (success, data) => {
98 | if (!success) {
99 | MessageBox.Show(resources["FailedToLoginMessage"] as string);
100 | showStage(homePanel);
101 | return;
102 | }
103 |
104 | gaeSimulator.CheckAppIdAvailability(prefix + "-1", (valid) => {
105 | if (!valid) {
106 | var r = MessageBox.Show(resources["InvalidGaeAppIdMessage"] as string, resources["XWall"] as string, MessageBoxButton.YesNo);
107 | if (r == MessageBoxResult.Yes) {
108 | prefix =
109 | prefixTextBox.Text = "ga-" + randomString();
110 | }
111 | showStage(homePanel);
112 | return;
113 | }
114 |
115 | var ids = new List();
116 | var noneDeployedIds = new List(data.NoneDeployedAppIds);
117 |
118 | if (data.AppIds.Length > 0) {
119 | var r = MessageBox.Show(resources["GaeAppsCreatedMessage"] as string, resources["XWall"] as string, MessageBoxButton.YesNoCancel);
120 | if (r == MessageBoxResult.Cancel) {
121 | showStage(homePanel);
122 | return;
123 | }
124 | else if (r == MessageBoxResult.Yes) {
125 | ids.AddRange(data.AppIds.Take(appsNumber));
126 | }
127 | }
128 |
129 | var createNumber = Math.Min(data.RemainingNumber, appsNumber - ids.Count);
130 |
131 | processingProgressBar.IsIndeterminate = false;
132 | processingProgressBar.Value = 0;
133 |
134 | gaeSimulator.VerificationRequired += (callback) => {
135 | showStage(verifyPanel);
136 | gaeSimulatorVerifyCallback = callback;
137 | };
138 |
139 | gaeSimulator.CreateApps(prefix, createNumber, (done, i, id, error) => {
140 | if (error) {
141 | showStage(homePanel);
142 | return;
143 | }
144 |
145 | if (!done) {
146 | processingStatusTextBlock.Text = String.Format(resources["CreatingGaeApps"] as string, i + 1, createNumber);
147 | setProgressBarValue(processingProgressBar, i * 1.0 / createNumber * 20);
148 |
149 | ids.Add(id);
150 | noneDeployedIds.Add(id);
151 | }
152 | else {
153 | string[] idsArr;
154 | if (
155 | data.AppIds.Length != data.NoneDeployedAppIds.Length &&
156 | MessageBox.Show(resources["DeployDeployedGaeAppsMessage"] as string, resources["XWall"] as string, MessageBoxButton.YesNo) == MessageBoxResult.Yes
157 | ) {
158 | idsArr = ids.ToArray();
159 | }
160 | else {
161 | idsArr = (
162 | from appId in ids
163 | where noneDeployedIds.Contains(appId)
164 | select appId
165 | ).ToArray();
166 | }
167 |
168 | gaeSimulator.Deploy(email, password, idsArr, (dDone, dI, currentProgress, err) => {
169 | Dispatcher.Invoke(new Action(() => {
170 | if (err) {
171 | showStage(homePanel);
172 | return;
173 | }
174 |
175 | if (!dDone) {
176 | processingStatusTextBlock.Text = String.Format(resources["DeployingGaeApps"] as string, dI + 1, idsArr.Length);
177 | setProgressBarValue(processingProgressBar, (dI + currentProgress) / idsArr.Length * 80 + 20);
178 | }
179 | else {
180 | processingStatusTextBlock.Text = resources["GaeWizardFinished"] as string;
181 | setProgressBarValue(processingProgressBar, 100);
182 | settings.GaAppIds = string.Join("|", ids.ToArray());
183 | Rules.Enabled = true;
184 | new Action(() => {
185 | Thread.Sleep(3000);
186 | Dispatcher.BeginInvoke(new Action(() => {
187 | Close();
188 | }));
189 | }).BeginInvoke(null, null);
190 | }
191 | }));
192 | });
193 | }
194 | });
195 | });
196 | });
197 | }
198 |
199 | void setProgressBarValue(ProgressBar progressBar, double value) {
200 | var duration = TimeSpan.FromMilliseconds(500);
201 | var animation = new DoubleAnimation(value, duration);
202 | progressBar.BeginAnimation(ProgressBar.ValueProperty, animation);
203 | }
204 |
205 | private string randomString(int n = 8) {
206 | var chrs = "abcdefghijklmnopqrstuvwxyz1234567890";
207 | var str = "";
208 | var rnd = new Random();
209 | for (int i = 0; i < n; i++) {
210 | str += chrs[rnd.Next(chrs.Length)];
211 | }
212 | return str;
213 | }
214 |
215 | private void sendVerificationButton_Click(object sender, RoutedEventArgs e) {
216 | var method = (bool)smsRadio.IsChecked ? "SMS" : "CTC";
217 | var country = "CN";
218 | var phone = verifyPhoneTextBox.Text.Trim();
219 |
220 | if (!new Regex(@"^\d{11}$").IsMatch(phone)) {
221 | MessageBox.Show(resources["GaeInvalidPhoneMessage"] as string);
222 | return;
223 | }
224 |
225 | sendVerifierButton.IsEnabled = false;
226 | sendVerifierButton.Content = resources["Sending"] as string;
227 |
228 | gaeSimulator.SendVerifier(method, country, phone, (success) => {
229 | if (success) {
230 | verifierTextBox.Focus();
231 | verifyButton.IsEnabled = true;
232 | }
233 | else {
234 | MessageBox.Show(resources["GaeFailToSendVerifierMessage"] as string);
235 | }
236 | sendVerifierButton.IsEnabled = true;
237 | sendVerifierButton.Content = resources["Send"] as string;
238 | });
239 | }
240 |
241 | private void verifyButton_Click(object sender, RoutedEventArgs e) {
242 | var verifier = verifierTextBox.Text.Trim();
243 |
244 | if (verifier == "") {
245 | MessageBox.Show(resources["GaeEmptyVerifierMessage"] as string);
246 | return;
247 | }
248 |
249 | verifyButton.IsEnabled = false;
250 | sendVerifierButton.IsEnabled = false;
251 | verifyButton.Content = resources["Verifying"] as string;
252 |
253 | gaeSimulator.Verify(verifier, (success) => {
254 | if (success) {
255 | gaeSimulatorVerifyCallback();
256 | showStage(processingPanel);
257 | }
258 | else {
259 | MessageBox.Show(resources["GaeInvalidVerifierMessage"] as string);
260 | }
261 |
262 | verifierTextBox.Text = "";
263 | verifyButton.IsEnabled = true;
264 | sendVerifierButton.IsEnabled = true;
265 | verifyButton.Content = resources["Verify"] as string;
266 | });
267 | }
268 |
269 | private void passwordBox_KeyDown(object sender, KeyEventArgs e) {
270 | if (e.Key == Key.Enter && processButton.IsEnabled) {
271 | processButton_Click(null, null);
272 | }
273 | }
274 |
275 | private void verifyPhoneTextBox_KeyDown(object sender, KeyEventArgs e) {
276 | if (e.Key == Key.Enter && sendVerifierButton.IsEnabled) {
277 | sendVerificationButton_Click(null, null);
278 | }
279 | }
280 |
281 | private void verifierTextBox_KeyDown(object sender, KeyEventArgs e) {
282 | if (e.Key == Key.Enter && verifyButton.IsEnabled) {
283 | verifyButton_Click(null, null);
284 | }
285 | }
286 |
287 | }
288 | }
289 |
--------------------------------------------------------------------------------
/src/Icons/main.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/Icons/main.ico
--------------------------------------------------------------------------------
/src/Icons/tray.error.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/Icons/tray.error.ico
--------------------------------------------------------------------------------
/src/Icons/tray.ok.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/Icons/tray.ok.ico
--------------------------------------------------------------------------------
/src/Icons/tray.processing.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/Icons/tray.processing.ico
--------------------------------------------------------------------------------
/src/Icons/tray.stopped.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/Icons/tray.stopped.ico
--------------------------------------------------------------------------------
/src/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("X-Wall")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("LunaTech")]
14 | [assembly: AssemblyProduct("X-Wall")]
15 | [assembly: AssemblyCopyright("Copyright © LunaTech 2015")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | [assembly: AssemblyVersion("1.3.*")]
54 | //[assembly: AssemblyVersion("1.0.*")]
55 | //[assembly: AssemblyFileVersion("1.0.*")]
56 | [assembly: GuidAttribute("CEE80EAA-3CD9-425B-8119-F3ECBCB5DB52")]
57 |
--------------------------------------------------------------------------------
/src/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本:4.0.30319.34209
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将会丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace XWall.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// 一个强类型的资源类,用于查找本地化的字符串等。
17 | ///
18 | // 此类是由 StronglyTypedResourceBuilder
19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
21 | // (以 /str 作为命令选项),或重新生成 VS 项目。
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// 返回此类使用的缓存的 ResourceManager 实例。
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("XWall.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// 使用此强类型资源类,为所有资源查找
51 | /// 重写当前线程的 CurrentUICulture 属性。
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// 查找类似于 (Icon) 的 System.Drawing.Icon 类型的本地化资源。
65 | ///
66 | internal static System.Drawing.Icon MainWindowIcon {
67 | get {
68 | object obj = ResourceManager.GetObject("MainWindowIcon", resourceCulture);
69 | return ((System.Drawing.Icon)(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// 查找类似于 (Icon) 的 System.Drawing.Icon 类型的本地化资源。
75 | ///
76 | internal static System.Drawing.Icon TrayErrorIcon {
77 | get {
78 | object obj = ResourceManager.GetObject("TrayErrorIcon", resourceCulture);
79 | return ((System.Drawing.Icon)(obj));
80 | }
81 | }
82 |
83 | ///
84 | /// 查找类似于 (Icon) 的 System.Drawing.Icon 类型的本地化资源。
85 | ///
86 | internal static System.Drawing.Icon TrayOKIcon {
87 | get {
88 | object obj = ResourceManager.GetObject("TrayOKIcon", resourceCulture);
89 | return ((System.Drawing.Icon)(obj));
90 | }
91 | }
92 |
93 | ///
94 | /// 查找类似于 (Icon) 的 System.Drawing.Icon 类型的本地化资源。
95 | ///
96 | internal static System.Drawing.Icon TrayProcessingIcon {
97 | get {
98 | object obj = ResourceManager.GetObject("TrayProcessingIcon", resourceCulture);
99 | return ((System.Drawing.Icon)(obj));
100 | }
101 | }
102 |
103 | ///
104 | /// 查找类似于 (Icon) 的 System.Drawing.Icon 类型的本地化资源。
105 | ///
106 | internal static System.Drawing.Icon TrayStoppedIcon {
107 | get {
108 | object obj = ResourceManager.GetObject("TrayStoppedIcon", resourceCulture);
109 | return ((System.Drawing.Icon)(obj));
110 | }
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Icons\main.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
125 | ..\Icons\tray.error.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
126 |
127 |
128 | ..\Icons\tray.ok.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
129 |
130 |
131 | ..\Icons\tray.processing.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
132 |
133 |
134 | ..\Icons\tray.stopped.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
135 |
136 |
--------------------------------------------------------------------------------
/src/Properties/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
52 |
--------------------------------------------------------------------------------
/src/ShowUpdateLog.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
14 | 0
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/ShowUpdateLog.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Shapes;
14 | using System.Reflection;
15 |
16 | namespace XWall
17 | {
18 | ///
19 | /// ShowUpdateLog.xaml 的交互逻辑
20 | ///
21 | public partial class ShowUpdateLog : Window
22 | {
23 | private Boolean allowClose = false;
24 | public ShowUpdateLog()
25 | {
26 | InitializeComponent();
27 | }
28 |
29 | private void Update_UpdateLogExpander_Collapsed(object sender, RoutedEventArgs e)
30 | {
31 | this.Height = 150;
32 | }
33 |
34 | private void Update_UpdateLogExpander_Expanded(object sender, RoutedEventArgs e)
35 | {
36 | this.Height = 270;
37 | }
38 |
39 | private void Update_Cancel_Click(object sender, RoutedEventArgs e)
40 | {
41 | MainSetting.isUpdateCancel = true;
42 | allowClose = true;
43 | this.Close();
44 | }
45 |
46 | private void Update_Confirm_Click(object sender, RoutedEventArgs e)
47 | {
48 | allowClose = true;
49 | this.Close();
50 | }
51 |
52 | private void Window_Loaded(object sender, RoutedEventArgs e)
53 | {
54 | Update_LocalVerNum.Content = Assembly.GetExecutingAssembly().GetName().Version.ToString();
55 | if (MainSetting.latestVersion != null)
56 | {
57 | Update_OnlineVerNum.Content = MainSetting.latestVersion;
58 | Update_UpdateLogBox.Text = MainSetting.updateLog;
59 | }
60 | Update_UpdateLogBox.IsReadOnly = true;
61 | }
62 |
63 | private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
64 | {
65 | if (allowClose == false)
66 | {
67 | e.Cancel = true;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/X-Wall.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {F70204E7-AD12-4628-B200-D3FA863B3041}
8 | WinExe
9 | Properties
10 | XWall
11 | x-wall
12 | v4.5.1
13 | 512
14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 | 4
16 | true
17 | C:\Projects\X-Wall\X-Wall\publish\
18 | true
19 | Web
20 | true
21 | Background
22 | 7
23 | Days
24 | false
25 | false
26 | true
27 | https://github.com/vilic/x-wall/raw/master/publish/
28 | https://github.com/vilic/x-wall/wiki
29 | https://github.com/vilic/x-wall/issues
30 | X-Wall
31 | 5
32 | 1.0.0.%2a
33 | false
34 | true
35 | true
36 | true
37 |
38 |
39 |
40 | AnyCPU
41 | true
42 | full
43 | false
44 | bin\Debug\
45 | DEBUG;TRACE
46 | prompt
47 | 4
48 | false
49 |
50 |
51 | AnyCPU
52 | pdbonly
53 | true
54 | bin\Release\
55 | TRACE
56 | prompt
57 | 4
58 | false
59 |
60 |
61 | Icons\main.ico
62 |
63 |
64 |
65 |
66 |
67 | 1FD08474BF7B5D529D3892618BCB772218B9720F
68 |
69 |
70 | X-Wall_TemporaryKey.pfx
71 |
72 |
73 | false
74 |
75 |
76 | false
77 |
78 |
79 | LocalIntranet
80 |
81 |
82 | Properties\app.manifest
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | ..\..\dot-net-server\bin\Release\WebDev.WebHost20.dll
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | MSBuild:Compile
107 | Designer
108 |
109 |
110 |
111 | Component
112 |
113 |
114 |
115 |
116 | CustomRulesEditor.xaml
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 | ShowUpdateLog.xaml
125 |
126 |
127 | Designer
128 | MSBuild:Compile
129 |
130 |
131 | Designer
132 | MSBuild:Compile
133 |
134 |
135 | MSBuild:Compile
136 | Designer
137 | PreserveNewest
138 |
139 |
140 | MSBuild:Compile
141 | Designer
142 |
143 |
144 | Designer
145 | MSBuild:Compile
146 |
147 |
148 | MSBuild:Compile
149 | Designer
150 |
151 |
152 | App.xaml
153 | Code
154 |
155 |
156 | GAEWizard.xaml
157 |
158 |
159 | MainWindow.xaml
160 | Code
161 |
162 |
163 |
164 |
165 |
166 |
167 | Code
168 |
169 |
170 | True
171 | True
172 | Resources.resx
173 |
174 |
175 | True
176 | Settings.settings
177 | True
178 |
179 |
180 | ResXFileCodeGenerator
181 | Resources.Designer.cs
182 | Designer
183 |
184 |
185 | Designer
186 |
187 |
188 |
189 | PreserveNewest
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 | SettingsSingleFileGenerator
209 | Settings.Designer.cs
210 | Designer
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | False
232 | .NET Framework 3.5 SP1 Client Profile
233 | false
234 |
235 |
236 | False
237 | .NET Framework 3.5 SP1
238 | true
239 |
240 |
241 |
242 |
243 | PreserveNewest
244 |
245 |
246 | PreserveNewest
247 |
248 |
249 | PreserveNewest
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
271 |
--------------------------------------------------------------------------------
/src/X-Wall.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | C:\Projects\X-Wall\X-Wall\publish\|publish\
5 | https://github.com/vilic/x-wall/raw/master/publish/
6 | https://github.com/vilic/x-wall/wiki
7 |
8 |
9 | https://github.com/vilic/x-wall/issues
10 | en-US
11 | false
12 | ShowAllFiles
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/X-Wall.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.31101.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "X-Wall", "X-Wall.csproj", "{F70204E7-AD12-4628-B200-D3FA863B3041}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {F70204E7-AD12-4628-B200-D3FA863B3041}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {F70204E7-AD12-4628-B200-D3FA863B3041}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {F70204E7-AD12-4628-B200-D3FA863B3041}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {F70204E7-AD12-4628-B200-D3FA863B3041}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/src/X-Wall.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/X-Wall.suo
--------------------------------------------------------------------------------
/src/X-Wall.v12.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/X-Wall.v12.suo
--------------------------------------------------------------------------------
/src/copy.bat:
--------------------------------------------------------------------------------
1 | xcopy /Y /s configs bin\Release\configs
2 | xcopy /Y /s configs bin\Debug\configs
3 | xcopy /Y /s resources bin\Release\resources
4 | xcopy /Y /s resources bin\Debug\resources
--------------------------------------------------------------------------------
/src/mgwz.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/mgwz.dll
--------------------------------------------------------------------------------
/src/plink.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/plink.exe
--------------------------------------------------------------------------------
/src/plonk.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/plonk.exe
--------------------------------------------------------------------------------
/src/post-build.txt:
--------------------------------------------------------------------------------
1 | if $(ConfigurationName) == Release (
2 | start "" /D "$(SolutionDir)/release" "$(SolutionDir)/release/version.js"
3 | )
--------------------------------------------------------------------------------
/src/privoxy.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/privoxy.exe
--------------------------------------------------------------------------------
/src/resources/about-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/resources/about-logo.png
--------------------------------------------------------------------------------
/src/resources/icon-error.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/resources/icon-error.ico
--------------------------------------------------------------------------------
/src/resources/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/resources/icon.ico
--------------------------------------------------------------------------------
/src/resources/logo-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/resources/logo-error.png
--------------------------------------------------------------------------------
/src/resources/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/resources/logo.png
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/connect-failed:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #include mod-head-error
7 |
10 |
11 |
12 | #include mod-header-error
13 | #include mod-content-begin
14 |
15 |
Connect Failed
16 |
Detailed information
17 |
18 | Your request for @protocol@@hostport@@path@ could
19 | not be fulfilled, because the connection to @host@ (@host-ip@) could not be established.
20 |
21 |
22 | This is often a temporary failure, so you might just
23 | try again .
24 |
25 |
26 |
27 |
连接失败
28 |
详细信息
29 |
30 | 请求 @protocol@@hostport@@path@
31 | 无法完成, 因为不能建立到 @host@ (@host-ip@) 的连接.
32 |
33 |
34 | 这通常只是一个临时的错误, 您可以 重试看看 .
35 |
36 |
37 | #include mod-gfw-operation
38 | #include mod-content-end
39 | #include mod-lang-helper
40 |
41 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/connection-timeout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #include mod-head-error
7 |
10 |
11 |
12 | #include mod-header-error
13 | #include mod-content-begin
14 |
15 |
Connection Timeout
16 |
Detailed Information
17 |
18 | Your request for @protocol@@hostport@@path@
19 | could not be fulfilled, because the connection to @host@ (@host-ip@) timed out.
20 |
21 |
22 | This is often a temporary failure, so you might just
23 | try again .
24 |
25 |
26 |
37 | #include mod-content-end
38 | #include mod-lang-helper
39 |
40 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/default:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/forwarding-failed:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #include mod-head-error
7 |
10 |
11 |
12 | #include mod-header-error
13 | #include mod-content-begin
14 |
15 |
Forwarding Failure
16 |
Detailed information
17 |
18 | Privoxy was unable to @forwarding-type@forward your request
19 | @protocol@@hostport@@path@
20 | through @gateway@, @error-message@.
21 |
22 |
23 | Just try again to
24 | see if this is a temporary problem. Otherwise, please check whether you have correctly connected to the SSH server
25 | or your HTTP proxy.
26 |
27 |
28 |
29 |
转发失败
30 |
详细信息
31 |
32 | Privoxy 无法以 @forwarding-type@forward 的方式通过 @gateway@ 转发您的请求
33 | @protocol@@hostport@@path@ , @error-message@.
34 |
35 |
36 | 请 重试 以确定不是临时错误.
37 | 如果无效的话, 请检查是否正确连接了 SSH 服务器或者 HTTP 代理.
38 |
39 |
40 | #include mod-content-end
41 | #include mod-lang-helper
42 |
43 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/lang-helper.js:
--------------------------------------------------------------------------------
1 | var pageLang;
2 |
3 | (function () {
4 | pageLang = function () {
5 | var langsMap = {};
6 | var langs = ["en-US", "zh-CN"];
7 | var divs = document.getElementsByTagName("div");
8 | var langDivs = [];
9 |
10 | for (var i = 0; i < divs.length; i++) {
11 | var div = divs[i];
12 | var lang = div.getAttribute("data-lang");
13 | if (lang) {
14 | langDivs.push(div);
15 | //if (!(lang in langsMap)) {
16 | // langs.push(lang);
17 | // langsMap[lang] = true;
18 | //}
19 | }
20 | }
21 |
22 | var langName =
23 | navigator.language ||
24 | navigator.userLanguage ||
25 | navigator.browserLanguage ||
26 | navigator.systemLanguage ||
27 | langs[0];
28 |
29 | var lang = getLang(langName) || getLang(langName.substr(0, 2)) || langs[0];
30 |
31 | for (var i = 0; i < langDivs.length; i++) {
32 | var div = langDivs[i];
33 | var dataLang = div.getAttribute("data-lang");
34 | if (!dataLang) continue;
35 | if (dataLang == lang) {
36 | div.style.display = "block";
37 | var title = div.getAttribute("data-title");
38 | if (title)
39 | document.title = title;
40 | }
41 | else {
42 | div.parentNode.removeChild(div);
43 | }
44 | }
45 |
46 | return lang;
47 |
48 | function getLang(name) {
49 | for (var i = 0; i < langs.length; i++) {
50 | if (langs[i].indexOf(name) == 0)
51 | return langs[i];
52 | }
53 | }
54 | }();
55 |
56 | if (typeof onlangready == "function")
57 | onlangready();
58 | })();
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/mod-content-begin:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/mod-content-end:
--------------------------------------------------------------------------------
1 |
2 |
20 |
21 |
24 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/mod-gfw-operation:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Fetching IP information...
4 |
5 |
It might be GFWed
6 |
7 | If simply refreshing the page doesn't help, this error then might be caused by the Great Firewall of China.
8 | You can
9 |
10 |
11 |
12 |
13 |
14 |
正在获取 IP 信息...
15 |
16 |
可能是被墙了
17 |
18 | 如果刷新页面没有用, 这个错误则可能是防火长城引起的.
19 | 你可以
20 |
21 |
22 |
23 |
24 |
25 |
86 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/mod-head:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/mod-head-error:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/mod-header:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/mod-header-error:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/mod-lang-helper:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/no-server-data:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #include mod-head-error
7 |
10 |
11 |
12 | #include mod-header-error
13 | #include mod-content-begin
14 |
15 |
No Server or Forwarder Data Received
16 |
Detailed information
17 |
18 | Your request for @protocol@@hostport@@path@
19 | could not be fulfilled, because the connection to @host@ (@host-ip@) has been closed
20 | before Privoxy received any data for this request.
21 |
22 |
23 | This is often a temporary failure, so you might just
24 | try again .
25 |
26 |
27 |
28 |
没有收到来自服务器或转发的数据
29 |
详细信息
30 |
31 | 请求 @protocol@@hostport@@path@
32 | 无法完成, 因为到 @host@ (@host-ip@) 的连接在 Privoxy 接收到任何数据前被关闭了.
33 |
34 |
35 | 这通常只是一个临时的错误, 您可以 重试看看 .
36 |
37 |
38 | #include mod-gfw-operation
39 | #include mod-content-end
40 | #include mod-lang-helper
41 |
42 |
43 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/no-such-domain:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #include mod-head-error
7 |
10 |
11 |
12 | #include mod-header-error
13 | #include mod-content-begin
14 |
15 |
No Such Domain
16 |
Detailed Information
17 |
18 | Your request for @protocol@@hostport@@path@
19 | could not be fulfilled, because the domain name @host@ could not be resolved.
20 |
21 |
22 | This is often a temporary failure, so you might just
23 | try again .
24 |
25 |
26 |
37 | #include mod-gfw-operation
38 | #include mod-content-end
39 | #include mod-lang-helper
40 |
41 |
--------------------------------------------------------------------------------
/src/resources/privoxy-templates/show-url-info:
--------------------------------------------------------------------------------
1 | (function () {
2 | var type, host, port;
3 |
4 | /* @if-valid-url-start */
5 |
6 | /* @if-http-forwarder-start */
7 | type = "http";
8 | host = "@forward-host@";
9 | port = Number("@forward-port@");
10 | /* if-http-forwarder-end@ */
11 |
12 | /* @if-socks-forwarder-start */
13 | type = "socks";
14 | host = "@gateway-host@";
15 | port = Number("@gateway-port@");
16 | /* if-socks-forwarder-end@ */
17 |
18 | /* if-valid-url-end@ */
19 |
20 | var matchesHTML = (function () {/*
21 | @matches@
22 | */}).toString().match(/\/\*\s*([\s\S]*)\s*\*\//)[1];
23 |
24 | var temp = document.createElement("div");
25 | temp.innerHTML = matchesHTML;
26 |
27 | var tds = temp.getElementsByTagName("td");
28 |
29 | var rule;
30 | var rules = ["online-forward", "online-default", "custom-forward", "custom-default"];
31 |
32 | for (var i = 0; i < tds.length; i++) {
33 | if (tds[i].getElementsByTagName("code").length > 0) {
34 | rule = rules[i];
35 | }
36 | }
37 |
38 | urlInfoCallback({
39 | url: "@url@",
40 | rule: rule,
41 | forward: {
42 | type: type,
43 | host: host,
44 | port: port
45 | }
46 | });
47 | })();
--------------------------------------------------------------------------------
/src/resources/spirits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lunadream/XWall/0a0a08b89a91cf323e4142e84ae9f22d29483556/src/resources/spirits.png
--------------------------------------------------------------------------------
/src/resources/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0px;
3 | font-size: 14px; color: #999999; font-family: Segoe UI, 微软雅黑, 黑体, Arial;
4 | background-color: #EEEEEE;
5 | }
6 |
7 | ul, li {
8 | margin: 0px; padding: 0px;
9 | list-style: none;
10 | }
11 |
12 | h1, h2, h3, h4, h5 {
13 | margin: 0px; padding: 0px;
14 | font-weight: normal;
15 | }
16 |
17 | p {
18 | margin: 0px 0px 0.5em 0px;
19 | }
20 |
21 | img {
22 | border: none;
23 | }
24 |
25 | button {
26 | border: solid 1px #CCCCCC;
27 | padding: 0px 10px;
28 | line-height: 24px;
29 | color: #888888; font-family: Segoe UI, 微软雅黑, 黑体, Arial;
30 | background-color: #FFFFFF;
31 | cursor: pointer;
32 | -moz-transition: all linear 0.2s;
33 | -o-transition: all linear 0.2s;
34 | -webkit-transition: all linear 0.2s;
35 | transition: all linear 0.2s;
36 | }
37 |
38 | button:hover {
39 | color: #666666;
40 | border-color: #999999;
41 | }
42 |
43 | button:disabled {
44 | color: #AAAAAA;
45 | border-color: #CCCCCC;
46 | cursor: default;
47 | }
48 |
49 | button.center {
50 | display: block;
51 | margin: 5px auto;
52 | }
53 |
54 | input {
55 | border: solid 1px #CCCCCC;
56 | padding: 2px 5px;
57 | width: 200px;
58 | line-height: 20px;
59 | font-size: 14px;
60 | color: #999999;
61 | font-family: Segoe UI, 微软雅黑, 黑体, Arial;
62 | outline: none;
63 | -moz-transition: all linear 0.2s;
64 | -o-transition: all linear 0.2s;
65 | -webkit-transition: all linear 0.2s;
66 | transition: all linear 0.2s;
67 | }
68 |
69 | input:focus {
70 | border-color: #999999;
71 | }
72 |
73 | .anchor {
74 | position: absolute;
75 | margin-top: -66px;
76 | font-size: 0px;
77 | overflow: hidden;
78 | }
79 |
80 | .hidden {
81 | position: absolute;
82 | width: 0px; height: 0px;
83 | font-size: 0px;
84 | visibility: hidden;
85 | }
86 |
87 | /* LAYOUT */
88 |
89 | #main-wrapper {
90 | position: absolute;
91 | top: 66px;
92 | width: 100%;
93 | z-index: 0;
94 | }
95 |
96 | /* Header */
97 |
98 | #header-wrapper {
99 | position: fixed;
100 | border-bottom: solid 1px #CCCCCC;
101 | width: 100%; height: 65px;
102 | background-color: #FFFFFF;
103 | z-index: 1;
104 | }
105 |
106 | #header {
107 | position: relative;
108 | margin: auto;
109 | width: 1000px; height: 65px;
110 | }
111 |
112 | #logo-wrapper {
113 | position: absolute;
114 | left: 25px; bottom: 10px;
115 | height: 40px;
116 | text-decoration: none;
117 | }
118 |
119 | #logo {
120 | position: absolute;
121 | left: 0px; top: 0px;
122 | width: 40px; height: 40px;
123 | cursor: pointer;
124 | }
125 |
126 | #title {
127 | position: absolute;
128 | left: 48px; top: 18px;
129 | line-height: 22px;
130 | white-space: nowrap;
131 | font-size: 18px; color: #666666; text-transform: uppercase;
132 | cursor: pointer;
133 | }
134 |
135 | #domain {
136 | position: absolute;
137 | left: 48px; top: 2px;
138 | line-height: 16px;
139 | white-space: nowrap;
140 | font-size: 14px; color: #CCCCCC;
141 | cursor: pointer;
142 | }
143 |
144 | #nav {
145 | position: absolute;
146 | right: 5px; bottom: -1px;
147 | }
148 |
149 | #nav > li {
150 | float: left;
151 | padding: 0px;
152 | height: 45px;
153 | }
154 |
155 | #nav > li > a {
156 | display: block;
157 | padding: 0px 10px;
158 | border-bottom: solid 1px #CCCCCC;
159 | line-height: 44px;
160 | color: #999999; text-decoration: none; text-transform: uppercase;
161 | -moz-transition: all linear 0.2s;
162 | -o-transition: all linear 0.2s;
163 | -webkit-transition: all linear 0.2s;
164 | transition: all linear 0.2s;
165 | }
166 |
167 | #nav > li > a:hover {
168 | border-bottom-color: #666666;
169 | color: #666666;
170 | }
171 |
172 | #nav ul {
173 | display: none;
174 | }
175 |
176 | /* MAIN MENU */
177 | #main-menu-list-wrapper {
178 | display: none;
179 | position: absolute;
180 | margin-top: 2px;
181 | padding-top: 5px;
182 | line-height: 28px; font-size: 14px;
183 | z-index: 1;
184 | }
185 |
186 | /* menu arrow */
187 | #main-menu-list-wrapper b {
188 | position: absolute;
189 | /*left: 46px;*/ top: 0px;
190 | margin: 0px -6px;
191 | border: dashed transparent; border-width: 0px 6px; border-bottom: solid 6px #CCCCCC;
192 | width: 0px; height: 0px;
193 | line-height: 0px;
194 | z-index: 1;
195 | }
196 |
197 | #main-menu-list-wrapper b i {
198 | position: absolute;
199 | left: -6px; top: 1px;
200 | border: dashed transparent; border-width: 0px 6px; border-bottom: solid 6px #FFFFFF;
201 | width: 0px; height: 0px;
202 | line-height: 0px;
203 | }
204 |
205 | #main-menu-list {
206 | position: relative;
207 | border: solid 1px #DDDDDD;
208 | padding: 8px 0px 12px 0px;
209 | background-color: #FFFFFF;
210 | overflow: hidden;
211 | }
212 |
213 | #main-menu-list li {
214 | height: 28px; width: 100%;
215 | float: left;
216 | }
217 |
218 | #main-menu-list li a {
219 | position: absolute;
220 | width: 100%;
221 | padding: 0px 40px 0px 15px;
222 | text-decoration: none; color: #999999;
223 | white-space: nowrap;
224 | -moz-transition: color linear 0.2s;
225 | -o-transition: color linear 0.2s;
226 | -webkit-transition: color linear 0.2s;
227 | transition: color linear 0.2s;
228 | }
229 |
230 | #main-menu-list li a.adjusting {
231 | width: auto;
232 | }
233 |
234 | #main-menu-list li a:hover {
235 | color: #666666;
236 | }
237 |
238 | /* BODY WRAPPER */
239 |
240 | #body-wrapper {
241 | position: relative;
242 | margin: auto;
243 | width: 1000px;
244 | }
245 |
246 | /* CONTENT WRAPPER */
247 |
248 | #content-wrapper {
249 | padding: 0px 10px 10px 30px;
250 | width: 680px;
251 | }
252 |
253 | #content-wrapper img {
254 | display: block;
255 | margin: 10px 0px;
256 | }
257 |
258 | #content-wrapper h3 {
259 | margin-left: -5px;
260 | padding: 10px 0px 5px 0px;
261 | text-transform: uppercase; color: #666666; font-size: 20px;
262 | }
263 |
264 | #content-wrapper h4 {
265 | padding: 5px 0px;
266 | font-size: 16px; color: #666666;
267 | }
268 |
269 | #content-wrapper h5 {
270 | margin: 0.8em 0px 0.5em 0px;
271 | font-size: 14px; color: #666666;
272 | }
273 |
274 | #content-wrapper ul {
275 | margin-bottom: 0.5em;
276 | }
277 |
278 |
279 | #content-wrapper a {
280 | color: #666666; text-decoration: none; word-break: break-all;
281 | -moz-transition: all linear 0.2s;
282 | -o-transition: all linear 0.2s;
283 | -webkit-transition: all linear 0.2s;
284 | transition: all linear 0.2s;
285 | }
286 |
287 | #content-wrapper a:hover {
288 | color: #333333;
289 | }
290 |
291 | #content-wrapper em {
292 | font-style: normal; color: #666666;
293 | }
294 |
295 |
296 | #content-wrapper ul {
297 | padding-left: 5px;
298 | }
299 |
300 | #content-wrapper ul li {
301 | /* see sidebar wrapper section */
302 | }
303 |
304 | #faq-list {
305 | padding-left: 0px!important;
306 | }
307 |
308 | #faq-list li {
309 | margin-bottom: 8px;
310 | padding-left: 0px!important;
311 | color: #666666!important;
312 | background: none!important;
313 | list-style: decimal inside;
314 | }
315 |
316 | #faq-list p.q {
317 | display: inline-block;
318 | }
319 |
320 | #faq-list p.a {
321 | text-indent: 1em;
322 | color: #999999;
323 | }
324 |
325 | #ds-thread {
326 | padding-top: 10px;
327 | }
328 |
329 | #ds-thread div.ds-waiting:after {
330 | content: "正在加载评论...";
331 | }
332 |
333 | #ds-thread div.ds-waiting img {
334 | display: none;
335 | }
336 |
337 | /* SIDEBAR WRAPPER */
338 |
339 | #sidebar-wrapper {
340 | position: absolute;
341 | top: 0px;
342 | margin-left: 720px;
343 | padding: 10px;
344 | width: 260px;
345 | }
346 |
347 | #sidebar-wrapper .item {
348 | margin-bottom: 10px;
349 | border: solid 1px #CCCCCC;
350 | padding: 12px 10px 12px 20px;
351 | width: 228px;
352 | }
353 |
354 | #sidebar-wrapper .item h2 {
355 | margin-left: -8px; margin-bottom: 10px;
356 | border-left: solid 4px;
357 | padding-left: 5px;
358 | line-height: 16px;
359 | font-size: 14px; text-transform: uppercase;
360 | }
361 |
362 | #content-wrapper ul li,
363 | #sidebar-wrapper .item ul li {
364 | line-height: 18px;
365 | padding-left: 10px;
366 | background: url(transmit.ashx?file=spirits.png&type=image/png) no-repeat;
367 | }
368 |
369 | #provider-list {
370 | margin-bottom: 0.5em;
371 | }
372 |
373 | #sidebar-wrapper .item ul li a {
374 | text-decoration: none;
375 | -moz-transition: all linear 0.2s;
376 | -o-transition: all linear 0.2s;
377 | -webkit-transition: all linear 0.2s;
378 | transition: all linear 0.2s;
379 | }
380 |
381 | #version {
382 | color: #F9F9F9;
383 | }
384 |
385 | /* .item.dark */
386 | #sidebar-wrapper .dark {
387 | background-color: #CCCCCC;
388 | }
389 |
390 | #sidebar-wrapper .dark h2 {
391 | border-left-color: #999999;
392 | color: #666666;
393 | }
394 |
395 | #content-wrapper ul li,
396 | #sidebar-wrapper .dark ul li {
397 | color: #999999;
398 | background-position: -196px 0px;
399 | }
400 |
401 | #sidebar-wrapper .dark ul li a {
402 | color: #F9F9F9;
403 | }
404 |
405 | #sidebar-wrapper .dark ul li a:hover {
406 | color: #FFFFFF;
407 | }
408 |
409 | /* .item.light */
410 | #sidebar-wrapper .light {
411 | background-color: #FFFFFF;
412 | }
413 |
414 | #sidebar-wrapper .light h2 {
415 | border-left-color: #6DD900;
416 | color: #666666;
417 | }
418 |
419 | #sidebar-wrapper .light ul li {
420 | color: #6DD900;
421 | background-position: 0px -182px;
422 | }
423 |
424 | #sidebar-wrapper .light ul li a {
425 | color: #888888;
426 | }
427 |
428 | #sidebar-wrapper .light ul li a:hover {
429 | color: #666666;
430 | }
431 |
432 | /* FOOTER */
433 |
434 | #footer {
435 | margin: auto; padding: 20px 0px;
436 | width: 1000px;
437 | line-height: 20px;
438 | font-size: 12px; text-align: center; color: #CCCCCC;
439 | }
440 |
441 | #footer a {
442 | color: #CCCCCC; text-decoration: none;
443 | }
--------------------------------------------------------------------------------