mirror of
https://github.com/reactos/reactos.git
synced 2024-10-15 05:37:44 +00:00
Add command-line shutdown/logoff utility
svn path=/trunk/; revision=10028
This commit is contained in:
parent
6d616faf61
commit
8d126dbfc4
|
@ -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>
|
#include <assert.h>
|
||||||
|
@ -426,7 +426,7 @@ int _tmain(int argc, _TCHAR const * const * argv)
|
||||||
unsigned nFibers;
|
unsigned nFibers;
|
||||||
|
|
||||||
if(argc > 1)
|
if(argc > 1)
|
||||||
nFibers = _tcstoul(argv[1], 0, NULL);
|
nFibers = _tcstoul(argv[1], NULL, 0);
|
||||||
else
|
else
|
||||||
nFibers = FIBERTEST_COUNT;
|
nFibers = FIBERTEST_COUNT;
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ include $(PATH_TO_TOP)/rules.mak
|
||||||
|
|
||||||
# Console system utilities
|
# Console system utilities
|
||||||
# cabman cat net objdir partinfo pice ps sc stats
|
# 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 =
|
UTIL_NET_APPS =
|
||||||
|
|
||||||
|
|
6
reactos/apps/utils/shutdown/.cvsignore
Normal file
6
reactos/apps/utils/shutdown/.cvsignore
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
*.o
|
||||||
|
*.d
|
||||||
|
*.exe
|
||||||
|
*.coff
|
||||||
|
*.sym
|
||||||
|
*.map
|
23
reactos/apps/utils/shutdown/Makefile
Normal file
23
reactos/apps/utils/shutdown/Makefile
Normal 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
|
168
reactos/apps/utils/shutdown/shutdown.c
Normal file
168
reactos/apps/utils/shutdown/shutdown.c
Normal 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;
|
||||||
|
}
|
|
@ -29,14 +29,20 @@
|
||||||
* DISCLAIMED. This includes but is not limited to warranties of
|
* DISCLAIMED. This includes but is not limited to warranties of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
*
|
*
|
||||||
* $Revision: 1.10 $
|
* $Revision: 1.11 $
|
||||||
* $Author: royce $
|
* $Author: gvg $
|
||||||
* $Date: 2003/08/11 00:04:05 $
|
* $Date: 2004/07/07 22:29:37 $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _TCHAR_H_
|
#ifndef _ROS_TCHAR_H_
|
||||||
#define _TCHAR_H_
|
#define _ROS_TCHAR_H_
|
||||||
|
|
||||||
|
#ifdef __USE_W32API
|
||||||
|
|
||||||
|
#include_next <tchar.h>
|
||||||
|
|
||||||
|
#else /* Not __USE_W32API */
|
||||||
|
|
||||||
#include <msvcrt/string.h>
|
#include <msvcrt/string.h>
|
||||||
|
|
||||||
|
@ -259,3 +265,4 @@ typedef char TCHAR;
|
||||||
|
|
||||||
#endif /* Not _TCHAR_H_ */
|
#endif /* Not _TCHAR_H_ */
|
||||||
|
|
||||||
|
#endif /* Not __USE_W32API */
|
||||||
|
|
Loading…
Reference in a new issue