YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense alongwiththisprogram;ifnot,writetotheFreeSoftware
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
SHFILEOPSTRUCTW fileop;
fileop.hwnd= NULL; /* no status display */
fileop.wFunc= FO_DELETE; /* delete operation */
fileop.pFrom= dir; /* source file name as double null terminated string */
fileop.pTo= NULL; /* no destination needed */
fileop.fFlags= FOF_NOCONFIRMATION|FOF_SILENT; /* do not prompt the user */
WcaLog(LOGMSG_STANDARD, "Checking files in %S", datadir);
empty= IsDirectoryEmptyOrNonExisting(datadir); if (empty)
WcaLog(LOGMSG_STANDARD, "DATADIR is empty or non-existent"); else
WcaLog(LOGMSG_STANDARD, "DATADIR is NOT empty");
if (!empty)
{
WcaSetProperty(L"DATADIRERROR", L"data directory exist and not empty"); goto LExit;
}
WcaSetProperty(L"DATADIRERROR", L"");
WcaGetFormattedString(L"[INSTALLDIR]",&path); if (path && !wcsicmp(datadir, path))
{
WcaSetProperty(L"DATADIRERROR", L"data directory can not be "
L"installation root directory");
ReleaseStr(path); goto LExit;
} for (auto dir :
{L"[INSTALLDIR]bin\\", L"[INSTALLDIR]include\\",
L"[INSTALLDIR]lib\\", L"[INSTALLDIR]share\\"})
{
WcaGetFormattedString(dir, &path); if (path && !wcsnicmp(datadir, path, wcslen(path)))
{ constwchar_t *subdir= dir + sizeof("[INSTALLDIR]") - 1; wchar_t msg[MAX_PATH]= L"data directory conflicts with '";
wcsncat_s(msg, subdir, wcslen(subdir) - 1);
wcscat_s(msg, L"' directory, which is part of this installation");
WcaSetProperty(L"DATADIRERROR", msg);
ReleaseStr(path); goto LExit;
}
ReleaseStr(path);
path= 0;
}
LExit: return WcaFinalize(er);
}
service = OpenService(manager, name, SC_MANAGER_CONNECT); if(service)
CloseServiceHandle(service);
CloseServiceHandle(manager);
return service?true:false;
}
/* User in rollback of create database custom action */ bool ExecRemoveService(constwchar_t *name)
{
SC_HANDLE manager =0, service=0;
manager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); bool ret; if (!manager)
{ returnfalse;
}
service = OpenService(manager, name, DELETE); if(service)
{
ret= DeleteService(service);
} else
{
ret= false;
}
CloseServiceHandle(manager); return ret;
}
/* Find whether TCP port is in use by trying to bind to the port. */ staticbool IsPortInUse(unsignedshort port)
{ struct addrinfo* ai, * a; struct addrinfo hints {};
if (getaddrinfo(NULL, port_buf, &hints, &ai))
{ returnfalse;
}
/* PreferIPv6sockettoIPv4,sincewe'lluseIPv6dualsocket, whichcoversbothIPversions.
*/ for (a = ai; a; a = a->ai_next)
{ if (a->ai_family == AF_INET6 &&
(ip_sock = socket(a->ai_family, a->ai_socktype, a->ai_protocol)) != INVALID_SOCKET)
{ break;
}
}
if (ip_sock == INVALID_SOCKET)
{ for (a = ai; a; a = a->ai_next)
{ if (ai->ai_family == AF_INET &&
(ip_sock = socket(a->ai_family, a->ai_socktype, a->ai_protocol)) != INVALID_SOCKET)
{ break;
}
}
}
if (ip_sock == INVALID_SOCKET)
{ returnfalse;
}
/* Use SO_EXCLUSIVEADDRUSE to prevent multiple binding. */ int arg = 1;
setsockopt(ip_sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char*)&arg, sizeof(arg));
/* Allow dual socket, so that IPv4 and IPv6 are both covered.*/ if (a->ai_family == AF_INET6)
{
arg = 0;
setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg, sizeof(arg));
}
WcaLog(LOGMSG_STANDARD, "MySQL/MariaDB service %S found: CommandLine= %S",
other_servicename, commandline); if (wcsstr(argv[0], bindir))
{
WcaLog(LOGMSG_STANDARD, "executable under bin directory");
same_bindir = true;
}
is_my_service = (_wcsicmp(my_servicename, other_servicename) == 0); if(!is_my_service)
{
WcaLog(LOGMSG_STANDARD, "service does not match current service"); /* TODOprobablythebestthingpossiblewouldbetoaddtemporary rowtoMSIServiceConfigtablewithremoveonuninstall
*/
} elseif (!same_bindir)
{
WcaLog(LOGMSG_STANDARD, "Service name matches, but not the executable path directory, mine is %S",
bindir);
WcaSetProperty(L"SERVICENAME", L"");
}
/* Check if data directory is used */ if(!datadir || numargs <= 1 || wcsncmp(argv[1],L"--defaults-file=",16) != 0)
{ goto end;
}
WcaLog(LOGMSG_STANDARD, "parsed defaults file is %S", defaults_file);
if (GetPrivateProfileStringW(L"mysqld", L"datadir", NULL, current_datadir,
MAX_PATH, defaults_file) == 0)
{
WcaLog(LOGMSG_STANDARD, "Cannot find datadir in ini file '%S'", defaults_file); goto end;
}
WcaLog(LOGMSG_STANDARD, "datadir from defaults-file is %S", current_datadir);
strip_quotes(current_datadir);
/* Convert to Windows path */ 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'",
normalized_current_datadir);
}
if (_wcsicmp(datadir, normalized_current_datadir) == 0 && !same_bindir)
{
WcaLog(LOGMSG_STANDARD, "database directory from current installation, but different mysqld.exe");
WcaSetProperty(L"CLEANUPDATA", L"");
}
hr = WcaInitialize(hInstall, __FUNCTION__);
ExitOnFailure(hr, "Failed to initialize");
WcaLog(LOGMSG_STANDARD, "Initialized.");
MsiGetPropertyW (hInstall, L"SERVICENAME", ServiceName, &ServiceNameLen); if(ServiceName[0])
{ if(ServiceNameLen > 256)
{
ErrorMsg= L"Invalid service name. The maximum length is 256 characters."; goto LExit;
} for(DWORD i=0; i< ServiceNameLen;i++)
{ if(ServiceName[i] == L'\\' || ServiceName[i] == L'/'
|| ServiceName[i]=='\'' || ServiceName[i] ==L'"')
{
ErrorMsg =
L"Invalid service name. Forward slash and back slash are forbidden."
L"Single and double quotes are also not permitted."; goto LExit;
}
} if(CheckServiceExists(ServiceName))
{
ErrorMsg=
L"A service with the same name already exists. "
L"Please use a different name."; goto LExit;
}
}
if(PortLen > 5 || PortLen <= 3)
haveInvalidPort = true; else
{ for (DWORD i=0; i< PortLen && Port[i] != 0;i++)
{ if(Port[i] < '0' || Port[i] >'9')
{
haveInvalidPort=true; break;
}
}
} if (haveInvalidPort)
{
ErrorMsg =
L"Invalid port number. Please use a number between 1025 and 65535."; goto LExit;
}
unsignedshort port = (unsignedshort)_wtoi(Port); if (!IsPortFree(port))
{
ErrorMsg =
L"The TCP Port you selected is already in use. "
L"Please choose a different port."; goto LExit;
}
}
if (!GlobalMemoryStatusEx(&memstatus))
{
WcaLog(LOGMSG_STANDARD, "Error %u from GlobalMemoryStatusEx",
GetLastError());
er= ERROR_INSTALL_FAILURE; goto LExit;
}
DWORD BufferPoolSizeLen= 16;
MsiGetPropertyW(hInstall, L"BUFFERPOOLSIZE", BufferPoolSize, &BufferPoolSizeLen); /* Strip spaces */ for(DWORD i=BufferPoolSizeLen-1; i > 0; i--)
{ if(BufferPoolSize[i]== ' ')
BufferPoolSize[i] = 0;
} unsignedlonglong availableMemory=
GetMaxBufferSize(memstatus.ullTotalPhys)/ONE_MB;
swprintf_s(invalidValueMsg,
L"Invalid buffer pool size. Please use a number between %llu and %llu",
minBufferpoolMB, availableMemory); if (BufferPoolSizeLen == 0 || BufferPoolSizeLen > 15 || !BufferPoolSize[0])
{
ErrorMsg= invalidValueMsg; goto LExit;
}
BufferPoolSize[BufferPoolSizeLen]=0;
MsiSetPropertyW(hInstall, L"BUFFERPOOLSIZE", BufferPoolSize); wchar_t *end; unsignedlonglong sz = wcstoull(BufferPoolSize, &end, 10); if (sz > availableMemory || sz < minBufferpoolMB || *end)
{ if (*end == 0)
{ if(sz > availableMemory)
{
swprintf_s(invalidValueMsg,
L"Value for buffer pool size is too large."
L"Only approximately %llu MB is available for allocation."
L"Please use a number between %llu and %llu.",
availableMemory, minBufferpoolMB, availableMemory);
} elseif(sz < minBufferpoolMB)
{
swprintf_s(invalidValueMsg,
L"Value for buffer pool size is too small."
L"Please use a number between %llu and %llu.",
minBufferpoolMB, availableMemory);
}
}
ErrorMsg= invalidValueMsg; goto LExit;
}
}
LExit:
MsiSetPropertyW (hInstall, L"WarningText", ErrorMsg); return WcaFinalize(er);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.