Basic Univers

; this code send a Shutdownmessage to a local or remote computer running Windows NT.


#SE_SHUTDOWN_NAME                         = "SeShutdownPrivilege"
#SE_REMOTE_SHUTDOWN_NAME                  = "SeRemoteShutdownPrivilege"

InitNetwork()

Procedure.l IPF_EnablePrivilege(Privilege.s, Enable.l = 1)
  Protected Res.l
  Protected hToken.l, hProcess.l
  Protected tTP.TOKEN_PRIVILEGES, tTPOld.TOKEN_PRIVILEGES, lTpOld.l
  Protected Success.l
  
  Res = LookupPrivilegeValue_(0, Privilege, @tLUID.LUID)
  If Res
    hProcess = GetCurrentProcess_()
    If hProcess
      Res = OpenProcessToken_(hProcess, #TOKEN_ADJUST_PRIVILEGES | #TOKEN_QUERY, @hToken)
      If Res
        With tTP
          \PrivilegeCount = 1
          If Enable
            \Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
          Else
            \Privileges[0]\Attributes = 0
          EndIf
          \Privileges[0]\Luid\lowpart = tLUID\lowpart
          \Privileges[0]\Luid\highpart = tLUID\highpart
        EndWith
        Res = AdjustTokenPrivileges_(hToken, 0, @tTP, SizeOf(tTP), @tTPOld, @lTpOld)
        If Res
          Success = 1
        EndIf
        CloseHandle_(hToken)
      EndIf
    EndIf
  EndIf
  
  If Success
    If Enable
      Debug Privilege +" enabled"
    Else
      Debug Privilege +" disabled"
    EndIf
  Else
    If Enable
      Debug Privilege +" not enabled"
    Else
      Debug Privilege +" not disabled"
    EndIf
  EndIf
  
  ProcedureReturn Success
EndProcedure

Procedure.l InitiateSystemShutdown(MachineName$ = "", Message$ = "", Timeout.l = 10, ForceAppsClosed.b = 0, RebootAfterShutdown.b = 0)
  ; InitiateSystemShutdown Function
  ; http://msdn2.microsoft.com/en-us/library/aa376873.aspx
  
  Protected AdvapiDLL, Res, *Msg, Privilege.s
  
  ; Test OK on WinNT4 - SP6 / WinXP - SP2
  If OSVersion()=#PB_OS_Windows_95 Or OSVersion()=#PB_OS_Windows_98 Or OSVersion()=#PB_OS_Windows_ME
    ProcedureReturn 0
  EndIf
  
  If UCase(MachineName$)= UCase(Hostname()) Or MachineName$ = ""
    Privilege = #SE_SHUTDOWN_NAME
  Else
    Privilege = #SE_REMOTE_SHUTDOWN_NAME
  EndIf
  
  If IPF_EnablePrivilege(Privilege)
    AdvapiDLL = OpenLibrary(#PB_Any, "Advapi32.dll")
    If AdvapiDLL
      *Machine = 0
      If MachineName$<>""
        *Machine =@MachineName$
      EndIf
      *Msg = 0
      If Message$<>""
        *Msg =@Message$
      EndIf
      
      CompilerIf #PB_Compiler_Unicode
      Res = CallFunction(AdvapiDLL, "InitiateSystemShutdownW", *Machine, *Msg, Timeout, ForceAppsClosed, RebootAfterShutdown)
      CompilerElse
      Res = CallFunction(AdvapiDLL, "InitiateSystemShutdownA", *Machine, *Msg, Timeout, ForceAppsClosed, RebootAfterShutdown)
      CompilerEndIf
      
      CloseLibrary(AdvapiDLL)
    EndIf
    IPF_EnablePrivilege(Privilege, 0)
  EndIf
  
  ProcedureReturn Res
EndProcedure

Procedure AbortSystemShutdown(MachineName$ = "")
  ; AbortSystemShutdown Function
  ; http://msdn2.microsoft.com/en-us/library/aa376630.aspx
  
  Protected AdvapiDLL, Res, Privilege.s
  
  ; Test OK on WinNT4 - SP6 / WinXP - SP2
  If OSVersion()=#PB_OS_Windows_95 Or OSVersion()=#PB_OS_Windows_98 Or OSVersion()=#PB_OS_Windows_ME
    ProcedureReturn 0
  EndIf
  
  If UCase(MachineName$)= UCase(Hostname()) Or MachineName$ = ""
    Privilege = #SE_SHUTDOWN_NAME
  Else
    Privilege = #SE_REMOTE_SHUTDOWN_NAME
  EndIf
  
  If IPF_EnablePrivilege(Privilege)
    AdvapiDLL = OpenLibrary(#PB_Any, "Advapi32.dll")
    If AdvapiDLL
      *Machine = 0
      If MachineName$<>""
        *Machine =@MachineName$
      EndIf
      
      CompilerIf #PB_Compiler_Unicode
      Res = CallFunction(AdvapiDLL, "AbortSystemShutdownW", *Machine)
      CompilerElse
      Res = CallFunction(AdvapiDLL, "AbortSystemShutdownA", *Machine)
      CompilerEndIf
      
      CloseLibrary(AdvapiDLL)
    EndIf
    IPF_EnablePrivilege(Privilege, 0)
  EndIf
  
  ProcedureReturn Res
EndProcedure

MachineName$ = "C266"
Message$ = "PureBasic shutdown test"
Timeout.l = 10
ForceAppsClosed.b = 1
RebootAfterShutdown.b = 1
InitiateSystemShutdown(MachineName$, Message$, Timeout, ForceAppsClosed, RebootAfterShutdown)
Delay(1000)
AbortSystemShutdown(MachineName$)