| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 <wchar.h> |
| #include <stdio.h> |
| #include "JavaUtils.h" |
| #include "RegistryUtils.h" |
| #include "StringUtils.h" |
| #include "SystemUtils.h" |
| #include "FileUtils.h" |
| #include "ProcessUtils.h" |
| #include "Launcher.h" |
| #include "Main.h" |
| |
| const DWORD JAVA_VERIFICATION_PROCESS_TIMEOUT = 10000; // 10sec |
| const DWORD UNPACK200_EXTRACTION_TIMEOUT = 60000; //60 seconds on each file |
| const DWORD JAVA_VERIFICATION_PROCESS_PRIORITY = NORMAL_PRIORITY_CLASS; |
| const WCHAR * JAVA_EXE_SUFFIX = L"\\bin\\java.exe"; |
| const WCHAR * UNPACK200_EXE_SUFFIX = L"\\bin\\unpack200.exe"; |
| const WCHAR * JAVA_LIB_SUFFIX = L"\\lib"; |
| const WCHAR * PACK_GZ_SUFFIX = L".pack.gz"; |
| const WCHAR * JAR_PACK_GZ_SUFFIX = L".jar.pack.gz"; |
| |
| const DWORD JVM_EXTRACTION_TIMEOUT = 180000; //180sec |
| |
| WCHAR * JAVA_REGISTRY_KEYS [] = { |
| L"SOFTWARE\\JavaSoft\\Java Runtime Environment", |
| L"SOFTWARE\\JavaSoft\\Java Development Kit", |
| L"SOFTWARE\\JavaSoft\\JDK", |
| L"SOFTWARE\\JRockit\\Java Runtime Environment", |
| L"SOFTWARE\\JRockit\\Java Development Kit", |
| L"SOFTWARE\\IBM\\Java Runtime Environment", |
| L"SOFTWARE\\IBM\\Java2 Runtime Environment", |
| L"SOFTWARE\\IBM\\Java Development Kit", |
| }; |
| WCHAR * JAVA_HOME = L"JavaHome"; |
| WCHAR * CURRENT_VERSION = L"CurrentVersion"; |
| |
| WCHAR * getJavaHomeValue(WCHAR *parentkey, WCHAR *subkey, BOOL access64key) { |
| return getStringValuePC(HKEY_LOCAL_MACHINE, parentkey, subkey, JAVA_HOME, access64key); |
| } |
| |
| |
| WCHAR * getTestJVMFileName(WCHAR * testJVMFile) { |
| WCHAR * filePtr = testJVMFile; |
| WCHAR * testJavaClass = NULL; |
| |
| if(filePtr!=NULL) { |
| WCHAR * dotClass = NULL; |
| while(searchW(filePtr, L"\\")!=NULL) { |
| filePtr = searchW(filePtr, L"\\"); |
| filePtr++; |
| } |
| dotClass = searchW(filePtr, L".class"); |
| |
| if(dotClass!=NULL) { |
| testJavaClass = appendStringNW(NULL, 0, filePtr, getLengthW(filePtr) - getLengthW(dotClass)); |
| } |
| } |
| return testJavaClass; |
| } |
| |
| |
| //returns 0 if equals, 1 if first > second, -1 if first < second |
| char compareJavaVersion(JavaVersion * first, JavaVersion * second) { |
| if(first==NULL) return (second==NULL) ? 0 : -1; |
| if(second==NULL) return -1; |
| if(first->major == second->major) { |
| if(first->minor == second->minor) { |
| if(first->micro == second->micro) { |
| if(first->update == second->update) return 0; |
| return (first->update > second->update) ? 1 : -1; |
| } |
| return (first->micro > second->micro) ? 1 : -1; |
| } |
| return (first->minor > second->minor) ? 1 : -1; |
| } else { |
| return (first->major > second->major) ? 1 : -1; |
| } |
| } |
| DWORD isJavaCompatible(JavaProperties *currentJava, JavaCompatible ** compatibleJava, DWORD number) { |
| JavaVersion * current = currentJava->version; |
| DWORD i = 0 ; |
| |
| for(i=0;i<number;i++) { |
| DWORD check = 1; |
| |
| check = (compareJavaVersion(current, compatibleJava[i]->minVersion) >= 0 && |
| compareJavaVersion(current, compatibleJava[i]->maxVersion) <= 0) ? check : 0; |
| |
| if (check) { |
| if(compatibleJava[i]->vendor!=NULL) { |
| check = (searchA(currentJava->vendor, compatibleJava[i]->vendor) != NULL) ? check : 0; |
| } |
| if (compatibleJava[i]->osName!=NULL) { |
| check = (searchA(currentJava->osName, compatibleJava[i]->osName)!=NULL) ? check : 0; |
| } |
| |
| if (compatibleJava[i]->osArch!=NULL) { |
| check = (searchA(currentJava->osArch, compatibleJava[i]->osArch)!=NULL) ? check : 0; |
| } |
| if(check) { |
| return 1; |
| } |
| } |
| } |
| return 0; |
| } |
| |
| JavaVersion * getJavaVersionFromString(char * string, DWORD * result) { |
| JavaVersion *vers = NULL; |
| if(getLengthA(string)<3) { |
| return vers; |
| } |
| |
| const char *p = string; |
| |
| // get major |
| long major = 0; |
| while(*p!=0) { |
| char c = *p++; |
| if(c>='0' && c<='9') { |
| major = (major) * 10 + c - '0'; |
| if (major > 999) return vers; |
| continue; |
| } else if(c=='.' || c=='+'){ |
| break; |
| } else{ |
| return vers; |
| } |
| } |
| |
| // get minor |
| long minor = 0; |
| while(*p!=0) { |
| char c = *p; |
| if(c>='0' && c<='9') { |
| minor = (minor) * 10 + c - '0'; |
| p++; |
| continue; |
| } |
| break; |
| } |
| |
| *result = ERROR_OK; |
| vers = (JavaVersion*) LocalAlloc(LPTR, sizeof(JavaVersion)); |
| vers->major = major; |
| vers->minor = minor; |
| vers->micro = 0; |
| vers->update = 0; |
| ZERO(vers->build, 128); |
| |
| if(p[0]=='.') { // micro... |
| p++; |
| while(*p!=0) { |
| char c = *p; |
| if(c>='0' && c<='9') { |
| vers->micro = (vers->micro) * 10 + c - '0'; |
| p++; |
| continue; |
| } else if(c=='_') {//update |
| p++; |
| while((c = *p) != 0) { |
| p++; |
| if(c>='0' && c<='9') { |
| vers->update = (vers->update) * 10 + c - '0'; |
| continue; |
| } else { |
| break; |
| } |
| } |
| } else { |
| if(*p!=0) p++; |
| } |
| if(c=='-' && *p!=0) { // build number |
| lstrcpyn(vers->build, p, min(127, getLengthA(p)+1)); |
| } |
| break; |
| } |
| } |
| return vers; |
| } |
| |
| DWORD getJavaPropertiesFromOutput(LauncherProperties * props, char *str, JavaProperties ** javaProps) { |
| DWORD separators = getLineSeparatorNumber(str); |
| DWORD result = ERROR_INPUTOUPUT; |
| * javaProps = NULL; |
| if(separators == TEST_JAVA_PARAMETERS) { |
| char * start; |
| char * end; |
| char * javaVersion; |
| char * javaVmVersion; |
| char * javaVendor; |
| char * osName; |
| char * osArch; |
| char * string; |
| JavaVersion * vers; |
| |
| start = str; |
| end = searchA(start, "\n"); |
| |
| javaVersion = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " java.version = ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, javaVersion, 1); |
| start = end + 1; |
| end = searchA(start, "\n"); |
| |
| |
| javaVmVersion = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " java.vm.version = ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, javaVmVersion, 1); |
| start = end + 1; |
| end = searchA(start, "\n"); |
| |
| javaVendor = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " java.vendor = ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, javaVendor, 1); |
| start = end + 1; |
| end = searchA(start, "\n"); |
| |
| osName = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " os.name = ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, osName, 1); |
| start = end + 1; |
| end = searchA(start, "\n"); |
| |
| osArch = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " os.arch = ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, osArch, 2); |
| |
| string = javaVersion; |
| |
| |
| if(javaVmVersion!=NULL) { |
| string = searchA(javaVmVersion, javaVersion); |
| if(string==NULL) { |
| string = javaVersion; |
| } |
| } |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... getting java version from string : ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, string, 1); |
| |
| vers = getJavaVersionFromString(string, & result); |
| if(javaProps != NULL) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... some java there", 1); |
| * javaProps = (JavaProperties *) LocalAlloc(LPTR, sizeof(JavaProperties)); |
| (*javaProps)->version = vers; |
| (*javaProps)->vendor = javaVendor; |
| (*javaProps)->osName = osName; |
| (*javaProps)->osArch = osArch; |
| (*javaProps)->javaHome = NULL; |
| (*javaProps)->javaExe = NULL; |
| } else { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... no java there", 1); |
| FREE(javaVendor); |
| FREE(osName); |
| FREE(osArch); |
| } |
| FREE(javaVmVersion); |
| FREE(javaVersion); |
| } |
| return result; |
| } |
| |
| |
| void getJavaProperties(WCHAR * location, LauncherProperties * props, JavaProperties ** javaProps) { |
| WCHAR *testJavaClass = props->testJVMClass; |
| WCHAR *javaExecutable = getJavaResource(location, JAVA_EXE_SUFFIX); |
| WCHAR *libDirectory = getJavaResource(location, JAVA_LIB_SUFFIX); |
| |
| if(fileExists(javaExecutable) && testJavaClass!=NULL && isDirectory(libDirectory)) { |
| WCHAR * command = NULL; |
| HANDLE hRead; |
| HANDLE hWrite; |
| |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... java hierarchy there", 1); |
| // <location>\bin\java.exe exists |
| |
| |
| appendCommandLineArgument(&command, javaExecutable); |
| appendCommandLineArgument(&command, L"-classpath"); |
| appendCommandLineArgument(&command, props->testJVMFile->resolved); |
| appendCommandLineArgument(&command, testJavaClass); |
| |
| |
| CreatePipe(&hRead, &hWrite, NULL, 0); |
| // Start the child process. |
| executeCommand(props, command, NULL, JAVA_VERIFICATION_PROCESS_TIMEOUT, hWrite, INVALID_HANDLE_VALUE, JAVA_VERIFICATION_PROCESS_PRIORITY); |
| if(props->status!= ERROR_ON_EXECUTE_PROCESS && props->status!= ERROR_PROCESS_TIMEOUT) { |
| char * output = readHandle(hRead); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " output :\n", 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, output, 1); |
| |
| props->status = getJavaPropertiesFromOutput(props, output, javaProps); |
| if(props->status == ERROR_OK) { |
| (*javaProps)->javaHome = appendStringW(NULL, location); |
| (*javaProps)->javaExe = appendStringW(NULL, javaExecutable); |
| } |
| FREE(output); |
| } else if(props->status == ERROR_PROCESS_TIMEOUT) { |
| // java verification process finished by time out |
| props->status = ERROR_INPUTOUPUT; |
| } |
| FREE(command); |
| CloseHandle(hWrite); |
| CloseHandle(hRead); |
| } else { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... not a java hierarchy", 1); |
| props->status = ERROR_INPUTOUPUT; |
| } |
| FREE(libDirectory); |
| FREE(javaExecutable); |
| } |
| |
| |
| |
| char * getJavaVersionFormatted(const JavaProperties * javaProps) { |
| char *result = NULL; |
| if(javaProps!=NULL) { |
| JavaVersion * version = javaProps->version; |
| if(version!=NULL) { |
| char * majorStr = long2char(version->major); |
| char * minorStr = long2char(version->minor); |
| char * microStr = long2char(version->micro); |
| result = appendString(result, majorStr); |
| result = appendString(result, "."); |
| result = appendString(result, minorStr); |
| result = appendString(result, "."); |
| result = appendString(result, microStr); |
| FREE(majorStr); |
| FREE(minorStr); |
| FREE(microStr); |
| |
| if(version->update!=0) { |
| char * updateStr = long2charN(version->update, 2); |
| result = appendString(result, "_"); |
| result = appendString(result, updateStr); |
| FREE(updateStr); |
| } |
| if(getLengthA(version->build) > 0) { |
| result = appendString(result, "-"); |
| result = appendString(result, version->build); |
| } |
| } |
| } |
| return result; |
| } |
| |
| |
| JavaCompatible * newJavaCompatible() { |
| JavaCompatible * props = (JavaCompatible *) LocalAlloc(LPTR, sizeof(JavaCompatible)); |
| props->minVersion = NULL; |
| props->maxVersion = NULL; |
| props->vendor = NULL; |
| props->osName = NULL; |
| return props; |
| } |
| |
| void freeJavaProperties(JavaProperties ** props) { |
| if(*props!=NULL) { |
| FREE((*props)->version); |
| FREE((*props)->javaHome); |
| FREE((*props)->javaExe); |
| FREE((*props)->vendor); |
| FREE(*props); |
| } |
| } |
| |
| WCHAR * getJavaResource(WCHAR * location, const WCHAR * suffix) { |
| return appendStringW(appendStringW(NULL, location), suffix); |
| } |
| |
| |
| void searchCurrentJavaRegistry(LauncherProperties * props, BOOL access64key) { |
| DWORD i=0; |
| WCHAR ** keys = JAVA_REGISTRY_KEYS; |
| DWORD k=0; |
| WCHAR * buffer = newpWCHAR(MAX_LEN_VALUE_NAME); |
| HKEY rootKeys [2] = {HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER}; |
| DWORD rootKeysNumber = sizeof(rootKeys)/sizeof(HKEY); |
| DWORD keysNumber = sizeof(JAVA_REGISTRY_KEYS)/sizeof(WCHAR*); |
| DWORD status = ERROR_OK; |
| |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in CurrentVersion values...", 1); |
| |
| |
| for ( k = 0; k < rootKeysNumber; k++) { |
| for(i=0; i < keysNumber;i++) { |
| if(isTerminated(props)) { |
| return; |
| } |
| else { |
| |
| WCHAR * value = getStringValue(rootKeys[k], keys[i], CURRENT_VERSION, access64key); |
| if(value!=NULL) { |
| WCHAR *javaHome = getStringValuePC(rootKeys[k], keys[i], value, JAVA_HOME, access64key); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, (rootKeys[k]==HKEY_LOCAL_MACHINE) ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER", 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, keys[i], 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, CURRENT_VERSION, 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "->", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, value, 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "[", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, JAVA_HOME, 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "] = ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaHome, 1); |
| |
| FREE(value); |
| trySetCompatibleJava(javaHome, props); |
| FREE(javaHome); |
| if(props->java!=NULL) { |
| FREE(buffer); |
| return; |
| } |
| } |
| } |
| } |
| } |
| |
| |
| // we found no CurrentVersion java... just search for other possible keys |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in other values...", 1); |
| |
| |
| for(k=0;k<rootKeysNumber;k++) { |
| for(i=0;i<keysNumber;i++) { |
| HKEY hkey = 0; |
| DWORD index = 0 ; |
| if (RegOpenKeyExW(rootKeys[k], keys[i], 0, KEY_READ | ((access64key && IsWow64) ? KEY_WOW64_64KEY : 0), &hkey) == ERROR_SUCCESS) { |
| DWORD number = 0; |
| if (RegQueryInfoKeyW(hkey, NULL, NULL, NULL, &number, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { |
| DWORD err = 0; |
| do { |
| |
| DWORD size = MAX_LEN_VALUE_NAME; |
| buffer[0] = 0; |
| err = RegEnumKeyExW(hkey, index, buffer, &size, NULL, NULL, NULL, NULL); |
| if (err == ERROR_SUCCESS) { |
| WCHAR * javaHome = getJavaHomeValue(keys[i], buffer, access64key); |
| status = ERROR_OK; |
| |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, (rootKeys[k]==HKEY_LOCAL_MACHINE) ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER", 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, keys[i], 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, buffer, 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "[", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, JAVA_HOME, 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "] = ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaHome, 1); |
| |
| trySetCompatibleJava(javaHome, props); |
| FREE(javaHome); |
| if(props->java!=NULL) { |
| i = keysNumber; // to the end of cycles |
| k = rootKeysNumber; |
| break; |
| } |
| |
| } |
| index++; |
| } while (err == ERROR_SUCCESS); |
| } |
| } |
| if (hkey != 0) { |
| RegCloseKey(hkey); |
| } |
| } |
| } |
| FREE(buffer); |
| return; |
| } |
| |
| |
| void searchJavaFromEnvVariables(LauncherProperties * props) { |
| static WCHAR * ENVS [] = { |
| L"JAVA_HOME", |
| L"JAVAHOME", |
| L"JAVA_PATH", |
| L"JDK_HOME", |
| L"JDKHOME", |
| L"ANT_JAVA", |
| L"JAVA", |
| L"JDK" |
| }; |
| |
| WCHAR buffer [MAX_PATH]; |
| |
| int size = sizeof(ENVS)/sizeof(WCHAR *); |
| int i=0; |
| int ret; |
| |
| for(i=0;i<size;i++) { |
| if(isTerminated(props)) return; |
| buffer[0]='\0'; |
| ret = GetEnvironmentVariableW((WCHAR *) ENVS[i], (WCHAR *) buffer, MAX_PATH); |
| if (ret > 0 && ret <= MAX_PATH) { |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " <", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, ENVS[i], 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "> = ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, buffer, 1); |
| trySetCompatibleJava(buffer, props); |
| if(props->java!=NULL) { |
| break; |
| } |
| } |
| } |
| } |
| |
| |
| |
| |
| void unpackJars(LauncherProperties * props, WCHAR * jvmDir, WCHAR * startDir, WCHAR * unpack200exe) { |
| DWORD attrs; |
| DWORD dwError; |
| DWORD count = 0 ; |
| |
| if(!isOK(props)) return; |
| attrs = GetFileAttributesW(startDir); |
| if(attrs==INVALID_FILE_ATTRIBUTES) { |
| writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t get attributes of the file : ", startDir, GetLastError()); |
| return; |
| } |
| if(attrs & FILE_ATTRIBUTE_DIRECTORY) { // is directory |
| WIN32_FIND_DATAW FindFileData; |
| HANDLE hFind = INVALID_HANDLE_VALUE; |
| |
| WCHAR * DirSpec = appendStringW(appendStringW(NULL, startDir), L"\\*" ); |
| |
| // Find the first file in the directory. |
| hFind = FindFirstFileW(DirSpec, &FindFileData); |
| |
| if (hFind == INVALID_HANDLE_VALUE) { |
| writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t file with pattern ", DirSpec, GetLastError()); |
| } |
| else { |
| // List all the other files in the directory. |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... listing directory ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, startDir, 1); |
| |
| while (FindNextFileW(hFind, &FindFileData) != 0 && isOK(props)) { |
| if(lstrcmpW(FindFileData.cFileName, L".")!=0 && |
| lstrcmpW(FindFileData.cFileName, L"..")!=0) { |
| WCHAR * child = NULL; |
| |
| child = appendStringW(appendStringW(appendStringW(NULL, startDir), FILE_SEP), FindFileData.cFileName); |
| if(isDirectory(child)) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... directory : ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, child, 1); |
| unpackJars(props, jvmDir, child, unpack200exe); |
| } else if(searchW(FindFileData.cFileName, JAR_PACK_GZ_SUFFIX)!=NULL) { |
| WCHAR * jarName = appendStringW(appendStringW( |
| appendStringW(NULL, startDir), FILE_SEP), |
| appendStringNW(NULL, 0, FindFileData.cFileName, |
| getLengthW(FindFileData.cFileName) - getLengthW(PACK_GZ_SUFFIX))); |
| WCHAR * unpackCommand = NULL; |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... packed jar : ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, child, 1); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... jar name : ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, jarName, 1); |
| |
| |
| appendCommandLineArgument(&unpackCommand, unpack200exe); |
| appendCommandLineArgument(&unpackCommand, L"-r"); // remove input file |
| appendCommandLineArgument(&unpackCommand, child); |
| appendCommandLineArgument(&unpackCommand, jarName); |
| |
| executeCommand(props, unpackCommand, NULL, UNPACK200_EXTRACTION_TIMEOUT, props->stdoutHandle, props->stderrHandle, NORMAL_PRIORITY_CLASS); |
| FREE(unpackCommand); |
| if(!isOK(props)) { |
| if(props->status==ERROR_PROCESS_TIMEOUT) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... could not unpack file : timeout", 1); |
| } else { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... an error occured unpacking the file", 1); |
| } |
| props->exitCode = props->status; |
| } |
| FREE(jarName); |
| } |
| FREE(child); |
| } |
| } |
| |
| dwError = GetLastError(); |
| FindClose(hFind); |
| if (dwError != ERROR_NO_MORE_FILES) { |
| writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t find file with pattern : ", DirSpec, dwError); |
| } |
| } |
| FREE(DirSpec); |
| } |
| |
| } |
| void installJVM(LauncherProperties * props, LauncherResource *jvm) { |
| WCHAR * command = NULL; |
| WCHAR * jvmDir = getParentDirectory(jvm->resolved); |
| |
| jvmDir = appendStringW(jvmDir, L"\\_jvm"); |
| createDirectory(props, jvmDir); |
| if(!isOK(props)) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... cannot create dir for JVM extraction :", 0); |
| writeMessageW(props, OUTPUT_LEVEL_DEBUG, 1, jvmDir, 1); |
| FREE(jvmDir); |
| return; |
| } |
| |
| appendCommandLineArgument(&command, jvm->resolved); |
| appendCommandLineArgument(&command, L"-d"); |
| appendCommandLineArgument(&command, jvmDir); |
| |
| executeCommand(props, command, jvmDir, JVM_EXTRACTION_TIMEOUT, props->stdoutHandle, props->stderrHandle, NORMAL_PRIORITY_CLASS); |
| FREE(command); |
| if(!isOK(props)) { |
| if(props->status==ERROR_PROCESS_TIMEOUT) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... could not extract JVM : timeout", 1); |
| } else { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... an error occured during running JVM extraction file", 1); |
| } |
| props->exitCode = props->status; |
| } else { |
| WCHAR * unpack200exe = appendStringW(appendStringW(NULL, jvmDir), UNPACK200_EXE_SUFFIX); |
| if(fileExists(unpack200exe)) { |
| unpackJars(props, jvmDir, jvmDir, unpack200exe); |
| } else { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... no unpack200 command", 1); |
| props->status = ERROR_BUNDLED_JVM_EXTRACTION; |
| } |
| if(!isOK(props)) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Could not unpack200 the JVM jars", 1); |
| } |
| FREE(unpack200exe); |
| } |
| FREE(jvm->resolved); |
| jvm->resolved = jvmDir; |
| } |
| |
| void installBundledJVMs(LauncherProperties * props) { |
| if ( props->jvms->size > 0 ) { |
| DWORD i=0; |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... search for bundled JVMs", 1); |
| for(i=0;i<props->jvms->size; i++) { |
| if(props->jvms->items[i]->type==0 && !isTerminated(props)) { |
| resolvePath(props, props->jvms->items[i]); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... install bundled JVM ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, props->jvms->items[i]->resolved, 1); |
| installJVM(props, props->jvms->items[i]); |
| if(isTerminated(props)) return; |
| if(isOK(props)) { |
| trySetCompatibleJava(props->jvms->items[i]->resolved, props); |
| if(props->java!=NULL) { |
| break; |
| } else { |
| props->status = ERROR_BUNDLED_JVM_VERIFICATION; |
| return; |
| } |
| } |
| else { |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... error occured during JVM extraction", 1); |
| props->status = ERROR_BUNDLED_JVM_EXTRACTION; |
| return; |
| } |
| } |
| } |
| } |
| } |
| void searchJavaInstallationFolder(LauncherProperties * props) { |
| char executablePath [MAX_PATH]; |
| GetModuleFileName(0, executablePath, MAX_PATH); |
| char * pch = strrchr(executablePath, '\\'); |
| char installationFolder [MAX_PATH]= ""; |
| int i = 0; |
| int end = (int) (pch - executablePath); |
| printf("%i", end); |
| for(i; i < end; i++) { |
| installationFolder[i] = executablePath[i]; |
| } |
| strcat(installationFolder, "\\bin\\jre"); |
| |
| // check if JRE is in installation folder |
| WCHAR * nestedJreFolder = toWCHAR(installationFolder); |
| if (!fileExists(nestedJreFolder)) { |
| // if not exists - return |
| return; |
| } |
| |
| // if exists - copy to temp folder to run uninstaller on that jvm |
| // to be able to delete jvm in installation folder |
| WCHAR * tempJreFolder = NULL; |
| tempJreFolder = appendStringW(tempJreFolder, props->testJVMFile->resolved); |
| tempJreFolder = appendStringW(tempJreFolder, L"\\_jvm\\"); |
| |
| WCHAR * command = NULL; |
| appendCommandLineArgument(&command, L"xcopy"); |
| appendCommandLineArgument(&command, nestedJreFolder); |
| appendCommandLineArgument(&command, tempJreFolder); |
| appendCommandLineArgument(&command, L"/e"); |
| appendCommandLineArgument(&command, L"/y"); |
| |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Copying nested JRE to temp folder", 0); |
| |
| executeCommand(props, command, NULL, JVM_EXTRACTION_TIMEOUT, props->stdoutHandle, props->stderrHandle, NORMAL_PRIORITY_CLASS); |
| |
| if (fileExists(tempJreFolder)) { |
| trySetCompatibleJava(tempJreFolder, props); |
| } |
| } |
| void searchJavaSystemLocations(LauncherProperties * props) { |
| if ( props->jvms->size > 0 ) { |
| DWORD i=0; |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search jvm using some predefined locations", 1); |
| for(i=0;i<props->jvms->size && !isTerminated(props);i++) { |
| resolvePath(props, props->jvms->items[i]); |
| if(props->jvms->items[i]->type!=0) { // bundled JVMs are already checked |
| trySetCompatibleJava(props->jvms->items[i]->resolved, props); |
| if(props->java!=NULL) { |
| break; |
| } |
| } |
| } |
| } |
| } |
| void findSystemJava(LauncherProperties *props) { |
| // install bundled JVMs if any |
| if(isTerminated(props)) return; |
| installBundledJVMs(props); |
| |
| if(!isOK(props) || isTerminated(props)) return; |
| // search in <installation folder>/bin/jre |
| if(props->java==NULL) { |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in installation folder", 1); |
| searchJavaInstallationFolder(props); |
| } |
| // search JVM in the system paths |
| if(props->java==NULL) { |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in the system paths", 1); |
| searchJavaSystemLocations(props); |
| } |
| |
| if(isTerminated(props)) return; |
| if(props->java==NULL) { |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in environment variables", 1); |
| searchJavaFromEnvVariables(props); |
| } |
| |
| // search JVM in the registry |
| if(isTerminated(props)) return; |
| if(props->java==NULL) { |
| if(IsWow64) { |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in 64-bit registry", 1); |
| searchCurrentJavaRegistry(props, 1); |
| } |
| if(props->java==NULL) { |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in 32-bit registry", 1); |
| searchCurrentJavaRegistry(props, 0); |
| } |
| } |
| } |
| |
| |
| void printJavaProperties(LauncherProperties * props, JavaProperties * javaProps) { |
| if(javaProps!=NULL) { |
| char * jv = getJavaVersionFormatted(javaProps); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Current Java:", 1); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " javaHome: ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->javaHome, 1); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " javaExe: ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->javaExe, 1); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " version: ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, jv, 1); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " vendor: ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->vendor, 1); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " os.name: ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->osName, 1); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " os.arch: ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->osArch, 1); |
| FREE(jv); |
| } |
| } |