xref: /reactos/base/applications/sc/sc.c (revision a0d412b7)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:     ReactOS Services
3c2c66affSColin Finck  * LICENSE:     GPL - See COPYING in the top level directory
4c2c66affSColin Finck  * FILE:        base/applications/sc/sc.c
5c2c66affSColin Finck  * PURPOSE:     parse command line
6c2c66affSColin Finck  * COPYRIGHT:   Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com>
7c2c66affSColin Finck  *
8c2c66affSColin Finck  */
9c2c66affSColin Finck 
10c2c66affSColin Finck #include "sc.h"
11c2c66affSColin Finck 
12c2c66affSColin Finck SC_HANDLE hSCManager;
13c2c66affSColin Finck 
14c2c66affSColin Finck VOID
15c2c66affSColin Finck ReportLastError(VOID)
16c2c66affSColin Finck {
17c2c66affSColin Finck     LPVOID lpMsgBuf;
18c2c66affSColin Finck     DWORD RetVal;
19c2c66affSColin Finck 
20c2c66affSColin Finck     DWORD ErrorCode = GetLastError();
21c2c66affSColin Finck     if (ErrorCode != ERROR_SUCCESS)
22c2c66affSColin Finck     {
23c2c66affSColin Finck         RetVal = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
24c2c66affSColin Finck                                FORMAT_MESSAGE_FROM_SYSTEM |
25c2c66affSColin Finck                                FORMAT_MESSAGE_IGNORE_INSERTS,
26c2c66affSColin Finck                                NULL,
27c2c66affSColin Finck                                ErrorCode,
28c2c66affSColin Finck                                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
29c2c66affSColin Finck                                (LPTSTR) &lpMsgBuf,
30c2c66affSColin Finck                                0,
31c2c66affSColin Finck                                NULL );
32c2c66affSColin Finck 
33c2c66affSColin Finck         if (RetVal != 0)
34c2c66affSColin Finck         {
35c2c66affSColin Finck             _tprintf(_T("%s"), (LPTSTR)lpMsgBuf);
36c2c66affSColin Finck             LocalFree(lpMsgBuf);
37c2c66affSColin Finck         }
38c2c66affSColin Finck     }
39c2c66affSColin Finck }
40c2c66affSColin Finck 
41c2c66affSColin Finck 
42c2c66affSColin Finck static INT
43c2c66affSColin Finck ScControl(LPCTSTR Server,       // remote machine name
44c2c66affSColin Finck           LPCTSTR Command,      // sc command
45c2c66affSColin Finck           LPCTSTR *ServiceArgs, // any options
46c2c66affSColin Finck           DWORD ArgCount)       // argument counter
47c2c66affSColin Finck {
48c2c66affSColin Finck     LPCTSTR ServiceName = NULL;
49c2c66affSColin Finck 
50c2c66affSColin Finck     if (Server)
51c2c66affSColin Finck     {
52c2c66affSColin Finck         _tprintf(_T("Remote service control is not yet implemented\n"));
53c2c66affSColin Finck         return 2;
54c2c66affSColin Finck     }
55c2c66affSColin Finck 
56c2c66affSColin Finck     if (!lstrcmpi(Command, _T("query")))
57c2c66affSColin Finck     {
58c2c66affSColin Finck         Query(ServiceArgs,
59c2c66affSColin Finck               ArgCount,
60c2c66affSColin Finck               FALSE);
61c2c66affSColin Finck     }
62c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("queryex")))
63c2c66affSColin Finck     {
64c2c66affSColin Finck         Query(ServiceArgs,
65c2c66affSColin Finck               ArgCount,
66c2c66affSColin Finck               TRUE);
67c2c66affSColin Finck     }
68c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("start")))
69c2c66affSColin Finck     {
70c2c66affSColin Finck         if (ArgCount > 0)
71c2c66affSColin Finck         {
72c2c66affSColin Finck             ServiceName = *ServiceArgs++;
73c2c66affSColin Finck             ArgCount--;
74c2c66affSColin Finck 
75c2c66affSColin Finck             Start(ServiceName,
76c2c66affSColin Finck                   ServiceArgs,
77c2c66affSColin Finck                   ArgCount);
78c2c66affSColin Finck         }
79c2c66affSColin Finck         else
80c2c66affSColin Finck             StartUsage();
81c2c66affSColin Finck     }
82c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("pause")))
83c2c66affSColin Finck     {
84c2c66affSColin Finck         if (ArgCount > 0)
85c2c66affSColin Finck         {
86c2c66affSColin Finck             ServiceName = *ServiceArgs++;
87c2c66affSColin Finck             ArgCount--;
88c2c66affSColin Finck 
89c2c66affSColin Finck             Control(SERVICE_CONTROL_PAUSE,
90c2c66affSColin Finck                     ServiceName,
91c2c66affSColin Finck                     ServiceArgs,
92c2c66affSColin Finck                     ArgCount);
93c2c66affSColin Finck         }
94c2c66affSColin Finck         else
95c2c66affSColin Finck             PauseUsage();
96c2c66affSColin Finck     }
97c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("interrogate")))
98c2c66affSColin Finck     {
99c2c66affSColin Finck         if (ArgCount > 0)
100c2c66affSColin Finck         {
101c2c66affSColin Finck             ServiceName = *ServiceArgs++;
102c2c66affSColin Finck             ArgCount--;
103c2c66affSColin Finck 
104c2c66affSColin Finck             Control(SERVICE_CONTROL_INTERROGATE,
105c2c66affSColin Finck                     ServiceName,
106c2c66affSColin Finck                     ServiceArgs,
107c2c66affSColin Finck                     ArgCount);
108c2c66affSColin Finck         }
109c2c66affSColin Finck         else
110c2c66affSColin Finck             InterrogateUsage();
111c2c66affSColin Finck     }
112c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("stop")))
113c2c66affSColin Finck     {
114c2c66affSColin Finck         if (ArgCount > 0)
115c2c66affSColin Finck         {
116c2c66affSColin Finck             ServiceName = *ServiceArgs++;
117c2c66affSColin Finck             ArgCount--;
118c2c66affSColin Finck 
119c2c66affSColin Finck             Control(SERVICE_CONTROL_STOP,
120c2c66affSColin Finck                     ServiceName,
121c2c66affSColin Finck                     ServiceArgs,
122c2c66affSColin Finck                     ArgCount);
123c2c66affSColin Finck         }
124c2c66affSColin Finck         else
125c2c66affSColin Finck             StopUsage();
126c2c66affSColin Finck     }
127c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("continue")))
128c2c66affSColin Finck     {
129c2c66affSColin Finck         if (ArgCount > 0)
130c2c66affSColin Finck         {
131c2c66affSColin Finck             ServiceName = *ServiceArgs++;
132c2c66affSColin Finck             ArgCount--;
133c2c66affSColin Finck 
134c2c66affSColin Finck             Control(SERVICE_CONTROL_CONTINUE,
135c2c66affSColin Finck                     ServiceName,
136c2c66affSColin Finck                     ServiceArgs,
137c2c66affSColin Finck                     ArgCount);
138c2c66affSColin Finck         }
139c2c66affSColin Finck         else
140c2c66affSColin Finck             ContinueUsage();
141c2c66affSColin Finck     }
142c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("delete")))
143c2c66affSColin Finck     {
144c2c66affSColin Finck         if (ArgCount > 0)
145c2c66affSColin Finck         {
146c2c66affSColin Finck             ServiceName = *ServiceArgs++;
147c2c66affSColin Finck             ArgCount--;
148c2c66affSColin Finck 
149c2c66affSColin Finck             Delete(ServiceName);
150c2c66affSColin Finck         }
151c2c66affSColin Finck         else
152c2c66affSColin Finck             DeleteUsage();
153c2c66affSColin Finck     }
154c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("create")))
155c2c66affSColin Finck     {
156c2c66affSColin Finck         Create(ServiceArgs, ArgCount);
157c2c66affSColin Finck     }
158c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("control")))
159c2c66affSColin Finck     {
160*a0d412b7SEric Kohl         INT ControlCode = 0;
161c2c66affSColin Finck 
162c2c66affSColin Finck         if (ArgCount > 1)
163c2c66affSColin Finck         {
164c2c66affSColin Finck             ServiceName = *ServiceArgs++;
165c2c66affSColin Finck             ArgCount--;
166c2c66affSColin Finck 
167*a0d412b7SEric Kohl             if (!lstrcmpi(ServiceArgs[0], _T("paramchange")))
168*a0d412b7SEric Kohl                 ControlCode = SERVICE_CONTROL_PARAMCHANGE;
169*a0d412b7SEric Kohl             else if (!lstrcmpi(ServiceArgs[0], _T("netbindadd")))
170*a0d412b7SEric Kohl                 ControlCode = SERVICE_CONTROL_NETBINDADD;
171*a0d412b7SEric Kohl             else if (!lstrcmpi(ServiceArgs[0], _T("netbindremove")))
172*a0d412b7SEric Kohl                 ControlCode = SERVICE_CONTROL_NETBINDREMOVE;
173*a0d412b7SEric Kohl             else if (!lstrcmpi(ServiceArgs[0], _T("netbindenable")))
174*a0d412b7SEric Kohl                 ControlCode = SERVICE_CONTROL_NETBINDENABLE;
175*a0d412b7SEric Kohl             else if (!lstrcmpi(ServiceArgs[0], _T("netbinddisable")))
176*a0d412b7SEric Kohl                 ControlCode = SERVICE_CONTROL_NETBINDDISABLE;
177*a0d412b7SEric Kohl             else
178*a0d412b7SEric Kohl             {
179*a0d412b7SEric Kohl                 ControlCode = _ttoi(ServiceArgs[0]);
180*a0d412b7SEric Kohl                 if ((ControlCode < 128) && (ControlCode > 255))
181*a0d412b7SEric Kohl                     ControlCode = 0;
182*a0d412b7SEric Kohl             }
183*a0d412b7SEric Kohl 
184c2c66affSColin Finck             ServiceArgs++;
185c2c66affSColin Finck             ArgCount--;
186c2c66affSColin Finck 
187*a0d412b7SEric Kohl             if (ControlCode != 0)
188*a0d412b7SEric Kohl                 Control(ControlCode,
189c2c66affSColin Finck                         ServiceName,
190c2c66affSColin Finck                         ServiceArgs,
191c2c66affSColin Finck                         ArgCount);
192c2c66affSColin Finck             else
193c2c66affSColin Finck                 ControlUsage();
194c2c66affSColin Finck         }
195c2c66affSColin Finck         else
196c2c66affSColin Finck             ControlUsage();
197c2c66affSColin Finck     }
198c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("sdshow")))
199c2c66affSColin Finck     {
200c2c66affSColin Finck         if (ArgCount > 0)
201c2c66affSColin Finck         {
202c2c66affSColin Finck             ServiceName = *ServiceArgs++;
203c2c66affSColin Finck             ArgCount--;
204c2c66affSColin Finck 
205c2c66affSColin Finck             SdShow(ServiceName);
206c2c66affSColin Finck         }
207c2c66affSColin Finck         else
208c2c66affSColin Finck             SdShowUsage();
209c2c66affSColin Finck     }
210c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("sdset")))
211c2c66affSColin Finck     {
212c2c66affSColin Finck         LPCTSTR SecurityDescriptor;
213c2c66affSColin Finck 
214c2c66affSColin Finck         if (ArgCount > 1)
215c2c66affSColin Finck         {
216c2c66affSColin Finck             ServiceName = *ServiceArgs++;
217c2c66affSColin Finck             ArgCount--;
218c2c66affSColin Finck 
219c2c66affSColin Finck             SecurityDescriptor = *ServiceArgs++;
220c2c66affSColin Finck             ArgCount--;
221c2c66affSColin Finck 
222c2c66affSColin Finck             SdSet(ServiceName, SecurityDescriptor);
223c2c66affSColin Finck         }
224c2c66affSColin Finck         else
225c2c66affSColin Finck             SdSetUsage();
226c2c66affSColin Finck     }
227c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("qc")))
228c2c66affSColin Finck     {
229c2c66affSColin Finck         if (ArgCount > 0)
230c2c66affSColin Finck         {
231c2c66affSColin Finck             ServiceName = *ServiceArgs++;
232c2c66affSColin Finck             ArgCount--;
233c2c66affSColin Finck 
234c2c66affSColin Finck             QueryConfig(ServiceName);
235c2c66affSColin Finck         }
236c2c66affSColin Finck         else
237c2c66affSColin Finck             QueryConfigUsage();
238c2c66affSColin Finck     }
239c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("qdescription")))
240c2c66affSColin Finck     {
241c2c66affSColin Finck         if (ArgCount > 0)
242c2c66affSColin Finck         {
243c2c66affSColin Finck             ServiceName = *ServiceArgs++;
244c2c66affSColin Finck             ArgCount--;
245c2c66affSColin Finck 
246c2c66affSColin Finck             QueryDescription(ServiceName);
247c2c66affSColin Finck         }
248c2c66affSColin Finck         else
249c2c66affSColin Finck             QueryDescriptionUsage();
250c2c66affSColin Finck     }
251c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("qfailure")))
252c2c66affSColin Finck     {
253c2c66affSColin Finck         if (ArgCount > 0)
254c2c66affSColin Finck         {
255c2c66affSColin Finck             ServiceName = *ServiceArgs++;
256c2c66affSColin Finck             ArgCount--;
257c2c66affSColin Finck 
258c2c66affSColin Finck             QueryFailure(ServiceName);
259c2c66affSColin Finck         }
260c2c66affSColin Finck         else
261c2c66affSColin Finck             QueryFailureUsage();
262c2c66affSColin Finck     }
263c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("description")))
264c2c66affSColin Finck     {
265c2c66affSColin Finck         LPCTSTR Description = NULL;
266c2c66affSColin Finck 
267c2c66affSColin Finck         if (ArgCount > 0)
268c2c66affSColin Finck         {
269c2c66affSColin Finck             ServiceName = *ServiceArgs++;
270c2c66affSColin Finck             ArgCount--;
271c2c66affSColin Finck 
272c2c66affSColin Finck             if (ArgCount > 0)
273c2c66affSColin Finck             {
274c2c66affSColin Finck                 Description = *ServiceArgs++;
275c2c66affSColin Finck                 ArgCount--;
276c2c66affSColin Finck             }
277c2c66affSColin Finck 
278c2c66affSColin Finck             SetDescription(ServiceName, Description);
279c2c66affSColin Finck         }
280c2c66affSColin Finck         else
281c2c66affSColin Finck             SetDescriptionUsage();
282c2c66affSColin Finck     }
283c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("config")))
284c2c66affSColin Finck     {
285c2c66affSColin Finck         SetConfig(ServiceArgs, ArgCount);
286c2c66affSColin Finck     }
287c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("failure")))
288c2c66affSColin Finck     {
289c2c66affSColin Finck         SetFailure(ServiceArgs, ArgCount);
290c2c66affSColin Finck     }
291c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("GetDisplayName")))
292c2c66affSColin Finck     {
293c2c66affSColin Finck         if (ArgCount > 0)
294c2c66affSColin Finck         {
295c2c66affSColin Finck             ServiceName = *ServiceArgs++;
296c2c66affSColin Finck             ArgCount--;
297c2c66affSColin Finck 
298c2c66affSColin Finck             GetDisplayName(ServiceName);
299c2c66affSColin Finck         }
300c2c66affSColin Finck         else
301c2c66affSColin Finck             GetDisplayNameUsage();
302c2c66affSColin Finck     }
303c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("GetKeyName")))
304c2c66affSColin Finck     {
305c2c66affSColin Finck         if (ArgCount > 0)
306c2c66affSColin Finck         {
307c2c66affSColin Finck             ServiceName = *ServiceArgs++;
308c2c66affSColin Finck             ArgCount--;
309c2c66affSColin Finck 
310c2c66affSColin Finck             GetKeyName(ServiceName);
311c2c66affSColin Finck         }
312c2c66affSColin Finck         else
313c2c66affSColin Finck             GetKeyNameUsage();
314c2c66affSColin Finck     }
315c2c66affSColin Finck     else if (!lstrcmpi(Command, _T("EnumDepend")))
316c2c66affSColin Finck     {
317c2c66affSColin Finck         if (ArgCount > 0)
318c2c66affSColin Finck         {
319c2c66affSColin Finck             ServiceName = *ServiceArgs++;
320c2c66affSColin Finck             ArgCount--;
321c2c66affSColin Finck 
322c2c66affSColin Finck             EnumDepend(ServiceName);
323c2c66affSColin Finck         }
324c2c66affSColin Finck         else
325c2c66affSColin Finck             EnumDependUsage();
326c2c66affSColin Finck     }
327c2c66affSColin Finck     else
328c2c66affSColin Finck     {
329c2c66affSColin Finck         MainUsage();
330c2c66affSColin Finck     }
331c2c66affSColin Finck 
332c2c66affSColin Finck     return 0;
333c2c66affSColin Finck }
334c2c66affSColin Finck 
335c2c66affSColin Finck int _tmain(int argc, LPCTSTR argv[])
336c2c66affSColin Finck {
337c2c66affSColin Finck     LPCTSTR Server = NULL;   // remote machine
338c2c66affSColin Finck     LPCTSTR Command = NULL;  // sc command
339c2c66affSColin Finck     LPCTSTR *Args = NULL;    // Any remaining args
340c2c66affSColin Finck 
341c2c66affSColin Finck     if (argc < 2)
342c2c66affSColin Finck     {
343c2c66affSColin Finck         MainUsage();
344c2c66affSColin Finck         return -1;
345c2c66affSColin Finck     }
346c2c66affSColin Finck 
347c2c66affSColin Finck     /* get server name */
348c2c66affSColin Finck     if ((argv[1][0] == '\\') && (argv[1][1] == '\\'))
349c2c66affSColin Finck     {
350c2c66affSColin Finck         if (argc < 3)
351c2c66affSColin Finck         {
352c2c66affSColin Finck             MainUsage();
353c2c66affSColin Finck             return -1;
354c2c66affSColin Finck         }
355c2c66affSColin Finck 
356c2c66affSColin Finck         Server = argv[1];
357c2c66affSColin Finck         Command = argv[2];
358c2c66affSColin Finck         if (argc > 3)
359c2c66affSColin Finck             Args = &argv[3];
360c2c66affSColin Finck 
361c2c66affSColin Finck         return ScControl(Server,
362c2c66affSColin Finck                          Command,
363c2c66affSColin Finck                          Args,
364c2c66affSColin Finck                          argc-3);
365c2c66affSColin Finck     }
366c2c66affSColin Finck     else
367c2c66affSColin Finck     {
368c2c66affSColin Finck         Command = argv[1];
369c2c66affSColin Finck         if (argc > 2)
370c2c66affSColin Finck             Args = &argv[2];
371c2c66affSColin Finck 
372c2c66affSColin Finck         return ScControl(Server,
373c2c66affSColin Finck                          Command,
374c2c66affSColin Finck                          Args,
375c2c66affSColin Finck                          argc-2);
376c2c66affSColin Finck     }
377c2c66affSColin Finck }
378