- Get autochk, calc, cmd, devmgr, expand, format, gettype, hostname, lsass, msconfig...
[reactos.git] / reactos / subsys / system / sm / sm.c
1 /*
2 * ReactOS Win32 Applications
3 * Copyright (C) 2005 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$
20 *
21 * COPYRIGHT : See COPYING in the top level directory
22 * PROJECT : ReactOS/Win32 Session Manager Control Tool
23 * FILE : subsys/system/sm/sm.c
24 * PROGRAMMER: Emanuele Aliberti (ea@reactos.com)
25 */
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <tchar.h>
30 #include "resource.h"
31
32 #define WIN32_NO_STATUS
33 #include <windows.h>
34 #include <lpctypes.h>
35 #include <lpcfuncs.h>
36 #include <rtlfuncs.h>
37
38 #include <sm/helper.h>
39
40 VOID PrintWin32Error(PWCHAR,DWORD); /* win32err.c */
41
42 #define SM_CMD(n) cmd_##n
43 #define SM_CMD_DECL(n) int SM_CMD(n)(int argc, char * argv[])
44 #define SM_CMD_CALL(n,c,v) SM_CMD(n)((c),(v))
45
46 HANDLE hSmApiPort = (HANDLE) 0;
47
48 VOID STDCALL PrintStatusError (NTSTATUS Status)
49 {
50 DWORD Win32Error = RtlNtStatusToDosError (Status);
51
52 PrintWin32Error (L"sm", Win32Error);
53 }
54
55 typedef struct _SM_CMD_DESCRIPTOR
56 {
57 TCHAR Name[RC_STRING_MAX_SIZE];
58 int (*EntryPoint)(int,TCHAR**);
59 TCHAR Synopsis[RC_STRING_MAX_SIZE];
60 TCHAR Description[RC_STRING_MAX_SIZE];
61
62 } SM_CMD_DESCRIPTOR, *PSM_CMD_DESCRIPTOR;
63
64 SM_CMD_DECL(boot);
65 SM_CMD_DECL(help);
66 SM_CMD_DECL(info);
67 SM_CMD_DECL(reboot);
68 SM_CMD_DECL(shutdown);
69
70 /* internal commands directory */
71 SM_CMD_DESCRIPTOR Command [] =
72 {
73 {"boot", SM_CMD(boot), _T("boot subsystem_name"), _T("bootstrap an optional environment subsystem;")},
74 {"help", SM_CMD(help), _T("help [command]"), _T("print help for command;")},
75 {"info", SM_CMD(info), _T("info [subsystem_id]"), _T("print information about a booted subsystem\n"
76 "if subsystem_id is omitted, a list of booted\n"
77 "environment subsystems is printed.")},
78 {"reboot", SM_CMD(reboot), _T("reboot subsystem_id"), _T("reboot an optional environment subsystem;")},
79 {"shutdown", SM_CMD(shutdown), _T("shutdown subsystem_id"), _T("shutdown an optional environment subsystem;")},
80 };
81
82 TCHAR UsageMessage[RC_STRING_MAX_SIZE];
83 void loadlang(PSM_CMD_DESCRIPTOR );
84
85 PSM_CMD_DESCRIPTOR LookupCommand (const TCHAR * CommandName)
86 {
87 int i;
88 const int command_count = (sizeof Command / sizeof Command[0]);
89
90 /* parse the command... */
91
92 for (i=0; (i < command_count); i ++)
93 {
94 if (0 == _tcscmp(CommandName, Command[i].Name))
95 {
96 break;
97 }
98 }
99 if (i == command_count)
100 {
101 LoadString( GetModuleHandle(NULL), IDS_Unknown, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
102
103 _ftprintf(stderr, UsageMessage, CommandName);
104 return NULL;
105 }
106 return & Command [i];
107 }
108
109 /* user commands */
110
111 SM_CMD_DECL(boot)
112 {
113 int rc = EXIT_SUCCESS;
114 ANSI_STRING ProgramA;
115 UNICODE_STRING ProgramW;
116 NTSTATUS Status = STATUS_SUCCESS;
117
118 if (3 == argc)
119 {
120 #ifndef _UNICODE
121 RtlInitAnsiString (& ProgramA, argv[2]);
122 RtlAnsiStringToUnicodeString (& ProgramW, & ProgramA, TRUE);
123 Status = SmExecuteProgram (hSmApiPort, & ProgramW);
124 RtlFreeUnicodeString (& ProgramW);
125 #else
126 ProgramW = &argv[2];
127 Status = SmExecuteProgram (hSmApiPort, & ProgramW);
128 #endif
129 if (STATUS_SUCCESS != Status)
130 {
131 PrintStatusError (Status);
132 }
133
134 }
135 else
136 {
137 argv[2]=_T("boot");
138 return SM_CMD_CALL(help,3,argv);
139 }
140 return rc;
141 }
142
143 SM_CMD_DECL(help)
144 {
145 unsigned int i = 0;
146 PSM_CMD_DESCRIPTOR cmd = NULL;
147 int rc = EXIT_SUCCESS;
148
149 switch (argc)
150 {
151 case 2:
152 for (i=0; (i < (sizeof Command / sizeof Command[0])); i ++)
153 {
154 _tprintf(_T("%s\n"), Command[i].Synopsis);
155 }
156 break;
157 case 3:
158 cmd = LookupCommand (argv[2]);
159 if (NULL == cmd)
160 {
161 rc = EXIT_FAILURE;
162 break;
163 }
164 _tprintf(_T("%s\n%s\n\n%s\n"),
165 cmd->Name,
166 cmd->Synopsis,
167 cmd->Description);
168 break;
169 }
170 return rc;
171 }
172
173 SM_CMD_DECL(info)
174 {
175 int rc = EXIT_SUCCESS;
176 NTSTATUS Status = STATUS_SUCCESS;
177 SM_INFORMATION_CLASS InformationClass = SmBasicInformation;
178 union {
179 SM_BASIC_INFORMATION bi;
180 SM_SUBSYSTEM_INFORMATION ssi;
181 } Info;
182 ULONG DataLength = 0;
183 ULONG ReturnDataLength = 0;
184 INT i = 0;
185
186 RtlZeroMemory (& Info, sizeof Info);
187 switch (argc)
188 {
189 case 2: /* sm info */
190 InformationClass = SmBasicInformation;
191 DataLength = sizeof Info.bi;
192 break;
193 case 3: /* sm info id */
194 InformationClass = SmSubSystemInformation;
195 DataLength = sizeof Info.ssi;
196 Info.ssi.SubSystemId = atol(argv[2]);
197 break;
198 default:
199 return EXIT_FAILURE;
200 break;
201 }
202 Status = SmQueryInformation (hSmApiPort,
203 InformationClass,
204 & Info,
205 DataLength,
206 & ReturnDataLength);
207 if (STATUS_SUCCESS != Status)
208 {
209 PrintStatusError (Status);
210 return EXIT_FAILURE;
211 }
212 switch (argc)
213 {
214 case 2:
215 LoadString( GetModuleHandle(NULL), IDS_SM1, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
216 _tprintf(UsageMessage);
217
218 LoadString( GetModuleHandle(NULL), IDS_SM2, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
219 for (i = 0; i < Info.bi.SubSystemCount; i ++)
220 {
221 _tprintf(UsageMessage,
222 Info.bi.SubSystem[i].Id,
223 Info.bi.SubSystem[i].ProcessId,
224 Info.bi.SubSystem[i].Flags);
225 }
226 break;
227 case 3:
228 LoadString( GetModuleHandle(NULL), IDS_ID, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
229
230 _tprintf (UsageMessage, Info.ssi.SubSystemId, Info.ssi.Flags, Info.ssi.ProcessId);
231 wprintf(L" NSRootNode: '%s'\n", Info.ssi.NameSpaceRootNode);
232 break;
233 default:
234 break;
235 }
236 return rc;
237 }
238
239 SM_CMD_DECL(shutdown)
240 {
241 int rc = EXIT_SUCCESS;
242
243 LoadString( GetModuleHandle(NULL), IDS_Not_Imp, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
244
245 _ftprintf(stderr,UsageMessage);
246 return rc;
247 }
248
249 SM_CMD_DECL(reboot)
250 {
251 int rc = SM_CMD(shutdown)(argc,argv);
252 if(EXIT_SUCCESS == rc)
253 {
254 rc = SM_CMD(boot)(argc,argv);
255 }
256 return rc;
257 }
258
259 /* print command's synopsys */
260 int print_synopsys (int argc, TCHAR *argv[])
261 {
262 LoadString( GetModuleHandle(NULL), IDS_Mangers, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
263 _ftprintf (stderr, UsageMessage);
264
265 LoadString( GetModuleHandle(NULL), IDS_USING, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
266 _tprintf (UsageMessage);
267 return EXIT_SUCCESS;
268 }
269
270 /* parse and execute */
271 int pande (int argc, TCHAR *argv[])
272 {
273 PSM_CMD_DESCRIPTOR Command = NULL;
274 NTSTATUS Status = STATUS_SUCCESS;
275
276 /* Lookup the user command... */
277 Command = LookupCommand (argv[1]);
278 if (NULL == Command)
279 {
280 return EXIT_FAILURE;
281 }
282 /* Connect to the SM in non-registering mode. */
283 Status = SmConnectApiPort (0, 0, 0, & hSmApiPort);
284 if (STATUS_SUCCESS == Status)
285 {
286 /* ...and execute it */
287 return Command->EntryPoint (argc, argv);
288 }
289 LoadString( GetModuleHandle(NULL), IDS_FAILS_MNG, (LPTSTR) UsageMessage,RC_STRING_MAX_SIZE);
290 _ftprintf (stderr, UsageMessage, Status);
291
292 return EXIT_FAILURE;
293 }
294
295 void loadlang(PSM_CMD_DESCRIPTOR cmd)
296 {
297 int i=0;
298 if (cmd==NULL) return;
299 for (i=0;i < 5; i++)
300 {
301 LoadString( GetModuleHandle(NULL), IDS_boot+i, (LPTSTR) &cmd->Synopsis[i],RC_STRING_MAX_SIZE);
302 }
303 }
304
305 int _tmain (int argc, TCHAR *argv[])
306 {
307 loadlang(Command);
308
309 return (1==argc)
310 ? print_synopsys (argc, argv)
311 : pande (argc, argv);
312 }
313 /* EOF */