From 5e9d2fc44ad90c8301e0369e3e60255a14a26f5b Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Mon, 3 May 2010 12:57:22 +0200 Subject: [PATCH] sc: Implement the create and delete commands. --- programs/sc/Makefile.in | 2 +- programs/sc/sc.c | 183 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 181 insertions(+), 4 deletions(-) diff --git a/programs/sc/Makefile.in b/programs/sc/Makefile.in index 71a20cc66a1..4d34f5a81b8 100644 --- a/programs/sc/Makefile.in +++ b/programs/sc/Makefile.in @@ -4,7 +4,7 @@ SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = sc.exe APPMODE = -mconsole -municode -IMPORTS = kernel32 +IMPORTS = advapi32 kernel32 EXTRADEFS = -DWINE_NO_UNICODE_MACROS C_SRCS = sc.c diff --git a/programs/sc/sc.c b/programs/sc/sc.c index 6eb9c9e7a71..1994fff7378 100644 --- a/programs/sc/sc.c +++ b/programs/sc/sc.c @@ -16,12 +16,189 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define WIN32_LEAN_AND_MEAN + #include "wine/debug.h" +#include "wine/unicode.h" + +#include +#include +#include +#include WINE_DEFAULT_DEBUG_CHANNEL(sc); -int wmain( int argc, WCHAR *argv[] ) +struct create_params { - WINE_FIXME("stub\n"); - return 1; + const WCHAR *displayname; + const WCHAR *binpath; + const WCHAR *group; + const WCHAR *depend; + const WCHAR *obj; + const WCHAR *password; + DWORD type; + DWORD start; + DWORD error; + BOOL tag; +}; + +static BOOL parse_create_params( int argc, const WCHAR *argv[], struct create_params *cp ) +{ + static const WCHAR displaynameW[] = {'d','i','s','p','l','a','y','n','a','m','e','=',0}; + static const WCHAR typeW[] = {'t','y','p','e','=',0}; + static const WCHAR startW[] = {'s','t','a','r','t','=',0}; + static const WCHAR errorW[] = {'e','r','r','o','r','=',0}; + static const WCHAR binpathW[] = {'b','i','n','p','a','t','h','=',0}; + static const WCHAR groupW[] = {'g','r','o','u','p','=',0}; + static const WCHAR tagW[] = {'t','a','g','=',0}; + static const WCHAR dependW[] = {'d','e','p','e','n','d','=',0}; + static const WCHAR objW[] = {'o','b','j','=',0}; + static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d','=',0}; + unsigned int i; + + cp->displayname = NULL; + cp->type = SERVICE_WIN32_OWN_PROCESS; + cp->start = SERVICE_DEMAND_START; + cp->error = SERVICE_ERROR_NORMAL; + cp->binpath = NULL; + cp->group = NULL; + cp->tag = FALSE; + cp->depend = NULL; + cp->obj = NULL; + cp->password = NULL; + + for (i = 0; i < argc; i++) + { + if (!strcmpiW( argv[i], displaynameW ) && i < argc - 1) cp->displayname = argv[i + 1]; + if (!strcmpiW( argv[i], binpathW ) && i < argc - 1) cp->binpath = argv[i + 1]; + if (!strcmpiW( argv[i], groupW ) && i < argc - 1) cp->group = argv[i + 1]; + if (!strcmpiW( argv[i], dependW ) && i < argc - 1) cp->depend = argv[i + 1]; + if (!strcmpiW( argv[i], objW ) && i < argc - 1) cp->obj = argv[i + 1]; + if (!strcmpiW( argv[i], passwordW ) && i < argc - 1) cp->password = argv[i + 1]; + + if (!strcmpiW( argv[i], tagW ) && i < argc - 1) + { + static const WCHAR yesW[] = {'y','e','s',0}; + if (!strcmpiW( argv[i], yesW )) + { + WINE_FIXME("tag argument not supported\n"); + cp->tag = TRUE; + } + } + if (!strcmpiW( argv[i], typeW ) && i < argc - 1) + { + static const WCHAR ownW[] = {'o','w','n',0}; + static const WCHAR shareW[] = {'s','h','a','r','e',0}; + static const WCHAR kernelW[] = {'k','e','r','n','e','l',0}; + static const WCHAR filesysW[] = {'f','i','l','e','s','y','s',0}; + static const WCHAR recW[] = {'r','e','c',0}; + static const WCHAR interactW[] = {'i','n','t','e','r','a','c','t',0}; + + if (!strcmpiW( argv[i + 1], ownW )) cp->type = SERVICE_WIN32_OWN_PROCESS; + if (!strcmpiW( argv[i + 1], shareW )) cp->type = SERVICE_WIN32_SHARE_PROCESS; + if (!strcmpiW( argv[i + 1], kernelW )) cp->type = SERVICE_KERNEL_DRIVER; + if (!strcmpiW( argv[i + 1], filesysW )) cp->type = SERVICE_FILE_SYSTEM_DRIVER; + if (!strcmpiW( argv[i + 1], recW )) cp->type = SERVICE_RECOGNIZER_DRIVER; + if (!strcmpiW( argv[i + 1], interactW )) cp->type |= SERVICE_INTERACTIVE_PROCESS; + } + if (!strcmpiW( argv[i], startW ) && i < argc - 1) + { + static const WCHAR bootW[] = {'b','o','o','t',0}; + static const WCHAR systemW[] = {'s','y','s','t','e','m',0}; + static const WCHAR autoW[] = {'a','u','t','o',0}; + static const WCHAR demandW[] = {'d','e','m','a','n','d',0}; + static const WCHAR disabledW[] = {'d','i','s','a','b','l','e','d',0}; + + if (!strcmpiW( argv[i + 1], bootW )) cp->start = SERVICE_BOOT_START; + if (!strcmpiW( argv[i + 1], systemW )) cp->start = SERVICE_SYSTEM_START; + if (!strcmpiW( argv[i + 1], autoW )) cp->start = SERVICE_AUTO_START; + if (!strcmpiW( argv[i + 1], demandW )) cp->start = SERVICE_DEMAND_START; + if (!strcmpiW( argv[i + 1], disabledW )) cp->start = SERVICE_DISABLED; + } + if (!strcmpiW( argv[i], errorW ) && i < argc - 1) + { + static const WCHAR normalW[] = {'n','o','r','m','a','l',0}; + static const WCHAR severeW[] = {'s','e','v','e','r','e',0}; + static const WCHAR criticalW[] = {'c','r','i','t','i','c','a','l',0}; + static const WCHAR ignoreW[] = {'i','g','n','o','r','e',0}; + + if (!strcmpiW( argv[i + 1], normalW )) cp->error = SERVICE_ERROR_NORMAL; + if (!strcmpiW( argv[i + 1], severeW )) cp->error = SERVICE_ERROR_SEVERE; + if (!strcmpiW( argv[i + 1], criticalW )) cp->error = SERVICE_ERROR_CRITICAL; + if (!strcmpiW( argv[i + 1], ignoreW )) cp->error = SERVICE_ERROR_IGNORE; + } + } + if (!cp->binpath) return FALSE; + return TRUE; +} + +static void usage( void ) +{ + WINE_MESSAGE( "Usage: sc command servicename [parameter= value ...]\n" ); + exit( 1 ); +} + +int wmain( int argc, const WCHAR *argv[] ) +{ + static const WCHAR createW[] = {'c','r','e','a','t','e',0}; + static const WCHAR deleteW[] = {'d','e','l','e','t','e',0}; + SC_HANDLE manager, service; + BOOL ret = FALSE; + + if (argc < 3) usage(); + + if (argv[2][0] == '\\' && argv[2][1] == '\\') + { + WINE_FIXME("server argument not supported\n"); + return 1; + } + + manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ALL_ACCESS ); + if (!manager) + { + WINE_ERR("failed to open service manager\n"); + return 1; + } + + if (!strcmpiW( argv[1], createW )) + { + struct create_params cp; + + if (argc < 4) + { + CloseServiceHandle( manager ); + usage(); + } + if (!parse_create_params( argc - 3, argv + 3, &cp )) + { + WINE_WARN("failed to parse create parameters\n"); + CloseServiceHandle( manager ); + return 1; + } + service = CreateServiceW( manager, argv[2], cp.displayname, SERVICE_ALL_ACCESS, + cp.type, cp.start, cp.error, cp.binpath, cp.group, NULL, + cp.depend, cp.obj, cp.password ); + if (service) + { + CloseServiceHandle( service ); + ret = TRUE; + } + else WINE_TRACE("failed to create service %u\n", GetLastError()); + } + else if (!strcmpiW( argv[1], deleteW )) + { + service = OpenServiceW( manager, argv[2], DELETE ); + if (service) + { + ret = DeleteService( service ); + if (!ret) WINE_TRACE("failed to delete service %u\n", GetLastError()); + CloseServiceHandle( service ); + } + else WINE_TRACE("failed to open service %u\n", GetLastError()); + } + else + WINE_FIXME("command not supported\n"); + + CloseServiceHandle( manager ); + return !ret; }