Module: wine
Branch: master
Commit: e50edb61f06eb4d7a2ae3c881228f6a622382972
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e50edb61f06eb4d7a2ae3c881…
Author: Paul Vriens <paul.vriens.wine(a)gmail.com>
Date: Thu Jul 19 21:30:35 2007 +0200
advapi32/service: Some 'refcount' tests.
---
dlls/advapi32/tests/service.c | 99 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/dlls/advapi32/tests/service.c b/dlls/advapi32/tests/service.c
index 0bdb0bf..5c9c663 100644
--- a/dlls/advapi32/tests/service.c
+++ b/dlls/advapi32/tests/service.c
@@ -517,6 +517,101 @@ static void test_sequence(void)
CloseServiceHandle(scm_handle);
}
+static void test_refcount(void)
+{
+ SC_HANDLE scm_handle, svc_handle1, svc_handle2, svc_handle3, svc_handle4, svc_handle5;
+ static const CHAR servicename [] = "Winetest";
+ static const CHAR pathname [] = "we_dont_care.exe";
+ BOOL ret;
+
+ /* Get a handle to the Service Control Manager */
+ SetLastError(0xdeadbeef);
+ scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
+ if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
+ {
+ skip("Not enough rights to get a handle to the manager\n");
+ return;
+ }
+
+ /* Create a service */
+ svc_handle1 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
+ SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
+ SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
+ ok(svc_handle1 != NULL, "Expected success\n");
+
+ /* Get a handle to this new service */
+ svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
+ ok(svc_handle2 != NULL, "Expected success\n");
+
+ /* Get another handle to this new service */
+ svc_handle3 = OpenServiceA(scm_handle, servicename, GENERIC_READ);
+ ok(svc_handle3 != NULL, "Expected success\n");
+
+ /* Check if we can close the handle to the Service Control Manager */
+ ret = CloseServiceHandle(scm_handle);
+ ok(ret, "Expected success\n");
+
+ /* Get a new handle to the Service Control Manager */
+ scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
+ ok(scm_handle != NULL, "Expected success\n");
+
+ /* Get a handle to this new service */
+ svc_handle4 = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
+ ok(svc_handle4 != NULL, "Expected success\n");
+
+ /* Delete the service */
+ ret = DeleteService(svc_handle4);
+ ok(ret, "Expected success\n");
+
+ /* We cannot create the same service again as it's still marked as 'being deleted'.
+ * The reason is that we still have 4 open handles to this service eventhough we
+ * closed the handle to the Service Control Manager in between.
+ */
+ SetLastError(0xdeadbeef);
+ svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
+ SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
+ SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
+ todo_wine
+ {
+ ok(!svc_handle5, "Expected failure\n");
+ ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE,
+ "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError());
+ }
+
+ /* FIXME: Remove this when Wine is fixed */
+ if (svc_handle5)
+ {
+ DeleteService(svc_handle5);
+ CloseServiceHandle(svc_handle5);
+ }
+
+ /* Close all the handles to the service and try again */
+ ret = CloseServiceHandle(svc_handle4);
+ ok(ret, "Expected success\n");
+ ret = CloseServiceHandle(svc_handle3);
+ ok(ret, "Expected success\n");
+ ret = CloseServiceHandle(svc_handle2);
+ ok(ret, "Expected success\n");
+ ret = CloseServiceHandle(svc_handle1);
+ ok(ret, "Expected success\n");
+
+ /* We succeed now as all handles are closed (tested this also with a long SLeep() */
+ svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL,
+ SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
+ SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL);
+ ok(svc_handle5 != NULL, "Expected success\n");
+
+ /* Delete the service */
+ ret = DeleteService(svc_handle5);
+ ok(ret, "Expected success\n");
+
+ /* Wait a while. Just in case one of the following tests does a CreateService again */
+ Sleep(1000);
+
+ CloseServiceHandle(svc_handle5);
+ CloseServiceHandle(scm_handle);
+}
+
START_TEST(service)
{
SC_HANDLE scm_handle;
@@ -539,4 +634,8 @@ START_TEST(service)
test_close();
/* Test the creation, querying and deletion of a service */
test_sequence();
+ /* The main reason for this test is to check if any refcounting is used
+ * and what the rules are
+ */
+ test_refcount();
}