From f6ba47d9973bbb113257401b6eeb82b23da7acc4 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Sun, 5 May 2002 14:18:36 +0000
Subject: [PATCH] added wxShutdown (patch 547443)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@15383 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt           |  1 +
 docs/latex/wx/function.tex | 21 ++++++++++++
 include/wx/utils.h         |  9 +++++
 src/mac/carbon/utils.cpp   |  7 ++++
 src/mac/utils.cpp          |  7 ++++
 src/msw/utils.cpp          | 68 +++++++++++++++++++++++++++++++++++---
 src/os2/utils.cpp          |  7 ++++
 src/unix/utilsunx.cpp      | 23 +++++++++++++
 8 files changed, 139 insertions(+), 4 deletions(-)

diff --git a/docs/changes.txt b/docs/changes.txt
index 709fc6a11f..5808c49333 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -131,6 +131,7 @@ wxBase:
 - fixed the bug related to the redrawing on resize introduced in 2.3.2
 - added static wxFontMapper::Get() accessor (use of wxTheFontMapper is now
   deprecated)
+- added wxShutdown() function (Marco Cavallini)
 
 Unix (Base/GUI):
 
diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex
index 90d1f7f7a9..4ba9c2f115 100644
--- a/docs/latex/wx/function.tex
+++ b/docs/latex/wx/function.tex
@@ -196,6 +196,7 @@ the corresponding topic.
 \helpref{wxSetWorkingDirectory}{wxsetworkingdirectory}\\
 \helpref{wxShell}{wxshell}\\
 \helpref{wxShowTip}{wxshowtip}\\
+\helpref{wxShutdown}{wxshutdown}\\
 \helpref{wxSleep}{wxsleep}\\
 \helpref{wxSnprintf}{wxsnprintf}\\
 \helpref{wxSplitPath}{wxsplitfunction}\\
@@ -595,6 +596,26 @@ See also \helpref{wxExecute}{wxexecute}, \helpref{Exec sample}{sampleexec}.
 
 <wx/utils.h>
 
+\membersection{::wxShutdown}\label{wxshutdown}
+
+\func{bool}{wxShutdown}{\param{wxShutdownFlags}{flags}}
+
+This function shuts down or reboots the computer depending on the value of the 
+{\it flags}. Please notice that doing this requires the corresponding access
+rights (superuser under Unix, {\tt SE\_SHUTDOWN} privelege under Windows NT)
+and that this function is only implemented under Unix and Win32.
+
+\wxheading{Parameters}
+
+\docparam{flags}{Either {\tt wxSHUTDOWN\_POWEROFF} or {\tt wxSHUTDOWN\_REBOOT}}
+
+\wxheading{Returns}
+
+{\tt TRUE} on success, {\tt FALSE} if an error occured.
+
+\wxheading{Include files}
+
+<wx/utils.h>
 
 \section{Thread functions}\label{threadfunctions}
 
diff --git a/include/wx/utils.h b/include/wx/utils.h
index 9bca5317cb..73737d91dc 100644
--- a/include/wx/utils.h
+++ b/include/wx/utils.h
@@ -220,6 +220,15 @@ enum wxKillError
     wxKILL_ERROR            // another, unspecified error
 };
 
+enum wxShutdownFlags
+{
+    wxSHUTDOWN_POWEROFF,    // power off the computer
+    wxSHUTDOWN_REBOOT       // shutdown and reboot
+};
+
+// Shutdown or reboot the PC 
+WXDLLEXPORT bool wxShutdown(wxShutdownFlags wFlags);
+
 // send the given signal to the process (only NONE and KILL are supported under
 // Windows, all others mean TERM), return 0 if ok and -1 on error
 //
diff --git a/src/mac/carbon/utils.cpp b/src/mac/carbon/utils.cpp
index 4cd5021df4..90fff0dd64 100644
--- a/src/mac/carbon/utils.cpp
+++ b/src/mac/carbon/utils.cpp
@@ -139,6 +139,13 @@ bool wxShell(const wxString& command)
     return FALSE;
 }
 
+// Shutdown or reboot the PC 
+bool wxShutdown(wxShutdownFlags wFlags)
+{
+    // TODO
+    return FALSE;
+}
+
 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
 long wxGetFreeMemory()
 {
diff --git a/src/mac/utils.cpp b/src/mac/utils.cpp
index 4cd5021df4..90fff0dd64 100644
--- a/src/mac/utils.cpp
+++ b/src/mac/utils.cpp
@@ -139,6 +139,13 @@ bool wxShell(const wxString& command)
     return FALSE;
 }
 
+// Shutdown or reboot the PC 
+bool wxShutdown(wxShutdownFlags wFlags)
+{
+    // TODO
+    return FALSE;
+}
+
 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
 long wxGetFreeMemory()
 {
diff --git a/src/msw/utils.cpp b/src/msw/utils.cpp
index 2256d8fc5e..bfed9170c1 100644
--- a/src/msw/utils.cpp
+++ b/src/msw/utils.cpp
@@ -845,7 +845,7 @@ int wxKill(long pid, wxSignal sig, wxKillError *krc)
             return 0;
         }
     }
-#else // Win15
+#else // Win16
     wxFAIL_MSG( _T("not implemented") );
 #endif // Win32/Win16
 
@@ -875,6 +875,66 @@ bool wxShell(const wxString& command)
     return wxExecute(cmd, TRUE /* sync */) != 0;
 }
 
+// Shutdown or reboot the PC 
+bool wxShutdown(wxShutdownFlags wFlags)
+{
+#ifdef __WIN32__
+    bool bOK = TRUE;
+
+    if ( wxGetOsVersion(NULL, NULL) == wxWINDOWS_NT ) // if is NT or 2K
+    {
+        // Get a token for this process. 
+        HANDLE hToken; 
+        bOK = ::OpenProcessToken(GetCurrentProcess(),
+                                 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
+                                 &hToken) != 0;
+        if ( bOK )
+        {
+            TOKEN_PRIVILEGES tkp; 
+
+            // Get the LUID for the shutdown privilege. 
+            ::LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
+                                   &tkp.Privileges[0].Luid); 
+
+            tkp.PrivilegeCount = 1;  // one privilege to set    
+            tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
+
+            // Get the shutdown privilege for this process. 
+            ::AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
+                                    (PTOKEN_PRIVILEGES)NULL, 0); 
+
+            // Cannot test the return value of AdjustTokenPrivileges. 
+            bOK = ::GetLastError() == ERROR_SUCCESS;
+        }
+    }
+
+    if ( bOK )
+    {
+        UINT flags = EWX_SHUTDOWN | EWX_FORCE;
+        switch ( wFlags )
+        {
+            case wxSHUTDOWN_POWEROFF:
+                flags |= EWX_POWEROFF;
+                break;
+
+            case wxSHUTDOWN_REBOOT:
+                flags |= EWX_REBOOT;
+                break;
+
+            default:
+                wxFAIL_MSG( _T("unknown wxShutdown() flag") );
+                return FALSE;
+        }
+
+        bOK = ::ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE | EWX_REBOOT, 0) != 0; 
+    }
+
+    return bOK;
+#else // Win16
+    return FALSE;
+#endif // Win32/16
+}
+
 // ----------------------------------------------------------------------------
 // misc
 // ----------------------------------------------------------------------------
@@ -1106,12 +1166,12 @@ void wxDebugMsg(const wxChar *fmt ...)
   static wxChar buffer[512];
 
   if (!wxTheApp->GetWantDebugOutput())
-    return ;
+    return;
 
   va_start(ap, fmt);
 
-  wvsprintf(buffer,fmt,ap) ;
-  OutputDebugString((LPCTSTR)buffer) ;
+  wvsprintf(buffer,fmt,ap);
+  OutputDebugString((LPCTSTR)buffer);
 
   va_end(ap);
 }
diff --git a/src/os2/utils.cpp b/src/os2/utils.cpp
index 5ac046f10a..1475bbef3d 100644
--- a/src/os2/utils.cpp
+++ b/src/os2/utils.cpp
@@ -198,6 +198,13 @@ bool wxShell(
     return (rc != 0);
 }
 
+// Shutdown or reboot the PC 
+bool wxShutdown(wxShutdownFlags wFlags)
+{
+    // TODO
+    return FALSE;
+}
+
 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
 long wxGetFreeMemory()
 {
diff --git a/src/unix/utilsunx.cpp b/src/unix/utilsunx.cpp
index b372b21c34..fbeb877d03 100644
--- a/src/unix/utilsunx.cpp
+++ b/src/unix/utilsunx.cpp
@@ -290,6 +290,29 @@ bool wxShell(const wxString& command, wxArrayString& output)
     return wxExecute(wxMakeShellCommand(command), output);
 }
 
+// Shutdown or reboot the PC
+bool wxShutdown(wxShutdownFlags wFlags)
+{
+    wxChar level;
+    switch ( wFlags )
+    {
+        case wxSHUTDOWN_POWEROFF:
+            level = _T('0');
+            break;
+
+        case wxSHUTDOWN_REBOOT:
+            level = _T('6');
+            break;
+
+        default:
+            wxFAIL_MSG( _T("unknown wxShutdown() flag") );
+            return FALSE;
+    }
+
+    return system(wxString::Format(_T("init %c"), level).mb_str()) == 0;
+}
+
+
 #if wxUSE_GUI
 
 void wxHandleProcessTermination(wxEndProcessData *proc_data)
-- 
2.50.0

