0

プログラムで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を除いて、各関数呼び出しは成功します。ExitWindowsExは、管理者として実行している場合でも、エラーコード1314(特権が保持されていません)で必ず失敗します。再起動にも同じ問題がありますが、ログオフは機能します。

私はここで何が間違っているのですか?

4

1 に答える 1

2

間違ったmbでLookupPrivilegeValueWを呼び出し、AdjustTokenPrivilegesに間違ったmbを渡します。

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
于 2011-11-18T10:25:51.450 に答える