sm info ssid - implemented
[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
30 #define NTOS_MODE_USER
31 #include <ntos.h>
32 #include <sm/helper.h>
33
34 #define SM_CMD(n) cmd_##n
35 #define SM_CMD_DECL(n) int SM_CMD(n)(int argc, char * argv[])
36 #define SM_CMD_CALL(n,c,v) SM_CMD(n)((c),(v))
37
38 HANDLE hSmApiPort = (HANDLE) 0;
39
40 typedef struct _SM_CMD_DESCRIPTOR
41 {
42 const char * Name;
43 int (*EntryPoint)(int,char**);
44 const char * Synopsis;
45 const char * Description;
46
47 } SM_CMD_DESCRIPTOR, *PSM_CMD_DESCRIPTOR;
48
49 SM_CMD_DECL(boot);
50 SM_CMD_DECL(help);
51 SM_CMD_DECL(info);
52 SM_CMD_DECL(reboot);
53 SM_CMD_DECL(shutdown);
54
55 /* internal commands directory */
56 SM_CMD_DESCRIPTOR Command [] =
57 {
58 {"boot", SM_CMD(boot), "boot subsystem_name", "bootstrap an optional environment subsystem;"},
59 {"help", SM_CMD(help), "help [command]", "print help for command;"},
60 {"info", SM_CMD(info), "info [subsystem_id]", "print information about a booted subsystem\n"
61 "if subsystem_id is omitted, a list of booted\n"
62 "environment subsystems is printed."},
63 {"reboot", SM_CMD(reboot), "reboot subsystem_id", "reboot an optional environment subsystem;"},
64 {"shutdown", SM_CMD(shutdown), "shutdown subsystem_id", "shutdown an optional environment subsystem;"},
65 };
66
67 PSM_CMD_DESCRIPTOR LookupCommand (const char * CommandName)
68 {
69 int i;
70 const int command_count = (sizeof Command / sizeof Command[0]);
71
72 /* parse the command... */
73
74 for (i=0; (i < command_count); i ++)
75 {
76 if (0 == strcmp(CommandName, Command[i].Name))
77 {
78 break;
79 }
80 }
81 if (i == command_count)
82 {
83 fprintf(stderr, "Unknown command '%s'.\n", CommandName);
84 return NULL;
85 }
86 return & Command [i];
87 }
88
89 /* user commands */
90
91 SM_CMD_DECL(boot)
92 {
93 int rc = EXIT_SUCCESS;
94 ANSI_STRING ProgramA;
95 UNICODE_STRING ProgramW;
96 NTSTATUS Status = STATUS_SUCCESS;
97
98 if (3 == argc)
99 {
100 RtlInitAnsiString (& ProgramA, argv[2]);
101 RtlAnsiStringToUnicodeString (& ProgramW, & ProgramA, TRUE);
102 Status = SmExecuteProgram (hSmApiPort, & ProgramW);
103 RtlFreeUnicodeString (& ProgramW);
104 if (STATUS_SUCCESS != Status)
105 {
106 printf ("Status 0x%08lx\n", Status);
107 }
108 }
109 else
110 {
111 argv[2]="boot";
112 return SM_CMD_CALL(help,3,argv);
113 }
114 return rc;
115 }
116
117 SM_CMD_DECL(help)
118 {
119 int i = 0;
120 PSM_CMD_DESCRIPTOR cmd = NULL;
121 int rc = EXIT_SUCCESS;
122
123 switch (argc)
124 {
125 case 2:
126 for (i=0; (i < (sizeof Command / sizeof Command[0])); i ++)
127 {
128 printf("%s\n", Command[i].Synopsis);
129 }
130 break;
131 case 3:
132 cmd = LookupCommand (argv[2]);
133 if (NULL == cmd)
134 {
135 rc = EXIT_FAILURE;
136 break;
137 }
138 printf("%s\n%s\n\n%s\n",
139 cmd->Name,
140 cmd->Synopsis,
141 cmd->Description);
142 break;
143 }
144 return rc;
145 }
146
147 SM_CMD_DECL(info)
148 {
149 int rc = EXIT_SUCCESS;
150 NTSTATUS Status = STATUS_SUCCESS;
151 SM_INFORMATION_CLASS InformationClass = SmBasicInformation;
152 union {
153 SM_BASIC_INFORMATION bi;
154 SM_SUBSYSTEM_INFORMATION ssi;
155 } Info;
156 ULONG DataLength = 0;
157 ULONG ReturnDataLength = 0;
158 INT i = 0;
159
160 RtlZeroMemory (& Info, sizeof Info);
161 switch (argc)
162 {
163 case 2: /* sm info */
164 InformationClass = SmBasicInformation;
165 DataLength = sizeof Info.bi;
166 break;
167 case 3: /* sm info id */
168 InformationClass = SmSubSystemInformation;
169 DataLength = sizeof Info.ssi;
170 Info.ssi.SubSystemId = atol(argv[2]);
171 break;
172 default:
173 return EXIT_FAILURE;
174 break;
175 }
176 Status = SmQueryInformation (hSmApiPort,
177 InformationClass,
178 & Info,
179 DataLength,
180 & ReturnDataLength);
181 if (STATUS_SUCCESS != Status)
182 {
183 printf ("Status 0x%08lx\n", Status);
184 return EXIT_FAILURE;
185 }
186 switch (argc)
187 {
188 case 2:
189 printf ("SM SubSystem Directory\n\n");
190 printf ("SSID PID Flags\n");
191 printf ("---- -------- ------------\n");
192 for (i = 0; i < Info.bi.SubSystemCount; i ++)
193 {
194 printf ("%04x %08lx %04x\n",
195 Info.bi.SubSystem[i].Id,
196 Info.bi.SubSystem[i].ProcessId,
197 Info.bi.SubSystem[i].Flags);
198 }
199 break;
200 case 3:
201 printf ("SubSystem ID: %d\n", Info.ssi.SubSystemId);
202 printf (" Flags: %04x\n", Info.ssi.Flags);
203 printf (" Process ID: %ld\n", Info.ssi.ProcessId);
204 wprintf(L" NSRootNode: '%s'\n", Info.ssi.NameSpaceRootNode);
205 break;
206 default:
207 break;
208 }
209 return rc;
210 }
211
212 SM_CMD_DECL(shutdown)
213 {
214 int rc = EXIT_SUCCESS;
215
216 fprintf(stderr,"not implemented\n");
217 return rc;
218 }
219
220 SM_CMD_DECL(reboot)
221 {
222 int rc = SM_CMD(shutdown)(argc,argv);
223 if(EXIT_SUCCESS == rc)
224 {
225 rc = SM_CMD(boot)(argc,argv);
226 }
227 return rc;
228 }
229
230 /* print command's synopsys */
231 int print_synopsys (int argc, char *argv[])
232 {
233 fprintf (stderr, "ReactOS/Win32 Session Manager Control Tool\n\n");
234 printf ("Usage:\n"
235 "\tsm\n"
236 "\tsm help [command]\n"
237 "\tsm command [arguments]\n\n"
238 "'sm help' will print the list of valid commands.\n");
239 return EXIT_SUCCESS;
240 }
241
242 /* parse and execute */
243 int pande (int argc, char *argv[])
244 {
245 PSM_CMD_DESCRIPTOR Command = NULL;
246 NTSTATUS Status = STATUS_SUCCESS;
247
248 /* Lookup the user command... */
249 Command = LookupCommand (argv[1]);
250 if (NULL == Command)
251 {
252 return EXIT_FAILURE;
253 }
254 /* Connect to the SM in non-registering mode. */
255 Status = SmConnectApiPort (0, 0, 0, & hSmApiPort);
256 if (STATUS_SUCCESS == Status)
257 {
258 /* ...and execute it */
259 return Command->EntryPoint (argc, argv);
260 }
261 fprintf (stderr, "Failed to connect to the Session Manager! (Status=0x%08lx)\n", Status);
262 return EXIT_FAILURE;
263 }
264
265 int main (int argc, char *argv[])
266 {
267 return (1==argc)
268 ? print_synopsys (argc, argv)
269 : pande (argc, argv);
270 }
271 /* EOF */