diff --git a/native/WinLauncher/.gitignore b/native/WinLauncher/.gitignore new file mode 100644 index 000000000000..c8003381da80 --- /dev/null +++ b/native/WinLauncher/.gitignore @@ -0,0 +1,6 @@ +*.opensdf +*.suo +*.sdf +Debug +Release +ipch diff --git a/native/WinLauncher/WinLauncher.sln b/native/WinLauncher/WinLauncher.sln new file mode 100644 index 000000000000..e1e3593979a2 --- /dev/null +++ b/native/WinLauncher/WinLauncher.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinLauncher", "WinLauncher\WinLauncher.vcxproj", "{B4C8D7ED-DA7A-4CD7-AEE6-3373A95FDD40}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B4C8D7ED-DA7A-4CD7-AEE6-3373A95FDD40}.Debug|Win32.ActiveCfg = Debug|Win32 + {B4C8D7ED-DA7A-4CD7-AEE6-3373A95FDD40}.Debug|Win32.Build.0 = Debug|Win32 + {B4C8D7ED-DA7A-4CD7-AEE6-3373A95FDD40}.Release|Win32.ActiveCfg = Release|Win32 + {B4C8D7ED-DA7A-4CD7-AEE6-3373A95FDD40}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/native/WinLauncher/WinLauncher/.gitignore b/native/WinLauncher/WinLauncher/.gitignore new file mode 100644 index 000000000000..febd967e9adb --- /dev/null +++ b/native/WinLauncher/WinLauncher/.gitignore @@ -0,0 +1,3 @@ +Debug +*.aps +*.vcxproj.user diff --git a/native/WinLauncher/WinLauncher/WinLauncher.cpp b/native/WinLauncher/WinLauncher/WinLauncher.cpp new file mode 100644 index 000000000000..d74e65f1c00d --- /dev/null +++ b/native/WinLauncher/WinLauncher/WinLauncher.cpp @@ -0,0 +1,312 @@ +/* +* Copyright 2000-2013 JetBrains s.r.o. +* +* 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 "stdafx.h" +#include "WinLauncher.h" + +typedef JNIIMPORT jint (JNICALL *JNI_createJavaVM)(JavaVM **pvm, JNIEnv **env, void *args); + +HINSTANCE hInst; // current instance +char jvmPath[_MAX_PATH]; +JavaVMOption* vmOptions = NULL; +int vmOptionCount = 0; +bool bServerJVM = false; +HMODULE hJVM = NULL; +JNI_createJavaVM pCreateJavaVM = NULL; +JavaVM* jvm = NULL; +JNIEnv* env = NULL; + +bool IsValidJRE(char* path) +{ + char dllPath[_MAX_PATH]; + strcpy_s(dllPath, path); + strcat_s(dllPath, "\\bin\\client\\jvm.dll"); + return GetFileAttributesA(dllPath) != INVALID_FILE_ATTRIBUTES; +} + +bool FindValidJVM(char* path) +{ + if (IsValidJRE(path)) + { + strcpy_s(jvmPath, _MAX_PATH-1, path); + return true; + } + char jrePath[_MAX_PATH]; + strcpy_s(jrePath, path); + if (jrePath[strlen(jrePath)-1] != '\\') + { + strcat_s(jrePath, "\\"); + } + strcat_s(jrePath, _MAX_PATH-1, "jre"); + if (IsValidJRE(jrePath)) + { + strcpy_s(jvmPath, jrePath); + return true; + } + return false; +} + +bool LocateJVM() +{ + char envVarName[_MAX_PATH]; + if (LoadStringA(hInst, IDS_JDK_ENV_VAR, envVarName, _MAX_PATH-1)) + { + char envVarValue[_MAX_PATH]; + if (GetEnvironmentVariableA(envVarName, envVarValue, _MAX_PATH-1)) + { + if (FindValidJVM(envVarValue)) + { + return 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", + envVarValue, jvmPath); + MessageBoxA(NULL, buf, "Error Launching IntelliJ Platform", MB_OK); + return false; + } + } + } + return false; +} + +void TrimLine(char* line) +{ + char *p = line + strlen(line) - 1; + if (p >= line && *p == '\n') + { + *p-- = '\0'; + } + while(p >= line && (*p == ' ' || *p == '\t')) + { + *p-- = 0; + } +} + +bool LoadVMOptionsFile(const TCHAR* path, std::vector& vmOptionLines) +{ + FILE *f = _tfopen(path, _T("rt")); + if (!f) return false; + + char line[_MAX_PATH]; + while(fgets(line, _MAX_PATH-1, f)) + { + TrimLine(line); + if (strcmp(line, "-server") == 0) + { + bServerJVM = true; + } + else if (strlen(line) > 0) + { + vmOptionLines.push_back(line); + } + } + fclose(f); + + return true; +} + +std::string FindToolsJar() +{ + std::string toolsJarPath = jvmPath; + size_t lastSlash = toolsJarPath.rfind('\\'); + if (lastSlash != std::string::npos) + { + toolsJarPath = toolsJarPath.substr(0, lastSlash+1); + toolsJarPath += "lib\\tools.jar"; + if (GetFileAttributesA(toolsJarPath.c_str()) != INVALID_FILE_ATTRIBUTES) + { + return toolsJarPath; + } + } + return ""; +} + +std::string BuildClassPath() +{ + char libDir[_MAX_PATH]; + GetCurrentDirectoryA(_MAX_PATH-1, libDir); + char* lastSlash = strrchr(libDir, '\\'); + strcpy(lastSlash+1, "lib\\"); + if (GetFileAttributesA(libDir) == INVALID_FILE_ATTRIBUTES) + { + return ""; + } + + char classpathLibs[_MAX_PATH]; + std::string result; + LoadStringA(hInst, IDS_CLASSPATH_LIBS, classpathLibs, _MAX_PATH-1); + char *pJarName = classpathLibs; + while(pJarName) + { + char *pNextJarName = strchr(pJarName, ';'); + if (pNextJarName) + { + *pNextJarName++ = '\0'; + } + if (result.size() > 0) + { + result += ";"; + } + result += libDir; + result += pJarName; + pJarName = pNextJarName; + } + + std::string toolsJar = FindToolsJar(); + if (toolsJar.size() > 0) + { + result += ";"; + result += toolsJar; + } + + return result; +} + +bool LoadVMOptions() +{ + TCHAR optionsFileName[_MAX_PATH]; + if (LoadString(hInst, IDS_VM_OPTIONS_PATH, optionsFileName, _MAX_PATH-1)) + { + TCHAR optionsFileNameExpanded[_MAX_PATH]; + ExpandEnvironmentStrings(optionsFileName, optionsFileNameExpanded, _MAX_PATH-1); + + std::vector vmOptionLines; + if (LoadVMOptionsFile(optionsFileNameExpanded, vmOptionLines)) + { + std::string classPath = BuildClassPath(); + if (classPath.size() == 0) return false; + std::string classPathArg("-Djava.class.path="); + classPathArg += classPath; + vmOptionLines.push_back(classPathArg); + + vmOptionCount = vmOptionLines.size(); + vmOptions = (JavaVMOption*) malloc(vmOptionCount * sizeof(JavaVMOption)); + for(int i=0; iFindClass(mainClassName); + if (!mainClass) + { + char buf[_MAX_PATH]; + sprintf(buf, "Could not find main class %s", mainClassName); + MessageBoxA(NULL, buf, "Error Launching IntelliJ Platform", MB_OK); + return false; + } + + jclass stringClass = env->FindClass("java/lang/String"); + jobjectArray args = env->NewObjectArray(0, stringClass, NULL); + jmethodID mainMethod = env->GetStaticMethodID(mainClass, "main", "([Ljava/lang/String;)V"); + if (!mainClass) + { + MessageBoxA(NULL, "Could not find main method", "Error Launching IntelliJ Platform", MB_OK); + return false; + } + + env->CallStaticVoidMethod(mainClass, mainMethod, args); + + return true; +} + +int APIENTRY _tWinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPTSTR lpCmdLine, + int nCmdShow) +{ + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpCmdLine); + + hInst = hInstance; + + if (!LocateJVM()) return 1; + if (!LoadVMOptions()) return 1; + if (!LoadJVMLibrary()) return 1; + if (!CreateJVM()) return 1; + if (!RunMainClass()) return 1; + + jvm->DestroyJavaVM(); + + return 0; +} + + + diff --git a/native/WinLauncher/WinLauncher/WinLauncher.h b/native/WinLauncher/WinLauncher/WinLauncher.h new file mode 100644 index 000000000000..d00d47e78850 --- /dev/null +++ b/native/WinLauncher/WinLauncher/WinLauncher.h @@ -0,0 +1,3 @@ +#pragma once + +#include "resource.h" diff --git a/native/WinLauncher/WinLauncher/WinLauncher.ico b/native/WinLauncher/WinLauncher/WinLauncher.ico new file mode 100644 index 000000000000..d551aa3aaf80 Binary files /dev/null and b/native/WinLauncher/WinLauncher/WinLauncher.ico differ diff --git a/native/WinLauncher/WinLauncher/WinLauncher.rc b/native/WinLauncher/WinLauncher/WinLauncher.rc new file mode 100644 index 000000000000..a421f77dbf83 Binary files /dev/null and b/native/WinLauncher/WinLauncher/WinLauncher.rc differ diff --git a/native/WinLauncher/WinLauncher/WinLauncher.vcxproj b/native/WinLauncher/WinLauncher/WinLauncher.vcxproj new file mode 100644 index 000000000000..36d51ef6a27a --- /dev/null +++ b/native/WinLauncher/WinLauncher/WinLauncher.vcxproj @@ -0,0 +1,100 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {B4C8D7ED-DA7A-4CD7-AEE6-3373A95FDD40} + Win32Proj + WinLauncher + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + C:\Java\jdk1.6.0_37\include;C:\Java\jdk1.6.0_37\include\win32;$(IncludePath) + + + false + C:\Java\jdk1.6.0_37\include;C:\Java\jdk1.6.0_37\include\win32;$(IncludePath) + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + \ No newline at end of file diff --git a/native/WinLauncher/WinLauncher/WinLauncher.vcxproj.filters b/native/WinLauncher/WinLauncher/WinLauncher.vcxproj.filters new file mode 100644 index 000000000000..ff46c65935f1 --- /dev/null +++ b/native/WinLauncher/WinLauncher/WinLauncher.vcxproj.filters @@ -0,0 +1,53 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + Resource Files + + + Resource Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/native/WinLauncher/WinLauncher/resource.h b/native/WinLauncher/WinLauncher/resource.h new file mode 100644 index 000000000000..520b2666dfda Binary files /dev/null and b/native/WinLauncher/WinLauncher/resource.h differ diff --git a/native/WinLauncher/WinLauncher/small.ico b/native/WinLauncher/WinLauncher/small.ico new file mode 100644 index 000000000000..d551aa3aaf80 Binary files /dev/null and b/native/WinLauncher/WinLauncher/small.ico differ diff --git a/native/WinLauncher/WinLauncher/stdafx.cpp b/native/WinLauncher/WinLauncher/stdafx.cpp new file mode 100644 index 000000000000..43d93c75583b --- /dev/null +++ b/native/WinLauncher/WinLauncher/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// WinLauncher.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/native/WinLauncher/WinLauncher/stdafx.h b/native/WinLauncher/WinLauncher/stdafx.h new file mode 100644 index 000000000000..c82f7764d68e --- /dev/null +++ b/native/WinLauncher/WinLauncher/stdafx.h @@ -0,0 +1,25 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include + +// C RunTime Header Files +#include +#include +#include +#include +#include + +#include + +#include + +// TODO: reference additional headers your program requires here diff --git a/native/WinLauncher/WinLauncher/targetver.h b/native/WinLauncher/WinLauncher/targetver.h new file mode 100644 index 000000000000..87c0086de751 --- /dev/null +++ b/native/WinLauncher/WinLauncher/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include