2 * ReactOS SC - service control console program
6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 #define TARGET "UNICODE"
36 BOOL verbose_flagged
= 0;
37 BOOL status_flagged
= 0;
43 void dprintf(char* fmt
, ...)
49 wvsprintfA(buffer
, fmt
, args
);
50 WriteConsoleA(OutputHandle
, buffer
, lstrlenA(buffer
), NULL
, NULL
);
54 long getinput(char* buf
, int buflen
)
58 ReadConsoleA(InputHandle
, buf
, buflen
, &result
, NULL
);
62 DWORD
ReportLastError(void)
64 DWORD dwError
= GetLastError();
65 if (dwError
!= ERROR_SUCCESS
) {
67 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|FORMAT_MESSAGE_FROM_SYSTEM
,
68 0, dwError
, MAKELANGID(LANG_NEUTRAL
,SUBLANG_DEFAULT
), (PTSTR
)&msg
, 0, NULL
)) {
70 dprintf("ReportLastError() %d - %s\n", dwError
, msg
);
72 dprintf("ERROR: ReportLastError() %d - returned TRUE but with no msg string!\n", dwError
);
75 dprintf("ReportLastError() %d - unknown error\n", dwError
);
84 int usage(char* argv0
)
86 dprintf("DESCRIPTION:\n");
87 dprintf("\tSC is a command line program used for communicating with\n");
88 dprintf("\tthe Service Control Manager and its services.\n");
90 dprintf("\tsc <server> [command] [service name] <option1> <option2>...\n");
92 dprintf("\tThe optional parameter <server> has the form \"\\ServerName\"\n");
93 dprintf("\tFurther help on commands can be obtained by typing: \"sc [command]\"\n");
94 dprintf("\tService Commands:\n");
95 dprintf("\t query : Queries the status for a service, or\n");
96 dprintf("\t enumerates the status for types of services.\n");
97 dprintf("\t queryex : Queries the extended status for a service, or\n");
98 dprintf("\t enumerates the status for types of services.\n");
99 dprintf("\t start : Starts a service.\n");
100 dprintf("\t pause : Sends a PAUSE control request to a service.\n");
101 dprintf("\t interrogate : Sends a INTERROGATE control request to a service.\n");
102 dprintf("\t continue : Sends a CONTINUE control request to a service.\n");
103 dprintf("\t stop : Sends a STOP request to a service.\n");
104 dprintf("\t config : Changes the configuration of a service (persistant).\n");
105 dprintf("\t description : Changes the description of a service.\n");
106 dprintf("\t failure : Changes the actions taken by a service upon failure.\n");
107 dprintf("\t qc : Queries the configuration information for a service.\n");
108 dprintf("\t qdescription : Queries the description for a service.\n");
109 dprintf("\t qfailure : Queries the actions taken by a service upon failure.\n");
110 dprintf("\t delete : Deletes a service (from the registry).\n");
111 dprintf("\t create : Creates a service. (adds it to the registry).\n");
112 dprintf("\t control : Sends a control to a service.\n");
113 // dprintf("\t sdshow : Displays a service's security descriptor.\n");
114 // dprintf("\t sdset : Sets a service's security descriptor.\n");
115 dprintf("\t GetDisplayName : Gets the DisplayName for a service.\n");
116 dprintf("\t GetKeyName : Gets the ServiceKeyName for a service.\n");
117 dprintf("\t EnumDepend : Enumerates Service Dependencies.\n");
119 dprintf("\tService Name Independant Commands:\n");
120 dprintf("\t boot : (ok | bad) Indicates whether the last boot should\n");
121 dprintf("\t be saved as the last-known-good boot configuration\n");
122 dprintf("\t Lock : Locks the SCM Database\n");
123 dprintf("\t QueryLock : Queries the LockStatus for the SCM Database\n");
129 typedef int (*sc_cmd_proc
)(SC_HANDLE hSCManager
, SC_CMDS sc_cmd
, char* argv
[]);
135 DWORD dwDesiredAccess
;
138 sc_cmd_entry sc_cmds_table
[] = {
139 { SC_CMD_QUERY
, "query", sc_query
, SC_MANAGER_ALL_ACCESS
},
140 { SC_CMD_QUERYEX
, "queryex", sc_query
, SC_MANAGER_ALL_ACCESS
},
141 { SC_CMD_START
, "start", sc_command
, 0L },
142 { SC_CMD_PAUSE
, "pause", sc_command
, 0L },
143 { SC_CMD_INTERROGATE
, "interrogate", sc_command
, 0L },
144 { SC_CMD_CONTINUE
, "continue", sc_command
, 0L },
145 { SC_CMD_STOP
, "stop", sc_command
, 0L },
146 { SC_CMD_CONFIG
, "config", sc_setup
, 0L },
147 { SC_CMD_DESCRIPTION
, "description", sc_setup
, 0L },
148 { SC_CMD_FAILURE
, "failure", sc_setup
, 0L },
149 { SC_CMD_QC
, "qc", sc_query
, 0L },
150 { SC_CMD_QDESCRIPTION
, "qdescription", sc_query
, 0L },
151 { SC_CMD_QFAILURE
, "qfailure", sc_query
, 0L },
152 { SC_CMD_DELETE
, "delete", sc_setup
, 0L },
153 { SC_CMD_CREATE
, "create", sc_setup
, 0L },
154 { SC_CMD_CONTROL
, "control", sc_setup
, 0L },
155 { SC_CMD_SDSHOW
, "sdshow", sc_query
, 0L },
156 { SC_CMD_SDSET
, "sdset", sc_setup
, 0L },
157 { SC_CMD_GETDISPLAYNAME
, "GetDisplayName", sc_query
, 0L },
158 { SC_CMD_GETKEYNAME
, "GetKeyName", sc_query
, 0L },
159 { SC_CMD_ENUMDEPEND
, "EnumDepend", sc_query
, 0L },
160 { SC_CMD_BOOT
, "boot", sc_config
, 0L },
161 { SC_CMD_LOCK
, "Lock", sc_config
, 0L },
162 { SC_CMD_QUERYLOCK
, "QueryLock", sc_config
, 0L }
166 int sc_main(const sc_cmd_entry
* cmd_entry
,
167 const char* sc_machine_name
,
171 SC_HANDLE hSCManager
;
172 DWORD dwDesiredAccess
;
174 dprintf("sc_main(%s) - called.\n", cmd_entry
->cmd_str
);
175 if (sc_machine_name
) {
176 dprintf("remote service control not yet implemented.\n");
179 dwDesiredAccess
= cmd_entry
->dwDesiredAccess
;
180 if (!dwDesiredAccess
) dwDesiredAccess
= SC_MANAGER_CONNECT
+ GENERIC_READ
;
182 hSCManager
= OpenSCManagerA(sc_machine_name
, NULL
, dwDesiredAccess
);
183 //hSCManager = OpenSCManagerW(NULL, NULL, dwDesiredAccess);
184 if (hSCManager
!= NULL
) {
185 result
= cmd_entry
->funcptr(hSCManager
, cmd_entry
->sc_cmd
, sc_cmd_arg
);
186 if (!CloseServiceHandle(hSCManager
)) {
187 dprintf("Failed to CLOSE handle to SCM.\n");
191 dprintf("Failed to open Service Control Manager.\n");
198 int __cdecl
main(int argc
, char* argv
[])
201 const char* sc_machine_name
= NULL
;
202 const char* sc_cmd_str
= argv
[1];
203 char** sc_cmd_arg
= NULL
;
206 InputHandle
= GetStdHandle(STD_INPUT_HANDLE
);
207 OutputHandle
= GetStdHandle(STD_OUTPUT_HANDLE
);
209 dprintf("%s application - build %03d (default: %s)\n", argv
[0], VERSION
, TARGET
);
211 return usage(argv
[0]);
214 if ((argv
[1][0] == '\\') && (argv
[1][1] == '\\')) {
216 return usage(argv
[0]);
218 sc_machine_name
= argv
[1];
219 sc_cmd_str
= argv
[2];
220 sc_cmd_arg
= &argv
[3];
222 sc_machine_name
= NULL
;
223 sc_cmd_str
= argv
[1];
224 sc_cmd_arg
= &argv
[2];
227 for (i
= 0; i
< sizeof(sc_cmds_table
)/sizeof(sc_cmd_entry
); i
++) {
228 sc_cmd_entry
* cmd_entry
= &(sc_cmds_table
[i
]);
229 if (lstrcmpiA(sc_cmd_str
, cmd_entry
->cmd_str
) == 0) {
230 return sc_main(cmd_entry
, sc_machine_name
, sc_cmd_arg
);
233 return usage(argv
[0]);
239 //char* args[] = { "sc.exe", "pause", "smplserv" };
240 char* args
[] = { "sc.exe", "EnumDepend", "" };
242 int __cdecl
mainCRTStartup(void)