From 3dc71b65a77d3f1c6c6ec73d538d8db4bd5a148b Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Sat, 13 Dec 2003 03:25:37 +0000 Subject: [PATCH] Better handling of some service functions. --- dlls/advapi32/service.c | 105 ++++++++++++++++++++++++++++++++++++++-- include/winsvc.h | 52 ++++++++++++++++++++ 2 files changed, 152 insertions(+), 5 deletions(-) diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index f743d4b70ee..70f7b5297a6 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -40,6 +40,10 @@ static LPWSTR *start_lpServiceArgVectors; static const WCHAR _ServiceStartDataW[] = {'A','D','V','A','P','I','_','S', 'e','r','v','i','c','e','S','t', 'a','r','t','D','a','t','a',0}; +static const WCHAR szServiceManagerKey[] = { 'S','y','s','t','e','m','\\', + 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', + 'S','e','r','v','i','c','e','s','\\',0 }; + /****************************************************************************** * EnumServicesStatusA [ADVAPI32.@] @@ -273,9 +277,6 @@ SC_HANDLE WINAPI OpenSCManagerW( LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess ) { - const WCHAR szKey[] = { 'S','y','s','t','e','m','\\', - 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', - 'S','e','r','v','i','c','e','s','\\',0 }; HKEY hReg, hKey = NULL; LONG r; @@ -291,7 +292,7 @@ OpenSCManagerW( LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, r = RegConnectRegistryW(lpMachineName,HKEY_LOCAL_MACHINE,&hReg); if (r==ERROR_SUCCESS) { - r = RegOpenKeyExW(hReg, szKey, 0, dwDesiredAccess, &hKey ); + r = RegOpenKeyExW(hReg, szServiceManagerKey,0, dwDesiredAccess, &hKey ); RegCloseKey( hReg ); } @@ -436,9 +437,10 @@ CreateServiceW( SC_HANDLE hSCManager, LPCWSTR lpServiceName, debugstr_w(lpServiceName), debugstr_w(lpDisplayName)); r = RegCreateKeyExW(hSCManager, lpServiceName, 0, NULL, - REG_OPTION_NON_VOLATILE, dwDesiredAccess, NULL, &hKey, &dp); + REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dp); if (r!=ERROR_SUCCESS) return 0; + if (dp != REG_CREATED_NEW_KEY) return 0; @@ -601,7 +603,64 @@ CreateServiceA( SC_HANDLE hSCManager, LPCSTR lpServiceName, BOOL WINAPI DeleteService( SC_HANDLE hService ) { + WCHAR valname[MAX_PATH+1]; + INT index = 0; + LONG rc; + DWORD value = 0x1; + DWORD size; + HKEY hKey; + + static const WCHAR szDeleted[] = {'D','e','l','e','t','e','d',0}; + FIXME("(%p): stub\n",hService); + + size = MAX_PATH+1; + /* Clean out the values */ + rc = RegEnumValueW(hService, index, valname,&size,0,0,0,0); + while (rc == ERROR_SUCCESS) + { + RegDeleteValueW(hService,valname); + index++; + size = MAX_PATH+1; + rc = RegEnumValueW(hService, index, valname, &size,0,0,0,0); + } + + /* tag for deletion */ + RegSetValueExW(hService, szDeleted, 0, REG_DWORD, (LPVOID)&value, + sizeof (DWORD) ); + + RegCloseKey(hService); + + /* find and delete the key */ + rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szServiceManagerKey,0, + KEY_ALL_ACCESS, &hKey ); + index = 0; + size = MAX_PATH+1; + rc = RegEnumKeyExW(hKey,0, valname, &size, 0, 0, 0, 0); + while (rc == ERROR_SUCCESS) + { + HKEY checking; + rc = RegOpenKeyExW(hKey,valname,0,KEY_ALL_ACCESS,&checking); + if (rc == ERROR_SUCCESS) + { + DWORD deleted = 0; + DWORD size = sizeof(DWORD); + rc = RegQueryValueExW(checking, szDeleted , NULL, NULL, + (LPVOID)&deleted, &size); + if (deleted) + { + RegDeleteValueW(checking,szDeleted); + RegDeleteKeyW(hKey,valname); + } + else + index ++; + RegCloseKey(checking); + } + size = MAX_PATH+1; + rc = RegEnumKeyExW(hKey, index, valname, &size, 0, 0, 0, 0); + } + RegCloseKey(hKey); + return TRUE; } @@ -978,3 +1037,39 @@ BOOL WINAPI ChangeServiceConfigA( SC_HANDLE hService, DWORD dwServiceType, debugstr_a(lpPassword), debugstr_a(lpDisplayName) ); return TRUE; } + +/****************************************************************************** + * ChangeServiceConfig2A [ADVAPI32.@] + */ +BOOL WINAPI ChangeServiceConfig2A( SC_HANDLE hService, DWORD dwInfoLevel, + LPVOID lpInfo) +{ + FIXME("STUB: %p %ld %p\n",hService, dwInfoLevel, lpInfo); + return TRUE; +} + +/****************************************************************************** + * ChangeServiceConfig2W [ADVAPI32.@] + */ +BOOL WINAPI ChangeServiceConfig2W( SC_HANDLE hService, DWORD dwInfoLevel, + LPVOID lpInfo) +{ + if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION) + { + static const WCHAR szDescription[] = {'D','e','s','c','r','i','p','t','i','o','n',0}; + LPSERVICE_DESCRIPTIONW sd = (LPSERVICE_DESCRIPTIONW)lpInfo; + if (sd->lpDescription) + { + TRACE("Setting Description to %s\n",debugstr_w(sd->lpDescription)); + if (sd->lpDescription[0] == 0) + RegDeleteValueW(hService,szDescription); + else + RegSetValueExW(hService, szDescription, 0, REG_SZ, + (LPVOID)sd->lpDescription, + sizeof(WCHAR)*(strlenW(sd->lpDescription)+1)); + } + } + else + FIXME("STUB: %p %ld %p\n",hService, dwInfoLevel, lpInfo); + return TRUE; +} diff --git a/include/winsvc.h b/include/winsvc.h index fe37ead5354..572a9582c0b 100644 --- a/include/winsvc.h +++ b/include/winsvc.h @@ -178,12 +178,64 @@ typedef struct _QUERY_SERVICE_CONFIGW { LPWSTR lpDisplayName; } QUERY_SERVICE_CONFIGW, *LPQUERY_SERVICE_CONFIGW; +/* defines and structures for ChangeServiceConfig2 */ +#define SERVICE_CONFIG_DESCRIPTION 1 +#define SERVICE_CONFIG_FAILURE_ACTIONS 2 + +typedef struct _SERVICE_DESCRIPTIONA { + LPSTR lpDescription; +} SERVICE_DESCRIPTIONA,*LPSERVICE_DESCRIPTIONA; + +typedef struct _SERVICE_DESCRIPTIONW { + LPWSTR lpDescription; +} SERVICE_DESCRIPTIONW,*LPSERVICE_DESCRIPTIONW; + +DECL_WINELIB_TYPE_AW(SERVICE_DESCRIPTION) +DECL_WINELIB_TYPE_AW(LPSERVICE_DESCRIPTION) + +typedef enum _SC_ACTION_TYPE { + SC_ACTION_NONE = 0, + SC_ACTION_RESTART = 1, + SC_ACTION_REBOOT = 2, + SC_ACTION_RUN_COMMAND = 3 +} SC_ACTION_TYPE; + +typedef struct _SC_ACTION { + SC_ACTION_TYPE Type; + DWORD Delay; +} SC_ACTION,*LPSC_ACTION; + +typedef struct _SERVICE_FAILURE_ACTIONSA { + DWORD dwResetPeriod; + LPSTR lpRebootMsg; + LPSTR lpCommand; + DWORD cActions; + SC_ACTION * lpsaActions; +} SERVICE_FAILURE_ACTIONSA,*LPSERVICE_FAILURE_ACTIONSA; + +typedef struct _SERVICE_FAILURE_ACTIONSW { + DWORD dwResetPeriod; + LPWSTR lpRebootMsg; + LPWSTR lpCommand; + DWORD cActions; + SC_ACTION * lpsaActions; +} SERVICE_FAILURE_ACTIONSW,*LPSERVICE_FAILURE_ACTIONSW; + +DECL_WINELIB_TYPE_AW(SERVICE_FAILURE_ACTIONS) +DECL_WINELIB_TYPE_AW(LPSERVICE_FAILURE_ACTIONS) + /* Service control handler function prototype */ typedef VOID (WINAPI *LPHANDLER_FUNCTION)(DWORD); /* API function prototypes */ +BOOL WINAPI ChangeServiceConfigA(SC_HANDLE,DWORD,DWORD,DWORD,LPCSTR,LPCSTR,LPDWORD,LPCSTR,LPCSTR,LPCSTR,LPCSTR); +BOOL WINAPI ChangeServiceConfigW(SC_HANDLE,DWORD,DWORD,DWORD,LPCWSTR,LPCWSTR,LPDWORD,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR); +#define ChangeServiceConfig WINELIB_NAME_AW(ChangeServiceConfig) +BOOL WINAPI ChangeServiceConfig2A(SC_HANDLE,DWORD,LPVOID); +BOOL WINAPI ChangeServiceConfig2W(SC_HANDLE,DWORD,LPVOID); +#define ChangeServiceConfig2 WINELIB_NAME_AW(ChangeServiceConfig2) BOOL WINAPI CloseServiceHandle(SC_HANDLE); BOOL WINAPI ControlService(SC_HANDLE,DWORD,LPSERVICE_STATUS); SC_HANDLE WINAPI CreateServiceA(SC_HANDLE,LPCSTR,LPCSTR,DWORD,DWORD,DWORD,DWORD,LPCSTR,