ddraw: Y coords are inversed.
[wine] / dlls / advapi32 / tests / service.c
1 /*
2  * Unit tests for service functions
3  *
4  * Copyright (c) 2007 Paul Vriens
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "winsvc.h"
27
28 #include "wine/test.h"
29
30 static void test_open_scm(void)
31 {
32     SC_HANDLE scm_handle;
33
34     /* No access rights */
35     SetLastError(0xdeadbeef);
36     scm_handle = OpenSCManagerA(NULL, NULL, 0);
37     ok(scm_handle != NULL, "Expected success\n");
38     ok(GetLastError() == ERROR_SUCCESS    /* W2K3, Vista */ ||
39        GetLastError() == 0xdeadbeef       /* NT4, XP */ ||
40        GetLastError() == ERROR_IO_PENDING /* W2K */,
41        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
42     CloseServiceHandle(scm_handle);
43
44     /* Unknown database name */
45     SetLastError(0xdeadbeef);
46     scm_handle = OpenSCManagerA(NULL, "DoesNotExist", SC_MANAGER_CONNECT);
47     ok(!scm_handle, "Expected failure\n");
48     ok(GetLastError() == ERROR_INVALID_NAME, "Expected ERROR_INVALID_NAME, got %d\n", GetLastError());
49     CloseServiceHandle(scm_handle); /* Just in case */
50
51     /* MSDN says only ServiceActive is allowed, or NULL */
52     SetLastError(0xdeadbeef);
53     scm_handle = OpenSCManagerA(NULL, SERVICES_FAILED_DATABASEA, SC_MANAGER_CONNECT);
54     ok(!scm_handle, "Expected failure\n");
55     ok(GetLastError() == ERROR_DATABASE_DOES_NOT_EXIST, "Expected ERROR_DATABASE_DOES_NOT_EXIST, got %d\n", GetLastError());
56     CloseServiceHandle(scm_handle); /* Just in case */
57
58     /* Remote unknown host */
59     SetLastError(0xdeadbeef);
60     scm_handle = OpenSCManagerA("DOESNOTEXIST", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
61     ok(!scm_handle, "Expected failure\n");
62     todo_wine
63     ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE, "Expected RPC_S_SERVER_UNAVAILABLE, got %d\n", GetLastError());
64     CloseServiceHandle(scm_handle); /* Just in case */
65
66     /* Proper call with an empty hostname */
67     SetLastError(0xdeadbeef);
68     scm_handle = OpenSCManagerA("", SERVICES_ACTIVE_DATABASEA, SC_MANAGER_CONNECT);
69     ok(scm_handle != NULL, "Expected success\n");
70     ok(GetLastError() == ERROR_SUCCESS          /* W2K3, Vista */ ||
71        GetLastError() == ERROR_ENVVAR_NOT_FOUND /* NT4 */ ||
72        GetLastError() == 0xdeadbeef             /* XP */ ||
73        GetLastError() == ERROR_IO_PENDING       /* W2K */,
74        "Expected ERROR_SUCCESS, ERROR_IO_PENDING, ERROR_ENVVAR_NOT_FOUND or 0xdeadbeef, got %d\n", GetLastError());
75     CloseServiceHandle(scm_handle);
76
77     /* Again a correct one */
78     SetLastError(0xdeadbeef);
79     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
80     ok(scm_handle != NULL, "Expected success\n");
81     ok(GetLastError() == ERROR_SUCCESS    /* W2K3, Vista */ ||
82        GetLastError() == 0xdeadbeef       /* NT4, XP */ ||
83        GetLastError() == ERROR_IO_PENDING /* W2K */,
84        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
85     CloseServiceHandle(scm_handle);
86 }
87
88 static void test_open_svc(void)
89 {
90     SC_HANDLE scm_handle, svc_handle;
91
92     /* All NULL (invalid access rights) */
93     SetLastError(0xdeadbeef);
94     svc_handle = OpenServiceA(NULL, NULL, 0);
95     ok(!svc_handle, "Expected failure\n");
96     todo_wine
97     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
98
99     /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
100
101     /* NULL service */
102     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
103     SetLastError(0xdeadbeef);
104     svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
105     ok(!svc_handle, "Expected failure\n");
106     ok(GetLastError() == ERROR_INVALID_ADDRESS   /* W2K, XP, W2K3, Vista */ ||
107        GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */,
108        "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
109
110     /* Non-existent service */
111     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
112     SetLastError(0xdeadbeef);
113     svc_handle = OpenServiceA(scm_handle, "deadbeef", GENERIC_READ);
114     ok(!svc_handle, "Expected failure\n");
115     ok(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST, "Expected ERROR_SERVICE_DOES_NOT_EXIST, got %d\n", GetLastError());
116     CloseServiceHandle(scm_handle);
117
118     /* Proper SCM handle but different access rights */
119     scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
120     SetLastError(0xdeadbeef);
121     svc_handle = OpenServiceA(scm_handle, "Spooler", GENERIC_WRITE);
122     if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
123         skip("Not enough rights to get a handle to the service\n");
124     else
125     {
126         ok(svc_handle != NULL, "Expected success\n");
127         ok(GetLastError() == ERROR_SUCCESS    /* W2K3, Vista */ ||
128            GetLastError() == ERROR_IO_PENDING /* W2K */ ||
129            GetLastError() == 0xdeadbeef       /* XP, NT4 */,
130            "Expected ERROR_SUCCESS or 0xdeadbeef, got %d\n", GetLastError());
131         CloseServiceHandle(svc_handle);
132     }
133     CloseServiceHandle(scm_handle);
134 }
135
136 static void test_close(void)
137 {
138     SC_HANDLE handle;
139     BOOL ret;
140
141     /* NULL handle */
142     SetLastError(0xdeadbeef);
143     ret = CloseServiceHandle(NULL);
144     todo_wine
145     {
146     ok(!ret, "Expected failure\n");
147     ok(GetLastError() == ERROR_INVALID_HANDLE, "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
148     }
149
150     /* TODO: Add some tests with invalid handles. These produce errors on Windows but crash on Wine */
151
152     /* Proper call */
153     handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT);
154     SetLastError(0xdeadbeef);
155     ret = CloseServiceHandle(handle);
156     ok(ret, "Expected success\n");
157     ok(GetLastError() == ERROR_IO_PENDING /* W2K */ ||
158        GetLastError() == ERROR_SUCCESS    /* W2K3 */ ||
159        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */,
160        "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
161 }
162
163 static void test_sequence(void)
164 {
165     SC_HANDLE scm_handle, svc_handle;
166     BOOL ret;
167     QUERY_SERVICE_CONFIGA *config;
168     DWORD given, needed;
169     static const CHAR servicename [] = "Winetest";
170     static const CHAR displayname [] = "Winetest dummy service";
171     static const CHAR pathname    [] = "we_dont_care.exe";
172     static const CHAR dependencies[] = "Master1\0Master2\0+MasterGroup1\0\0";
173     static const CHAR password    [] = "";
174     static const CHAR empty       [] = "";
175     static const CHAR localsystem [] = "LocalSystem";
176
177     SetLastError(0xdeadbeef);
178     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
179
180     if (!scm_handle && (GetLastError() == ERROR_ACCESS_DENIED))
181     {
182         skip("Not enough rights to get a handle to the manager\n");
183         return;
184     }
185     else
186         ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
187
188     if (!scm_handle) return;
189
190     /* Create a dummy service */
191     SetLastError(0xdeadbeef);
192     svc_handle = CreateServiceA(scm_handle, servicename, displayname, GENERIC_ALL,
193         SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, SERVICE_DISABLED, SERVICE_ERROR_IGNORE,
194         pathname, NULL, NULL, dependencies, NULL, password);
195
196     if (!svc_handle && (GetLastError() == ERROR_SERVICE_EXISTS))
197     {
198         /* We try and open the service and do the rest of the tests. Some could
199          * fail if the tests were changed between these runs.
200          */
201         trace("Deletion probably didn't work last time\n");
202         SetLastError(0xdeadbeef);
203         svc_handle = OpenServiceA(scm_handle, servicename, GENERIC_ALL);
204         if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
205         {
206             skip("Not enough rights to open the service\n");
207             CloseServiceHandle(scm_handle);        
208             return;
209         }
210         ok(svc_handle != NULL, "Could not open the service : %d\n", GetLastError());
211     }
212     else if (!svc_handle && (GetLastError() == ERROR_ACCESS_DENIED))
213     {
214         skip("Not enough rights to create the service\n");
215         CloseServiceHandle(scm_handle);        
216         return;
217     }
218     else
219         ok(svc_handle != NULL, "Could not create the service : %d\n", GetLastError());
220
221     if (!svc_handle) return;
222
223     /* TODO:
224      * Before we do a QueryServiceConfig we should check the registry. This will make sure
225      * that the correct keys are used.
226      */
227
228     /* Request the size for the buffer */
229     SetLastError(0xdeadbeef);
230     ret = QueryServiceConfigA(svc_handle, NULL, 0, &needed);
231     ok(!ret, "Expected failure\n");
232     ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
233
234     config = HeapAlloc(GetProcessHeap(), 0, needed);
235     given = needed;
236     SetLastError(0xdeadbeef);
237     ret = QueryServiceConfigA(svc_handle, config, given, &needed);
238     ok(ret, "Expected success\n");
239     todo_wine
240     {
241     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */||
242        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */ ||
243        GetLastError() == ERROR_IO_PENDING /* W2K */,
244         "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
245     ok(given == needed, "Expected the given (%d) and needed (%d) buffersizes to be equal\n", given, needed);
246     }
247     ok(config->lpBinaryPathName && config->lpLoadOrderGroup && config->lpDependencies && config->lpServiceStartName &&
248         config->lpDisplayName, "Expected all string struct members to be non-NULL\n");
249     ok(config->dwServiceType == (SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS),
250         "Expected SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, got %d\n", config->dwServiceType);
251     ok(config->dwStartType == SERVICE_DISABLED, "Expected SERVICE_DISABLED, got %d\n", config->dwStartType);
252     ok(config->dwErrorControl == SERVICE_ERROR_IGNORE, "Expected SERVICE_ERROR_IGNORE, got %d\n", config->dwErrorControl);
253     ok(!strcmp(config->lpBinaryPathName, pathname), "Expected '%s', got '%s'\n", pathname, config->lpBinaryPathName);
254     ok(!strcmp(config->lpLoadOrderGroup, empty), "Expected an empty string, got '%s'\n", config->lpLoadOrderGroup);
255     ok(config->dwTagId == 0, "Expected 0, got %d\n", config->dwTagId);
256     /* TODO: Show the double 0 terminated string */
257     todo_wine
258     {
259     ok(!memcmp(config->lpDependencies, dependencies, sizeof(dependencies)), "Wrong string\n");
260     ok(!strcmp(config->lpServiceStartName, localsystem), "Expected 'LocalSystem', got '%s'\n", config->lpServiceStartName);
261     }
262     ok(!strcmp(config->lpDisplayName, displayname), "Expected '%s', got '%s'\n", displayname, config->lpDisplayName);
263     
264     SetLastError(0xdeadbeef);
265     ret = DeleteService(svc_handle);
266     ok(ret, "Expected success\n");
267     ok(GetLastError() == ERROR_SUCCESS    /* W2K3 */||
268        GetLastError() == 0xdeadbeef       /* NT4, XP, Vista */ ||
269        GetLastError() == ERROR_IO_PENDING /* W2K */,
270         "Expected ERROR_SUCCESS, ERROR_IO_PENDING or 0xdeadbeef, got %d\n", GetLastError());
271     
272     CloseServiceHandle(svc_handle);
273     CloseServiceHandle(scm_handle);
274 }
275
276 START_TEST(service)
277 {
278     SC_HANDLE scm_handle;
279
280     /* Bail out if we are on win98 */
281     SetLastError(0xdeadbeef);
282     scm_handle = OpenSCManagerA(NULL, NULL, GENERIC_ALL);
283
284     if (!scm_handle && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
285     {
286         skip("OpenSCManagerA is not implemented, we are most likely on win9x\n");
287         return;
288     }
289     CloseServiceHandle(scm_handle);
290
291     /* First some parameter checking */
292     test_open_scm();
293     test_open_svc();
294     test_close();
295     /* Test the creation, querying and deletion of a service */
296     test_sequence();
297 }