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