summaryrefslogtreecommitdiff
path: root/win
diff options
context:
space:
mode:
Diffstat (limited to 'win')
-rw-r--r--win/packaging/CMakeLists.txt75
-rw-r--r--win/packaging/CPackWixConfig.cmake2
-rw-r--r--win/packaging/ca/CMakeLists.txt22
-rw-r--r--win/packaging/ca/CustomAction.cpp473
-rw-r--r--win/packaging/ca/CustomAction.def3
-rw-r--r--win/packaging/ca/symlinks.cc.in6
-rw-r--r--win/packaging/ca/symlinks.h8
-rw-r--r--win/packaging/create_msi.cmake12
-rw-r--r--win/packaging/extra.wxs.in36
-rw-r--r--win/packaging/mysql_server.wxs.in2
-rw-r--r--win/upgrade_wizard/CMakeLists.txt18
11 files changed, 503 insertions, 154 deletions
diff --git a/win/packaging/CMakeLists.txt b/win/packaging/CMakeLists.txt
index 0b46ea19a27..af4283d9f07 100644
--- a/win/packaging/CMakeLists.txt
+++ b/win/packaging/CMakeLists.txt
@@ -21,8 +21,6 @@ IF(MSVC_VERSION LESS 1600)
RETURN()
ENDIF()
-
-
SET(MANUFACTURER "MariaDB Corporation Ab")
SET(WIX_BIN_PATHS)
FOREACH(WIX_VER 3.9 3.10 3.11)
@@ -178,6 +176,43 @@ IF(CMAKE_GENERATOR MATCHES "Visual Studio")
SET(CONFIG_PARAM "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_CFG_INTDIR}")
ENDIF()
+IF(MSVC_CRT_TYPE MATCHES "/MD")
+ # Find out CRT merge module path, we're going to use it in installer
+ # The path and name depends on VS version
+ IF(MSVC_VERSION LESS 1900)
+ # VS2015
+ SET(VCREDIST_MSM_FILENAME Microsoft_VC140_CRT_${WIX_ARCH_SUFFIX}.msm)
+ SET(ProgramFilesX86 "ProgramFiles(x86)")
+ FIND_FILE(${VCREDIST_MSM_FILENAME}
+ NO_DEFAULT_PATH
+ PATHS
+ "$ENV{${ProgramFilesX86}}/Common Files/Merge Modules"
+ "$ENV{ProgramFiles}/Common Files/Merge Modules"
+ )
+ ELSEIF(MSVC_VERSION LESS 1920)
+ # VS2017
+ SET(VCREDIST_MSM_FILENAME Microsoft_VC141_CRT_${WIX_ARCH_SUFFIX}.msm)
+ FILE(GLOB MSM_LIST "C:/Program Files*/Microsoft Visual Studio/2017/*/VC/Redist/MSVC/*/MergeModules/${VCREDIST_MSM_FILENAME}")
+ LIST(LENGTH MSM_LIST LEN)
+ IF(LEN GREATER 0)
+ LIST(GET MSM_LIST 0 VCRedist_MSM)
+ ENDIF()
+ ELSE()
+ # VS2019
+ SET(VCREDIST_MSM_FILENAME Microsoft_VC142_CRT_${WIX_ARCH_SUFFIX}.msm)
+ FILE(GLOB MSM_LIST "C:/Program Files*/Microsoft Visual Studio/2019/*/VC/Redist/MSVC/*/MergeModules/${VCREDIST_MSM_FILENAME}")
+ LIST(LENGTH MSM_LIST LEN)
+ IF(LEN GREATER 0)
+ LIST(GET MSM_LIST 0 VCRedist_MSM)
+ ENDIF()
+ ENDIF()
+ IF (NOT VCRedist_MSM)
+ MESSAGE(WARNING "Can't find merge module ${VCREDIST_MSM_FILENAME}")
+ ELSE()
+ FILE(TO_NATIVE_PATH ${VCRedist_MSM} VCRedist_MSM)
+ # MESSAGE("VCRedist_MSM=${VCRedist_MSM}")
+ ENDIF()
+ENDIF()
ADD_CUSTOM_TARGET(
MSI
@@ -209,44 +244,12 @@ ADD_CUSTOM_TARGET(
-DVERSION="${VERSION}"
-DWITH_THIRD_PARTY="${WITH_THIRD_PARTY}"
-DWIXCA_LOCATION="$<TARGET_FILE:wixca>"
+ -DMSVC_CRT_TYPE="${MSVC_CRT_TYPE}"
+ -DVCRedist_MSM="${VCRedist_MSM}"
-P ${CMAKE_CURRENT_SOURCE_DIR}/create_msi.cmake
)
ADD_DEPENDENCIES(MSI wixca)
-ADD_CUSTOM_TARGET(
- MSI_ESSENTIALS
- COMMAND ${CMAKE_COMMAND} ${CONFIG_PARAM} -DESSENTIALS=1
- -DCANDLE_EXECUTABLE="${CANDLE_EXECUTABLE}"
- -DCMAKE_CFG_INTDIR="${CMAKE_CFG_INTDIR}"
- -DCMAKE_FULL_VER="${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}"
- -DCMAKE_SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P}
- -DCOPYING_RTF="${COPYING_RTF}"
- -DCPACK_WIX_CONFIG="${CPACK_WIX_CONFIG}"
- -DCPACK_WIX_INCLUDE="${CPACK_WIX_INCLUDE}"
- -DCPACK_WIX_PACKAGE_BASE_NAME="${CPACK_WIX_PACKAGE_BASE_NAME}"
- -DCPACK_WIX_PACKAGE_NAME="${CPACK_WIX_PACKAGE_NAME}"
- -DCPACK_WIX_UPGRADE_CODE="${CPACK_WIX_UPGRADE_CODE}"
- -DEXTRA_WIX_PREPROCESSOR_FLAGS="${EXTRA_WIX_PREPROCESSOR_FLAGS}"
- -DLIGHT_EXECUTABLE="${LIGHT_EXECUTABLE}"
- -DMAJOR_VERSION="${MAJOR_VERSION}"
- -DMANUFACTURER="${MANUFACTURER}"
- -DMINOR_VERSION="${MINOR_VERSION}"
- -DPATCH_VERSION="${PATCH_VERSION}"
- -DSIGNCODE="${SIGNCODE}"
- -DSIGNTOOL_EXECUTABLE="${SIGNTOOL_EXECUTABLE}"
- -DSIGNTOOL_PARAMETERS="${SIGNTOOL_PARAMETERS}"
- -DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}"
- -DTHIRD_PARTY_DOWNLOAD_LOCATION="${THIRD_PARTY_DOWNLOAD_LOCATION}"
- -DTHIRD_PARTY_FEATURE_CONDITION="${THIRD_PARTY_FEATURE_CONDITION}"
- -DTINY_VERSION="${TINY_VERSION}"
- -DTOP_BINDIR="${CMAKE_BINARY_DIR}"
- -DVERSION="${VERSION}"
- -DWITH_THIRD_PARTY="${WITH_THIRD_PARTY}"
- -DWIXCA_LOCATION="$<TARGET_FILE:wixca>"
- -P ${CMAKE_CURRENT_SOURCE_DIR}/create_msi.cmake
-)
-ADD_DEPENDENCIES(MSI_ESSENTIALS wixca)
-
IF(CMAKE_GENERATOR MATCHES "Visual Studio")
SET(CPACK_CONFIG_PARAM -C $(Configuration))
diff --git a/win/packaging/CPackWixConfig.cmake b/win/packaging/CPackWixConfig.cmake
index 994b121797a..74329e79247 100644
--- a/win/packaging/CPackWixConfig.cmake
+++ b/win/packaging/CPackWixConfig.cmake
@@ -9,7 +9,7 @@ IF(ESSENTIALS)
ENDIF()
ELSE()
SET(CPACK_COMPONENTS_USED
- "Server;Client;Development;SharedLibraries;Documentation;Readme;Common;VCCRT;connect-engine;ClientPlugins;gssapi-server;gssapi-client;aws-key-management;rocksdb-engine;backup")
+ "Server;Client;Development;SharedLibraries;Documentation;Readme;Common;connect-engine;ClientPlugins;gssapi-server;gssapi-client;aws-key-management;rocksdb-engine;backup")
ENDIF()
SET( WIX_FEATURE_MySQLServer_EXTRA_FEATURES "DBInstance;SharedClientServerComponents")
diff --git a/win/packaging/ca/CMakeLists.txt b/win/packaging/ca/CMakeLists.txt
index 1a24ee9a082..99dc7da01fb 100644
--- a/win/packaging/ca/CMakeLists.txt
+++ b/win/packaging/ca/CMakeLists.txt
@@ -14,11 +14,23 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
INCLUDE_DIRECTORIES(${WIX_DIR}/../SDK/${WIX_MSVC_SUFFIX}/inc)
-SET(WIXCA_SOURCES CustomAction.cpp CustomAction.def)
+SET(WIXCA_SOURCES CustomAction.cpp CustomAction.def ${CMAKE_CURRENT_BINARY_DIR}/symlinks.cc)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql ${CMAKE_CURRENT_SOURCE_DIR})
+INCLUDE(symlinks)
+LIST(LENGTH MARIADB_SYMLINK_FROMS LEN)
+MATH(EXPR max_index "${LEN}-1")
+SET(ALL_SYMLINKS "")
+FOREACH(i RANGE 0 ${max_index})
+ LIST(GET MARIADB_SYMLINK_FROMS ${i} src)
+ LIST(GET MARIADB_SYMLINK_TOS ${i} dst)
+ STRING(APPEND ALL_SYMLINKS "{L\"${src}\",L\"${dst}\"},\n")
+ENDFOREACH()
+CONFIGURE_FILE(symlinks.cc.in symlinks.cc)
+
+# Custom action should not depend on C runtime, since we do not know if CRT is installed.
+FORCE_STATIC_CRT()
ADD_VERSION_INFO(wixca SHARED WIXCA_SOURCES)
-ADD_LIBRARY(wixca SHARED EXCLUDE_FROM_ALL ${WIXCA_SOURCES})
-TARGET_LINK_LIBRARIES(wixca ${WIX_WCAUTIL_LIBRARY} ${WIX_DUTIL_LIBRARY}
- msi version winservice)
+ADD_LIBRARY(wixca SHARED EXCLUDE_FROM_ALL ${WIXCA_SOURCES} ${CMAKE_SOURCE_DIR}/sql/winservice.c)
+TARGET_LINK_LIBRARIES(wixca ${WIX_WCAUTIL_LIBRARY} ${WIX_DUTIL_LIBRARY} msi version)
diff --git a/win/packaging/ca/CustomAction.cpp b/win/packaging/ca/CustomAction.cpp
index b9d938f4443..5acbca1e186 100644
--- a/win/packaging/ca/CustomAction.cpp
+++ b/win/packaging/ca/CustomAction.cpp
@@ -33,6 +33,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
#include <shellapi.h>
#include <stdlib.h>
#include <winservice.h>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <vector>
+#include <map>
+
+using namespace std;
#define ONE_MB 1048576
@@ -58,7 +66,7 @@ UINT ExecRemoveDataDirectory(wchar_t *dir)
}
-extern "C" UINT __stdcall RemoveDataDirectory(MSIHANDLE hInstall)
+extern "C" UINT __stdcall RemoveDataDirectory(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
@@ -74,13 +82,13 @@ extern "C" UINT __stdcall RemoveDataDirectory(MSIHANDLE hInstall)
er= ExecRemoveDataDirectory(dir);
WcaLog(LOGMSG_STANDARD, "SHFileOperation returned %d", er);
LExit:
- return WcaFinalize(er);
+ return WcaFinalize(er);
}
/*
Escape command line parameter fpr pass to CreateProcess().
- We assume out has enough space to include encoded string
+ We assume out has enough space to include encoded string
2*wcslen(in) is enough.
It is assumed that called will add double quotation marks before and after
@@ -108,21 +116,21 @@ static void EscapeCommandLine(const wchar_t *in, wchar_t *out, size_t buflen)
}
pos= 0;
- for(int i = 0 ; ; i++)
+ for(int i = 0 ; ; i++)
{
size_t n_backslashes = 0;
wchar_t c;
- while (in[i] == L'\\')
+ while (in[i] == L'\\')
{
i++;
n_backslashes++;
}
c= in[i];
- if (c == 0)
+ if (c == 0)
{
/*
- Escape all backslashes, but let the terminating double quotation mark
+ Escape all backslashes, but let the terminating double quotation mark
that caller adds be interpreted as a metacharacter.
*/
for(size_t j= 0; j < 2*n_backslashes;j++)
@@ -131,7 +139,7 @@ static void EscapeCommandLine(const wchar_t *in, wchar_t *out, size_t buflen)
}
break;
}
- else if (c == L'"')
+ else if (c == L'"')
{
/*
Escape all backslashes and the following double quotation mark.
@@ -142,7 +150,7 @@ static void EscapeCommandLine(const wchar_t *in, wchar_t *out, size_t buflen)
}
out[pos++]= L'"';
}
- else
+ else
{
/* Backslashes aren't special here. */
for (size_t j=0; j < n_backslashes; j++)
@@ -153,11 +161,11 @@ static void EscapeCommandLine(const wchar_t *in, wchar_t *out, size_t buflen)
}
out[pos++]= 0;
}
-/*
- Check for if directory is empty during install,
+/*
+ Check for if directory is empty during install,
sets "<PROPERTY>_NOT_EMPTY" otherise
*/
-extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall,
+extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall,
const wchar_t *PropertyName)
{
HRESULT hr = S_OK;
@@ -167,14 +175,14 @@ extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall,
WIN32_FIND_DATAW data;
HANDLE h;
bool empty;
-
+
hr = WcaInitialize(hInstall, __FUNCTION__);
ExitOnFailure(hr, "Failed to initialize");
WcaLog(LOGMSG_STANDARD, "Initialized.");
MsiGetPropertyW(hInstall, PropertyName, buf, &len);
wcscat_s(buf, MAX_PATH, L"*.*");
-
+
WcaLog(LOGMSG_STANDARD, "Checking files in %S", buf);
h= FindFirstFile(buf, &data);
@@ -200,7 +208,7 @@ extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall,
}
if(empty)
- WcaLog(LOGMSG_STANDARD, "Directory %S is empty or non-existent",
+ WcaLog(LOGMSG_STANDARD, "Directory %S is empty or non-existent",
PropertyName);
else
WcaLog(LOGMSG_STANDARD, "Directory %S is NOT empty", PropertyName);
@@ -210,7 +218,7 @@ extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall,
WcaSetProperty(buf, empty? L"":L"1");
LExit:
- return WcaFinalize(er);
+ return WcaFinalize(er);
}
extern "C" UINT __stdcall CheckDataDirectoryEmpty(MSIHANDLE hInstall)
@@ -222,12 +230,12 @@ bool CheckServiceExists(const wchar_t *name)
{
SC_HANDLE manager =0, service=0;
manager = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT);
- if (!manager)
+ if (!manager)
{
return false;
}
- service = OpenService(manager, name, SC_MANAGER_CONNECT);
+ service = OpenService(manager, name, SC_MANAGER_CONNECT);
if(service)
CloseServiceHandle(service);
CloseServiceHandle(manager);
@@ -241,11 +249,11 @@ bool ExecRemoveService(const wchar_t *name)
SC_HANDLE manager =0, service=0;
manager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
bool ret;
- if (!manager)
+ if (!manager)
{
return false;
}
- service = OpenService(manager, name, DELETE);
+ service = OpenService(manager, name, DELETE);
if(service)
{
ret= DeleteService(service);
@@ -344,7 +352,7 @@ bool IsPortFree(unsigned short port)
}
-/*
+/*
Helper function used in filename normalization.
Removes leading quote and terminates string at the position of the next one
(if applicable, does not change string otherwise). Returns modified string
@@ -365,23 +373,23 @@ wchar_t *strip_quotes(wchar_t *s)
/*
Checks for consistency of service configuration.
- It can happen that SERVICENAME or DATADIR
- MSI properties are in inconsistent state after somebody upgraded database
- We catch this case during uninstall. In particular, either service is not
+ It can happen that SERVICENAME or DATADIR
+ MSI properties are in inconsistent state after somebody upgraded database
+ We catch this case during uninstall. In particular, either service is not
removed even if SERVICENAME was set (but this name is reused by someone else)
or data directory is not removed (if it is used by someone else). To find out
- whether service name and datadirectory are in use For every service,
+ whether service name and datadirectory are in use For every service,
configuration is read and checked as follows:
- look if a service has to do something with mysql
- - If so, check its name against SERVICENAME. if match, check binary path
+ - If so, check its name against SERVICENAME. if match, check binary path
against INSTALLDIR\bin. If binary path does not match, then service runs
under different installation and won't be removed.
- Check options file for datadir and look if this is inside this
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 or CLEANUPDATA property, which later on in course of
+ "Don't remove" in this context means that custom action is removing
+ SERVICENAME property or CLEANUPDATA property, which later on in course of
installation mean, that either datadir or service is kept.
*/
@@ -410,7 +418,7 @@ void CheckServiceConfig(
goto end;
}
- WcaLog(LOGMSG_STANDARD, "MySQL service %S found: CommandLine= %S",
+ WcaLog(LOGMSG_STANDARD, "MySQL/MariaDB service %S found: CommandLine= %S",
other_servicename, commandline);
if (wcsstr(argv[0], bindir))
{
@@ -422,15 +430,15 @@ void CheckServiceConfig(
if(!is_my_service)
{
WcaLog(LOGMSG_STANDARD, "service does not match current service");
- /*
+ /*
TODO probably the best thing possible would be to add temporary
row to MSI ServiceConfig table with remove on uninstall
*/
}
else if (!same_bindir)
{
- WcaLog(LOGMSG_STANDARD,
- "Service name matches, but not the executable path directory, mine is %S",
+ WcaLog(LOGMSG_STANDARD,
+ "Service name matches, but not the executable path directory, mine is %S",
bindir);
WcaSetProperty(L"SERVICENAME", L"");
}
@@ -447,10 +455,10 @@ void CheckServiceConfig(
WcaLog(LOGMSG_STANDARD, "parsed defaults file is %S", defaults_file);
- if (GetPrivateProfileStringW(L"mysqld", L"datadir", NULL, current_datadir,
+ if (GetPrivateProfileStringW(L"mysqld", L"datadir", NULL, current_datadir,
MAX_PATH, defaults_file) == 0)
{
- WcaLog(LOGMSG_STANDARD,
+ WcaLog(LOGMSG_STANDARD,
"Cannot find datadir in ini file '%S'", defaults_file);
goto end;
}
@@ -459,18 +467,18 @@ void CheckServiceConfig(
strip_quotes(current_datadir);
/* Convert to Windows path */
- if (GetFullPathNameW(current_datadir, MAX_PATH, normalized_current_datadir,
+ if (GetFullPathNameW(current_datadir, MAX_PATH, normalized_current_datadir,
NULL))
{
/* Add backslash to be compatible with directory formats in MSI */
wcsncat(normalized_current_datadir, L"\\", MAX_PATH+1);
- WcaLog(LOGMSG_STANDARD, "normalized current datadir is '%S'",
+ WcaLog(LOGMSG_STANDARD, "normalized current datadir is '%S'",
normalized_current_datadir);
}
if (_wcsicmp(datadir, normalized_current_datadir) == 0 && !same_bindir)
{
- WcaLog(LOGMSG_STANDARD,
+ WcaLog(LOGMSG_STANDARD,
"database directory from current installation, but different mysqld.exe");
WcaSetProperty(L"CLEANUPDATA", L"");
}
@@ -482,13 +490,13 @@ end:
/*
Checks if database directory or service are modified by user
For example, service may point to different mysqld.exe that it was originally
- installed, or some different service might use this database directory. This
- would normally mean user has done an upgrade of the database and in this case
+ installed, or some different service might use this database directory. This
+ would normally mean user has done an upgrade of the database and in this case
uninstall should neither delete service nor database directory.
- If this function find that service is modified by user (mysqld.exe used by
+ If this function find that service is modified by user (mysqld.exe used by
service does not point to the installation bin directory), MSI public variable
- SERVICENAME is removed, if DATADIR is used by some other service, variables
+ SERVICENAME is removed, if DATADIR is used by some other service, variables
DATADIR and CLEANUPDATA are removed.
The effect of variable removal is that service does not get uninstalled and
@@ -508,11 +516,11 @@ extern "C" UINT CheckDBInUse(MSIHANDLE hInstall)
wchar_t *datadir= NULL;
wchar_t *bindir=NULL;
- SC_HANDLE scm = NULL;
- ULONG bufsize = sizeof(buf);
- ULONG bufneed = 0x00;
- ULONG num_services = 0x00;
- LPENUM_SERVICE_STATUS_PROCESS info = NULL;
+ SC_HANDLE scm = NULL;
+ ULONG bufsize = sizeof(buf);
+ ULONG bufneed = 0x00;
+ ULONG num_services = 0x00;
+ LPENUM_SERVICE_STATUS_PROCESS info = NULL;
BOOL ok;
hr = WcaInitialize(hInstall, __FUNCTION__);
@@ -522,48 +530,49 @@ extern "C" UINT CheckDBInUse(MSIHANDLE hInstall)
WcaGetProperty(L"SERVICENAME", &servicename);
WcaGetProperty(L"DATADIR", &datadir);
WcaGetFormattedString(L"[INSTALLDIR]bin\\", &bindir);
+
WcaLog(LOGMSG_STANDARD,"SERVICENAME=%S, DATADIR=%S, bindir=%S",
servicename, datadir, bindir);
- scm = OpenSCManager(NULL, NULL,
- SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
- if (scm == NULL)
- {
+ scm = OpenSCManager(NULL, NULL,
+ SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
+ if (scm == NULL)
+ {
ExitOnFailure(E_FAIL, "OpenSCManager failed");
}
ok = EnumServicesStatusExW( scm,
- SC_ENUM_PROCESS_INFO,
+ SC_ENUM_PROCESS_INFO,
SERVICE_WIN32,
- SERVICE_STATE_ALL,
- buf,
- bufsize,
- &bufneed,
- &num_services,
- NULL,
+ SERVICE_STATE_ALL,
+ buf,
+ bufsize,
+ &bufneed,
+ &num_services,
+ NULL,
NULL);
- if(!ok)
+ if(!ok)
{
WcaLog(LOGMSG_STANDARD, "last error %d", GetLastError());
ExitOnFailure(E_FAIL, "EnumServicesStatusExW failed");
}
- info = (LPENUM_SERVICE_STATUS_PROCESS)buf;
+ info = (LPENUM_SERVICE_STATUS_PROCESS)buf;
for (ULONG i=0; i < num_services; i++)
{
- SC_HANDLE service= OpenServiceW(scm, info[i].lpServiceName,
+ SC_HANDLE service= OpenServiceW(scm, info[i].lpServiceName,
SERVICE_QUERY_CONFIG);
if (!service)
continue;
WcaLog(LOGMSG_VERBOSE, "Checking Service %S", info[i].lpServiceName);
- QUERY_SERVICE_CONFIGW *config=
+ QUERY_SERVICE_CONFIGW *config=
(QUERY_SERVICE_CONFIGW *)(void *)config_buffer;
DWORD needed;
- BOOL ok= QueryServiceConfigW(service, config,sizeof(config_buffer),
+ BOOL ok= QueryServiceConfigW(service, config,sizeof(config_buffer),
&needed);
CloseServiceHandle(service);
if (ok)
{
- CheckServiceConfig(servicename, datadir, bindir, info[i].lpServiceName,
+ CheckServiceConfig(servicename, datadir, bindir, info[i].lpServiceName,
config);
}
}
@@ -575,18 +584,18 @@ LExit:
ReleaseStr(servicename);
ReleaseStr(datadir);
ReleaseStr(bindir);
- return WcaFinalize(er);
+ return WcaFinalize(er);
}
-/*
+/*
Get maximum size of the buffer process can allocate.
this is calculated as min(RAM,virtualmemorylimit)
For 32bit processes, virtual address memory is 2GB (x86 OS)
or 4GB(x64 OS).
-
- Fragmentation due to loaded modules, heap and stack
+
+ Fragmentation due to loaded modules, heap and stack
limit maximum size of continuous memory block further,
- so that limit for 32 bit process is about 1200 on 32 bit OS
+ so that limit for 32 bit process is about 1200 on 32 bit OS
or 2000 MB on 64 bit OS(found experimentally).
*/
unsigned long long GetMaxBufferSize(unsigned long long totalPhys)
@@ -604,9 +613,9 @@ unsigned long long GetMaxBufferSize(unsigned long long totalPhys)
/*
- Checks SERVICENAME, PORT and BUFFERSIZE parameters
+ Checks SERVICENAME, PORT and BUFFERSIZE parameters
*/
-extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
+extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
{
wchar_t ServiceName[MAX_PATH]={0};
wchar_t SkipNetworking[MAX_PATH]={0};
@@ -629,7 +638,7 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
ExitOnFailure(hr, "Failed to initialize");
WcaLog(LOGMSG_STANDARD, "Initialized.");
-
+
MsiGetPropertyW (hInstall, L"SERVICENAME", ServiceName, &ServiceNameLen);
if(ServiceName[0])
{
@@ -640,10 +649,10 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
}
for(DWORD i=0; i< ServiceNameLen;i++)
{
- if(ServiceName[i] == L'\\' || ServiceName[i] == L'/'
+ if(ServiceName[i] == L'\\' || ServiceName[i] == L'/'
|| ServiceName[i]=='\'' || ServiceName[i] ==L'"')
{
- ErrorMsg =
+ ErrorMsg =
L"Invalid service name. Forward slash and back slash are forbidden."
L"Single and double quotes are also not permitted.";
goto LExit;
@@ -663,10 +672,10 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
sizeof(EscapedPassword)/sizeof(EscapedPassword[0]));
MsiSetPropertyW(hInstall,L"ESCAPEDPASSWORD",EscapedPassword);
- MsiGetPropertyW(hInstall, L"SKIPNETWORKING", SkipNetworking,
+ MsiGetPropertyW(hInstall, L"SKIPNETWORKING", SkipNetworking,
&SkipNetworkingLen);
MsiGetPropertyW(hInstall, L"PORT", Port, &PortLen);
-
+
if(SkipNetworking[0]==0 && Port[0] != 0)
{
/* Strip spaces */
@@ -699,13 +708,13 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
unsigned short port = (unsigned short)_wtoi(Port);
if (!IsPortFree(port))
{
- ErrorMsg =
+ ErrorMsg =
L"The TCP Port you selected is already in use. "
L"Please choose a different port.";
goto LExit;
}
}
-
+
MsiGetPropertyW (hInstall, L"STDCONFIG", QuickConfig, &QuickConfigLen);
if(QuickConfig[0] !=0)
{
@@ -715,7 +724,7 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
if (!GlobalMemoryStatusEx(&memstatus))
{
- WcaLog(LOGMSG_STANDARD, "Error %u from GlobalMemoryStatusEx",
+ WcaLog(LOGMSG_STANDARD, "Error %u from GlobalMemoryStatusEx",
GetLastError());
er= ERROR_INSTALL_FAILURE;
goto LExit;
@@ -769,7 +778,7 @@ LExit:
return WcaFinalize(er);
}
-/*
+/*
Sets Innodb buffer pool size (1/8 of RAM by default), if not already specified
via command line.
Calculates innodb log file size as min(50, innodb buffer pool size/8)
@@ -792,7 +801,7 @@ extern "C" UINT __stdcall PresetDatabaseProperties(MSIHANDLE hInstall)
if (BufferPoolsizeParamLen && buff[0])
{
- WcaLog(LOGMSG_STANDARD, "BUFFERPOOLSIZE=%s, len=%u",buff, BufferPoolsizeParamLen);
+ WcaLog(LOGMSG_STANDARD, "BUFFERPOOLSIZE=%S, len=%u",buff, BufferPoolsizeParamLen);
InnodbBufferPoolSize= _wtoi64(buff);
}
else
@@ -800,7 +809,7 @@ extern "C" UINT __stdcall PresetDatabaseProperties(MSIHANDLE hInstall)
memstatus.dwLength = sizeof(memstatus);
if (!GlobalMemoryStatusEx(&memstatus))
{
- WcaLog(LOGMSG_STANDARD, "Error %u from GlobalMemoryStatusEx",
+ WcaLog(LOGMSG_STANDARD, "Error %u from GlobalMemoryStatusEx",
GetLastError());
er= ERROR_INSTALL_FAILURE;
goto LExit;
@@ -809,14 +818,14 @@ extern "C" UINT __stdcall PresetDatabaseProperties(MSIHANDLE hInstall)
/* Give innodb 12.5% of available physical memory. */
InnodbBufferPoolSize= totalPhys/ONE_MB/8;
#ifdef _M_IX86
- /*
+ /*
For 32 bit processes, take virtual address space limitation into account.
Do not try to use more than 3/4 of virtual address space, even if there
is plenty of physical memory.
*/
InnodbBufferPoolSize= min(GetMaxBufferSize(totalPhys)/ONE_MB*3/4,
InnodbBufferPoolSize);
- #endif
+ #endif
swprintf_s(buff, L"%llu",InnodbBufferPoolSize);
MsiSetPropertyW(hInstall, L"BUFFERPOOLSIZE", buff);
}
@@ -871,7 +880,7 @@ static void DumpErrorLog(const wchar_t *dir)
}
/* Remove service and data directory created by CreateDatabase operation */
-extern "C" UINT __stdcall CreateDatabaseRollback(MSIHANDLE hInstall)
+extern "C" UINT __stdcall CreateDatabaseRollback(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
@@ -912,17 +921,17 @@ extern "C" UINT __stdcall CreateDatabaseRollback(MSIHANDLE hInstall)
ExecRemoveDataDirectory(dir);
}
LExit:
- return WcaFinalize(er);
+ return WcaFinalize(er);
}
/*
- Enables/disables optional "Launch upgrade wizard" checkbox at the end of
+ Enables/disables optional "Launch upgrade wizard" checkbox at the end of
installation
*/
#define MAX_VERSION_PROPERTY_SIZE 64
-extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
+extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
{
HRESULT hr = S_OK;
UINT er = ERROR_SUCCESS;
@@ -939,7 +948,7 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
hr = WcaInitialize(hInstall, __FUNCTION__);
WcaLog(LOGMSG_STANDARD, "Initialized.");
- if (MsiGetPropertyW(hInstall, L"ProductVersion", installerVersion, &size)
+ if (MsiGetPropertyW(hInstall, L"ProductVersion", installerVersion, &size)
!= ERROR_SUCCESS)
{
hr = HRESULT_FROM_WIN32(GetLastError());
@@ -958,12 +967,12 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
hr = HRESULT_FROM_WIN32(GetLastError());
ExitOnFailure(hr, "MsiGetPropertyW failed");
}
-
- scm = OpenSCManager(NULL, NULL,
- SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
- if (scm == NULL)
- {
+
+ scm = OpenSCManager(NULL, NULL,
+ SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT);
+ if (scm == NULL)
+ {
hr = HRESULT_FROM_WIN32(GetLastError());
ExitOnFailure(hr,"OpenSCManager failed");
}
@@ -976,7 +985,7 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
DWORD num_services;
ok= EnumServicesStatusExW(scm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32,
SERVICE_STATE_ALL, buf, bufsize, &bufneed, &num_services, NULL, NULL);
- if(!ok)
+ if(!ok)
{
hr = HRESULT_FROM_WIN32(GetLastError());
ExitOnFailure(hr,"EnumServicesStatusEx failed");
@@ -986,11 +995,11 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
index=-1;
for (ULONG i=0; i < num_services; i++)
{
- SC_HANDLE service= OpenServiceW(scm, info[i].lpServiceName,
+ SC_HANDLE service= OpenServiceW(scm, info[i].lpServiceName,
SERVICE_QUERY_CONFIG);
if (!service)
continue;
- QUERY_SERVICE_CONFIGW *config=
+ QUERY_SERVICE_CONFIGW *config=
(QUERY_SERVICE_CONFIGW*)(void *)config_buffer;
DWORD needed;
ok= QueryServiceConfigW(service, config,sizeof(config_buffer),
@@ -1001,7 +1010,7 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
mysqld_service_properties props;
if (get_mysql_service_properties(config->lpBinaryPathName, &props))
continue;
- /*
+ /*
Only look for services that have mysqld.exe outside of the current
installation directory.
*/
@@ -1010,7 +1019,7 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
WcaLog(LOGMSG_STANDARD, "found service %S, major=%d, minor=%d",
info[i].lpServiceName, props.version_major, props.version_minor);
if(props.version_major < installerMajorVersion
- || (props.version_major == installerMajorVersion &&
+ || (props.version_major == installerMajorVersion &&
props.version_minor <= installerMinorVersion))
{
upgradableServiceFound= true;
@@ -1034,7 +1043,7 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall)
LExit:
if(scm)
CloseServiceHandle(scm);
- return WcaFinalize(er);
+ return WcaFinalize(er);
}
@@ -1058,3 +1067,269 @@ extern "C" BOOL WINAPI DllMain(
return TRUE;
}
+
+
+static wstring MakeExePath(const wchar_t *installDir, const wchar_t *basename)
+{
+ wstring path(installDir);
+ if (path.back() != L'\\')
+ path.append(L"\\");
+ path.append(L"bin\\");
+ path.append(basename);
+ path.append(L".exe");
+ return path;
+}
+
+static wstring MakeExePath(const wchar_t *installDir, string basename)
+{
+ wstring path(installDir);
+ if (path.back() != L'\\')
+ path.append(L"\\");
+ path.append(L"bin\\");
+ for (auto c : basename)
+ path+= c;
+ path.append(L".exe");
+ return path;
+}
+static wstring MakeFixSymlinksLogPath()
+{
+ wchar_t buf[MAX_PATH];
+ if (GetTempPathW(MAX_PATH, buf))
+ return wstring(buf) + L"\\mariadb_msi_fix_symlinks.log";
+ return L"";
+}
+
+static string w2s(wstring w)
+{
+ string s;
+ for (auto wc : w)
+ s += (char)wc;
+ return s;
+}
+
+/*
+ Remove symlinks if target file does not exist.
+ Create symlink if target exists, but symlink is not.
+*/
+static void fix_symlink(const wchar_t *file, const wchar_t *link,
+ const wchar_t *installdir,
+ vector<string> &rollback_actions)
+{
+ WcaLog(LOGMSG_STANDARD, "fix_symlink %S=>%S", link, file);
+
+ auto tgt= MakeExePath(installdir, file);
+ auto lnk= MakeExePath(installdir, link);
+ auto target_path= tgt.c_str();
+ auto link_path= lnk.c_str();
+
+ auto target_attr= GetFileAttributesW(target_path);
+ auto link_attr= GetFileAttributesW(link_path);
+ WcaLog(LOGMSG_STANDARD, "%S %s", target_path,
+ target_attr == INVALID_FILE_ATTRIBUTES ? "does not exist" : "exists");
+ WcaLog(LOGMSG_STANDARD, "%S %s", link_path,
+ link_attr == INVALID_FILE_ATTRIBUTES ? "does not exist" : "exists");
+
+ if (link_attr != INVALID_FILE_ATTRIBUTES &&
+ ((link_attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0))
+ {
+ WcaLog(LOGMSG_STANDARD, "%S is not a symlink!", link_path);
+ return;
+ }
+
+ if (target_attr == INVALID_FILE_ATTRIBUTES)
+ {
+ if (link_attr == INVALID_FILE_ATTRIBUTES)
+ {
+ return;
+ }
+ auto ok= DeleteFileW(link_path);
+ WcaLog(LOGMSG_STANDARD, "DeleteFileW(L\"%S\") returned %s, last error %lu",
+ link_path, ok ? "success" : "error", GetLastError());
+ if (ok)
+ {
+ rollback_actions.push_back(string("create_symlink ") + w2s(link) + " " +
+ w2s(file));
+ }
+ return;
+ }
+
+ if (link_attr != INVALID_FILE_ATTRIBUTES)
+ return;
+
+ auto ok= CreateSymbolicLinkW(link_path, target_path, 0);
+ WcaLog(LOGMSG_STANDARD,
+ "CreateSymbolicLinkW(\"%S\",\"%S\", 0) returned %s, last error %d",
+ link_path, target_path, ok ? "success" : "error",
+ (int) GetLastError());
+ if (ok)
+ rollback_actions.push_back(string("delete ") + w2s(link));
+}
+
+static string rollback_info_path()
+{
+ char tmppath[MAX_PATH];
+ if (!GetTempPathA(MAX_PATH, tmppath))
+ return "";
+ string filepath(tmppath);
+ filepath.append("\\mariadb_symlink_rollback_info.tmp");
+ return filepath;
+}
+
+
+static void save_symlink_rollback_info(vector<string> rollback_info)
+{
+ std::ofstream ofs;
+ string path = rollback_info_path();
+ ofs.open(path, std::ofstream::out | std::ofstream::trunc);
+ if (!ofs.good())
+ return;
+ WcaLog(LOGMSG_STANDARD,
+ "Storing this rollback script for custom action in %s, in case installation rolls back",
+ path.c_str());
+ for (auto line : rollback_info)
+ {
+ WcaLog(LOGMSG_STANDARD, "%s", line.c_str());
+ ofs << line << "\n";
+ }
+ WcaLog(LOGMSG_STANDARD, "End of rollback script");
+}
+
+
+#include <symlinks.h>
+/* MDEV-19781 MariaDB symlinks on Windows */
+extern "C" UINT __stdcall FixSymlinksRollback(MSIHANDLE hInstall)
+{
+ HRESULT hr= S_OK;
+ UINT er= ERROR_SUCCESS;
+ wchar_t targetdir[MAX_PATH];
+ DWORD len= MAX_PATH;
+ hr= WcaInitialize(hInstall, __FUNCTION__);
+ WcaLog(LOGMSG_STANDARD, "Initialized.");
+ std::ifstream ifs;
+ std::string command;
+
+ if (MsiGetPropertyW(hInstall, L"CustomActionData", targetdir, &len) !=
+ ERROR_SUCCESS)
+ {
+ hr= HRESULT_FROM_WIN32(GetLastError());
+ ExitOnFailure(hr, "MsiGetPropertyW failed");
+ }
+
+ ifs.open(rollback_info_path(), std::ofstream::in);
+ if (!ifs.good())
+ goto LExit;
+
+ while (ifs >> command)
+ {
+ if (command == "create_symlink")
+ {
+ string link;
+ ifs >> link;
+ auto link_path= MakeExePath(targetdir, link);
+ string file;
+ ifs >> file;
+ auto target_path= MakeExePath(targetdir, file);
+ bool ok= CreateSymbolicLinkW(link_path.c_str(), target_path.c_str(), 0);
+ WcaLog(LOGMSG_STANDARD, "CreateSymbolicLinkW(%S,%S) %s, last error %lu",
+ link_path.c_str(), target_path.c_str(), ok ? "success" : "error",
+ GetLastError());
+ }
+ else if (command == "delete")
+ {
+ string link;
+ ifs >> link;
+ auto link_path= MakeExePath(targetdir, link);
+ auto link_attr= GetFileAttributesW(link_path.c_str());
+ if (link_attr != INVALID_FILE_ATTRIBUTES &&
+ (link_attr & FILE_ATTRIBUTE_REPARSE_POINT))
+ {
+ auto ok= DeleteFileW(link_path.c_str());
+ WcaLog(LOGMSG_STANDARD, "DeleteFile(%S) %s, last error %lu",
+ link_path.c_str(), ok ? "success" : "error", GetLastError());
+ }
+ }
+ else
+ {
+ WcaLog(LOGMSG_STANDARD, "Unknown command '%s' in rollback script ",
+ command.c_str());
+ goto LExit;
+ }
+ }
+
+LExit:
+ return WcaFinalize(er);
+}
+
+
+extern "C" UINT __stdcall SymlinksUninstall(MSIHANDLE hInstall)
+{
+ HRESULT hr = S_OK;
+ UINT er = ERROR_SUCCESS;
+ wchar_t targetdir[MAX_PATH];
+ DWORD len = MAX_PATH;
+ int i;
+ hr = WcaInitialize(hInstall, __FUNCTION__);
+ WcaLog(LOGMSG_STANDARD, "Initialized.");
+
+ if (MsiGetPropertyW(hInstall, L"CustomActionData", targetdir, &len) !=
+ ERROR_SUCCESS)
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ ExitOnFailure(hr, "MsiGetPropertyW failed");
+ }
+
+ for (i = 0; all_symlinks[i].file; i++)
+ {
+ auto link_path = MakeExePath(targetdir, all_symlinks[i].link);
+ auto link_attr = GetFileAttributesW(link_path.c_str());
+ auto filepath = link_path.c_str();
+
+ if (link_attr == INVALID_FILE_ATTRIBUTES)
+ {
+ WcaLog(LOGMSG_STANDARD, " %S does not exist",filepath);
+ continue;
+ }
+
+ if(!(link_attr & FILE_ATTRIBUTE_REPARSE_POINT))
+ {
+ WcaLog(LOGMSG_STANDARD, " %S is not a symbolic link!",filepath);
+ continue;
+ }
+ BOOL ok = DeleteFileW(filepath);
+ WcaLog(LOGMSG_STANDARD, "DeleteFile(%S) %s, last error %lu",
+ filepath, ok? "succeeded":"failed", GetLastError());
+ }
+
+LExit:
+ return WcaFinalize(er);
+}
+
+/* MDEV-19781 MariaDB symlinks on Windows */
+extern "C" UINT __stdcall FixSymlinks(MSIHANDLE hInstall)
+{
+ HRESULT hr= S_OK;
+ UINT er= ERROR_SUCCESS;
+ wchar_t targetdir[MAX_PATH];
+ vector<string> rollback_actions;
+ DWORD len= MAX_PATH;
+ int i;
+ hr= WcaInitialize(hInstall, __FUNCTION__);
+ WcaLog(LOGMSG_STANDARD, "Initialized.");
+
+ if (MsiGetPropertyW(hInstall, L"CustomActionData", targetdir, &len) !=
+ ERROR_SUCCESS)
+ {
+ hr= HRESULT_FROM_WIN32(GetLastError());
+ ExitOnFailure(hr, "MsiGetPropertyW failed");
+ }
+
+ for (i= 0; all_symlinks[i].file; i++)
+ fix_symlink(all_symlinks[i].file, all_symlinks[i].link, targetdir,
+ rollback_actions);
+
+ save_symlink_rollback_info(rollback_actions);
+
+LExit:
+ return WcaFinalize(er);
+}
+
diff --git a/win/packaging/ca/CustomAction.def b/win/packaging/ca/CustomAction.def
index 0be77a97a08..8169968e26b 100644
--- a/win/packaging/ca/CustomAction.def
+++ b/win/packaging/ca/CustomAction.def
@@ -8,3 +8,6 @@ CheckDatabaseProperties
CheckDataDirectoryEmpty
CheckDBInUse
CheckServiceUpgrades
+FixSymlinks
+FixSymlinksRollback
+SymlinksUninstall
diff --git a/win/packaging/ca/symlinks.cc.in b/win/packaging/ca/symlinks.cc.in
new file mode 100644
index 00000000000..62ca9884af8
--- /dev/null
+++ b/win/packaging/ca/symlinks.cc.in
@@ -0,0 +1,6 @@
+#include "symlinks.h"
+symlink all_symlinks[]=
+{
+@ALL_SYMLINKS@
+{nullptr, nullptr}
+};
diff --git a/win/packaging/ca/symlinks.h b/win/packaging/ca/symlinks.h
new file mode 100644
index 00000000000..4fc1f2cb685
--- /dev/null
+++ b/win/packaging/ca/symlinks.h
@@ -0,0 +1,8 @@
+#pragma once
+struct symlink
+{
+ const wchar_t *file;
+ const wchar_t *link;
+};
+
+extern symlink all_symlinks[];
diff --git a/win/packaging/create_msi.cmake b/win/packaging/create_msi.cmake
index 58edcef3ef9..f992915cd22 100644
--- a/win/packaging/create_msi.cmake
+++ b/win/packaging/create_msi.cmake
@@ -1,3 +1,4 @@
+
MACRO(MAKE_WIX_IDENTIFIER str varname)
STRING(REPLACE "/" "." ${varname} "${str}")
STRING(REGEX REPLACE "[^a-zA-Z_0-9.]" "_" ${varname} "${${varname}}")
@@ -61,6 +62,11 @@ IF(CMAKE_INSTALL_CONFIG_NAME)
SET(CONFIG_PARAM "-DCMAKE_INSTALL_CONFIG_NAME=${CMAKE_INSTALL_CONFIG_NAME}")
ENDIF()
+IF((MSVC_CRT_TYPE MATCHES "/MD") AND (NOT VCRedist_MSM))
+ # Something was wrong, we package VC runtime merge modules
+ # when compiled with dynamic C runtime.
+ MESSAGE(FATAL_ERROR "Redistributable merge module was not found")
+ENDIF()
SET(COMPONENTS_ALL "${CPACK_COMPONENTS_ALL}")
FOREACH(comp ${COMPONENTS_ALL})
@@ -384,9 +390,13 @@ EXECUTE_PROCESS(
${EXTRA_CANDLE_ARGS}
)
+IF(VCRedist_MSM)
+ SET(SILENCE_VCREDIST_MSM_WARNINGS -sice:ICE82 -sice:ICE03)
+ENDIF()
+
EXECUTE_PROCESS(
COMMAND ${LIGHT_EXECUTABLE} -v -ext WixUIExtension -ext WixUtilExtension
- -ext WixFirewallExtension -sice:ICE61
+ -ext WixFirewallExtension -sice:ICE61 ${SILENCE_VCREDIST_MSM_WARNINGS}
mysql_server.wixobj extra.wixobj -out ${CPACK_PACKAGE_FILE_NAME}.msi
${EXTRA_LIGHT_ARGS}
)
diff --git a/win/packaging/extra.wxs.in b/win/packaging/extra.wxs.in
index ee4753d099f..d4fcce17445 100644
--- a/win/packaging/extra.wxs.in
+++ b/win/packaging/extra.wxs.in
@@ -279,7 +279,7 @@
<Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="&amp;Next">
<Publish Property="WarningText" Value="Passwords do not match."><![CDATA[PASSWORD <> RootPasswordConfirm]]></Publish>
<Publish Event="SpawnDialog" Value="WarningDlg"><![CDATA[WarningText <>""]]></Publish>
- <Publish Property="SERVICENAME" Value="MySQL">NOT SERVICENAME AND NOT WarningText</Publish>
+ <Publish Property="SERVICENAME" Value="MariaDB">NOT SERVICENAME AND NOT WarningText</Publish>
<Publish Event="NewDialog" Value="ServicePortDlg"><![CDATA[WarningText=""]]></Publish>
<Condition Action="enable"><![CDATA[NOT ModifyRootPassword OR PASSWORD]]> </Condition>
<Condition Action="disable"><![CDATA[ModifyRootPassword AND (NOT PASSWORD)]]> </Condition>
@@ -650,11 +650,37 @@
</Feature>
<?endif ?>
+
+ <?if "@VCRedist_MSM@" != "" ?>
+ <!-- VC runtime merge module -->
+ <DirectoryRef Id="TARGETDIR">
+ <Merge Id="VCRedist" SourceFile="@VCRedist_MSM@" DiskId="1" Language="0"/>
+ </DirectoryRef>
+ <Feature Id="VCRedist" Title="Visual C++ Runtime" AllowAdvertise="no" Display="hidden" Level="1">
+ <MergeRef Id="VCRedist"/>
+ </Feature>
+ <?endif?>
- <!-- Custom action, call mysql_install_db -->
- <SetProperty Sequence='execute' Before='CreateDatabaseCommand' Id="SKIPNETWORKING" Value="--skip-networking" >SKIPNETWORKING</SetProperty>
- <SetProperty Sequence='execute' Before='CreateDatabaseCommand' Id="ALLOWREMOTEROOTACCESS" Value="--allow-remote-root-access">ALLOWREMOTEROOTACCESS</SetProperty>
- <SetProperty Sequence='execute' Before='CreateDatabaseCommand' Id="DEFAULTUSER" Value="--default-user">DEFAULTUSER</SetProperty>
+ <!-- Custom action, create symlinks -->
+ <CustomAction Id="Symlinks.SetProperty" Return="check" Property="Symlinks" Value="[INSTALLDIR]" />
+ <CustomAction Id="Symlinks" BinaryKey="wixca.dll" DllEntry="FixSymlinks" Execute="deferred" Impersonate="no" Return="ignore"/>
+ <CustomAction Id="SymlinksRollback.SetProperty" Return="check" Property="SymlinksRollback" Value="[INSTALLDIR]" />
+ <CustomAction Id="SymlinksRollback" BinaryKey="wixca.dll" DllEntry="FixSymlinksRollback" Execute="rollback" Impersonate="no" Return="ignore"/>
+ <CustomAction Id="SymlinksUninstall.SetProperty" Return="check" Property="SymlinksUninstall" Value="[INSTALLDIR]" />
+ <CustomAction Id="SymlinksUninstall" BinaryKey="wixca.dll" DllEntry="SymlinksUninstall" Execute="deferred" Impersonate="no" Return="ignore"/>
+ <InstallExecuteSequence>
+ <Custom Action="Symlinks.SetProperty" Before="Symlinks">NOT Installed OR UPGRADINGPRODUCTCODE</Custom>
+ <Custom Action="Symlinks" After="SymlinksRollback">NOT Installed OR UPGRADINGPRODUCTCODE</Custom>
+ <Custom Action="SymlinksRollback.SetProperty" Before="SymlinksRollback">NOT Installed OR UPGRADINGPRODUCTCODE</Custom>
+ <Custom Action="SymlinksRollback" After="InstallFiles">NOT Installed OR UPGRADINGPRODUCTCODE</Custom>
+ <Custom Action="SymlinksUninstall.SetProperty" Before="SymlinksUninstall">Installed AND NOT UPGRADINGPRODUCTCODE</Custom>
+ <Custom Action="SymlinksUninstall" Before="RemoveFiles">Installed AND NOT UPGRADINGPRODUCTCODE</Custom>
+ </InstallExecuteSequence>
+
+ <!-- Custom action, call mysql_install_db -->
+ <SetProperty Sequence='execute' Before='CreateDatabaseCommand' Id="SKIPNETWORKING" Value="--skip-networking" >SKIPNETWORKING</SetProperty>
+ <SetProperty Sequence='execute' Before='CreateDatabaseCommand' Id="ALLOWREMOTEROOTACCESS" Value="--allow-remote-root-access">ALLOWREMOTEROOTACCESS</SetProperty>
+ <SetProperty Sequence='execute' Before='CreateDatabaseCommand' Id="DEFAULTUSER" Value="--default-user">DEFAULTUSER</SetProperty>
<CustomAction Id='CheckDatabaseProperties' BinaryKey='wixca.dll' DllEntry='CheckDatabaseProperties' />
<CustomAction Id='PresetDatabaseProperties' BinaryKey='wixca.dll' DllEntry='PresetDatabaseProperties' />
<CustomAction Id="CreateDatabaseCommand" Property="CreateDatabase"
diff --git a/win/packaging/mysql_server.wxs.in b/win/packaging/mysql_server.wxs.in
index c10116830e7..80dcc365e56 100644
--- a/win/packaging/mysql_server.wxs.in
+++ b/win/packaging/mysql_server.wxs.in
@@ -12,7 +12,7 @@
Keywords='Installer'
Description='MariaDB Server'
Manufacturer='@MANUFACTURER@'
- InstallerVersion='200'
+ InstallerVersion='301'
Languages='1033'
Compressed='yes'
SummaryCodepage='1252'
diff --git a/win/upgrade_wizard/CMakeLists.txt b/win/upgrade_wizard/CMakeLists.txt
index f4148ee98d2..7d0e774b968 100644
--- a/win/upgrade_wizard/CMakeLists.txt
+++ b/win/upgrade_wizard/CMakeLists.txt
@@ -23,21 +23,27 @@ IF(NOT MFC_FOUND)
ENDIF()
RETURN()
ENDIF()
+
IF(MSVC_CRT_TYPE MATCHES "/MD")
- # MFC should be dynamically linked
- SET(CMAKE_MFC_FLAG 2)
+ # FORCE static CRT and MFC for upgrade wizard,
+ # so we do not have to redistribute MFC.
+ FORCE_STATIC_CRT()
+ SET(UPGRADE_WIZARD_SOURCES ${CMAKE_SOURCE_DIR}/sql/winservice.c)
ELSE()
- # MFC should be statically linked
- SET(CMAKE_MFC_FLAG 1)
+ SET(UPGRADE_WIZARD_LINK_LIBRARIES winservice)
ENDIF()
+
+# MFC should be statically linked
+SET(CMAKE_MFC_FLAG 1)
+
# Enable exception handling (avoids warnings)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc -DNO_WARN_MBCS_MFC_DEPRECATION")
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql)
MYSQL_ADD_EXECUTABLE(mysql_upgrade_wizard
- upgrade.cpp upgradeDlg.cpp upgrade.rc
+ upgrade.cpp upgradeDlg.cpp upgrade.rc ${UPGRADE_WIZARD_SOURCES}
COMPONENT Server)
-TARGET_LINK_LIBRARIES(mysql_upgrade_wizard winservice)
+TARGET_LINK_LIBRARIES(mysql_upgrade_wizard ${UPGRADE_WIZARD_LINK_LIBRARIES})
# upgrade_wizard is Windows executable, set WIN32_EXECUTABLE so it does not
# create a console.
SET_TARGET_PROPERTIES(mysql_upgrade_wizard PROPERTIES WIN32_EXECUTABLE 1)