Zzz – Rev 1

Subversion Repositories:
Rev:
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Serilog;

namespace Zzz.Action
{
    public class ActionTrigger : IDisposable
    {
        #region Public Events & Delegates

        public event EventHandler<ActionEventArgs> Action;

        #endregion

        #region Private Delegates, Events, Enums, Properties, Indexers and Fields

        private readonly IntPtr _handle;

        #endregion

        #region Constructors, Destructors and Finalizers

        public ActionTrigger(IntPtr handle) : this()
        {
            _handle = handle;
        }

        private ActionTrigger()
        {
        }

        public void Dispose()
        {
        }

        #endregion

        #region Public Methods

        public void Execute(ZzzAction zzzAction)
        {
            var action = Enum.GetName(typeof(Action), zzzAction.Action);
            if (string.IsNullOrEmpty(action))
            {
                return;
            }

            Execute(action);
        }

        [Action]
        public void Lock()
        {
            ActionHelper.LockWorkStation();
        }

        [Action]
        public void Dim()
        {
            Action?.Invoke(this, new ActionEventArgs(Zzz.Action.Action.Dim));

            ActionHelper.SendMessage((IntPtr)ActionHelper.HwndBroadcast, (uint)ActionHelper.WmSysCommand,
                (UIntPtr) ActionHelper.ScMonitorPower,
                (IntPtr) 2);
        }

        [Action]
        public void Hibernate()
        {
            Action?.Invoke(this, new ActionEventArgs(Zzz.Action.Action.Hibernate));

            ActionHelper.SetSuspendState(true, true, true);
        }

        [Action]
        public void Standby()
        {
            Action?.Invoke(this, new ActionEventArgs(Zzz.Action.Action.Standby));

            ActionHelper.SetSuspendState(false, true, true);
        }

        [Action]
        public void ShutDown()
        {
            Action?.Invoke(this, new ActionEventArgs(Zzz.Action.Action.Shutdown));

            const string seShutdownName = "SeShutdownPrivilege";
            const short sePrivilegeEnabled = 2;
            const uint ewxShutdown = 1;
            const short tokenAdjustPrivileges = 32;
            const short tokenQuery = 8;
            ActionHelper.TokenPrivileges tkp;

            // Get shutdown privileges...
            ActionHelper.OpenProcessToken(Process.GetCurrentProcess().Handle,
                tokenAdjustPrivileges | tokenQuery, out var hToken);
            tkp.PrivilegeCount = 1;
            tkp.Privileges.Attributes = sePrivilegeEnabled;
            ActionHelper.LookupPrivilegeValue("", seShutdownName, out tkp.Privileges.PLuid);
            ActionHelper.AdjustTokenPrivileges(hToken, false, ref tkp, 0U, IntPtr.Zero,
                IntPtr.Zero);

            // Now we have the privileges, shutdown Windows
            ActionHelper.ExitWindowsEx(ewxShutdown, 0);
        }

        #endregion

        #region Private Methods

        private void Execute(string action)
        {
            var type = GetType();
            var methodInfo = type.GetMethods()
                .FirstOrDefault(method => string.Equals(method.Name, action, StringComparison.OrdinalIgnoreCase));

            if (methodInfo == null)
            {
                Log.Warning($"Zzz action \"{action}\" could not be resolved.");

                return;
            }

            var attribute = methodInfo.GetCustomAttribute(typeof(ActionAttribute));
            if (attribute is ActionAttribute)
            {
                methodInfo.Invoke(this, null);
            }
        }

        #endregion
    }
}

Generated by GNU Enscript 1.6.5.90.