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}. +\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} + + \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)