diff options
Diffstat (limited to 'sql/winservice.h')
-rw-r--r-- | sql/winservice.h | 176 |
1 files changed, 174 insertions, 2 deletions
diff --git a/sql/winservice.h b/sql/winservice.h index f9ab3eda332..aa0528be5ee 100644 --- a/sql/winservice.h +++ b/sql/winservice.h @@ -17,11 +17,22 @@ /* Extract properties of a windows service binary path */ +#pragma once + #ifdef __cplusplus extern "C" { #endif -#include <windows.h> +#include <windows.h> +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4995) +#endif +#include <winsvc.h> +#ifdef _MSC_VER +#pragma warning(pop) +#endif + typedef struct mysqld_service_properties_st { char mysqld_exe[MAX_PATH]; @@ -32,9 +43,170 @@ typedef struct mysqld_service_properties_st int version_patch; } mysqld_service_properties; -extern int get_mysql_service_properties(const wchar_t *bin_path, +extern int get_mysql_service_properties(const wchar_t *bin_path, mysqld_service_properties *props); + +#if !defined(UNICODE) +/* + The following wrappers workaround Windows bugs + with CreateService/OpenService with ANSI codepage UTF8. + + Apparently, these function in ANSI mode, for this codepage only + do *not* behave as expected (as-if string parameters were + converted to UTF16 and "wide" function were called) +*/ +#include <malloc.h> +static inline wchar_t* awstrdup(const char *str) +{ + if (!str) + return NULL; + size_t len= strlen(str) + 1; + wchar_t *wstr= (wchar_t *) malloc(sizeof(wchar_t)*len); + if (MultiByteToWideChar(GetACP(), 0, str, (int)len, wstr, (int)len) == 0) + { + free(wstr); + return NULL; + } + return wstr; +} + +#define AWSTRDUP(dest, src) \ + dest= awstrdup(src); \ + if (src && !dest) \ + { \ + ok= FALSE; \ + last_error = ERROR_OUTOFMEMORY; \ + goto end; \ + } + +static inline SC_HANDLE my_OpenService(SC_HANDLE hSCManager, LPCSTR lpServiceName, DWORD dwDesiredAccess) +{ + wchar_t *w_ServiceName= NULL; + BOOL ok=TRUE; + DWORD last_error=0; + SC_HANDLE sch=NULL; + + AWSTRDUP(w_ServiceName, lpServiceName); + sch= OpenServiceW(hSCManager, w_ServiceName, dwDesiredAccess); + if (!sch) + { + ok= FALSE; + last_error= GetLastError(); + } + +end: + free(w_ServiceName); + if (!ok) + SetLastError(last_error); + return sch; +} + +static inline SC_HANDLE my_CreateService(SC_HANDLE hSCManager, + LPCSTR lpServiceName, LPCSTR lpDisplayName, + DWORD dwDesiredAccess, DWORD dwServiceType, + DWORD dwStartType, DWORD dwErrorControl, + LPCSTR lpBinaryPathName, LPCSTR lpLoadOrderGroup, + LPDWORD lpdwTagId, LPCSTR lpDependencies, + LPCSTR lpServiceStartName, LPCSTR lpPassword) +{ + wchar_t *w_ServiceName= NULL; + wchar_t *w_DisplayName= NULL; + wchar_t *w_BinaryPathName= NULL; + wchar_t *w_LoadOrderGroup= NULL; + wchar_t *w_Dependencies= NULL; + wchar_t *w_ServiceStartName= NULL; + wchar_t *w_Password= NULL; + SC_HANDLE sch = NULL; + DWORD last_error=0; + BOOL ok= TRUE; + + AWSTRDUP(w_ServiceName,lpServiceName); + AWSTRDUP(w_DisplayName,lpDisplayName); + AWSTRDUP(w_BinaryPathName, lpBinaryPathName); + AWSTRDUP(w_LoadOrderGroup, lpLoadOrderGroup); + AWSTRDUP(w_Dependencies, lpDependencies); + AWSTRDUP(w_ServiceStartName, lpServiceStartName); + AWSTRDUP(w_Password, lpPassword); + + sch= CreateServiceW( + hSCManager, w_ServiceName, w_DisplayName, dwDesiredAccess, dwServiceType, + dwStartType, dwErrorControl, w_BinaryPathName, w_LoadOrderGroup, + lpdwTagId, w_Dependencies, w_ServiceStartName, w_Password); + if(!sch) + { + ok= FALSE; + last_error= GetLastError(); + } + +end: + free(w_ServiceName); + free(w_DisplayName); + free(w_BinaryPathName); + free(w_LoadOrderGroup); + free(w_Dependencies); + free(w_ServiceStartName); + free(w_Password); + + if (!ok) + SetLastError(last_error); + return sch; +} + +static inline BOOL my_ChangeServiceConfig(SC_HANDLE hService, DWORD dwServiceType, + DWORD dwStartType, DWORD dwErrorControl, + LPCSTR lpBinaryPathName, LPCSTR lpLoadOrderGroup, + LPDWORD lpdwTagId, LPCSTR lpDependencies, + LPCSTR lpServiceStartName, LPCSTR lpPassword, + LPCSTR lpDisplayName) +{ + wchar_t *w_DisplayName= NULL; + wchar_t *w_BinaryPathName= NULL; + wchar_t *w_LoadOrderGroup= NULL; + wchar_t *w_Dependencies= NULL; + wchar_t *w_ServiceStartName= NULL; + wchar_t *w_Password= NULL; + DWORD last_error=0; + BOOL ok= TRUE; + + AWSTRDUP(w_DisplayName, lpDisplayName); + AWSTRDUP(w_BinaryPathName, lpBinaryPathName); + AWSTRDUP(w_LoadOrderGroup, lpLoadOrderGroup); + AWSTRDUP(w_Dependencies, lpDependencies); + AWSTRDUP(w_ServiceStartName, lpServiceStartName); + AWSTRDUP(w_Password, lpPassword); + + ok= ChangeServiceConfigW( + hService, dwServiceType, dwStartType, dwErrorControl, w_BinaryPathName, + w_LoadOrderGroup, lpdwTagId, w_Dependencies, w_ServiceStartName, + w_Password, w_DisplayName); + if (!ok) + { + last_error= GetLastError(); + } + +end: + free(w_DisplayName); + free(w_BinaryPathName); + free(w_LoadOrderGroup); + free(w_Dependencies); + free(w_ServiceStartName); + free(w_Password); + + if (last_error) + SetLastError(last_error); + return ok; +} +#undef AWSTRDUP + +#undef OpenService +#define OpenService my_OpenService +#undef ChangeServiceConfig +#define ChangeServiceConfig my_ChangeServiceConfig +#undef CreateService +#define CreateService my_CreateService +#endif + #ifdef __cplusplus } #endif |