exitwindowsex: check which options are supported on the users system
- I use ExitWindowsEx to shut down/reboot computers, or log off users.But when I tried to use the 'reboot and restart applications' (0x00000040) parameter my computer (Vista) just logged off...An other check on a Windows 98: as well the reboot and restart apps as the 'shutdown and poweroff' (0x00000008) resulted in a logoff.From this I concluded that the system just logs off when it does not recognize the command given.For this reason (and an other: that I can inform the user that method X is not supported) I was wondering: is there any way to get all supported shutdown/reboot/logoff parameters of the system?
Answers
Hi famlam,
What's the return value of the api calling? This maybe a priveledge problem. To shut down or restart the system, the calling process must use the AdjustTokenPrivileges function to enable the SE_SHUTDOWN_NAME privilege. Most of the privilege is disabled for the user account by default. You have to use AdjustTokenPrivileges to enable it explicitly.
You can try the following code, it works well on my computerPublic Class Form1 Private Structure LUID Dim UsedPart As Integer Dim IgnoredForNowHigh32BitPart As Integer End Structure Private Structure TOKEN_PRIVILEGES Dim PrivilegeCount As Integer Dim TheLuid As LUID Dim Attributes As Integer End Structure 'The API functions below are all used to give the application the proper privilege so the OS will allow the app to Shutdown Windows. Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As IntPtr, ByVal DesiredAccess As Integer, ByRef TokenHandle As Integer) As Integer Private Declare Function LookupPrivilegeValue Lib "advapi32" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, ByRef lpLuid As LUID) As Integer Private Declare Function AdjustTokenPrivileges Lib "advapi32" (ByVal TokenHandle As Integer, ByVal DisableAllPrivileges As Boolean, ByRef NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Integer, ByRef PreviousState As TOKEN_PRIVILEGES, ByRef ReturnLength As Integer) As Integer 'This sub will do all of the work of setting up your apps process using the APIs posted above to get the proper privileges to shutdown the OS. I originally got this function from msdn and converted it from VB 6.0 to VB.Net and did a tweak here and there. Private Sub AdjustToken() Const TOKEN_ADJUST_PRIVILEGES As Int32 = &H20 Const TOKEN_QUERY As Int32 = &H8 Const SE_PRIVILEGE_ENABLED As Int32 = &H2 Dim hdlProcessHandle As IntPtr Dim hdlTokenHandle As Int32 Dim tmpLuid As LUID Dim tkp As TOKEN_PRIVILEGES Dim tkpNewButIgnored As TOKEN_PRIVILEGES Dim lBufferNeeded As Int32 hdlProcessHandle = Process.GetCurrentProcess.Handle OpenProcessToken(hdlProcessHandle, (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), hdlTokenHandle) 'Get the LUID for shutdown privilege. LookupPrivilegeValue("", "SeShutdownPrivilege", tmpLuid) tkp.PrivilegeCount = 1 'One privilege to set tkp.TheLuid = tmpLuid tkp.Attributes = SE_PRIVILEGE_ENABLED 'Enable the shutdown privilege in the access token of this process. Dim retval As Int32 retval = AdjustTokenPrivileges(hdlTokenHandle, False, tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeeded) If (retval = 0) Then MessageBox.Show(System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString()) End If End Sub 'The function used to actually send the request to shutdown windows. Set the 'shutdownTypes' parameter to whether you want windows to "shutdown, reboot, logOff, ect..." Private Declare Function ExitWindowsEx Lib "user32" (ByVal shutdownType As Integer, ByVal dwReserved As Integer) As Integer Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'To shutdown, restart, or logoff the computer you only need to call the AdjustToken() - Sub before the ExitWindowsEx code. AdjustToken() 'Calls the function to begin executing. Dim retval As Int32 retval = ExitWindowsEx(2 + 4, Nothing) If (retval = 0) Then MessageBox.Show(System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString()) End If End Sub End Class
I found it at this page.
Hope this helps
Regards
Jeff Shan
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- Marked As Answer byJeff ShanMSFT, ModeratorMonday, November 02, 2009 6:12 AM
All Replies
Hi famlam,
What's the return value of the api calling? This maybe a priveledge problem. To shut down or restart the system, the calling process must use the AdjustTokenPrivileges function to enable the SE_SHUTDOWN_NAME privilege. Most of the privilege is disabled for the user account by default. You have to use AdjustTokenPrivileges to enable it explicitly.
You can try the following code, it works well on my computerPublic Class Form1 Private Structure LUID Dim UsedPart As Integer Dim IgnoredForNowHigh32BitPart As Integer End Structure Private Structure TOKEN_PRIVILEGES Dim PrivilegeCount As Integer Dim TheLuid As LUID Dim Attributes As Integer End Structure 'The API functions below are all used to give the application the proper privilege so the OS will allow the app to Shutdown Windows. Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As IntPtr, ByVal DesiredAccess As Integer, ByRef TokenHandle As Integer) As Integer Private Declare Function LookupPrivilegeValue Lib "advapi32" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, ByRef lpLuid As LUID) As Integer Private Declare Function AdjustTokenPrivileges Lib "advapi32" (ByVal TokenHandle As Integer, ByVal DisableAllPrivileges As Boolean, ByRef NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Integer, ByRef PreviousState As TOKEN_PRIVILEGES, ByRef ReturnLength As Integer) As Integer 'This sub will do all of the work of setting up your apps process using the APIs posted above to get the proper privileges to shutdown the OS. I originally got this function from msdn and converted it from VB 6.0 to VB.Net and did a tweak here and there. Private Sub AdjustToken() Const TOKEN_ADJUST_PRIVILEGES As Int32 = &H20 Const TOKEN_QUERY As Int32 = &H8 Const SE_PRIVILEGE_ENABLED As Int32 = &H2 Dim hdlProcessHandle As IntPtr Dim hdlTokenHandle As Int32 Dim tmpLuid As LUID Dim tkp As TOKEN_PRIVILEGES Dim tkpNewButIgnored As TOKEN_PRIVILEGES Dim lBufferNeeded As Int32 hdlProcessHandle = Process.GetCurrentProcess.Handle OpenProcessToken(hdlProcessHandle, (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY), hdlTokenHandle) 'Get the LUID for shutdown privilege. LookupPrivilegeValue("", "SeShutdownPrivilege", tmpLuid) tkp.PrivilegeCount = 1 'One privilege to set tkp.TheLuid = tmpLuid tkp.Attributes = SE_PRIVILEGE_ENABLED 'Enable the shutdown privilege in the access token of this process. Dim retval As Int32 retval = AdjustTokenPrivileges(hdlTokenHandle, False, tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeeded) If (retval = 0) Then MessageBox.Show(System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString()) End If End Sub 'The function used to actually send the request to shutdown windows. Set the 'shutdownTypes' parameter to whether you want windows to "shutdown, reboot, logOff, ect..." Private Declare Function ExitWindowsEx Lib "user32" (ByVal shutdownType As Integer, ByVal dwReserved As Integer) As Integer Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'To shutdown, restart, or logoff the computer you only need to call the AdjustToken() - Sub before the ExitWindowsEx code. AdjustToken() 'Calls the function to begin executing. Dim retval As Int32 retval = ExitWindowsEx(2 + 4, Nothing) If (retval = 0) Then MessageBox.Show(System.Runtime.InteropServices.Marshal.GetLastWin32Error().ToString()) End If End Sub End Class
I found it at this page.
Hope this helps
Regards
Jeff Shan
Please remember to mark the replies as answers if they help and unmark them if they provide no help.- Marked As Answer byJeff ShanMSFT, ModeratorMonday, November 02, 2009 6:12 AM
Thanks, it helps a lot. Forcing it can be done by using ExitWindowsEx(2 Or &H4, Nothing)Hi famlam,
What's the return value of the api calling? This maybe a priveledge problem. To shut down or restart the system, the calling process must use the AdjustTokenPrivileges function to enable the SE_SHUTDOWN_NAME privilege. Most of the privilege is disabled for the user account by default. You have to use AdjustTokenPrivileges to enable it explicitly.
You can try the following code, it works well on my computer[...]
I found it at this page.
Hope this helps
Regards
Jeff Shan- But this part of my question isn't solved yet:But when I tried to use the 'reboot and restart applications' (0x00000040) parameter my computer (Vista) just logged off...An other check on a Windows 98: as well the reboot and restart apps as the 'shutdown and poweroff' (0x00000008) resulted in a logoff.From this I concluded that the system just logs off when it does not recognize the command given.For this reason (and an other: that I can inform the user that method X is not supported) I was wondering: is there any way to get all supported shutdown/reboot/logoff parameters of the system?any ideas?


