Jump to content

Preventing A Software Shutdown/logoff/restart


 Share

Recommended Posts

So far, I've tried identifying the window name of the "window" by classname you're trapped in when clicking the start menu, and then the "Turn off" button...

#NoTrayIcon
Opt("WinTitleMatchMode",4)
while 1
if WinActive("classname=Shell_TrayWnd") then WinKill("last")
wend

My explorer.exe promptly crashed afterwards..I'm looking for other ways of solving the problem...Pixel checks are not a viable solution, because different machines have different positions of pixels according to settings...etc..

I've also tried setting a shutdown with a large timer, keeping my fingers crossed that somehow, a shutdown cannot commence while another one is in progress...Course...that didn't work, because it seems that windows uses something else beside its nice shutdown.exe utility...I'm all out of ideas...Help me out..

Quote

Together we might liveDivided we must fall

 

Link to comment
Share on other sites

This is my code so far, and it doesn't work...

Global $WM_QUERYENDSESSION=0x0011
Func InterceptShutdown($hWnd,$msg,$w,$l)
Return 0
EndFunc
GUIRegisterMsg($WM_QUERYENDSESSION,"InterceptShutdown")
while 1
wend

Problem is, I'm not seeing any other way of returning false...

Edited by VicTT
Quote

Together we might liveDivided we must fall

 

Link to comment
Share on other sites

Update..tried:

Global $WM_QUERYENDSESSION=0x0011,$WM_CANCELMODE=0x001F
Func InterceptShutdown($hWnd,$msg,$w,$l)
Return $WM_CANCELMODE
EndFunc
GUIRegisterMsg($WM_QUERYENDSESSION,"InterceptShutdown")
while 1
wend

Would SendMessage be the way of doing it, and if so..WHO am I sending the message to?

Quote

Together we might liveDivided we must fall

 

Link to comment
Share on other sites

Unfortunately not...We're not talking about timed shutdowns, which can be canceled via shutdown -a...:think:..Thanks for trying to help me, though...If you get any ideas on how to do it the message-handler way, please tell me...you or any other WM guru...

Quote

Together we might liveDivided we must fall

 

Link to comment
Share on other sites

Normally, use of switches prevents software from restarting the system.

If you want to cancel the message sent, then you can only try and see what you can come up with. I believe it has been mentioned before over the sent shutdown message being unstoppable, but my memory is vague on it. Perhaps the sent message can be blocked in the 1st place.

Link to comment
Share on other sites

When Windows is about to shut down, it sends a WM_QueryEndSession to all open applications. To detect (and prevent shutdown) , we must define a message handler to this message. Put this definition on the private section of the main form:

~~~~~~~~~~~~~~~~~~~~~~~~~

procedure WMQueryEndSession

(var Msg : TWMQueryEndSession) ;

message WM_QueryEndSession;

~~~~~~~~~~~~~~~~~~~~~~~~~

Also, to prevent Windows shutting down put this method in the implementation section of the unit:

~~~~~~~~~~~~~~~~~~~~~~~~~

procedure TForm1.WMQueryEndSession

(var Msg : TWMQueryEndSession) ;

begin

if MessageDlg('Close Windows ?',

mtConfirmation,

[mbYes,mbNo], 0) = mrNo then

Msg.Result := 0

else

Msg.Result := 1 ;

end;

~~~~~~~~~~~~~~~~~~~~~~~~~

How do I get the HWnd of the window that sent the WMQueryEndSession message, so that I can reply with a SendMessage CancelMode?

There must be a "system" window sending the message, that can be identified through title or classname means, so that I can get its handle, and SendMessage the result=0..or, $WM_CANCELMODE...

Worst-case scenario, I get all HWnd's and SendMessage to all...

w0uter:

Help me get the show on the road..Translating from OOP to AutoIt is proving harder than it never seemed...

So..question to the devs...

HOW DO I REPLY TO A CERTAIN MESSAGE?It was my belief that it automagically used the Return value of the message-handler function...

Quote

Together we might liveDivided we must fall

 

Link to comment
Share on other sites

Global $SE_SHUTDOWN_NAME="SeShutdownPrivilege"
Func SetPrivilege( $privilege, $bEnable )
    Const $TOKEN_ADJUST_PRIVILEGES = 0x0020
    Const $TOKEN_QUERY = 0x0008
    Const $SE_PRIVILEGE_ENABLED = 0x0002
    Local $hToken, $SP_auxret, $SP_ret, $hCurrProcess, $nTokens, $nTokenIndex, $priv
    $nTokens = 1
    $LUID = DLLStructCreate("dword;int")
    If IsArray($privilege) Then $nTokens = UBound($privilege)
    $TOKEN_PRIVILEGES = DLLStructCreate("dword;dword[" & (3 * $nTokens) & "]")
    $NEWTOKEN_PRIVILEGES = DLLStructCreate("dword;dword[" & (3 * $nTokens) & "]")
    $hCurrProcess = DLLCall("kernel32.dll","hwnd","GetCurrentProcess")
    $SP_auxret = DLLCall("advapi32.dll","int","OpenProcessToken","hwnd",$hCurrProcess[0], _
                "int",BitOR($TOKEN_ADJUST_PRIVILEGES,$TOKEN_QUERY),"int_ptr",0)
    If $SP_auxret[0] Then
        $hToken = $SP_auxret[3]
        DLLStructSetData($TOKEN_PRIVILEGES,1,1)
        $nTokenIndex = 1
        While $nTokenIndex <= $nTokens
            If IsArray($privilege) Then
                $priv = $privilege[$nTokenIndex-1]
            Else
                $priv = $privilege
            EndIf
            $ret = DLLCall("advapi32.dll","int","LookupPrivilegeValue","str","","str",$priv, _
                        "ptr",DLLStructGetPtr($LUID))
            If $ret[0] Then
                If $bEnable Then
                    DLLStructSetData($TOKEN_PRIVILEGES,2,$SE_PRIVILEGE_ENABLED,(3 * $nTokenIndex))
                Else
                    DLLStructSetData($TOKEN_PRIVILEGES,2,0,(3 * $nTokenIndex))
                EndIf
                DLLStructSetData($TOKEN_PRIVILEGES,2,DllStructGetData($LUID,1),(3 * ($nTokenIndex-1)) + 1)
                DLLStructSetData($TOKEN_PRIVILEGES,2,DllStructGetData($LUID,2),(3 * ($nTokenIndex-1)) + 2)
                DLLStructSetData($LUID,1,0)
                DLLStructSetData($LUID,2,0)
            EndIf
            $nTokenIndex += 1
        WEnd
        $ret = DLLCall("advapi32.dll","int","AdjustTokenPrivileges","hwnd",$hToken,"int",0, _
            "ptr",DllStructGetPtr($TOKEN_PRIVILEGES),"int",DllStructGetSize($NEWTOKEN_PRIVILEGES), _
            "ptr",DllStructGetPtr($NEWTOKEN_PRIVILEGES),"int_ptr",0)
        $f = DLLCall("kernel32.dll","int","GetLastError")
    EndIf
    $NEWTOKEN_PRIVILEGES=0
    $TOKEN_PRIVILEGES=0
    $LUID=0
    If $SP_auxret[0] = 0 Then Return 0
    $SP_auxret = DLLCall("kernel32.dll","int","CloseHandle","hwnd",$hToken)
    If Not $ret[0] And Not $SP_auxret[0] Then Return 0
    return $ret[0]
EndFunc
SetPrivilege($SE_SHUTDOWN_NAME,1)
while 1
Dllcall("advapi32.dll","int","AbortSystemShutdown","str","")
wend

@Larry

So the following code, would abort any shutdown initiated after the program started running, is that correct?

Quote

Together we might liveDivided we must fall

 

Link to comment
Share on other sites

I can't further stress the fact that AbortSystemShutDown WORKS ONLY FOR TIMED SHUTDOWNS!!!

While the program above is running, if I am to click start-->Turn off-->Shutdown, the program fails to stop the shutdown...If I am to shutdown -s -f -t 30, then the program stops it...

Can anyone understand my problem?AbortSystemShutDown is not the answer here!

THIS IS:

When Windows is about to shut down, it sends a WM_QueryEndSession to all open applications. To detect (and prevent shutdown) , we must define a message handler to this message. Put this definition on the private section of the main form:

~~~~~~~~~~~~~~~~~~~~~~~~~

procedure WMQueryEndSession

(var Msg : TWMQueryEndSession) ;

message WM_QueryEndSession;

~~~~~~~~~~~~~~~~~~~~~~~~~

Also, to prevent Windows shutting down put this method in the implementation section of the unit:

~~~~~~~~~~~~~~~~~~~~~~~~~

procedure TForm1.WMQueryEndSession

(var Msg : TWMQueryEndSession) ;

begin

if MessageDlg('Close Windows ?',

mtConfirmation,

[mbYes,mbNo], 0) = mrNo then

Msg.Result := 0

else

Msg.Result := 1 ;

end;

~~~~~~~~~~~~~~~~~~~~~~~~~

Let's put it all in pseudo-code, shall we?

While 1
if Check_For_WMQueryEndSession_Message()=1 then Send_Message($originating_HWND,$WM_CANCELMODE)
While End

The check is made via message-handler (GUIRegisterMsg) as I have said in the 1st posts..

QUOTE:

Global $WM_QUERYENDSESSION=0x0011,$WM_CANCELMODE=0x001F

Func InterceptShutdown($hWnd,$msg,$w,$l)

Return $WM_CANCELMODE

EndFunc

GUIRegisterMsg($WM_QUERYENDSESSION,"InterceptShutdown")

while 1

wend

My question is...HOW DO I SEND THE PROCESS THAT SENT THE SCRIPT A $WM_QUERYENDSESSION A RESPONSE, AND IN THIS CASE, $WM_CANCELMODE?

DO I USE SENDMESSAGE?

CAN I SOMEHOW RETURN THE VALUE, AS I HAVE ATTEMPTED ABOVE?

LOOK AT THE DELPHI EXAMPLE ABOVE...IT USES NO ABORTSYSTEMSHUTDOWN, BUT IT RETURNS "0" TO THE CALLING PROCESS...

Quote

Together we might liveDivided we must fall

 

Link to comment
Share on other sites

Ok I have been trying to help you but IF this can be done in AutoIT I have no idea how. If someone who understands AutoIT extremly well and happens to know VB takes a look at this...

http://www.vbaccelerator.com/home/VB/Tips/...own/article.asp

perhaps they can translate. I understand what is going on from the VB standpoint; but how to pull this off within the confines of AutoIt is beyond me as well.

I don't know what you need this for in general terms (to lock down users, to protect yourself, etc.) but this may also fulfill your requirements. -> http://www.shutdownlock.com

Until then I hope someone can translate that VB code in to Auto-It or know if it is possible to translate.

EDIT:

If all you want to do is prevent users from shutting down the machine you could just do this.

while 1
If WinExists ("Shut Down Windows","") Then
    ControlClick("Shut Down Windows", "", "Button4")
EndIf
WEnd

But I am guessing you want something more powerful then that...

Edited by NightGaunt
"I have discovered that all human evil comes from this, man's being unable to sit still in a room. " - Blaise Pascal
Link to comment
Share on other sites

Ya know I figured that'd be the answer, course with the link he could just switch over to VB for this code; and call AutoIt for other functions as a wrapper...

"I have discovered that all human evil comes from this, man's being unable to sit still in a room. " - Blaise Pascal
Link to comment
Share on other sites

Sigh..Sorry Larry...didn't mean to sound like a total moron..(maybe just a little: for good measure)...How do-able is the SendMessage thing?

@NightGaunt:

The script does not work under Windows XP SP1...at least not on MY SP1...My first post mentioned that I have attempted to use AutoIt Window Information to get the title of the window, or any other info to aid in its detection...Unfortunately, the window has NO title..It only has a classname that is always present, and cannot be used to detect the spawning of the window...

Pixel Checks cannot be used, since different machines yield different colors(as a result of different settings)...

Quote

Together we might liveDivided we must fall

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...