ExitWindowsEX - How to get it to work in VB.Net 2005

I have been attempting to get the ExitWindowsEX function to work in VB. I have not been able to get it to work as yet. I have read numerous MSDN articles and help solutions from various sources on the internet. Non of the solutions I have found work for me. I am hoping to get some help in making this work in VB.

Here is what I have so far:

Public Enum TokenQueryFlags 'As UInteger

STANDARD_RIGHTS_REQUIRED = &HF0000

STANDARD_RIGHTS_READ = &H20000

TOKEN_ASSIGN_PRIMARY = &H1

TOKEN_DUPLICATE = &H2

TOKEN_IMPERSONATE = &H4

TOKEN_QUERY = &H8

TOKEN_QUERY_SOURCE = &H10

TOKEN_ADJUST_PRIVILEGES = &H20

TOKEN_ADJUST_GROUPS = &H40

TOKEN_ADJUST_DEFAULT = &H80

TOKEN_ADJUST_SESSIONID = &H100

TOKEN_READ = (STANDARD_RIGHTS_READ Or TOKEN_QUERY)

TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or TOKEN_ASSIGN_PRIMARY Or _

TOKEN_DUPLICATE Or TOKEN_IMPERSONATE Or TOKEN_QUERY Or TOKEN_QUERY_SOURCE Or _

TOKEN_ADJUST_PRIVILEGES Or TOKEN_ADJUST_GROUPS Or TOKEN_ADJUST_DEFAULT Or _

TOKEN_ADJUST_SESSIONID)

End Enum

Public Enum ExitWindowsFlags As UInteger

' ONE of the following five:

EWX_LOGOFF = &H0 '0x00

EWX_SHUTDOWN = &H1 '0x01

EWX_REBOOT = &H2 '0x02

EWX_POWEROFF = &H8 '0x08

EWX_RESTARTAPPS = &H40 '0x40

End Enum

Public Enum ExitWindowsExtendedFlags As UInteger

' Plus AT MOST ONE of the following two:

EWX_FORCE = &H4 '0x04

EWX_FORCEIFHUNG = &H10 '0x10

End Enum

Private Const SE_SHUTDOWN_NAME As String = "SeShutdownPrivilege"

Private Const SE_RESTORE_NAME As String = "SeRestorePrivilege"

Private Const SE_PRIVILEGE_ENABLED As UInt32 = &H2

Private Const ANYSIZE_ARRAY = 0

Structure TOKEN_PRIVILEGESb

Public PrivilegeCount As Integer

Public TheLuid As LUID

Public Attributes As Integer

End Structure

Structure TOKEN_PRIVILEGES

Public PrivilegeCount As Integer

Public Privileges() As LUID_AND_ATTRIBUTES

End Structure

Structure LUID_AND_ATTRIBUTES

Public Luid As LUID

Public Attributes As UInt32

End Structure

Structure LUID

Public LowPart As Integer

Public HighPart As Integer

End Structure

Declare Function ExitWindowsEx Lib "user32.dll" ( _

ByVal dwOptions As Int32, _

ByVal dwReserved As Int32) As Int32

Declare Function GetCurrentProcess Lib "kernel32.dll" () As IntPtr

Declare Function OpenProcessToken Lib "advapi32.dll" ( _

ByVal ProcessHandle As IntPtr, _

ByVal DesiredAccess As Integer, _

ByRef TokenHandle As IntPtr) As Boolean

Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" ( _

ByVal lpSystemName As String, _

ByVal lpName As String, _

ByRef lpLuid As LUID) As Boolean

Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" ( _

ByVal lpSystemName As String, _

ByVal lpName As String, _

ByRef lpLuid As Long) As Boolean

'Declare Function AdjustTokenPrivileges Lib "advapi32.dll" ( _

' ByVal TokenHandle As IntPtr, _

' ByVal DisableAllPrivileges As Boolean, _

' ByRef NewState As TOKEN_PRIVILEGES, _

' ByVal BufferLength As Integer, _

' ByRef PreviousState As TOKEN_PRIVILEGES, _

' ByVal ReturnLength As IntPtr) As Boolean

Declare Function AdjustTokenPrivileges Lib "advapi32.dll" ( _

ByVal TokenHandle As IntPtr, _

ByVal DisableAllPrivileges As Boolean, _

ByRef NewState As TOKEN_PRIVILEGES, _

ByVal BufferLength As Integer, _

ByRef PreviousState As IntPtr, _

ByVal ReturnLength As IntPtr) As Boolean

'Declare Function AdjustTokenPrivileges Lib "advapi32.dll" ( _

' ByVal TokenHandle As IntPtr, _

' ByVal DisableAllPrivileges As Boolean, _

' ByRef NewState As TOKEN_PRIVILEGES, _

' ByVal BufferLength As Integer, _

' ByRef PreviousState As Long, _

' ByVal ReturnLength As Long) As Boolean

Declare Function AdjustTokenPrivileges Lib "advapi32.dll" ( _

ByVal TokenHandle As IntPtr, _

ByVal DisableAllPrivileges As Boolean, _

ByRef NewState As TOKEN_PRIVILEGESb, _

ByVal BufferLength As Integer, _

ByRef PreviousState As IntPtr, _

ByVal ReturnLength As IntPtr) As Boolean

The problem is occuring when I attemp to AdjustTokenPrivileges. I have gotten everything to work up to this point. I have a method written that attempts to adjust the privilege:

Private Function AdjustTokenPrivlege() As Boolean

Dim hProc, hToken As IntPtr

Dim tkp As New TOKEN_PRIVILEGES

Dim Btkp As New TOKEN_PRIVILEGESb

ReDim tkp.Privileges(0)

' get the current process's token

hProc = Process.GetCurrentProcess().Handle

hToken = IntPtr.Zero

If Not OpenProcessToken(hProc, (TokenQueryFlags.TOKEN_ADJUST_PRIVILEGES Or TokenQueryFlags.TOKEN_QUERY), hToken) Then

Return False

End If

' get the LUID for the Restore privilege (provided it already exist)

If Not LookupPrivilegeValue(Nothing, SE_SHUTDOWN_NAME, tkp.Privileges(0).Luid) Then

Return False

End If

tkp.PrivilegeCount = 1

tkp.Privileges(0).Attributes = SE_PRIVILEGE_ENABLED

Btkp.PrivilegeCount = 1

Btkp.Attributes = SE_PRIVILEGE_ENABLED

Btkp.TheLuid = tkp.Privileges(0).Luid

' enable the privileges

If Not AdjustTokenPrivileges(hToken, False, Btkp, 0, 0, 0) Then

Dim e As Integer = Err.LastDllError

Return False

End If

End Function

I have tried several different ways of calling this function. If I use the TOKEN_PRIVILEGES structure in place of TOKEN_PRIVILEGESB , I get HRESULT error E_INVALIDARG 0x80070057. If I use the TOKEN_PRIVILEGESB structure, I get a dll error (it passes through the function). I get error code 998 which is ERROR_NOACCESS Invalid access to memory location. I'm not extreemly knowlegeable about API calls. I have tried various forms of this function from various sources, but not found one that works. I have a C++ source that works, but I am not very familure with C++ yet.

Any suggetions What am I doing wrong

Thanks.




Answer this question

ExitWindowsEX - How to get it to work in VB.Net 2005

  • Fluxtah

    Strange, I wanted to put in this: http://www.pinvoke.net/search.aspx search=TOKEN_PRIVILEGES&namespace=[All]

    www.pinvoke.net is a good source for getting declarations.

    --
    SvenC


  • araw012

    SvenC

    Thanks for the link, I have used www.pinvoke.net, and find it to be a good resource as well.

    As the site recommends, I have created the structure like this:

    Structure TOKEN_PRIVILEGES

    Public PrivilegeCount As Integer

    Public TheLuid As LUID

    Public Attributes As Integer

    End Structure

    When I call the API in this part of the code:

    If Not AdjustTokenPrivileges(hToken, False, tkp, 0, 0, 0) Then

    Dim e As Integer = Err.LastDllError

    Return False

    End If

    It passes through the API Call with a FALSE value. The MSDN article on AdjustTokenPrivileges states "If the function succeeds, the return value is nonzero." The application then drops down to the next line and calls the Err.LastDllError, which returns 998 as the error code. Looking up this code on the system errors, I get "ERROR_NOACCESS Invalid access to memory location." This leads me to beleive that the API call failed, but I do not know how to get past the error.

    Any thoughts

    Thanks again.


  • Thomas Maine

    SvenC,

    Thanks for your response. Was there a link in your reply What link should I follow

    Thanks.


  • Rhubarb

  • IamHuM

    Check this page, it has a link to the struct and method declaration you need for VB.Net

    --
    SvenC


  • ExitWindowsEX - How to get it to work in VB.Net 2005