blob: 9eee52806f19a9ea429452adf1538ac85f9ba819 [file] [log] [blame]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +00001/*
2 * Win32 advapi functions
3 *
4 * Copyright 1995 Sven Verdoolaege
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00005 *
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Juergen Schmiedf7b0de31999-01-03 12:48:29 +000019 */
20
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000021#include <stdarg.h>
James Juranf4d5fef2001-01-26 20:43:40 +000022#include <string.h>
Juergen Schmiedf7b0de31999-01-03 12:48:29 +000023#include <time.h>
Patrik Stridvall4a739731999-07-04 11:01:21 +000024
Jim Aston2e1cafa1999-03-14 16:35:05 +000025#include "windef.h"
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000026#include "winbase.h"
Patrik Stridvall4a739731999-07-04 11:01:21 +000027#include "winsvc.h"
Marcus Meissner317af321999-02-17 13:51:06 +000028#include "winerror.h"
Michael McCormack75a84131999-11-21 00:58:14 +000029#include "winreg.h"
Alexandre Julliardc7e7df82000-08-14 14:41:19 +000030#include "wine/unicode.h"
Marcus Meissner317af321999-02-17 13:51:06 +000031#include "heap.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000032#include "wine/debug.h"
Matthew Davison6f2a0712003-01-20 23:23:12 +000033#include "winternl.h"
Juergen Schmiedf7b0de31999-01-03 12:48:29 +000034
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000035WINE_DEFAULT_DEBUG_CHANNEL(advapi);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000036
Michael McCormack0c0f7d31999-12-04 04:03:45 +000037static DWORD start_dwNumServiceArgs;
38static LPWSTR *start_lpServiceArgVectors;
39
Alexandre Julliardb10dcfe2003-10-10 00:05:49 +000040static const WCHAR _ServiceStartDataW[] = {'A','D','V','A','P','I','_','S',
41 'e','r','v','i','c','e','S','t',
42 'a','r','t','D','a','t','a',0};
43
Matthew Beckere905f3c1999-01-28 13:46:25 +000044/******************************************************************************
Patrik Stridvall54fe8382000-04-06 20:21:16 +000045 * EnumServicesStatusA [ADVAPI32.@]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +000046 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000047BOOL WINAPI
Patrik Stridvall4a739731999-07-04 11:01:21 +000048EnumServicesStatusA( SC_HANDLE hSCManager, DWORD dwServiceType,
Patrik Stridvall54fe8382000-04-06 20:21:16 +000049 DWORD dwServiceState, LPENUM_SERVICE_STATUSA lpServices,
50 DWORD cbBufSize, LPDWORD pcbBytesNeeded,
51 LPDWORD lpServicesReturned, LPDWORD lpResumeHandle )
Michael Stefaniuccbacde52002-10-25 19:17:33 +000052{ FIXME("%p type=%lx state=%lx %p %lx %p %p %p\n", hSCManager,
Patrik Stridvall54fe8382000-04-06 20:21:16 +000053 dwServiceType, dwServiceState, lpServices, cbBufSize,
54 pcbBytesNeeded, lpServicesReturned, lpResumeHandle);
55 SetLastError (ERROR_ACCESS_DENIED);
François Gouget97ad5a72001-01-02 20:20:34 +000056 return FALSE;
Patrik Stridvall54fe8382000-04-06 20:21:16 +000057}
58
59/******************************************************************************
60 * EnumServicesStatusW [ADVAPI32.@]
61 */
62BOOL WINAPI
63EnumServicesStatusW( SC_HANDLE hSCManager, DWORD dwServiceType,
64 DWORD dwServiceState, LPENUM_SERVICE_STATUSW lpServices,
65 DWORD cbBufSize, LPDWORD pcbBytesNeeded,
66 LPDWORD lpServicesReturned, LPDWORD lpResumeHandle )
Michael Stefaniuccbacde52002-10-25 19:17:33 +000067{ FIXME("%p type=%lx state=%lx %p %lx %p %p %p\n", hSCManager,
Juergen Schmiedf7b0de31999-01-03 12:48:29 +000068 dwServiceType, dwServiceState, lpServices, cbBufSize,
69 pcbBytesNeeded, lpServicesReturned, lpResumeHandle);
70 SetLastError (ERROR_ACCESS_DENIED);
François Gouget97ad5a72001-01-02 20:20:34 +000071 return FALSE;
Juergen Schmiedf7b0de31999-01-03 12:48:29 +000072}
Matthew Beckere905f3c1999-01-28 13:46:25 +000073
74/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +000075 * StartServiceCtrlDispatcherA [ADVAPI32.@]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +000076 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000077BOOL WINAPI
78StartServiceCtrlDispatcherA( LPSERVICE_TABLE_ENTRYA servent )
Vincent Béron9a624912002-05-31 23:06:46 +000079{
Michael McCormack0c0f7d31999-12-04 04:03:45 +000080 LPSERVICE_MAIN_FUNCTIONA fpMain;
81 HANDLE wait;
82 DWORD dwNumServiceArgs ;
83 LPWSTR *lpArgVecW;
84 LPSTR *lpArgVecA;
85 int i;
Vincent Béron9a624912002-05-31 23:06:46 +000086
Michael McCormack0c0f7d31999-12-04 04:03:45 +000087 TRACE("(%p)\n", servent);
Alexandre Julliardb10dcfe2003-10-10 00:05:49 +000088 wait = OpenSemaphoreW(SEMAPHORE_ALL_ACCESS, FALSE, _ServiceStartDataW);
Michael McCormack0c0f7d31999-12-04 04:03:45 +000089 if(wait == 0)
90 {
91 ERR("Couldn't find wait semaphore\n");
92 ERR("perhaps you need to start services using StartService\n");
93 return FALSE;
94 }
Juergen Schmiedf7b0de31999-01-03 12:48:29 +000095
Michael McCormack0c0f7d31999-12-04 04:03:45 +000096 dwNumServiceArgs = start_dwNumServiceArgs;
97 lpArgVecW = start_lpServiceArgVectors;
98
99 ReleaseSemaphore(wait, 1, NULL);
100
101 /* Convert the Unicode arg vectors back to ASCII */
102 if(dwNumServiceArgs)
Vincent Béron9a624912002-05-31 23:06:46 +0000103 lpArgVecA = (LPSTR*) HeapAlloc( GetProcessHeap(), 0,
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000104 dwNumServiceArgs*sizeof(LPSTR) );
105 else
106 lpArgVecA = NULL;
107
108 for(i=0; i<dwNumServiceArgs; i++)
109 lpArgVecA[i]=HEAP_strdupWtoA(GetProcessHeap(), 0, lpArgVecW[i]);
110
111 /* FIXME: should we blindly start all services? */
Vincent Béron9a624912002-05-31 23:06:46 +0000112 while (servent->lpServiceName) {
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000113 TRACE("%s at %p)\n", debugstr_a(servent->lpServiceName),servent);
114 fpMain = servent->lpServiceProc;
115
116 /* try to start the service */
117 fpMain( dwNumServiceArgs, lpArgVecA);
118
119 servent++;
120 }
121
122 if(dwNumServiceArgs)
123 {
124 /* free arg strings */
125 for(i=0; i<dwNumServiceArgs; i++)
126 HeapFree(GetProcessHeap(), 0, lpArgVecA[i]);
127 HeapFree(GetProcessHeap(), 0, lpArgVecA);
128 }
129
130 return TRUE;
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000131}
132
Matthew Beckere905f3c1999-01-28 13:46:25 +0000133/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000134 * StartServiceCtrlDispatcherW [ADVAPI32.@]
Matthew Beckere905f3c1999-01-28 13:46:25 +0000135 *
136 * PARAMS
137 * servent []
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000138 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000139BOOL WINAPI
140StartServiceCtrlDispatcherW( LPSERVICE_TABLE_ENTRYW servent )
Vincent Béron9a624912002-05-31 23:06:46 +0000141{
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000142 LPSERVICE_MAIN_FUNCTIONW fpMain;
143 HANDLE wait;
144 DWORD dwNumServiceArgs ;
145 LPWSTR *lpServiceArgVectors ;
Vincent Béron9a624912002-05-31 23:06:46 +0000146
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000147 TRACE("(%p)\n", servent);
Matthew Davison620323e2003-01-24 00:45:51 +0000148 wait = OpenSemaphoreW(SEMAPHORE_ALL_ACCESS, FALSE, _ServiceStartDataW);
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000149 if(wait == 0)
150 {
151 ERR("Couldn't find wait semaphore\n");
152 ERR("perhaps you need to start services using StartService\n");
153 return FALSE;
154 }
155
156 dwNumServiceArgs = start_dwNumServiceArgs;
157 lpServiceArgVectors = start_lpServiceArgVectors;
158
159 ReleaseSemaphore(wait, 1, NULL);
160
161 /* FIXME: should we blindly start all services? */
Vincent Béron9a624912002-05-31 23:06:46 +0000162 while (servent->lpServiceName) {
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000163 TRACE("%s at %p)\n", debugstr_w(servent->lpServiceName),servent);
164 fpMain = servent->lpServiceProc;
165
166 /* try to start the service */
167 fpMain( dwNumServiceArgs, lpServiceArgVectors);
168
169 servent++;
170 }
171
172 return TRUE;
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000173}
174
Matthew Becker6d594451999-01-30 12:54:32 +0000175/******************************************************************************
Uwe Bonnes574d4a92003-01-14 19:31:44 +0000176 * LockServiceDatabase [ADVAPI32.@]
177 */
178LPVOID WINAPI LockServiceDatabase (SC_HANDLE hSCManager)
179{
180 FIXME("%p\n",hSCManager);
181 return (SC_HANDLE)0xcacacafe;
182}
183
184/******************************************************************************
185 * UnlockServiceDatabase [ADVAPI32.@]
186 */
187BOOL WINAPI UnlockServiceDatabase (LPVOID ScLock)
188{
189 FIXME(": %p\n",ScLock);
190 return TRUE;
191}
192
193/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000194 * RegisterServiceCtrlHandlerA [ADVAPI32.@]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000195 */
Matthew Beckere905f3c1999-01-28 13:46:25 +0000196SERVICE_STATUS_HANDLE WINAPI
Patrik Stridvall4a739731999-07-04 11:01:21 +0000197RegisterServiceCtrlHandlerA( LPCSTR lpServiceName,
Matthew Beckere905f3c1999-01-28 13:46:25 +0000198 LPHANDLER_FUNCTION lpfHandler )
Alexandre Julliard9fe7a251999-05-14 08:17:14 +0000199{ FIXME("%s %p\n", lpServiceName, lpfHandler);
Vincent Béron9a624912002-05-31 23:06:46 +0000200 return 0xcacacafe;
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000201}
Matthew Beckere905f3c1999-01-28 13:46:25 +0000202
203/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000204 * RegisterServiceCtrlHandlerW [ADVAPI32.@]
Matthew Beckere905f3c1999-01-28 13:46:25 +0000205 *
206 * PARAMS
207 * lpServiceName []
208 * lpfHandler []
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000209 */
Matthew Beckere905f3c1999-01-28 13:46:25 +0000210SERVICE_STATUS_HANDLE WINAPI
Vincent Béron9a624912002-05-31 23:06:46 +0000211RegisterServiceCtrlHandlerW( LPCWSTR lpServiceName,
Matthew Beckere905f3c1999-01-28 13:46:25 +0000212 LPHANDLER_FUNCTION lpfHandler )
Alexandre Julliard9fe7a251999-05-14 08:17:14 +0000213{ FIXME("%s %p\n", debugstr_w(lpServiceName), lpfHandler);
Vincent Béron9a624912002-05-31 23:06:46 +0000214 return 0xcacacafe;
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000215}
Matthew Beckere905f3c1999-01-28 13:46:25 +0000216
217/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000218 * SetServiceStatus [ADVAPI32.@]
Matthew Beckere905f3c1999-01-28 13:46:25 +0000219 *
220 * PARAMS
221 * hService []
222 * lpStatus []
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000223 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000224BOOL WINAPI
Matthew Beckere905f3c1999-01-28 13:46:25 +0000225SetServiceStatus( SERVICE_STATUS_HANDLE hService, LPSERVICE_STATUS lpStatus )
François Gouget97ad5a72001-01-02 20:20:34 +0000226{ FIXME("0x%lx %p\n",hService, lpStatus);
Alexandre Julliard9fe7a251999-05-14 08:17:14 +0000227 TRACE("\tType:%lx\n",lpStatus->dwServiceType);
228 TRACE("\tState:%lx\n",lpStatus->dwCurrentState);
229 TRACE("\tControlAccepted:%lx\n",lpStatus->dwControlsAccepted);
230 TRACE("\tExitCode:%lx\n",lpStatus->dwWin32ExitCode);
231 TRACE("\tServiceExitCode:%lx\n",lpStatus->dwServiceSpecificExitCode);
232 TRACE("\tCheckPoint:%lx\n",lpStatus->dwCheckPoint);
233 TRACE("\tWaitHint:%lx\n",lpStatus->dwWaitHint);
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000234 return TRUE;
235}
236
237/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000238 * OpenSCManagerA [ADVAPI32.@]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000239 */
Patrik Stridvall4a739731999-07-04 11:01:21 +0000240SC_HANDLE WINAPI
Alexandre Julliarda3960291999-02-26 11:11:13 +0000241OpenSCManagerA( LPCSTR lpMachineName, LPCSTR lpDatabaseName,
Matthew Beckere905f3c1999-01-28 13:46:25 +0000242 DWORD dwDesiredAccess )
Vincent Béron9a624912002-05-31 23:06:46 +0000243{
Matthew Davison6f2a0712003-01-20 23:23:12 +0000244 UNICODE_STRING lpMachineNameW;
245 UNICODE_STRING lpDatabaseNameW;
246 SC_HANDLE ret;
247
248 RtlCreateUnicodeStringFromAsciiz (&lpMachineNameW,lpMachineName);
249 RtlCreateUnicodeStringFromAsciiz (&lpDatabaseNameW,lpDatabaseName);
250 ret = OpenSCManagerW(lpMachineNameW.Buffer,lpDatabaseNameW.Buffer, dwDesiredAccess);
251 RtlFreeUnicodeString(&lpDatabaseNameW);
252 RtlFreeUnicodeString(&lpMachineNameW);
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000253 return ret;
254}
255
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000256/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000257 * OpenSCManagerW [ADVAPI32.@]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000258 * Establishes a connection to the service control manager and opens database
259 *
260 * NOTES
Matthew Beckere905f3c1999-01-28 13:46:25 +0000261 * This should return a SC_HANDLE
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000262 *
263 * PARAMS
Matthew Beckere905f3c1999-01-28 13:46:25 +0000264 * lpMachineName [I] Pointer to machine name string
265 * lpDatabaseName [I] Pointer to database name string
266 * dwDesiredAccess [I] Type of access
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000267 *
268 * RETURNS
Matthew Beckere905f3c1999-01-28 13:46:25 +0000269 * Success: Handle to service control manager database
270 * Failure: NULL
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000271 */
Patrik Stridvall4a739731999-07-04 11:01:21 +0000272SC_HANDLE WINAPI
Alexandre Julliarda3960291999-02-26 11:11:13 +0000273OpenSCManagerW( LPCWSTR lpMachineName, LPCWSTR lpDatabaseName,
Matthew Beckere905f3c1999-01-28 13:46:25 +0000274 DWORD dwDesiredAccess )
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000275{
Mike McCormack9b513ad2003-12-02 03:48:53 +0000276 const WCHAR szKey[] = { 'S','y','s','t','e','m','\\',
277 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
278 'S','e','r','v','i','c','e','s','\\',0 };
279 HKEY hReg, hKey = NULL;
Michael McCormack75a84131999-11-21 00:58:14 +0000280 LONG r;
281
Vincent Béron9a624912002-05-31 23:06:46 +0000282 TRACE("(%s,%s,0x%08lx)\n", debugstr_w(lpMachineName),
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000283 debugstr_w(lpDatabaseName), dwDesiredAccess);
Michael McCormack75a84131999-11-21 00:58:14 +0000284
285 /*
286 * FIXME: what is lpDatabaseName?
287 * It should be set to "SERVICES_ACTIVE_DATABASE" according to
288 * docs, but what if it isn't?
289 */
290
Mike McCormack9b513ad2003-12-02 03:48:53 +0000291 r = RegConnectRegistryW(lpMachineName,HKEY_LOCAL_MACHINE,&hReg);
292 if (r==ERROR_SUCCESS)
293 {
294 r = RegOpenKeyExW(hReg, szKey, 0, dwDesiredAccess, &hKey );
295 RegCloseKey( hReg );
296 }
Michael McCormack75a84131999-11-21 00:58:14 +0000297
Mike McCormack9b513ad2003-12-02 03:48:53 +0000298 TRACE("returning %p\n", hKey);
Michael McCormack75a84131999-11-21 00:58:14 +0000299
300 return hKey;
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000301}
302
303
Matthew Beckere905f3c1999-01-28 13:46:25 +0000304/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000305 * AllocateLocallyUniqueId [ADVAPI32.@]
Matthew Beckere905f3c1999-01-28 13:46:25 +0000306 *
307 * PARAMS
308 * lpluid []
309 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000310BOOL WINAPI
Juergen Schmied1ed51af1999-02-12 17:47:07 +0000311AllocateLocallyUniqueId( PLUID lpluid )
Matthew Beckere905f3c1999-01-28 13:46:25 +0000312{
Francois Gougetea31cf02001-11-20 18:52:20 +0000313 lpluid->LowPart = time(NULL);
314 lpluid->HighPart = 0;
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000315 return TRUE;
316}
317
318
319/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000320 * ControlService [ADVAPI32.@]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000321 * Sends a control code to a Win32-based service.
322 *
Matthew Beckere905f3c1999-01-28 13:46:25 +0000323 * PARAMS
324 * hService []
325 * dwControl []
326 * lpServiceStatus []
327 *
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000328 * RETURNS STD
329 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000330BOOL WINAPI
Vincent Béron9a624912002-05-31 23:06:46 +0000331ControlService( SC_HANDLE hService, DWORD dwControl,
Matthew Beckere905f3c1999-01-28 13:46:25 +0000332 LPSERVICE_STATUS lpServiceStatus )
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000333{
Michael Stefaniuccbacde52002-10-25 19:17:33 +0000334 FIXME("(%p,%ld,%p): stub\n",hService,dwControl,lpServiceStatus);
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000335 return TRUE;
336}
337
338
339/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000340 * CloseServiceHandle [ADVAPI32.@]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000341 * Close handle to service or service control manager
342 *
343 * PARAMS
Matthew Beckere905f3c1999-01-28 13:46:25 +0000344 * hSCObject [I] Handle to service or service control manager database
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000345 *
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000346 * RETURNS STD
347 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000348BOOL WINAPI
Patrik Stridvall4a739731999-07-04 11:01:21 +0000349CloseServiceHandle( SC_HANDLE hSCObject )
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000350{
Michael Stefaniuccbacde52002-10-25 19:17:33 +0000351 TRACE("(%p)\n", hSCObject);
Michael McCormack75a84131999-11-21 00:58:14 +0000352
353 RegCloseKey(hSCObject);
Vincent Béron9a624912002-05-31 23:06:46 +0000354
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000355 return TRUE;
356}
357
358
359/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000360 * OpenServiceA [ADVAPI32.@]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000361 */
Patrik Stridvall4a739731999-07-04 11:01:21 +0000362SC_HANDLE WINAPI
Vincent Béron9a624912002-05-31 23:06:46 +0000363OpenServiceA( SC_HANDLE hSCManager, LPCSTR lpServiceName,
Matthew Beckere905f3c1999-01-28 13:46:25 +0000364 DWORD dwDesiredAccess )
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000365{
Matthew Davison6f2a0712003-01-20 23:23:12 +0000366 UNICODE_STRING lpServiceNameW;
François Gouget97ad5a72001-01-02 20:20:34 +0000367 SC_HANDLE ret;
Matthew Davison6f2a0712003-01-20 23:23:12 +0000368 RtlCreateUnicodeStringFromAsciiz (&lpServiceNameW,lpServiceName);
Michael McCormack75a84131999-11-21 00:58:14 +0000369 if(lpServiceName)
370 TRACE("Request for service %s\n",lpServiceName);
371 else
372 return FALSE;
Matthew Davison6f2a0712003-01-20 23:23:12 +0000373 ret = OpenServiceW( hSCManager, lpServiceNameW.Buffer, dwDesiredAccess);
374 RtlFreeUnicodeString(&lpServiceNameW);
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000375 return ret;
376}
377
378
379/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000380 * OpenServiceW [ADVAPI32.@]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000381 * Opens a handle to an existing service
382 *
Matthew Beckere905f3c1999-01-28 13:46:25 +0000383 * PARAMS
384 * hSCManager []
385 * lpServiceName []
386 * dwDesiredAccess []
387 *
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000388 * RETURNS
389 * Success: Handle to the service
390 * Failure: NULL
391 */
Patrik Stridvall4a739731999-07-04 11:01:21 +0000392SC_HANDLE WINAPI
393OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName,
Matthew Beckere905f3c1999-01-28 13:46:25 +0000394 DWORD dwDesiredAccess)
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000395{
Michael McCormack75a84131999-11-21 00:58:14 +0000396 HKEY hKey;
397 long r;
398
Michael Stefaniuccbacde52002-10-25 19:17:33 +0000399 TRACE("(%p,%p,%ld)\n",hSCManager, lpServiceName,
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000400 dwDesiredAccess);
Michael McCormack75a84131999-11-21 00:58:14 +0000401
Michael McCormack75a84131999-11-21 00:58:14 +0000402 /* FIXME: dwDesiredAccess may need some processing */
Mike McCormack9b513ad2003-12-02 03:48:53 +0000403 r = RegOpenKeyExW(hSCManager, lpServiceName, 0, dwDesiredAccess, &hKey );
Michael McCormack75a84131999-11-21 00:58:14 +0000404 if (r!=ERROR_SUCCESS)
405 return 0;
406
Michael Stefaniuccbacde52002-10-25 19:17:33 +0000407 TRACE("returning %p\n",hKey);
Michael McCormack75a84131999-11-21 00:58:14 +0000408
409 return hKey;
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000410}
411
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000412/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000413 * CreateServiceW [ADVAPI32.@]
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000414 */
415SC_HANDLE WINAPI
Peter Hunnisett565b0082000-09-19 02:43:00 +0000416CreateServiceW( SC_HANDLE hSCManager, LPCWSTR lpServiceName,
Vincent Béron9a624912002-05-31 23:06:46 +0000417 LPCWSTR lpDisplayName, DWORD dwDesiredAccess,
418 DWORD dwServiceType, DWORD dwStartType,
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000419 DWORD dwErrorControl, LPCWSTR lpBinaryPathName,
Vincent Béron9a624912002-05-31 23:06:46 +0000420 LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId,
421 LPCWSTR lpDependencies, LPCWSTR lpServiceStartName,
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000422 LPCWSTR lpPassword )
423{
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000424 HKEY hKey;
425 LONG r;
426 DWORD dp;
Mike McCormack9b513ad2003-12-02 03:48:53 +0000427 const WCHAR szDisplayName[] = { 'D','i','s','p','l','a','y','N','a','m','e', 0 };
428 const WCHAR szType[] = {'T','y','p','e',0};
429 const WCHAR szStart[] = {'S','t','a','r','t',0};
430 const WCHAR szError[] = {'E','r','r','o','r','C','o','n','t','r','o','l', 0};
431 const WCHAR szImagePath[] = {'I','m','a','g','e','P','a','t','h',0};
432 const WCHAR szGroup[] = {'G','r','o','u','p',0};
433 const WCHAR szDependencies[] = { 'D','e','p','e','n','d','e','n','c','i','e','s',0};
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000434
Mike McCormack9b513ad2003-12-02 03:48:53 +0000435 FIXME("%p %s %s\n", hSCManager,
436 debugstr_w(lpServiceName), debugstr_w(lpDisplayName));
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000437
Mike McCormack9b513ad2003-12-02 03:48:53 +0000438 r = RegCreateKeyExW(hSCManager, lpServiceName, 0, NULL,
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000439 REG_OPTION_NON_VOLATILE, dwDesiredAccess, NULL, &hKey, &dp);
440 if (r!=ERROR_SUCCESS)
441 return 0;
442 if (dp != REG_CREATED_NEW_KEY)
443 return 0;
444
445 if(lpDisplayName)
446 {
Mike McCormack9b513ad2003-12-02 03:48:53 +0000447 r = RegSetValueExW(hKey, szDisplayName, 0, REG_SZ, (LPBYTE)lpDisplayName,
448 (strlenW(lpDisplayName)+1)*sizeof(WCHAR) );
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000449 if (r!=ERROR_SUCCESS)
450 return 0;
451 }
452
Mike McCormack9b513ad2003-12-02 03:48:53 +0000453 r = RegSetValueExW(hKey, szType, 0, REG_DWORD, (LPVOID)&dwServiceType, sizeof (DWORD) );
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000454 if (r!=ERROR_SUCCESS)
455 return 0;
456
Mike McCormack9b513ad2003-12-02 03:48:53 +0000457 r = RegSetValueExW(hKey, szStart, 0, REG_DWORD, (LPVOID)&dwStartType, sizeof (DWORD) );
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000458 if (r!=ERROR_SUCCESS)
459 return 0;
460
Mike McCormack9b513ad2003-12-02 03:48:53 +0000461 r = RegSetValueExW(hKey, szError, 0, REG_DWORD,
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000462 (LPVOID)&dwErrorControl, sizeof (DWORD) );
463 if (r!=ERROR_SUCCESS)
464 return 0;
465
466 if(lpBinaryPathName)
467 {
Mike McCormack9b513ad2003-12-02 03:48:53 +0000468 r = RegSetValueExW(hKey, szImagePath, 0, REG_SZ, (LPBYTE)lpBinaryPathName,
469 (strlenW(lpBinaryPathName)+1)*sizeof(WCHAR) );
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000470 if (r!=ERROR_SUCCESS)
471 return 0;
472 }
473
474 if(lpLoadOrderGroup)
475 {
Mike McCormack9b513ad2003-12-02 03:48:53 +0000476 r = RegSetValueExW(hKey, szGroup, 0, REG_SZ, (LPBYTE)lpLoadOrderGroup,
477 (strlenW(lpLoadOrderGroup)+1)*sizeof(WCHAR) );
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000478 if (r!=ERROR_SUCCESS)
479 return 0;
480 }
481
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000482 if(lpDependencies)
483 {
Vincent Béron9a624912002-05-31 23:06:46 +0000484 DWORD len = 0;
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000485
486 /* determine the length of a double null terminated multi string */
487 do {
Mike McCormack9b513ad2003-12-02 03:48:53 +0000488 len += (strlenW(&lpDependencies[len])+1);
Vincent Béron9a624912002-05-31 23:06:46 +0000489 } while (lpDependencies[len++]);
490
Mike McCormack9b513ad2003-12-02 03:48:53 +0000491 r = RegSetValueExW(hKey, szDependencies, 0, REG_MULTI_SZ,
492 (LPBYTE)lpDependencies, len );
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000493 if (r!=ERROR_SUCCESS)
494 return 0;
495 }
496
497 if(lpPassword)
498 {
499 FIXME("Don't know how to add a Password for a service.\n");
500 }
501
502 if(lpServiceStartName)
503 {
504 FIXME("Don't know how to add a ServiceStartName for a service.\n");
505 }
506
507 return hKey;
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000508}
509
510
Mike McCormack9b513ad2003-12-02 03:48:53 +0000511static inline LPWSTR SERV_dup( LPCSTR str )
512{
513 UINT len;
514 LPWSTR wstr;
515
516 if( !str )
517 return NULL;
518 len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
519 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
520 MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, len );
521 return wstr;
522}
523
524static inline LPWSTR SERV_dupmulti( LPCSTR str )
525{
526 UINT len = 0, n = 0;
527 LPWSTR wstr;
528
529 do {
530 len += MultiByteToWideChar( CP_ACP, 0, &str[n], -1, NULL, 0 );
531 n += (strlen( &str[n] ) + 1);
532 } while (str[n]);
533 len++;
534 n++;
535
536 wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
537 MultiByteToWideChar( CP_ACP, 0, str, n, wstr, len );
538 return wstr;
539}
540
541static inline VOID SERV_free( LPWSTR wstr )
542{
543 HeapFree( GetProcessHeap(), 0, wstr );
544}
545
546/******************************************************************************
547 * CreateServiceA [ADVAPI32.@]
548 */
549SC_HANDLE WINAPI
550CreateServiceA( SC_HANDLE hSCManager, LPCSTR lpServiceName,
551 LPCSTR lpDisplayName, DWORD dwDesiredAccess,
552 DWORD dwServiceType, DWORD dwStartType,
553 DWORD dwErrorControl, LPCSTR lpBinaryPathName,
554 LPCSTR lpLoadOrderGroup, LPDWORD lpdwTagId,
555 LPCSTR lpDependencies, LPCSTR lpServiceStartName,
556 LPCSTR lpPassword )
557{
558 LPWSTR lpServiceNameW, lpDisplayNameW, lpBinaryPathNameW,
559 lpLoadOrderGroupW, lpDependenciesW, lpServiceStartNameW, lpPasswordW;
560 SC_HANDLE r;
561
562 TRACE("%p %s %s\n", hSCManager,
563 debugstr_a(lpServiceName), debugstr_a(lpDisplayName));
564
565 lpServiceNameW = SERV_dup( lpServiceName );
566 lpDisplayNameW = SERV_dup( lpDisplayName );
567 lpBinaryPathNameW = SERV_dup( lpBinaryPathName );
568 lpLoadOrderGroupW = SERV_dup( lpLoadOrderGroup );
569 lpDependenciesW = SERV_dupmulti( lpDependencies );
570 lpServiceStartNameW = SERV_dup( lpServiceStartName );
571 lpPasswordW = SERV_dup( lpPassword );
572
573 r = CreateServiceW( hSCManager, lpServiceNameW, lpDisplayNameW,
574 dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl,
575 lpBinaryPathNameW, lpLoadOrderGroupW, lpdwTagId,
576 lpDependenciesW, lpServiceStartNameW, lpPasswordW );
577
578 SERV_free( lpServiceNameW );
579 SERV_free( lpDisplayNameW );
580 SERV_free( lpBinaryPathNameW );
581 SERV_free( lpLoadOrderGroupW );
582 SERV_free( lpDependenciesW );
583 SERV_free( lpServiceStartNameW );
584 SERV_free( lpPasswordW );
585
586 return r;
587}
588
589
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000590/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000591 * DeleteService [ADVAPI32.@]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000592 *
593 * PARAMS
594 * hService [I] Handle to service
595 *
596 * RETURNS STD
597 *
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000598 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000599BOOL WINAPI
Patrik Stridvall4a739731999-07-04 11:01:21 +0000600DeleteService( SC_HANDLE hService )
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000601{
Michael Stefaniuccbacde52002-10-25 19:17:33 +0000602 FIXME("(%p): stub\n",hService);
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000603 return TRUE;
604}
605
606
607/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000608 * StartServiceA [ADVAPI32.@]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000609 *
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000610 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000611BOOL WINAPI
Patrik Stridvall4a739731999-07-04 11:01:21 +0000612StartServiceA( SC_HANDLE hService, DWORD dwNumServiceArgs,
Matthew Beckere905f3c1999-01-28 13:46:25 +0000613 LPCSTR *lpServiceArgVectors )
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000614{
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000615 LPWSTR *lpwstr=NULL;
Matthew Davison60009b92003-01-23 23:07:38 +0000616 UNICODE_STRING usBuffer;
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000617 int i;
618
Michael Stefaniuccbacde52002-10-25 19:17:33 +0000619 TRACE("(%p,%ld,%p)\n",hService,dwNumServiceArgs,lpServiceArgVectors);
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000620
621 if(dwNumServiceArgs)
Vincent Béron9a624912002-05-31 23:06:46 +0000622 lpwstr = (LPWSTR*) HeapAlloc( GetProcessHeap(), 0,
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000623 dwNumServiceArgs*sizeof(LPWSTR) );
624 else
625 lpwstr = NULL;
626
627 for(i=0; i<dwNumServiceArgs; i++)
Matthew Davison60009b92003-01-23 23:07:38 +0000628 {
629 RtlCreateUnicodeStringFromAsciiz (&usBuffer,lpServiceArgVectors[i]);
630 lpwstr[i]=usBuffer.Buffer;
631 }
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000632
Andreas Mohr7fb732e1999-12-12 00:47:51 +0000633 StartServiceW(hService, dwNumServiceArgs, (LPCWSTR *)lpwstr);
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000634
635 if(dwNumServiceArgs)
636 {
637 for(i=0; i<dwNumServiceArgs; i++)
638 HeapFree(GetProcessHeap(), 0, lpwstr[i]);
639 HeapFree(GetProcessHeap(), 0, lpwstr);
640 }
641
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000642 return TRUE;
643}
644
645
646/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000647 * StartServiceW [ADVAPI32.@]
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000648 * Starts a service
649 *
650 * PARAMS
Matthew Beckere905f3c1999-01-28 13:46:25 +0000651 * hService [I] Handle of service
652 * dwNumServiceArgs [I] Number of arguments
653 * lpServiceArgVectors [I] Address of array of argument string pointers
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000654 *
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000655 * NOTES
656 *
657 * NT implements this function using an obscure RPC call...
658 *
659 * Might need to do a "setenv SystemRoot \\WINNT" in your .cshrc
660 * to get things like %SystemRoot%\\System32\\service.exe to load.
661 *
662 * Will only work for shared address space. How should the service
663 * args be transferred when address spaces are separated?
664 *
665 * Can only start one service at a time.
666 *
Francois Gouget3bb9a362001-10-22 19:04:32 +0000667 * Has no concept of privilege.
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000668 *
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000669 * RETURNS STD
670 *
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000671 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000672BOOL WINAPI
Patrik Stridvall4a739731999-07-04 11:01:21 +0000673StartServiceW( SC_HANDLE hService, DWORD dwNumServiceArgs,
Matthew Beckere905f3c1999-01-28 13:46:25 +0000674 LPCWSTR *lpServiceArgVectors )
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000675{
Matthew Davison620323e2003-01-24 00:45:51 +0000676 static const WCHAR _WaitServiceStartW[] = {'A','D','V','A','P','I','_','W',
677 'a','i','t','S','e','r','v','i',
678 'c','e','S','t','a','r','t',0};
679 static const WCHAR _ImagePathW[] = {'I','m','a','g','e','P','a','t','h',0};
680
681 WCHAR path[MAX_PATH],str[MAX_PATH];
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000682 DWORD type,size;
683 long r;
684 HANDLE data,wait;
685 PROCESS_INFORMATION procinfo;
Matthew Davison620323e2003-01-24 00:45:51 +0000686 STARTUPINFOW startupinfo;
Michael Stefaniuccbacde52002-10-25 19:17:33 +0000687 TRACE("(%p,%ld,%p)\n",hService,dwNumServiceArgs,
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000688 lpServiceArgVectors);
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000689
Francois Gouget95918362003-06-18 19:45:22 +0000690 size = sizeof(str);
Matthew Davison620323e2003-01-24 00:45:51 +0000691 r = RegQueryValueExW(hService, _ImagePathW, NULL, &type, (LPVOID)str, &size);
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000692 if (r!=ERROR_SUCCESS)
693 return FALSE;
Francois Gouget95918362003-06-18 19:45:22 +0000694 ExpandEnvironmentStringsW(str,path,sizeof(path));
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000695
Matthew Davison620323e2003-01-24 00:45:51 +0000696 TRACE("Starting service %s\n", debugstr_w(path) );
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000697
Matthew Davison620323e2003-01-24 00:45:51 +0000698 data = CreateSemaphoreW(NULL,1,1,_ServiceStartDataW);
Alexandre Julliard73755972002-07-31 19:26:03 +0000699 if (!data)
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000700 {
Alexandre Julliardb10dcfe2003-10-10 00:05:49 +0000701 ERR("Couldn't create data semaphore\n");
702 return FALSE;
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000703 }
Matthew Davison620323e2003-01-24 00:45:51 +0000704 wait = CreateSemaphoreW(NULL,0,1,_WaitServiceStartW);
Alexandre Julliardb10dcfe2003-10-10 00:05:49 +0000705 if (!wait)
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000706 {
Alexandre Julliardb10dcfe2003-10-10 00:05:49 +0000707 ERR("Couldn't create wait semaphore\n");
708 return FALSE;
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000709 }
710
Vincent Béron9a624912002-05-31 23:06:46 +0000711 /*
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000712 * FIXME: lpServiceArgsVectors need to be stored and returned to
713 * the service when it calls StartServiceCtrlDispatcher
714 *
715 * Chuck these in a global (yuk) so we can pass them to
716 * another process - address space separation will break this.
717 */
Vincent Béron9a624912002-05-31 23:06:46 +0000718
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000719 r = WaitForSingleObject(data,INFINITE);
720
721 if( r == WAIT_FAILED)
722 return FALSE;
723
Andreas Mohr18a9d742001-01-17 21:52:42 +0000724 FIXME("problematic because of address space separation.\n");
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000725 start_dwNumServiceArgs = dwNumServiceArgs;
Andreas Mohr7fb732e1999-12-12 00:47:51 +0000726 start_lpServiceArgVectors = (LPWSTR *)lpServiceArgVectors;
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000727
Matthew Davison620323e2003-01-24 00:45:51 +0000728 ZeroMemory(&startupinfo,sizeof(STARTUPINFOW));
729 startupinfo.cb = sizeof(STARTUPINFOW);
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000730
Matthew Davison620323e2003-01-24 00:45:51 +0000731 r = CreateProcessW(path,
Vincent Béron9a624912002-05-31 23:06:46 +0000732 NULL,
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000733 NULL, /* process security attribs */
734 NULL, /* thread security attribs */
735 FALSE, /* inherit handles */
736 0, /* creation flags */
737 NULL, /* environment */
738 NULL, /* current directory */
739 &startupinfo, /* startup info */
740 &procinfo); /* process info */
741
742 if(r == FALSE)
743 {
744 ERR("Couldn't start process\n");
745 /* ReleaseSemaphore(data, 1, NULL);
746 return FALSE; */
747 }
748
749 /* docs for StartServiceCtrlDispatcher say this should be 30 sec */
750 r = WaitForSingleObject(wait,30000);
Vincent Béron9a624912002-05-31 23:06:46 +0000751
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000752 ReleaseSemaphore(data, 1, NULL);
753
754 if( r == WAIT_FAILED)
755 return FALSE;
756
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000757 return TRUE;
758}
759
760/******************************************************************************
Patrik Stridvalld0a41772001-02-14 23:11:17 +0000761 * QueryServiceStatus [ADVAPI32.@]
Matthew Beckere905f3c1999-01-28 13:46:25 +0000762 *
763 * PARAMS
764 * hService []
765 * lpservicestatus []
Vincent Béron9a624912002-05-31 23:06:46 +0000766 *
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000767 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000768BOOL WINAPI
Patrik Stridvall4a739731999-07-04 11:01:21 +0000769QueryServiceStatus( SC_HANDLE hService, LPSERVICE_STATUS lpservicestatus )
Matthew Beckere905f3c1999-01-28 13:46:25 +0000770{
Michael McCormack75a84131999-11-21 00:58:14 +0000771 LONG r;
772 DWORD type, val, size;
773
Michael Stefaniuccbacde52002-10-25 19:17:33 +0000774 FIXME("(%p,%p) partial\n",hService,lpservicestatus);
Michael McCormack75a84131999-11-21 00:58:14 +0000775
776 /* read the service type from the registry */
Francois Gouget95918362003-06-18 19:45:22 +0000777 size = sizeof(val);
Michael McCormack75a84131999-11-21 00:58:14 +0000778 r = RegQueryValueExA(hService, "Type", NULL, &type, (LPBYTE)&val, &size);
779 if(type!=REG_DWORD)
780 {
781 ERR("invalid Type\n");
782 return FALSE;
783 }
784 lpservicestatus->dwServiceType = val;
Michael McCormack75a84131999-11-21 00:58:14 +0000785 /* FIXME: how are these determined or read from the registry? */
Michael McCormack0c0f7d31999-12-04 04:03:45 +0000786 /* SERVICE: unavailable=0, stopped=1, starting=2, running=3? */;
787 lpservicestatus->dwCurrentState = 1;
Michael McCormack75a84131999-11-21 00:58:14 +0000788 lpservicestatus->dwControlsAccepted = 0;
789 lpservicestatus->dwWin32ExitCode = NO_ERROR;
790 lpservicestatus->dwServiceSpecificExitCode = 0;
791 lpservicestatus->dwCheckPoint = 0;
792 lpservicestatus->dwWaitHint = 0;
793
794 return TRUE;
Juergen Schmiedf7b0de31999-01-03 12:48:29 +0000795}
Steve Lustbaderf1e1fd02002-11-25 20:50:53 +0000796
797/******************************************************************************
798 * QueryServiceStatusEx [ADVAPI32.@]
799 *
800 * PARAMS
801 * hService [handle to service]
802 * InfoLevel [information level]
803 * lpBuffer [buffer]
804 * cbBufSize [size of buffer]
805 * pcbBytesNeeded [bytes needed]
806*/
807BOOL WINAPI QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel,
808 LPBYTE lpBuffer, DWORD cbBufSize,
809 LPDWORD pcbBytesNeeded)
810{
811 FIXME("stub\n");
812 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
813 return FALSE;
814}
Mike McCormack9b513ad2003-12-02 03:48:53 +0000815
816/******************************************************************************
817 * QueryServiceConfigA [ADVAPI32.@]
818 */
819BOOL WINAPI
820QueryServiceConfigA( SC_HANDLE hService,
821 LPQUERY_SERVICE_CONFIGA lpServiceConfig,
822 DWORD cbBufSize, LPDWORD pcbBytesNeeded)
823{
824 FIXME("%p %p %ld %p\n", hService, lpServiceConfig,
825 cbBufSize, pcbBytesNeeded);
826 return FALSE;
827}
828
829/******************************************************************************
830 * QueryServiceConfigW [ADVAPI32.@]
831 */
832BOOL WINAPI
833QueryServiceConfigW( SC_HANDLE hService,
834 LPQUERY_SERVICE_CONFIGW lpServiceConfig,
835 DWORD cbBufSize, LPDWORD pcbBytesNeeded)
836{
837 const WCHAR szDisplayName[] = {
838 'D','i','s','p','l','a','y','N','a','m','e', 0 };
839 const WCHAR szType[] = {'T','y','p','e',0};
840 const WCHAR szStart[] = {'S','t','a','r','t',0};
841 const WCHAR szError[] = {
842 'E','r','r','o','r','C','o','n','t','r','o','l', 0};
843 const WCHAR szImagePath[] = {'I','m','a','g','e','P','a','t','h',0};
844 const WCHAR szGroup[] = {'G','r','o','u','p',0};
845 const WCHAR szDependencies[] = {
846 'D','e','p','e','n','d','e','n','c','i','e','s',0};
847 LONG r;
848 DWORD type, val, sz, total, n;
849 LPBYTE p;
850
851 TRACE("%p %p %ld %p\n", hService, lpServiceConfig,
852 cbBufSize, pcbBytesNeeded);
853
854 /* calculate the size required first */
855 total = sizeof (QUERY_SERVICE_CONFIGW);
856
857 sz = 0;
858 r = RegQueryValueExW( hService, szImagePath, 0, &type, NULL, &sz );
859 if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) )
860 total += sz;
861
862 sz = 0;
863 r = RegQueryValueExW( hService, szGroup, 0, &type, NULL, &sz );
864 if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) )
865 total += sz;
866
867 sz = 0;
868 r = RegQueryValueExW( hService, szDependencies, 0, &type, NULL, &sz );
869 if( ( r == ERROR_SUCCESS ) && ( type == REG_MULTI_SZ ) )
870 total += sz;
871
872 sz = 0;
873 r = RegQueryValueExW( hService, szStart, 0, &type, NULL, &sz );
874 if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) )
875 total += sz;
876
877 sz = 0;
878 r = RegQueryValueExW( hService, szDisplayName, 0, &type, NULL, &sz );
879 if( ( r == ERROR_SUCCESS ) && ( type == REG_SZ ) )
880 total += sz;
881
882 /* if there's not enough memory, return an error */
883 if( total > *pcbBytesNeeded )
884 {
885 *pcbBytesNeeded = total;
886 SetLastError( ERROR_INSUFFICIENT_BUFFER );
887 return FALSE;
888 }
889
890 *pcbBytesNeeded = total;
891 ZeroMemory( lpServiceConfig, total );
892
893 sz = sizeof val;
894 r = RegQueryValueExW( hService, szType, 0, &type, (LPBYTE)&val, &sz );
895 if( ( r == ERROR_SUCCESS ) || ( type == REG_DWORD ) )
896 lpServiceConfig->dwServiceType = val;
897
898 sz = sizeof val;
899 r = RegQueryValueExW( hService, szStart, 0, &type, (LPBYTE)&val, &sz );
900 if( ( r == ERROR_SUCCESS ) || ( type == REG_DWORD ) )
901 lpServiceConfig->dwStartType = val;
902
903 sz = sizeof val;
904 r = RegQueryValueExW( hService, szError, 0, &type, (LPBYTE)&val, &sz );
905 if( ( r == ERROR_SUCCESS ) || ( type == REG_DWORD ) )
906 lpServiceConfig->dwErrorControl = val;
907
908 /* now do the strings */
909 p = (LPBYTE) &lpServiceConfig[1];
910 n = total - sizeof (QUERY_SERVICE_CONFIGW);
911
912 sz = n;
913 r = RegQueryValueExW( hService, szImagePath, 0, &type, p, &sz );
914 if( ( r == ERROR_SUCCESS ) || ( type == REG_SZ ) )
915 {
916 lpServiceConfig->lpBinaryPathName = (LPWSTR) p;
917 p += sz;
918 n -= sz;
919 }
920
921 sz = n;
922 r = RegQueryValueExW( hService, szGroup, 0, &type, p, &sz );
923 if( ( r == ERROR_SUCCESS ) || ( type == REG_SZ ) )
924 {
925 lpServiceConfig->lpLoadOrderGroup = (LPWSTR) p;
926 p += sz;
927 n -= sz;
928 }
929
930 sz = n;
931 r = RegQueryValueExW( hService, szDependencies, 0, &type, p, &sz );
932 if( ( r == ERROR_SUCCESS ) || ( type == REG_SZ ) )
933 {
934 lpServiceConfig->lpDependencies = (LPWSTR) p;
935 p += sz;
936 n -= sz;
937 }
938
939 if( n < 0 )
940 ERR("Buffer overflow!\n");
941
942 TRACE("Image path = %s\n", debugstr_w(lpServiceConfig->lpBinaryPathName) );
943 TRACE("Group = %s\n", debugstr_w(lpServiceConfig->lpLoadOrderGroup) );
944
945 return TRUE;
946}
947
948/******************************************************************************
949 * ChangeServiceConfigW [ADVAPI32.@]
950 */
951BOOL WINAPI ChangeServiceConfigW( SC_HANDLE hService, DWORD dwServiceType,
952 DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName,
953 LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCWSTR lpDependencies,
954 LPCWSTR lpServiceStartName, LPCWSTR lpPassword, LPCWSTR lpDisplayName)
955{
956 FIXME("%p %ld %ld %ld %s %s %p %p %s %s %s\n",
957 hService, dwServiceType, dwStartType, dwErrorControl,
958 debugstr_w(lpBinaryPathName), debugstr_w(lpLoadOrderGroup),
959 lpdwTagId, lpDependencies, debugstr_w(lpServiceStartName),
960 debugstr_w(lpPassword), debugstr_w(lpDisplayName) );
961 return TRUE;
962}
963
964/******************************************************************************
965 * ChangeServiceConfigA [ADVAPI32.@]
966 */
967BOOL WINAPI ChangeServiceConfigA( SC_HANDLE hService, DWORD dwServiceType,
968 DWORD dwStartType, DWORD dwErrorControl, LPCSTR lpBinaryPathName,
969 LPCSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCSTR lpDependencies,
970 LPCSTR lpServiceStartName, LPCSTR lpPassword, LPCSTR lpDisplayName)
971{
972 FIXME("%p %ld %ld %ld %s %s %p %p %s %s %s\n",
973 hService, dwServiceType, dwStartType, dwErrorControl,
974 debugstr_a(lpBinaryPathName), debugstr_a(lpLoadOrderGroup),
975 lpdwTagId, lpDependencies, debugstr_a(lpServiceStartName),
976 debugstr_a(lpPassword), debugstr_a(lpDisplayName) );
977 return TRUE;
978}