diff options
Diffstat (limited to 'native/WinLauncher/WinLauncher/WinLauncher.cpp')
-rw-r--r-- | native/WinLauncher/WinLauncher/WinLauncher.cpp | 199 |
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 |