【问题标题】:ExitWindowsEx fails even after adjusting my privilege token即使在调整我的权限令牌后,ExitWindowsEx 也会失败
【发布时间】:2011-10-25 06:37:41
【问题描述】:

我正在尝试以编程方式关闭 Windows:

Function ExitWindows() As Integer
  Declare Function GetCurrentProcess Lib "Kernel32" () As Integer
  Declare Function OpenProcessToken Lib "AdvApi32" (handle As Integer, access As Integer, ByRef tHandle As Integer) As Boolean
  Declare Function LookupPrivilegeValueW Lib "AdvApi32" (sysName As Ptr, privName As WString, Luid As Ptr) As Boolean
  Declare Function AdjustTokenPrivileges Lib "AdvApi32" (tHandle As Integer, disableAllPrivs As Boolean, newState As Ptr, buffLength As Integer, prevPrivs As Ptr, ByRef retLen As Integer) As Boolean
  Declare Function ExitWindowsEx Lib "User32" (flags As Integer, reason As Integer) As Boolean
  Declare Function GetLastError Lib "Kernel32" () As Integer

  Const SE_PRIVILEGE_ENABLED = &h00000002
  Const TOKEN_QUERY = &h00000008
  Const TOKEN_ADJUST_PRIVILEGES = &h00000020
  Const SE_SHUTDOWN_NAME = "SeShutdownPrivilege"
  Const EWX_SHUTDOWN = &h00000001

  Dim pHandle As Integer = GetCurrentProcess()   //a handle to the current process
  Dim tHandle As Integer                         //a handle to the token

  If OpenProcessToken(pHandle, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, tHandle) Then
    Dim mb As New MemoryBlock(8)
    mb.UInt32Value(0) = 1
    mb.Int32Value(4) = SE_PRIVILEGE_ENABLED
    Dim pt As Ptr
    If LookupPrivilegeValueW(Nil, "SeShutdownPrivilege", mb) Then
      Dim z As Integer
      If AdjustTokenPrivileges(tHandle, False, mb, mb.Size, pt, z) Then
        If Not ExitWindowsEx(EWX_SHUTDOWN, 0) Then
          Return GetLastError()     //Returns 1314
        End If
      Else 
        Return GetLastError()
      End If
    Else
      Return GetLastError()
    End If
  Else
    Return GetLastError()
  End If
End Function

每个函数调用都成功,但 ExitWindowsEx 除外,即使以管理员身份运行,它也总是会失败并显示错误代码 1314(未保留特权)。重新启动有同样的问题,但注销工作。

我在这里做错了什么?

【问题讨论】:

  • 我认为您的 mb 参数在 AdjustTokenPrivileges 调用中不正确。见vbaccelerator.com/home/VB/Tips/…
  • @Roman R. 我没明白你的意思。 LUID 不是 8 个字节长吗?
  • 不完全。对于 LUID 和属性,参数是 4 字节计数 + 每个元素 12 字节。您只为所有内容传递 8 个字节。
  • 所以,即使内存块非常大,我仍然会返回 1314 作为错误。

标签: winapi realbasic system-shutdown


【解决方案1】:

您使用错误的 mb 调用 LookupPrivilegeValueW 并将错误的 mb 传递给 AdjustTokenPrivileges。

Dim luid As New MemoryBlock(8)
If LookupPrivilegeValueW(Nil, "SeShutdownPrivilege", luid) Then     
   Dim mb As New MemoryBlock(16)
   mb.UInt32Value(0) = 1
   mb.UInt32Value(4) = luid.UInt32Value(0)
   mb.UInt32Value(8) = luid.UInt32Value(4)
   mb.UInt32Value(12) = SE_PRIVILEGE_ENABLED
   Dim z As Integer
   If AdjustTokenPrivileges(tHandle, False, mb, mb.Size, pt, z) Then

【讨论】:

  • 啊,太棒了!谢谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-09
  • 1970-01-01
  • 2021-02-12
  • 1970-01-01
  • 2016-02-19
  • 2015-06-03
  • 1970-01-01
相关资源
最近更新 更多