[PATCH 2/2] setupapi/tests: Add some service installation flags tests.
Rémi Bernon
rbernon at codeweavers.com
Thu Jan 27 06:30:05 CST 2022
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
I believe this should show that patches 224469 and 224464 are the right
thing to do if we want the services to be started after their initial
registration, when initializing a prefix.
Otherwise I don't see what's wrong in the 224469, 224465, 224464 series.
dlls/setupapi/tests/install.c | 188 ++++++++++++++++++++++++++++------
1 file changed, 157 insertions(+), 31 deletions(-)
diff --git a/dlls/setupapi/tests/install.c b/dlls/setupapi/tests/install.c
index 758a0761037..44b7d09d1e5 100644
--- a/dlls/setupapi/tests/install.c
+++ b/dlls/setupapi/tests/install.c
@@ -609,13 +609,26 @@ static void test_install_svc_from(void)
/* TODO: Test the Flags */
}
-static void test_driver_install(void)
+static void test_service_install(const char *executable, const char *argument)
{
- HANDLE handle;
+ struct
+ {
+ const char *add_service_flags;
+ const char *service_type;
+ const char *start_type;
+ DWORD expect_start_error;
+ } tests[] =
+ {
+ {.add_service_flags = "", .service_type = "1", .start_type = "4", .expect_start_error = ERROR_SERVICE_DISABLED},
+ {.add_service_flags = "", .service_type = "0x10", .start_type = "2", .expect_start_error = 0},
+ {.add_service_flags = "0x800", .service_type = "0x10", .start_type = "2", .expect_start_error = ERROR_SERVICE_ALREADY_RUNNING},
+ };
+
SC_HANDLE scm_handle, svc_handle;
+ SERVICE_STATUS status;
BOOL ret;
char path[MAX_PATH + 9], windir[MAX_PATH], driver[MAX_PATH];
- DWORD attrs;
+ DWORD i, attrs;
/* Minimal stuff needed */
static const char *inf =
"[Version]\n"
@@ -625,14 +638,15 @@ static void test_driver_install(void)
"[DefaultInstall]\n"
"CopyFiles=Winetest.DriverFiles\n"
"[DefaultInstall.Services]\n"
- "AddService=Winetest,,Winetest.Service\n"
+ "AddService=Winetest,%s,Winetest.Service\n"
"[Winetest.Service]\n"
- "ServiceBinary=%12%\\winetest.sys\n"
- "ServiceType=1\n"
- "StartType=4\n"
+ "ServiceBinary=%%12%%\\winetest.sys %s service\n"
+ "ServiceType=%s\n"
+ "StartType=%s\n"
"ErrorControl=1\n"
"[Winetest.DriverFiles]\n"
"winetest.sys";
+ char buffer[1024];
/* Bail out if we don't have enough rights */
SetLastError(0xdeadbeef);
@@ -649,36 +663,70 @@ static void test_driver_install(void)
lstrcpyA(driver, windir);
lstrcatA(driver, "\\system32\\drivers\\winetest.sys");
- /* Create a dummy driver file */
- handle = CreateFileA("winetest.sys", GENERIC_WRITE, 0, NULL,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- CloseHandle(handle);
+ ret = CopyFileA(executable, "winetest.sys", TRUE);
+ ok(ret, "CopyFileA failed, error %u\n", GetLastError());
- create_inf_file(inffile, inf);
- sprintf(path, "%s\\%s", CURR_DIR, inffile);
- run_cmdline("DefaultInstall", 128, path);
+ for (i = 0; i < ARRAY_SIZE(tests); ++i)
+ {
+ winetest_push_context("%u", i);
- /* Driver should have been installed */
- attrs = GetFileAttributesA(driver);
- ok(attrs != INVALID_FILE_ATTRIBUTES, "Expected driver to exist\n");
+ sprintf(buffer, inf, tests[i].add_service_flags, argument, tests[i].service_type, tests[i].start_type);
+ create_inf_file(inffile, buffer);
+ sprintf(path, "%s\\%s", CURR_DIR, inffile);
+ run_cmdline("DefaultInstall", 128, path);
- scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
+ /* Driver should have been installed */
+ attrs = GetFileAttributesA(driver);
+ ok(attrs != INVALID_FILE_ATTRIBUTES, "Expected driver to exist\n");
- /* Open the service to see if it's really there */
- svc_handle = OpenServiceA(scm_handle, "Winetest", DELETE);
- ok(svc_handle != NULL, "Service was not created\n");
+ scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
- SetLastError(0xdeadbeef);
- ret = DeleteService(svc_handle);
- ok(ret, "Service could not be deleted : %d\n", GetLastError());
+ /* Open the service to see if it's really there */
+ svc_handle = OpenServiceA(scm_handle, "Winetest", SERVICE_START|SERVICE_STOP|SERVICE_QUERY_STATUS|DELETE);
+ ok(svc_handle != NULL, "Service was not created\n");
- CloseServiceHandle(svc_handle);
- CloseServiceHandle(scm_handle);
+ ret = StartServiceA(svc_handle, 0, NULL);
+ if (!tests[i].expect_start_error)
+ ok(ret, "StartServiceA failed, error %u\n", GetLastError());
+ else
+ {
+ ok(!ret, "StartServiceA succeeded\n");
+ ok(GetLastError() == tests[i].expect_start_error, "got error %u\n", GetLastError());
+ }
+
+ ret = QueryServiceStatus(svc_handle, &status);
+ ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
+ while (status.dwCurrentState == SERVICE_START_PENDING)
+ {
+ Sleep(100);
+ ret = QueryServiceStatus(svc_handle, &status);
+ ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
+ }
+
+ ret = ControlService(svc_handle, SERVICE_CONTROL_STOP, &status);
+ while (status.dwCurrentState == SERVICE_STOP_PENDING)
+ {
+ Sleep(100);
+ ret = QueryServiceStatus(svc_handle, &status);
+ ok(ret, "QueryServiceStatus failed: %u\n", GetLastError());
+ }
+ ok(status.dwCurrentState == SERVICE_STOPPED, "expected SERVICE_STOPPED, got %d\n", status.dwCurrentState);
+
+ SetLastError(0xdeadbeef);
+ ret = DeleteService(svc_handle);
+ ok(ret, "Service could not be deleted : %d\n", GetLastError());
+
+ CloseServiceHandle(svc_handle);
+ CloseServiceHandle(scm_handle);
+
+ /* File cleanup */
+ DeleteFileA(inffile);
+ DeleteFileA(driver);
+
+ winetest_pop_context();
+ }
- /* File cleanup */
- DeleteFileA(inffile);
DeleteFileA("winetest.sys");
- DeleteFileA(driver);
}
static void test_profile_items(void)
@@ -2132,11 +2180,89 @@ static void test_register_dlls(void)
ok(ret, "Failed to delete test DLL, error %u.\n", GetLastError());
}
+static WCHAR service_name[] = L"Wine Test Service";
+static SERVICE_STATUS_HANDLE service_handle;
+static HANDLE stop_event;
+
+static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context )
+{
+ SERVICE_STATUS status;
+
+ status.dwServiceType = SERVICE_WIN32;
+ status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ status.dwWin32ExitCode = 0;
+ status.dwServiceSpecificExitCode = 0;
+ status.dwCheckPoint = 0;
+ status.dwWaitHint = 0;
+
+ switch(ctrl)
+ {
+ case SERVICE_CONTROL_STOP:
+ case SERVICE_CONTROL_SHUTDOWN:
+ trace( "shutting down\n" );
+ status.dwCurrentState = SERVICE_STOP_PENDING;
+ status.dwControlsAccepted = 0;
+ SetServiceStatus( service_handle, &status );
+ SetEvent( stop_event );
+ return NO_ERROR;
+ default:
+ trace( "got service ctrl %x\n", ctrl );
+ status.dwCurrentState = SERVICE_RUNNING;
+ SetServiceStatus( service_handle, &status );
+ return NO_ERROR;
+ }
+}
+
+static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
+{
+ SERVICE_STATUS status;
+
+ trace( "starting service\n" );
+
+ stop_event = CreateEventW( NULL, TRUE, FALSE, NULL );
+
+ service_handle = RegisterServiceCtrlHandlerExW( L"Wine Test Service", service_handler, NULL );
+ if (!service_handle)
+ return;
+
+ status.dwServiceType = SERVICE_WIN32;
+ status.dwCurrentState = SERVICE_RUNNING;
+ status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+ status.dwWin32ExitCode = 0;
+ status.dwServiceSpecificExitCode = 0;
+ status.dwCheckPoint = 0;
+ status.dwWaitHint = 10000;
+ SetServiceStatus( service_handle, &status );
+
+ WaitForSingleObject( stop_event, INFINITE );
+
+ status.dwCurrentState = SERVICE_STOPPED;
+ status.dwControlsAccepted = 0;
+ SetServiceStatus( service_handle, &status );
+ trace( "service stopped\n" );
+}
+
START_TEST(install)
{
- char temp_path[MAX_PATH], prev_path[MAX_PATH];
+ char temp_path[MAX_PATH], prev_path[MAX_PATH], path[MAX_PATH];
+ char **argv;
DWORD len;
+ int argc;
+ argc = winetest_get_mainargs(&argv);
+ if (argc > 2 && !strcmp( argv[2], "service" ))
+ {
+ static const SERVICE_TABLE_ENTRYW service_table[] =
+ {
+ { service_name, ServiceMain },
+ { NULL, NULL }
+ };
+
+ StartServiceCtrlDispatcherW( service_table );
+ return;
+ }
+
+ GetFullPathNameA(argv[0], ARRAY_SIZE(path), path, NULL);
GetCurrentDirectoryA(MAX_PATH, prev_path);
GetTempPathA(MAX_PATH, temp_path);
SetCurrentDirectoryA(temp_path);
@@ -2154,7 +2280,7 @@ START_TEST(install)
test_registry();
test_install_from();
test_install_svc_from();
- test_driver_install();
+ test_service_install(path, argv[1]);
test_dirid();
test_install_files_queue();
test_need_media();
--
2.34.1
More information about the wine-devel
mailing list