diff options
Diffstat (limited to 'launcher/java/JavaUtils.cpp')
| -rw-r--r-- | launcher/java/JavaUtils.cpp | 155 | 
1 files changed, 86 insertions, 69 deletions
| diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp index 24a1556e..2b19fca0 100644 --- a/launcher/java/JavaUtils.cpp +++ b/launcher/java/JavaUtils.cpp @@ -1,16 +1,36 @@ -/* Copyright 2013-2021 MultiMC Contributors +// SPDX-License-Identifier: GPL-3.0-only +/* + *  PolyMC - Minecraft Launcher + *  Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>   * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + *  This program is free software: you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation, version 3.   * - *     http://www.apache.org/licenses/LICENSE-2.0 + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details.   * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + *  You should have received a copy of the GNU General Public License + *  along with this program.  If not, see <https://www.gnu.org/licenses/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + *      Copyright 2013-2021 MultiMC Contributors + * + *      Licensed under the Apache License, Version 2.0 (the "License"); + *      you may not use this file except in compliance with the License. + *      You may obtain a copy of the License at + * + *          http://www.apache.org/licenses/LICENSE-2.0 + * + *      Unless required by applicable law or agreed to in writing, software + *      distributed under the License is distributed on an "AS IS" BASIS, + *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + *      See the License for the specific language governing permissions and + *      limitations under the License.   */  #include <QStringList> @@ -32,25 +52,24 @@ JavaUtils::JavaUtils()  {  } -#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) -static QString processLD_LIBRARY_PATH(const QString & LD_LIBRARY_PATH) +QString stripVariableEntries(QString name, QString target, QString remove)  { -    QDir mmcBin(QCoreApplication::applicationDirPath()); -    auto items = LD_LIBRARY_PATH.split(':'); -    QStringList final; -    for(auto & item: items) -    { -        QDir test(item); -        if(test == mmcBin) -        { -            qDebug() << "Env:LD_LIBRARY_PATH ignoring path" << item; -            continue; -        } -        final.append(item); +    char delimiter = ':'; +#ifdef Q_OS_WIN32 +    delimiter = ';'; +#endif + +    auto targetItems = target.split(delimiter); +    auto toRemove = remove.split(delimiter); + +    for (QString item : toRemove) { +        bool removed = targetItems.removeOne(item); +        if (!removed) +            qWarning() << "Entry" << item +                << "could not be stripped from variable" << name;      } -    return final.join(':'); +    return targetItems.join(delimiter);  } -#endif  QProcessEnvironment CleanEnviroment()  { @@ -69,6 +88,16 @@ QProcessEnvironment CleanEnviroment()          "JAVA_OPTIONS",          "JAVA_TOOL_OPTIONS"      }; + +    QStringList stripped = +    { +#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD) +        "LD_LIBRARY_PATH", +        "LD_PRELOAD", +#endif +        "QT_PLUGIN_PATH", +        "QT_FONTPATH" +    };      for(auto key: rawenv.keys())      {          auto value = rawenv.value(key); @@ -78,19 +107,22 @@ QProcessEnvironment CleanEnviroment()              qDebug() << "Env: ignoring" << key << value;              continue;          } -        // filter PolyMC-related things -        if(key.startsWith("QT_")) + +        // These are used to strip the original variables +        // If there is "LD_LIBRARY_PATH" and "LAUNCHER_LD_LIBRARY_PATH", we want to +        // remove all values in "LAUNCHER_LD_LIBRARY_PATH" from "LD_LIBRARY_PATH" +        if(key.startsWith("LAUNCHER_"))          {              qDebug() << "Env: ignoring" << key << value;              continue;          } -#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) -        // Do not pass LD_* variables to java. They were intended for PolyMC -        if(key.startsWith("LD_")) +        if(stripped.contains(key))          { -            qDebug() << "Env: ignoring" << key << value; -            continue; +            QString newValue = stripVariableEntries(key, value, rawenv.value("LAUNCHER_" + key)); + +            qDebug() << "Env: stripped" << key << value << "to" << newValue;          } +#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)          // Strip IBus          // IBus is a Linux IME framework. For some reason, it breaks MC?          if (key == "XMODIFIERS" && value.contains(IBUS)) @@ -99,22 +131,12 @@ QProcessEnvironment CleanEnviroment()              value.replace(IBUS, "");              qDebug() << "Env: stripped" << IBUS << "from" << save << ":" << value;          } -        if(key == "GAME_PRELOAD") -        { -            env.insert("LD_PRELOAD", value); -            continue; -        } -        if(key == "GAME_LIBRARY_PATH") -        { -            env.insert("LD_LIBRARY_PATH", processLD_LIBRARY_PATH(value)); -            continue; -        }  #endif          // qDebug() << "Env: " << key << value;          env.insert(key, value);      }  #ifdef Q_OS_LINUX -    // HACK: Workaround for QTBUG42500 +    // HACK: Workaround for QTBUG-42500      if(!env.contains("LD_LIBRARY_PATH"))      {          env.insert("LD_LIBRARY_PATH", ""); @@ -177,25 +199,17 @@ QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString          archType = "32";      HKEY jreKey; -    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName.toStdString().c_str(), 0, +    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName.toStdWString().c_str(), 0,                        KEY_READ | keyType | KEY_ENUMERATE_SUB_KEYS, &jreKey) == ERROR_SUCCESS)      {          // Read the current type version from the registry.          // This will be used to find any key that contains the JavaHome value. -        char *value = new char[0]; -        DWORD valueSz = 0; -        if (RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz) == -            ERROR_MORE_DATA) -        { -            value = new char[valueSz]; -            RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz); -        } -        TCHAR subKeyName[255]; +        WCHAR subKeyName[255];          DWORD subKeyNameSize, numSubKeys, retCode;          // Get the number of subkeys -        RegQueryInfoKey(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, +        RegQueryInfoKeyW(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL,                          NULL, NULL);          // Iterate until RegEnumKeyEx fails @@ -204,34 +218,37 @@ QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString              for (DWORD i = 0; i < numSubKeys; i++)              {                  subKeyNameSize = 255; -                retCode = RegEnumKeyEx(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL, -                                       NULL); +                retCode = RegEnumKeyExW(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL, +                                        NULL); +                QString newSubkeyName = QString::fromWCharArray(subKeyName);                  if (retCode == ERROR_SUCCESS)                  {                      // Now open the registry key for the version that we just got. -                    QString newKeyName = keyName + "\\" + subKeyName + subkeySuffix; +                    QString newKeyName = keyName + "\\" + newSubkeyName + subkeySuffix;                      HKEY newKey; -                    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, newKeyName.toStdString().c_str(), 0, -                                     KEY_READ | KEY_WOW64_64KEY, &newKey) == ERROR_SUCCESS) +                    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, newKeyName.toStdWString().c_str(), 0, +                                      KEY_READ | KEY_WOW64_64KEY, &newKey) == ERROR_SUCCESS)                      {                          // Read the JavaHome value to find where Java is installed. -                        value = new char[0]; -                        valueSz = 0; -                        if (RegQueryValueEx(newKey, keyJavaDir.toStdString().c_str(), NULL, NULL, (BYTE *)value, -                                            &valueSz) == ERROR_MORE_DATA) +                        DWORD valueSz = 0; +                        if (RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, NULL, +                                             &valueSz) == ERROR_SUCCESS)                          { -                            value = new char[valueSz]; -                            RegQueryValueEx(newKey, keyJavaDir.toStdString().c_str(), NULL, NULL, (BYTE *)value, -                                            &valueSz); +                            WCHAR *value = new WCHAR[valueSz]; +                            RegQueryValueExW(newKey, keyJavaDir.toStdWString().c_str(), NULL, NULL, (BYTE *)value, +                                             &valueSz); + +                            QString newValue = QString::fromWCharArray(value); +                            delete [] value;                              // Now, we construct the version object and add it to the list.                              JavaInstallPtr javaVersion(new JavaInstall()); -                            javaVersion->id = subKeyName; +                            javaVersion->id = newSubkeyName;                              javaVersion->arch = archType;                              javaVersion->path = -                                QDir(FS::PathCombine(value, "bin")).absoluteFilePath("javaw.exe"); +                                QDir(FS::PathCombine(newValue, "bin")).absoluteFilePath("javaw.exe");                              javas.append(javaVersion);                          } | 
