Announcement

Collapse
No announcement yet.

Is there a way to stop a reboot/shutdown?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Mike Doty
    replied
    Good catch.
    I'll add some code that uses the current running program title and test with Vista while at it.

    Leave a comment:


  • Dave Biggs
    replied
    Glad you have what you need Mike but FYI your code didn't prevent my PC (WinXP Home) from rebooting.
    I don't have a window with "END PROGRAM" in the title though..

    Leave a comment:


  • Mike Doty
    replied
    Thanks, Dave. I have working code and posted it above.

    Leave a comment:


  • Dave Biggs
    replied
    Mike,

    I fixed the sample code http://www.powerbasic.com/support/pb...ION#post300982 so that it doesn't close the message box after 3seconds.

    If you add these three functions to your TCP program and insert the Case statements into it's DialogProc that might be all you need?
    Code:
    %SHTDN_REASON_FLAG_USER_DEFINED = &H40000000
     
    FUNCTION IsNt () AS LONG
     LOCAL tOsVersion AS OSVERSIONINFO
      tOsVersion.dwOSVersionInfoSize = SIZEOF(tOsVersion)
      IF GetVersionEx(tOsVersion) THEN
          FUNCTION = (tOsVersion.dwPlatformId = %VER_PLATFORM_WIN32_NT)
      END IF
    END FUNCTION
    '------------------/IsNt
     
    FUNCTION AdjustToken () AS LONG
     LOCAL hToken       AS DWORD
     LOCAL tokenProcess AS TOKEN_PRIVILEGES
        ' Get the privilege token for this process. - keep in hToken
      IF ISFALSE OpenProcessToken(GetCurrentProcess(), %TOKEN_ADJUST_PRIVILEGES OR %TOKEN_QUERY, hToken) THEN
        EXIT FUNCTION
      END IF
        ' Get the value of the shutdown privilege.
      IF LookupPrivilegeValue(BYVAL %NULL, "SeShutdownPrivilege", tokenProcess.Privileges(0).pLuid) THEN
        ' Enable the shutdown privilege for this process.
        tokenProcess.PrivilegeCount           = 1
        tokenProcess.Privileges(0).Attributes = %SE_PRIVILEGE_ENABLED
        FUNCTION = AdjustTokenPrivileges(hToken, %FALSE, tokenProcess, 0, BYVAL %NULL, BYVAL %NULL)
      END IF
     CloseHandle hToken
    END FUNCTION
    '------------------/AdjustTken
     
    FUNCTION ResumeShutDown(BYVAL LogOff AS LONG) AS LONG
      IF IsNT() THEN
        IF ISFALSE AdjustToken() THEN
          MSGBOX "Could not obtain shutdown privilege."
          EXIT FUNCTION
        END IF
      END IF
        ' If you're using Windows XP or later, you may want to provide a shutdown
        ' reason code in the second parameter. See the Reason.inc file for codes.
        ' The major reason code should be ORed with the minor reason code.
        ' eg %SHTDN_REASON_FLAG_USER_DEFINED  = &H40000000
      IF LogOff = 0 THEN
        IF ISFALSE ExitWindowsEx(%EWX_SHUTDOWN OR %EWX_FORCEIFHUNG, %SHTDN_REASON_FLAG_USER_DEFINED) THEN
            MSGBOX "Shutdown failed."
        END IF
      ELSE
        IF ISFALSE ExitWindowsEx(%EWX_LOGOFF, 0) THEN
            MSGBOX "Shutdown failed."
        END IF
      END IF
    END FUNCTION
    '------------------/ResumeShutDown
     
    CALLBACK FUNCTION DlgProc
      DIM Res AS LONG
      STATIC ThisProc, LogOff AS Long 
    '..
      SELECT CASE AS LONG CbMsg
    '..
     
          CASE %WM_QUERYENDSESSION
            IF ThisProc = 0 THEN
              ThisProc = %TRUE          ' Test for resume shutdown
              LogOff = IIF(CblParam AND %ENDSESSION_LOGOFF = %ENDSESSION_LOGOFF, 1, 0)
              PostMessage CbHndl, %WM_USER + 1000, 0, 0
              FUNCTION = 0              ' Stop the shutdown process
              EXIT FUNCTION
            END IF
     
          CASE %WM_USER + 1000
            MSGBOX TIME$ & ": Prevented ShutDown."
     
            ' Here you could wait for your TCP thread to end...
     
            Res = MSGBOX ("Resume Shutdown / LogOff?", %MB_YESNO OR %MB_SYSTEMMODAL _    ' / logoff
                     OR %MB_ICONWARNING OR %MB_DEFBUTTON2, "Ready to quit?")
            IF Res = %IDYES THEN
              ResumeShutDown (LogOff)
            ELSE
              ThisProc = 0
              LogOff = 0
     
      END SELECT
    END FUNCTION
    '------------------/DlgProc
    That will enable the shutdown privilege too, if required.

    Leave a comment:


  • Mike Doty
    replied
    I posted code tested with DDT. PB 9 and XP SP3.
    What did you test with?
    Just exiting that way does not stop shutdown.

    Leave a comment:


  • Michael Mattias
    replied
    >This code is to prevent reboot if say a file download is in progress.


    Now I am really confused.

    If the file download is in your program and you have a global variable indicating a download is in progress, then all you should have to do on WM_QUERYENDSESSION is check that variable and exit with %TRUE or %FALSE as appropriate.

    If some other program is NOT checking WM_QUERYENDSESSION during its file downloads, I'd get a new download program.

    MCM

    Leave a comment:


  • Mike Doty
    replied
    Stop reboot - also closes End Program window

    *** SOLVED PROBLEM This code works correctly. Thread may be closed. Thank you. ***
    This code is to prevent reboot if say a file download is in progress.
    This sniplet shows a global is set so reboot should not be allowed.
    Code:
    CASE %WM_QUERYENDSESSION
      IF gBusy THEN
        SLEEP 8000 'normally between 5 and 6 seconds
        DIALOG DOEVENTS
        result = EnumWindows(CODEPTR(EnumWindowsProc), 0)
      END IF 
     
    EnumWindows uses this logic:
    IF UCASE$(LEFT$(zTitle,11)) = "END PROGRAM" THEN
        PostMessage(lHandle, %WM_CLOSE,0,0) 'WM_QUIT doesn't work
    'Here is a completed working test program
    Code:
    #PBFORMS CREATED V1.52
    #COMPILE EXE
    #DIM ALL
    #PBFORMS BEGIN INCLUDES
    #IF NOT %DEF(%WINAPI)
        #INCLUDE "WIN32API.INC"
    #ENDIF
    #PBFORMS END INCLUDES
    #PBFORMS BEGIN CONSTANTS
    %IDD_DIALOG1 = 101
    #PBFORMS END CONSTANTS
    DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
    DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
    #PBFORMS DECLARATIONS
    FUNCTION PBMAIN()
        ShowDIALOG1 %HWND_DESKTOP
    END FUNCTION
    CALLBACK FUNCTION ShowDIALOG1Proc()
        SELECT CASE AS LONG CBMSG
            CASE %WM_QUERYENDSESSION
              SLEEP 8000  'normally between 5 and 6 seconds
              EnumWindows CODEPTR(EnumWindowsProc), 0
     
            CASE %WM_INITDIALOG
                ' Initialization handler
            CASE %WM_NCACTIVATE
                STATIC hWndSaveFocus AS DWORD
                IF ISFALSE CBWPARAM THEN
                    ' Save control focus
                    hWndSaveFocus = GetFocus()
                ELSEIF hWndSaveFocus THEN
                    ' Restore control focus
                    SetFocus(hWndSaveFocus)
                    hWndSaveFocus = 0
                END IF
            CASE %WM_COMMAND
                ' Process control notifications
                SELECT CASE AS LONG CBCTL
                END SELECT
        END SELECT
    END FUNCTION
    '------------------------------------------------------------------------------
    '------------------------------------------------------------------------------
    '   ** Dialogs **
    '------------------------------------------------------------------------------
    FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt AS LONG
    #PBFORMS BEGIN DIALOG %IDD_DIALOG1->->
        LOCAL hDlg  AS DWORD
        DIALOG NEW hParent, "%WM_QUERYENDSESSION NOT ALLOWING REBOOT", 206, 164, 201, 121, %WS_POPUP OR _
            %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_CLIPSIBLINGS OR _
            %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
            %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR _
            %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
    #PBFORMS END DIALOG
        DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt
    #PBFORMS BEGIN CLEANUP %IDD_DIALOG1
    #PBFORMS END CLEANUP
        FUNCTION = lRslt
    END FUNCTION
    '------------------------------------------------------------------------------
    FUNCTION EnumWindowsProc(BYVAL lHandle AS LONG, BYVAL lNotUsed AS LONG) AS LONG
      LOCAL result AS LONG
      LOCAL zTitle AS ASCIIZ * 256
      GetWindowText lHandle, zTitle, 256
      zTitle  = EXTRACT$(zTitle,$NUL)
      IF UCASE$(LEFT$(zTitle,11)) = "END PROGRAM" THEN
        PostMessage(lHandle, %WM_CLOSE,0,0) 'WM_QUIT doesn't work with End Program shutdown
        SLEEP 10   'required
        DIALOG DOEVENTS
        FUNCTION = 0
        EXIT FUNCTION
      END IF
      FUNCTION = 1  'keep looking or signals done
    END FUNCTION
    Last edited by Mike Doty; 24 Nov 2008, 09:21 AM.

    Leave a comment:


  • Michael Mattias
    replied
    >I'm getting the handle to the End Program dialog and sending...

    ???
    The shutdown sequence is ended...
    The WM_QUERYENDSESSION message is sent when the user chooses to end the session or when an application calls the ExitWindows function. If any application returns zero, the session is not ended. The system stops sending WM_QUERYENDSESSION messages as soon as one application returns zero.
    I don't understand what you are trying to accomplish here. Returning zero in response to WM_QUERYENDSESSION should be all you need to do to terminate the shutdown sequence.

    If other applications choose to use another mechanism...

    Code:
          CASE %WM_QUERYENDSESSION
             bQuit =  ISTRUE (MSGBOX (question) = %IDYES )
             FUNCTION =  ISTRUE (bQuit) 
             EXIT FUNCTION
    ... there is nothing you can do about that unless you can respond the the message box or other prompt.

    Only thing I can think of which might be interfering with this would be, maybe your process needs certain permissions to "terminate the Windows' shutdown sequence"

    Leave a comment:


  • Mike Doty
    replied
    Can End Program dialog be closed with PostMessage?

    I'm getting the handle to the End Program dialog and sending
    x = PostMessage(gShutDownHandle, %WM_QUIT,0,0) 'returns 1
    'This doesn't close the End Program dialog. How would it be done?
    'Is %WM_QUIT the correct message to send
    'Is this the correct windows handle?

    Tried modifying the code to shutdown NOTEPAD and it does shut NOTEPAD so
    the code might be close to ending the shutdown dialog?

    Tried SendMessage without luck, too.
    I'll try sending ALT+F4 next.



    Code:
    CALLBACK FUNCTION MyCallBack()
      LOCAL x AS LONG
        SELECT CASE AS LONG CBMSG
          CASE %WM_QUERYENDSESSION
            SLEEP 10000  'wait for end program dialog
            EnumWindows CODEPTR(EnumWindowsProc), 0
            IF gShutDownHandle THEN
               x = PostMessage(gShutDownHandle, %WM_QUIT,0,0)
               ? "Result was" + STR$(x) 'returns 1
            END IF
            ? "Here as a safeguard" 
     
    FUNCTION EnumWindowsProc(BYVAL lHandle AS LONG, BYVAL lNotUsed AS LONG) AS LONG
      LOCAL result AS LONG
      gsTitle = STRING$(256,0)
      GetWindowText lHandle, BYVAL STRPTR(gsTitle), 256
      gsTitle = EXTRACT$(gsTitle,CHR$(0))
      IF UCASE$(LEFT$(gsTitle,11)) = "END PROGRAM" THEN
        gShutDownHandle = lHandle
        result = PostMessage(lHandle, %WM_QUIT,0,0)  'returns 1
        EXIT FUNCTION
      END IF
      FUNCTION = 1  'keep looking while 1
    END FUNCTION
    Last edited by Mike Doty; 24 Nov 2008, 06:23 AM.

    Leave a comment:


  • Mike Doty
    replied
    Dave,
    Your code works. It displays the first message box for 3-seconds which is better than my unpredictable results. It then allows not allowing
    the reboot. I will try the same method and get back. I'm not sure that
    my TCP session will be trashed in the process, but at least I can notify
    the user it wasn't completed.

    Michael DDT 9 modal.

    Leave a comment:


  • Michael Mattias
    replied
    Code:
    CASE %WM_QUERYENDSESSION
                 PostQuitMessage 0
    PostQuitMessag()? Here?

    "Normally " you'd post WM_QUIT on WM_DESTROY. That might be causing you some issues.

    For that matter if this is the callback for a MODAL dialog (code not shown) then PostQuitmessage is not required at all.

    Leave a comment:


  • Dave Biggs
    replied
    This might help..
    http://www.powerbasic.com/support/pb...ION#post300982

    Leave a comment:


  • Mike Doty
    started a topic Is there a way to stop a reboot/shutdown?

    Is there a way to stop a reboot/shutdown?

    This code might slow down a reboot, but won't prevent it.
    Using DDT with PB 9 on XP SP3. If TCP transfer is in progress
    it is halted (which is what I'm trying to complete.)

    Code:
    CALLBACK FUNCTION MyCallBack()
        SELECT CASE AS LONG CBMSG
             CASE %WM_QUERYENDSESSION
                 PostQuitMessage 0
                 FUNCTION = %TRUE     ' don't allow default action
                 'BEEP
                 'PostQuitMessage 0
                 'PostMessage CBHNDL, %WM_USER + 2049, 0, 0
                  'DoNotEnd
Working...
X