private bool ChangeTimer(TimerSettings timerSettings)
        {
            try{
                    int rslt;

                    if (timerSettings.WakeTimer == null)
                        timerSettings.WakeTimer = new Mischel.Synchronization.WaitableTimer(true);

                    if (timerSettings.WakeUpDateTime == null)
                    {
                        LogMessage("SystemServices", "ChangeTimer - Timer " + timerSettings.Id + " null wake time", LogEntryType.Trace);
                        // after 10 seconds timer thread will expire
                        TimeSpan t = TimeSpan.FromSeconds(10);
                        rslt = timerSettings.WakeTimer.Change(t, 0, null, null, false);
                    }
                    else
                    {
                        LogMessage("SystemServices", "ChangeTimer - Timer " + timerSettings.Id + " set - wake at: " + timerSettings.WakeUpDateTime, LogEntryType.Trace);
                        TimeSpan t = timerSettings.WakeUpDateTime.Value - DateTime.Now;
                        if (t.TotalSeconds < 0)
                        {
                            LogMessage("SystemServices", "ChangeTimer - attempt to set negative timer "
                                + timerSettings.Id + " - Wake Time: " + timerSettings.WakeUpDateTime.Value, LogEntryType.ErrorMessage);
                            t = TimeSpan.FromSeconds(10);
                        }
                        rslt = timerSettings.WakeTimer.Change(t, 0, null, null, true);
                    }

                    if (rslt == Mischel.Synchronization.WaitableTimer.ErrorNotSupported)
                    {
                        LogMessage("SystemServices", "ChangeTimer - System does not support resume", LogEntryType.ErrorMessage);
                        timerSettings.WakeUpDateTime = null;
                        return false;
                    }

                    return true;
                }
                catch (Exception e)
                {
                    LogMessage("SystemServices", "ChangeTimer - Timer " + timerSettings.Id + " - Exception - Wake Time: " + timerSettings.WakeUpDateTime.Value
                        + " - Exception: " + e.Message, LogEntryType.Trace);
                    return false;
                }
        }
        private void KillWakeTimerThread(TimerSettings settings)
        {
            if (settings == null)
                return;

            settings.TimerMutex.WaitOne();

            if (settings.WakeTimerThread != null)
            {
                if (settings.WakeTimerThread.IsAlive)
                {
                    try
                    {
                        LogMessage("SystemServices", "KillWakeTimerThread - id " + settings.Id, LogEntryType.Trace);
                        settings.WakeTimerThread.Abort();
                        if (settings.WakeTimer != null)
                        {
                            settings.WakeTimer.Cancel();
                            settings.WakeTimer.Close();
                            settings.WakeTimer.Dispose();
                            settings.WakeTimer = null;
                        }
                        // allow dust to settle!!!
                        System.Threading.Thread.Sleep(1000);
                    }
                    catch (Exception e)
                    {
                        LogMessage("SystemServices", "KillWakeTimerThread - id " + settings.Id + " - Exception: " + e.Message, LogEntryType.ErrorMessage);
                    }
                }
                settings.WakeTimerThread = null;
            }
            settings.TimerMutex.ReleaseMutex();
        }
        // sets the primary and backup timers. These timers are used solely to wake the computer
        // from a suspended state. No operational functionality is associated with these timers
        public void SetupWakeEvent(DateTime? wakeTime, DateTime? nextWakeTime)
        {
            // LogMessage("SystemServices", "SetupWakeEvent - Timer 1: " + wakeTime + " - Timer 2: " + nextWakeTime, LogEntryType.Trace);
            bool haveMutex1 = false;
            bool haveMutex2 = false;

            try
            {

                if (TimerSettings1 == null)
                {
                    TimerSettings1 = new TimerSettings();
                    TimerSettings1.Id = "1";
                }

                TimerSettings1.TimerMutex.WaitOne();
                haveMutex1 = true;

                TimerSettings1.NextWakeUpDateTime = nextWakeTime;

                if (wakeTime == TimerSettings1.WakeUpDateTime)
                {
                    // LogMessage("SystemServices", "SetupWakeEvent: Timer 1 already set: " + wakeTime, LogEntryType.Trace);
                }
                else
                {
                    // timer1 is the primary timer. This will normally be the only timer
                    // that actually triggers.
                    TimerSettings1.WakeUpDateTime = wakeTime;

                    if (TimerSettings1.WakeTimerThread == null)
                    {
                        TimerSettings1.WakeTimerThread = new System.Threading.Thread(RunWakeTimer);
                        TimerSettings1.WakeTimerThread.Start(TimerSettings1);
                    }
                    else
                        ChangeTimer(TimerSettings1);
                }

                TimerSettings1.TimerMutex.ReleaseMutex();
                haveMutex1 = false;

                if (TimerSettings2 == null)
                {
                    TimerSettings2 = new TimerSettings();
                    TimerSettings2.Id = "2";
                }

                TimerSettings2.TimerMutex.WaitOne();
                haveMutex2 = true;

                if (nextWakeTime == TimerSettings2.WakeUpDateTime)
                {
                    // LogMessage("SystemServices", "SetupWakeEvent: Timer 2 already set: " + nextWakeTime, LogEntryType.Trace);
                }
                else
                {
                    // timer 2 is a backup timer. In the event that the computer is suspended
                    // after the primary timer has fired but before the timer has been reset
                    // the secondary timer will eventually wake the computer
                    TimerSettings2.WakeUpDateTime = nextWakeTime;

                    if (TimerSettings2.WakeTimerThread == null)
                    {
                        TimerSettings2.WakeTimerThread = new System.Threading.Thread(RunWakeTimer);
                        TimerSettings2.WakeTimerThread.Start(TimerSettings2);
                    }
                    else
                        ChangeTimer(TimerSettings2);
                }

                TimerSettings2.TimerMutex.ReleaseMutex();
                haveMutex2 = false;
            }
            catch (Exception e)
            {
                LogMessage("SystemServices", "SetupWakeEvent - Exception: " + e.Message, LogEntryType.ErrorMessage);
            }
            finally
            {
                if (haveMutex1)
                    TimerSettings1.TimerMutex.ReleaseMutex();
                if (haveMutex2)
                    TimerSettings2.TimerMutex.ReleaseMutex();
            }
        }