// CoreUtil // // Copyright (C) 2012-2014 Daiyuu Nobori. All Rights Reserved. // Copyright (C) 2012-2014 SoftEther VPN Project at University of Tsukuba. All Rights Reserved. // Comments: Tetsuo Sugiyama, Ph.D. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License version 2 // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE // AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE. // // // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, // UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, // MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS // SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS // SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER // CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL // DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING, // MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR // SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO // EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, // JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION // AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN // THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE. // // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS // YOU HAVE A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY // CRIMINAL LAWS OR CIVIL RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS // SOFTWARE IN OTHER COUNTRIES IS COMPLETELY AT YOUR OWN RISK. THE // SOFTETHER VPN PROJECT HAS DEVELOPED AND DISTRIBUTED THIS SOFTWARE TO // COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING CIVIL RIGHTS INCLUDING // PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER COUNTRIES' LAWS OR // CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES. WE HAVE // NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ // COUNTRIES AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE // WORLD, WITH DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY // COUNTRIES' LAWS, REGULATIONS AND CIVIL RIGHTS TO MAKE THE SOFTWARE // COMPLY WITH ALL COUNTRIES' LAWS BY THE PROJECT. EVEN IF YOU WILL BE // SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A PUBLIC SERVANT IN YOUR // COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE LIABLE TO // RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT // JUST A STATEMENT FOR WARNING AND DISCLAIMER. // // // SOURCE CODE CONTRIBUTION // ------------------------ // // Your contribution to SoftEther VPN Project is much appreciated. // Please send patches to us through GitHub. // Read the SoftEther VPN Patch Acceptance Policy in advance: // http://www.softether.org/5-download/src/9.patch // // // DEAR SECURITY EXPERTS // --------------------- // // If you find a bug or a security vulnerability please kindly inform us // about the problem immediately so that we can fix the security problem // to protect a lot of users around the world as soon as possible. // // Our e-mail address for security reports is: // softether-vpn-security [at] softether.org // // Please note that the above e-mail address is not a technical support // inquiry address. If you need technical assistance, please visit // http://www.softether.org/ and ask your question on the users forum. // // Thank you for your cooperation. // // // NO MEMORY OR RESOURCE LEAKS // --------------------------- // // The memory-leaks and resource-leaks verification under the stress // test has been passed before release this source code. using System; using System.Threading; using System.Data; using System.Data.Sql; using System.Data.SqlClient; using System.Data.SqlTypes; using System.Text; using System.Configuration; using System.Collections; using System.Collections.Generic; using System.Security.Cryptography; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.IO; using System.Drawing; using System.Drawing.Imaging; using System.Drawing.Drawing2D; using System.Web.Mail; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; using System.ComponentModel; using System.Runtime.InteropServices; namespace CoreUtil { public enum CoreLanguage { Japanese = 0, English = 1, } public class CoreLanguageClass { public readonly CoreLanguage Language; public readonly int Id; readonly string name; public string Name { get { if (name == "ja") { if (CoreLanguageList.RegardsJapanAsJP) { return "jp"; } } return name; } } public readonly string TitleInEnglish; public readonly string TitleInNative; public CoreLanguageClass(CoreLanguage lang, int id, string name, string titleInEnglish, string titleInNative) { this.Language = lang; this.Id = id; this.name = name; this.TitleInEnglish = titleInEnglish; this.TitleInNative = titleInNative; } public static void SetCurrentThreadLanguageClass(CoreLanguageClass lang) { ThreadData.CurrentThreadData.DataList["current_thread_language"] = lang; } public static CoreLanguageClass CurrentThreadLanguageClass { get { return GetCurrentThreadLanguageClass(); } set { SetCurrentThreadLanguageClass(value); } } public static CoreLanguage CurrentThreadLanguage { get { return CurrentThreadLanguageClass.Language; } } public static CoreLanguageClass GetCurrentThreadLanguageClass() { CoreLanguageClass lang = null; try { lang = (CoreLanguageClass)ThreadData.CurrentThreadData.DataList["current_thread_language"]; } catch { } if (lang == null) { lang = CoreLanguageList.DefaultLanguage; SetCurrentThreadLanguageClass(lang); } return lang; } } public static class CoreLanguageList { public static readonly CoreLanguageClass DefaultLanguage; public static readonly CoreLanguageClass Japanese; public static readonly CoreLanguageClass English; public static bool RegardsJapanAsJP = false; public static readonly List LanguageList = new List(); static CoreLanguageList() { CoreLanguageList.LanguageList = new List(); CoreLanguageList.Japanese = new CoreLanguageClass(CoreLanguage.Japanese, 0, "ja", "Japanese", "日本語"); CoreLanguageList.English = new CoreLanguageClass(CoreLanguage.English, 1, "en", "English", "English"); CoreLanguageList.DefaultLanguage = CoreLanguageList.Japanese; CoreLanguageList.LanguageList.Add(CoreLanguageList.Japanese); CoreLanguageList.LanguageList.Add(CoreLanguageList.English); } public static CoreLanguageClass GetLanguageClassByName(string name) { Str.NormalizeStringStandard(ref name); foreach (CoreLanguageClass c in LanguageList) { if (Str.StrCmpi(c.Name, name)) { return c; } } return DefaultLanguage; } public static CoreLanguageClass GetLangugageClassByEnum(CoreLanguage lang) { foreach (CoreLanguageClass c in LanguageList) { if (c.Language == lang) { return c; } } return DefaultLanguage; } } public static class Util { public const int SizeOfInt32 = 4; public const int SizeOfInt16 = 2; public const int SizeOfInt64 = 8; public const int SizeOfInt8 = 1; public static byte[] ToByte(ushort i) { byte[] ret = BitConverter.GetBytes(i); Endian(ret); return ret; } public static byte[] ToByte(short i) { byte[] ret = BitConverter.GetBytes(i); Endian(ret); return ret; } public static byte[] ToByte(uint i) { byte[] ret = BitConverter.GetBytes(i); Endian(ret); return ret; } public static byte[] ToByte(int i) { byte[] ret = BitConverter.GetBytes(i); Endian(ret); return ret; } public static byte[] ToByte(ulong i) { byte[] ret = BitConverter.GetBytes(i); Endian(ret); return ret; } public static byte[] ToByte(long i) { byte[] ret = BitConverter.GetBytes(i); Endian(ret); return ret; } public static ushort ByteToUShort(byte[] b) { byte[] c = CloneByteArray(b); Endian(c); return BitConverter.ToUInt16(c, 0); } public static short ByteToShort(byte[] b) { byte[] c = CloneByteArray(b); Endian(c); return BitConverter.ToInt16(c, 0); } public static uint ByteToUInt(byte[] b) { byte[] c = CloneByteArray(b); Endian(c); return BitConverter.ToUInt32(c, 0); } public static int ByteToInt(byte[] b) { byte[] c = CloneByteArray(b); Endian(c); return BitConverter.ToInt32(c, 0); } public static ulong ByteToULong(byte[] b) { byte[] c = CloneByteArray(b); Endian(c); return BitConverter.ToUInt64(c, 0); } public static long ByteToLong(byte[] b) { byte[] c = CloneByteArray(b); Endian(c); return BitConverter.ToInt64(c, 0); } public static byte[] ReadAllFromStream(Stream st) { byte[] tmp = new byte[32 * 1024]; Buf b = new Buf(); while (true) { int r = st.Read(tmp, 0, tmp.Length); if (r == 0) { break; } b.Write(tmp, 0, r); } return b.ByteData; } public static List CloneList(List src) { List ret = new List(); foreach (T t in src) { ret.Add(t); } return ret; } public static byte[] ExtractByteArray(byte[] data, int pos, int len) { byte[] ret = new byte[len]; Util.CopyByte(ret, 0, data, pos, len); return ret; } public static T[] CombineArray(params T[][] arrays) { List o = new List(); foreach (T[] array in arrays) { foreach (T element in array) { o.Add(element); } } return o.ToArray(); } public static byte[] CombineByteArray(byte[] b1, byte[] b2) { Buf b = new Buf(); if (b1 != null) { b.Write(b1); } if (b2 != null) { b.Write(b2); } return b.ByteData; } public static byte[] RemoveStartByteArray(byte[] src, int numBytes) { if (numBytes == 0) { return src; } int num = src.Length - numBytes; byte[] ret = new byte[num]; Util.CopyByte(ret, 0, src, numBytes, num); return ret; } public static DateTime[] GetYearNendoList(DateTime startYear, DateTime endYear) { startYear = GetStartOfNendo(startYear); endYear = GetEndOfNendo(endYear); if (startYear > endYear) { throw new ArgumentException(); } List ret = new List(); DateTime dt; for (dt = startYear; dt <= endYear; dt = GetStartOfNendo(dt.AddYears(1))) { ret.Add(dt); } return ret.ToArray(); } public static DateTime[] GetYearList(DateTime startYear, DateTime endYear) { startYear = GetStartOfYear(startYear); endYear = GetEndOfYear(endYear); if (startYear > endYear) { throw new ArgumentException(); } List ret = new List(); DateTime dt; for (dt = startYear; dt <= endYear; dt = GetStartOfYear(dt.AddYears(1))) { ret.Add(dt); } return ret.ToArray(); } public static DateTime[] GetMonthList(DateTime startMonth, DateTime endMonth) { startMonth = GetStartOfMonth(startMonth); endMonth = GetEndOfMonth(endMonth); if (startMonth > endMonth) { throw new ArgumentException(); } List ret = new List(); DateTime dt; for (dt = startMonth; dt <= endMonth; dt = GetStartOfMonth(dt.AddMonths(1))) { ret.Add(dt); } return ret.ToArray(); } public static int GetAge(DateTime birthDay, DateTime now) { birthDay = birthDay.Date; now = now.Date; DateTime dayBirthDay = new DateTime(2000, birthDay.Month, birthDay.Day); DateTime dayNow = new DateTime(2000, now.Month, now.Day); int ret = now.Year - birthDay.Year; if (dayBirthDay > dayNow) { ret -= 1; } return Math.Max(ret, 0); } public static int GetNumOfDaysInMonth(DateTime dt) { DateTime dt1 = new DateTime(dt.Year, dt.Month, dt.Day); DateTime dt2 = dt1.AddMonths(1); TimeSpan span = dt2 - dt1; return span.Days; } public static int GetNumMonthSpan(DateTime dt1, DateTime dt2, bool kiriage) { if (dt1 > dt2) { DateTime dtt = dt2; dt2 = dt1; dt1 = dtt; } int i; DateTime dt = dt1; for (i = 0; ; i++) { if (kiriage) { if (dt >= dt2) { return i; } } else { if (dt >= dt2.AddMonths(1).AddTicks(-1)) { return i; } } dt = dt.AddMonths(1); } } public static DateTime GetStartOfMonth(DateTime dt) { return new DateTime(dt.Year, dt.Month, 1); } public static DateTime GetEndOfMonth(DateTime dt) { return new DateTime(dt.Year, dt.Month, 1).AddMonths(1).AddSeconds(-1).Date; } public static DateTime GetStartOfYear(DateTime dt) { return new DateTime(dt.Year, 1, 1, 0, 0, 0); } public static DateTime GetEndOfYear(DateTime dt) { return GetStartOfYear(dt).AddYears(1).AddSeconds(-1).Date; } public static DateTime GetEndOfMonthForSettle(DateTime dt) { dt = new DateTime(dt.Year, dt.Month, 1).AddMonths(1).AddSeconds(-1).Date; if (dt.Month == 4 && (new DateTime(dt.Year, 4, 29).DayOfWeek == DayOfWeek.Sunday)) { dt = dt.AddDays(1); } while ((dt.DayOfWeek == DayOfWeek.Sunday || dt.DayOfWeek == DayOfWeek.Saturday) || (dt.Month == 12 && dt.Day >= 29) || (dt.Month == 1 && dt.Day <= 3)) { dt = dt.AddDays(1); } return dt; } public static DateTime GetStartOfDay(DateTime dt) { return dt.Date; } public static DateTime GetEndOfDate(DateTime dt) { return GetStartOfDay(dt).AddDays(1).AddTicks(-1); } public static int GetNendo(DateTime dt) { if (dt.Month >= 4) { return dt.Year; } else { return dt.Year - 1; } } public static DateTime GetStartOfNendo(DateTime dt) { return GetStartOfNendo(GetNendo(dt)); } public static DateTime GetStartOfNendo(int nendo) { return new DateTime(nendo, 4, 1, 0, 0, 0).Date; } public static DateTime GetEndOfNendo(DateTime dt) { return GetEndOfNendo(GetNendo(dt)); } public static DateTime GetEndOfNendo(int nendo) { return new DateTime(nendo + 1, 3, 31, 0, 0, 0).Date; } public static void Endian(byte[] b) { if (Env.IsLittleEndian) { Array.Reverse(b); } } public static byte[] EndianRetByte(byte[] b) { b = Util.CloneByteArray(b); Endian(b); return b; } public static UInt16 Endian(UInt16 v) { return Util.ByteToUShort(Util.EndianRetByte(Util.ToByte(v))); } public static UInt32 Endian(UInt32 v) { return Util.ByteToUInt(Util.EndianRetByte(Util.ToByte(v))); } public static UInt64 Endian(UInt64 v) { return Util.ByteToULong(Util.EndianRetByte(Util.ToByte(v))); } public static string SafeDomainStr(string str) { string ret = str.Replace("(", "").Replace(")", "").Replace(" ", "").Replace("-", "").Replace("#", "") .Replace("%", "").Replace("%", "").Replace("&", "").Replace(".", ""); if (ret == "") { ret = "host"; } return ret; } public static byte[] CopyByte(byte[] src) { return (byte[])src.Clone(); } public static byte[] CopyByte(byte[] src, int srcOffset) { return CopyByte(src, srcOffset, src.Length - srcOffset); } public static byte[] CopyByte(byte[] src, int srcOffset, int size) { byte[] ret = new byte[size]; CopyByte(ret, 0, src, srcOffset, size); return ret; } public static void CopyByte(byte[] dst, byte[] src, int srcOffset, int size) { CopyByte(dst, 0, src, srcOffset, size); } public static void CopyByte(byte[] dst, int dstOffset, byte[] src) { CopyByte(dst, dstOffset, src, 0, src.Length); } public static void CopyByte(byte[] dst, int dstOffset, byte[] src, int srcOffset, int size) { Array.Copy(src, srcOffset, dst, dstOffset, size); } public static bool IsZero(byte[] data) { return IsZero(data, 0, data.Length); } public static bool IsZero(byte[] data, int offset, int size) { int i; for (i = offset; i < offset + size; i++) { if (data[i] != 0) { return false; } } return true; } public static bool CompareByte(byte[] b1, byte[] b2) { if (b1.Length != b2.Length) { return false; } int i, len; len = b1.Length; for (i = 0; i < len; i++) { if (b1[i] != b2[i]) { return false; } } return true; } public static int CompareByteRetInt(byte[] b1, byte[] b2) { int i; for (i = 0; ; i++) { int a1 = -1, a2 = -1; if (b1.Length < i) { a1 = (int)b1[i]; } if (b2.Length < i) { a2 = (int)b2[i]; } if (a1 > a2) { return 1; } else if (a1 < a2) { return -1; } if (a1 == -1 && a2 == -1) { return 0; } } } public static byte[] CloneByteArray(byte[] src) { byte[] ret = new byte[src.Length]; Util.CopyByte(ret, src, 0, src.Length); return ret; } public static DateTime UnixTimeToDateTime(uint t) { return new DateTime(1970, 1, 1).AddSeconds(t); } public static uint DateTimeToUnixTime(DateTime dt) { TimeSpan ts = dt - new DateTime(1970, 1, 1); if (ts.Ticks < 0) { throw new InvalidDataException("dt"); } return (uint)ts.TotalSeconds; } public static DateTime ConvertDateTime(ulong time64) { if (time64 == 0) { return new DateTime(0); } return new DateTime(((long)time64 + 62135629200000) * 10000); } public static ulong ConvertDateTime(DateTime dt) { if (dt.Ticks == 0) { return 0; } return (ulong)dt.Ticks / 10000 - 62135629200000; } public static TimeSpan ConvertTimeSpan(ulong tick) { return new TimeSpan((long)tick * 10000); } public static ulong ConvertTimeSpan(TimeSpan span) { return (ulong)span.Ticks / 10000; } public static ushort DateTimeToDosDate(DateTime dt) { return (ushort)( ((uint)(dt.Year - 1980) << 9) | ((uint)dt.Month << 5) | (uint)dt.Day); } public static ushort DateTimeToDosTime(DateTime dt) { return (ushort)( ((uint)dt.Hour << 11) | ((uint)dt.Minute << 5) | ((uint)dt.Second >> 1)); } public static bool IsNullOrEmpty(object o) { if (o == null) { return true; } if (o is string) { string s = (string)o; return Str.IsEmptyStr(s); } if (o is Array) { Array a = (Array)o; if (a.Length == 0) { return true; } } return false; } public static byte[] GetXmlSchemaFromType(Type type) { XmlSchemas sms = new XmlSchemas(); XmlSchemaExporter ex = new XmlSchemaExporter(sms); XmlReflectionImporter im = new XmlReflectionImporter(); XmlTypeMapping map = im.ImportTypeMapping(type); ex.ExportTypeMapping(map); sms.Compile(null, false); MemoryStream ms = new MemoryStream(); StreamWriter sw = new StreamWriter(ms); foreach (System.Xml.Schema.XmlSchema sm in sms) { sm.Write(sw); } sw.Close(); ms.Flush(); byte[] data = ms.ToArray(); return data; } public static string GetXmlSchemaFromTypeString(Type type) { byte[] data = GetXmlSchemaFromType(type); return Str.Utf8Encoding.GetString(data); } public static string ObjectToXmlString(object o) { byte[] data = ObjectToXml(o); return Str.Utf8Encoding.GetString(data); } public static byte[] ObjectToXml(object o) { if (o == null) { return null; } Type t = o.GetType(); return ObjectToXml(o, t); } public static string ObjectToXmlString(object o, Type t) { byte[] data = ObjectToXml(o, t); return Str.Utf8Encoding.GetString(data); } public static byte[] ObjectToXml(object o, Type t) { if (o == null) { return null; } MemoryStream ms = new MemoryStream(); XmlSerializer x = new XmlSerializer(t); x.Serialize(ms, o); return ms.ToArray(); } public static object XmlToObject(string str, Type t) { if (Str.IsEmptyStr(str)) { return null; } byte[] data = Str.Utf8Encoding.GetBytes(str); return XmlToObject(data, t); } public static object XmlToObject(byte[] data, Type t) { if (data == null || data.Length == 0) { return null; } MemoryStream ms = new MemoryStream(); ms.Write(data, 0, data.Length); ms.Position = 0; XmlSerializer x = new XmlSerializer(t); return x.Deserialize(ms); } public static void NoOP(object o) { } public static void NoOP() { } public static bool False { get { return false; } } public static bool True { get { return true; } } public static int Zero { get { return 0; } } public static object ByteToStruct(byte[] src, Type type) { int size = src.Length; if (size != SizeOfStruct(type)) { throw new SystemException("size error"); } IntPtr p = Marshal.AllocHGlobal(size); try { Marshal.Copy(src, 0, p, size); return Marshal.PtrToStructure(p, type); } finally { Marshal.FreeHGlobal(p); } } public static byte[] StructToByte(object obj) { int size = SizeOfStruct(obj); IntPtr p = Marshal.AllocHGlobal(size); try { Marshal.StructureToPtr(obj, p, false); byte[] ret = new byte[size]; Marshal.Copy(p, ret, 0, size); return ret; } finally { Marshal.FreeHGlobal(p); } } public static int SizeOfStruct(object obj) { return Marshal.SizeOf(obj); } public static int SizeOfStruct(Type type) { return Marshal.SizeOf(type); } public static XmlAndXsd GenerateXmlAndXsd(object obj) { XmlAndXsd ret = new XmlAndXsd(); Type type = obj.GetType(); ret.XsdFileName = Str.MakeSafeFileName(type.Name + ".xsd"); ret.XsdData = GetXmlSchemaFromType(type); ret.XmlFileName = Str.MakeSafeFileName(type.Name + ".xml"); string str = Util.ObjectToXmlString(obj); str = str.Replace( "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"", "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xsi:noNamespaceSchemaLocation=\"" + ret.XsdFileName + "\""); ret.XmlData = Str.Utf8Encoding.GetBytes(str); return ret; } } public class XmlAndXsd { public byte[] XmlData; public byte[] XsdData; public string XmlFileName; public string XsdFileName; } }