Merge trunk HEAD (46152)
[reactos.git] / base / applications / logoff / logoff.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS logoff utility
4 * FILE: base\applications\logoff\logoff.c
5 * PURPOSE: Logoff current session, or another session, potentially on another machine
6 * AUTHOR: 30.07.2007 - Frode Lillerud
7 */
8
9 /* Note
10 * This application is a lightweight version of shutdown.exe. It is intended to be function-compatible
11 * with Windows' system32\logoff.exe commandline application.
12 */
13
14 #define NDEBUG
15 #include "precomp.h"
16
17 //Commandline argument switches
18 LPTSTR szRemoteServerName = NULL;
19 BOOL bVerbose;
20
21 //----------------------------------------------------------------------
22 //
23 //Retrieve resource string and output the Usage to the console
24 //
25 //----------------------------------------------------------------------
26 static void PrintUsage() {
27 LPTSTR lpUsage = NULL;
28
29 if (AllocAndLoadString(&lpUsage, GetModuleHandle(NULL), IDS_USAGE)) {
30 _putts(lpUsage);
31 }
32
33 }
34
35 //----------------------------------------------------------------------
36 //
37 // Writes the last error as both text and error code to the console.
38 //
39 //----------------------------------------------------------------------
40 void DisplayLastError()
41 {
42 int errorCode = GetLastError();
43 LPTSTR lpMsgBuf;
44
45 // Display the error message to the user
46 FormatMessage(
47 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
48 NULL,
49 errorCode,
50 LANG_USER_DEFAULT,
51 (LPTSTR) &lpMsgBuf,
52 0,
53 NULL);
54
55 _ftprintf(stderr, lpMsgBuf);
56 _ftprintf(stderr, _T("Error code: %d\n"), errorCode);
57
58 LocalFree(lpMsgBuf);
59 }
60
61 //----------------------------------------------------------------------
62 //
63 //Sets flags based on commandline arguments
64 //
65 //----------------------------------------------------------------------
66 BOOL ParseCommandLine(int argc, TCHAR *argv[])
67 {
68 int i;
69 LPTSTR lpIllegalMsg;
70
71 //FIXME: Add handling of commandline arguments to select the session number and name, and also name of remote machine
72 //Example: logoff.exe 4 /SERVER:Master should logoff session number 4 on remote machine called Master.
73
74 for (i = 1; i < argc; i++) {
75 switch(argv[i][0]){
76 case '-':
77 case '/':
78 // -v (verbose)
79 if (argv[i][1] == 'v') {
80 bVerbose = TRUE;
81 break; //continue parsing the arguments
82 }
83 // -? (usage)
84 else if(argv[i][1] == '?') {
85 return FALSE; //display the Usage
86 }
87 default:
88 //Invalid parameter detected
89 if (AllocAndLoadString(&lpIllegalMsg, GetModuleHandle(NULL), IDS_ILLEGAL_PARAM))
90 _putts(lpIllegalMsg);
91 return FALSE;
92 }
93 }
94
95 return TRUE;
96 }
97
98 //----------------------------------------------------------------------
99 //
100 //Main entry for program
101 //
102 //----------------------------------------------------------------------
103 int _tmain(int argc, TCHAR *argv[])
104 {
105 LPTSTR lpLogoffRemote, lpLogoffLocal;
106
107 //
108 // Parse command line
109 //
110 if (!ParseCommandLine(argc, argv)) {
111 PrintUsage();
112 return 1;
113 }
114
115 //
116 //Should we log off session on remote server?
117 //
118 if (szRemoteServerName) {
119 if (bVerbose) {
120 if (AllocAndLoadString(&lpLogoffRemote, GetModuleHandle(NULL), IDS_LOGOFF_REMOTE))
121 _putts(lpLogoffRemote);
122 }
123
124 //FIXME: Add Remote Procedure Call to logoff user on a remote machine
125 _ftprintf(stderr, "Remote Procedure Call in logoff.exe has not been implemented");
126 }
127 //
128 //Perform logoff of current session on local machine instead
129 //
130 else {
131 if (bVerbose) {
132 //Get resource string, and print it.
133 if (AllocAndLoadString(&lpLogoffLocal, GetModuleHandle(NULL), IDS_LOGOFF_LOCAL))
134 _putts(lpLogoffLocal);
135 }
136
137 //Actual logoff
138 if (!ExitWindows(NULL, NULL)) {
139 DisplayLastError();
140 return 1;
141 }
142 }
143
144 return 0;
145 }
146 /* EOF */