oslib-win32: always get java path from registry
authorJinhyung Jo <jinhyung.jo@samsung.com>
Wed, 27 Jan 2016 05:51:17 +0000 (14:51 +0900)
committerJinhyung Jo <jinhyung.jo@samsung.com>
Wed, 27 Jan 2016 09:04:30 +0000 (18:04 +0900)
Regardless of the architecture of the emulator(32bit or 64bit),
always gets the java execution path from Windows registry.
This commit would be helpful to reduce the java execution failure.

Change-Id: I890bfa67ffdde36bbbd28678e196d7a50bce65a8
Signed-off-by: Jinhyung Jo <jinhyung.jo@samsung.com>
(cherry picked from commit 62425a158ab5382ad75674b7a5906da3fa75b0a6)

tizen/src/emulator_common.h
tizen/src/skin/maruskin_client.c
util/oslib-posix.c
util/oslib-win32.c

index fb9d5c3..d6c243c 100644 (file)
 #define JAR_SKINFILE "emulator-skin.jar"
 #define JAVA_LIBRARY_PATH "-Djava.library.path"
 
-#ifndef CONFIG_DARWIN
-#define JAVA_EXEOPTION "-jar"
+#ifdef CONFIG_DARWIN
+/* Must start the Java window on the first thread on Mac */
+#define JAVA_EXEOPTION "-XstartOnFirstThread -jar"
 #else
-#define JAVA_EXEOPTION "-XstartOnFirstThread -jar" // Must start the Java window on the first thread on Mac
+#define JAVA_EXEOPTION "-jar"
 #endif
 #define JAVA_SIMPLEMODE_OPTION "simple.msg"
 
 #ifdef CONFIG_WIN32
-#define MY_KEY_WOW64_64KEY 0x0100
-#ifdef __cplusplus
-extern "C" {
-#endif
-int is_wow64(void);
-bool get_java_path(char **java_path);
-#ifdef __cplusplus
-}
+void get_java_path_win32(const char **java_path);
 #endif
+
+static inline void get_java_path(const char **java_path)
+{
+#ifdef CONFIG_WIN32
+    get_java_path_win32(java_path);
 #else
-#define JAVA_EXEFILE_PATH "java"
+    *java_path = "java";
 #endif
+}
 
 #endif /* __EMULATOR_COMMON_H__ */
index a533050..6d92a11 100644 (file)
@@ -77,9 +77,7 @@ extern char tizen_target_path[];
 static int skin_argc;
 static char** skin_argv;
 
-#ifdef CONFIG_WIN32
-static char* JAVA_EXEFILE_PATH = NULL;
-#endif
+static const char *java_exec_path = NULL;
 
 static void *run_skin_client(void *arg)
 {
@@ -134,19 +132,8 @@ static void *run_skin_client(void *arg)
     sprintf(buf_proxy_addr, "%s", get_emul_http_proxy_addr());
     sprintf(buf_proxy_port, "%s", get_emul_http_proxy_port());
 
+    get_java_path(&java_exec_path);
 #ifdef CONFIG_WIN32
-    /* find java path in 64bit windows */
-    JAVA_EXEFILE_PATH = malloc(JAVA_MAX_COMMAND_LENGTH);
-    memset(JAVA_EXEFILE_PATH, 0, JAVA_MAX_COMMAND_LENGTH);
-    if (is_wow64()) {
-        INFO("This process is running under WOW64.\n");
-        if (!get_java_path(&JAVA_EXEFILE_PATH)) {
-             strcpy(JAVA_EXEFILE_PATH, "java");
-        }
-    } else {
-        strcpy(JAVA_EXEFILE_PATH, "java");
-    }
-
     char const* bin_dir = get_bin_path();
     int bin_len = strlen(bin_dir);
     char bin_dir_win[bin_len];
@@ -166,7 +153,7 @@ static void *run_skin_client(void *arg)
     }
 
     /* calculate buffer length */
-    int cmd_len = strlen(JAVA_EXEFILE_PATH) + SPACE_LEN +
+    int cmd_len = strlen(java_exec_path) + SPACE_LEN +
         strlen(JAVA_EXEOPTION) + SPACE_LEN +
         strlen(JAVA_LIBRARY_PATH) + EQUAL_LEN +
 #ifdef CONFIG_WIN32
@@ -217,7 +204,7 @@ static void *run_skin_client(void *arg)
 %s=%s \
 %s=%s \
 %s",
-        JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAVA_LIBRARY_PATH,
+        java_exec_path, JAVA_EXEOPTION, JAVA_LIBRARY_PATH,
 #ifdef CONFIG_WIN32
         bin_dir_win, bin_dir, JAR_SKINFILE,
 #else
@@ -236,11 +223,8 @@ static void *run_skin_client(void *arg)
 
     INFO("command for swt : %s\n", cmd);
 
+    java_exec_path = NULL;
 #ifdef CONFIG_WIN32
-    /* for 64bit windows */
-    free(JAVA_EXEFILE_PATH);
-    JAVA_EXEFILE_PATH = NULL;
-
     //WinExec( cmd, SW_SHOW );
     {
         STARTUPINFO sti = { 0 };
@@ -371,19 +355,8 @@ int start_simple_client(char* msg)
 
     INFO("run simple client\n");
 
+    get_java_path(&java_exec_path);
 #ifdef CONFIG_WIN32
-    /* find java path in 64bit windows */
-    JAVA_EXEFILE_PATH = malloc(JAVA_MAX_COMMAND_LENGTH);
-    memset(JAVA_EXEFILE_PATH, 0, JAVA_MAX_COMMAND_LENGTH);
-    if (is_wow64()) {
-        INFO("This process is running under WOW64.\n");
-        if (!get_java_path(&JAVA_EXEFILE_PATH)) {
-             strcpy(JAVA_EXEFILE_PATH, "java");
-        }
-    } else {
-        strcpy(JAVA_EXEFILE_PATH, "java");
-    }
-
     char const* bin_dir = get_bin_path();
     int bin_dir_len = strlen(bin_dir);
     char bin_dir_win[bin_dir_len];
@@ -395,7 +368,7 @@ int start_simple_client(char* msg)
     INFO("bin directory : %s\n", bin_dir);
 
     /* calculate buffer length */
-    int cmd_len = strlen(JAVA_EXEFILE_PATH) + SPACE_LEN +
+    int cmd_len = strlen(java_exec_path) + SPACE_LEN +
         strlen(JAVA_EXEOPTION) + SPACE_LEN +
         strlen(JAVA_LIBRARY_PATH) + EQUAL_LEN +
 #ifdef CONFIG_WIN32
@@ -414,19 +387,16 @@ int start_simple_client(char* msg)
 
     snprintf(cmd, cmd_len, "%s %s %s=\"%s\" \"%s%s\" %s=\"%s\"",
 #ifdef CONFIG_WIN32
-        JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAVA_LIBRARY_PATH, bin_dir_win,
+        java_exec_path, JAVA_EXEOPTION, JAVA_LIBRARY_PATH, bin_dir_win,
 #else
-        JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAVA_LIBRARY_PATH, bin_dir,
+        java_exec_path, JAVA_EXEOPTION, JAVA_LIBRARY_PATH, bin_dir,
 #endif
         bin_dir, JAR_SKINFILE, JAVA_SIMPLEMODE_OPTION, msg);
 
     INFO("command for swt : %s\n", cmd);
 
+    java_exec_path = NULL;
 #ifdef CONFIG_WIN32
-    /* for 64bit windows */
-    free(JAVA_EXEFILE_PATH);
-    JAVA_EXEFILE_PATH=0;
-
     ret = WinExec(cmd, SW_SHOW);
 #else
     ret = system(cmd);
index f7a8325..0c37eea 100644 (file)
@@ -90,13 +90,15 @@ void *qemu_oom_check(void *ptr)
 #ifdef CONFIG_MARU
     const char _msg[] = "Failed to allocate memory in qemu.";
     char cmd[JAVA_MAX_COMMAND_LENGTH] = { 0, };
+    const char *java_exefile_path = NULL;
     int len;
 #endif
 
     if (ptr == NULL) {
         fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
 #ifdef CONFIG_MARU
-        len = strlen(JAVA_EXEFILE_PATH) + strlen(JAVA_EXEOPTION) +
+        get_java_path(&java_exefile_path);
+        len = strlen(java_exefile_path) + strlen(JAVA_EXEOPTION) +
             strlen(JAR_SKINFILE) + strlen(JAVA_SIMPLEMODE_OPTION) +
             strlen(_msg) + 7;
         if (len > JAVA_MAX_COMMAND_LENGTH) {
@@ -104,10 +106,11 @@ void *qemu_oom_check(void *ptr)
         }
 
         snprintf(cmd, len, "%s %s %s %s=\"%s\"",
-            JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAR_SKINFILE, JAVA_SIMPLEMODE_OPTION, _msg);
+            java_exefile_path, JAVA_EXEOPTION, JAR_SKINFILE, JAVA_SIMPLEMODE_OPTION, _msg);
         if (system(cmd) == -1) {
             fprintf(stderr, "failed to execute this command: %s\n", cmd);
         }
+        java_exefile_path = NULL;
 #endif
         abort();
     }
index 22bdb0b..abf00a3 100644 (file)
 
 #ifdef CONFIG_MARU
 #include "tizen/src/emulator_common.h"
-
-typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
-
-int is_wow64(void)
+/* Gets the JavaHome path from the windows registry.
+   Must call the RegOpenKeyEx by using the following flag.
+   For details, "http://stackoverflow.com/questions/10533421/
+   accessing-64-bit-registry-from-32-bit-application" */
+#define MY_KEY_WOW64_64KEY 0x0100
+void get_java_path_win32(const char **java_path)
 {
-    int result = 0;
-    LPFN_ISWOW64PROCESS fnIsWow64Process;
-
-    /* IsWow64Process is not available on all supported versions of Windows.
-       Use GetModuleHandle to get a handle to the DLL that contains the function
-       and GetProcAddress to get a pointer to the function if available. */
-
-    fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
-        GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
-
-    if (NULL != fnIsWow64Process) {
-        if (!fnIsWow64Process(GetCurrentProcess(), &result)) {
-            /* No need to handle error,
-               just check whether is this WoW64 process */
-        }
+    LONG res;
+    HKEY hKey;
+    char strKey[PATH_MAX] = {0};
+    char strVersion[PATH_MAX] = {0};
+    char strJavaHome[PATH_MAX] = {0};
+    DWORD dwBufLen = PATH_MAX;
+    static char current_java_path[PATH_MAX];
+
+    if (current_java_path[0] != '\0') {
+        *java_path = current_java_path;
+        return;
     }
-    return result;
-}
 
-static char wow64_java_path[JAVA_MAX_COMMAND_LENGTH];
-bool get_java_path(char **java_path)
-{
-    int index;
-    LONG res;
-    HKEY hKey, hSubKey;
-    char strChoosenName[JAVA_MAX_COMMAND_LENGTH] = {0};
-    char strSubKeyName[JAVA_MAX_COMMAND_LENGTH] = {0};
-    char strJavaHome[JAVA_MAX_COMMAND_LENGTH] = {0};
-    DWORD dwSubKeyNameMax = JAVA_MAX_COMMAND_LENGTH;
-    DWORD dwBufLen = JAVA_MAX_COMMAND_LENGTH;
-    char strKeyList[4][64] = {
-                /* 64bit runtime */
-                "SOFTWARE\\JavaSoft\\Java Runtime Environment",
-                "SOFTWARE\\JavaSoft\\Java Development Kit",
-                /* 32bit runtime */
-                "SOFTWARE\\Wow6432Node\\JavaSoft\\Java Runtime Environment",
-                "SOFTWARE\\Wow6432Node\\JavaSoft\\Java Development Kit"
-            };
-
-    if (wow64_java_path[0] != '\0') {
-        strcpy(*java_path, wow64_java_path);
-        return true;
+    g_strlcpy(strKey,
+              "SOFTWARE\\JavaSoft\\Java Runtime Environment",
+              PATH_MAX);
+
+    /* Opens above key to query the current version */
+    res = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                       strKey,
+                       0,
+                       KEY_QUERY_VALUE |
+                       MY_KEY_WOW64_64KEY,
+                       &hKey);
+    if (res != ERROR_SUCCESS) {
+        fprintf(stderr,
+                "oslib-win32: Java Runtime Environment key not found\n");
+        goto javahome_not_found;
     }
 
-    for (index = 0; index < ARRAY_SIZE(strKeyList); index++) {
-        res = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                           strKeyList[index],
-                           0,
-                           KEY_QUERY_VALUE |
-                           KEY_ENUMERATE_SUB_KEYS |
-                           MY_KEY_WOW64_64KEY,
-                           &hKey);
-        if (res == ERROR_SUCCESS) {
-            break;
-        }
+    /* Queries for the current version */
+    res = RegQueryValueEx(hKey,
+                          "CurrentVersion",
+                          NULL,
+                          NULL,
+                          (LPBYTE)strVersion,
+                          &dwBufLen);
+    RegCloseKey(hKey);
+    if (res != ERROR_SUCCESS) {
+        fprintf(stderr, "oslib-win32: JRE CurrentVersion not found\n");
+        goto javahome_not_found;
     }
 
+    /* Adds the current version to the key */
+    g_strlcat(strKey, "\\", PATH_MAX);
+    g_strlcat(strKey, strVersion, PATH_MAX);
+
+    /* Opens above key to query the JavaHome */
+    res = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                       strKey,
+                       0,
+                       KEY_QUERY_VALUE |
+                       MY_KEY_WOW64_64KEY,
+                       &hKey);
     if (res == ERROR_SUCCESS) {
-        index = 0;
-        do {
-            dwSubKeyNameMax = JAVA_MAX_COMMAND_LENGTH;
-            res = RegEnumKeyEx(hKey,
-                               index++,
-                               (LPSTR)strSubKeyName,
-                               &dwSubKeyNameMax,
-                               NULL, NULL, NULL, NULL);
-            if (strcmp(strChoosenName, strSubKeyName) < 0) {
-                strcpy(strChoosenName, strSubKeyName);
-            }
-        } while (res == ERROR_SUCCESS);
-
-        RegOpenKeyEx(hKey, strChoosenName, 0,
-                     KEY_QUERY_VALUE | MY_KEY_WOW64_64KEY, &hSubKey);
-        RegQueryValueEx(hSubKey, "JavaHome", NULL,
+        /* Queries for the JavaHome */
+        dwBufLen = PATH_MAX;
+        RegQueryValueEx(hKey, "JavaHome", NULL,
                         NULL, (LPBYTE)strJavaHome, &dwBufLen);
-        RegCloseKey(hSubKey);
-        RegCloseKey(hKey);
-    } else {
-        /* TODO:
-           get from %winDir%\System32
-           but, is this really needed?
-        */
-        DWORD dwRet = 0;
-        char strJavaHomeVar[JAVA_MAX_COMMAND_LENGTH] = {0,};
-        dwRet = GetEnvironmentVariable("JAVA_HOME",
-                                       strJavaHomeVar,
-                                       JAVA_MAX_COMMAND_LENGTH);
-        if (dwRet != 0 && dwRet < JAVA_MAX_COMMAND_LENGTH) {
-            strcpy(strJavaHome, strJavaHomeVar);
-        }
     }
-    if (strJavaHome[0] != '\0') {
-        sprintf(*java_path, "\"%s\\bin\\javaw.exe\"", strJavaHome);
-        strcpy(wow64_java_path, *java_path);
-    } else {
-        return false;
+    RegCloseKey(hKey);
+
+javahome_not_found:
+    if (strJavaHome[0] == '\0') {
+        dwBufLen = GetEnvironmentVariable("JAVA_HOME",
+                                          strJavaHome,
+                                          PATH_MAX);
+        if (dwBufLen == 0) {
+            fprintf(stderr, "oslib-win32: There is no JavaHome\n");
+            /* try it with "javaw.exe" */
+            *java_path = "javaw.exe";
+            return;
+        }
     }
+    g_sprintf(current_java_path, "\"%s\\bin\\javaw.exe\"", strJavaHome);
+    fprintf(stderr, "oslib-win32: CurrentVersion JavaHome path: %s\n",
+         current_java_path);
 
-    return true;
+    *java_path = current_java_path;
 }
 #endif
 
@@ -150,28 +132,15 @@ void *qemu_oom_check(void *ptr)
 #ifdef CONFIG_MARU
     const char _msg[] = "Failed to allocate memory in qemu.";
     char cmd[JAVA_MAX_COMMAND_LENGTH] = { 0, };
-    char *JAVA_EXEFILE_PATH = NULL;
+    const char *java_exefile_path = NULL;
     int len, ret;
 #endif
 
     if (ptr == NULL) {
         fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
 #ifdef CONFIG_MARU
-        JAVA_EXEFILE_PATH = malloc(JAVA_MAX_COMMAND_LENGTH);
-        if (!JAVA_EXEFILE_PATH) {
-            // TODO: print error message.
-            return ptr;
-        }
-
-        memset(JAVA_EXEFILE_PATH, 0, JAVA_MAX_COMMAND_LENGTH);
-        if (is_wow64()) {
-            if (!get_java_path(&JAVA_EXEFILE_PATH)) {
-                strcpy(JAVA_EXEFILE_PATH, "java");
-            }
-        } else {
-            strcpy(JAVA_EXEFILE_PATH, "java");
-        }
-        len = strlen(JAVA_EXEFILE_PATH) + strlen(JAVA_EXEOPTION) +
+        get_java_path(&java_exefile_path);
+        len = strlen(java_exefile_path) + strlen(JAVA_EXEOPTION) +
                   strlen(JAR_SKINFILE) + strlen(JAVA_SIMPLEMODE_OPTION) +
                   strlen(_msg) + 7;
         if (len > JAVA_MAX_COMMAND_LENGTH) {
@@ -179,16 +148,13 @@ void *qemu_oom_check(void *ptr)
         }
 
         snprintf(cmd, len, "%s %s %s %s=\"%s\"",
-            JAVA_EXEFILE_PATH, JAVA_EXEOPTION, JAR_SKINFILE,
+            java_exefile_path, JAVA_EXEOPTION, JAR_SKINFILE,
             JAVA_SIMPLEMODE_OPTION, _msg);
         ret = WinExec(cmd, SW_SHOW);
         if (ret < 32) {
             // TODO: error handling...
         }
-
-        /* for 64bit windows */
-        free(JAVA_EXEFILE_PATH);
-        JAVA_EXEFILE_PATH=0;
+        java_exefile_path = NULL;
 #endif
         abort();
     }