split long lines, use get_mysql_service_properties()
This commit is contained in:
parent
366ee3c791
commit
1b28a0883d
167
sql/winservice.c
Normal file
167
sql/winservice.c
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
Get Properties of an existing mysqld Windows service
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsvc.h>
|
||||||
|
#include "winservice.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get version from an executable file
|
||||||
|
*/
|
||||||
|
void get_file_version(const char *path, int *major, int *minor, int *patch)
|
||||||
|
{
|
||||||
|
DWORD version_handle;
|
||||||
|
char *ver= 0;
|
||||||
|
VS_FIXEDFILEINFO info;
|
||||||
|
UINT len;
|
||||||
|
DWORD size;
|
||||||
|
void *p;
|
||||||
|
*major= *minor= *patch= 0;
|
||||||
|
|
||||||
|
size= GetFileVersionInfoSize(path, &version_handle);
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
ver= (char *)malloc(size);
|
||||||
|
if(!GetFileVersionInfo(path, version_handle, size, ver))
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
if(!VerQueryValue(ver,"\\",&p,&len))
|
||||||
|
goto end;
|
||||||
|
memcpy(&info,p ,sizeof(VS_FIXEDFILEINFO));
|
||||||
|
|
||||||
|
*major= (info.dwFileVersionMS & 0xFFFF0000) >> 16;
|
||||||
|
*minor= (info.dwFileVersionMS & 0x0000FFFF);
|
||||||
|
*patch= (info.dwFileVersionLS & 0xFFFF0000) >> 16;
|
||||||
|
end:
|
||||||
|
free(ver);
|
||||||
|
}
|
||||||
|
|
||||||
|
void normalize_path(char *path, size_t size)
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
if (*path== '"')
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
strcpy_s(buf, MAX_PATH, path+1);
|
||||||
|
p= strchr(buf, '"');
|
||||||
|
if (p)
|
||||||
|
*p=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy_s(buf, MAX_PATH, path);
|
||||||
|
GetFullPathName(buf, MAX_PATH, buf, NULL);
|
||||||
|
strcpy_s(path, size, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Retrieve some properties from windows mysqld service binary path.
|
||||||
|
We're interested in ini file location and datadir, and also in version of
|
||||||
|
the data. We tolerate missing mysqld.exe.
|
||||||
|
|
||||||
|
Note that this function carefully avoids using mysql libraries (e.g dbug),
|
||||||
|
since it is used in unusual environments (windows installer, MFC), where we
|
||||||
|
do not have much control over how threads are created and destroyed, so we
|
||||||
|
cannot assume MySQL thread initilization here.
|
||||||
|
*/
|
||||||
|
int get_mysql_service_properties(const wchar_t *bin_path,
|
||||||
|
mysqld_service_properties *props)
|
||||||
|
{
|
||||||
|
int numargs;
|
||||||
|
wchar_t mysqld_path[MAX_PATH + 4];
|
||||||
|
wchar_t *file_part;
|
||||||
|
wchar_t **args= NULL;
|
||||||
|
int retval= 1;
|
||||||
|
|
||||||
|
props->datadir[0]= 0;
|
||||||
|
props->inifile[0]= 0;
|
||||||
|
props->mysqld_exe[0]= 0;
|
||||||
|
props->version_major= 0;
|
||||||
|
props->version_minor= 0;
|
||||||
|
props->version_patch= 0;
|
||||||
|
|
||||||
|
args= CommandLineToArgvW(bin_path, &numargs);
|
||||||
|
|
||||||
|
if(numargs != 3)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
if(wcsncmp(args[1], L"--defaults-file=", 16) != 0)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
GetFullPathNameW(args[0], MAX_PATH, mysqld_path, &file_part);
|
||||||
|
|
||||||
|
if(wcsstr(mysqld_path, L".exe") == NULL)
|
||||||
|
wcscat(mysqld_path, L".exe");
|
||||||
|
|
||||||
|
if(wcsicmp(file_part, L"mysqld.exe") != 0 &&
|
||||||
|
wcsicmp(file_part, L"mysqld.exe") != 0 &&
|
||||||
|
wcsicmp(file_part, L"mysqld-nt.exe") != 0)
|
||||||
|
{
|
||||||
|
/* The service executable is not mysqld. */
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
wcstombs(props->mysqld_exe, args[0], MAX_PATH);
|
||||||
|
wcstombs(props->inifile, args[1]+16, MAX_PATH);
|
||||||
|
normalize_path(props->inifile, MAX_PATH);
|
||||||
|
|
||||||
|
if (GetFileAttributes(props->inifile) == INVALID_FILE_ATTRIBUTES)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* If mysqld.exe exists, try to get its version from executable */
|
||||||
|
if (GetFileAttributes(props->mysqld_exe) != INVALID_FILE_ATTRIBUTES)
|
||||||
|
{
|
||||||
|
get_file_version(props->mysqld_exe, &props->version_major,
|
||||||
|
&props->version_minor, &props->version_patch);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetPrivateProfileString("mysqld", "datadir", NULL, props->datadir, MAX_PATH,
|
||||||
|
props->inifile);
|
||||||
|
|
||||||
|
if (props->datadir[0])
|
||||||
|
{
|
||||||
|
normalize_path(props->datadir, MAX_PATH);
|
||||||
|
/* Check if datadir really exists */
|
||||||
|
if (GetFileAttributes(props->datadir) == INVALID_FILE_ATTRIBUTES)
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* There is no datadir in ini file, bail out.*/
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
If version could not be determined so far, try mysql_upgrade_info in
|
||||||
|
database directory.
|
||||||
|
*/
|
||||||
|
if(props->version_major == 0)
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH];
|
||||||
|
FILE *mysql_upgrade_info;
|
||||||
|
|
||||||
|
sprintf_s(buf, MAX_PATH, "%s\\mysql_upgrade_info", props->datadir);
|
||||||
|
mysql_upgrade_info= fopen(buf, "r");
|
||||||
|
if(mysql_upgrade_info)
|
||||||
|
{
|
||||||
|
if (fgets(buf, MAX_PATH, mysql_upgrade_info))
|
||||||
|
{
|
||||||
|
int major,minor,patch;
|
||||||
|
if (sscanf(buf, "%d.%d.%d", &major, &minor, &patch) == 3)
|
||||||
|
{
|
||||||
|
props->version_major= major;
|
||||||
|
props->version_minor= minor;
|
||||||
|
props->version_patch= patch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
end:
|
||||||
|
LocalFree((HLOCAL)args);
|
||||||
|
return retval;
|
||||||
|
}
|
24
sql/winservice.h
Normal file
24
sql/winservice.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
Extract properties of a windows service binary path
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
typedef struct mysqld_service_properties_st
|
||||||
|
{
|
||||||
|
char mysqld_exe[MAX_PATH];
|
||||||
|
char inifile[MAX_PATH];
|
||||||
|
char datadir[MAX_PATH];
|
||||||
|
int version_major;
|
||||||
|
int version_minor;
|
||||||
|
int version_patch;
|
||||||
|
} mysqld_service_properties;
|
||||||
|
|
||||||
|
extern int get_mysql_service_properties(const wchar_t *bin_path,
|
||||||
|
mysqld_service_properties *props);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
0
win/cmake/dummy.in
Normal file
0
win/cmake/dummy.in
Normal file
@ -70,8 +70,12 @@ LExit:
|
|||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for if directory is empty during install, sets "<PROPERTY>_NOT_EMPTY" otherise */
|
/*
|
||||||
extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall, const wchar_t *PropertyName)
|
Check for if directory is empty during install,
|
||||||
|
sets "<PROPERTY>_NOT_EMPTY" otherise
|
||||||
|
*/
|
||||||
|
extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall,
|
||||||
|
const wchar_t *PropertyName)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
UINT er = ERROR_SUCCESS;
|
UINT er = ERROR_SUCCESS;
|
||||||
@ -112,7 +116,8 @@ extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall, const wchar_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(empty)
|
if(empty)
|
||||||
WcaLog(LOGMSG_STANDARD, "Directory %S is empty or non-existent", PropertyName);
|
WcaLog(LOGMSG_STANDARD, "Directory %S is empty or non-existent",
|
||||||
|
PropertyName);
|
||||||
else
|
else
|
||||||
WcaLog(LOGMSG_STANDARD, "Directory %S is NOT empty", PropertyName);
|
WcaLog(LOGMSG_STANDARD, "Directory %S is NOT empty", PropertyName);
|
||||||
|
|
||||||
@ -225,22 +230,22 @@ wchar_t *strip_quotes(wchar_t *s)
|
|||||||
|
|
||||||
It can happen that SERVICENAME or DATADIR
|
It can happen that SERVICENAME or DATADIR
|
||||||
MSI properties are in inconsistent state after somebody upgraded database
|
MSI properties are in inconsistent state after somebody upgraded database
|
||||||
We catch this case during uninstall. In particular, either service is not removed
|
We catch this case during uninstall. In particular, either service is not
|
||||||
even if SERVICENAME was set (but this name is reused by someone else) or data
|
removed even if SERVICENAME was set (but this name is reused by someone else)
|
||||||
directory is not removed (if it is used by someone else). To find out whether
|
or data directory is not removed (if it is used by someone else). To find out
|
||||||
service name and datadirectory are in use For every service, configuration is
|
whether service name and datadirectory are in use For every service,
|
||||||
read and checked as follows:
|
configuration is read and checked as follows:
|
||||||
|
|
||||||
- look if a service has to do something with mysql
|
- look if a service has to do something with mysql
|
||||||
- If so, check its name against SERVICENAME. if match, check binary path against
|
- If so, check its name against SERVICENAME. if match, check binary path
|
||||||
INSTALLDIR\bin. If binary path does not match, then service runs under different
|
against INSTALLDIR\bin. If binary path does not match, then service runs
|
||||||
installation and won't be removed.
|
under different installation and won't be removed.
|
||||||
- Check options file for datadir and look if this is inside this installation's
|
- Check options file for datadir and look if this is inside this
|
||||||
datadir don't remove datadir if this is the case.
|
installation's datadir don't remove datadir if this is the case.
|
||||||
|
|
||||||
"Don't remove" in this context means that custom action is removing SERVICENAME property
|
"Don't remove" in this context means that custom action is removing
|
||||||
or CLEANUPDATA property, which later on in course of installation mean that either datadir
|
SERVICENAME property or CLEANUPDATA property, which later on in course of
|
||||||
or service is retained.
|
installation mean, that either datadir or service is kept.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void CheckServiceConfig(
|
void CheckServiceConfig(
|
||||||
@ -262,7 +267,8 @@ void CheckServiceConfig(
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
WcaLog(LOGMSG_STANDARD, "MySQL service %S found: CommandLine= %S", other_servicename, commandline);
|
WcaLog(LOGMSG_STANDARD, "MySQL service %S found: CommandLine= %S",
|
||||||
|
other_servicename, commandline);
|
||||||
if (wcsstr(argv[0], bindir))
|
if (wcsstr(argv[0], bindir))
|
||||||
{
|
{
|
||||||
WcaLog(LOGMSG_STANDARD, "executable under bin directory");
|
WcaLog(LOGMSG_STANDARD, "executable under bin directory");
|
||||||
@ -281,7 +287,8 @@ void CheckServiceConfig(
|
|||||||
else if (!same_bindir)
|
else if (!same_bindir)
|
||||||
{
|
{
|
||||||
WcaLog(LOGMSG_STANDARD,
|
WcaLog(LOGMSG_STANDARD,
|
||||||
"Service name matches, but not the executable path directory, mine is %S", bindir);
|
"Service name matches, but not the executable path directory, mine is %S",
|
||||||
|
bindir);
|
||||||
WcaSetProperty(L"SERVICENAME", L"");
|
WcaSetProperty(L"SERVICENAME", L"");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,8 +306,8 @@ void CheckServiceConfig(
|
|||||||
|
|
||||||
WcaLog(LOGMSG_STANDARD, "parsed defaults file is %S", defaults_file);
|
WcaLog(LOGMSG_STANDARD, "parsed defaults file is %S", defaults_file);
|
||||||
|
|
||||||
if (GetPrivateProfileStringW(L"mysqld", L"datadir", NULL, current_datadir, MAX_PATH,
|
if (GetPrivateProfileStringW(L"mysqld", L"datadir", NULL, current_datadir,
|
||||||
defaults_file) == 0)
|
MAX_PATH, defaults_file) == 0)
|
||||||
{
|
{
|
||||||
WcaLog(LOGMSG_STANDARD,
|
WcaLog(LOGMSG_STANDARD,
|
||||||
"Cannot find datadir in ini file '%S'", defaults_file);
|
"Cannot find datadir in ini file '%S'", defaults_file);
|
||||||
@ -311,16 +318,19 @@ void CheckServiceConfig(
|
|||||||
strip_quotes(current_datadir);
|
strip_quotes(current_datadir);
|
||||||
|
|
||||||
/* Convert to Windows path */
|
/* Convert to Windows path */
|
||||||
if (GetFullPathNameW(current_datadir, MAX_PATH, normalized_current_datadir, NULL))
|
if (GetFullPathNameW(current_datadir, MAX_PATH, normalized_current_datadir,
|
||||||
|
NULL))
|
||||||
{
|
{
|
||||||
/* Add backslash to be compatible with directory formats in MSI */
|
/* Add backslash to be compatible with directory formats in MSI */
|
||||||
wcsncat(normalized_current_datadir, L"\\", MAX_PATH+1);
|
wcsncat(normalized_current_datadir, L"\\", MAX_PATH+1);
|
||||||
WcaLog(LOGMSG_STANDARD, "normalized current datadir is '%S'", normalized_current_datadir);
|
WcaLog(LOGMSG_STANDARD, "normalized current datadir is '%S'",
|
||||||
|
normalized_current_datadir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_wcsicmp(datadir, normalized_current_datadir) == 0 && !same_bindir)
|
if (_wcsicmp(datadir, normalized_current_datadir) == 0 && !same_bindir)
|
||||||
{
|
{
|
||||||
WcaLog(LOGMSG_STANDARD, "database directory from current installation, but different mysqld.exe");
|
WcaLog(LOGMSG_STANDARD,
|
||||||
|
"database directory from current installation, but different mysqld.exe");
|
||||||
WcaSetProperty(L"CLEANUPDATA", L"");
|
WcaSetProperty(L"CLEANUPDATA", L"");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,22 +345,22 @@ end:
|
|||||||
would normally mean user has done an upgrade of the database and in this case
|
would normally mean user has done an upgrade of the database and in this case
|
||||||
uninstall should neither delete service nor database directory.
|
uninstall should neither delete service nor database directory.
|
||||||
|
|
||||||
If this function find that service is modified by user (mysqld.exe used by service
|
If this function find that service is modified by user (mysqld.exe used by
|
||||||
does not point to the installation bin directory), MSI public variable SERVICENAME is
|
service does not point to the installation bin directory), MSI public variable
|
||||||
removed, if DATADIR is used by some other service, variables DATADIR and CLEANUPDATA
|
SERVICENAME is removed, if DATADIR is used by some other service, variables
|
||||||
are removed.
|
DATADIR and CLEANUPDATA are removed.
|
||||||
|
|
||||||
The effect of variable removal is that service does not get uninstalled and datadir
|
The effect of variable removal is that service does not get uninstalled and
|
||||||
is not touched by uninstallation.
|
datadir is not touched by uninstallation.
|
||||||
|
|
||||||
Note that this function is running without elevation and does not use anything that would
|
Note that this function is running without elevation and does not use anything
|
||||||
require special privileges.
|
that would require special privileges.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
extern "C" UINT CheckDBInUse(MSIHANDLE hInstall)
|
extern "C" UINT CheckDBInUse(MSIHANDLE hInstall)
|
||||||
{
|
{
|
||||||
static BYTE buf[256*1024]; /* largest possible buffer for EnumServices */
|
static BYTE buf[256*1024]; /* largest possible buffer for EnumServices */
|
||||||
static char config_buffer[8*1024]; /*largest possible buffer for QueryServiceConfig */
|
static char config_buffer[8*1024]; /*largest buffer for QueryServiceConfig */
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
UINT er = ERROR_SUCCESS;
|
UINT er = ERROR_SUCCESS;
|
||||||
wchar_t *servicename= NULL;
|
wchar_t *servicename= NULL;
|
||||||
@ -373,7 +383,8 @@ extern "C" UINT CheckDBInUse(MSIHANDLE hInstall)
|
|||||||
WcaLog(LOGMSG_STANDARD,"SERVICENAME=%S, DATADIR=%S, bindir=%S",
|
WcaLog(LOGMSG_STANDARD,"SERVICENAME=%S, DATADIR=%S, bindir=%S",
|
||||||
servicename, datadir, bindir);
|
servicename, datadir, bindir);
|
||||||
|
|
||||||
scm = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
|
scm = OpenSCManager(NULL, NULL,
|
||||||
|
SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
|
||||||
if (scm == NULL)
|
if (scm == NULL)
|
||||||
{
|
{
|
||||||
ExitOnFailure(E_FAIL, "OpenSCManager failed");
|
ExitOnFailure(E_FAIL, "OpenSCManager failed");
|
||||||
@ -397,17 +408,21 @@ extern "C" UINT CheckDBInUse(MSIHANDLE hInstall)
|
|||||||
info = (LPENUM_SERVICE_STATUS_PROCESS)buf;
|
info = (LPENUM_SERVICE_STATUS_PROCESS)buf;
|
||||||
for (ULONG i=0; i < num_services; i++)
|
for (ULONG i=0; i < num_services; i++)
|
||||||
{
|
{
|
||||||
SC_HANDLE service= OpenServiceW(scm, info[i].lpServiceName, SERVICE_QUERY_CONFIG);
|
SC_HANDLE service= OpenServiceW(scm, info[i].lpServiceName,
|
||||||
|
SERVICE_QUERY_CONFIG);
|
||||||
if (!service)
|
if (!service)
|
||||||
continue;
|
continue;
|
||||||
WcaLog(LOGMSG_VERBOSE, "Checking Service %S", info[i].lpServiceName);
|
WcaLog(LOGMSG_VERBOSE, "Checking Service %S", info[i].lpServiceName);
|
||||||
QUERY_SERVICE_CONFIGW *config= (QUERY_SERVICE_CONFIGW *)(void *)config_buffer;
|
QUERY_SERVICE_CONFIGW *config=
|
||||||
|
(QUERY_SERVICE_CONFIGW *)(void *)config_buffer;
|
||||||
DWORD needed;
|
DWORD needed;
|
||||||
BOOL ok= QueryServiceConfigW(service, config,sizeof(config_buffer), &needed);
|
BOOL ok= QueryServiceConfigW(service, config,sizeof(config_buffer),
|
||||||
|
&needed);
|
||||||
CloseServiceHandle(service);
|
CloseServiceHandle(service);
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
CheckServiceConfig(servicename, datadir, bindir, info[i].lpServiceName, config);
|
CheckServiceConfig(servicename, datadir, bindir, info[i].lpServiceName,
|
||||||
|
config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,14 +469,17 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
|
|||||||
}
|
}
|
||||||
if(CheckServiceExists(ServiceName))
|
if(CheckServiceExists(ServiceName))
|
||||||
{
|
{
|
||||||
ErrorMsg= L"A service with the same name already exists. Please use a different name.";
|
ErrorMsg=
|
||||||
|
L"A service with the same name already exists. "
|
||||||
|
L"Please use a different name.";
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD SkipNetworkingLen= MAX_PATH;
|
DWORD SkipNetworkingLen= MAX_PATH;
|
||||||
|
|
||||||
MsiGetPropertyW(hInstall, L"SKIPNETWORKING", SkipNetworking, &SkipNetworkingLen);
|
MsiGetPropertyW(hInstall, L"SKIPNETWORKING", SkipNetworking,
|
||||||
|
&SkipNetworkingLen);
|
||||||
MsiGetPropertyW(hInstall, L"PORT", Port, &PortLen);
|
MsiGetPropertyW(hInstall, L"PORT", Port, &PortLen);
|
||||||
|
|
||||||
if(SkipNetworking[0]==0 && Port[0] != 0)
|
if(SkipNetworking[0]==0 && Port[0] != 0)
|
||||||
@ -488,14 +506,17 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
|
|||||||
}
|
}
|
||||||
if (haveInvalidPort)
|
if (haveInvalidPort)
|
||||||
{
|
{
|
||||||
ErrorMsg = L"Invalid port number. Please use a number between 1025 and 65535.";
|
ErrorMsg =
|
||||||
|
L"Invalid port number. Please use a number between 1025 and 65535.";
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
short port = (short)_wtoi(Port);
|
short port = (short)_wtoi(Port);
|
||||||
if (!IsPortFree(port))
|
if (!IsPortFree(port))
|
||||||
{
|
{
|
||||||
ErrorMsg = L"The TCP Port you selected is already in use. Please choose a different port.";
|
ErrorMsg =
|
||||||
|
L"The TCP Port you selected is already in use. "
|
||||||
|
L"Please choose a different port.";
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -550,7 +571,8 @@ LExit:
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Enables/disables optional "Launch upgrade wizard" checkbox at the end of installation
|
Enables/disables optional "Launch upgrade wizard" checkbox at the end of
|
||||||
|
installation
|
||||||
*/
|
*/
|
||||||
#define MAX_VERSION_PROPERTY_SIZE 64
|
#define MAX_VERSION_PROPERTY_SIZE 64
|
||||||
|
|
||||||
@ -589,7 +611,8 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
|
SC_HANDLE scm = OpenSCManager(NULL, NULL,
|
||||||
|
SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
|
||||||
if (scm == NULL)
|
if (scm == NULL)
|
||||||
{
|
{
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
@ -621,31 +644,30 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
|
|||||||
QUERY_SERVICE_CONFIGW *config=
|
QUERY_SERVICE_CONFIGW *config=
|
||||||
(QUERY_SERVICE_CONFIGW*)(void *)config_buffer;
|
(QUERY_SERVICE_CONFIGW*)(void *)config_buffer;
|
||||||
DWORD needed;
|
DWORD needed;
|
||||||
BOOL ok= QueryServiceConfigW(service, config,sizeof(config_buffer), &needed);
|
BOOL ok= QueryServiceConfigW(service, config,sizeof(config_buffer),
|
||||||
|
&needed);
|
||||||
CloseServiceHandle(service);
|
CloseServiceHandle(service);
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
bool isMySQL;
|
mysqld_service_properties props;
|
||||||
int major;
|
if (get_mysql_service_properties(config->lpBinaryPathName, &props))
|
||||||
int minor;
|
continue;
|
||||||
wchar_t program[MAX_PATH]={0};
|
/*
|
||||||
GetMySQLVersion(config->lpBinaryPathName, program, &isMySQL, &major, &minor);
|
Only look for services that have mysqld.exe outside of the current
|
||||||
|
installation directory.
|
||||||
/*
|
*/
|
||||||
Only look for services that have mysqld.exe outside of the current
|
if(strstr(props.mysqld_exe,installDir) == 0)
|
||||||
installation directory.
|
|
||||||
*/
|
|
||||||
if(isMySQL && (wcsstr(program,installDir) == 0))
|
|
||||||
{
|
|
||||||
WcaLog(LOGMSG_STANDARD, "found service %S, major=%d, minor=%d",
|
|
||||||
info[i].lpServiceName, major, minor);
|
|
||||||
if(major < installerMajorVersion
|
|
||||||
|| (major == installerMajorVersion && minor <= installerMinorVersion))
|
|
||||||
{
|
{
|
||||||
upgradableServiceFound= true;
|
WcaLog(LOGMSG_STANDARD, "found service %S, major=%d, minor=%d",
|
||||||
break;
|
info[i].lpServiceName, props.version_major, props.version_minor);
|
||||||
}
|
if(props.version_major < installerMajorVersion
|
||||||
}
|
|| (props.version_major == installerMajorVersion &&
|
||||||
|
props.version_minor <= installerMinorVersion))
|
||||||
|
{
|
||||||
|
upgradableServiceFound= true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user