Add command-line shutdown/logoff utility

svn path=/trunk/; revision=10028
This commit is contained in:
Gé van Geldorp 2004-07-07 22:29:37 +00:00
parent 6d616faf61
commit 8d126dbfc4
6 changed files with 212 additions and 8 deletions

View file

@ -1,4 +1,4 @@
/* $Id: fiber.c,v 1.3 2004/07/03 17:40:19 navaraf Exp $
/* $Id: fiber.c,v 1.4 2004/07/07 22:29:37 gvg Exp $
*/
#include <assert.h>
@ -426,7 +426,7 @@ int _tmain(int argc, _TCHAR const * const * argv)
unsigned nFibers;
if(argc > 1)
nFibers = _tcstoul(argv[1], 0, NULL);
nFibers = _tcstoul(argv[1], NULL, 0);
else
nFibers = FIBERTEST_COUNT;

View file

@ -9,7 +9,7 @@ include $(PATH_TO_TOP)/rules.mak
# Console system utilities
# cabman cat net objdir partinfo pice ps sc stats
UTIL_APPS = cat objdir partinfo pnpdump sc stats tickcount consw rundll32 regsvr32
UTIL_APPS = cat objdir partinfo pnpdump sc shutdown stats tickcount consw rundll32 regsvr32
UTIL_NET_APPS =

View file

@ -0,0 +1,6 @@
*.o
*.d
*.exe
*.coff
*.sym
*.map

View file

@ -0,0 +1,23 @@
# $Id: Makefile,v 1.1 2004/07/07 22:29:37 gvg Exp $
PATH_TO_TOP = ../../..
TARGET_NORC = yes
TARGET_TYPE = program
TARGET_APPTYPE = console
TARGET_NAME = shutdown
TARGET_SDKLIBS = kernel32.a user32.a
TARGET_OBJECTS = shutdown.o
TARGET_CFLAGS = -Wall -Werror -D__USE_W32API
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
# EOF

View file

@ -0,0 +1,168 @@
/* $Id: shutdown.c,v 1.1 2004/07/07 22:29:37 gvg Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS shutdown/logoff utility
* FILE: apps/utils/shutdown/shutdown.c
* PURPOSE: Initiate logoff, shutdown or reboot of the system
*/
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <tchar.h>
static void
PrintUsage(LPCTSTR Cmd)
{
_ftprintf(stderr, _T("usage: %s [action] [flag]\n"), Cmd);
_ftprintf(stderr, _T(" action = \"logoff\", \"reboot\", \"shutdown\" or \"poweroff\"\n"));
_ftprintf(stderr, _T(" flag = \"force\"\n"));
}
int
_tmain(int argc, TCHAR *argv[])
{
static struct
{
TCHAR *Name;
UINT ExitType;
UINT ExitFlags;
}
Options[] =
{
{ _T("logoff"), EWX_LOGOFF, 0 },
{ _T("logout"), EWX_LOGOFF, 0 },
{ _T("poweroff"), EWX_POWEROFF, 0 },
{ _T("powerdown"), EWX_POWEROFF, 0 },
{ _T("reboot"), EWX_REBOOT, 0 },
{ _T("restart"), EWX_REBOOT, 0 },
{ _T("shutdown"), EWX_SHUTDOWN, 0 },
{ _T("force"), 0, EWX_FORCE }
};
UINT ExitType, ExitFlags;
HANDLE hToken;
TOKEN_PRIVILEGES npr;
TCHAR *Arg;
TCHAR BaseName[_MAX_FNAME];
unsigned i, j;
BOOL HaveType, Matched;
ExitType = 0;
ExitFlags = 0;
HaveType = FALSE;
_tsplitpath(argv[0], NULL, NULL, BaseName, NULL);
/* Process optional arguments */
for (i = 1; i < (unsigned) argc; i++)
{
/* Allow e.g. "/s" or "-l" for shutdown resp. logoff */
Arg = argv[i];
if (_T('/') == *Arg || _T('-') == *Arg)
{
Arg++;
}
/* Search known options */
Matched = FALSE;
for (j = 0; j < sizeof(Options) / sizeof(Options[0]) && ! Matched; j++)
{
/* Match if arg starts the same as the option name */
if (0 == _tcsnicmp(Options[j].Name, Arg, _tcslen(Arg)))
{
if (0 != Options[j].ExitType)
{
/* Can have only 1 type */
if (HaveType)
{
PrintUsage(BaseName);
exit(1);
}
ExitType = Options[j].ExitType;
HaveType = TRUE;
}
else
{
/* Can have only 1 flag */
if (0 != ExitFlags)
{
PrintUsage(BaseName);
exit(1);
}
ExitFlags |= Options[j].ExitFlags;
}
Matched = TRUE;
}
}
/* Was the argument processed? */
if (! Matched)
{
PrintUsage(BaseName);
exit(1);
}
}
/* Check command name if user didn't explicitly specify action */
if (! HaveType)
{
for (j = 0; j < sizeof(Options) / sizeof(Options[0]); j++)
{
if (0 == _tcsicmp(Options[j].Name, BaseName) && 0 != Options[j].ExitType)
{
ExitType = Options[j].ExitType;
HaveType = TRUE;
}
}
}
/* Still not sure what to do? */
if (! HaveType)
{
PrintUsage(BaseName);
exit(1);
}
/* Everyone can logoff, for the other actions you need the appropriate privilege */
if (EWX_LOGOFF != ExitType)
{
/* enable shutdown privilege for current process */
if (! OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
_ftprintf(stderr, _T("OpenProcessToken failed with error %d\n"), (int) GetLastError());
exit(1);
}
npr.PrivilegeCount = 1;
npr.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (! LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &npr.Privileges[0].Luid))
{
CloseHandle(hToken);
_ftprintf(stderr, _T("LookupPrivilegeValue failed with error %d\n"), (int) GetLastError());
exit(1);
}
if (! AdjustTokenPrivileges(hToken, FALSE, &npr, 0, 0, 0)
|| ERROR_SUCCESS != GetLastError())
{
CloseHandle(hToken);
if (ERROR_NOT_ALL_ASSIGNED == GetLastError())
{
_ftprintf(stderr, _T("You are not authorized to shutdown the system\n"));
}
else
{
_ftprintf(stderr, _T("AdjustTokenPrivileges failed with error %d\n"), (int) GetLastError());
}
exit(1);
}
CloseHandle(hToken);
}
/* Finally do it */
if (! ExitWindowsEx(ExitType | ExitFlags, 0))
{
_ftprintf(stderr, _T("ExitWindowsEx failed with error %d\n"), (int) GetLastError());
exit(1);
}
return 0;
}

View file

@ -29,14 +29,20 @@
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* $Revision: 1.10 $
* $Author: royce $
* $Date: 2003/08/11 00:04:05 $
* $Revision: 1.11 $
* $Author: gvg $
* $Date: 2004/07/07 22:29:37 $
*
*/
#ifndef _TCHAR_H_
#define _TCHAR_H_
#ifndef _ROS_TCHAR_H_
#define _ROS_TCHAR_H_
#ifdef __USE_W32API
#include_next <tchar.h>
#else /* Not __USE_W32API */
#include <msvcrt/string.h>
@ -259,3 +265,4 @@ typedef char TCHAR;
#endif /* Not _TCHAR_H_ */
#endif /* Not __USE_W32API */