Share this page 

Shutdown from applicationTag(s): WinAPI/Registry


[PB external function declaration]
FUNCTION boolean ExitWindowsEx(ulong uFlags, long dwReserved ) &
   LIBRARY 'user32.dll'


[Powerscript]
ulong EWX_LOGOFF   = 0
ulong EWX_SHUTDOWN = 1
ulong EWX_REBOOT   = 2

ExitWindowsEx(EWX_REBOOT, 0)
NOTE: While you can shutdown from an application in Win95, you can't with WinNT. You need to call first the AdjustTokenPrivileges API function to grant the current process to right to shutdown the workstation.
[structure definitions]
luid
        unsignedlong    lowpart
        long            highpart

luid_and_attributes
        luid            pluid
        long            attributes

token_privileges
        long            privilegecount
        luid_and_attributes  privileges


[functions declaration]

Function long OpenProcessToken &
 (long ProcessHandle, long DesiredAccess, ref long TokenHandle) &
   Library "ADVAPI32.DLL"
Function long GetCurrentProcess () Library "kernel32"
Function long LookupPrivilegeValue &
  (string lpSystemName,  string lpName, ref LUID lpLUID) &
  Library "ADVAPI32.DLL" Alias for "LookupPrivilegeValueA"
Function long AdjustTokenPrivileges &
  (long TokenHandle, long DisableAllPrivileges, &
   ref TOKEN_PRIVILEGES newstate, long BufferLength, &
   ref TOKEN_PRIVILEGES PreviousState, ref long ReturnLength) &
  Library "ADVAPI32.DLL"
Function long CloseHandle (long hObject) Library "kernel32"
FUNCTION long ExitWindowsEx(uint Flags, long dwReserved) &
  LIBRARY "User32.dll"

[Powerscript]
Constant string SE_SHUTDOWN_NAME = "SeShutdownPrivilege"

Constant long SE_PRIVILEGE_ENABLED = 2
Constant long TOKEN_ADJUST_PRIVILEGES = 32
Constant long TOKEN_QUERY = 8

CONSTANT long TokenDefaultDacl = 6
CONSTANT long TokenGroups = 2
CONSTANT long TokenImpersonationLevel = 9
CONSTANT long TokenOwner = 4
CONSTANT long TokenPrimaryGroup = 5
CONSTANT long TokenPrivileges = 3
CONSTANT long TokenSource = 7
CONSTANT long TokenStatistics = 10
CONSTANT long TokenType = 8
CONSTANT long TokenUser = 1

CONSTANT INTEGER EWX_LOGOFF = 0
CONSTANT INTEGER EWX_SHUTDOWN = 1
CONSTANT INTEGER EWX_REBOOT = 2
CONSTANT INTEGER EWX_FORCE = 4


// author Philip Salgannik
LUID tLUID
ULong hProcess
Long hToken
TOKEN_PRIVILEGES tTPOld,  tTP
Long lTpOld, lR, ll_size
string ls_null
boolean NTEnableShutDown

SetNull(ls_null)

lR = LookupPrivilegeValue(ls_null, SE_SHUTDOWN_NAME, tLUID)

IF (lR <> 0) THEN
    // Get the current process handle:
    hProcess = GetCurrentProcess()
    IF (hProcess <> 0) THEN
       lR = OpenProcessToken &
               (hProcess, TOKEN_ADJUST_PRIVILEGES + TOKEN_QUERY, hToken)
        IF (lR <> 0) THEN
           //Ok we can now adjust the shutdown priviledges:
           tTP.PrivilegeCount = 1
           tTP.Privileges.Attributes = SE_PRIVILEGE_ENABLED
           tTP.Privileges.pLuid.HighPart = tLUID.HighPart
           tTP.Privileges.pLuid.LowPart = tLUID.LowPart

           //Now allow this process to shutdown the system:
           ll_size = 16 //sizeof(tTP)
           lR = AdjustTokenPrivileges&
                  (hToken, 0, tTP, ll_size, tTPOld, lTpOld)
           IF (lR <> 0) THEN
              NTEnableShutDown = True
           ELSE
              MessageBox &
               ("Error", "You do not have the privileges to shutdown")
           END IF
           CloseHandle(hToken)
        END IF
    END IF
END IF

IF NOT NTEnableShutDown THEN RETURN

lR = ExitWindowsEx(ewx_shutdown, 0)
IF (lR = 0) THEN
   MessageBox("Error", "ShutdownSystem failed")
   RETURN
ELSE
   RETURN
END IF