mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 22:33:00 +00:00
Create a branch for network fixes.
svn path=/branches/aicom-network-fixes/; revision=34994
This commit is contained in:
parent
0e213bbc00
commit
c501d8112c
18148 changed files with 0 additions and 860488 deletions
213
base/applications/shutdown/shutdown.c
Normal file
213
base/applications/shutdown/shutdown.c
Normal file
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS shutdown/logoff utility
|
||||
* FILE: base/application/shutdown/shutdown.c
|
||||
* PURPOSE: Initiate logoff, shutdown or reboot of the system
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
// Print information about which commandline arguments the program accepts.
|
||||
static void PrintUsage() {
|
||||
LPTSTR lpUsage = NULL;
|
||||
|
||||
if( AllocAndLoadString( &lpUsage,
|
||||
GetModuleHandle(NULL),
|
||||
IDS_USAGE ) )
|
||||
{
|
||||
_putts( lpUsage );
|
||||
}
|
||||
}
|
||||
|
||||
struct CommandLineOptions {
|
||||
BOOL abort; // Not used yet
|
||||
BOOL force;
|
||||
BOOL logoff;
|
||||
BOOL restart;
|
||||
BOOL shutdown;
|
||||
};
|
||||
|
||||
struct ExitOptions {
|
||||
// This flag is used to distinguish between a user-initiated LOGOFF (which has value 0)
|
||||
// and an underdetermined situation because user didn't give an argument to start Exit.
|
||||
BOOL shouldExit;
|
||||
// flags is the type of shutdown to do - EWX_LOGOFF, EWX_REBOOT, EWX_POWEROFF, etc..
|
||||
UINT flags;
|
||||
// reason is the System Shutdown Reason code. F.instance SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED.
|
||||
DWORD reason;
|
||||
};
|
||||
|
||||
// Takes the commandline arguments, and creates a struct which matches the arguments supplied.
|
||||
static struct CommandLineOptions ParseArguments(int argc, TCHAR *argv[])
|
||||
{
|
||||
struct CommandLineOptions opts;
|
||||
int i;
|
||||
|
||||
// Reset all flags in struct
|
||||
opts.abort = FALSE;
|
||||
opts.force = FALSE;
|
||||
opts.logoff = FALSE;
|
||||
opts.restart = FALSE;
|
||||
opts.shutdown = FALSE;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-' || argv[i][0] == '/')
|
||||
{
|
||||
switch(argv[i][1]) {
|
||||
case '?':
|
||||
PrintUsage();
|
||||
exit(0);
|
||||
case 'f':
|
||||
case 'F':
|
||||
opts.force = TRUE;
|
||||
break;
|
||||
case 'l':
|
||||
case 'L':
|
||||
opts.logoff = TRUE;
|
||||
break;
|
||||
case 'r':
|
||||
case 'R':
|
||||
opts.restart = TRUE;
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
opts.shutdown = TRUE;
|
||||
break;
|
||||
default:
|
||||
// Unknown arguments will exit program.
|
||||
PrintUsage();
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
// Converts the commandline arguments to flags used to shutdown computer
|
||||
static struct ExitOptions ParseCommandLineOptionsToExitOptions(struct CommandLineOptions opts)
|
||||
{
|
||||
struct ExitOptions exitOpts;
|
||||
exitOpts.shouldExit = TRUE;
|
||||
|
||||
// Sets ONE of the exit type flags
|
||||
if (opts.logoff)
|
||||
exitOpts.flags = EWX_LOGOFF;
|
||||
else if (opts.restart)
|
||||
exitOpts.flags = EWX_REBOOT;
|
||||
else if(opts.shutdown)
|
||||
exitOpts.flags = EWX_POWEROFF;
|
||||
else
|
||||
{
|
||||
exitOpts.flags = 0;
|
||||
exitOpts.shouldExit = FALSE;
|
||||
}
|
||||
|
||||
// Sets additional flags
|
||||
if (opts.force)
|
||||
{
|
||||
exitOpts.flags = exitOpts.flags | EWX_FORCE;
|
||||
|
||||
// This makes sure that we log off, also if there is only the "-f" option specified.
|
||||
// The Windows shutdown utility does it the same way.
|
||||
exitOpts.shouldExit = TRUE;
|
||||
}
|
||||
|
||||
// Reason for shutdown
|
||||
// Hardcoded to "Other (Planned)"
|
||||
exitOpts.reason = SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER | SHTDN_REASON_FLAG_PLANNED;
|
||||
|
||||
return exitOpts;
|
||||
}
|
||||
|
||||
// Writes the last error as both text and error code to the console.
|
||||
void DisplayLastError()
|
||||
{
|
||||
int errorCode = GetLastError();
|
||||
LPTSTR lpMsgBuf;
|
||||
|
||||
// Display the error message to the user
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
errorCode,
|
||||
LANG_USER_DEFAULT,
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
_ftprintf(stderr, lpMsgBuf);
|
||||
_ftprintf(stderr, _T("Error code: %d\n"), errorCode);
|
||||
}
|
||||
|
||||
void EnableShutdownPrivileges()
|
||||
{
|
||||
HANDLE token;
|
||||
TOKEN_PRIVILEGES privs;
|
||||
|
||||
// Check to see if the choosen action is allowed by the user. Everyone can call LogOff, but only privilieged users can shutdown/restart etc.
|
||||
if (! OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
|
||||
{
|
||||
DisplayLastError();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Get LUID (Locally Unique Identifier) for the privilege we need
|
||||
if (!LookupPrivilegeValue(
|
||||
NULL, // system - NULL is localsystem
|
||||
SE_SHUTDOWN_NAME, // name of the privilege
|
||||
&privs.Privileges[0].Luid) // output
|
||||
)
|
||||
{
|
||||
DisplayLastError();
|
||||
exit(1);
|
||||
}
|
||||
// and give our current process (i.e. shutdown.exe) the privilege to shutdown the machine.
|
||||
privs.PrivilegeCount = 1;
|
||||
privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
if (AdjustTokenPrivileges(
|
||||
token,
|
||||
FALSE,
|
||||
&privs,
|
||||
0,
|
||||
(PTOKEN_PRIVILEGES)NULL, // previous state. Set to NULL, we don't care about previous state.
|
||||
NULL
|
||||
) == 0) // return value 0 means failure
|
||||
{
|
||||
DisplayLastError();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Main entry for program
|
||||
int _tmain(int argc, TCHAR *argv[])
|
||||
{
|
||||
struct CommandLineOptions opts;
|
||||
struct ExitOptions exitOpts;
|
||||
|
||||
if (argc == 1) // i.e. no commandline arguments given
|
||||
{
|
||||
PrintUsage();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
opts = ParseArguments(argc, argv);
|
||||
exitOpts = ParseCommandLineOptionsToExitOptions(opts);
|
||||
|
||||
// Perform the shutdown/restart etc. action
|
||||
if (exitOpts.shouldExit)
|
||||
{
|
||||
EnableShutdownPrivileges();
|
||||
|
||||
if (!ExitWindowsEx(exitOpts.flags, exitOpts.reason))
|
||||
{
|
||||
DisplayLastError();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EOF
|
Loading…
Add table
Add a link
Reference in a new issue