diff --git a/reactos/base/applications/applications.rbuild b/reactos/base/applications/applications.rbuild index ca1fe852e3c..aafcf9e527e 100644 --- a/reactos/base/applications/applications.rbuild +++ b/reactos/base/applications/applications.rbuild @@ -25,6 +25,9 @@ + + + diff --git a/reactos/base/applications/logoff/lang/en-US.rc b/reactos/base/applications/logoff/lang/en-US.rc new file mode 100644 index 00000000000..64a3e2a4fc7 --- /dev/null +++ b/reactos/base/applications/logoff/lang/en-US.rc @@ -0,0 +1,15 @@ +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE DISCARDABLE +{ + +IDS_USAGE, "Terminates a session.\n\n\ + /v\t\tDisplays information about the actions performed.\n\ + /?\t\tShows this information.\n\n" + +IDS_LOGOFF_REMOTE, "Terminating session on remote machine." +IDS_LOGOFF_LOCAL, "Terminating the current session on this machine." + +IDS_ILLEGAL_PARAM, "Invalid parameter(s)\n" +} +/* EOF */ diff --git a/reactos/base/applications/logoff/lang/nb-NO.rc b/reactos/base/applications/logoff/lang/nb-NO.rc new file mode 100644 index 00000000000..b4f8a8826e1 --- /dev/null +++ b/reactos/base/applications/logoff/lang/nb-NO.rc @@ -0,0 +1,16 @@ +LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + +IDS_USAGE, "Avslutter en sesjon.\n\n\ + /v\t\tViser informasjon om handlingen som utføres.\n\ + /?\t\tViser denne informasjonen.\n\n" + +IDS_LOGOFF_REMOTE, "Logger av økt på en annen maskin" +IDS_LOGOFF_LOCAL, "Logger av økten på denne maskinen." + +IDS_ILLEGAL_PARAM, "En eller flere ugyldige parametre.\n" +} + +/* EOF */ diff --git a/reactos/base/applications/logoff/logoff.c b/reactos/base/applications/logoff/logoff.c new file mode 100644 index 00000000000..d333fc97815 --- /dev/null +++ b/reactos/base/applications/logoff/logoff.c @@ -0,0 +1,146 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS logoff utility + * FILE: base\applications\logoff\logoff.c + * PURPOSE: Logoff current session, or another session, potentially on another machine + * AUTHOR: 30.07.2007 - Frode Lillerud + */ + +/* Note + * This application is a lightweight version of shutdown.exe. It is intended to be function-compatible + * with Windows' system32\logoff.exe commandline application. + */ + +#define NDEBUG +#include "precomp.h" + +//Commandline argument switches +LPTSTR szRemoteServerName = NULL; +BOOL bVerbose; + +//---------------------------------------------------------------------- +// +//Retrieve resource string and output the Usage to the console +// +//---------------------------------------------------------------------- +static void PrintUsage() { + LPTSTR lpUsage = NULL; + + if (AllocAndLoadString(&lpUsage, GetModuleHandle(NULL), IDS_USAGE)) { + _putts(lpUsage); + } + +} + +//---------------------------------------------------------------------- +// +// 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); + + LocalFree(lpMsgBuf); +} + +//---------------------------------------------------------------------- +// +//Sets flags based on commandline arguments +// +//---------------------------------------------------------------------- +BOOL ParseCommandLine(int argc, TCHAR *argv[]) +{ + int i; + LPTSTR lpIllegalMsg; + + //FIXME: Add handling of commandline arguments to select the session number and name, and also name of remote machine + //Example: logoff.exe 4 /SERVER:Master should logoff session number 4 on remote machine called Master. + + for (i = 1; i < argc; i++) { + switch(argv[i][0]){ + case '-': + case '/': + // -v (verbose) + if (argv[i][1] == 'v') { + bVerbose = TRUE; + break; //continue parsing the arguments + } + // -? (usage) + else if(argv[i][1] == '?') { + return FALSE; //display the Usage + } + default: + //Invalid parameter detected + if (AllocAndLoadString(&lpIllegalMsg, GetModuleHandle(NULL), IDS_ILLEGAL_PARAM)) + _putts(lpIllegalMsg); + return FALSE; + } + } + + return TRUE; +} + +//---------------------------------------------------------------------- +// +//Main entry for program +// +//---------------------------------------------------------------------- +int _tmain(int argc, TCHAR *argv[]) +{ + LPTSTR lpLogoffRemote, lpLogoffLocal; + + // + // Parse command line + // + if (!ParseCommandLine(argc, argv)) { + PrintUsage(); + return 1; + } + + // + //Should we log off session on remote server? + // + if (szRemoteServerName) { + if (bVerbose) { + if (AllocAndLoadString(&lpLogoffRemote, GetModuleHandle(NULL), IDS_LOGOFF_REMOTE)) + _putts(lpLogoffRemote); + } + + //FIXME: Add Remote Procedure Call to logoff user on a remote machine + _ftprintf(stderr, "Remote Procedure Call in logoff.exe has not been implemented"); + } + // + //Perform logoff of current session on local machine instead + // + else { + if (bVerbose) { + //Get resource string, and print it. + if (AllocAndLoadString(&lpLogoffLocal, GetModuleHandle(NULL), IDS_LOGOFF_LOCAL)) + _putts(lpLogoffLocal); + } + + //Actual logoff + if (!ExitWindows(NULL, NULL)) { + DisplayLastError(); + return 1; + } + } + + return 0; +} +/* EOF */ diff --git a/reactos/base/applications/logoff/logoff.rbuild b/reactos/base/applications/logoff/logoff.rbuild new file mode 100644 index 00000000000..4333531c3c6 --- /dev/null +++ b/reactos/base/applications/logoff/logoff.rbuild @@ -0,0 +1,14 @@ + + + + . + + 0x0501 + advapi32 + user32 + kernel32 + misc.c + logoff.c + logoff.rc + precomp.h + diff --git a/reactos/base/applications/logoff/logoff.rc b/reactos/base/applications/logoff/logoff.rc new file mode 100644 index 00000000000..1ff19aa5ef8 --- /dev/null +++ b/reactos/base/applications/logoff/logoff.rc @@ -0,0 +1,9 @@ +#include +#include "resource.h" + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Logoff Utility\0" +#define REACTOS_STR_INTERNAL_NAME "logoff\0" +#define REACTOS_STR_ORIGINAL_FILENAME "logoff.exe\0" +#include + +#include "rsrc.rc" diff --git a/reactos/base/applications/logoff/misc.c b/reactos/base/applications/logoff/misc.c new file mode 100644 index 00000000000..d7b042bc501 --- /dev/null +++ b/reactos/base/applications/logoff/misc.c @@ -0,0 +1,63 @@ +#include "precomp.h" + +static INT +LengthOfStrResource(IN HINSTANCE hInst, + IN UINT uID) +{ + HRSRC hrSrc; + HGLOBAL hRes; + LPWSTR lpName, lpStr; + + if (hInst == NULL) + { + return -1; + } + + /* There are always blocks of 16 strings */ + lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1); + + /* Find the string table block */ + if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) && + (hRes = LoadResource(hInst, hrSrc)) && + (lpStr = (WCHAR*) LockResource(hRes))) + { + UINT x; + + /* Find the string we're looking for */ + uID &= 0xF; /* position in the block, same as % 16 */ + for (x = 0; x < uID; x++) + { + lpStr += (*lpStr) + 1; + } + + /* Found the string */ + return (int)(*lpStr); + } + return -1; +} + +INT +AllocAndLoadString(OUT LPTSTR *lpTarget, + IN HINSTANCE hInst, + IN UINT uID) +{ + INT ln; + + ln = LengthOfStrResource(hInst, + uID); + if (ln++ > 0) + { + (*lpTarget) = (LPTSTR)LocalAlloc(LMEM_FIXED, + ln * sizeof(TCHAR)); + if ((*lpTarget) != NULL) + { + INT Ret; + if (!(Ret = LoadString(hInst, uID, *lpTarget, ln))) + { + LocalFree((HLOCAL)(*lpTarget)); + } + return Ret; + } + } + return 0; +} diff --git a/reactos/base/applications/logoff/precomp.h b/reactos/base/applications/logoff/precomp.h new file mode 100644 index 00000000000..24e122baefc --- /dev/null +++ b/reactos/base/applications/logoff/precomp.h @@ -0,0 +1,16 @@ +#ifndef __SHUTDOWN_PRECOMP_H +#define __SHUTDOWN_PRECOMP_H + +#include +#include +#include +#include +#include //shutdown codes +#include "resource.h" + +// misc.c +INT AllocAndLoadString(OUT LPTSTR *lpTarget, + IN HINSTANCE hInst, + IN UINT uID); + +#endif diff --git a/reactos/base/applications/logoff/resource.h b/reactos/base/applications/logoff/resource.h new file mode 100644 index 00000000000..a04334117e1 --- /dev/null +++ b/reactos/base/applications/logoff/resource.h @@ -0,0 +1,4 @@ +#define IDS_USAGE 1000 +#define IDS_LOGOFF_REMOTE 1001 +#define IDS_LOGOFF_LOCAL 1002 +#define IDS_ILLEGAL_PARAM 1003 diff --git a/reactos/base/applications/logoff/rsrc.rc b/reactos/base/applications/logoff/rsrc.rc new file mode 100644 index 00000000000..2bbd29e394b --- /dev/null +++ b/reactos/base/applications/logoff/rsrc.rc @@ -0,0 +1,5 @@ +#include +#include "resource.h" + +#include "lang/en-US.rc" +#include "lang/nb-NO.rc" diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index bae00ee8270..c5c9e64c224 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -41,6 +41,7 @@ base\applications\games\solitaire\sol.exe 1 base\applications\games\winemine\winemine.exe 1 base\applications\hh\hh.exe 1 base\applications\hostname\hostname.exe 1 +base\applications\logoff\logoff.exe 1 base\applications\msconfig\msconfig.exe 1 base\applications\network\arp\arp.exe 1 base\applications\network\route\route.exe 1