sc/tests: Add tests.
Signed-off-by: Torge Matthies <tmatthies@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4643bb2852
commit
a2bc9e5f36
|
@ -22076,6 +22076,7 @@ wine_fn_config_makefile programs/rpcss enable_rpcss
|
|||
wine_fn_config_makefile programs/rundll.exe16 enable_win16
|
||||
wine_fn_config_makefile programs/rundll32 enable_rundll32
|
||||
wine_fn_config_makefile programs/sc enable_sc
|
||||
wine_fn_config_makefile programs/sc/tests enable_tests
|
||||
wine_fn_config_makefile programs/schtasks enable_schtasks
|
||||
wine_fn_config_makefile programs/schtasks/tests enable_tests
|
||||
wine_fn_config_makefile programs/sdbinst enable_sdbinst
|
||||
|
|
|
@ -3322,6 +3322,7 @@ WINE_CONFIG_MAKEFILE(programs/rpcss)
|
|||
WINE_CONFIG_MAKEFILE(programs/rundll.exe16,enable_win16)
|
||||
WINE_CONFIG_MAKEFILE(programs/rundll32)
|
||||
WINE_CONFIG_MAKEFILE(programs/sc)
|
||||
WINE_CONFIG_MAKEFILE(programs/sc/tests)
|
||||
WINE_CONFIG_MAKEFILE(programs/schtasks)
|
||||
WINE_CONFIG_MAKEFILE(programs/schtasks/tests)
|
||||
WINE_CONFIG_MAKEFILE(programs/sdbinst)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
TESTDLL = sc.exe
|
||||
IMPORTS = advapi32
|
||||
|
||||
C_SRCS = \
|
||||
sc.c
|
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
* Copyright 2022 Torge Matthies for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <winsvc.h>
|
||||
#include <stdio.h>
|
||||
#include "wine/test.h"
|
||||
|
||||
#define lok ok_(__FILE__,line)
|
||||
|
||||
#define TEST_SERVICE_NAME "wine_test_svc"
|
||||
#define TEST_SERVICE_NAME2 "wine_test_svc_2"
|
||||
#define TEST_SERVICE_BINARY "c:\\windows\\system32\\cmd.exe"
|
||||
#define TEST_SERVICE_BINARY_START_BOOT "\\SystemRoot\\system32\\cmd.exe"
|
||||
#define TEST_SERVICE_BINARY_START_SYSTEM "\\??\\" TEST_SERVICE_BINARY
|
||||
|
||||
#define SC_EXIT_SUCCESS ERROR_SUCCESS
|
||||
#define SC_EXIT_INVALID_PARAMETER ERROR_INVALID_PARAMETER
|
||||
#define SC_EXIT_CIRCULAR_DEPENDENCY ERROR_CIRCULAR_DEPENDENCY
|
||||
#define SC_EXIT_SERVICE_DOES_NOT_EXIST ERROR_SERVICE_DOES_NOT_EXIST
|
||||
#define SC_EXIT_SERVICE_EXISTS ERROR_SERVICE_EXISTS
|
||||
#define SC_EXIT_INVALID_COMMAND_LINE ERROR_INVALID_COMMAND_LINE
|
||||
|
||||
static HANDLE nul_file;
|
||||
static SC_HANDLE scmgr;
|
||||
|
||||
/* Copied and modified from the reg.exe tests */
|
||||
#define run_sc_exe(c,r) run_sc_exe_(__FILE__,__LINE__,c,r)
|
||||
static BOOL run_sc_exe_(const char *file, unsigned line, const char *cmd, DWORD *rc)
|
||||
{
|
||||
STARTUPINFOA si = {sizeof(STARTUPINFOA)};
|
||||
PROCESS_INFORMATION pi;
|
||||
BOOL bret;
|
||||
DWORD ret;
|
||||
char cmdline[256];
|
||||
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.hStdInput = nul_file;
|
||||
si.hStdOutput = nul_file;
|
||||
si.hStdError = nul_file;
|
||||
|
||||
strcpy(cmdline, cmd);
|
||||
if (!CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
|
||||
return FALSE;
|
||||
|
||||
ret = WaitForSingleObject(pi.hProcess, 10000);
|
||||
if (ret == WAIT_TIMEOUT)
|
||||
TerminateProcess(pi.hProcess, 1);
|
||||
|
||||
bret = GetExitCodeProcess(pi.hProcess, rc);
|
||||
lok(bret, "GetExitCodeProcess failed: %ld\n", GetLastError());
|
||||
|
||||
CloseHandle(pi.hThread);
|
||||
CloseHandle(pi.hProcess);
|
||||
return bret;
|
||||
}
|
||||
|
||||
#define BROKEN_CREATE 0x000000001UL
|
||||
#define BROKEN_BINPATH 0x000000002UL
|
||||
#define BROKEN_TYPE 0x000000004UL
|
||||
#define BROKEN_START 0x000000008UL
|
||||
#define BROKEN_ERROR 0x000000010UL
|
||||
#define BROKEN_DEPEND 0x000000020UL
|
||||
#define BROKEN_DISPLAY_NAME 0x000000040UL
|
||||
#define BROKEN_DELAYED_AUTO_START 0x000000080UL
|
||||
#define BROKEN_ALL ~0UL
|
||||
|
||||
#define SERVICE_DELAYED_AUTO_START (SERVICE_AUTO_START | 0x80000000)
|
||||
|
||||
#define check_service_definition(n,bi,t,s,e,de,di,br) check_service_definition_(__FILE__,__LINE__,n,bi,t,s,e,de,di,br)
|
||||
static void check_service_definition_(const char *file, unsigned line, char const *name,
|
||||
const char *binpath, DWORD type, DWORD start, DWORD error,
|
||||
const char *depend, const char *display_name, DWORD broken)
|
||||
{
|
||||
SERVICE_DELAYED_AUTO_START_INFO delayed_auto_info = {0};
|
||||
union {
|
||||
char buffer[8192];
|
||||
QUERY_SERVICE_CONFIGA config;
|
||||
} cfg;
|
||||
BOOL delayed_auto;
|
||||
SC_HANDLE svc;
|
||||
DWORD needed;
|
||||
BOOL ret;
|
||||
|
||||
delayed_auto = !!(start & 0x80000000);
|
||||
start &= ~0x80000000;
|
||||
|
||||
if (!scmgr)
|
||||
return;
|
||||
|
||||
svc = OpenServiceA(scmgr, name, GENERIC_READ);
|
||||
todo_wine_if(broken & BROKEN_CREATE)
|
||||
lok(!!svc, "OpenServiceA failed: %ld\n", GetLastError());
|
||||
if (!svc)
|
||||
return;
|
||||
|
||||
ret = QueryServiceConfigA(svc, &cfg.config, sizeof(cfg.buffer), &needed);
|
||||
lok(!!ret, "QueryServiceConfigA failed: %ld\n", GetLastError());
|
||||
if (!ret)
|
||||
goto done;
|
||||
|
||||
ret = QueryServiceConfig2A(svc, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, (LPBYTE)&delayed_auto_info,
|
||||
sizeof(delayed_auto_info), &needed);
|
||||
todo_wine lok(!!ret, "QueryServiceConfig2A(SERVICE_CONFIG_DELAYED_AUTO_START_INFO) failed: %ld\n",
|
||||
GetLastError());
|
||||
|
||||
#define check_str(a, b, msg) lok((a) && (b) && (a) != (b) && !strcmp((a), (b)), msg ": %s != %s\n", \
|
||||
debugstr_a((a)), debugstr_a((b)))
|
||||
#define check_dw(a, b, msg) lok((a) == (b), msg ": 0x%lx != 0x%lx\n", a, b)
|
||||
|
||||
todo_wine_if(broken & BROKEN_BINPATH)
|
||||
check_str(cfg.config.lpBinaryPathName, binpath, "Wrong binary path");
|
||||
todo_wine_if(broken & BROKEN_TYPE)
|
||||
check_dw(cfg.config.dwServiceType, type, "Wrong service type");
|
||||
todo_wine_if(broken & BROKEN_START)
|
||||
check_dw(cfg.config.dwStartType, start, "Wrong start type");
|
||||
todo_wine_if(broken & BROKEN_ERROR)
|
||||
check_dw(cfg.config.dwErrorControl, error, "Wrong error control");
|
||||
todo_wine_if(broken & BROKEN_DEPEND)
|
||||
check_str(cfg.config.lpDependencies, depend, "Wrong dependencies");
|
||||
todo_wine_if(broken & BROKEN_DISPLAY_NAME)
|
||||
check_str(cfg.config.lpDisplayName, display_name, "Wrong display name");
|
||||
todo_wine_if(broken & BROKEN_DELAYED_AUTO_START)
|
||||
check_dw((DWORD)delayed_auto_info.fDelayedAutostart, (DWORD)delayed_auto, "Wrong delayed autostart value");
|
||||
|
||||
#undef check_dw
|
||||
#undef check_str
|
||||
|
||||
done:
|
||||
CloseServiceHandle(svc);
|
||||
}
|
||||
|
||||
#define delete_service(n,e,b) delete_service_(__FILE__,__LINE__,n,e,b)
|
||||
static void delete_service_(const char *file, unsigned line, const char *name, DWORD expected_status, BOOL broken)
|
||||
{
|
||||
char command[256];
|
||||
BOOL bret;
|
||||
DWORD r;
|
||||
|
||||
strcpy(command, "sc delete ");
|
||||
strcat(command, name);
|
||||
bret = run_sc_exe_(file, line, command, &r);
|
||||
lok(bret, "run_sc_exe failed\n");
|
||||
if (expected_status != SC_EXIT_SUCCESS && !strcmp(winetest_platform, "wine"))
|
||||
expected_status = 1;
|
||||
todo_wine_if(broken) lok(r == expected_status, "got exit code %ld, expected %ld\n", r, expected_status);
|
||||
}
|
||||
|
||||
static void test_create_service(BOOL elevated)
|
||||
{
|
||||
static struct {
|
||||
const char *param;
|
||||
DWORD expected_start_type;
|
||||
DWORD expected_service_type;
|
||||
const char * expected_binary_path;
|
||||
} start_types[] = {
|
||||
{ "boot type= kernel", SERVICE_BOOT_START, SERVICE_KERNEL_DRIVER, TEST_SERVICE_BINARY_START_BOOT },
|
||||
{ "system type= kernel", SERVICE_SYSTEM_START, SERVICE_KERNEL_DRIVER, TEST_SERVICE_BINARY_START_SYSTEM },
|
||||
{ "auto", SERVICE_AUTO_START, SERVICE_WIN32_OWN_PROCESS, TEST_SERVICE_BINARY },
|
||||
{ "demand", SERVICE_DEMAND_START, SERVICE_WIN32_OWN_PROCESS, TEST_SERVICE_BINARY },
|
||||
{ "disabled", SERVICE_DISABLED, SERVICE_WIN32_OWN_PROCESS, TEST_SERVICE_BINARY },
|
||||
{ "delayed-auto", SERVICE_DELAYED_AUTO_START, SERVICE_WIN32_OWN_PROCESS, TEST_SERVICE_BINARY }
|
||||
};
|
||||
static struct {
|
||||
const char *param;
|
||||
DWORD expected_error_control;
|
||||
} error_severities[] = {
|
||||
{ "normal", SERVICE_ERROR_NORMAL },
|
||||
{ "severe", SERVICE_ERROR_SEVERE },
|
||||
{ "critical", SERVICE_ERROR_CRITICAL },
|
||||
{ "ignore", SERVICE_ERROR_IGNORE }
|
||||
};
|
||||
unsigned int i;
|
||||
DWORD r;
|
||||
|
||||
if (!elevated)
|
||||
{
|
||||
win_skip("\"sc create\" tests need elevated permissions\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#define check_exit_code(x) ok(r == (x), "got exit code %ld, expected %d\n", r, (x))
|
||||
#define check_test_service(t,s,e,de,di,br) \
|
||||
check_service_definition(TEST_SERVICE_NAME, TEST_SERVICE_BINARY, t, s, e, de, di ? di : TEST_SERVICE_NAME, br)
|
||||
#define delete_test_service(x, y) \
|
||||
delete_service(TEST_SERVICE_NAME, (x) ? SC_EXIT_SUCCESS : SC_EXIT_SERVICE_DOES_NOT_EXIST, (y))
|
||||
#define check_test_service2(t,s,e,de,di,br) \
|
||||
check_service_definition(TEST_SERVICE_NAME2, TEST_SERVICE_BINARY, t, s, e, de, di ? di : TEST_SERVICE_NAME2, br)
|
||||
#define delete_test_service2(x, y) \
|
||||
delete_service(TEST_SERVICE_NAME2, (x) ? SC_EXIT_SUCCESS : SC_EXIT_SERVICE_DOES_NOT_EXIST, (y))
|
||||
|
||||
/* too few parameters */
|
||||
|
||||
run_sc_exe("sc create", &r);
|
||||
todo_wine check_exit_code(SC_EXIT_INVALID_COMMAND_LINE);
|
||||
delete_test_service(FALSE, FALSE);
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME, &r);
|
||||
todo_wine check_exit_code(SC_EXIT_INVALID_COMMAND_LINE);
|
||||
delete_test_service(FALSE, FALSE);
|
||||
|
||||
/* binpath= */
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME " binpath= \"" TEST_SERVICE_BINARY "\"", &r);
|
||||
todo_wine check_exit_code(SC_EXIT_SUCCESS);
|
||||
check_test_service(SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, "", NULL,
|
||||
BROKEN_CREATE);
|
||||
|
||||
/* existing service */
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME " binpath= \"" TEST_SERVICE_BINARY "\" start= auto", &r);
|
||||
todo_wine check_exit_code(SC_EXIT_SERVICE_EXISTS);
|
||||
check_test_service(SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, "", NULL,
|
||||
BROKEN_CREATE);
|
||||
delete_test_service(TRUE, TRUE);
|
||||
|
||||
/* type= */
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME " binpath= \"" TEST_SERVICE_BINARY "\" type= invalid", &r);
|
||||
todo_wine check_exit_code(SC_EXIT_INVALID_COMMAND_LINE);
|
||||
delete_test_service(FALSE, FALSE);
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME " binpath= \"" TEST_SERVICE_BINARY "\" type= own", &r);
|
||||
todo_wine check_exit_code(SC_EXIT_SUCCESS);
|
||||
check_test_service(SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, "", NULL,
|
||||
BROKEN_CREATE);
|
||||
delete_test_service(TRUE, TRUE);
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME " binpath= \"" TEST_SERVICE_BINARY "\" type= interact", &r);
|
||||
todo_wine check_exit_code(SC_EXIT_INVALID_PARAMETER);
|
||||
delete_test_service(FALSE, FALSE);
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME " binpath= \"" TEST_SERVICE_BINARY "\" type= interact type= own", &r);
|
||||
todo_wine check_exit_code(SC_EXIT_SUCCESS);
|
||||
check_test_service(SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_DEMAND_START,
|
||||
SERVICE_ERROR_NORMAL, "", NULL, BROKEN_CREATE);
|
||||
delete_test_service(TRUE, TRUE);
|
||||
|
||||
/* start= */
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME " binpath= \"" TEST_SERVICE_BINARY "\" start= invalid", &r);
|
||||
todo_wine check_exit_code(SC_EXIT_INVALID_COMMAND_LINE);
|
||||
delete_test_service(FALSE, FALSE);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(start_types); i++)
|
||||
{
|
||||
char cmdline[256];
|
||||
|
||||
strcpy(cmdline, "sc create " TEST_SERVICE_NAME " binpath= \"" TEST_SERVICE_BINARY "\" start= ");
|
||||
strcat(cmdline, start_types[i].param);
|
||||
run_sc_exe(cmdline, &r);
|
||||
todo_wine check_exit_code(SC_EXIT_SUCCESS);
|
||||
check_service_definition(TEST_SERVICE_NAME, start_types[i].expected_binary_path,
|
||||
start_types[i].expected_service_type, start_types[i].expected_start_type,
|
||||
SERVICE_ERROR_NORMAL, "", TEST_SERVICE_NAME, BROKEN_CREATE);
|
||||
delete_test_service(TRUE, TRUE);
|
||||
}
|
||||
|
||||
/* error= */
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(error_severities); i++)
|
||||
{
|
||||
char cmdline[256];
|
||||
|
||||
strcpy(cmdline, "sc create " TEST_SERVICE_NAME " binpath= \"" TEST_SERVICE_BINARY "\" error= ");
|
||||
strcat(cmdline, error_severities[i].param);
|
||||
run_sc_exe(cmdline, &r);
|
||||
todo_wine check_exit_code(SC_EXIT_SUCCESS);
|
||||
check_test_service(SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START,
|
||||
error_severities[i].expected_error_control, "", NULL, BROKEN_CREATE);
|
||||
delete_test_service(TRUE, TRUE);
|
||||
}
|
||||
|
||||
/* tag= */
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME " binpath= \"" TEST_SERVICE_BINARY "\" tag= yes", &r);
|
||||
todo_wine check_exit_code(SC_EXIT_INVALID_PARAMETER);
|
||||
delete_test_service(FALSE, FALSE);
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME " binpath= \"" TEST_SERVICE_BINARY "\" tag= no", &r);
|
||||
todo_wine check_exit_code(SC_EXIT_SUCCESS);
|
||||
check_test_service(SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, "", NULL,
|
||||
BROKEN_CREATE);
|
||||
delete_test_service(TRUE, TRUE);
|
||||
|
||||
/* depend= */
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME " binpath= \"" TEST_SERVICE_BINARY "\" depend= " TEST_SERVICE_NAME, &r);
|
||||
todo_wine check_exit_code(SC_EXIT_CIRCULAR_DEPENDENCY);
|
||||
delete_test_service(FALSE, FALSE);
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME2 " binpath= \"" TEST_SERVICE_BINARY "\" depend= " TEST_SERVICE_NAME, &r);
|
||||
todo_wine check_exit_code(SC_EXIT_SUCCESS);
|
||||
check_test_service2(SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
|
||||
TEST_SERVICE_NAME, NULL, BROKEN_CREATE);
|
||||
delete_test_service2(TRUE, TRUE);
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME " binpath= " TEST_SERVICE_BINARY, &r);
|
||||
todo_wine check_exit_code(SC_EXIT_SUCCESS);
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME2 " binpath= \"" TEST_SERVICE_BINARY "\" depend= " TEST_SERVICE_NAME, &r);
|
||||
todo_wine check_exit_code(SC_EXIT_SUCCESS);
|
||||
check_test_service2(SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
|
||||
TEST_SERVICE_NAME, NULL, BROKEN_CREATE);
|
||||
delete_test_service2(TRUE, TRUE);
|
||||
delete_test_service(TRUE, TRUE);
|
||||
|
||||
/* displayname= */
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME " binpath= " TEST_SERVICE_BINARY
|
||||
" displayname= \"Wine Test Service\"", &r);
|
||||
todo_wine check_exit_code(SC_EXIT_SUCCESS);
|
||||
check_test_service(SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, "",
|
||||
"Wine Test Service", BROKEN_CREATE);
|
||||
delete_test_service(TRUE, TRUE);
|
||||
|
||||
/* without spaces */
|
||||
|
||||
run_sc_exe("sc create " TEST_SERVICE_NAME2 " binpath=\"" TEST_SERVICE_BINARY "\" type=own start=auto"
|
||||
" error=normal tag=no depend=" TEST_SERVICE_NAME " displayname=\"Wine Test Service\"", &r);
|
||||
ok(r == SC_EXIT_SUCCESS || broken(r == SC_EXIT_INVALID_COMMAND_LINE), "got exit code %ld, expected %d\n",
|
||||
r, SC_EXIT_SUCCESS);
|
||||
if (r == SC_EXIT_SUCCESS)
|
||||
{
|
||||
check_test_service2(SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
|
||||
TEST_SERVICE_NAME, "Wine Test Service", BROKEN_DEPEND);
|
||||
delete_test_service2(TRUE, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete_test_service2(FALSE, FALSE);
|
||||
}
|
||||
|
||||
/* case-insensitive */
|
||||
|
||||
run_sc_exe("SC CREATE " TEST_SERVICE_NAME2 " BINPATH= \"" TEST_SERVICE_BINARY "\" TYPE= OWN START= AUTO"
|
||||
" ERROR= NORMAL TAG= NO DEPEND= " TEST_SERVICE_NAME " DISPLAYNAME= \"Wine Test Service\"", &r);
|
||||
todo_wine check_exit_code(SC_EXIT_SUCCESS);
|
||||
check_test_service2(SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
|
||||
TEST_SERVICE_NAME, "Wine Test Service", BROKEN_CREATE);
|
||||
delete_test_service2(TRUE, TRUE);
|
||||
|
||||
#undef delete_test_service2
|
||||
#undef check_test_service2
|
||||
#undef delete_test_service
|
||||
#undef check_test_service
|
||||
#undef check_exit_code
|
||||
}
|
||||
|
||||
/* taken from winetest, only whitespace changes */
|
||||
static int running_elevated(void)
|
||||
{
|
||||
HANDLE token;
|
||||
TOKEN_ELEVATION elevation_info;
|
||||
DWORD size;
|
||||
|
||||
/* Get the process token */
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token))
|
||||
return -1;
|
||||
|
||||
/* Get the elevation info from the token */
|
||||
if (!GetTokenInformation(token, TokenElevation, &elevation_info, sizeof(TOKEN_ELEVATION), &size))
|
||||
{
|
||||
CloseHandle(token);
|
||||
return -1;
|
||||
}
|
||||
CloseHandle(token);
|
||||
|
||||
return elevation_info.TokenIsElevated;
|
||||
}
|
||||
|
||||
|
||||
START_TEST(sc)
|
||||
{
|
||||
SECURITY_ATTRIBUTES secattr = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
|
||||
BOOL elevated = running_elevated();
|
||||
|
||||
nul_file = CreateFileA("NUL", GENERIC_READ | GENERIC_WRITE, 0, &secattr, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
scmgr = OpenSCManagerA(NULL, NULL, GENERIC_READ);
|
||||
ok(!!scmgr, "OpenSCManagerA failed: %ld\n", GetLastError());
|
||||
|
||||
test_create_service(elevated);
|
||||
|
||||
CloseServiceHandle(scmgr);
|
||||
CloseHandle(nul_file);
|
||||
}
|
Loading…
Reference in New Issue