1 // SoftEther VPN Source Code - Stable Edition Repository
2 // Build Utility
3 //
4 // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0.
5 //
6 // Copyright (c) Daiyuu Nobori.
7 // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan.
8 // Copyright (c) SoftEther Corporation.
9 // Copyright (c) all contributors on SoftEther VPN project in GitHub.
10 //
11 // All Rights Reserved.
12 //
13 // http://www.softether.org/
14 //
15 // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project.
16 // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN
17 //
18 // License: The Apache License, Version 2.0
19 // https://www.apache.org/licenses/LICENSE-2.0
20 //
21 // DISCLAIMER
22 // ==========
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 // SOFTWARE.
31 //
32 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
33 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
34 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
35 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
36 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER
37 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND
38 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING,
39 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
40 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE
41 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE
42 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS.
43 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE
44 // LAW OR COURT RULE.
45 //
46 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE
47 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL
48 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS
49 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND
50 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING
51 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER
52 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES.
53 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
54 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES
55 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH
56 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS
57 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE
58 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A
59 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE
60 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
61 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A
62 // STATEMENT FOR WARNING AND DISCLAIMER.
63 //
64 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE.
65 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH
66 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE.
67 //
68 //
69 // SOURCE CODE CONTRIBUTION
70 // ------------------------
71 //
72 // Your contribution to SoftEther VPN Project is much appreciated.
73 // Please send patches to us through GitHub.
74 // Read the SoftEther VPN Patch Acceptance Policy in advance:
75 // http://www.softether.org/5-download/src/9.patch
76 //
77 //
78 // DEAR SECURITY EXPERTS
79 // ---------------------
80 //
81 // If you find a bug or a security vulnerability please kindly inform us
82 // about the problem immediately so that we can fix the security problem
83 // to protect a lot of users around the world as soon as possible.
84 //
85 // Our e-mail address for security reports is:
86 // softether-vpn-security [at] softether.org
87 //
88 // Please note that the above e-mail address is not a technical support
89 // inquiry address. If you need technical assistance, please visit
90 // http://www.softether.org/ and ask your question on the users forum.
91 //
92 // Thank you for your cooperation.
93 //
94 //
95 // NO MEMORY OR RESOURCE LEAKS
96 // ---------------------------
97 //
98 // The memory-leaks and resource-leaks verification under the stress
99 // test has been passed before release this source code.
100 
101 
102 using System;
103 using System.Threading;
104 using System.Text;
105 using System.Configuration;
106 using System.Collections;
107 using System.Collections.Generic;
108 using System.Collections.Specialized;
109 using System.Security.Cryptography;
110 using System.Web;
111 using System.Web.Security;
112 using System.Web.UI;
113 using System.Web.UI.WebControls;
114 using System.Web.UI.WebControls.WebParts;
115 using System.Web.UI.HtmlControls;
116 using System.IO;
117 using System.Drawing;
118 using System.Drawing.Imaging;
119 using System.Drawing.Drawing2D;
120 using System.Diagnostics;
121 using System.Net;
122 using System.Net.Security;
123 using System.Security.Cryptography.X509Certificates;
124 using CoreUtil;
125 
126 namespace BuildUtil
127 {
128 	// Languages
129 	public class Language
130 	{
131 		public int Number;
132 		public string Id;
133 		public string Title;
134 		public string TitleUnicode;
135 		public string WindowsLocaleIds;
136 		public string UnixLocaleIds;
137 	}
138 
139 	// Build helper class
140 	public static class BuildHelper
141 	{
142 		// loads the language list text file
GetLanguageList()143 		public static Language[] GetLanguageList()
144 		{
145 			return GetLanguageList(Path.Combine(Paths.BinDirName, @"hamcore\languages.txt"));
146 		}
GetLanguageList(string filename)147 		public static Language[] GetLanguageList(string filename)
148 		{
149 			List<Language> ret = new List<Language>();
150 			string[] lines = File.ReadAllLines(filename, Str.Utf8Encoding);
151 
152 			foreach (string line in lines)
153 			{
154 				string s = line.Trim();
155 
156 				if (Str.IsEmptyStr(s) == false)
157 				{
158 					if (s.StartsWith("#", StringComparison.InvariantCultureIgnoreCase) == false)
159 					{
160 						string[] sps = { " ", "\t", };
161 						string[] tokens = s.Split(sps, StringSplitOptions.RemoveEmptyEntries);
162 
163 						if (tokens.Length == 6)
164 						{
165 							Language e = new Language();
166 
167 							e.Number = Str.StrToInt(tokens[0]);
168 							e.Id = tokens[1];
169 							e.Title = Str.ReplaceStr(tokens[2], "_", " ");
170 							e.TitleUnicode = tokens[3];
171 							e.WindowsLocaleIds = tokens[4];
172 							e.UnixLocaleIds = tokens[5];
173 
174 							ret.Add(e);
175 
176 							Con.WriteLine(tokens.Length);
177 						}
178 					}
179 				}
180 			}
181 
182 			return ret.ToArray();
183 		}
184 
185 		// Build
BuildMain(BuildSoftware soft, bool debugModeIfUnix)186 		public static void BuildMain(BuildSoftware soft, bool debugModeIfUnix)
187 		{
188 			int version, build;
189 			string name;
190 			DateTime date;
191 
192 			string title = Console.Title;
193 			Console.Title = string.Format("Building {0}", soft.IDString);
194 
195 			try
196 			{
197 				Win32BuildUtil.ReadBuildInfoFromTextFile(out build, out version, out name, out date);
198 
199 				soft.SetBuildNumberVersionName(build, version, name, date);
200 
201 				Con.WriteLine("Building '{0}' - {1}...", soft.IDString, soft.TitleString);
202 
203 				BuildSoftwareUnix softUnix = soft as BuildSoftwareUnix;
204 
205 				if (softUnix == null)
206 				{
207 					soft.Build();
208 				}
209 				else
210 				{
211 					softUnix.Build(debugModeIfUnix);
212 				}
213 			}
214 			finally
215 			{
216 				Console.Title = title;
217 			}
218 		}
219 
220 		// Convert the number to a version number
VersionIntToString(int version)221 		public static string VersionIntToString(int version)
222 		{
223 			return string.Format("{0}.{1:D2}", version / 100, version % 100);
224 		}
225 
226 		// Get a product list that is included in the software
GetSoftwareProductList(Software soft)227 		public static string GetSoftwareProductList(Software soft)
228 		{
229 			string ret = "";
230 
231 			switch (soft)
232 			{
233 				case Software.vpnbridge:
234 					ret = "PacketiX VPN Bridge";
235 					break;
236 
237 				case Software.vpnclient:
238 					ret = "PacketiX VPN Client, PacketiX VPN Command-Line Admin Utility (vpncmd)";
239 					break;
240 
241 				case Software.vpnserver:
242 					ret = "PacketiX VPN Server, PacketiX VPN Command-Line Admin Utility (vpncmd)";
243 					break;
244 
245 				case Software.vpnserver_vpnbridge:
246 					ret = "PacketiX VPN Server, PacketiX VPN Bridge, PacketiX VPN Server Manager for Windows, PacketiX VPN Command-Line Admin Utility (vpncmd)";
247 					break;
248 
249 				default:
250 					throw new ApplicationException("invalid soft.");
251 			}
252 
253 #if BU_SOFTETHER
254 			ret = Str.ReplaceStr(ret, "PacketiX", "SoftEther", false);
255 #endif
256 
257 			return ret;
258 		}
259 
260 		// Get the title of the software
GetSoftwareTitle(Software soft)261 		public static string GetSoftwareTitle(Software soft)
262 		{
263 			string ret = "";
264 
265 			switch (soft)
266 			{
267 				case Software.vpnbridge:
268 					ret = "PacketiX VPN Bridge";
269 					break;
270 
271 				case Software.vpnclient:
272 					ret = "PacketiX VPN Client";
273 					break;
274 
275 				case Software.vpnserver:
276 					ret = "PacketiX VPN Server";
277 					break;
278 
279 				case Software.vpnserver_vpnbridge:
280 					ret = "PacketiX VPN Server and VPN Bridge";
281 					break;
282 
283 				default:
284 					throw new ApplicationException("invalid soft.");
285 			}
286 
287 #if BU_SOFTETHER
288 			ret = Str.ReplaceStr(ret, "PacketiX", "SoftEther", false);
289 #endif
290 
291 			return ret;
292 		}
293 	}
294 
295 	// Basic path information
296 	public static class Paths
297 	{
298 		public static readonly string ExeFileName = Env.ExeFileName;
299 		public static readonly string ExeDirName = Env.ExeFileDir;
300 		public static readonly string BinDirName = ExeDirName;
301 		public static readonly string BaseDirName = IO.NormalizePath(Path.Combine(BinDirName, @"..\"));
302 		public static readonly string UtilityDirName = IO.NormalizePath(Path.Combine(BinDirName, @"..\BuildFiles\Utility"));
303 
304 #if !BU_SOFTETHER
305 		// PacketiX VPN (build by SoftEther)
306 		public static readonly string VPN4SolutionFileName = Path.Combine(BaseDirName, "VPN4.sln");
307 		public static readonly string DebugSnapshotBaseDir = @"S:\SE4\DebugFilesSnapshot";
308 		public static readonly string ReleaseDestDir = @"s:\SE4\Releases";
309 		public const string Prefix = "";
310 #else
311 #if !BU_OSS
312 		// SoftEther VPN (build by SoftEther)
313 		public static readonly string VPN4SolutionFileName = Path.Combine(BaseDirName, "SEVPN.sln");
314 		public static readonly string DebugSnapshotBaseDir = @"S:\SE4\DebugFilesSnapshot_SEVPN";
315 		public static readonly string ReleaseDestDir = @"s:\SE4\Releases_SEVPN";
316 		public const string Prefix = "softether-";
317 #else
318 		// SoftEther VPN (build by Open Source Developers)
319 		public static readonly string VPN4SolutionFileName = Path.Combine(BaseDirName, "SEVPN.sln");
320 		public static readonly string DebugSnapshotBaseDir = IO.NormalizePath(Path.Combine(BaseDirName, @"..\output\debug"));
321 		public static readonly string ReleaseDestDir = IO.NormalizePath(Path.Combine(BaseDirName, @"..\output\pkg"));
322 		public const string Prefix = "softether_open-";
323 #endif
324 #endif
325 
326 		public static readonly string ReleaseDestDir_SEVPN = @"s:\SE4\Releases_SEVPN";
327 
328 		public static readonly string BuildHamcoreFilesDirName = Path.Combine(BinDirName, "BuiltHamcoreFiles");
329 		public static readonly string VisualStudioVCDir;
330 		public static readonly string VisualStudioVCBatchFileName;
331 		public static readonly string DotNetFramework35Dir;
332 		public static readonly string MSBuildFileName;
333 		public static readonly string TmpDirName;
334 		public static readonly DateTime StartDateTime = DateTime.Now;
335 		public static readonly string StartDateTimeStr;
336 		public static readonly string CmdFileName;
337 		public static readonly string ManifestsDir = Path.Combine(BaseDirName, @"BuildFiles\Manifests");
338 		public static readonly string XCopyExeFileName = Path.Combine(Env.SystemDir, "xcopy.exe");
339 		public static readonly string ReleaseDir = Path.Combine(BaseDirName, @"tmp\Release");
340 		public static readonly string ReleaseSrckitDir = Path.Combine(BaseDirName, @"tmp\ReleaseSrcKit");
341 		public static readonly string StringsDir = Path.Combine(BaseDirName, @"BuildFiles\Strings");
342 		public static readonly string CrossCompilerBaseDir = @"S:\CommomDev\xc";
343 		public static readonly string UnixInstallScript = Path.Combine(BaseDirName, @"BuildFiles\UnixFiles\InstallScript.txt");
344 		public static readonly string OssCommentsFile = Path.Combine(StringsDir, "OssComments.txt");
345 		public static readonly string AutorunSrcDir = IO.NormalizePath(Path.Combine(BaseDirName, @"..\Autorun"));
346 		public static readonly string MicrosoftSDKDir;
347 		public static readonly string MakeCatFilename;
348 		public static readonly string RcFilename;
349 		public static readonly string SoftEtherBuildDir = Env.SystemDir.Substring(0, 2) + @"\tmp\softether_build_dir";
350 		public static readonly string OpenSourceDestDir = Env.SystemDir.Substring(0, 2) + @"\tmp\softether_oss_dest_dir";
351 
352 		// Initialize
Paths()353 		static Paths()
354 		{
355 			// Starting date and time string
356 			Paths.StartDateTimeStr = Str.DateTimeToStrShort(Paths.StartDateTime);
357 
358 			// Check whether the execution path is the bin directory in the VPN directory
359 			if (Paths.BinDirName.EndsWith(@"\bin", StringComparison.InvariantCultureIgnoreCase) == false)
360 			{
361 				throw new ApplicationException(string.Format("'{0}' is not a VPN bin directory.", Paths.BinDirName));
362 			}
363 			if (File.Exists(Paths.VPN4SolutionFileName) == false)
364 			{
365 				throw new ApplicationException(string.Format("'{0}' is not a VPN base directory.", Paths.BaseDirName));
366 			}
367 
368 			// Get the VC++ directory
369 			// Visual Studio 2008
370 			if (IntPtr.Size == 4)
371 			{
372 				Paths.VisualStudioVCDir = IO.RemoteLastEnMark(Reg.ReadStr(RegRoot.LocalMachine, @"SOFTWARE\Microsoft\VisualStudio\9.0\Setup\VC", "ProductDir"));
373 			}
374 			else
375 			{
376 				Paths.VisualStudioVCDir = IO.RemoteLastEnMark(Reg.ReadStr(RegRoot.LocalMachine, @"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\9.0\Setup\VC", "ProductDir"));
377 			}
378 			if (Str.IsEmptyStr(Paths.VisualStudioVCDir))
379 			{
380 				throw new ApplicationException("Visual C++ directory not found.\n");
381 			}
382 			if (Directory.Exists(Paths.VisualStudioVCDir) == false)
383 			{
384 				throw new ApplicationException(string.Format("Directory '{0}' not found.", Paths.VisualStudioVCDir));
385 			}
386 
387 			// Get the VC++ batch file name
388 			Paths.VisualStudioVCBatchFileName = Path.Combine(Paths.VisualStudioVCDir, "vcvarsall.bat");
389 			if (File.Exists(Paths.VisualStudioVCBatchFileName) == false)
390 			{
391 				throw new ApplicationException(string.Format("File '{0}' not found.", Paths.VisualStudioVCBatchFileName));
392 			}
393 
394 			bool x86_dir = false;
395 
396 			// Get Microsoft SDK 6.0a directory
397 			if (IntPtr.Size == 4)
398 			{
399 				Paths.MicrosoftSDKDir = IO.RemoteLastEnMark(Reg.ReadStr(RegRoot.LocalMachine, @"SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v6.0A", "InstallationFolder"));
400 			}
401 			else
402 			{
403 				Paths.MicrosoftSDKDir = IO.RemoteLastEnMark(Reg.ReadStr(RegRoot.LocalMachine, @"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v6.0A", "InstallationFolder"));
404 			}
405 
406 			// Get makecat.exe file name
407 			Paths.MakeCatFilename = Path.Combine(Paths.MicrosoftSDKDir, @"bin\" + (x86_dir ? @"x86\" : "") + "makecat.exe");
408 
409 			// Get the rc.exe file name
410 			Paths.RcFilename = Path.Combine(Paths.MicrosoftSDKDir, @"bin\" + (x86_dir ? @"x86\" : "") + "rc.exe");
411 
412 			// Get the cmd.exe file name
413 			Paths.CmdFileName = Path.Combine(Env.SystemDir, "cmd.exe");
414 			if (File.Exists(Paths.CmdFileName) == false)
415 			{
416 				throw new ApplicationException(string.Format("File '{0}' not found.", Paths.CmdFileName));
417 			}
418 
419 			// Get .NET Framework 3.5 directory
420 			Paths.DotNetFramework35Dir = Path.Combine(Env.WindowsDir, @"Microsoft.NET\Framework\v3.5");
421 
422 			// Get msbuild.exe directory
423 			Paths.MSBuildFileName = Path.Combine(Paths.DotNetFramework35Dir, "MSBuild.exe");
424 			if (File.Exists(Paths.MSBuildFileName) == false)
425 			{
426 				throw new ApplicationException(string.Format("File '{0}' not found.", Paths.MSBuildFileName));
427 			}
428 
429 			// Get the TMP directory
430 			Paths.TmpDirName = Path.Combine(Paths.BaseDirName, "tmp");
431 			if (Directory.Exists(Paths.TmpDirName) == false)
432 			{
433 				Directory.CreateDirectory(Paths.TmpDirName);
434 			}
435 		}
436 
DeleteAllReleaseTarGz()437 		public static void DeleteAllReleaseTarGz()
438 		{
439 			if (Directory.Exists(Paths.ReleaseDir))
440 			{
441 				string[] files = Directory.GetFiles(Paths.ReleaseDir, "*.gz", SearchOption.AllDirectories);
442 
443 				foreach (string file in files)
444 				{
445 					File.Delete(file);
446 				}
447 			}
448 
449 			if (Directory.Exists(Paths.ReleaseSrckitDir))
450 			{
451 				string[] files = Directory.GetFiles(Paths.ReleaseSrckitDir, "*.gz", SearchOption.AllDirectories);
452 
453 				foreach (string file in files)
454 				{
455 					File.Delete(file);
456 				}
457 			}
458 		}
459 
DeleteAllReleaseAdminKits()460 		public static void DeleteAllReleaseAdminKits()
461 		{
462 			if (Directory.Exists(Paths.ReleaseDir))
463 			{
464 				string[] files = Directory.GetFiles(Paths.ReleaseDir, "*.zip", SearchOption.AllDirectories);
465 
466 				foreach (string file in files)
467 				{
468 					if (Str.InStr(file, "vpnadminpak"))
469 					{
470 						File.Delete(file);
471 					}
472 				}
473 			}
474 		}
475 
DeleteAllReleaseManuals()476 		public static void DeleteAllReleaseManuals()
477 		{
478 			if (Directory.Exists(Paths.ReleaseDir))
479 			{
480 				string[] files = Directory.GetFiles(Paths.ReleaseDir, "*", SearchOption.AllDirectories);
481 
482 				foreach (string file in files)
483 				{
484 					if (Str.InStr(file, "vpnmanual"))
485 					{
486 						File.Delete(file);
487 					}
488 				}
489 			}
490 		}
491 
DeleteAllReleaseExe()492 		public static void DeleteAllReleaseExe()
493 		{
494 			if (Directory.Exists(Paths.ReleaseDir))
495 			{
496 				string[] files = Directory.GetFiles(Paths.ReleaseDir, "*.exe", SearchOption.AllDirectories);
497 
498 				foreach (string file in files)
499 				{
500 					if (Str.InStr(file, "vpnmanual") == false)
501 					{
502 						File.Delete(file);
503 					}
504 				}
505 			}
506 		}
507 	}
508 
509 	// HamCore build utility
510 	public static class HamCoreBuildUtil
511 	{
512 		// Identify whether a file is necessary only in the Win32
IsFileForOnlyWin32(string filename)513 		public static bool IsFileForOnlyWin32(string filename)
514 		{
515 			string[] filesOnlyWin32 =
516 			{
517 				".exe",
518 				".dll",
519 				".sys",
520 				".inf",
521 				".wav",
522 				".cat",
523 			};
524 
525 			foreach (string ext in filesOnlyWin32)
526 			{
527 				if (filename.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase))
528 				{
529 					return true;
530 				}
531 			}
532 
533 			return false;
534 		}
535 
536 		// Delete svn file
DeleteSVNFilesFromHamCoreBuilder(HamCoreBuilder b)537 		public static void DeleteSVNFilesFromHamCoreBuilder(HamCoreBuilder b)
538 		{
539 			List<string> removeFiles = new List<string>();
540 			foreach (HamCoreBuilderFileEntry f in b.FileList)
541 			{
542 				string name = f.Name;
543 				if (name.StartsWith(".svn", StringComparison.InvariantCultureIgnoreCase) ||
544 					name.IndexOf(@"\.svn", StringComparison.InvariantCultureIgnoreCase) != -1)
545 				{
546 					removeFiles.Add(name);
547 				}
548 			}
549 			foreach (string file in removeFiles)
550 			{
551 				b.DeleteFile(file);
552 			}
553 		}
554 
555 		// Delete node_modules file
DeleteNodeModulesFilesFromHamCoreBuilder(HamCoreBuilder b)556 		public static void DeleteNodeModulesFilesFromHamCoreBuilder(HamCoreBuilder b)
557 		{
558 			List<string> removeFiles = new List<string>();
559 			foreach (HamCoreBuilderFileEntry f in b.FileList)
560 			{
561 				string name = f.Name;
562 				if (name.IndexOf(@"\node_modules\", StringComparison.InvariantCultureIgnoreCase) != -1)
563 				{
564 					removeFiles.Add(name);
565 				}
566 			}
567 			foreach (string file in removeFiles)
568 			{
569 				b.DeleteFile(file);
570 			}
571 		}
572 
573 		// Build Hamcore file
BuildHamcore()574 		public static void BuildHamcore()
575 		{
576 			string srcDirNameBasic = Path.Combine(Paths.BinDirName, "hamcore");
577 			// Create the destination directory
578 			string win32DestDir = Path.Combine(Paths.BuildHamcoreFilesDirName, "hamcore_win32");
579 			string win32DestFileName = Path.Combine(win32DestDir, "hamcore.se2");
580 			string unixDestDir = Path.Combine(Paths.BuildHamcoreFilesDirName, "hamcore_unix");
581 			string unixDestFileName = Path.Combine(unixDestDir, "hamcore.se2");
582 			IO.MakeDir(win32DestDir);
583 			IO.MakeDir(unixDestDir);
584 
585 
586 			BuildHamcoreEx(srcDirNameBasic, win32DestFileName, unixDestFileName);
587 
588 			// Copy to bin\hamcore.se2
589 			try
590 			{
591 				string binHamcoreFileName = Path.Combine(Paths.BinDirName, "hamcore.se2");
592 
593 				try
594 				{
595 					File.Delete(binHamcoreFileName);
596 				}
597 				catch
598 				{
599 				}
600 
601 				File.Copy(win32DestFileName, binHamcoreFileName, true);
602 			}
603 			catch
604 			{
605 			}
606 		}
607 
BuildHamcoreEx(string srcDirNameBasic, string win32DestFileName, string unixDestFileName)608 		public static void BuildHamcoreEx(string srcDirNameBasic, string win32DestFileName, string unixDestFileName)
609 		{
610 			HamCoreBuilder b = new HamCoreBuilder();
611 			b.AddDir(srcDirNameBasic);
612 			Con.WriteLine("* Building hamcore ...");
613 
614 			DeleteSVNFilesFromHamCoreBuilder(b);
615 			DeleteNodeModulesFilesFromHamCoreBuilder(b);
616 
617 			try
618 			{
619 				File.Delete(win32DestFileName);
620 			}
621 			catch
622 			{
623 			}
624 			b.Build(win32DestFileName);
625 
626 			// unix
627 			List<string> removeFiles = new List<string>();
628 			foreach (HamCoreBuilderFileEntry f in b.FileList)
629 			{
630 				if (IsFileForOnlyWin32(f.Name))
631 				{
632 					removeFiles.Add(f.Name);
633 				}
634 			}
635 			foreach (string removeFile in removeFiles)
636 			{
637 				b.DeleteFile(removeFile);
638 			}
639 
640 			DeleteSVNFilesFromHamCoreBuilder(b);
641 			DeleteNodeModulesFilesFromHamCoreBuilder(b);
642 
643 			try
644 			{
645 				File.Delete(unixDestFileName);
646 			}
647 			catch
648 			{
649 			}
650 			b.Build(unixDestFileName);
651 		}
652 	}
653 
654 	// Number of bits
655 	public enum CPUBits
656 	{
657 		Both,
658 		Bits32,
659 		Bits64,
660 	}
661 
662 	// Conversion a string to the number of bits
663 	public static class CPUBitsUtil
664 	{
StringToCPUBits(string str)665 		public static CPUBits StringToCPUBits(string str)
666 		{
667 			if (str.Equals("32bit", StringComparison.InvariantCultureIgnoreCase))
668 			{
669 				return CPUBits.Bits32;
670 			}
671 			else if (str.Equals("64bit", StringComparison.InvariantCultureIgnoreCase))
672 			{
673 				return CPUBits.Bits64;
674 			}
675 			else if (str.Equals("intel", StringComparison.InvariantCultureIgnoreCase))
676 			{
677 				return CPUBits.Both;
678 			}
679 
680 			throw new ApplicationException(string.Format("Invalid bits string '{0}'.", str));
681 		}
682 
CPUBitsToString(CPUBits bits)683 		public static string CPUBitsToString(CPUBits bits)
684 		{
685 			switch (bits)
686 			{
687 				case CPUBits.Bits32:
688 					return "32bit";
689 
690 				case CPUBits.Bits64:
691 					return "64bit";
692 
693 				case CPUBits.Both:
694 					return "intel";
695 			}
696 
697 			throw new ApplicationException("bits invalid.");
698 		}
699 	}
700 }
701 
702 
703