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.

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 IntegerEnd 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 IfIt 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
See my last post at this link
http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=949229&SiteID=1
IamHuM
Check this page, it has a link to the struct and method declaration you need for VB.Net
--
SvenC