/*
 * 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);
    }
}
