Announcement

Collapse
No announcement yet.

Is there a way to stop a reboot/shutdown?

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

  • 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
    The world is full of apathy, but who cares?

  • #2
    This might help..
    Rgds, Dave

    Comment


    • #3
      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.
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        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.
        The world is full of apathy, but who cares?

        Comment


        • #5
          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.
          The world is full of apathy, but who cares?

          Comment


          • #6
            >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"
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              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.
              The world is full of apathy, but who cares?

              Comment


              • #8
                >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
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  I posted code tested with DDT. PB 9 and XP SP3.
                  What did you test with?
                  Just exiting that way does not stop shutdown.
                  The world is full of apathy, but who cares?

                  Comment


                  • #10
                    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.
                    Rgds, Dave

                    Comment


                    • #11
                      Thanks, Dave. I have working code and posted it above.
                      The world is full of apathy, but who cares?

                      Comment


                      • #12
                        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..
                        Rgds, Dave

                        Comment


                        • #13
                          Good catch.
                          I'll add some code that uses the current running program title and test with Vista while at it.
                          The world is full of apathy, but who cares?

                          Comment

                          Working...
                          X