#if FRAMEWORK20 using System; using System.Collections.Generic; using System.Text; using System.Security.Permissions; using System.Runtime.Serialization; using System.Globalization; using System.Security; using Microsoft.Win32; using System.Runtime.InteropServices; using System.Security.AccessControl; using System.IO; using System.Runtime.ConstrainedExecution; namespace DevComponents.Schedule { [Serializable, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] public sealed class TimeZoneInfo : IEquatable, ISerializable, IDeserializationCallback { // Fields private const string c_daylightValue = "Dlt"; private const string c_disableDST = "DisableAutoDaylightTimeSet"; private const string c_disableDynamicDST = "DynamicDaylightTimeDisabled"; private const string c_displayValue = "Display"; private const string c_firstEntryValue = "FirstEntry"; private const string c_lastEntryValue = "LastEntry"; private const string c_localId = "Local"; private const int c_maxKeyLength = 0xff; private const string c_muiDaylightValue = "MUI_Dlt"; private const string c_muiDisplayValue = "MUI_Display"; private const string c_muiStandardValue = "MUI_Std"; private const string c_standardValue = "Std"; private const long c_ticksPerDay = 0xc92a69c000L; private const long c_ticksPerDayRange = 0xc92a6998f0L; private const long c_ticksPerHour = 0x861c46800L; private const long c_ticksPerMillisecond = 0x2710L; private const long c_ticksPerMinute = 0x23c34600L; private const long c_ticksPerSecond = 0x989680L; private const string c_timeZoneInfoRegistryHive = @"SYSTEM\CurrentControlSet\Control\TimeZoneInformation"; private const string c_timeZoneInfoRegistryHivePermissionList = @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation"; private const string c_timeZoneInfoValue = "TZI"; private const string c_timeZonesRegistryHive = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"; private const string c_timeZonesRegistryHivePermissionList = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"; private const string c_utcId = "UTC"; private AdjustmentRule[] m_adjustmentRules; private TimeSpan m_baseUtcOffset; private string m_daylightDisplayName; private string m_displayName; private string m_id; private string m_standardDisplayName; private bool m_supportsDaylightSavingTime; private static bool s_allSystemTimeZonesRead = false; private static object s_hiddenInternalSyncObject; private static Dictionary s_hiddenSystemTimeZones; private static TimeZoneInfo s_localTimeZone; private static List s_readOnlySystemTimeZones; private static TimeZoneInfo s_utcTimeZone; // Methods private TimeZoneInfo(NativeMethods.TimeZoneInformation zone, bool dstDisabled) { if (string.IsNullOrEmpty(zone.StandardName)) { this.m_id = "Local"; } else { this.m_id = zone.StandardName; } this.m_baseUtcOffset = new TimeSpan(0, -zone.Bias, 0); if (!dstDisabled) { NativeMethods.RegistryTimeZoneInformation timeZoneInformation = new NativeMethods.RegistryTimeZoneInformation(zone); AdjustmentRule rule = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, DateTime.MinValue.Date, DateTime.MaxValue.Date); if (rule != null) { this.m_adjustmentRules = new AdjustmentRule[] { rule }; } } ValidateTimeZoneInfo(this.m_id, this.m_baseUtcOffset, this.m_adjustmentRules, out this.m_supportsDaylightSavingTime); this.m_displayName = zone.StandardName; this.m_standardDisplayName = zone.StandardName; this.m_daylightDisplayName = zone.DaylightName; } private TimeZoneInfo(SerializationInfo info, StreamingContext context) { if (info == null) { throw new ArgumentNullException("info"); } this.m_id = (string)info.GetValue("Id", typeof(string)); this.m_displayName = (string)info.GetValue("DisplayName", typeof(string)); this.m_standardDisplayName = (string)info.GetValue("StandardName", typeof(string)); this.m_daylightDisplayName = (string)info.GetValue("DaylightName", typeof(string)); this.m_baseUtcOffset = (TimeSpan)info.GetValue("BaseUtcOffset", typeof(TimeSpan)); this.m_adjustmentRules = (AdjustmentRule[])info.GetValue("AdjustmentRules", typeof(AdjustmentRule[])); this.m_supportsDaylightSavingTime = (bool)info.GetValue("SupportsDaylightSavingTime", typeof(bool)); } private TimeZoneInfo(string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName, string daylightDisplayName, AdjustmentRule[] adjustmentRules, bool disableDaylightSavingTime) { bool flag; ValidateTimeZoneInfo(id, baseUtcOffset, adjustmentRules, out flag); if ((!disableDaylightSavingTime && (adjustmentRules != null)) && (adjustmentRules.Length > 0)) { this.m_adjustmentRules = (AdjustmentRule[])adjustmentRules.Clone(); } this.m_id = id; this.m_baseUtcOffset = baseUtcOffset; this.m_displayName = displayName; this.m_standardDisplayName = standardDisplayName; this.m_daylightDisplayName = disableDaylightSavingTime ? null : daylightDisplayName; this.m_supportsDaylightSavingTime = flag && !disableDaylightSavingTime; } [SecurityCritical, SecurityTreatAsSafe] private static bool CheckDaylightSavingTimeDisabled() { try { PermissionSet set = new PermissionSet(PermissionState.None); set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation")); set.Assert(); using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\TimeZoneInformation", RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey)) { if (key == null) { return false; } int num = 0; try { num = (int)key.GetValue("DisableAutoDaylightTimeSet", 0, RegistryValueOptions.None); } catch (InvalidCastException) { } if (num != 1) { try { num = (int)key.GetValue("DynamicDaylightTimeDisabled", 0, RegistryValueOptions.None); } catch (InvalidCastException) { } if (num != 1) { goto Label_009C; } } return true; } } finally { PermissionSet.RevertAssert(); } Label_009C: return false; } private static bool CheckDaylightSavingTimeNotSupported(NativeMethods.TimeZoneInformation timeZone) { return (((((timeZone.DaylightDate.Year == timeZone.StandardDate.Year) && (timeZone.DaylightDate.Month == timeZone.StandardDate.Month)) && ((timeZone.DaylightDate.DayOfWeek == timeZone.StandardDate.DayOfWeek) && (timeZone.DaylightDate.Day == timeZone.StandardDate.Day))) && (((timeZone.DaylightDate.Hour == timeZone.StandardDate.Hour) && (timeZone.DaylightDate.Minute == timeZone.StandardDate.Minute)) && (timeZone.DaylightDate.Second == timeZone.StandardDate.Second))) && (timeZone.DaylightDate.Milliseconds == timeZone.StandardDate.Milliseconds)); } private static bool CheckIsDst(DateTime startTime, DateTime time, DateTime endTime) { if (startTime.Year != endTime.Year) { endTime = endTime.AddYears(startTime.Year - endTime.Year); } if (startTime.Year != time.Year) { time = time.AddYears(startTime.Year - time.Year); } if (startTime > endTime) { return ((time < endTime) || (time >= startTime)); } return ((time >= startTime) && (time < endTime)); } public static void ClearCachedData() { lock (s_internalSyncObject) { s_localTimeZone = null; s_utcTimeZone = null; s_systemTimeZones = null; s_readOnlySystemTimeZones = null; s_allSystemTimeZonesRead = false; } } public static DateTime ConvertTime(DateTime dateTime, TimeZoneInfo destinationTimeZone) { if (destinationTimeZone == null) { throw new ArgumentNullException("destinationTimeZone"); } if (dateTime.Kind == DateTimeKind.Utc) { lock (s_internalSyncObject) { return ConvertTime(dateTime, Utc, destinationTimeZone); } } lock (s_internalSyncObject) { return ConvertTime(dateTime, Local, destinationTimeZone); } } public static DateTimeOffset ConvertTime(DateTimeOffset dateTimeOffset, TimeZoneInfo destinationTimeZone) { if (destinationTimeZone == null) { throw new ArgumentNullException("destinationTimeZone"); } DateTime utcDateTime = dateTimeOffset.UtcDateTime; TimeSpan utcOffsetFromUtc = GetUtcOffsetFromUtc(utcDateTime, destinationTimeZone); long ticks = utcDateTime.Ticks + utcOffsetFromUtc.Ticks; if (ticks > DateTimeOffset.MaxValue.Ticks) { return DateTimeOffset.MaxValue; } if (ticks < DateTimeOffset.MinValue.Ticks) { return DateTimeOffset.MinValue; } return new DateTimeOffset(ticks, utcOffsetFromUtc); } public static DateTime ConvertTime(DateTime dateTime, TimeZoneInfo sourceTimeZone, TimeZoneInfo destinationTimeZone) { return ConvertTime(dateTime, sourceTimeZone, destinationTimeZone, TimeZoneInfoOptions.None); } internal static DateTime ConvertTime(DateTime dateTime, TimeZoneInfo sourceTimeZone, TimeZoneInfo destinationTimeZone, TimeZoneInfoOptions flags) { if (sourceTimeZone == null) { throw new ArgumentNullException("sourceTimeZone"); } if (destinationTimeZone == null) { throw new ArgumentNullException("destinationTimeZone"); } DateTimeKind correspondingKind = sourceTimeZone.GetCorrespondingKind(); if ((((flags & TimeZoneInfoOptions.NoThrowOnInvalidTime) == 0) && (dateTime.Kind != DateTimeKind.Unspecified)) && (dateTime.Kind != correspondingKind)) { throw new ArgumentException("Argument_ConvertMismatch", "sourceTimeZone"); } AdjustmentRule adjustmentRuleForTime = sourceTimeZone.GetAdjustmentRuleForTime(dateTime); TimeSpan baseUtcOffset = sourceTimeZone.BaseUtcOffset; if (adjustmentRuleForTime != null) { bool flag = false; DaylightTime daylightTime = GetDaylightTime(dateTime.Year, adjustmentRuleForTime); if (((flags & TimeZoneInfoOptions.NoThrowOnInvalidTime) == 0) && GetIsInvalidTime(dateTime, adjustmentRuleForTime, daylightTime)) { throw new ArgumentException("Argument_DateTimeIsInvalid", "dateTime"); } flag = GetIsDaylightSavings(dateTime, adjustmentRuleForTime, daylightTime); baseUtcOffset += flag ? adjustmentRuleForTime.DaylightDelta : TimeSpan.Zero; } DateTimeKind kind = destinationTimeZone.GetCorrespondingKind(); if (((dateTime.Kind != DateTimeKind.Unspecified) && (correspondingKind != DateTimeKind.Unspecified)) && (correspondingKind == kind)) { return dateTime; } long ticks = dateTime.Ticks - baseUtcOffset.Ticks; DateTime time2 = ConvertUtcToTimeZone(ticks, destinationTimeZone); if (kind == DateTimeKind.Local) { kind = DateTimeKind.Unspecified; } return new DateTime(time2.Ticks, kind); } public static DateTime ConvertTimeBySystemTimeZoneId(DateTime dateTime, string destinationTimeZoneId) { return ConvertTime(dateTime, FindSystemTimeZoneById(destinationTimeZoneId)); } public static DateTimeOffset ConvertTimeBySystemTimeZoneId(DateTimeOffset dateTimeOffset, string destinationTimeZoneId) { return ConvertTime(dateTimeOffset, FindSystemTimeZoneById(destinationTimeZoneId)); } public static DateTime ConvertTimeBySystemTimeZoneId(DateTime dateTime, string sourceTimeZoneId, string destinationTimeZoneId) { if ((dateTime.Kind == DateTimeKind.Local) && (string.Compare(sourceTimeZoneId, Local.Id, StringComparison.OrdinalIgnoreCase) == 0)) { lock (s_internalSyncObject) { return ConvertTime(dateTime, Local, FindSystemTimeZoneById(destinationTimeZoneId)); } } if ((dateTime.Kind == DateTimeKind.Utc) && (string.Compare(sourceTimeZoneId, Utc.Id, StringComparison.OrdinalIgnoreCase) == 0)) { lock (s_internalSyncObject) { return ConvertTime(dateTime, Utc, FindSystemTimeZoneById(destinationTimeZoneId)); } } return ConvertTime(dateTime, FindSystemTimeZoneById(sourceTimeZoneId), FindSystemTimeZoneById(destinationTimeZoneId)); } public static DateTime ConvertTimeFromUtc(DateTime dateTime, TimeZoneInfo destinationTimeZone) { lock (s_internalSyncObject) { return ConvertTime(dateTime, Utc, destinationTimeZone); } } public static DateTime ConvertTimeToUtc(DateTime dateTime) { if (dateTime.Kind == DateTimeKind.Utc) { return dateTime; } lock (s_internalSyncObject) { return ConvertTime(dateTime, Local, Utc); } } public static DateTime ConvertTimeToUtc(DateTime dateTime, TimeZoneInfo sourceTimeZone) { lock (s_internalSyncObject) { return ConvertTime(dateTime, sourceTimeZone, Utc); } } private static DateTime ConvertUtcToTimeZone(long ticks, TimeZoneInfo destinationTimeZone) { DateTime maxValue; if (ticks > DateTime.MaxValue.Ticks) { maxValue = DateTime.MaxValue; } else if (ticks < DateTime.MinValue.Ticks) { maxValue = DateTime.MinValue; } else { maxValue = new DateTime(ticks); } TimeSpan utcOffsetFromUtc = GetUtcOffsetFromUtc(maxValue, destinationTimeZone); ticks += utcOffsetFromUtc.Ticks; if (ticks > DateTime.MaxValue.Ticks) { return DateTime.MaxValue; } if (ticks < DateTime.MinValue.Ticks) { return DateTime.MinValue; } return new DateTime(ticks); } private static AdjustmentRule CreateAdjustmentRuleFromTimeZoneInformation(NativeMethods.RegistryTimeZoneInformation timeZoneInformation, DateTime startDate, DateTime endDate) { if (timeZoneInformation.StandardDate.Month == 0) { return null; } TransitionTime? nullable = TransitionTimeFromTimeZoneInformation(timeZoneInformation, true); if (!nullable.HasValue) { return null; } TransitionTime? nullable2 = TransitionTimeFromTimeZoneInformation(timeZoneInformation, false); if (!nullable2.HasValue) { return null; } if (nullable.Equals(nullable2)) { return null; } return AdjustmentRule.CreateAdjustmentRule(startDate, endDate, new TimeSpan(0, -timeZoneInformation.DaylightBias, 0), nullable.Value, nullable2.Value); } public static TimeZoneInfo CreateCustomTimeZone(string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName) { return new TimeZoneInfo(id, baseUtcOffset, displayName, standardDisplayName, standardDisplayName, null, false); } public static TimeZoneInfo CreateCustomTimeZone(string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName, string daylightDisplayName, AdjustmentRule[] adjustmentRules) { return new TimeZoneInfo(id, baseUtcOffset, displayName, standardDisplayName, daylightDisplayName, adjustmentRules, false); } public static TimeZoneInfo CreateCustomTimeZone(string id, TimeSpan baseUtcOffset, string displayName, string standardDisplayName, string daylightDisplayName, AdjustmentRule[] adjustmentRules, bool disableDaylightSavingTime) { return new TimeZoneInfo(id, baseUtcOffset, displayName, standardDisplayName, daylightDisplayName, adjustmentRules, disableDaylightSavingTime); } public bool Equals(TimeZoneInfo other) { return (((other != null) && (string.Compare(this.m_id, other.m_id, StringComparison.OrdinalIgnoreCase) == 0)) && this.HasSameRules(other)); } [SecurityCritical, SecurityTreatAsSafe] private static string FindIdFromTimeZoneInformation(NativeMethods.TimeZoneInformation timeZone, out bool dstDisabled) { dstDisabled = false; try { PermissionSet set = new PermissionSet(PermissionState.None); set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones")); set.Assert(); using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey)) { if (key == null) { return null; } foreach (string str in key.GetSubKeyNames()) { if (TryCompareTimeZoneInformationToRegistry(timeZone, str, out dstDisabled)) { return str; } } } } finally { PermissionSet.RevertAssert(); } return null; } public static TimeZoneInfo FindSystemTimeZoneById(string id) { if (string.Compare(id, "UTC", StringComparison.OrdinalIgnoreCase) == 0) { return Utc; } lock (s_internalSyncObject) { return GetTimeZone(id); } } public static TimeZoneInfo FromSerializedString(string source) { if (source == null) { throw new ArgumentNullException("source"); } if (source.Length == 0) { throw new ArgumentException("Argument_InvalidSerializedString source"); } return StringSerializer.GetDeserializedTimeZoneInfo(source); } private AdjustmentRule GetAdjustmentRuleForTime(DateTime dateTime) { if ((this.m_adjustmentRules != null) && (this.m_adjustmentRules.Length != 0)) { DateTime date = dateTime.Date; for (int i = 0; i < this.m_adjustmentRules.Length; i++) { if ((this.m_adjustmentRules[i].DateStart <= date) && (this.m_adjustmentRules[i].DateEnd >= date)) { return this.m_adjustmentRules[i]; } } } return null; } public AdjustmentRule[] GetAdjustmentRules() { if (this.m_adjustmentRules == null) { return new AdjustmentRule[0]; } return (AdjustmentRule[])this.m_adjustmentRules.Clone(); } public TimeSpan[] GetAmbiguousTimeOffsets(DateTime dateTime) { DateTime time; bool flag; if (!this.m_supportsDaylightSavingTime) { throw new ArgumentException("Argument_DateTimeIsNotAmbiguous", "dateTime"); } if (dateTime.Kind == DateTimeKind.Local) { lock (s_internalSyncObject) { time = ConvertTime(dateTime, Local, this, TimeZoneInfoOptions.NoThrowOnInvalidTime); goto Label_007D; } } if (dateTime.Kind == DateTimeKind.Utc) { lock (s_internalSyncObject) { time = ConvertTime(dateTime, Utc, this, TimeZoneInfoOptions.NoThrowOnInvalidTime); goto Label_007D; } } time = dateTime; Label_007D: flag = false; AdjustmentRule adjustmentRuleForTime = this.GetAdjustmentRuleForTime(time); if (adjustmentRuleForTime != null) { DaylightTime daylightTime = GetDaylightTime(time.Year, adjustmentRuleForTime); flag = GetIsAmbiguousTime(time, adjustmentRuleForTime, daylightTime); } if (!flag) { throw new ArgumentException("Argument_DateTimeIsNotAmbiguous", "dateTime"); } TimeSpan[] spanArray = new TimeSpan[2]; if (adjustmentRuleForTime.DaylightDelta > TimeSpan.Zero) { spanArray[0] = this.m_baseUtcOffset; spanArray[1] = this.m_baseUtcOffset + adjustmentRuleForTime.DaylightDelta; return spanArray; } spanArray[0] = this.m_baseUtcOffset + adjustmentRuleForTime.DaylightDelta; spanArray[1] = this.m_baseUtcOffset; return spanArray; } public TimeSpan[] GetAmbiguousTimeOffsets(DateTimeOffset dateTimeOffset) { if (!this.m_supportsDaylightSavingTime) { throw new ArgumentException("Argument_DateTimeOffsetIsNotAmbiguous", "dateTimeOffset"); } DateTime dateTime = ConvertTime(dateTimeOffset, this).DateTime; bool flag = false; AdjustmentRule adjustmentRuleForTime = this.GetAdjustmentRuleForTime(dateTime); if (adjustmentRuleForTime != null) { DaylightTime daylightTime = GetDaylightTime(dateTime.Year, adjustmentRuleForTime); flag = GetIsAmbiguousTime(dateTime, adjustmentRuleForTime, daylightTime); } if (!flag) { throw new ArgumentException("Argument_DateTimeOffsetIsNotAmbiguous", "dateTimeOffset"); } TimeSpan[] spanArray = new TimeSpan[2]; if (adjustmentRuleForTime.DaylightDelta > TimeSpan.Zero) { spanArray[0] = this.m_baseUtcOffset; spanArray[1] = this.m_baseUtcOffset + adjustmentRuleForTime.DaylightDelta; return spanArray; } spanArray[0] = this.m_baseUtcOffset + adjustmentRuleForTime.DaylightDelta; spanArray[1] = this.m_baseUtcOffset; return spanArray; } private DateTimeKind GetCorrespondingKind() { if (this == s_utcTimeZone) { return DateTimeKind.Utc; } if (this == s_localTimeZone) { return DateTimeKind.Local; } return DateTimeKind.Unspecified; } private static DaylightTime GetDaylightTime(int year, AdjustmentRule rule) { TimeSpan daylightDelta = rule.DaylightDelta; DateTime start = TransitionTimeToDateTime(year, rule.DaylightTransitionStart); return new DaylightTime(start, TransitionTimeToDateTime(year, rule.DaylightTransitionEnd), daylightDelta); } public override int GetHashCode() { return this.m_id.ToUpperInvariant().GetHashCode(); } private static bool GetIsAmbiguousTime(DateTime time, AdjustmentRule rule, DaylightTime daylightTime) { bool flag = false; if ((rule != null) && (rule.DaylightDelta != TimeSpan.Zero)) { DateTime end; DateTime time3; DateTime time4; DateTime time5; if (rule.DaylightDelta > TimeSpan.Zero) { end = daylightTime.End; time3 = daylightTime.End - rule.DaylightDelta; } else { end = daylightTime.Start; time3 = daylightTime.Start + rule.DaylightDelta; } flag = (time >= time3) && (time < end); if (flag || (end.Year == time3.Year)) { return flag; } try { time4 = end.AddYears(1); time5 = time3.AddYears(1); flag = (time >= time5) && (time < time4); } catch (ArgumentOutOfRangeException) { } if (flag) { return flag; } try { time4 = end.AddYears(-1); time5 = time3.AddYears(-1); flag = (time >= time5) && (time < time4); } catch (ArgumentOutOfRangeException) { } } return flag; } private static bool GetIsDaylightSavings(DateTime time, AdjustmentRule rule, DaylightTime daylightTime) { if (rule == null) { return false; } bool flag = rule.DaylightDelta > TimeSpan.Zero; DateTime startTime = daylightTime.Start + (flag ? rule.DaylightDelta : TimeSpan.Zero); DateTime endTime = daylightTime.End + (flag ? -(rule.DaylightDelta) : TimeSpan.Zero); return CheckIsDst(startTime, time, endTime); } private static bool GetIsDaylightSavingsFromUtc(DateTime time, int Year, TimeSpan utc, AdjustmentRule rule) { if (rule == null) { return false; } TimeSpan span = utc; DaylightTime daylightTime = GetDaylightTime(Year, rule); DateTime startTime = daylightTime.Start - span; DateTime endTime = (daylightTime.End - span) - rule.DaylightDelta; return CheckIsDst(startTime, time, endTime); } private static bool GetIsInvalidTime(DateTime time, AdjustmentRule rule, DaylightTime daylightTime) { bool flag = false; if ((rule != null) && (rule.DaylightDelta != TimeSpan.Zero)) { DateTime end; DateTime time3; DateTime time4; DateTime time5; if (rule.DaylightDelta < TimeSpan.Zero) { end = daylightTime.End; time3 = daylightTime.End - rule.DaylightDelta; } else { end = daylightTime.Start; time3 = daylightTime.Start + rule.DaylightDelta; } flag = (time >= end) && (time < time3); if (flag || (end.Year == time3.Year)) { return flag; } try { time4 = end.AddYears(1); time5 = time3.AddYears(1); flag = (time >= time4) && (time < time5); } catch (ArgumentOutOfRangeException) { } if (flag) { return flag; } try { time4 = end.AddYears(-1); time5 = time3.AddYears(-1); flag = (time >= time4) && (time < time5); } catch (ArgumentOutOfRangeException) { } } return flag; } [SecurityCritical] private static TimeZoneInfo GetLocalTimeZone() { string id = null; try { TimeZoneInfo info; Exception exception; TimeZoneInfo info2; Exception exception2; NativeMethods.DynamicTimeZoneInformation lpDynamicTimeZoneInformation = new NativeMethods.DynamicTimeZoneInformation(); long dynamicTimeZoneInformation = UnsafeNativeMethods.GetDynamicTimeZoneInformation(out lpDynamicTimeZoneInformation); if (dynamicTimeZoneInformation == -1L) { return CreateCustomTimeZone("Local", TimeSpan.Zero, "Local", "Local"); } NativeMethods.TimeZoneInformation timeZone = new NativeMethods.TimeZoneInformation(lpDynamicTimeZoneInformation); bool dstDisabled = CheckDaylightSavingTimeDisabled(); if (!string.IsNullOrEmpty(lpDynamicTimeZoneInformation.TimeZoneKeyName) && (TryGetTimeZone(lpDynamicTimeZoneInformation.TimeZoneKeyName, dstDisabled, out info, out exception) == TimeZoneInfoResult.Success)) { return info; } id = FindIdFromTimeZoneInformation(timeZone, out dstDisabled); if ((id != null) && (TryGetTimeZone(id, dstDisabled, out info2, out exception2) == TimeZoneInfoResult.Success)) { return info2; } return GetLocalTimeZoneFromWin32Data(timeZone, dstDisabled); } catch (EntryPointNotFoundException) { bool flag2; TimeZoneInfo info3; Exception exception3; NativeMethods.TimeZoneInformation lpTimeZoneInformation = new NativeMethods.TimeZoneInformation(); long timeZoneInformation = UnsafeNativeMethods.GetTimeZoneInformation(out lpTimeZoneInformation); if (timeZoneInformation == -1L) { return CreateCustomTimeZone("Local", TimeSpan.Zero, "Local", "Local"); } id = FindIdFromTimeZoneInformation(lpTimeZoneInformation, out flag2); if ((id != null) && (TryGetTimeZone(id, flag2, out info3, out exception3) == TimeZoneInfoResult.Success)) { return info3; } return GetLocalTimeZoneFromWin32Data(lpTimeZoneInformation, flag2); } } private static TimeZoneInfo GetLocalTimeZoneFromWin32Data(NativeMethods.TimeZoneInformation timeZoneInformation, bool dstDisabled) { TimeZoneInfo info = null; try { info = new TimeZoneInfo(timeZoneInformation, dstDisabled); } catch (ArgumentException) { } catch (InvalidTimeZoneException) { } return info; try { info = new TimeZoneInfo(timeZoneInformation, true); } catch (ArgumentException) { } catch (InvalidTimeZoneException) { } return info; } [SecurityTreatAsSafe, SecurityCritical] public static List GetSystemTimeZones() { lock (s_internalSyncObject) { if (!s_allSystemTimeZonesRead) { PermissionSet set = new PermissionSet(PermissionState.None); set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones")); set.Assert(); using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey)) { if (key == null) { List list; if (s_systemTimeZones != null) { list = new List(s_systemTimeZones.Values); } else { list = new List(); } s_readOnlySystemTimeZones = new List(list); s_allSystemTimeZonesRead = true; return s_readOnlySystemTimeZones; } foreach (string str in key.GetSubKeyNames()) { TimeZoneInfo info; Exception exception; TryGetTimeZone(str, false, out info, out exception); } } IComparer comparer = new TimeZoneInfoComparer(); List list2 = new List(s_systemTimeZones.Values); list2.Sort(comparer); s_readOnlySystemTimeZones = new List(list2); s_allSystemTimeZonesRead = true; } return s_readOnlySystemTimeZones; } } private static TimeZoneInfo GetTimeZone(string id) { TimeZoneInfo info; Exception exception; if (id == null) { throw new ArgumentNullException("id"); } if (((id.Length == 0) || (id.Length > 0xff)) || id.Contains("\0")) { throw new TimeZoneNotFoundException("TimeZoneNotFound_MissingRegistryData, id"); } switch (TryGetTimeZone(id, false, out info, out exception)) { case TimeZoneInfoResult.Success: return info; case TimeZoneInfoResult.InvalidTimeZoneException: throw new InvalidTimeZoneException("InvalidTimeZone_InvalidRegistryData, id", exception); case TimeZoneInfoResult.SecurityException: throw new SecurityException("Security_CannotReadRegistryData, id", exception); } throw new TimeZoneNotFoundException("TimeZoneNotFound_MissingRegistryData, id", exception); } public TimeSpan GetUtcOffset(DateTime dateTime) { if (dateTime.Kind == DateTimeKind.Local) { DateTime time; lock (s_internalSyncObject) { if (this.GetCorrespondingKind() == DateTimeKind.Local) { return GetUtcOffset(dateTime, this); } time = ConvertTime(dateTime, Local, Utc, TimeZoneInfoOptions.NoThrowOnInvalidTime); } return GetUtcOffsetFromUtc(time, this); } if (dateTime.Kind != DateTimeKind.Utc) { return GetUtcOffset(dateTime, this); } if (this.GetCorrespondingKind() == DateTimeKind.Utc) { return this.m_baseUtcOffset; } return GetUtcOffsetFromUtc(dateTime, this); } public TimeSpan GetUtcOffset(DateTimeOffset dateTimeOffset) { return GetUtcOffsetFromUtc(dateTimeOffset.UtcDateTime, this); } private static TimeSpan GetUtcOffset(DateTime time, TimeZoneInfo zone) { TimeSpan baseUtcOffset = zone.BaseUtcOffset; AdjustmentRule adjustmentRuleForTime = zone.GetAdjustmentRuleForTime(time); if (adjustmentRuleForTime != null) { DaylightTime daylightTime = GetDaylightTime(time.Year, adjustmentRuleForTime); bool flag = GetIsDaylightSavings(time, adjustmentRuleForTime, daylightTime); baseUtcOffset += flag ? adjustmentRuleForTime.DaylightDelta : TimeSpan.Zero; } return baseUtcOffset; } private static TimeSpan GetUtcOffsetFromUtc(DateTime time, TimeZoneInfo zone) { bool flag; return GetUtcOffsetFromUtc(time, zone, out flag); } private static TimeSpan GetUtcOffsetFromUtc(DateTime time, TimeZoneInfo zone, out bool isDaylightSavings) { int year; AdjustmentRule adjustmentRuleForTime; isDaylightSavings = false; TimeSpan baseUtcOffset = zone.BaseUtcOffset; if (time > new DateTime(0x270f, 12, 0x1f)) { adjustmentRuleForTime = zone.GetAdjustmentRuleForTime(DateTime.MaxValue); year = 0x270f; } else if (time < new DateTime(1, 1, 2)) { adjustmentRuleForTime = zone.GetAdjustmentRuleForTime(DateTime.MinValue); year = 1; } else { DateTime dateTime = time + baseUtcOffset; year = time.Year; adjustmentRuleForTime = zone.GetAdjustmentRuleForTime(dateTime); } if (adjustmentRuleForTime != null) { isDaylightSavings = GetIsDaylightSavingsFromUtc(time, year, zone.m_baseUtcOffset, adjustmentRuleForTime); baseUtcOffset += isDaylightSavings ? adjustmentRuleForTime.DaylightDelta : TimeSpan.Zero; } return baseUtcOffset; } public bool HasSameRules(TimeZoneInfo other) { if (other == null) { throw new ArgumentNullException("other"); } if ((this.m_baseUtcOffset != other.m_baseUtcOffset) || (this.m_supportsDaylightSavingTime != other.m_supportsDaylightSavingTime)) { return false; } AdjustmentRule[] adjustmentRules = this.m_adjustmentRules; AdjustmentRule[] ruleArray2 = other.m_adjustmentRules; bool flag = ((adjustmentRules == null) && (ruleArray2 == null)) || ((adjustmentRules != null) && (ruleArray2 != null)); if (!flag) { return false; } if (adjustmentRules != null) { if (adjustmentRules.Length != ruleArray2.Length) { return false; } for (int i = 0; i < adjustmentRules.Length; i++) { if (!adjustmentRules[i].Equals(ruleArray2[i])) { return false; } } } return flag; } public bool IsAmbiguousTime(DateTime dateTime) { DateTime time; AdjustmentRule rule; if (!this.m_supportsDaylightSavingTime) { return false; } if (dateTime.Kind == DateTimeKind.Local) { lock (s_internalSyncObject) { time = ConvertTime(dateTime, Local, this, TimeZoneInfoOptions.NoThrowOnInvalidTime); goto Label_0068; } } if (dateTime.Kind == DateTimeKind.Utc) { lock (s_internalSyncObject) { time = ConvertTime(dateTime, Utc, this, TimeZoneInfoOptions.NoThrowOnInvalidTime); goto Label_0068; } } time = dateTime; Label_0068: rule = this.GetAdjustmentRuleForTime(time); if (rule != null) { DaylightTime daylightTime = GetDaylightTime(time.Year, rule); return GetIsAmbiguousTime(time, rule, daylightTime); } return false; } public bool IsAmbiguousTime(DateTimeOffset dateTimeOffset) { if (!this.m_supportsDaylightSavingTime) { return false; } DateTimeOffset offset = ConvertTime(dateTimeOffset, this); return this.IsAmbiguousTime(offset.DateTime); } public bool IsDaylightSavingTime(DateTime dateTime) { DateTime time; AdjustmentRule rule; if (!this.m_supportsDaylightSavingTime || (this.m_adjustmentRules == null)) { return false; } if (dateTime.Kind == DateTimeKind.Local) { lock (s_internalSyncObject) { time = ConvertTime(dateTime, Local, this, TimeZoneInfoOptions.NoThrowOnInvalidTime); goto Label_0064; } } if (dateTime.Kind == DateTimeKind.Utc) { bool flag; if (this.GetCorrespondingKind() == DateTimeKind.Utc) { return false; } GetUtcOffsetFromUtc(dateTime, this, out flag); return flag; } time = dateTime; Label_0064: rule = this.GetAdjustmentRuleForTime(time); if (rule != null) { DaylightTime daylightTime = GetDaylightTime(time.Year, rule); return GetIsDaylightSavings(time, rule, daylightTime); } return false; } public bool IsDaylightSavingTime(DateTimeOffset dateTimeOffset) { bool flag; GetUtcOffsetFromUtc(dateTimeOffset.UtcDateTime, this, out flag); return flag; } public bool IsInvalidTime(DateTime dateTime) { bool flag = false; if ((dateTime.Kind != DateTimeKind.Unspecified) && ((dateTime.Kind != DateTimeKind.Local) || (this.GetCorrespondingKind() != DateTimeKind.Local))) { return flag; } AdjustmentRule adjustmentRuleForTime = this.GetAdjustmentRuleForTime(dateTime); if (adjustmentRuleForTime != null) { DaylightTime daylightTime = GetDaylightTime(dateTime.Year, adjustmentRuleForTime); return GetIsInvalidTime(dateTime, adjustmentRuleForTime, daylightTime); } return false; } void IDeserializationCallback.OnDeserialization(object sender) { try { bool flag; ValidateTimeZoneInfo(this.m_id, this.m_baseUtcOffset, this.m_adjustmentRules, out flag); if (flag != this.m_supportsDaylightSavingTime) { throw new SerializationException("Serialization_CorruptField, SupportsDaylightSavingTime" ); } } catch (ArgumentException exception) { throw new SerializationException("Serialization_InvalidData", exception); } catch (InvalidTimeZoneException exception2) { throw new SerializationException("Serialization_InvalidData", exception2); } } [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) { throw new ArgumentNullException("info"); } info.AddValue("Id", this.m_id); info.AddValue("DisplayName", this.m_displayName); info.AddValue("StandardName", this.m_standardDisplayName); info.AddValue("DaylightName", this.m_daylightDisplayName); info.AddValue("BaseUtcOffset", this.m_baseUtcOffset); info.AddValue("AdjustmentRules", this.m_adjustmentRules); info.AddValue("SupportsDaylightSavingTime", this.m_supportsDaylightSavingTime); } public string ToSerializedString() { return StringSerializer.GetSerializedString(this); } public override string ToString() { return this.DisplayName; } private static TransitionTime? TransitionTimeFromTimeZoneInformation(NativeMethods.RegistryTimeZoneInformation timeZoneInformation, bool readStartDate) { TransitionTime time; if (timeZoneInformation.StandardDate.Month == 0) { return null; } if (readStartDate) { if (timeZoneInformation.DaylightDate.Year == 0) { time = TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, timeZoneInformation.DaylightDate.Hour, timeZoneInformation.DaylightDate.Minute, timeZoneInformation.DaylightDate.Second, timeZoneInformation.DaylightDate.Milliseconds), timeZoneInformation.DaylightDate.Month, timeZoneInformation.DaylightDate.Day, (DayOfWeek)timeZoneInformation.DaylightDate.DayOfWeek); } else { time = TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, timeZoneInformation.DaylightDate.Hour, timeZoneInformation.DaylightDate.Minute, timeZoneInformation.DaylightDate.Second, timeZoneInformation.DaylightDate.Milliseconds), timeZoneInformation.DaylightDate.Month, timeZoneInformation.DaylightDate.Day); } } else if (timeZoneInformation.StandardDate.Year == 0) { time = TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, timeZoneInformation.StandardDate.Hour, timeZoneInformation.StandardDate.Minute, timeZoneInformation.StandardDate.Second, timeZoneInformation.StandardDate.Milliseconds), timeZoneInformation.StandardDate.Month, timeZoneInformation.StandardDate.Day, (DayOfWeek)timeZoneInformation.StandardDate.DayOfWeek); } else { time = TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, timeZoneInformation.StandardDate.Hour, timeZoneInformation.StandardDate.Minute, timeZoneInformation.StandardDate.Second, timeZoneInformation.StandardDate.Milliseconds), timeZoneInformation.StandardDate.Month, timeZoneInformation.StandardDate.Day); } return new TransitionTime?(time); } private static DateTime TransitionTimeToDateTime(int year, TransitionTime transitionTime) { DateTime time; DateTime timeOfDay = transitionTime.TimeOfDay; if (transitionTime.IsFixedDateRule) { int num = DateTime.DaysInMonth(year, transitionTime.Month); return new DateTime(year, transitionTime.Month, (num < transitionTime.Day) ? num : transitionTime.Day, timeOfDay.Hour, timeOfDay.Minute, timeOfDay.Second, timeOfDay.Millisecond); } if (transitionTime.Week <= 4) { time = new DateTime(year, transitionTime.Month, 1, timeOfDay.Hour, timeOfDay.Minute, timeOfDay.Second, timeOfDay.Millisecond); int dayOfWeek = (int)time.DayOfWeek; int num3 = ((int)transitionTime.DayOfWeek) - dayOfWeek; if (num3 < 0) { num3 += 7; } num3 += 7 * (transitionTime.Week - 1); if (num3 > 0) { time = time.AddDays((double)num3); } return time; } int day = DateTime.DaysInMonth(year, transitionTime.Month); time = new DateTime(year, transitionTime.Month, day, timeOfDay.Hour, timeOfDay.Minute, timeOfDay.Second, timeOfDay.Millisecond); int num6 = (int)(time.DayOfWeek - transitionTime.DayOfWeek); if (num6 < 0) { num6 += 7; } if (num6 > 0) { time = time.AddDays((double)-num6); } return time; } private static bool TryCompareStandardDate(NativeMethods.TimeZoneInformation timeZone, NativeMethods.RegistryTimeZoneInformation registryTimeZoneInfo) { return ((((((timeZone.Bias == registryTimeZoneInfo.Bias) && (timeZone.StandardBias == registryTimeZoneInfo.StandardBias)) && ((timeZone.StandardDate.Year == registryTimeZoneInfo.StandardDate.Year) && (timeZone.StandardDate.Month == registryTimeZoneInfo.StandardDate.Month))) && (((timeZone.StandardDate.DayOfWeek == registryTimeZoneInfo.StandardDate.DayOfWeek) && (timeZone.StandardDate.Day == registryTimeZoneInfo.StandardDate.Day)) && ((timeZone.StandardDate.Hour == registryTimeZoneInfo.StandardDate.Hour) && (timeZone.StandardDate.Minute == registryTimeZoneInfo.StandardDate.Minute)))) && (timeZone.StandardDate.Second == registryTimeZoneInfo.StandardDate.Second)) && (timeZone.StandardDate.Milliseconds == registryTimeZoneInfo.StandardDate.Milliseconds)); } [SecurityTreatAsSafe, SecurityCritical] private static bool TryCompareTimeZoneInformationToRegistry(NativeMethods.TimeZoneInformation timeZone, string id, out bool dstDisabled) { bool flag2; dstDisabled = false; try { PermissionSet set = new PermissionSet(PermissionState.None); set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones")); set.Assert(); using (RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", new object[] { @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", id }), RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey)) { NativeMethods.RegistryTimeZoneInformation information; if (key == null) { return false; } try { information = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue("TZI", null, RegistryValueOptions.None)); } catch (InvalidCastException) { return false; } catch (ArgumentException) { return false; } if (!TryCompareStandardDate(timeZone, information)) { return false; } dstDisabled = CheckDaylightSavingTimeDisabled(); bool flag = (dstDisabled || CheckDaylightSavingTimeNotSupported(timeZone)) || (((((timeZone.DaylightBias == information.DaylightBias) && (timeZone.DaylightDate.Year == information.DaylightDate.Year)) && ((timeZone.DaylightDate.Month == information.DaylightDate.Month) && (timeZone.DaylightDate.DayOfWeek == information.DaylightDate.DayOfWeek))) && (((timeZone.DaylightDate.Day == information.DaylightDate.Day) && (timeZone.DaylightDate.Hour == information.DaylightDate.Hour)) && ((timeZone.DaylightDate.Minute == information.DaylightDate.Minute) && (timeZone.DaylightDate.Second == information.DaylightDate.Second)))) && (timeZone.DaylightDate.Milliseconds == information.DaylightDate.Milliseconds)); if (flag) { string strA = key.GetValue("Std", string.Empty, RegistryValueOptions.None) as string; flag = string.Compare(strA, timeZone.StandardName, StringComparison.Ordinal) == 0; } flag2 = flag; } } finally { PermissionSet.RevertAssert(); } return flag2; } private static bool TryCreateAdjustmentRules(string id, NativeMethods.RegistryTimeZoneInformation defaultTimeZoneInformation, out AdjustmentRule[] rules, out Exception e) { e = null; try { using (RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format(CultureInfo.InvariantCulture, @"{0}\{1}\Dynamic DST", new object[] { @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", id }), RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey)) { if (key == null) { AdjustmentRule rule = CreateAdjustmentRuleFromTimeZoneInformation(defaultTimeZoneInformation, DateTime.MinValue.Date, DateTime.MaxValue.Date); if (rule == null) { rules = null; } else { rules = new AdjustmentRule[] { rule }; } return true; } int year = (int)key.GetValue("FirstEntry", -1, RegistryValueOptions.None); int num2 = (int)key.GetValue("LastEntry", -1, RegistryValueOptions.None); if (((year == -1) || (num2 == -1)) || (year > num2)) { rules = null; return false; } NativeMethods.RegistryTimeZoneInformation timeZoneInformation = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue(year.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None)); if (year == num2) { AdjustmentRule rule2 = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, DateTime.MinValue.Date, DateTime.MaxValue.Date); if (rule2 == null) { rules = null; } else { rules = new AdjustmentRule[] { rule2 }; } return true; } List list = new List(1); AdjustmentRule item = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, DateTime.MinValue.Date, new DateTime(year, 12, 0x1f)); if (item != null) { list.Add(item); } for (int i = year + 1; i < num2; i++) { timeZoneInformation = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue(i.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None)); AdjustmentRule rule4 = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, new DateTime(i, 1, 1), new DateTime(i, 12, 0x1f)); if (rule4 != null) { list.Add(rule4); } } timeZoneInformation = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue(num2.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None)); AdjustmentRule rule5 = CreateAdjustmentRuleFromTimeZoneInformation(timeZoneInformation, new DateTime(num2, 1, 1), DateTime.MaxValue.Date); if (rule5 != null) { list.Add(rule5); } rules = list.ToArray(); if ((rules != null) && (rules.Length == 0)) { rules = null; } } } catch (InvalidCastException exception) { rules = null; e = exception; return false; } catch (ArgumentOutOfRangeException exception2) { rules = null; e = exception2; return false; } catch (ArgumentException exception3) { rules = null; e = exception3; return false; } return true; } [SecurityTreatAsSafe, SecurityCritical, FileIOPermission(SecurityAction.Assert, AllLocalFiles = FileIOPermissionAccess.PathDiscovery)] private static string TryGetLocalizedNameByMuiNativeResource(string resource) { string str; int num; if (string.IsNullOrEmpty(resource)) { return string.Empty; } string[] strArray = resource.Split(new char[] { ',' }, StringSplitOptions.None); if (strArray.Length != 2) { return string.Empty; } string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.System); string str3 = strArray[0].TrimStart(new char[] { '@' }); try { str = Path.Combine(folderPath, str3); } catch (ArgumentException) { return string.Empty; } if (!int.TryParse(strArray[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out num)) { return string.Empty; } num = -num; try { StringBuilder fileMuiPath = new StringBuilder(260); fileMuiPath.Length = 260; int fileMuiPathLength = 260; int languageLength = 0; long enumerator = 0L; if (!UnsafeNativeMethods.GetFileMUIPath(0x10, str, null, ref languageLength, fileMuiPath, ref fileMuiPathLength, ref enumerator)) { return string.Empty; } return TryGetLocalizedNameByNativeResource(fileMuiPath.ToString(), num); } catch (EntryPointNotFoundException) { return string.Empty; } } [SecurityCritical] private static string TryGetLocalizedNameByNativeResource(string filePath, int resource) { if (File.Exists(filePath)) { using (SafeLibraryHandle handle = UnsafeNativeMethods.LoadLibraryEx(filePath, IntPtr.Zero, 2)) { if (!handle.IsInvalid) { StringBuilder buffer = new StringBuilder(500); buffer.Length = 500; if (UnsafeNativeMethods.LoadString(handle, resource, buffer, buffer.Length) != 0) { return buffer.ToString(); } } } } return string.Empty; } private static bool TryGetLocalizedNamesByRegistryKey(RegistryKey key, out string displayName, out string standardName, out string daylightName) { displayName = string.Empty; standardName = string.Empty; daylightName = string.Empty; string str = key.GetValue("MUI_Display", string.Empty, RegistryValueOptions.None) as string; string str2 = key.GetValue("MUI_Std", string.Empty, RegistryValueOptions.None) as string; string str3 = key.GetValue("MUI_Dlt", string.Empty, RegistryValueOptions.None) as string; if (!string.IsNullOrEmpty(str)) { displayName = TryGetLocalizedNameByMuiNativeResource(str); } if (!string.IsNullOrEmpty(str2)) { standardName = TryGetLocalizedNameByMuiNativeResource(str2); } if (!string.IsNullOrEmpty(str3)) { daylightName = TryGetLocalizedNameByMuiNativeResource(str3); } if (string.IsNullOrEmpty(displayName)) { displayName = key.GetValue("Display", string.Empty, RegistryValueOptions.None) as string; } if (string.IsNullOrEmpty(standardName)) { standardName = key.GetValue("Std", string.Empty, RegistryValueOptions.None) as string; } if (string.IsNullOrEmpty(daylightName)) { daylightName = key.GetValue("Dlt", string.Empty, RegistryValueOptions.None) as string; } return true; } private static TimeZoneInfoResult TryGetTimeZone(string id, bool dstDisabled, out TimeZoneInfo value, out Exception e) { TimeZoneInfoResult success = TimeZoneInfoResult.Success; e = null; TimeZoneInfo info = null; if (s_systemTimeZones.TryGetValue(id, out info)) { if (dstDisabled && info.m_supportsDaylightSavingTime) { value = CreateCustomTimeZone(info.m_id, info.m_baseUtcOffset, info.m_displayName, info.m_standardDisplayName); return success; } value = new TimeZoneInfo(info.m_id, info.m_baseUtcOffset, info.m_displayName, info.m_standardDisplayName, info.m_daylightDisplayName, info.m_adjustmentRules, false); return success; } if (!s_allSystemTimeZonesRead) { success = TryGetTimeZoneByRegistryKey(id, out info, out e); if (success == TimeZoneInfoResult.Success) { s_systemTimeZones.Add(id, info); if (dstDisabled && info.m_supportsDaylightSavingTime) { value = CreateCustomTimeZone(info.m_id, info.m_baseUtcOffset, info.m_displayName, info.m_standardDisplayName); return success; } value = new TimeZoneInfo(info.m_id, info.m_baseUtcOffset, info.m_displayName, info.m_standardDisplayName, info.m_daylightDisplayName, info.m_adjustmentRules, false); return success; } value = null; return success; } success = TimeZoneInfoResult.TimeZoneNotFoundException; value = null; return success; } [SecurityCritical, SecurityTreatAsSafe] private static TimeZoneInfoResult TryGetTimeZoneByRegistryKey(string id, out TimeZoneInfo value, out Exception e) { TimeZoneInfoResult invalidTimeZoneException; e = null; try { PermissionSet set = new PermissionSet(PermissionState.None); set.AddPermission(new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones")); set.Assert(); using (RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format(CultureInfo.InvariantCulture, @"{0}\{1}", new object[] { @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones", id }), RegistryKeyPermissionCheck.Default, RegistryRights.ExecuteKey)) { NativeMethods.RegistryTimeZoneInformation information; AdjustmentRule[] ruleArray; string str; string str2; string str3; if (key == null) { value = null; return TimeZoneInfoResult.TimeZoneNotFoundException; } try { information = new NativeMethods.RegistryTimeZoneInformation((byte[])key.GetValue("TZI", null, RegistryValueOptions.None)); } catch (InvalidCastException exception) { value = null; e = exception; return TimeZoneInfoResult.InvalidTimeZoneException; } catch (ArgumentException exception2) { value = null; e = exception2; return TimeZoneInfoResult.InvalidTimeZoneException; } if (!TryCreateAdjustmentRules(id, information, out ruleArray, out e)) { value = null; return TimeZoneInfoResult.InvalidTimeZoneException; } if (!TryGetLocalizedNamesByRegistryKey(key, out str, out str2, out str3)) { value = null; invalidTimeZoneException = TimeZoneInfoResult.InvalidTimeZoneException; } else { try { value = new TimeZoneInfo(id, new TimeSpan(0, -information.Bias, 0), str, str2, str3, ruleArray, false); invalidTimeZoneException = TimeZoneInfoResult.Success; } catch (ArgumentException exception3) { value = null; e = exception3; invalidTimeZoneException = TimeZoneInfoResult.InvalidTimeZoneException; } catch (InvalidTimeZoneException exception4) { value = null; e = exception4; invalidTimeZoneException = TimeZoneInfoResult.InvalidTimeZoneException; } } } } finally { PermissionSet.RevertAssert(); } return invalidTimeZoneException; } internal static bool UtcOffsetOutOfRange(TimeSpan offset) { if (offset.TotalHours >= -14.0) { return (offset.TotalHours > 14.0); } return true; } private static void ValidateTimeZoneInfo(string id, TimeSpan baseUtcOffset, AdjustmentRule[] adjustmentRules, out bool adjustmentRulesSupportDst) { adjustmentRulesSupportDst = false; if (id == null) { throw new ArgumentNullException("id"); } if (id.Length == 0) { throw new ArgumentException("Argument_InvalidId , id"); } if (UtcOffsetOutOfRange(baseUtcOffset)) { throw new ArgumentOutOfRangeException("baseUtcOffset", "ArgumentOutOfRange_UtcOffset"); } if ((baseUtcOffset.Ticks % 0x23c34600L) != 0L) { throw new ArgumentException("Argument_TimeSpanHasSeconds", "baseUtcOffset"); } if ((adjustmentRules != null) && (adjustmentRules.Length != 0)) { adjustmentRulesSupportDst = true; AdjustmentRule rule = null; AdjustmentRule rule2 = null; for (int i = 0; i < adjustmentRules.Length; i++) { rule = rule2; rule2 = adjustmentRules[i]; if (rule2 == null) { throw new InvalidTimeZoneException("Argument_AdjustmentRulesNoNulls"); } if (UtcOffsetOutOfRange(baseUtcOffset + rule2.DaylightDelta)) { throw new InvalidTimeZoneException("ArgumentOutOfRange_UtcOffsetAndDaylightDelta"); } if ((rule != null) && (rule2.DateStart <= rule.DateEnd)) { throw new InvalidTimeZoneException("Argument_AdjustmentRulesOutOfOrder"); } } } } // Properties public TimeSpan BaseUtcOffset { get { return this.m_baseUtcOffset; } } public string DaylightName { get { if (this.m_daylightDisplayName != null) { return this.m_daylightDisplayName; } return string.Empty; } } public string DisplayName { get { if (this.m_displayName != null) { return this.m_displayName; } return string.Empty; } } public string Id { get { return this.m_id; } } public static TimeZoneInfo Local { [SecurityCritical] get { TimeZoneInfo info = s_localTimeZone; if (info != null) { return info; } lock (s_internalSyncObject) { if (s_localTimeZone == null) { TimeZoneInfo localTimeZone = GetLocalTimeZone(); s_localTimeZone = new TimeZoneInfo(localTimeZone.m_id, localTimeZone.m_baseUtcOffset, localTimeZone.m_displayName, localTimeZone.m_standardDisplayName, localTimeZone.m_daylightDisplayName, localTimeZone.m_adjustmentRules, false); } return s_localTimeZone; } } } private static object s_internalSyncObject { get { if (s_hiddenInternalSyncObject == null) { object obj2 = new object(); System.Threading.Interlocked.CompareExchange(ref s_hiddenInternalSyncObject, obj2, null); } return s_hiddenInternalSyncObject; } } private static Dictionary s_systemTimeZones { get { if (s_hiddenSystemTimeZones == null) { s_hiddenSystemTimeZones = new Dictionary(); } return s_hiddenSystemTimeZones; } set { s_hiddenSystemTimeZones = value; } } public string StandardName { get { if (this.m_standardDisplayName != null) { return this.m_standardDisplayName; } return string.Empty; } } public bool SupportsDaylightSavingTime { get { return this.m_supportsDaylightSavingTime; } } public static TimeZoneInfo Utc { get { TimeZoneInfo info = s_utcTimeZone; if (info != null) { return info; } lock (s_internalSyncObject) { if (s_utcTimeZone == null) { s_utcTimeZone = CreateCustomTimeZone("UTC", TimeSpan.Zero, "UTC", "UTC"); } return s_utcTimeZone; } } } // Nested Types [Serializable, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true), HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] public sealed class AdjustmentRule : IEquatable, ISerializable, IDeserializationCallback { // Fields private DateTime m_dateEnd; private DateTime m_dateStart; private TimeSpan m_daylightDelta; private TimeZoneInfo.TransitionTime m_daylightTransitionEnd; private TimeZoneInfo.TransitionTime m_daylightTransitionStart; // Methods private AdjustmentRule() { } private AdjustmentRule(SerializationInfo info, StreamingContext context) { if (info == null) { throw new ArgumentNullException("info"); } this.m_dateStart = (DateTime)info.GetValue("DateStart", typeof(DateTime)); this.m_dateEnd = (DateTime)info.GetValue("DateEnd", typeof(DateTime)); this.m_daylightDelta = (TimeSpan)info.GetValue("DaylightDelta", typeof(TimeSpan)); this.m_daylightTransitionStart = (TimeZoneInfo.TransitionTime)info.GetValue("DaylightTransitionStart", typeof(TimeZoneInfo.TransitionTime)); this.m_daylightTransitionEnd = (TimeZoneInfo.TransitionTime)info.GetValue("DaylightTransitionEnd", typeof(TimeZoneInfo.TransitionTime)); } public static TimeZoneInfo.AdjustmentRule CreateAdjustmentRule(DateTime dateStart, DateTime dateEnd, TimeSpan daylightDelta, TimeZoneInfo.TransitionTime daylightTransitionStart, TimeZoneInfo.TransitionTime daylightTransitionEnd) { ValidateAdjustmentRule(dateStart, dateEnd, daylightDelta, daylightTransitionStart, daylightTransitionEnd); TimeZoneInfo.AdjustmentRule rule = new TimeZoneInfo.AdjustmentRule(); rule.m_dateStart = dateStart; rule.m_dateEnd = dateEnd; rule.m_daylightDelta = daylightDelta; rule.m_daylightTransitionStart = daylightTransitionStart; rule.m_daylightTransitionEnd = daylightTransitionEnd; return rule; } public bool Equals(TimeZoneInfo.AdjustmentRule other) { return ((((((other != null) && (this.m_dateStart == other.m_dateStart)) && (this.m_dateEnd == other.m_dateEnd)) && (this.m_daylightDelta == other.m_daylightDelta)) && this.m_daylightTransitionEnd.Equals(other.m_daylightTransitionEnd)) && this.m_daylightTransitionStart.Equals(other.m_daylightTransitionStart)); } public override int GetHashCode() { return this.m_dateStart.GetHashCode(); } void IDeserializationCallback.OnDeserialization(object sender) { try { ValidateAdjustmentRule(this.m_dateStart, this.m_dateEnd, this.m_daylightDelta, this.m_daylightTransitionStart, this.m_daylightTransitionEnd); } catch (ArgumentException exception) { throw new SerializationException("Serialization_InvalidData", exception); } } [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) { throw new ArgumentNullException("info"); } info.AddValue("DateStart", this.m_dateStart); info.AddValue("DateEnd", this.m_dateEnd); info.AddValue("DaylightDelta", this.m_daylightDelta); info.AddValue("DaylightTransitionStart", this.m_daylightTransitionStart); info.AddValue("DaylightTransitionEnd", this.m_daylightTransitionEnd); } private static void ValidateAdjustmentRule(DateTime dateStart, DateTime dateEnd, TimeSpan daylightDelta, TimeZoneInfo.TransitionTime daylightTransitionStart, TimeZoneInfo.TransitionTime daylightTransitionEnd) { if (dateStart.Kind != DateTimeKind.Unspecified) { throw new ArgumentException("Argument_DateTimeKindMustBeUnspecified", "dateStart"); } if (dateEnd.Kind != DateTimeKind.Unspecified) { throw new ArgumentException("Argument_DateTimeKindMustBeUnspecified", "dateEnd"); } if (daylightTransitionStart.Equals(daylightTransitionEnd)) { throw new ArgumentException("Argument_TransitionTimesAreIdentical", "daylightTransitionEnd"); } if (dateStart > dateEnd) { throw new ArgumentException("Argument_OutOfOrderDateTimes", "dateStart"); } if (TimeZoneInfo.UtcOffsetOutOfRange(daylightDelta)) { throw new ArgumentOutOfRangeException("daylightDelta", daylightDelta, "ArgumentOutOfRange_UtcOffset"); } if ((daylightDelta.Ticks % 0x23c34600L) != 0L) { throw new ArgumentException("Argument_TimeSpanHasSeconds", "daylightDelta"); } if (dateStart.TimeOfDay != TimeSpan.Zero) { throw new ArgumentException("Argument_DateTimeHasTimeOfDay", "dateStart"); } if (dateEnd.TimeOfDay != TimeSpan.Zero) { throw new ArgumentException("Argument_DateTimeHasTimeOfDay", "dateEnd"); } } // Properties public DateTime DateEnd { get { return this.m_dateEnd; } } public DateTime DateStart { get { return this.m_dateStart; } } public TimeSpan DaylightDelta { get { return this.m_daylightDelta; } } public TimeZoneInfo.TransitionTime DaylightTransitionEnd { get { return this.m_daylightTransitionEnd; } } public TimeZoneInfo.TransitionTime DaylightTransitionStart { get { return this.m_daylightTransitionStart; } } } private sealed class StringSerializer { // Fields private const string dateTimeFormat = "MM:dd:yyyy"; private const char esc = '\\'; private const string escapedEsc = @"\\"; private const string escapedLhs = @"\["; private const string escapedRhs = @"\]"; private const string escapedSep = @"\;"; private const string escString = @"\"; private const int initialCapacityForString = 0x40; private const char lhs = '['; private const string lhsString = "["; private int m_currentTokenStartIndex; private string m_serializedText; private State m_state; private const char rhs = ']'; private const string rhsString = "]"; private const char sep = ';'; private const string sepString = ";"; private const string timeOfDayFormat = "HH:mm:ss.FFF"; // Methods private StringSerializer(string str) { this.m_serializedText = str; this.m_state = State.StartOfToken; } public static TimeZoneInfo GetDeserializedTimeZoneInfo(string source) { TimeZoneInfo info; TimeZoneInfo.StringSerializer serializer = new TimeZoneInfo.StringSerializer(source); string nextStringValue = serializer.GetNextStringValue(false); TimeSpan nextTimeSpanValue = serializer.GetNextTimeSpanValue(false); string displayName = serializer.GetNextStringValue(false); string standardDisplayName = serializer.GetNextStringValue(false); string daylightDisplayName = serializer.GetNextStringValue(false); TimeZoneInfo.AdjustmentRule[] nextAdjustmentRuleArrayValue = serializer.GetNextAdjustmentRuleArrayValue(false); try { info = TimeZoneInfo.CreateCustomTimeZone(nextStringValue, nextTimeSpanValue, displayName, standardDisplayName, daylightDisplayName, nextAdjustmentRuleArrayValue); } catch (ArgumentException exception) { throw new SerializationException("Serialization_InvalidData", exception); } catch (InvalidTimeZoneException exception2) { throw new SerializationException("Serialization_InvalidData", exception2); } return info; } private TimeZoneInfo.AdjustmentRule[] GetNextAdjustmentRuleArrayValue(bool canEndWithoutSeparator) { List list = new List(1); int num = 0; for (TimeZoneInfo.AdjustmentRule rule = this.GetNextAdjustmentRuleValue(true); rule != null; rule = this.GetNextAdjustmentRuleValue(true)) { list.Add(rule); num++; } if (!canEndWithoutSeparator) { if (this.m_state == State.EndOfLine) { throw new SerializationException("Serialization_InvalidData"); } if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) { throw new SerializationException("Serialization_InvalidData"); } } if (num == 0) { return null; } return list.ToArray(); } private TimeZoneInfo.AdjustmentRule GetNextAdjustmentRuleValue(bool canEndWithoutSeparator) { TimeZoneInfo.AdjustmentRule rule; if (this.m_state == State.EndOfLine) { if (!canEndWithoutSeparator) { throw new SerializationException("Serialization_InvalidData"); } return null; } if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) { throw new SerializationException("Serialization_InvalidData"); } if (this.m_serializedText[this.m_currentTokenStartIndex] == ';') { return null; } if (this.m_serializedText[this.m_currentTokenStartIndex] != '[') { throw new SerializationException("Serialization_InvalidData"); } this.m_currentTokenStartIndex++; DateTime nextDateTimeValue = this.GetNextDateTimeValue(false, "MM:dd:yyyy"); DateTime dateEnd = this.GetNextDateTimeValue(false, "MM:dd:yyyy"); TimeSpan nextTimeSpanValue = this.GetNextTimeSpanValue(false); TimeZoneInfo.TransitionTime nextTransitionTimeValue = this.GetNextTransitionTimeValue(false); TimeZoneInfo.TransitionTime daylightTransitionEnd = this.GetNextTransitionTimeValue(false); if ((this.m_state == State.EndOfLine) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) { throw new SerializationException("Serialization_InvalidData"); } if (this.m_serializedText[this.m_currentTokenStartIndex] != ']') { this.SkipVersionNextDataFields(1); } else { this.m_currentTokenStartIndex++; } try { rule = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(nextDateTimeValue, dateEnd, nextTimeSpanValue, nextTransitionTimeValue, daylightTransitionEnd); } catch (ArgumentException exception) { throw new SerializationException("Serialization_InvalidData", exception); } if (this.m_currentTokenStartIndex >= this.m_serializedText.Length) { this.m_state = State.EndOfLine; return rule; } this.m_state = State.StartOfToken; return rule; } private DateTime GetNextDateTimeValue(bool canEndWithoutSeparator, string format) { DateTime time; if (!DateTime.TryParseExact(this.GetNextStringValue(canEndWithoutSeparator), format, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out time)) { throw new SerializationException("Serialization_InvalidData"); } return time; } private int GetNextInt32Value(bool canEndWithoutSeparator) { int num; if (!int.TryParse(this.GetNextStringValue(canEndWithoutSeparator), NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out num)) { throw new SerializationException("Serialization_InvalidData"); } return num; } private string GetNextStringValue(bool canEndWithoutSeparator) { if (this.m_state == State.EndOfLine) { if (!canEndWithoutSeparator) { throw new SerializationException("Serialization_InvalidData"); } return null; } if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) { throw new SerializationException("Serialization_InvalidData"); } State notEscaped = State.NotEscaped; StringBuilder builder = new StringBuilder(0x40); for (int i = this.m_currentTokenStartIndex; i < this.m_serializedText.Length; i++) { if (notEscaped == State.Escaped) { VerifyIsEscapableCharacter(this.m_serializedText[i]); builder.Append(this.m_serializedText[i]); notEscaped = State.NotEscaped; } else if (notEscaped == State.NotEscaped) { switch (this.m_serializedText[i]) { case '[': throw new SerializationException("Serialization_InvalidData"); case '\\': notEscaped = State.Escaped; break; case ']': if (!canEndWithoutSeparator) { throw new SerializationException("Serialization_InvalidData"); } this.m_currentTokenStartIndex = i; this.m_state = State.StartOfToken; return builder.ToString(); case ';': this.m_currentTokenStartIndex = i + 1; if (this.m_currentTokenStartIndex >= this.m_serializedText.Length) { this.m_state = State.EndOfLine; } else { this.m_state = State.StartOfToken; } return builder.ToString(); case '\0': throw new SerializationException("Serialization_InvalidData"); default: builder.Append(this.m_serializedText[i]); break; } } } if (notEscaped == State.Escaped) { throw new SerializationException("Serialization_InvalidEscapeSequence"); } if (!canEndWithoutSeparator) { throw new SerializationException("Serialization_InvalidData"); } this.m_currentTokenStartIndex = this.m_serializedText.Length; this.m_state = State.EndOfLine; return builder.ToString(); } private TimeSpan GetNextTimeSpanValue(bool canEndWithoutSeparator) { TimeSpan span; int minutes = this.GetNextInt32Value(canEndWithoutSeparator); try { span = new TimeSpan(0, minutes, 0); } catch (ArgumentOutOfRangeException exception) { throw new SerializationException("Serialization_InvalidData", exception); } return span; } private TimeZoneInfo.TransitionTime GetNextTransitionTimeValue(bool canEndWithoutSeparator) { TimeZoneInfo.TransitionTime time; if ((this.m_state == State.EndOfLine) || ((this.m_currentTokenStartIndex < this.m_serializedText.Length) && (this.m_serializedText[this.m_currentTokenStartIndex] == ']'))) { throw new SerializationException("Serialization_InvalidData"); } if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) { throw new SerializationException("Serialization_InvalidData"); } if (this.m_serializedText[this.m_currentTokenStartIndex] != '[') { throw new SerializationException("Serialization_InvalidData"); } this.m_currentTokenStartIndex++; int num = this.GetNextInt32Value(false); if ((num != 0) && (num != 1)) { throw new SerializationException("Serialization_InvalidData"); } DateTime nextDateTimeValue = this.GetNextDateTimeValue(false, "HH:mm:ss.FFF"); nextDateTimeValue = new DateTime(1, 1, 1, nextDateTimeValue.Hour, nextDateTimeValue.Minute, nextDateTimeValue.Second, nextDateTimeValue.Millisecond); int month = this.GetNextInt32Value(false); if (num == 1) { int day = this.GetNextInt32Value(false); try { time = TimeZoneInfo.TransitionTime.CreateFixedDateRule(nextDateTimeValue, month, day); goto Label_015B; } catch (ArgumentException exception) { throw new SerializationException("Serialization_InvalidData", exception); } } int week = this.GetNextInt32Value(false); int num5 = this.GetNextInt32Value(false); try { time = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(nextDateTimeValue, month, week, (DayOfWeek)num5); } catch (ArgumentException exception2) { throw new SerializationException("Serialization_InvalidData", exception2); } Label_015B: if ((this.m_state == State.EndOfLine) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) { throw new SerializationException("Serialization_InvalidData"); } if (this.m_serializedText[this.m_currentTokenStartIndex] != ']') { this.SkipVersionNextDataFields(1); } else { this.m_currentTokenStartIndex++; } bool flag = false; if ((this.m_currentTokenStartIndex < this.m_serializedText.Length) && (this.m_serializedText[this.m_currentTokenStartIndex] == ';')) { this.m_currentTokenStartIndex++; flag = true; } if (!flag && !canEndWithoutSeparator) { throw new SerializationException("Serialization_InvalidData"); } if (this.m_currentTokenStartIndex >= this.m_serializedText.Length) { this.m_state = State.EndOfLine; return time; } this.m_state = State.StartOfToken; return time; } public static string GetSerializedString(TimeZoneInfo zone) { StringBuilder serializedText = new StringBuilder(); serializedText.Append(SerializeSubstitute(zone.Id)); serializedText.Append(';'); serializedText.Append(SerializeSubstitute(zone.BaseUtcOffset.TotalMinutes.ToString(CultureInfo.InvariantCulture))); serializedText.Append(';'); serializedText.Append(SerializeSubstitute(zone.DisplayName)); serializedText.Append(';'); serializedText.Append(SerializeSubstitute(zone.StandardName)); serializedText.Append(';'); serializedText.Append(SerializeSubstitute(zone.DaylightName)); serializedText.Append(';'); TimeZoneInfo.AdjustmentRule[] adjustmentRules = zone.GetAdjustmentRules(); if ((adjustmentRules != null) && (adjustmentRules.Length > 0)) { for (int i = 0; i < adjustmentRules.Length; i++) { TimeZoneInfo.AdjustmentRule rule = adjustmentRules[i]; serializedText.Append('['); serializedText.Append(SerializeSubstitute(rule.DateStart.ToString("MM:dd:yyyy", DateTimeFormatInfo.InvariantInfo))); serializedText.Append(';'); serializedText.Append(SerializeSubstitute(rule.DateEnd.ToString("MM:dd:yyyy", DateTimeFormatInfo.InvariantInfo))); serializedText.Append(';'); serializedText.Append(SerializeSubstitute(rule.DaylightDelta.TotalMinutes.ToString(CultureInfo.InvariantCulture))); serializedText.Append(';'); SerializeTransitionTime(rule.DaylightTransitionStart, serializedText); serializedText.Append(';'); SerializeTransitionTime(rule.DaylightTransitionEnd, serializedText); serializedText.Append(';'); serializedText.Append(']'); } } serializedText.Append(';'); return serializedText.ToString(); } private static string SerializeSubstitute(string text) { text = text.Replace(@"\", @"\\"); text = text.Replace("[", @"\["); text = text.Replace("]", @"\]"); return text.Replace(";", @"\;"); } private static void SerializeTransitionTime(TimeZoneInfo.TransitionTime time, StringBuilder serializedText) { serializedText.Append('['); serializedText.Append((time.IsFixedDateRule ? 1 : 0).ToString(CultureInfo.InvariantCulture)); serializedText.Append(';'); if (time.IsFixedDateRule) { serializedText.Append(SerializeSubstitute(time.TimeOfDay.ToString("HH:mm:ss.FFF", DateTimeFormatInfo.InvariantInfo))); serializedText.Append(';'); serializedText.Append(SerializeSubstitute(time.Month.ToString(CultureInfo.InvariantCulture))); serializedText.Append(';'); serializedText.Append(SerializeSubstitute(time.Day.ToString(CultureInfo.InvariantCulture))); serializedText.Append(';'); } else { serializedText.Append(SerializeSubstitute(time.TimeOfDay.ToString("HH:mm:ss.FFF", DateTimeFormatInfo.InvariantInfo))); serializedText.Append(';'); serializedText.Append(SerializeSubstitute(time.Month.ToString(CultureInfo.InvariantCulture))); serializedText.Append(';'); serializedText.Append(SerializeSubstitute(time.Week.ToString(CultureInfo.InvariantCulture))); serializedText.Append(';'); serializedText.Append(SerializeSubstitute(((int)time.DayOfWeek).ToString(CultureInfo.InvariantCulture))); serializedText.Append(';'); } serializedText.Append(']'); } private void SkipVersionNextDataFields(int depth) { if ((this.m_currentTokenStartIndex < 0) || (this.m_currentTokenStartIndex >= this.m_serializedText.Length)) { throw new SerializationException("Serialization_InvalidData"); } State notEscaped = State.NotEscaped; for (int i = this.m_currentTokenStartIndex; i < this.m_serializedText.Length; i++) { switch (notEscaped) { case State.Escaped: { VerifyIsEscapableCharacter(this.m_serializedText[i]); notEscaped = State.NotEscaped; continue; } case State.NotEscaped: switch (this.m_serializedText[i]) { case '[': { depth++; continue; } case '\\': { notEscaped = State.Escaped; continue; } case ']': depth--; if (depth != 0) { continue; } this.m_currentTokenStartIndex = i + 1; if (this.m_currentTokenStartIndex < this.m_serializedText.Length) { goto Label_00B5; } this.m_state = State.EndOfLine; return; case '\0': throw new SerializationException("Serialization_InvalidData"); } break; } continue; Label_00B5: this.m_state = State.StartOfToken; return; } throw new SerializationException("Serialization_InvalidData"); } private static void VerifyIsEscapableCharacter(char c) { if (((c != '\\') && (c != ';')) && ((c != '[') && (c != ']'))) { throw new SerializationException("Serialization_InvalidEscapeSequence " + c.ToString()); } } // Nested Types private enum State { Escaped, NotEscaped, StartOfToken, EndOfLine } } private class TimeZoneInfoComparer : IComparer { // Methods int IComparer.Compare(TimeZoneInfo x, TimeZoneInfo y) { return DevComponents.AdvTree.Utilities.CompareAlphaNumeric(x.Id, y.Id); } } private enum TimeZoneInfoResult { Success, TimeZoneNotFoundException, InvalidTimeZoneException, SecurityException } [Serializable, StructLayout(LayoutKind.Sequential), HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true), HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] public struct TransitionTime : IEquatable, ISerializable, IDeserializationCallback { private DateTime m_timeOfDay; private byte m_month; private byte m_week; private byte m_day; private DayOfWeek m_dayOfWeek; private bool m_isFixedDateRule; public DateTime TimeOfDay { get { return this.m_timeOfDay; } } public int Month { get { return this.m_month; } } public int Week { get { return this.m_week; } } public int Day { get { return this.m_day; } } public DayOfWeek DayOfWeek { get { return this.m_dayOfWeek; } } public bool IsFixedDateRule { get { return this.m_isFixedDateRule; } } public override bool Equals(object obj) { return ((obj is TimeZoneInfo.TransitionTime) && this.Equals((TimeZoneInfo.TransitionTime)obj)); } public static bool operator ==(TimeZoneInfo.TransitionTime left, TimeZoneInfo.TransitionTime right) { return left.Equals(right); } public static bool operator !=(TimeZoneInfo.TransitionTime left, TimeZoneInfo.TransitionTime right) { return !left.Equals(right); } public bool Equals(TimeZoneInfo.TransitionTime other) { bool flag = ((this.m_isFixedDateRule == other.m_isFixedDateRule) && (this.m_timeOfDay == other.m_timeOfDay)) && (this.m_month == other.m_month); if (!flag) { return flag; } if (other.m_isFixedDateRule) { return (this.m_day == other.m_day); } return ((this.m_week == other.m_week) && (this.m_dayOfWeek == other.m_dayOfWeek)); } public override int GetHashCode() { return (this.m_month ^ (this.m_week << 8)); } public static TimeZoneInfo.TransitionTime CreateFixedDateRule(DateTime timeOfDay, int month, int day) { return CreateTransitionTime(timeOfDay, month, 1, day, DayOfWeek.Sunday, true); } public static TimeZoneInfo.TransitionTime CreateFloatingDateRule(DateTime timeOfDay, int month, int week, DayOfWeek dayOfWeek) { return CreateTransitionTime(timeOfDay, month, week, 1, dayOfWeek, false); } private static TimeZoneInfo.TransitionTime CreateTransitionTime(DateTime timeOfDay, int month, int week, int day, DayOfWeek dayOfWeek, bool isFixedDateRule) { ValidateTransitionTime(timeOfDay, month, week, day, dayOfWeek); TimeZoneInfo.TransitionTime time = new TimeZoneInfo.TransitionTime(); time.m_isFixedDateRule = isFixedDateRule; time.m_timeOfDay = timeOfDay; time.m_dayOfWeek = dayOfWeek; time.m_day = (byte)day; time.m_week = (byte)week; time.m_month = (byte)month; return time; } private static void ValidateTransitionTime(DateTime timeOfDay, int month, int week, int day, DayOfWeek dayOfWeek) { if (timeOfDay.Kind != DateTimeKind.Unspecified) { throw new ArgumentException("Argument_DateTimeKindMustBeUnspecified", "timeOfDay"); } if ((month < 1) || (month > 12)) { throw new ArgumentOutOfRangeException("month", "ArgumentOutOfRange_Month"); } if ((day < 1) || (day > 0x1f)) { throw new ArgumentOutOfRangeException("day", "ArgumentOutOfRange_Day"); } if ((week < 1) || (week > 5)) { throw new ArgumentOutOfRangeException("week", "ArgumentOutOfRange_Week"); } if ((dayOfWeek < DayOfWeek.Sunday) || (dayOfWeek > DayOfWeek.Saturday)) { throw new ArgumentOutOfRangeException("dayOfWeek", "ArgumentOutOfRange_DayOfWeek"); } if (((timeOfDay.Year != 1) || (timeOfDay.Month != 1)) || ((timeOfDay.Day != 1) || ((timeOfDay.Ticks % 0x2710L) != 0L))) { throw new ArgumentException("Argument_DateTimeHasTicks", "timeOfDay"); } } void IDeserializationCallback.OnDeserialization(object sender) { try { ValidateTransitionTime(this.m_timeOfDay, this.m_month, this.m_week, this.m_day, this.m_dayOfWeek); } catch (ArgumentException exception) { throw new SerializationException("Serialization_InvalidData", exception); } } [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) { throw new ArgumentNullException("info"); } info.AddValue("TimeOfDay", this.m_timeOfDay); info.AddValue("Month", this.m_month); info.AddValue("Week", this.m_week); info.AddValue("Day", this.m_day); info.AddValue("RelativeDayOfWeek", this.m_dayOfWeek); info.AddValue("IsFixedDateRule", this.m_isFixedDateRule); } private TransitionTime(SerializationInfo info, StreamingContext context) { if (info == null) { throw new ArgumentNullException("info"); } this.m_timeOfDay = (DateTime)info.GetValue("TimeOfDay", typeof(DateTime)); this.m_month = (byte)info.GetValue("Month", typeof(byte)); this.m_week = (byte)info.GetValue("Week", typeof(byte)); this.m_day = (byte)info.GetValue("Day", typeof(byte)); this.m_dayOfWeek = (DayOfWeek)info.GetValue("RelativeDayOfWeek", typeof(DayOfWeek)); this.m_isFixedDateRule = (bool)info.GetValue("IsFixedDateRule", typeof(bool)); } } } [Flags] internal enum TimeZoneInfoOptions { None = 1, NoThrowOnInvalidTime = 2 } [Serializable, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] public class InvalidTimeZoneException : Exception { // Methods public InvalidTimeZoneException() { } public InvalidTimeZoneException(string message) : base(message) { } protected InvalidTimeZoneException(SerializationInfo info, StreamingContext context) : base(info, context) { } public InvalidTimeZoneException(string message, Exception innerException) : base(message, innerException) { } } [Serializable, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] public class TimeZoneNotFoundException : Exception { // Methods public TimeZoneNotFoundException() { } public TimeZoneNotFoundException(string message) : base(message) { } protected TimeZoneNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { } public TimeZoneNotFoundException(string message, Exception innerException) : base(message, innerException) { } } [SuppressUnmanagedCodeSecurity, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] internal sealed class SafeLibraryHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid { // Methods internal SafeLibraryHandle() : base(true) { } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("kernel32.dll", CharSet = CharSet.Unicode)] private static extern bool FreeLibrary(IntPtr hModule); [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] internal static extern SafeLibraryHandle LoadLibraryEx(string libFilename, IntPtr reserved, int flags); protected override bool ReleaseHandle() { return FreeLibrary(base.handle); } } } #endif