Shutdown Local/Remote Computers (Windows only)
Posted: Sat Nov 17, 2007 9:51 pm
Hi,
this code send a Shutdownmessage to a local or remote computer running Windows NT.
[Edit]
- added descriptions of the routines
- added debug output when an error occurs
this code send a Shutdownmessage to a local or remote computer running Windows NT.
Code: Select all
#SE_SHUTDOWN_NAME = "SeShutdownPrivilege"
#SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege"
InitNetwork()
Procedure.s GetLastError(Err.l)
Protected buffer.l=0,ferr.l,errormsg$=""
ferr=FormatMessage_(#FORMAT_MESSAGE_ALLOCATE_BUFFER|#FORMAT_MESSAGE_FROM_SYSTEM,0,Err,GetUserDefaultLangID_(),@buffer,0,0)
If buffer<>0
errormsg$=PeekS(buffer)
LocalFree_(buffer)
errormsg$=RemoveString(errormsg$,Chr(13)+Chr(10))
EndIf
ProcedureReturn errormsg$
EndProcedure
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
Err=GetLastError_()
If Enable
Debug Privilege+" not enabled ("+GetLastError(Err)+")"
Else
Debug Privilege+" not disabled ("+GetLastError(Err)+")"
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
;ABBKlaus on 17.11.2007
;
;Usage :
;
;Err.l=InitiateSystemShutdown([MachineName$,[Message$,[Timeout,[ForceAppsClosed,[RebootAfterShutdown]]]]])
;
;Parameters :
;
;MachineName$
; The network name of the computer to be shut down.
; If MachineName$ is an empty string, the function shuts down the local computer.
;Message$
; The message to be displayed in the shutdown dialog box.
; This parameter can be an empty string if no message is required.
;Timeout
; The length of time that the shutdown dialog box should be displayed, in seconds.
;ForceAppsClosed
; If this parameter is TRUE, forces all open applications to close.
;RebootAfterShutdown
; If this parameter is TRUE, the computer is to restart immediately after shutting down.
;
;Return value :
; If the function succeeds, the return value is zero.
; If the wrong OS is used the function returns -1.
; If the function fails, the return value is an system error code.
Protected AdvapiDLL,*Msg,Privilege.s,Res.l=0
;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 -1
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
If Res
Res=0
Else
Res=GetLastError_()
EndIf
CloseLibrary(AdvapiDLL)
EndIf
IPF_EnablePrivilege(Privilege,0)
Else
Res=GetLastError_()
EndIf
ProcedureReturn Res
EndProcedure
Procedure.l AbortSystemShutdown(MachineName$="")
;AbortSystemShutdown Function
;http://msdn2.microsoft.com/en-us/library/aa376630.aspx
;ABBKlaus on 17.11.2007
;
;Usage :
;
;Err.l=AbortSystemShutdown([MachineName$])
;
;Parameters :
;
;MachineName$
; The network name of the computer where the shutdown is to be stopped.
; If lpMachineName is an empty string, the function stops the shutdown on the local computer.
;
;Return value :
; If the function succeeds, the return value is zero.
; If the wrong OS is used the function returns -1.
; If the function fails, the return value is an system error code.
Protected AdvapiDLL,Privilege.s,Res.l=0
;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 -1
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
If Res
Res=0
Else
Res=GetLastError_()
EndIf
CloseLibrary(AdvapiDLL)
EndIf
IPF_EnablePrivilege(Privilege,0)
Else
Res=GetLastError_()
EndIf
ProcedureReturn Res
EndProcedure
; Demo code
MachineName$=""
Message$="PureBasic shutdown test"
Timeout.l=10
ForceAppsClosed.b=1
RebootAfterShutdown.b=1
Res=InitiateSystemShutdown(MachineName$,Message$,Timeout,ForceAppsClosed,RebootAfterShutdown)
If Res=0
Delay(1000)
If AbortSystemShutdown(MachineName$)
Debug GetLastError(Res)
EndIf
Else
Debug GetLastError(Res)
EndIf
- added descriptions of the routines
- added debug output when an error occurs