Windowsの強制終了・再起動・ログオフ          <TOP>


呼び出し側プロセスはAdjustTokenPrivileges関数を呼び出し特権を有効にし、Windowsの『ログオフ』『シャットダウン』『再起動』を実行します。(WindowsNT以降)

GetCurrentProcess 現在のプロセスに対応する疑似ハンドルを取得

OpenProcessToken プロセスと結びつけられたアクセストークンを開く

ExitWindowsEx Windowsを強制終了

GetVersionEx オペレーティングシステムの種類やバージョンに関する情報を取得

LookupPrivilegeValue 指定されたシステムで使われているローカル一意識別子(LUID)を取得し、指定された特権名をローカルで表現

AdjustTokenPrivileges 指定したアクセストークン無いの特権を有効または無効に設定

 

参照

Windowsの終了・再起動・ログオフ(Windows95/98)

 

'================================================================
'= Windowsの終了・再起動・ログオフ
'= WindowsNT以降(Windows9xは対象外)
'=    (LookupPrivilegeValue.bas)
'================================================================
#include "Windows.bi"

#define ANYSIZE_ARRAY 1
#define EWX_FORCE 4                     '強制
#define EWX_LOGOFF 0                    'ログオフ
#define EWX_POWEROFF 8                  'パワーオフ
#define EWX_REBOOT 2                    'リブート
#define EWX_SHUTDOWN 1                  'シャットダウン
#define SE_PRIVILEGE_ENABLED &H2        '権限を有効にする
#define TOKEN_ADJUST_PRIVILEGES &H20    '特権を変更
#define TOKEN_QUERY &H8                 '問い合わせ
#define VER_PLATFORM_WIN32_NT 2         'WINDOWSNT、2000、XP

Type OSVERSIONINFO
    dwOSVersionInfoSize As Long
    dwMajorVersion      As Long
    dwMinorVersion      As Long
    dwBuildNumber       As Long
    dwPlatformId        As Long
    szCSDVersion        As String * 128
End Type

Type LUID
    LowPart  As Long
    HighPart As Long
End Type

Type LUID_AND_ATTRIBUTES
    pLuid      As LUID
    Attributes As Long
End Type

Type TOKEN_PRIVILEGES
    PrivilegeCount            As Long
    Privileges(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES
End Type

' 現在のプロセスに対応する疑似ハンドルを取得
Declare Function Api_GetCurrentProcess& Lib "Kernel32" Alias "GetCurrentProcess" ()

' プロセスと結び付けられたアクセストークンを開く
Declare Function Api_OpenProcessToken& Lib "advapi32" Alias "OpenProcessToken" (ByVal ProcessHandle&, ByVal DesiredAccess&, TokenHandle&)

' Windowsを強制終了
Declare Function Api_ExitWindowsEx& Lib "user32" Alias "ExitWindowsEx" (ByVal uFlags&, ByVal dwReserved&)

' オペレーティングシステムの種類やバージョンに関する情報を取得
Declare Function Api_GetVersionEx& Lib "Kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO)

' 指定されたシステムで使われているローカル一意識別子(LUID)を取得し、指定された特権名をローカルで表現
Declare Function Api_LookupPrivilegeValue& Lib "advapi32" Alias "LookupPrivilegeValueA" (ByVal lpSystemName$, ByVal lpName$, lpLuid As LUID)

' 指定したアクセストークン内の特権を有効または無効に設定
Declare Function Api_AdjustTokenPrivileges& Lib "advapi32" Alias "AdjustTokenPrivileges" (ByVal TokenHandle&, ByVal DisableAllPrivileges&, NewState As TOKEN_PRIVILEGES, ByVal BufferLength&, PreviousState As TOKEN_PRIVILEGES, ReturnLength&)

'================================================================
'=
'================================================================
Declare Function IsWinNT() As Integer
Function IsWinNT() As Integer
    Var myOS As OSVERSIONINFO
    Var Ret As Long

    myOS.dwOSVersionInfoSize = Len(myOS)
    Ret = Api_GetVersionEx(myOS)
    IsWinNT = (myOS.dwPlatformId = VER_PLATFORM_WIN32_NT)
End Function

'================================================================
'=
'================================================================
Declare Sub EnableShutDown()
Sub EnableShutDown()
    Var hProc As Long
    Var hToken As Long
    Var mLUID As LUID
    Var mPriv As TOKEN_PRIVILEGES
    Var mNewPriv As TOKEN_PRIVILEGES
    Var Ret As Long

    hProc = Api_GetCurrentProcess()
    Ret = Api_OpenProcessToken(hProc, TOKEN_ADJUST_PRIVILEGES + TOKEN_QUERY, hToken)
    Ret = Api_LookupPrivilegeValue("", "SeShutdownPrivilege", mLUID)

    mPriv.PrivilegeCount = 1
    mPriv.Privileges(0).Attributes = SE_PRIVILEGE_ENABLED
    mPriv.Privileges(0).pLuid = mLUID

    ' 
    Ret = Api_AdjustTokenPrivileges(hToken, False, mPriv, 4 + (12 * mPriv.PrivilegeCount), mNewPriv, 4 + (12 * mNewPriv.PrivilegeCount))
End Sub

'================================================================
'=
'================================================================
Declare Sub ShutDownNT(Force As Integer)
Sub ShutDownNT(Force As Integer)
    Var Flags As Long
    Var Ret As Long

    Flags = EWX_SHUTDOWN
    If Force Then Flags = Flags + EWX_FORCE
    If IsWinNT Then EnableShutDown
    Ret = Api_ExitWindowsEx(Flags, 0)
End Sub

'================================================================
'=
'================================================================
Declare Sub RebootNT(Force As Integer)
Sub RebootNT(Force As Integer)
    Var Flags As Long
    Var Ret As Long

    Flags = EWX_REBOOT
    If Force Then Flags = Flags + EWX_FORCE
    If IsWinNT Then EnableShutDown
    Ret = Api_ExitWindowsEx(Flags, 0)
End Sub

'================================================================
'=
'================================================================
Declare Sub LogOffNT(Force As Integer)
Sub LogOffNT(Force As Integer)
    Var Flags As Long
    Var Ret As Long

    Flags = EWX_LOGOFF
    If Force Then Flags = Flags + EWX_FORCE
    Ret = Api_ExitWindowsEx(Flags, 0)
End Sub

'================================================================
'=
'================================================================
Declare Sub Button1_on edecl ()
Sub Button1_on()
    A% = MessageBox(GetWindowText, "ログオフしますか?", 4, 1)
    If A% <> 5 Then Exit Sub
    LogOffNT True
End Sub

'================================================================
'=
'================================================================
Declare Sub Button2_on edecl ()
Sub Button2_on()
    A% = MessageBox(GetWindowText, "再起動しますか?", 4, 1)
    If A% <> 5 Then Exit Sub
    RebootNT True
End Sub

'================================================================
'=
'================================================================
Declare Sub Button3_on edecl ()
Sub Button3_on()
    A% = MessageBox(GetWindowText, "シャットダウンしますか?", 4, 1)
    If A% <> 5 Then Exit Sub
    ShutDownNT True
End Sub

'================================================================
'=
'================================================================
While 1
    WaitEvent
Wend
Stop
End