summaryrefslogtreecommitdiff
path: root/native/WinLauncher/WinLauncher/WinLauncher.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'native/WinLauncher/WinLauncher/WinLauncher.cpp')
-rw-r--r--native/WinLauncher/WinLauncher/WinLauncher.cpp199
1 files changed, 116 insertions, 83 deletions
diff --git a/native/WinLauncher/WinLauncher/WinLauncher.cpp b/native/WinLauncher/WinLauncher/WinLauncher.cpp
index 8d5ff13a46ed..a934a88da3d0 100644
--- a/native/WinLauncher/WinLauncher/WinLauncher.cpp
+++ b/native/WinLauncher/WinLauncher/WinLauncher.cpp
@@ -17,7 +17,7 @@
#include "stdafx.h"
#include "WinLauncher.h"
-typedef JNIIMPORT jint (JNICALL *JNI_createJavaVM)(JavaVM **pvm, JNIEnv **env, void *args);
+typedef JNIIMPORT jint(JNICALL *JNI_createJavaVM)(JavaVM **pvm, JNIEnv **env, void *args);
HINSTANCE hInst; // current instance
char jvmPath[_MAX_PATH];
@@ -45,7 +45,7 @@ std::string LoadStdString(int id)
{
wchar_t *buf = NULL;
int len = LoadStringW(hInst, id, reinterpret_cast<LPWSTR>(&buf), 0);
- if (len)
+ if (len)
{
int cbANSI = WideCharToMultiByte(CP_ACP, 0, buf, len, NULL, 0, NULL, NULL);
char* ansiBuf = new char[cbANSI];
@@ -65,7 +65,7 @@ bool FileExists(const std::string& path)
bool IsValidJRE(const char* path)
{
std::string dllPath(path);
- if (dllPath[dllPath.size()-1] != '\\')
+ if (dllPath[dllPath.size() - 1] != '\\')
{
dllPath += "\\";
}
@@ -83,16 +83,16 @@ bool FindValidJVM(const char* path)
{
if (IsValidJRE(path))
{
- strcpy_s(jvmPath, _MAX_PATH-1, path);
+ strcpy_s(jvmPath, _MAX_PATH - 1, path);
return true;
}
char jrePath[_MAX_PATH];
strcpy_s(jrePath, path);
- if (jrePath[strlen(jrePath)-1] != '\\')
+ if (jrePath[strlen(jrePath) - 1] != '\\')
{
strcat_s(jrePath, "\\");
}
- strcat_s(jrePath, _MAX_PATH-1, "jre");
+ strcat_s(jrePath, _MAX_PATH - 1, "jre");
if (IsValidJRE(jrePath))
{
strcpy_s(jvmPath, jrePath);
@@ -104,13 +104,13 @@ bool FindValidJVM(const char* path)
std::string GetAdjacentDir(const char* suffix)
{
char libDir[_MAX_PATH];
- GetModuleFileNameA(NULL, libDir, _MAX_PATH-1);
+ GetModuleFileNameA(NULL, libDir, _MAX_PATH - 1);
char* lastSlash = strrchr(libDir, '\\');
if (!lastSlash) return "";
*lastSlash = '\0';
lastSlash = strrchr(libDir, '\\');
if (!lastSlash) return "";
- strcpy(lastSlash+1, suffix);
+ strcpy(lastSlash + 1, suffix);
strcat_s(libDir, "\\");
return std::string(libDir);
}
@@ -118,7 +118,7 @@ std::string GetAdjacentDir(const char* suffix)
bool FindJVMInEnvVar(const char* envVarName, bool& result)
{
char envVarValue[_MAX_PATH];
- if (GetEnvironmentVariableA(envVarName, envVarValue, _MAX_PATH-1))
+ if (GetEnvironmentVariableA(envVarName, envVarValue, _MAX_PATH - 1))
{
if (FindValidJVM(envVarValue))
{
@@ -145,9 +145,9 @@ bool FindJVMInRegistryKey(const char* key, bool wow64_32)
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;
+ DWORD javaHomeSize = _MAX_PATH - 1;
bool success = false;
- if (RegQueryValueExA(hKey, "JavaHome", NULL, NULL, (LPBYTE) javaHome, &javaHomeSize) == ERROR_SUCCESS)
+ if (RegQueryValueExA(hKey, "JavaHome", NULL, NULL, (LPBYTE)javaHome, &javaHomeSize) == ERROR_SUCCESS)
{
success = FindValidJVM(javaHome);
}
@@ -157,7 +157,7 @@ bool FindJVMInRegistryKey(const char* key, bool wow64_32)
bool FindJVMInRegistryWithVersion(const char* version, bool wow64_32)
{
- const char* keyName = LoadStdString(IDS_JDK_ONLY) == std::string("true")
+ const char* keyName = LoadStdString(IDS_JDK_ONLY) == std::string("true")
? "Java Development Kit"
: "Java Runtime Environment";
@@ -217,7 +217,7 @@ void TrimLine(char* line)
{
*p-- = '\0';
}
- while(p >= line && (*p == ' ' || *p == '\t'))
+ while (p >= line && (*p == ' ' || *p == '\t'))
{
*p-- = '\0';
}
@@ -227,9 +227,9 @@ bool LoadVMOptionsFile(const TCHAR* path, std::vector<std::string>& vmOptionLine
{
FILE *f = _tfopen(path, _T("rt"));
if (!f) return false;
-
+
char line[_MAX_PATH];
- while(fgets(line, _MAX_PATH-1, f))
+ while (fgets(line, _MAX_PATH - 1, f))
{
TrimLine(line);
if (line[0] == '#') continue;
@@ -253,7 +253,7 @@ std::string FindToolsJar()
size_t lastSlash = toolsJarPath.rfind('\\');
if (lastSlash != std::string::npos)
{
- toolsJarPath = toolsJarPath.substr(0, lastSlash+1) + "lib\\tools.jar";
+ toolsJarPath = toolsJarPath.substr(0, lastSlash + 1) + "lib\\tools.jar";
if (FileExists(toolsJarPath))
{
return toolsJarPath;
@@ -272,7 +272,7 @@ std::string CollectLibJars(const std::string& jarList)
std::string result;
int pos = 0;
- while(pos < jarList.size())
+ while (pos < jarList.size())
{
int delimiterPos = jarList.find(';', pos);
if (delimiterPos == std::string::npos)
@@ -284,8 +284,8 @@ std::string CollectLibJars(const std::string& jarList)
result += ";";
}
result += libDir;
- result += jarList.substr(pos, delimiterPos-pos);
- pos = delimiterPos+1;
+ result += jarList.substr(pos, delimiterPos - pos);
+ pos = delimiterPos + 1;
}
return result;
}
@@ -324,17 +324,17 @@ bool AddClassPathOptions(std::vector<std::string>& vmOptionLines)
void AddPredefinedVMOptions(std::vector<std::string>& vmOptionLines)
{
std::string vmOptions = LoadStdString(IDS_VM_OPTIONS);
- while(vmOptions.size() > 0)
+ while (vmOptions.size() > 0)
{
int pos = vmOptions.find(' ');
if (pos == std::string::npos) pos = vmOptions.size();
vmOptionLines.push_back(vmOptions.substr(0, pos));
- while(pos < vmOptions.size() && vmOptions[pos] == ' ') pos++;
+ while (pos < vmOptions.size() && vmOptions[pos] == ' ') pos++;
vmOptions = vmOptions.substr(pos);
}
char ideaProperties[_MAX_PATH];
- if (GetEnvironmentVariableA("IDEA_PROPERTIES", ideaProperties, _MAX_PATH-1))
+ if (GetEnvironmentVariableA("IDEA_PROPERTIES", ideaProperties, _MAX_PATH - 1))
{
vmOptionLines.push_back(std::string("-Didea.properties.file=") + ideaProperties);
}
@@ -343,17 +343,17 @@ void AddPredefinedVMOptions(std::vector<std::string>& vmOptionLines)
bool LoadVMOptions()
{
TCHAR optionsFileName[_MAX_PATH];
- if (LoadString(hInst, IDS_VM_OPTIONS_PATH, optionsFileName, _MAX_PATH-1))
+ if (LoadString(hInst, IDS_VM_OPTIONS_PATH, optionsFileName, _MAX_PATH - 1))
{
TCHAR fullOptionsFileName[_MAX_PATH];
- ExpandEnvironmentStrings(optionsFileName, fullOptionsFileName, _MAX_PATH-1);
-
+ ExpandEnvironmentStrings(optionsFileName, fullOptionsFileName, _MAX_PATH - 1);
+
if (GetFileAttributes(fullOptionsFileName) == INVALID_FILE_ATTRIBUTES)
{
- GetModuleFileName(NULL, fullOptionsFileName, _MAX_PATH-1);
+ GetModuleFileName(NULL, fullOptionsFileName, _MAX_PATH - 1);
_tcscat_s(fullOptionsFileName, _T(".vmoptions"));
}
-
+
std::vector<std::string> vmOptionLines;
if (LoadVMOptionsFile(fullOptionsFileName, vmOptionLines))
{
@@ -361,8 +361,8 @@ bool LoadVMOptions()
AddPredefinedVMOptions(vmOptionLines);
vmOptionCount = vmOptionLines.size();
- vmOptions = (JavaVMOption*) malloc(vmOptionCount * sizeof(JavaVMOption));
- for(int i=0; i<vmOptionLines.size(); i++)
+ vmOptions = (JavaVMOption*)malloc(vmOptionCount * sizeof(JavaVMOption));
+ for (int i = 0; i < vmOptionLines.size(); i++)
{
vmOptions[i].optionString = _strdup(vmOptionLines[i].c_str());
vmOptions[i].extraInfo = 0;
@@ -394,7 +394,7 @@ bool LoadJVMLibrary()
hJVM = LoadLibraryA(dllName.c_str());
if (hJVM)
{
- pCreateJavaVM = (JNI_createJavaVM) GetProcAddress(hJVM, "JNI_CreateJavaVM");
+ pCreateJavaVM = (JNI_createJavaVM)GetProcAddress(hJVM, "JNI_CreateJavaVM");
}
if (!pCreateJavaVM)
{
@@ -416,7 +416,7 @@ bool CreateJVM()
int result = pCreateJavaVM(&jvm, &env, &initArgs);
- for(int i=0; i<vmOptionCount; i++)
+ for (int i = 0; i < vmOptionCount; i++)
{
free(vmOptions[i].optionString);
}
@@ -438,11 +438,11 @@ jobjectArray PrepareCommandLine()
int numArgs;
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &numArgs);
jclass stringClass = env->FindClass("java/lang/String");
- jobjectArray args = env->NewObjectArray(numArgs-1, stringClass, NULL);
- for(int i=1; i<numArgs; i++)
+ jobjectArray args = env->NewObjectArray(numArgs - 1, stringClass, NULL);
+ for (int i = 1; i < numArgs; i++)
{
const wchar_t* arg = argv[i];
- env->SetObjectArrayElement(args, i-1, env->NewString((const jchar *) arg, wcslen(argv[i])));
+ env->SetObjectArrayElement(args, i - 1, env->NewString((const jchar *)arg, wcslen(argv[i])));
}
return args;
}
@@ -484,7 +484,7 @@ void CallCommandLineProcessor(const std::wstring& curDir, const std::wstring& ar
attachArgs.version = JNI_VERSION_1_2;
attachArgs.name = "WinLauncher external command processing thread";
attachArgs.group = NULL;
- jvm->AttachCurrentThread((void**) &env, &attachArgs);
+ jvm->AttachCurrentThread((void**)&env, &attachArgs);
std::string processorClassName = LoadStdString(IDS_COMMAND_LINE_PROCESSOR_CLASS);
jclass processorClass = env->FindClass(processorClassName.c_str());
@@ -493,8 +493,8 @@ void CallCommandLineProcessor(const std::wstring& curDir, const std::wstring& ar
jmethodID processMethodID = env->GetStaticMethodID(processorClass, "processWindowsLauncherCommandLine", "(Ljava/lang/String;Ljava/lang/String;)V");
if (processMethodID)
{
- jstring jCurDir = env->NewString((const jchar *) curDir.c_str(), curDir.size());
- jstring jArgs = env->NewString((const jchar *) args.c_str(), args.size());
+ jstring jCurDir = env->NewString((const jchar *)curDir.c_str(), curDir.size());
+ jstring jArgs = env->NewString((const jchar *)args.c_str(), args.size());
env->CallStaticVoidMethod(processorClass, processMethodID, jCurDir, jArgs);
jthrowable exc = env->ExceptionOccurred();
if (exc)
@@ -509,7 +509,7 @@ void CallCommandLineProcessor(const std::wstring& curDir, const std::wstring& ar
DWORD WINAPI SingleInstanceThread(LPVOID args)
{
- while(true)
+ while (true)
{
WaitForSingleObject(hEvent, INFINITE);
if (terminating) break;
@@ -521,7 +521,7 @@ DWORD WINAPI SingleInstanceThread(LPVOID args)
if (pos >= 0)
{
std::wstring curDir = command.substr(0, pos);
- std::wstring args = command.substr(pos+1);
+ std::wstring args = command.substr(pos + 1);
CallCommandLineProcessor(curDir, args);
}
@@ -534,7 +534,7 @@ DWORD WINAPI SingleInstanceThread(LPVOID args)
void SendCommandLineToFirstInstance()
{
wchar_t curDir[_MAX_PATH];
- GetCurrentDirectoryW(_MAX_PATH-1, curDir);
+ GetCurrentDirectoryW(_MAX_PATH - 1, curDir);
std::wstring command(curDir);
command += _T("\n");
command += GetCommandLineW();
@@ -542,17 +542,17 @@ void SendCommandLineToFirstInstance()
void *view = MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (view)
{
- memcpy(view, command.c_str(), (command.size()+1) * sizeof(wchar_t));
+ memcpy(view, command.c_str(), (command.size() + 1) * sizeof(wchar_t));
UnmapViewOfFile(view);
}
- SetEvent(hEvent);
+ SetEvent(hEvent);
}
bool CheckSingleInstance()
{
char moduleFileName[_MAX_PATH];
- GetModuleFileNameA(NULL, moduleFileName, _MAX_PATH-1);
- for(char *p = moduleFileName; *p; p++)
+ GetModuleFileNameA(NULL, moduleFileName, _MAX_PATH - 1);
+ for (char *p = moduleFileName; *p; p++)
{
if (*p == ':' || *p == '\\') *p = '_';
}
@@ -564,7 +564,7 @@ bool CheckSingleInstance()
hFileMapping = OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, mappingName.c_str());
if (!hFileMapping)
{
- hFileMapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, FILE_MAPPING_SIZE,
+ hFileMapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, FILE_MAPPING_SIZE,
mappingName.c_str());
return true;
}
@@ -579,11 +579,11 @@ bool CheckSingleInstance()
void DrawSplashImage(HWND hWnd)
{
- HBITMAP hSplashBitmap = (HBITMAP) GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ HBITMAP hSplashBitmap = (HBITMAP)GetWindowLongPtr(hWnd, GWLP_USERDATA);
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
HDC hMemDC = CreateCompatibleDC(hDC);
- HBITMAP hOldBmp = (HBITMAP) SelectObject(hMemDC, hSplashBitmap);
+ HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, hSplashBitmap);
BITMAP splashBitmap;
GetObject(hSplashBitmap, sizeof(splashBitmap), &splashBitmap);
BitBlt(hDC, 0, 0, splashBitmap.bmWidth, splashBitmap.bmHeight, hMemDC, 0, 0, SRCCOPY);
@@ -594,12 +594,12 @@ void DrawSplashImage(HWND hWnd)
LRESULT CALLBACK SplashScreenWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- switch(uMsg)
+ switch (uMsg)
{
case WM_PAINT:
DrawSplashImage(hWnd);
break;
- }
+ }
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
@@ -616,7 +616,7 @@ void RegisterSplashScreenWndClass()
wcx.hInstance = hInst;
wcx.hIcon = 0;
wcx.hCursor = LoadCursor(NULL, IDC_WAIT);
- wcx.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
+ wcx.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
wcx.lpszMenuName = 0;
wcx.lpszClassName = splashClassName;
wcx.hIconSm = 0;
@@ -632,86 +632,120 @@ HWND ShowSplashScreenWindow(HBITMAP hSplashBitmap)
GetObject(hSplashBitmap, sizeof(splashBitmap), &splashBitmap);
int x = workArea.left + ((workArea.right - workArea.left) - splashBitmap.bmWidth) / 2;
int y = workArea.top + ((workArea.bottom - workArea.top) - splashBitmap.bmHeight) / 2;
-
+
HWND splashWindow = CreateWindowEx(WS_EX_TOOLWINDOW, splashClassName, splashClassName, WS_POPUP,
x, y, splashBitmap.bmWidth, splashBitmap.bmHeight, NULL, NULL, NULL, NULL);
- SetWindowLongPtr(splashWindow, GWLP_USERDATA, (LONG_PTR) hSplashBitmap);
+ SetWindowLongPtr(splashWindow, GWLP_USERDATA, (LONG_PTR)hSplashBitmap);
ShowWindow(splashWindow, SW_SHOW);
UpdateWindow(splashWindow);
return splashWindow;
}
+DWORD parentProcId;
+HANDLE parentProcHandle;
+
+BOOL IsParentProcessRunning(HANDLE hProcess)
+{
+ if (hProcess == NULL) return FALSE;
+ DWORD ret = WaitForSingleObject(hProcess, 0);
+ return ret == WAIT_TIMEOUT;
+}
+
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
- static DWORD currentProcId = GetCurrentProcessId();
DWORD procId = 0;
GetWindowThreadProcessId(hWnd, &procId);
- if(currentProcId == procId)
+ if (parentProcId == procId)
{
- TCHAR className[_MAX_PATH];
- GetClassName(hWnd, className, _MAX_PATH-1);
- if (_tcscmp(className, splashClassName) != 0)
+ WINDOWINFO wi;
+ wi.cbSize = sizeof(WINDOWINFO);
+ GetWindowInfo(hWnd, &wi);
+ if ((wi.dwStyle & WS_VISIBLE) != 0)
{
- WINDOWINFO wi;
- wi.cbSize = sizeof(WINDOWINFO);
- GetWindowInfo(hWnd, &wi);
- if((wi.dwStyle & WS_VISIBLE) != 0)
- {
- HWND *phNewWindow = (HWND *) lParam;
- *phNewWindow = hWnd;
- return FALSE;
- }
+ HWND *phNewWindow = (HWND *)lParam;
+ *phNewWindow = hWnd;
+ return FALSE;
}
}
return TRUE;
}
-
-DWORD WINAPI SplashScreenThread(LPVOID args)
+DWORD WINAPI SplashScreen(HBITMAP hSplashBitmap)
{
- HBITMAP hSplashBitmap = static_cast<HBITMAP>(args);
RegisterSplashScreenWndClass();
HWND splashWindow = ShowSplashScreenWindow(hSplashBitmap);
-
MSG msg;
- while(true)
+ while (true)
{
- while (PeekMessage(&msg, splashWindow, 0, 0, PM_REMOVE))
+ while (PeekMessage(&msg, splashWindow, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Sleep(50);
HWND hNewWindow = NULL;
- EnumWindows(EnumWindowsProc, (LPARAM) &hNewWindow);
+ EnumWindows(EnumWindowsProc, (LPARAM)&hNewWindow);
if (hNewWindow)
{
BringWindowToTop(hNewWindow);
+ Sleep(100);
DeleteObject(hSplashBitmap);
DestroyWindow(splashWindow);
+ break;
}
+ if (!IsParentProcessRunning(parentProcHandle)) break;
}
return 0;
}
+void StartSplashProcess()
+{
+ TCHAR ownPath[_MAX_PATH];
+ TCHAR params[_MAX_PATH];
+
+ PROCESS_INFORMATION splashProcessInformation;
+ STARTUPINFO startupInfo;
+ memset(&splashProcessInformation, 0, sizeof(splashProcessInformation));
+ memset(&startupInfo, 0, sizeof(startupInfo));
+ startupInfo.cb = sizeof(startupInfo);
+ startupInfo.dwFlags = STARTF_USESHOWWINDOW;
+ startupInfo.wShowWindow = SW_SHOW;
+
+ GetModuleFileName(NULL, ownPath, (sizeof(ownPath)));
+ _snwprintf(params, _MAX_PATH, _T("SPLASH %d"), GetCurrentProcessId());
+ if (CreateProcess(ownPath, params, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &splashProcessInformation))
+ {
+ CloseHandle(splashProcessInformation.hProcess);
+ CloseHandle(splashProcessInformation.hThread);
+ }
+}
+
int APIENTRY _tWinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPTSTR lpCmdLine,
- int nCmdShow)
+ HINSTANCE hPrevInstance,
+ LPTSTR lpCmdLine,
+ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
- UNREFERENCED_PARAMETER(lpCmdLine);
hInst = hInstance;
- if (!CheckSingleInstance()) return 1;
-
- HANDLE hSplashBitmap = static_cast<HBITMAP>(LoadImage(hInst, MAKEINTRESOURCE(IDB_SPLASH), IMAGE_BITMAP, 0, 0, 0));
- if (hSplashBitmap)
+ if (__argc == 2 && _wcsicmp(__wargv[0], _T("SPLASH")) == 0)
{
- CreateThread(NULL, 0, SplashScreenThread, hSplashBitmap, 0, NULL);
+ HBITMAP hSplashBitmap = static_cast<HBITMAP>(LoadImage(hInst, MAKEINTRESOURCE(IDB_SPLASH), IMAGE_BITMAP, 0, 0, 0));
+ if (hSplashBitmap)
+ {
+ parentProcId = _wtoi(__wargv[1]);
+ parentProcHandle = OpenProcess(SYNCHRONIZE, FALSE, parentProcId);
+ if (IsParentProcessRunning(parentProcHandle)) SplashScreen(hSplashBitmap);
+ }
+ CloseHandle(parentProcHandle);
+ return 0;
}
+ if (!CheckSingleInstance()) return 1;
+
+ if (wcsstr(lpCmdLine, _T("nosplash")) == NULL) StartSplashProcess();
+
if (!LocateJVM()) return 1;
if (!LoadVMOptions()) return 1;
if (!LoadJVMLibrary()) return 1;
@@ -731,4 +765,3 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
return 0;
}
- \ No newline at end of file