diff --git a/reactos/apps/tests/fiber/fiber.c b/reactos/apps/tests/fiber/fiber.c index 3dfb2dc1be8..94318f56d13 100644 --- a/reactos/apps/tests/fiber/fiber.c +++ b/reactos/apps/tests/fiber/fiber.c @@ -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 @@ -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; diff --git a/reactos/apps/utils/Makefile b/reactos/apps/utils/Makefile index ec127395847..2744bc70c11 100644 --- a/reactos/apps/utils/Makefile +++ b/reactos/apps/utils/Makefile @@ -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 = diff --git a/reactos/apps/utils/shutdown/.cvsignore b/reactos/apps/utils/shutdown/.cvsignore new file mode 100644 index 00000000000..d63774a7353 --- /dev/null +++ b/reactos/apps/utils/shutdown/.cvsignore @@ -0,0 +1,6 @@ +*.o +*.d +*.exe +*.coff +*.sym +*.map diff --git a/reactos/apps/utils/shutdown/Makefile b/reactos/apps/utils/shutdown/Makefile new file mode 100644 index 00000000000..d47429a5353 --- /dev/null +++ b/reactos/apps/utils/shutdown/Makefile @@ -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 diff --git a/reactos/apps/utils/shutdown/shutdown.c b/reactos/apps/utils/shutdown/shutdown.c new file mode 100644 index 00000000000..b978a8043cd --- /dev/null +++ b/reactos/apps/utils/shutdown/shutdown.c @@ -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 +#include +#include +#include + +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; +} diff --git a/reactos/include/tchar.h b/reactos/include/tchar.h index 95e6cdbeabd..0ac89e0cff1 100644 --- a/reactos/include/tchar.h +++ b/reactos/include/tchar.h @@ -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 + +#else /* Not __USE_W32API */ #include @@ -259,3 +265,4 @@ typedef char TCHAR; #endif /* Not _TCHAR_H_ */ +#endif /* Not __USE_W32API */