/* 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) */ extern "C" UINT __stdcall PresetDatabaseProperties(MSIHANDLE hInstall) { unsigned long long InnodbBufferPoolSize= 256; unsigned long long InnodbLogFileSize= 50; wchar_t buff[MAX_PATH]; UINT er = ERROR_SUCCESS; HRESULT hr= S_OK; MEMORYSTATUSEX memstatus; hr = WcaInitialize(hInstall, __FUNCTION__); ExitOnFailure(hr, "Failed to initialize"); WcaLog(LOGMSG_STANDARD, "Initialized."); /* Check if bufferpoolsize parameter was given on the command line*/ DWORD BufferPoolsizeParamLen = MAX_PATH; MsiGetPropertyW(hInstall, L"BUFFERPOOLSIZE", buff, &BufferPoolsizeParamLen); if (BufferPoolsizeParamLen && buff[0]) { WcaLog(LOGMSG_STANDARD, "BUFFERPOOLSIZE=%s, len=%u",buff, BufferPoolsizeParamLen); InnodbBufferPoolSize= _wtoi64(buff); } else { memstatus.dwLength = sizeof(memstatus); if (!GlobalMemoryStatusEx(&memstatus)) { WcaLog(LOGMSG_STANDARD, "Error %u from GlobalMemoryStatusEx", GetLastError()); er= ERROR_INSTALL_FAILURE; goto LExit; } unsigned long long totalPhys= memstatus.ullTotalPhys; /* 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 swprintf_s(buff, L"%llu",InnodbBufferPoolSize); MsiSetPropertyW(hInstall, L"BUFFERPOOLSIZE", buff); } InnodbLogFileSize = min(50, InnodbBufferPoolSize); swprintf_s(buff, L"%llu",InnodbLogFileSize); MsiSetPropertyW(hInstall, L"LOGFILESIZE", buff); LExit: return WcaFinalize(er); }
static UINT errorConvertFromHResult(MSIHANDLE hModule, HRESULT hr) { UINT uRet; switch (hr) { case S_OK: uRet = ERROR_SUCCESS; break; case NETCFG_S_REBOOT: { logStringW(hModule, L"Reboot required, setting REBOOT property to \"force\""); HRESULT hr2 = MsiSetPropertyW(hModule, L"REBOOT", L"Force"); if (hr2 != ERROR_SUCCESS) logStringW(hModule, L"Failed to set REBOOT property, error = 0x%x", hr2); uRet = ERROR_SUCCESS; /* Never fail here. */ break; } default: logStringW(hModule, L"Converting unhandled HRESULT (0x%x) to ERROR_GEN_FAILURE", hr); uRet = ERROR_GEN_FAILURE; } return uRet; }
/** * \par Implementation * The center of the implementation is the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa370391%28v=vs.85%29.aspx">MsiSetProperty function</a>. */ void Property::operator=(const std::wstring& value) { UINT x = MsiSetPropertyW(handle, name.c_str(), value.c_str()); if (x != ERROR_SUCCESS) { throw WindowsApiError("MsiSetPropertyW", x); } }
UINT __stdcall CreateHostOnlyInterface(MSIHANDLE hModule) { #ifdef VBOX_WITH_NETFLT netCfgLoggerEnable(hModule); BOOL bSetupModeInteractive = SetupSetNonInteractiveMode(FALSE); bool bSetStaticIp = true; logStringW(hModule, L"CreateHostOnlyInterface: Creating host-only interface"); HRESULT hr; GUID guid; WCHAR wszMpInf[MAX_PATH]; DWORD cchMpInf = RT_ELEMENTS(wszMpInf) - sizeof("VBoxNetAdp.inf") - 1; LPCWSTR pwszInfPath = NULL; bool bIsFile = false; UINT uErr = MsiGetPropertyW(hModule, L"CustomActionData", wszMpInf, &cchMpInf); if (uErr == ERROR_SUCCESS) { if (cchMpInf) { logStringW(hModule, L"CreateHostOnlyInterface: NetAdpDir property = %s", wszMpInf); if (wszMpInf[cchMpInf - 1] != L'\\') { wszMpInf[cchMpInf++] = L'\\'; wszMpInf[cchMpInf] = L'\0'; } wcscat(wszMpInf, L"VBoxNetAdp.inf"); pwszInfPath = wszMpInf; bIsFile = true; logStringW(hModule, L"CreateHostOnlyInterface: Resulting INF path = %s", pwszInfPath); } else logStringW(hModule, L"CreateHostOnlyInterface: VBox installation path is empty"); } else logStringW(hModule, L"CreateHostOnlyInterface: Unable to retrieve VBox installation path, error = 0x%x", uErr); /* Make sure the inf file is installed. */ if (pwszInfPath != NULL && bIsFile) { logStringW(hModule, L"CreateHostOnlyInterface: Calling VBoxDrvCfgInfInstall(%s)", pwszInfPath); hr = VBoxDrvCfgInfInstall(pwszInfPath); logStringW(hModule, L"CreateHostOnlyInterface: VBoxDrvCfgInfInstall returns 0x%x", hr); if (FAILED(hr)) logStringW(hModule, L"CreateHostOnlyInterface: Failed to install INF file, error = 0x%x", hr); } if (SUCCEEDED(hr)) { //first, try to update Host Only Network Interface BOOL fRebootRequired = FALSE; hr = VBoxNetCfgWinUpdateHostOnlyNetworkInterface(pwszInfPath, &fRebootRequired); if (SUCCEEDED(hr)) { if (fRebootRequired) { logStringW(hModule, L"UpdateHostOnlyInterfaces: Reboot required, setting REBOOT property to force"); HRESULT hr2 = MsiSetPropertyW(hModule, L"REBOOT", L"Force"); if (hr2 != ERROR_SUCCESS) logStringW(hModule, L"UpdateHostOnlyInterfaces: Failed to set REBOOT property, error = 0x%x", hr2); } } else logStringW(hModule, L"UpdateHostOnlyInterfaces: VBoxNetCfgWinUpdateHostOnlyNetworkInterface failed, hr = 0x%x", hr); //in fail case call CreateHostOnlyInterface if (FAILED(hr)) { logStringW(hModule, L"CreateHostOnlyInterface: calling VBoxNetCfgWinCreateHostOnlyNetworkInterface"); hr = VBoxNetCfgWinCreateHostOnlyNetworkInterface(pwszInfPath, bIsFile, &guid, NULL, NULL); logStringW(hModule, L"CreateHostOnlyInterface: VBoxNetCfgWinCreateHostOnlyNetworkInterface returns 0x%x", hr); if (SUCCEEDED(hr)) { ULONG ip = inet_addr("192.168.56.1"); ULONG mask = inet_addr("255.255.255.0"); logStringW(hModule, L"CreateHostOnlyInterface: calling VBoxNetCfgWinEnableStaticIpConfig"); hr = VBoxNetCfgWinEnableStaticIpConfig(&guid, ip, mask); logStringW(hModule, L"CreateHostOnlyInterface: VBoxNetCfgWinEnableStaticIpConfig returns 0x%x", hr); if (FAILED(hr)) logStringW(hModule, L"CreateHostOnlyInterface: VBoxNetCfgWinEnableStaticIpConfig failed, error = 0x%x", hr); } else logStringW(hModule, L"CreateHostOnlyInterface: VBoxNetCfgWinCreateHostOnlyNetworkInterface failed, error = 0x%x", hr); } } if (SUCCEEDED(hr)) logStringW(hModule, L"CreateHostOnlyInterface: Creating host-only interface done"); /* Restore original setup mode. */ logStringW(hModule, L"CreateHostOnlyInterface: Almost done..."); if (bSetupModeInteractive) SetupSetNonInteractiveMode(bSetupModeInteractive); netCfgLoggerDisable(); #endif /* VBOX_WITH_NETFLT */ logStringW(hModule, L"CreateHostOnlyInterface: Returns success (ignoring all failures)"); /* Never fail the install even if we did not succeed. */ return ERROR_SUCCESS; }
UINT __stdcall UpdateHostOnlyInterfaces(MSIHANDLE hModule) { #ifdef VBOX_WITH_NETFLT netCfgLoggerEnable(hModule); logStringW(hModule, L"UpdateHostOnlyInterfaces: Updating all host-only interfaces"); BOOL bSetupModeInteractive = SetupSetNonInteractiveMode(FALSE); WCHAR wszMpInf[MAX_PATH]; DWORD cchMpInf = RT_ELEMENTS(wszMpInf) - sizeof("VBoxNetAdp.inf") - 1; LPCWSTR pwszInfPath = NULL; bool bIsFile = false; UINT uErr = MsiGetPropertyW(hModule, L"CustomActionData", wszMpInf, &cchMpInf); if (uErr == ERROR_SUCCESS) { if (cchMpInf) { logStringW(hModule, L"UpdateHostOnlyInterfaces: NetAdpDir property = %s", wszMpInf); if (wszMpInf[cchMpInf - 1] != L'\\') { wszMpInf[cchMpInf++] = L'\\'; wszMpInf[cchMpInf] = L'\0'; } wcscat(wszMpInf, L"VBoxNetAdp.inf"); pwszInfPath = wszMpInf; bIsFile = true; logStringW(hModule, L"UpdateHostOnlyInterfaces: Resulting INF path = %s", pwszInfPath); DWORD attrFile = GetFileAttributesW(pwszInfPath); if (attrFile == INVALID_FILE_ATTRIBUTES) { DWORD dwErr = GetLastError(); logStringW(hModule, L"UpdateHostOnlyInterfaces: File \"%s\" not found, dwErr=%ld", pwszInfPath, dwErr); } else { logStringW(hModule, L"UpdateHostOnlyInterfaces: File \"%s\" exists", pwszInfPath); BOOL fRebootRequired = FALSE; HRESULT hr = VBoxNetCfgWinUpdateHostOnlyNetworkInterface(pwszInfPath, &fRebootRequired); if (SUCCEEDED(hr)) { if (fRebootRequired) { logStringW(hModule, L"UpdateHostOnlyInterfaces: Reboot required, setting REBOOT property to force"); HRESULT hr2 = MsiSetPropertyW(hModule, L"REBOOT", L"Force"); if (hr2 != ERROR_SUCCESS) logStringW(hModule, L"UpdateHostOnlyInterfaces: Failed to set REBOOT property, error = 0x%x", hr2); } } else logStringW(hModule, L"UpdateHostOnlyInterfaces: VBoxNetCfgWinUpdateHostOnlyNetworkInterface failed, hr = 0x%x", hr); } } else logStringW(hModule, L"UpdateHostOnlyInterfaces: VBox installation path is empty"); } else logStringW(hModule, L"UpdateHostOnlyInterfaces: Unable to retrieve VBox installation path, error = 0x%x", uErr); /* Restore original setup mode. */ if (bSetupModeInteractive) SetupSetNonInteractiveMode(bSetupModeInteractive); netCfgLoggerDisable(); #endif /* VBOX_WITH_NETFLT */ /* Never fail the install even if we did not succeed. */ return ERROR_SUCCESS; }
extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; wchar_t* service= 0; wchar_t* dir= 0; wchar_t installerVersion[MAX_VERSION_PROPERTY_SIZE]; char installDir[MAX_PATH]; DWORD size =MAX_VERSION_PROPERTY_SIZE; int installerMajorVersion, installerMinorVersion, installerPatchVersion; bool upgradableServiceFound=false; hr = WcaInitialize(hInstall, __FUNCTION__); WcaLog(LOGMSG_STANDARD, "Initialized."); if (MsiGetPropertyW(hInstall, L"ProductVersion", installerVersion, &size) != ERROR_SUCCESS) { hr = HRESULT_FROM_WIN32(GetLastError()); ExitOnFailure(hr, "MsiGetPropertyW failed"); } if (swscanf(installerVersion,L"%d.%d.%d", &installerMajorVersion, &installerMinorVersion, &installerPatchVersion) !=3) { assert(FALSE); } size= MAX_PATH; if (MsiGetPropertyA(hInstall,"INSTALLDIR", installDir, &size) != ERROR_SUCCESS) { hr = HRESULT_FROM_WIN32(GetLastError()); ExitOnFailure(hr, "MsiGetPropertyW failed"); } SC_HANDLE scm = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_CONNECT); if (scm == NULL) { hr = HRESULT_FROM_WIN32(GetLastError()); ExitOnFailure(hr,"OpenSCManager failed"); } static BYTE buf[64*1024]; static BYTE config_buffer[8*1024]; DWORD bufsize= sizeof(buf); DWORD bufneed; DWORD num_services; BOOL ok= EnumServicesStatusExW(scm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, buf, bufsize, &bufneed, &num_services, NULL, NULL); if(!ok) { hr = HRESULT_FROM_WIN32(GetLastError()); ExitOnFailure(hr,"EnumServicesStatusEx failed"); } LPENUM_SERVICE_STATUS_PROCESSW info = (LPENUM_SERVICE_STATUS_PROCESSW)buf; int index=-1; for (ULONG i=0; i < num_services; i++) { SC_HANDLE service= OpenServiceW(scm, info[i].lpServiceName, SERVICE_QUERY_CONFIG); if (!service) continue; QUERY_SERVICE_CONFIGW *config= (QUERY_SERVICE_CONFIGW*)(void *)config_buffer; DWORD needed; BOOL ok= QueryServiceConfigW(service, config,sizeof(config_buffer), &needed); CloseServiceHandle(service); if (ok) { 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. */ if(installDir[0] == 0 || strstr(props.mysqld_exe,installDir) == 0) { 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_minor <= installerMinorVersion)) { upgradableServiceFound= true; break; } } } } if(!upgradableServiceFound) { /* Disable optional checkbox at the end of installation */ MsiSetPropertyW(hInstall, L"WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT", L""); MsiSetPropertyW(hInstall, L"WIXUI_EXITDIALOGOPTIONALCHECKBOX",L""); } else { MsiSetPropertyW(hInstall, L"UpgradableServiceFound", L"1"); MsiSetPropertyW(hInstall, L"WIXUI_EXITDIALOGOPTIONALCHECKBOX",L"1"); } LExit: if(scm) CloseServiceHandle(scm); return WcaFinalize(er); }
/* Checks SERVICENAME, PORT and BUFFERSIZE parameters */ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall) { wchar_t ServiceName[MAX_PATH]={0}; wchar_t SkipNetworking[MAX_PATH]={0}; wchar_t QuickConfig[MAX_PATH]={0}; wchar_t Password[MAX_PATH]={0}; wchar_t EscapedPassword[2*MAX_PATH+2]; wchar_t Port[6]; wchar_t BufferPoolSize[16]; DWORD PortLen=6; bool haveInvalidPort=false; const wchar_t *ErrorMsg=0; HRESULT hr= S_OK; UINT er= ERROR_SUCCESS; hr = WcaInitialize(hInstall, __FUNCTION__); ExitOnFailure(hr, "Failed to initialize"); WcaLog(LOGMSG_STANDARD, "Initialized."); DWORD ServiceNameLen = MAX_PATH; 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; } } DWORD PasswordLen= MAX_PATH; MsiGetPropertyW (hInstall, L"PASSWORD", Password, &PasswordLen); EscapeCommandLine(Password, EscapedPassword, sizeof(EscapedPassword)/sizeof(EscapedPassword[0])); MsiSetPropertyW(hInstall,L"ESCAPEDPASSWORD",EscapedPassword); DWORD SkipNetworkingLen= MAX_PATH; MsiGetPropertyW(hInstall, L"SKIPNETWORKING", SkipNetworking, &SkipNetworkingLen); MsiGetPropertyW(hInstall, L"PORT", Port, &PortLen); if(SkipNetworking[0]==0 && Port[0] != 0) { /* Strip spaces */ for(DWORD i=PortLen-1; i > 0; i--) { if(Port[i]== ' ') Port[i] = 0; } 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; } short port = (short)_wtoi(Port); if (!IsPortFree(port)) { ErrorMsg = L"The TCP Port you selected is already in use. " L"Please choose a different port."; goto LExit; } } DWORD QuickConfigLen = MAX_PATH; MsiGetPropertyW (hInstall, L"STDCONFIG", QuickConfig, &QuickConfigLen); if(QuickConfig[0] !=0) { MEMORYSTATUSEX memstatus; memstatus.dwLength =sizeof(memstatus); wchar_t invalidValueMsg[256]; 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; } unsigned long long availableMemory= GetMaxBufferSize(memstatus.ullTotalPhys)/ONE_MB; swprintf_s(invalidValueMsg, L"Invalid buffer pool size. Please use a number between 1 and %llu", availableMemory); if(BufferPoolSizeLen == 0 || BufferPoolSizeLen > 15) { ErrorMsg= invalidValueMsg; goto LExit; } for (DWORD i=0; i < BufferPoolSizeLen && BufferPoolSize[BufferPoolSizeLen]; i++) { if(BufferPoolSize[i]< '0' || BufferPoolSize[i] > '9') { ErrorMsg= invalidValueMsg; goto LExit; } } BufferPoolSize[BufferPoolSizeLen]=0; MsiSetPropertyW(hInstall, L"BUFFERPOOLSIZE", BufferPoolSize); long long sz = _wtoi64(BufferPoolSize); if(sz <= 0 || sz > (long long)availableMemory) { if(sz > 0) { 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 1 and %llu.", availableMemory, availableMemory); } ErrorMsg= invalidValueMsg; goto LExit; } } LExit: MsiSetPropertyW (hInstall, L"WarningText", ErrorMsg); return WcaFinalize(er); }
UINT VBoxSetProperty(MSIHANDLE a_hModule, WCHAR *a_pwszName, WCHAR *a_pwszValue) { return MsiSetPropertyW(a_hModule, a_pwszName, a_pwszValue); }