/code/Cairo Desktop/CairoDesktop.Interop/NativeMethods.cs

https://github.com/ProgressiveDeveloper/cairoshell · C# · 140 lines · 97 code · 23 blank · 20 comment · 3 complexity · 4b26d70c095babe8298840a339f22b8d MD5 · raw file

  1. using System.Windows.Input;
  2. namespace CairoDesktop.Interop
  3. {
  4. using System;
  5. using System.Runtime.InteropServices;
  6. /// <summary>
  7. /// Container class for Win32 Native methods used within the desktop application (e.g. shutdown, sleep, et al).
  8. /// </summary>
  9. public class NativeMethods
  10. {
  11. private const uint TOKENADJUSTPRIVILEGES = 0x00000020;
  12. private const uint TOKENQUERY = 0x00000008;
  13. /// <summary>
  14. /// Calls the shutdown method on the Win32 API.
  15. /// </summary>
  16. public static void Shutdown()
  17. {
  18. AdjustTokenPrivilegesForShutdown();
  19. ExitWindowsEx((uint)(ExitWindows.Shutdown | ExitWindows.ForceIfHung), 0x0);
  20. }
  21. /// <summary>
  22. /// Calls the reboot method on the Win32 API.
  23. /// </summary>
  24. public static void Reboot()
  25. {
  26. AdjustTokenPrivilegesForShutdown();
  27. ExitWindowsEx((uint)(ExitWindows.Reboot | ExitWindows.ForceIfHung), 0x0);
  28. }
  29. /// <summary>
  30. /// Calls the logoff method on the Win32 API.
  31. /// </summary>
  32. public static void Logoff()
  33. {
  34. ExitWindowsEx((uint)ExitWindows.Logoff, 0x0);
  35. }
  36. /// <summary>
  37. /// Calls the Sleep method on the Win32 Power Profile API.
  38. /// </summary>
  39. public static void Sleep()
  40. {
  41. SetSuspendState(false, false, false);
  42. }
  43. public static void PostWindowsMessage(IntPtr hWnd, uint callback, uint uid, uint messageId)
  44. {
  45. PostMessage(hWnd, callback, uid, messageId);
  46. }
  47. public static IntPtr FindWindow(string className)
  48. {
  49. return FindWindow(className, string.Empty);
  50. }
  51. public static RECT GetWindowRectangle(IntPtr windowHandle)
  52. {
  53. RECT ret = new RECT();
  54. GetWindowRect(windowHandle, out ret);
  55. return ret;
  56. }
  57. #region Private Methods
  58. /// <summary>
  59. /// Adjusts the current process's token privileges to allow it to shut down or reboot the machine.
  60. /// Throws an ApplicationException if an error is encountered.
  61. /// </summary>
  62. private static void AdjustTokenPrivilegesForShutdown()
  63. {
  64. IntPtr procHandle = System.Diagnostics.Process.GetCurrentProcess().Handle;
  65. IntPtr tokenHandle = IntPtr.Zero;
  66. bool tokenOpenResult = OpenProcessToken(procHandle, TOKENADJUSTPRIVILEGES | TOKENQUERY, out tokenHandle);
  67. if (!tokenOpenResult)
  68. {
  69. throw new ApplicationException("Error attempting to open process token to raise level for shutdown.\nWin32 Error Code: " + Marshal.GetLastWin32Error());
  70. }
  71. long pluid = new long();
  72. bool privLookupResult = LookupPrivilegeValue(null, "SeShutdownPrivilege", ref pluid);
  73. if (!privLookupResult)
  74. {
  75. throw new ApplicationException("Error attempting to lookup value for shutdown privilege.\n Win32 Error Code: " + Marshal.GetLastWin32Error());
  76. }
  77. TOKEN_PRIVILEGES newPriv = new TOKEN_PRIVILEGES();
  78. newPriv.Luid = pluid;
  79. newPriv.PrivilegeCount = 1;
  80. newPriv.Attributes = 0x00000002;
  81. bool tokenPrivResult = AdjustTokenPrivileges(tokenHandle, false, ref newPriv, 0, IntPtr.Zero, IntPtr.Zero);
  82. if (!tokenPrivResult)
  83. {
  84. throw new ApplicationException("Error attempting to adjust the token privileges to allow shutdown.\n Win32 Error Code: " + Marshal.GetLastWin32Error());
  85. }
  86. }
  87. #region P/Invokes
  88. [DllImport("user32.dll")]
  89. private static extern bool ExitWindowsEx(uint flags, uint reason);
  90. // There is a method for this in System.Windows.Forms, however it calls the same p/invoke and I would prefer not to reference that lib
  91. [DllImport("powrprof.dll")]
  92. private static extern bool SetSuspendState(bool hibernate, bool forceCritical, bool disableWakeEvent);
  93. [DllImport("advapi32.dll", SetLastError = true)]
  94. private static extern bool OpenProcessToken(IntPtr processHandle, uint desiredAccess, out IntPtr tokenHandle);
  95. [DllImport("advapi32.dll", SetLastError = true)]
  96. private static extern bool AdjustTokenPrivileges(IntPtr tokenHandle, bool disableAllPrivileges, ref TOKEN_PRIVILEGES newState, uint bufferLength, IntPtr previousState, IntPtr returnLength);
  97. [DllImport("advapi32.dll", SetLastError = true)]
  98. private static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
  99. [DllImport("user32.dll")]
  100. private static extern bool PostMessage(IntPtr hWnd, uint callback, uint wParam, uint lParam);
  101. [DllImport("user32.dll", SetLastError=true)]
  102. private static extern IntPtr FindWindow(string className, string windowName);
  103. [DllImport("user32.dll")]
  104. [return: MarshalAs(UnmanagedType.Bool)]
  105. private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
  106. #endregion
  107. #endregion
  108. [StructLayout(LayoutKind.Sequential)]
  109. public struct RECT
  110. {
  111. public int left;
  112. public int top;
  113. public int right;
  114. public int bottom;
  115. }
  116. }
  117. }