Skip to content

Commit

Permalink
Adds support for detecting if an application has requested the screen…
Browse files Browse the repository at this point in the history
… stay on, such as during a presentation, media playback or video conference
  • Loading branch information
ryannewington committed Jul 22, 2017
1 parent 9268495 commit f484120
Show file tree
Hide file tree
Showing 15 changed files with 235 additions and 54 deletions.
6 changes: 6 additions & 0 deletions src/Lithnet.IdleLogoff/AdminCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ public static bool TryRestartElevated(out bool userCanceled)
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = Environment.CurrentDirectory;
startInfo.FileName = Application.ExecutablePath;

if (System.Diagnostics.Debugger.IsAttached)
{
startInfo.Arguments = "/attach";
}

startInfo.Verb = "runas";
userCanceled = false;

Expand Down
6 changes: 0 additions & 6 deletions src/Lithnet.IdleLogoff/ChangeLog.txt

This file was deleted.

1 change: 1 addition & 0 deletions src/Lithnet.IdleLogoff/EventLogging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public static void LogEvent(string eventText, int eventId)

public static void LogEvent(string eventText, int eventID, EventLogEntryType entryType)
{
Trace.WriteLine($"{entryType}: {eventID}: {eventText}");
if (LogEnabled)
{
EventLog.WriteEntry(evtSource, eventText, entryType, eventID);
Expand Down
18 changes: 18 additions & 0 deletions src/Lithnet.IdleLogoff/ExecutionState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Lithnet.idlelogoff
{
[Flags]
public enum EXECUTION_STATE : ulong
{
NONE = 0,
AWAYMODE_REQUIRED = 0x00000040,
CONTINUOUS = 0x80000000,
DISPLAY_REQUIRED = 0x00000002,
SYSTEM_REQUIRED = 0x00000001,
}
}
32 changes: 28 additions & 4 deletions src/Lithnet.IdleLogoff/NativeMethods.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,40 @@
namespace Lithnet.idlelogoff
{
using System.Runtime.InteropServices;
using System.ComponentModel;
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace Lithnet.idlelogoff
{
public class NativeMethods
{
[DllImport("powrprof.dll")]
private static extern int CallNtPowerInformation(
POWER_INFORMATION_LEVEL informationLevel,
IntPtr lpInputBuffer,
int nInputBufferSize,
out EXECUTION_STATE state,
int nOutputBufferSize
);

[DllImport("User32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool GetLastInputInfo(ref LastInputInfo lastInputInfo);

[DllImport("User32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool ExitWindowsEx(ShutdownFlags flags, int reason);

public static bool IsDisplayRequested()
{
EXECUTION_STATE state;

int retval = CallNtPowerInformation(POWER_INFORMATION_LEVEL.SystemExecutionState, IntPtr.Zero, 0, out state, sizeof(EXECUTION_STATE));

if (retval != 0)
{
throw new Win32Exception(retval);
}

return (state.HasFlag(EXECUTION_STATE.DISPLAY_REQUIRED));
}

public static int GetLastInputTime()
{
LastInputInfo info = new LastInputInfo();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
<presentationTable>
<presentation id="POL_978C1C26_0621_4860_A000_61A23A440151">
<decimalTextBox refId="DXT_7E914D9D_203C_40DF_8C49_93B29308A6B2" defaultValue="60">Idle timeout (minutes)</decimalTextBox>
<checkBox refId="DXT_B357DAA7-0013-45D9-94DC-E91206837C29" defaultChecked="false">Ignore sleep prevention requests from applications such as media playback</checkBox>
</presentation>
<presentation id="POL_1D519699-D182-4B28-A489-1F7DE9DB6DE5">
<decimalTextBox refId="DXT_B29D2480-E131-4C23-B4D4-F55CAA13C2FF" defaultValue="60">Idle timeout (minutes)</decimalTextBox>
<checkBox refId="DXT_CFF2EAC7-2034-47F9-B3CE-8D10C73FCA81" defaultChecked="false">Ignore sleep prevention requests from applications such as media playback</checkBox>
</presentation>
</presentationTable>
</resources>
Expand Down
17 changes: 16 additions & 1 deletion src/Lithnet.IdleLogoff/PolicyDefinitions/lithnet.idlelogoff.admx
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,29 @@
<supportedOn ref="TS_SUPPORTED_WindowsXP" />
<elements>
<decimal id="DXT_7E914D9D_203C_40DF_8C49_93B29308A6B2" key="Software\Policies\Lithnet\IdleLogoff" valueName="IdleLimit" minValue="1" />
<boolean id="DXT_B357DAA7-0013-45D9-94DC-E91206837C29" key="Software\Policies\Lithnet\IdleLogoff" valueName="IgnoreDisplayRequested">
<trueValue>
<decimal value="1" />
</trueValue>
<falseValue>
<decimal value="0" />
</falseValue>
</boolean>
</elements>
</policy>
<policy name="POL_1D519699-D182-4B28-A489-1F7DE9DB6DE5" class="User" displayName="$(string.POL_978C1C26_0621_4860_A000_61A23A440151)" presentation="$(presentation.POL_1D519699-D182-4B28-A489-1F7DE9DB6DE5)" key="Software\Policies\Lithnet\IdleLogoff" valueName="Enabled">
<parentCategory ref="CAT_78275968_599A_4E3F_BAD6_07C70894AF09" />
<supportedOn ref="TS_SUPPORTED_WindowsXP" />
<elements>
<decimal id="DXT_B29D2480-E131-4C23-B4D4-F55CAA13C2FF" key="Software\Policies\Lithnet\IdleLogoff" valueName="IdleLimit" minValue="1" />
</elements>
<boolean id="DXT_CFF2EAC7-2034-47F9-B3CE-8D10C73FCA81" key="Software\Policies\Lithnet\IdleLogoff" valueName="IgnoreDisplayRequested">
<trueValue>
<decimal value="1" />
</trueValue>
<falseValue>
<decimal value="0" />
</falseValue>
</boolean> </elements>
</policy>
</policies>
</policyDefinitions>
31 changes: 31 additions & 0 deletions src/Lithnet.IdleLogoff/PowerInformationLevel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lithnet.idlelogoff
{
public enum POWER_INFORMATION_LEVEL
{
AdministratorPowerPolicy = 9,
LastSleepTime = 15,
LastWakeTime = 14,
ProcessorInformation = 11,
ProcessorPowerPolicyAc = 18,
ProcessorPowerPolicyCurrent = 22,
ProcessorPowerPolicyDc = 19,
SystemBatteryState = 5,
SystemExecutionState = 16,
SystemPowerCapabilities = 4,
SystemPowerInformation = 12,
SystemPowerPolicyAc = 0,
SystemPowerPolicyCurrent = 8,
SystemPowerPolicyDc = 1,
SystemReserveHiberFile = 10,
VerifyProcessorPowerPolicyAc = 20,
VerifyProcessorPowerPolicyDc = 21,
VerifySystemPolicyAc = 2,
VerifySystemPolicyDc = 3
}
}
27 changes: 18 additions & 9 deletions src/Lithnet.IdleLogoff/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,13 @@ public static class Program
private static Timer eventTimer;
private static bool inTimer = false;
private static bool backgroundMode = false;
private static bool debug = false;
private static int initialTime = 0;

[STAThread]
public static void Main()
{
try
{
if (Debugger.IsAttached)
{
debug = true;
}

EventLogging.InitEventLog();
ValidateCommandLineArgs();

Expand Down Expand Up @@ -94,6 +88,10 @@ private static void ValidateCommandLineArgs()
{
backgroundMode = true;
}
else if (arg.ToLower() == "/attach")
{
System.Diagnostics.Debugger.Launch();
}
else
{
MessageBox.Show("An invalid command line argument was specified: " + arg);
Expand Down Expand Up @@ -125,22 +123,33 @@ private static void EventTimer_Tick(object sender, EventArgs e)
if (initialTime != logoffidletime)
{
EventLogging.TryLogEvent($"Idle timeout limit has changed. User {Environment.UserDomainName}\\{Environment.UserName} will now be logged off after {Settings.IdleLimit} minutes", EventLogging.EVT_TIMERINTERVALCHANGED);
initialTime = logoffidletime;
}

int currentticks = NativeMethods.GetLastInputTime();

if (!Settings.IgnoreDisplayRequested && NativeMethods.IsDisplayRequested())
{
Trace.WriteLine("An application has requested the system display stay on");
Program.lastDateTime = DateTime.Now;
Program.lastTicks = currentticks;
return;
}


if (currentticks != Program.lastTicks)
{
Trace.WriteLine("Input received");
Program.lastTicks = currentticks;
Program.lastDateTime = DateTime.Now;
return;
}

if (DateTime.Now.Subtract(Program.lastDateTime).TotalMilliseconds > logoffidletime)
{
EventLogging.TryLogEvent($"User {Environment.UserName} has passed the idle time limit of {Settings.IdleLimit} minutes. Initating logoff.", EventLogging.EVT_LOGOFFEVENT);
EventLogging.TryLogEvent($"User {Environment.UserName} has passed the idle time limit of {Settings.IdleLimit} minutes. Initiating logoff.", EventLogging.EVT_LOGOFFEVENT);

if (!debug)
if (!Settings.Debug)
{
try
{
Expand All @@ -151,7 +160,7 @@ private static void EventTimer_Tick(object sender, EventArgs e)
}
catch (Exception ex)
{
EventLogging.TryLogEvent("An error occured trying to log off the user\n" + ex.Message, EventLogging.EVT_LOGOFFFAILED);
EventLogging.TryLogEvent("An error occurred trying to log off the user\n" + ex.Message, EventLogging.EVT_LOGOFFFAILED);
}
}
else
Expand Down
77 changes: 72 additions & 5 deletions src/Lithnet.IdleLogoff/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public static class Settings
private static string strBaseSettingsKey = "Software\\Lithnet\\IdleLogOff";
private static string strBasePolicyKey = "Software\\Policies\\Lithnet\\IdleLogOff";
private static RegistryKey _regkeySettings;
private static RegistryKey _regkeySettingsWritable;
private static RegistryKey _regkeyMachinePolicy;
private static RegistryKey _regkeyUserPolicy;

Expand Down Expand Up @@ -52,19 +53,20 @@ private static RegistryKey SettingsKeyWriteable
try
{

if (_regkeySettings == null)
if (_regkeySettingsWritable == null)
{
_regkeySettings = Registry.LocalMachine.CreateSubKey(strBaseSettingsKey);

_regkeySettingsWritable = Registry.LocalMachine.CreateSubKey(strBaseSettingsKey);
}
else
{
try
{
int x = _regkeySettings.ValueCount;
int x = _regkeySettingsWritable.ValueCount;
}
catch // catch handler for a key that is missing and no longer valid
{
_regkeySettings = Registry.LocalMachine.CreateSubKey(strBaseSettingsKey);
_regkeySettingsWritable = Registry.LocalMachine.CreateSubKey(strBaseSettingsKey);
}
}
}
Expand All @@ -73,7 +75,7 @@ private static RegistryKey SettingsKeyWriteable
// could not open registry key
}

return _regkeySettings;
return _regkeySettingsWritable;

}

Expand Down Expand Up @@ -223,6 +225,39 @@ public static int IdleLimit
}
}

public static bool Debug
{
get
{
if (System.Diagnostics.Debugger.IsAttached)
{
return true;
}

object value = null;
bool status = false;

value = GetSetting("Debug");
if (value != null)
{
try
{
if ((int) value == 1)
{
status = true;
}
}
catch
{
//unable to cast
}

}

return status;
}
}

public static bool Enabled
{
get
Expand Down Expand Up @@ -254,6 +289,38 @@ public static bool Enabled
}
}

public static bool IgnoreDisplayRequested
{
get
{
object value = null;
bool status = false;

value = GetPolicyOrSetting("IgnoreDisplayRequested");
if (value != null)
{
try
{
if ((int)value == 1)
{
status = true;
}
}
catch
{
//unable to cast
}

}
return status;
}
set
{
SaveSetting("IgnoreDisplayRequested", Convert.ToInt32(value), RegistryValueKind.DWord);
}
}


public static void Release()
{
if (_regkeyMachinePolicy != null)
Expand Down
Loading

0 comments on commit f484120

Please sign in to comment.