bool FindJVMInSettings() {
    TCHAR buffer[_MAX_PATH];
    TCHAR copy[_MAX_PATH];

    GetModuleFileName(NULL, buffer, _MAX_PATH);
    std::wstring module(buffer);

    if (LoadString(hInst, IDS_VM_OPTIONS_PATH, buffer, _MAX_PATH)) {
        ExpandEnvironmentStrings(buffer, copy, _MAX_PATH - 1);
        std::wstring path(copy);
        path += L"\\config" + module.substr(module.find_last_of('\\')) + L".jdk";
        FILE *f = _tfopen(path.c_str(), _T("rt"));
        if (!f) return false;

        char line[_MAX_PATH];
        if (!fgets(line, _MAX_PATH, f)) {
            fclose(f);
            return false;
        }

        TrimLine(line);
        fclose(f);

        return FindValidJVM(line);
    }
    return false;
}
bool LocateJVM()
{
	bool result;
	if (FindJVMInEnvVar(LoadStdString(IDS_JDK_ENV_VAR).c_str(), result))
	{
		return result;
	}

	std::string jreDir = GetAdjacentDir("jre");
	if (FindValidJVM(jreDir.c_str()) && Is64BitJRE(jvmPath) == need64BitJRE)
	{
		return true;
	}

	if (FindJVMInRegistry())
	{
		return true;
	}

	if (FindJVMInEnvVar("JAVA_HOME", result))
	{
		return result;
	}

	MessageBoxA(NULL, "No JVM installation found. Please reinstall the product or install a JDK.", "Error Launching IntelliJ Platform", MB_OK);
	return false;
}
bool LocateJVM()
{
	bool result;
	if (FindJVMInEnvVar(LoadStdString(IDS_JDK_ENV_VAR).c_str(), result))
	{
		return result;
	}


        std::vector<std::string> jrePaths;
        if(need64BitJRE) jrePaths.push_back(GetAdjacentDir("jre64"));
        jrePaths.push_back(GetAdjacentDir("jre"));
        for(std::vector<std::string>::iterator it = jrePaths.begin(); it != jrePaths.end(); ++it) {
          if (FindValidJVM((*it).c_str()) && Is64BitJRE(jvmPath) == need64BitJRE)
          {
                  return true;
          }
        }

	if (FindJVMInRegistry())
	{
		return true;
	}

	if (FindJVMInEnvVar("JAVA_HOME", result))
	{
		return result;
	}

	MessageBoxA(NULL, "No JVM installation found. Please reinstall the product or install a JDK.", "Error Launching IntelliJ Platform", MB_OK);
	return false;
}
bool LocateJVM()
{
    bool result;
    if (FindJVMInEnvVar(LoadStdString(IDS_JDK_ENV_VAR).c_str(), result))
    {
        return result;
    }

    if (FindJVMInSettings()) return true;

    std::vector<std::string> jrePaths;
    if(need64BitJRE) jrePaths.push_back(GetAdjacentDir("jre64"));
    jrePaths.push_back(GetAdjacentDir("jre"));
    for(std::vector<std::string>::iterator it = jrePaths.begin(); it != jrePaths.end(); ++it) {
        if (FindValidJVM((*it).c_str()) && Is64BitJRE(jvmPath) == need64BitJRE)
        {
            return true;
        }
    }

    if (FindJVMInEnvVar("JAVA_HOME", result))
    {
        return result;
    }

    if (FindJVMInRegistry())
    {
        return true;
    }

    std::string jvmError;
    jvmError = "No JVM installation found. Please install a " BITS_STR " JDK.\n"
               "If you already have a JDK installed, define a JAVA_HOME variable in\n"
               "Computer > System Properties > System Settings > Environment Variables.";

    if (IsWow64())
    {
        // If WoW64, this means we are running a 32-bit program on 64-bit Windows. This may explain
        // why we couldn't locate the JVM.
        jvmError += "\n\nNOTE: We have detected that you are running a 64-bit version of the "
                    "Windows operating system but are running the 32-bit executable. This "
                    "can prevent you from finding a 64-bit installation of Java. Consider running "
                    "the 64-bit version instead, if this is the problem you're encountering.";
    }

    std::string error = LoadStdString(IDS_ERROR_LAUNCHING_APP);
    MessageBoxA(NULL, jvmError.c_str(),  error.c_str(), MB_OK);
    return false;
}
bool FindJVMInRegistryKey(const char* key, bool wow64_32)
{
    HKEY hKey;
    int flags = KEY_READ;
    if (wow64_32) flags |= KEY_WOW64_32KEY;
    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey) != ERROR_SUCCESS) return false;
    char javaHome[_MAX_PATH];
    DWORD javaHomeSize = _MAX_PATH - 1;
    bool success = false;
    if (RegQueryValueExA(hKey, "JavaHome", NULL, NULL, (LPBYTE)javaHome, &javaHomeSize) == ERROR_SUCCESS)
    {
        success = FindValidJVM(javaHome);
    }
    RegCloseKey(hKey);
    return success;
}
bool FindJVMInEnvVar(const char* envVarName, bool& result)
{
	char envVarValue[_MAX_PATH];
	if (GetEnvironmentVariableA(envVarName, envVarValue, _MAX_PATH-1))
	{
		if (FindValidJVM(envVarValue))
		{
			if (Is64BitJRE(jvmPath) != need64BitJRE) return false;
			result = true;
		}
		else
		{
			char buf[_MAX_PATH];
			sprintf_s(buf, "The environment variable %s (with the value of %s) does not point to a valid JVM installation.",
				envVarName, envVarValue);
			MessageBoxA(NULL, buf, "Error Launching IntelliJ Platform", MB_OK);
			result = false;
		}
		return true;
	}
	return false;
}
bool FindJVMInEnvVar(const char* envVarName, bool& result)
{
    char envVarValue[_MAX_PATH];
    if (GetEnvironmentVariableA(envVarName, envVarValue, _MAX_PATH - 1))
    {
        if (FindValidJVM(envVarValue))
        {
            if (Is64BitJRE(jvmPath) != need64BitJRE) return false;
            result = true;
        }
        else
        {
            char buf[_MAX_PATH];
            sprintf_s(buf, "The environment variable %s (with the value of %s) does not point to a valid JVM installation.",
                      envVarName, envVarValue);
            std::string error = LoadStdString(IDS_ERROR_LAUNCHING_APP);
            MessageBoxA(NULL, buf, error.c_str(), MB_OK);
            result = false;
        }
        return true;
    }
    return false;
}