alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Glassfish example source code file (java_md.winnt.c)

This example Glassfish source code file (java_md.winnt.c) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

closehandle, file_separator, file_separator, jni_false, jni_false, jni_true, loadwindows, memalloc, memalloc, min_text_margin, null, null, r_ok, regclosekey

The Glassfish java_md.winnt.c source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2008-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

#include <sys/types.h>

#include "java.h"
#include "resource.h"

#define JAVA_DLL "java.dll"

#define PIPE_SIZE 512

#define MIN_TEXT_MARGIN 10

struct jvminfo {
    char *version;
    char *path;
    struct jvminfo *next;
};

typedef const wchar_t *(*message_t)(void);

/*
 * Prototypes.
 */
static void
HideStatusWindow(void);

static INT_PTR CALLBACK
StatusCallback(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);

const char *
GetArch()
{
#ifdef _WIN64
    return "ia64";
#else
    return "i386";
#endif
}

static HANDLE lockfile = NULL;

static void
DeleteLockFile(void)
{
    if (lockfile)
        UnlockFile(lockfile, 0, 0, 1, 0);
}

void
ExitIfNotOnlyInstance()
{
    const char *execname;

    /*
     * Use an exclusive lock on the executable file to determine if another
     * instance is already running.
     */
    if ((execname = GetExecName()) != NULL && (lockfile = CreateFile(execname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != NULL)
    {
        if (LockFile(lockfile, 0, 0, 1, 0) == 0)
        {
            char *key = NULL;
            char *message = NULL;

            key = GetMessageKeyPrefix("already_started");
            message = GetLocalizedMessage(key);
            free(key);
            key = NULL;
            fprintf(stderr, message);
            free(message);
            message = NULL;
            exit(1);
        }
        atexit(DeleteLockFile);
    }
    return;
}

static char *tmpdir = NULL;

jboolean
SetTempDir(const char *path)
{
    char *tmppath = NULL;
    struct stat sb;

    if (path && !IsAbsolutePath(path))
    {
        char *cwd = NULL;
        unsigned int size = MAXPATHLEN;

        cwd = (char *)MemAlloc(size);
        while (GetCurrentDirectory(size, cwd) >= size)
        {
            size += MAXPATHLEN;
            free(cwd);
            cwd = (char *)MemAlloc(size);
        }
        tmppath = (char *)MemAlloc(strlen(cwd) + strlen(path) + 2);
        sprintf(tmppath, "%s" FILE_SEPARATOR "%s", cwd, path);
        free(cwd);
        cwd = NULL;
    }
    else
    {
        tmppath = StrDup(path);
    }
    if (tmppath[strlen(tmppath) - 1] == FILE_SEPARATOR_CHAR)
        tmppath[strlen(tmppath) - 1] = '\0';
    if (access(tmppath, R_OK | W_OK) == 0 && stat(tmppath, &sb) == 0 && (sb.st_mode & S_IFDIR) == S_IFDIR)
    {
        if (tmpdir)
            free(tmpdir);
        tmpdir = tmppath;
        return JNI_TRUE;
    }
    free(tmppath);
    tmppath = NULL;
    return JNI_FALSE;
}

#ifndef RES_BUNDLE_NAME
#error RES_BUNDLE_NAME macro must be set
#endif

/*
 * Retrieve a localized message from the resource bundle compiled into the
 * executable.
 */
char *
GetLocalizedMessage(const char *key)
{
    char *fullkey = NULL;
    char *lc = NULL;
    message_t sym = NULL;
    const wchar_t *value;
    int size;
    char *ret = NULL;

    lc = StrDup(GetLocale());
    fullkey = (char *)MemAlloc(sizeof(RES_BUNDLE_NAME) + strlen(lc) + strlen(key
) + 3);
    while (!sym)
    {
        strcpy(fullkey, RES_BUNDLE_NAME);
        if (strlen(lc) > 0)
        {
            strcat(fullkey, "_");
            strcat(fullkey, lc);
        }
        strcat(fullkey, "_");
        strcat(fullkey, key);
        if ((sym = (message_t)GetProcAddress(NULL, fullkey)) == NULL)
        {
            if (strlen(lc) > 0)
            {
                char *s;
                if ((s = strrchr(lc, '_')) != NULL)
                    *s = '\0';
                else
                    *lc = '\0';
            }
            else
            {
                goto error;
            }
        }
        else
        {
            break;
        }
    }
    free(lc);
    lc = NULL;
    free(fullkey);
    fullkey = NULL;
    if ((value = sym()) == NULL)
        goto error;
    if ((size = WideCharToMultiByte(GetACP() ? CP_ACP : CP_UTF8, 0, value, -1, NULL, 0, NULL, NULL)) < 0)
        goto error;
    ret = (char *)MemAlloc(size);
    if ((size = WideCharToMultiByte(GetACP() ? CP_ACP : CP_UTF8, 0, value, -1, ret, size, NULL, NULL)) < 0)
        goto error;

    return ret;

error:
    /* Always return a valid string */
    if (lc)
        free(lc);
    lc = NULL;
    if (fullkey)
        free(fullkey);
    fullkey = NULL;
    if (ret)
        free(ret);
    ret = (char *)MemAlloc(1);
    ret[0] = '\0';
    return ret;
}

const char *
GetTempDir()
{
    if (!tmpdir)
    {
        char *path = NULL;
        int size = MAXPATHLEN;
        int ret;

        path = (char *)MemAlloc(size);
        while ((ret = GetTempPath(size, path)) != 0 && ret >= size)
        {
            size = ret;
            free(path);
            path = (char *)MemAlloc(size);
        }
        if (ret)
        {
            SetTempDir(path);
        }
        else
        {
            free(path);
            path = NULL;
        }
    }
    return tmpdir;
}

/*
 * Find path to JRE based on a user specified Java installation directory.
 */
char *
GetJREPath(const char *path)
{
    char *libjava = NULL;

    libjava = (char *)MemAlloc(strlen(path) + strlen(JAVA_DLL) + 11);

    /* Is JRE co-located with the application? */
    sprintf(libjava, "%s" FILE_SEPARATOR "bin" FILE_SEPARATOR JAVA_DLL, path);
    if (access(libjava, R_OK) == 0)
    {
        strcpy(libjava, path);
        goto found;
    }

    /* Does the app ship a private JRE in <apphome>/jre directory? */
    sprintf(libjava, "%s" FILE_SEPARATOR "jre" FILE_SEPARATOR "bin" FILE_SEPARATOR JAVA_DLL, path);
    if (access(libjava, R_OK) == 0)
    {
        sprintf(libjava, "%s" FILE_SEPARATOR "jre", path);
        goto found;
    }

    if (libjava)
        free(libjava);
    libjava = NULL;

found:
    if (libjava)
    {
        char *java = NULL;
        char *javaw = NULL;
        char *keytool = NULL;

        /* Check that executables exist */
        java = (char *)MemAlloc(strlen(libjava) + strlen(JAVA_EXE) + 1);
        javaw = (char *)MemAlloc(strlen(libjava) + strlen(JAVAW_EXE) + 1);
        keytool = (char *)MemAlloc(strlen(libjava) + strlen(KEYTOOL_EXE) + 1);
        sprintf(java, "%s" JAVA_EXE, libjava);
        sprintf(javaw, "%s" JAVAW_EXE, libjava);
        sprintf(keytool, "%s" KEYTOOL_EXE, libjava);
        if (access(java, R_OK) != 0 || access(javaw, R_OK) != 0 || access(keytool, R_OK) != 0)
        {
            free(libjava);
            libjava = NULL;
        }
        free(java);
        java = NULL;
        free(javaw);
        javaw = NULL;
        free(keytool);
        keytool = NULL;
    }
    return libjava;
}

/*
 * Helpers to look in the registry for a public JRE.
 */
static char *
GetStringFromRegistry(HKEY key, const char *name)
{
    char *regvalue = NULL;
    DWORD type, size;

    if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0)
    {
        regvalue = (char *)MemAlloc(size + 1);
        if (RegQueryValueEx(key, name, 0, 0, regvalue, &size) != 0)
        {
            free(regvalue);
            regvalue = NULL;
        }
    }
    return regvalue;
}

HINSTANCE instance = NULL;
HWND statusdialog = NULL;
static char *statusmessage = NULL;
static jboolean dispatch = JNI_FALSE;

static DWORD
WINAPI DispatchWindowsEvents(LPVOID arg)
{
    /* Create the dialog */
    if ((statusdialog = CreateDialog(instance, MAKEINTRESOURCE(IDD_DIALOGBAR), NULL, StatusCallback)) == NULL)
        return 1;

    /* Set title */
    SetWindowText(statusdialog, GetTitle());

    while (dispatch)
    {
        MSG msg;

        if (GetMessage(&msg, statusdialog, 0, 0) != -1)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        Sleep(0);
    }

    /* Destry the dialog */
    HideStatusWindow();
    DestroyWindow(statusdialog);
    statusdialog = NULL;
    return 0;
}

static INT_PTR CALLBACK
StatusCallback(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    HDC dc;
    PAINTSTRUCT ps;
    INT_PTR ret = FALSE;

    switch (uMsg)
    {
        case WM_PAINT:
            InvalidateRect(statusdialog, NULL, TRUE);
            if (hWndDlg && statusmessage && (dc = BeginPaint(hWndDlg, &ps)) != NULL)
            {
                NONCLIENTMETRICS metrics;
                HFONT font = NULL;
                HFONT oldfont = NULL;
                RECT dialogrect;
                RECT textrect;
                RECT oldtextrect;
                int textheight;
                jboolean resize = JNI_FALSE;

                /* Attempt to get the standard message box font */
                metrics.cbSize = sizeof(NONCLIENTMETRICS);
                if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &metrics, 0) && (font = CreateFontIndirect(&metrics.lfMessageFont)) != NULL)
                    oldfont = SelectObject(dc, font);

                /*
                 * Calculate how much space we need for the text and resize
                 * and resize dialog if necessary
                 */
                GetWindowRect(hWndDlg, &dialogrect);
                textrect.left = MIN_TEXT_MARGIN;
                textrect.top = MIN_TEXT_MARGIN;
                textrect.right = dialogrect.right - dialogrect.left - MIN_TEXT_MARGIN;
                textrect.bottom = dialogrect.bottom - dialogrect.top - MIN_TEXT_MARGIN;
                CopyRect(&oldtextrect, &textrect);
                textheight = DrawText(dc, statusmessage, -1, &textrect, DT_CALCRECT | DT_CENTER | DT_EXPANDTABS | DT_NOPREFIX);
                if (textrect.right > oldtextrect.right)
                {
                    LONG adjust = ((textrect.right - oldtextrect.right) / 2) + ((textrect.right - oldtextrect.right) % 2);
                    resize = JNI_TRUE;
                    dialogrect.left -= adjust;
                    dialogrect.right += adjust;
                }
                if (textrect.bottom > oldtextrect.bottom)
                {
                    LONG adjust = ((textrect.bottom - oldtextrect.bottom) / 2) + ((textrect.bottom - oldtextrect.bottom) % 2);
                    dialogrect.top -= adjust;
                    dialogrect.bottom += adjust;
                    resize = JNI_TRUE;
                }
                if (resize)
                {
                    SetWindowPos(hWndDlg, HWND_TOP, dialogrect.left, dialogrect.top, dialogrect.right - dialogrect.left, dialogrect.bottom - dialogrect.top, 0);
                    GetWindowRect(hWndDlg, &dialogrect);
                }
                textrect.left = MIN_TEXT_MARGIN;
                textrect.top += (dialogrect.bottom - dialogrect.top - MIN_TEXT_MARGIN - textrect.top - textheight) / 2;
                textrect.right = dialogrect.right - dialogrect.left - MIN_TEXT_MARGIN;
                textrect.bottom = textrect.top + textheight;
                DrawText(dc, statusmessage, -1, &textrect, DT_CENTER | DT_EXPANDTABS | DT_NOPREFIX);
                if (oldfont)
                {
                    SelectObject(dc, oldfont);
                    oldfont = NULL;
                }
                if (font)
                {
                    DeleteObject(font);
                    font = NULL;
                }
                EndPaint(hWndDlg, &ps);
            }
            ret = TRUE;
            break;
        case WM_USER:
            if (lParam)
            {
                char *oldmessage = statusmessage;
                statusmessage = (char *)lParam;
                if (oldmessage)
                    free(oldmessage);
                oldmessage = NULL;
                ShowWindow(statusdialog, SW_SHOW);
                InvalidateRect(statusdialog, NULL, TRUE);
                SetForegroundWindow(statusdialog);
                UpdateWindow(statusdialog);
            }
            ret = TRUE;
            break;
        default:
            ret = FALSE;
            break;
    }
    return ret;
}

static jboolean
LoadWindows()
{
    static jboolean loadingwin = JNI_FALSE;
    HANDLE thrd = NULL;
    DWORD ctid = GetCurrentThreadId();
    DWORD tid;

    if (!instance)
        return JNI_FALSE;

    if (loadingwin)
        return JNI_FALSE;

    if (dispatch)
        return JNI_TRUE;

    loadingwin = JNI_TRUE;

    /* Initialize the lock */
    if (!dispatch)
        dispatch = JNI_TRUE;

    /* Create the event loop thread */
    if ((thrd = CreateThread(NULL, 0, DispatchWindowsEvents, &ctid, 0, &tid)) == NULL)
        goto error;

    /* Raise the thread's priority so that it is guaranteed a time slice */
    if (!SetThreadPriority(thrd, THREAD_PRIORITY_HIGHEST))
        goto error;

    loadingwin = JNI_FALSE;
    return JNI_TRUE;

error:
    if (dispatch)
    {
        dispatch = JNI_FALSE;
        if (thrd)
        {
            WaitForSingleObject(thrd, INFINITE);
            CloseHandle(thrd);
        }
    }
    loadingwin = JNI_FALSE;
    return JNI_FALSE;
}

static int
PrintToStatusWindow(const char *format, va_list args)
{
    int ret;
    int increment = 1024;
    int size = increment;
    char *message = NULL;
    int cachedlen = 0;
    static char *cachedmessage = NULL;

    if (cachedmessage)
        cachedlen = strlen(cachedmessage);
    for (;;)
    {
        message = (char *)MemAlloc(cachedlen + size);
        if (cachedmessage)
            strcpy(message, cachedmessage);

        ret = _vsnprintf(message + cachedlen, size, format, args);
        if (ret < 0 || ret >= size)
        {
            size += increment;
            free(message);
            message = NULL;
            continue;
        }
        break;
    }
    if (cachedmessage)
        free(cachedmessage);
    cachedmessage = NULL;

    if (LoadWindows() && dispatch)
    {
        if (message[strlen(message) - 1] == '\n')
        {
            /* Chop off trailing newline */
            message[strlen(message) - 1] = '\0';
        }
        else
        {
            /* If there is no newline, cache message and print later */
            cachedmessage = message;
            message = NULL;
            ret = 0;
        }

        if (statusdialog)
        {
            ret = strlen(message);
            if (PostMessage(statusdialog, WM_USER, 0, (LPARAM)message))
                message = NULL;
            else
                ret = vprintf(message, NULL);
        }
        else
        {
            ret = vprintf(message, NULL);
        }
    }
    else
    {
        ret = vprintf(message, NULL);
    }

    if (message)
        free(message);
    message = NULL;
    return ret;
}

static void
HideStatusWindow()
{
    if (LoadWindows() && dispatch && statusdialog)
        ShowWindow(statusdialog, SW_HIDE);
}

static int
PrintToMessageBox(UINT type, const char *format, va_list args)
{
    int ret;
    int increment = 1024;
    int size = increment;
    char *message = NULL;
    int cachedlen = 0;
    static char *cachedmessage = NULL;

    if (cachedmessage)
        cachedlen = strlen(cachedmessage);
    for (;;)
    {
        message = (char *)MemAlloc(cachedlen + size);
        if (cachedmessage)
            strcpy(message, cachedmessage);

        ret = _vsnprintf(message + cachedlen, size, format, args);
        if (ret < 0 || ret >= size)
        {
            size += increment;
            free(message);
            message = NULL;
            continue;
        }
        break;
    }
    if (cachedmessage)
        free(cachedmessage);
    cachedmessage = NULL;

    if (LoadWindows() && dispatch)
    {
        if (message[strlen(message) - 1] == '\n')
        {
            /* Chop off trailing newline */
            message[strlen(message) - 1] = '\0';
        }
        else
        {
            /* If there is no newline, cache message and print later */
            cachedmessage = message;
            message = NULL;
            ret = 0;
        }

        if (type == MB_ICONINFORMATION)
            MessageBox(statusdialog, message, GetTitle(), MB_OK | MB_APPLMODAL | MB_ICONINFORMATION);
        else
            MessageBox(statusdialog, message, GetTitle(), MB_OK | MB_APPLMODAL | MB_ICONERROR);
    }
    else
    {
        ret = vprintf(message, NULL);
    }

    if (message)
        free(message);
    message = NULL;
    return ret;
}

#define JDK_KEY "Software" FILE_SEPARATOR "JavaSoft" FILE_SEPARATOR "Java Development Kit"
#define JRE_KEY "Software" FILE_SEPARATOR "JavaSoft" FILE_SEPARATOR "Java Runtime Environment"
#define JAVA_HOME_VALUE "JavaHome"

char *
GetPublicJREPath()
{
    const char *envvar;
    struct jvminfo *bundledjdk = NULL;
    struct jvminfo *bundledjre = NULL;
    struct jvminfo *jdks = NULL;
    struct jvminfo *jres = NULL;
    char *jrefoundpath = NULL;
    HKEY key, subkey;
    int index;
    char subkeyName[MAXPATHLEN];
    int subkeySize;
    FILETIME subkeyTime;

    if ((envvar = GetBundledJREPath()) != NULL)
    {
        struct jvminfo *info = (struct jvminfo *)MemAlloc(sizeof(struct jvminfo)
);
        info->version = NULL;
        info->path = (char *)MemAlloc(strlen(envvar) + 1);
        info->next = NULL;
        strcpy(info->path, envvar);
        if (IsJDK(envvar))
            bundledjdk = info;
        else
            bundledjre = info;
    }

    /* Look for a public JDK in the Windows registry. */
    if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, JDK_KEY, 0, KEY_ALL_ACCESS, &key))
    {
        jboolean jdkfound = JNI_FALSE;

        index = 0;
        subkeySize = sizeof(subkeyName);
        /* Iterate through each of the JDK version keys */
        while (RegEnumKeyEx(key, index++, subkeyName, &subkeySize, NULL, NULL, NULL, &subkeyTime) == 0)
        {
            char *javapath;
            char *jrepath = NULL;
            subkeySize = sizeof(subkeyName);

            if (RegOpenKeyEx(key, subkeyName, 0, KEY_READ, &subkey) != 0)
                continue;

            /* Find a matching supported version */
            if (!CheckVersion(subkeyName))
            {
                RegCloseKey(subkey);
                continue;
            }

            if ((javapath = GetStringFromRegistry(subkey, JAVA_HOME_VALUE)) == NULL)
            {
                RegCloseKey(subkey);
                continue;
            }

            if ((jrepath = GetJREPath(javapath)) != NULL)
            {
                struct jvminfo *info = (struct jvminfo *)MemAlloc(sizeof(struct jvminfo));
                info->version = (char *)MemAlloc(strlen(subkeyName) + 1);
                strcpy(info->version, subkeyName);
                info->path = jrepath;
                if (IsJDK(jrepath))
                {
                    info->next = jdks;
                    jdks = info;
                }
                else
                {
                    info->next = jres;
                    jres = info;
                }
            }
            else
            {
                free(jrepath);
                jrepath = NULL;
            }
            free(javapath);
            javapath = NULL;
            RegCloseKey(subkey);
            if (jdkfound)
            {
                RegCloseKey(key);
                goto found;
            }
        }
        RegCloseKey(key);
    }

    /* Look for a public JRE in the Windows registry. */
    if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, JRE_KEY, 0, KEY_ALL_ACCESS, &key))
    {
        jboolean jdkfound = JNI_FALSE;

        index = 0;
        subkeySize = sizeof(subkeyName);
        /* Iterate through each of the JRE version keys */
        while (RegEnumKeyEx(key, index++, subkeyName, &subkeySize, NULL, NULL, NULL, &subkeyTime) == 0)
        {
            char *javapath;
            char *jrepath = NULL;
            subkeySize = sizeof(subkeyName);

            if (RegOpenKeyEx(key, subkeyName, 0, KEY_READ, &subkey) != 0)
                continue;

            /* Find a matching supported version */
            if (!CheckVersion(subkeyName))
            {
                RegCloseKey(subkey);
                continue;
            }

            if ((javapath = GetStringFromRegistry(subkey, JAVA_HOME_VALUE)) == NULL)
            {
                RegCloseKey(subkey);
                continue;
            }

            if ((jrepath = GetJREPath(javapath)) != NULL)
            {
                struct jvminfo *info = (struct jvminfo *)MemAlloc(sizeof(struct jvminfo));
                info->version = (char *)MemAlloc(strlen(subkeyName) + 1);
                strcpy(info->version, subkeyName);
                info->path = jrepath;
                if (IsJDK(jrepath))
                {
                    info->next = jdks;
                    jdks = info;
                }
                else
                {
                    info->next = jres;
                    jres = info;
                }
            }
            else
            {
                free(jrepath);
                jrepath = NULL;
            }
            free(javapath);
            javapath = NULL;
            RegCloseKey(subkey);
        }
        RegCloseKey(key);
    }

    /* Make bundled JDK first choice */
    if (bundledjdk)
    {
        if (!jrefoundpath)
            jrefoundpath = bundledjdk->path;
        else
            free(bundledjdk->path);
        free(bundledjdk);
        bundledjdk = NULL;
    }

    /* Iterate through JDKs and use the one with the highest version */
    while (jdks && jdks->next)
    {
        struct jvminfo *info;
        if (jrefoundpath || strcmp(jdks->next->version, jdks->version) > 0)
        {
            info = jdks;
            jdks = jdks->next;
        }
        else
        {
            info = jdks->next;
            jdks->next = jdks->next->next;
        }
        free(info->version);
        free(info->path);
        free(info);
        info = NULL;
    }
    if (jdks)
    {
        if (!jrefoundpath)
            jrefoundpath = jdks->path;
        else
            free(jdks->path);
        free(jdks->version);
        free(jdks);
        jdks = NULL;
    }

    /* Make bundled JRE the next choice */
    if (bundledjre)
    {
        if (!jrefoundpath)
            jrefoundpath = bundledjre->path;
        else
            free(bundledjre->path);
        free(bundledjre);
        bundledjre = NULL;
    }

    /* Iterate through JREs and use the one with the highest version */
    while (jres && jres->next)
    {
        struct jvminfo *info;
        if (jrefoundpath || strcmp(jres->next->version, jres->version) > 0)
        {
            info = jres;
            jres = jres->next;
        }
        else
        {
            info = jres->next;
            jres->next = jres->next->next;
        }
        free(info->version);
        free(info->path);
        free(info);
        info = NULL;
    }
    if (jres)
    {
        if (!jrefoundpath)
            jrefoundpath = jres->path;
        else
            free(jres->path);
        free(jres->version);
        free(jres);
        jres = NULL;
    }

found:
    return jrefoundpath;
}

jboolean
IsJDK(const char* path)
{
    jboolean isJDK = JNI_FALSE;
    char *toolsjar = (char *)MemAlloc(strlen(path) + sizeof(TOOLS_JAR_FILE) + 4)
;
    char *dir = strrchr(path, FILE_SEPARATOR_CHAR);

    /* Does the app ship a private JRE in <apphome>/jre directory? */
    if (dir && !strcmp(dir, FILE_SEPARATOR "jre"))
    {
        sprintf(toolsjar, "%s" FILE_SEPARATOR ".." TOOLS_JAR_FILE,  path);
        if (access(toolsjar, R_OK) == 0)
        {
            isJDK = JNI_TRUE;
            goto found;
        }
    }
    /* Is JRE co-located with the application? */
    else
    {
        sprintf(toolsjar, "%s" TOOLS_JAR_FILE,  path);
        if (access(toolsjar, R_OK) == 0)
        {
            isJDK = JNI_TRUE;
            goto found;
        }
    }

found:
    free(toolsjar);
    toolsjar = NULL;
    return isJDK;
}

/* Default to GUI mode */
static jboolean printToConsole = JNI_FALSE;

jboolean
GetPrintToConsole()
{
    return printToConsole;
}

void
SetPrintToConsole(jboolean mode)
{
    printToConsole = mode;
}

int
_printf(const char *format, ...)
{
    int ret;
    va_list args;
    va_start(args, format);
    if (printToConsole || !LoadWindows())
        ret = vprintf(format, args);
    else
        ret = PrintToMessageBox(MB_ICONINFORMATION, format, args);
    va_end(args);
    fflush(stdout);
    return ret;
}

int
_fprintf(FILE *stream, const char *format, ...)
{
    int ret;
    va_list args;
    va_start(args, format);
    if (printToConsole || !LoadWindows())
    {
        ret = vprintf(format, args);
    }
    else
    {
        if (stream == stderr)
            ret = PrintToMessageBox(MB_ICONERROR, format, args);
        else
            ret = PrintToMessageBox(MB_ICONINFORMATION, format, args);
    }
    va_end(args);
    fflush(stream);
    return ret;
}

int
statusf(const char *format, ...)
{
    int ret;
    va_list args;
    va_start(args, format);
    if (format)
    {
        if (printToConsole || !LoadWindows())
            ret = vprintf(format, args);
        else
            ret = PrintToStatusWindow(format, args);
    }
    else
    {
        HideStatusWindow();
    }
    va_end(args);
    return ret;
}

/*
 * Encodings for Windows language groups. Some locales do not have codepages,
 * and are supported in Windows 2000 solely through Unicode, so we also add
 * the appropriate Unicode variant.
 *
 * Note: this table is copied from the windows/native/common/locale_str.h
 * header in the J2SE 1.4.1 source code and should be updated as new releases
 * of J2SE come out.
 */
static const char *encoding_names[] = {
    "Cp1250",    /*  0:Latin 2  */
    "Cp1251",    /*  1:Cyrillic */
    "Cp1252",    /*  2:Latin 1  */
    "Cp1253",    /*  3:Greek    */
    "Cp1254",    /*  4:Latin 5  */
    "Cp1255",    /*  5:Hebrew   */
    "Cp1256",    /*  6:Arabic   */
    "Cp1257",    /*  7:Baltic   */
    "Cp1258",    /*  8:Viet Nam */
    "MS874",     /*  9:Thai     */
    "MS932",     /* 10:Japanese */
    "GBK",       /* 11:PRC GBK  */
    "MS949",     /* 12:Korean Extended Wansung */
    "MS950",     /* 13:Chinese (Taiwan, Hongkong, Macau) */
    "utf-16le",  /* 14:Unicode  */
    "MS1361",    /* 15:Korean Johab */
};

/*
 * List mapping from LanguageID to Java locale IDs.
 *
 * Note: this table is copied from the windows/native/common/locale_str.h
 * header in the J2SE 1.4.1 source code and should be updated as new releases
 * of J2SE come out.
 */
typedef struct LANGIDtoLocale {
    const WORD    langID;
    const WORD    encoding;
    const char*   javaID;
} LANGIDtoLocale;

static const LANGIDtoLocale langIDMap[] = {
    /* fallback locales to use when the country code doesn't match anything we have */
    0x01,    6, "ar",
    0x02,    1, "bg",
    0x03,    2, "ca",
    0x04,   11, "zh",
    0x05,    0, "cs",
    0x06,    2, "da",
    0x07,    2, "de",
    0x08,    3, "el",
    0x09,    2, "en",
    0x0a,    2, "es",
    0x0b,    2, "fi",
    0x0c,    2, "fr",
    0x0d,    5, "iw",
    0x0e,    0, "hu",
    0x0f,    2, "is",
    0x10,    2, "it",
    0x11,   10, "ja",
    0x12,   12, "ko",
    0x13,    2, "nl",
    0x14,    2, "no",
    0x15,    0, "pl",
    0x16,    2, "pt",
    0x17,    2, "rm",
    0x18,    0, "ro",
    0x19,    1, "ru",
    0x1a,    0, "sh",
    0x1b,    0, "sk",
    0x1c,    0, "sq",
    0x1d,    2, "sv",
    0x1e,    9, "th",
    0x1f,    4, "tr",
    0x20,    2, "ur",
    0x21,    2, "in",
    0x22,    1, "uk",
    0x23,    1, "be",
    0x24,    0, "sl",
    0x25,    7, "et",
    0x26,    7, "lv",
    0x27,    7, "lt",
    0x29,    6, "fa",
    0x2a,    8, "vi",
    0x2b,   14, "hy",
    0x2c,    4, "az",
    0x2d,    2, "eu",
    0x2f,    1, "mk",
    0x31,    2, "ts",
    0x32,    2, "tn",
    0x34,    2, "xh",
    0x35,    2, "zu",
    0x36,    2, "af",
    0x37,   14, "ka",
    0x38,    2, "fo",
    0x39,   14, "hi",
    0x3a,    2, "mt",
    0x3c,    2, "gd",
    0x3d,    2, "yi",
    0x3e,    2, "ms",
    0x3f,    1, "kk",
    0x40,    1, "ky",
    0x41,    2, "sw",
    0x43,    1, "uz",
    0x44,    1, "tt",
    0x46,   14, "pa",
    0x47,   14, "gu",
    0x49,   14, "ta",
    0x4a,   14, "te",
    0x4b,   14, "kn",
    0x4e,   14, "mr",
    0x4f,   14, "sa",
    0x50,    1, "mn",
    0x56,    2, "gl",
    /* mappings for real Windows LCID values */
    0x0401,  6, "ar_SA",
    0x0402,  1, "bg_BG",
    0x0403,  2, "ca_ES",
    0x0404, 13, "zh_TW",
    0x0405,  0, "cs_CZ",
    0x0406,  2, "da_DK",
    0x0407,  2, "de_DE",
    0x0408,  3, "el_GR",
    0x0409,  2, "en_US",
    0x040a,  2, "es_ES",  /* (traditional sort) */
    0x040b,  2, "fi_FI",
    0x040c,  2, "fr_FR",
    0x040d,  5, "iw_IL",
    0x040e,  0, "hu_HU",
    0x040f,  2, "is_IS",
    0x0410,  2, "it_IT",
    0x0411, 10, "ja_JP",
    0x0412, 12, "ko_KR",
    0x0413,  2, "nl_NL",
    0x0414,  2, "no_NO",
    0x0415,  0, "pl_PL",
    0x0416,  2, "pt_BR",
    0x0417,  2, "rm_CH",
    0x0418,  0, "ro_RO",
    0x0419,  1, "ru_RU",
    0x041a,  0, "hr_HR",
    0x041b,  0, "sk_SK",
    0x041c,  0, "sq_AL",
    0x041d,  2, "sv_SE",
    0x041e,  9, "th_TH",
    0x041f,  4, "tr_TR",
    0x0420,  6, "ur_PK",
    0x0421,  2, "in_ID",
    0x0422,  1, "uk_UA",
    0x0423,  1, "be_BY",
    0x0424,  0, "sl_SI",
    0x0425,  7, "et_EE",
    0x0426,  7, "lv_LV",
    0x0427,  7, "lt_LT",
    0x0429,  6, "fa_IR",
    0x042a,  8, "vi_VN",
    0x042b, 14, "hy_AM",  /* Armenian  */
    0x042c,  4, "az_AZ",  /* Azeri_Latin */
    0x042d,  2, "eu_ES",
/*  0x042e,  2, "??",      no ISO-639 abbreviation for Sorbian */
    0x042f,  1, "mk_MK",
/*  0x0430,  2, "??",      no ISO-639 abbreviation for Sutu */
    0x0431,  2, "ts",     /* (country?) */
    0x0432,  2, "tn_BW",
/*  0x0433,  2, "??",      no ISO-639 abbreviation for Venda */
    0x0434,  2, "xh",     /* (country?) */
    0x0435,  2, "zu",     /* (country?) */
    0x0436,  2, "af_ZA",
    0x0437, 14, "ka_GE",  /* Georgian   */
    0x0438,  2, "fo_FO",
    0x0439, 14, "hi_IN",
    0x043a,  2, "mt_MT",
/*  0x043b,  2, "??",      no ISO-639 abbreviation for Sami */
    0x043c,  2, "gd_GB",
    0x043d,  2, "yi",     /* (country?) */
    0x043e,  2, "ms_MY",
    0x043f,  1, "kk_KZ",  /* Kazakh */
    0x0440,  1, "ky_KG",  /* Kyrgyz     */
    0x0441,  2, "sw_KE",
    0x0443,  1, "uz_UZ",  /* Uzbek_Cyrillic*/
    0x0444,  1, "tt",     /* Tatar, no ISO-3166 abbreviation */
    0x0446, 14, "pa_IN",  /* Punjabi   */
    0x0447, 14, "gu_IN",  /* Gujarati  */
    0x0449, 14, "ta_IN",  /* Tamil     */
    0x044a, 14, "te_IN",  /* Telugu    */
    0x044b, 14, "kn_IN",  /* Kannada   */
    0x044e, 14, "mr_IN",  /* Marathi   */
    0x044f, 14, "sa_IN",  /* Sanskrit  */
    0x0450,  1, "mn_MN",  /* Mongolian */
    0x0456,  2, "gl_ES",  /* Galician  */
/*  0x0457, 14, "??_IN",  /* Konkani, no ISO-639 abbreviation*/
/*  0x045a, 14, "??_SY",  /* Syriac, no ISO-639 abbreviation*/
/*  0x0465, 14, "??_MV",  /* Divehi, no ISO-639 abbreviation*/
    0x0801,  6, "ar_IQ",
    0x0804, 11, "zh_CN",
    0x0807,  2, "de_CH",
    0x0809,  2, "en_GB",
    0x080a,  2, "es_MX",
    0x080c,  2, "fr_BE",
    0x0810,  2, "it_CH",
    0x0812, 15, "ko_KR",  /* Korean(Johab)*/
    0x0813,  2, "nl_BE",
    0x0814,  2, "no_NO_NY",
    0x0816,  2, "pt_PT",
    0x0818,  0, "ro_MD",
    0x0819,  1, "ru_MD",
    0x081a,  0, "sh_YU",
    0x081d,  2, "sv_FI",
    0x082c,  1, "az_AZ",  /* Azeri_Cyrillic */
    0x083c,  2, "ga_IE",
    0x083e,  2, "ms_BN",
    0x0843,  4, "uz_UZ",  /* Uzbek_Latin  */
    0x0c01,  6, "ar_EG",
    0x0c04, 13, "zh_HK",
    0x0c07,  2, "de_AT",
    0x0c09,  2, "en_AU",
    0x0c0a,  2, "es_ES",  /* (modern sort) */
    0x0c0c,  2, "fr_CA",
    0x0c1a,  1, "sr_YU",
    0x1001,  6, "ar_LY",
    0x1004, 11, "zh_SG",
    0x1007,  2, "de_LU",
    0x1009,  2, "en_CA",
    0x100a,  2, "es_GT",
    0x100c,  2, "fr_CH",
    0x1401,  6, "ar_DZ",
    0x1404, 13, "zh_MO",
    0x1407,  2, "de_LI",
    0x1409,  2, "en_NZ",
    0x140a,  2, "es_CR",
    0x140c,  2, "fr_LU",
    0x1801,  6, "ar_MA",
    0x1809,  2, "en_IE",
    0x180a,  2, "es_PA",
    0x180c,  2, "fr_MC",
    0x1c01,  6, "ar_TN",
    0x1c09,  2, "en_ZA",
    0x1c0a,  2, "es_DO",
    0x2001,  6, "ar_OM",
    0x2009,  2, "en_JM",
    0x200a,  2, "es_VE",
    0x2401,  6, "ar_YE",
    0x2409,  2, "en",     /* ("Caribbean", which could be any of many countries) */
    0x240a,  2, "es_CO",
    0x2801,  6, "ar_SY",
    0x2809,  2, "en_BZ",
    0x280a,  2, "es_PE",
    0x2c01,  6, "ar_JO",
    0x2c09,  2, "en_TT",
    0x2c0a,  2, "es_AR",
    0x3001,  6, "ar_LB",
    0x3009,  2, "en_ZW",
    0x300a,  2, "es_EC",
    0x3401,  6, "ar_KW",
    0x3409,  2, "en_PH",
    0x340a,  2, "es_CL",
    0x3801,  6, "ar_AE",
    0x380a,  2, "es_UY",
    0x3c01,  6, "ar_BH",
    0x3c0a,  2, "es_PY",
    0x4001,  6, "ar_QA",
    0x400a,  2, "es_BO",
    0x440a,  2, "es_SV",
    0x480a,  2, "es_HN",
    0x4c0a,  2, "es_NI",
    0x500a,  2, "es_PR"
};

static const char *locale = NULL;

const char *
GetLocale()
{
    if (!locale)
    {
        int index = -1;
        int tries = 0;

        /*
         * Query the system for the current system default locale
         * (which is a Windows LCID value),
         */
        LANGID langID = LANGIDFROMLCID(GetThreadLocale());

        /*
         * binary-search our list of LANGID values.  If we don't find the
	 * one we're looking for, mask out the country code and try again
	 * with just the primary language ID
         */
        do
        {
            int lo, hi, mid;
            lo = 0;
            hi = sizeof(langIDMap) / sizeof(LANGIDtoLocale);
            while (index == -1 && lo < hi)
            {
                mid = (lo + hi) / 2;
                if (langIDMap[mid].langID == langID)
                    index = mid;
                else if (langIDMap[mid].langID > langID)
                    hi = mid;
                else
                    lo = mid + 1;
            }
            langID = PRIMARYLANGID(langID);
            ++tries;
        } while (index == -1 && tries < 2);

        /*
         * If we found the LCID, look up the corresponding Java locale ID from
         * the list of Java locale IDs and set up the system properties
         * accordingly. Otherwise, fall back to "en".
         */
        if (index != -1)
            locale = langIDMap[index].javaID;
        else
            locale = "en";
    }

    return locale;
}

jboolean
IsMultiByteChar(const char *s, int pos)
{
    char *t = NULL;
    int lenwith;
    int lenwithout;
    jboolean ret = JNI_FALSE;

    /* Make sure that preceding character is not a multi-byte character */
    t = StrDup(s);
    t[pos + 1] = '\0';
    if ((lenwith = MultiByteToWideChar(GetACP() ? CP_ACP : CP_UTF8, 0, t, -1, NULL, 0)) < 0)
        goto leave;
    t[pos] = '\0';
    if ((lenwithout = MultiByteToWideChar(GetACP() ? CP_ACP : CP_UTF8, 0, t, -1, NULL, 0)) < 0)
        goto leave;
    if (lenwithout + 1 == lenwith)
        ret = JNI_TRUE;

leave:
    free(t);
    t = NULL;
    return ret;
}

char *
CheckJREVersion(const char *path)
{
    char *version = NULL;

    if (access(path, F_OK) == 0)
    {
        char *cmdline = NULL;
        SECURITY_ATTRIBUTES sa;
        PROCESS_INFORMATION pi;
        STARTUPINFO si;
        HANDLE inpipe[2];
        HANDLE outpipe[2];
        HANDLE errpipe[2];

        sa.nLength = sizeof(SECURITY_ATTRIBUTES);
        sa.bInheritHandle = TRUE;
        sa.lpSecurityDescriptor = NULL;
        memset(inpipe, 0, sizeof(inpipe));
        memset(outpipe, 0, sizeof(outpipe));
        memset(errpipe, 0, sizeof(errpipe));
        if (!CreatePipe(&inpipe[0], &inpipe[1], &sa, PIPE_SIZE) || !CreatePipe(&outpipe[0], &outpipe[1], &sa, PIPE_SIZE) || !CreatePipe(&errpipe[0], &errpipe[1], &sa, PIPE_SIZE))
            goto leave;

        /*
         * Determine the amount of memory to allocate assuming the individual
         * components will be quoted and space separated
         */
        cmdline = (char *)MemAlloc(strlen(path) + strlen(JAVAW_EXE) + strlen("-version") + 6);
        strcpy(cmdline, "\"");
        strcat(cmdline, path);
        strcat(cmdline, JAVAW_EXE "\" \"-version\"");

        memset(&pi, 0, sizeof(PROCESS_INFORMATION));
        memset(&si, 0, sizeof(STARTUPINFO));
        si.cb = sizeof(STARTUPINFO);
        si.dwFlags = STARTF_USESTDHANDLES;
        si.hStdInput = inpipe[0];
        si.hStdOutput = outpipe[1];
        si.hStdError = errpipe[1];
        SetHandleInformation(inpipe[1], HANDLE_FLAG_INHERIT, FALSE);
        SetHandleInformation(outpipe[0], HANDLE_FLAG_INHERIT, FALSE);
        SetHandleInformation(errpipe[0], HANDLE_FLAG_INHERIT, FALSE);

        if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
        {
            DWORD bytes;
            char *str = NULL;

            WaitForSingleObject(pi.hProcess, INFINITE);
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            CloseHandle(inpipe[0]);
            CloseHandle(outpipe[1]);
            CloseHandle(errpipe[1]);
            /*
             * Read the first line of output. We only need to read once since
             * the standard buffer size is far larger than the longest
             * version string.
             */
            version = (char *)MemAlloc(PIPE_SIZE + 1);
            ReadFile(errpipe[0], version, PIPE_SIZE, &bytes, NULL);
            if (bytes <= 0)
                bytes = 0;
            version[bytes] = '\0';
            /* Chop off any garbage after the first newline */
            if ((str = strchr(version, '\n')) != NULL)
                *str = '\0';
            /* Parse version string */
            if ((str = strrchr(version, '"')) != NULL)
                *str = '\0';
            if ((str = strrchr(version, '"')) != NULL)
            {
                *str++ = '\0';
                str = StrDup(str);
                free(version);
                version = str;
            }
            if (!CheckVersion(version))
            {
                free(version);
                version = NULL;
            }
        }

leave:
        if (cmdline)
            free(cmdline);
        cmdline = NULL;
        CloseHandle(inpipe[0]);
        CloseHandle(inpipe[1]);
        CloseHandle(outpipe[0]);
        CloseHandle(outpipe[1]);
        CloseHandle(errpipe[0]);
        CloseHandle(errpipe[1]);
    }

    return version;
}

/*
 * Execute a Java subprocess with the specified arguments.
 */
int
ExecuteJava(const char *jrepath, int numOptions, const JavaVMOption *options,int numProps, const JavaPropsOption *props)
{
    int i = 0;
    jboolean console = GetPrintToConsole();
    const char* class = GetJavaClassName();
    char *command = NULL;
    char *cmdline = NULL;
    size_t len = 0;
    const char *bundledlibpath = jrepath;
    const char *oldpath = getenv("PATH");
    char *newpath = NULL;
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    int ret = 1;

    /*
    if (!CheckJavaClassFile(class))
    {
        char *key = NULL;
        char *message = NULL;

        key = GetMessageKeyPrefix("no_files");
        message = GetLocalizedMessage(key);
        free(key);
        key = NULL;
        fprintf(stderr, message);
        free(message);
        message = NULL;
        return ret;
    }
   */

    command = (char *)MemAlloc(strlen(jrepath) + (console ? strlen(JAVA_EXE) : strlen(JAVAW_EXE)) + 1);
    strcpy(command, jrepath);
    strcat(command, console ? JAVA_EXE : JAVAW_EXE);

    if (access(command, R_OK) != 0)
    {
        char *message = GetLocalizedMessage("java_aborted");
        fprintf(stderr, message);
        free(message);
        message = NULL;
        free(command);
        command = NULL;
        return ret;
    }

    /*
     * Determine the amount of memory to allocate assuming the individual
     * components will be quoted and space separated
     */
    len = strlen(command) + 2;
    for (i = 0; i < numOptions; i++)
        len += strlen(options[i].optionString) + 3;
    for (i = 0; i < numProps; i++)
        len += strlen(props[i].propsString) + 3;

    len += strlen(class) + 3;

    cmdline = (char *)MemAlloc(len + 10 + 1);

    strcpy(cmdline, "\"");
    strcat(cmdline, command);
    strcat(cmdline, "\" ");
    /* Add the default Option "-client" here. */
    /*
    strcat(cmdline, " -client ");
    */
    for (i = 0; i < numOptions; i++)
    {
    	strcat(cmdline, "\"");
        strcat(cmdline, options[i].optionString);
    	strcat(cmdline, "\" ");
    }
    strcat(cmdline, " \"");
    strcat(cmdline, class);
    strcat(cmdline, "\" ");

    for (i = 0; i < numProps; i++)
    {
	strcat(cmdline, " ");
        strcat(cmdline, props[i].propsString);
	strcat(cmdline, " ");
    }


    newpath = (char *)MemAlloc(strlen("PATH=") + (bundledlibpath ? strlen(bundledlibpath) + 1 : 0) + (oldpath ? strlen(oldpath) + 1 : 0) + 10);
    strcpy(newpath, "PATH=");
    if (bundledlibpath)
    {
        strcat(newpath, bundledlibpath);
        strcat(newpath, "\\bin");
        strcat(newpath, PATH_SEPARATOR);
    }
    if (oldpath)
    {
        strcat(newpath, oldpath);
        strcat(newpath, PATH_SEPARATOR);
    }
    if (newpath[strlen(newpath) - 1] == PATH_SEPARATOR_CHAR)
        newpath[strlen(newpath) - 1] = '\0';
    putenv(newpath);
    free(newpath);
    newpath = NULL;

    /* Create the console here so that we can set the title */
    if (console)
    {
        HWND consolewindow;

        AllocConsole();
        SetConsoleTitle("");
        consolewindow = FindWindow(NULL, "");
        if (IsIconic(consolewindow))
            ShowWindow(consolewindow, SW_RESTORE);
        SetForegroundWindow(consolewindow);
    }

    memset(&pi, 0, sizeof(PROCESS_INFORMATION));
    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    if (CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
    {
        /* Wait a few seconds to display the status dialog */
        Sleep(10000);
        HideStatusWindow();

        WaitForSingleObject(pi.hProcess, INFINITE);
        GetExitCodeProcess(pi.hProcess, &ret);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
    else
    {
        char *message = GetLocalizedMessage("java_aborted");
        fprintf(stderr, message);
        free(message);
        message = NULL;
        return ret;
    }

    free(command);
    command = NULL;
    free(cmdline);
    cmdline = NULL;

    return ret;
}

/*
 * Perform recursive deletion of a file or directory. Note: don't use MemAlloc
 * function here since this is called from an exit handler.
 */
void
DeleteFilesAndDirectories(const char *path, char **savelist)
{
    struct stat sb;
    const char *filename;
    int i;

    if (!path || !IsAbsolutePath(path) || (filename = strrchr(path, FILE_SEPARATOR_CHAR)) == 0)
        return;
    filename++;

    /* Ignore special directory entries */
    if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0)
    {
        return;
    }
    /* Chop off any trailing file separator */
    else if (strlen(filename) == 0)
    {
        char *newpath = NULL;
        if ((newpath = (char *)malloc(strlen(path) + 1)) != NULL)
        {
            strcpy(newpath, path);
            *strrchr(newpath, FILE_SEPARATOR_CHAR) = '\0';
            DeleteFilesAndDirectories(newpath, savelist);
            free(newpath);
            newpath = NULL;
        }
    }

    /* Ignore files in the save list */
    for (i = 0; savelist && savelist[i] != NULL; i++)
    {
        if (strcmp(path, savelist[i]) == 0)
            return;
    }

    if (stat(path, &sb) == 0)
    {
        if ((sb.st_mode & S_IFDIR) == S_IFDIR)
        {
            char *searchpath = NULL;
            if ((searchpath = (char *)malloc(strlen(path) + 5)) != NULL)
            {
                struct _finddata_t filefound;
                long filehandle;
                strcpy(searchpath, path);
                strcat(searchpath, FILE_SEPARATOR "*.*");
                if ((filehandle = _findfirst(searchpath, &filefound)) >= 0)
                {
                    char *entrypath = NULL;
                    do {
                        if ((entrypath = (char *)malloc(strlen(path) + strlen(filefound.name) + 2)) != NULL)
                        {
                            strcpy(entrypath, path);
                            strcat(entrypath, FILE_SEPARATOR);
                            strcat(entrypath, filefound.name);
                            DeleteFilesAndDirectories(entrypath, savelist);
                            free(entrypath);
                            entrypath = NULL;
                        }
                    } while (_findnext(filehandle, &filefound) == 0);
                }
                _findclose(filehandle);
                free(searchpath);
                searchpath = NULL;
            }
            RemoveDirectory(path);
        }
        else
        {
            DeleteFile(path);
        }
    }
}

/* used to invoke the upgrade tool in console mode*/
int
InvokeUpgradeTool(const char *invokerPath)
{

    char *cmdline = NULL;
    int ret = 1;
 
    PROCESS_INFORMATION pi;
    STARTUPINFO si;

    memset(&pi, 0, sizeof(PROCESS_INFORMATION));
    memset(&si, 0, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);

    cmdline = (char *)MemAlloc(150);

    strcpy(cmdline, invokerPath);
 
    if(CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
    {   
		WaitForSingleObject(pi.hProcess, INFINITE);
		GetExitCodeProcess(pi.hProcess, &ret);  
		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
	
		free(cmdline);
		cmdline=NULL;
	
    }
    else
    {
	
	     free(cmdline);
		 cmdline=NULL;
    }

	return ret;
}
	

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish java_md.winnt.c source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.