diff options
author | Lyubomir Marinov <lyubomir.marinov@jitsi.org> | 2011-10-24 10:31:06 +0000 |
---|---|---|
committer | Lyubomir Marinov <lyubomir.marinov@jitsi.org> | 2011-10-24 10:31:06 +0000 |
commit | 2ce621309bcd2e0c1e55357be173fe47ac9e2fe9 (patch) | |
tree | 0908de4fa8cf84342f5447a91fa231c5c91ff802 /src/native/windows | |
parent | fbd33b96f8ffdd580e399502903e9f1cdc670292 (diff) | |
download | jitsi-2ce621309bcd2e0c1e55357be173fe47ac9e2fe9.zip jitsi-2ce621309bcd2e0c1e55357be173fe47ac9e2fe9.tar.gz jitsi-2ce621309bcd2e0c1e55357be173fe47ac9e2fe9.tar.bz2 |
Loads the Java VM into Jitsi's run.exe in order to fix issue #963: Starting Jitsi via pinned taskbar icon makes a second Jitsi icon appear in the taskbar instead of highlighting the existing one. Based on ibauersachs' patch.
Diffstat (limited to 'src/native/windows')
-rw-r--r-- | src/native/windows/run/Makefile | 107 | ||||
-rw-r--r-- | src/native/windows/run/run.c | 575 | ||||
-rw-r--r-- | src/native/windows/setup/nls.c | 75 | ||||
-rw-r--r-- | src/native/windows/setup/nls.h | 16 | ||||
-rw-r--r-- | src/native/windows/setup/setup.c | 80 |
5 files changed, 513 insertions, 340 deletions
diff --git a/src/native/windows/run/Makefile b/src/native/windows/run/Makefile index 525300b..caa5ef0 100644 --- a/src/native/windows/run/Makefile +++ b/src/native/windows/run/Makefile @@ -1,56 +1,51 @@ -# -# Jitsi, the OpenSource Java VoIP and Instant Messaging client. -# -# Distributable under LGPL license. -# See terms of license at gnu.org. -# - -MINGW_HOME ?= C:/mingw -PRODUCTNAME ?= Jitsi -TARGET_BASENAME ?= run -TARGET_DIR ?= ../../../../release/windows/tmp - -ifeq ($(wildcard /bin/cygpath.*),/bin/cygpath.exe) - target.dir := $(shell cygpath --mixed "$(TARGET_DIR)") - cygwin.target.dir := $(shell cygpath --unix "$(TARGET_DIR)") -else - target.dir := "$(TARGET_DIR)" - cygwin.target.dir := "$(TARGET_DIR)" -endif - -CC = $(MINGW_HOME)/bin/gcc.exe -CPPFLAGS := $(CPPFLAGS) \ - -O2 \ - -Wall -Wreturn-type \ - -DPSAPI_VERSION=1 \ - -DWINVER=0x0502 -D_WIN32_WINNT=0x0502 \ - -I$(target.dir) -LDFLAGS = -mwindows -LIBS = -ladvapi32 -lpsapi - -MACHINE = $(shell $(CC) -dumpmachine) -WINDRES = $(MINGW_HOME)/bin/windres.exe -ifneq ("x$(MACHINE)","x") -ifeq ($(wildcard $(MINGW_HOME)/bin/$(MACHINE)-windres.*),$(MINGW_HOME)/bin/$(MACHINE)-windres.exe) - WINDRES = $(MINGW_HOME)/bin/$(MACHINE)-windres.exe -endif -endif - -ifdef PACKAGECODE - DEFINE_PACKAGECODE = define PACKAGECODE "$(strip $(PACKAGECODE))" -else - DEFINE_PACKAGECODE = undef PACKAGECODE -endif - -$(cygwin.target.dir)/$(TARGET_BASENAME).exe: $(cygwin.target.dir)/config.h registry.c run.c $(cygwin.target.dir)/run.res - $(CC) $(CPPFLAGS) registry.c run.c $(target.dir)/run.res $(LDFLAGS) -o $(target.dir)/$(TARGET_BASENAME).exe $(LIBS) - -$(MINGW_HOME)/$(MACHINE)/bin/strip.exe $(target.dir)/$(TARGET_BASENAME).exe - -.PHONY: $(cygwin.target.dir)/config.h - -$(cygwin.target.dir)/config.h: - -rm.exe -f ../../../../resources/install/windows/config.h - echo.exe -e '#define PRODUCTNAME "$(PRODUCTNAME)"\n#$(DEFINE_PACKAGECODE)' > $(cygwin.target.dir)/config.h - -$(cygwin.target.dir)/run.res: $(cygwin.target.dir)/config.h run.rc - $(WINDRES) -I../../../../resources/install/windows -I$(target.dir) run.rc -O coff -o $(target.dir)/run.res +#
+# Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+#
+# Distributable under LGPL license.
+# See terms of license at gnu.org.
+#
+
+MINGW_HOME ?= C:/mingw
+PRODUCTNAME ?= Jitsi
+TARGET_BASENAME ?= run
+TARGET_DIR ?= ../../../../release/windows/tmp
+
+ifeq ($(wildcard /bin/cygpath.*),/bin/cygpath.exe)
+ target.dir := $(shell cygpath --mixed "$(TARGET_DIR)")
+ cygwin.target.dir := $(shell cygpath --unix "$(TARGET_DIR)")
+else
+ target.dir := "$(TARGET_DIR)"
+ cygwin.target.dir := "$(TARGET_DIR)"
+endif
+
+CC = $(MINGW_HOME)/bin/gcc.exe
+CPPFLAGS := $(CPPFLAGS) \
+ -O2 \
+ -Wall -Wreturn-type \
+ -DPSAPI_VERSION=1 \
+ -DWINVER=0x0502 -D_WIN32_WINNT=0x0502 \
+ -I$(target.dir) \
+ -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/win32
+LDFLAGS = -mwindows
+LIBS = -ladvapi32 -lpsapi
+
+MACHINE = $(shell $(CC) -dumpmachine)
+WINDRES = $(MINGW_HOME)/bin/windres.exe
+ifneq ("x$(MACHINE)","x")
+ifeq ($(wildcard $(MINGW_HOME)/bin/$(MACHINE)-windres.*),$(MINGW_HOME)/bin/$(MACHINE)-windres.exe)
+ WINDRES = $(MINGW_HOME)/bin/$(MACHINE)-windres.exe
+endif
+endif
+
+$(cygwin.target.dir)/$(TARGET_BASENAME).exe: $(cygwin.target.dir)/config.h registry.c run.c $(cygwin.target.dir)/run.res ../setup/nls.c
+ $(CC) $(CPPFLAGS) registry.c run.c $(target.dir)/run.res ../setup/nls.c $(LDFLAGS) -o $(target.dir)/$(TARGET_BASENAME).exe $(LIBS)
+ -$(MINGW_HOME)/$(MACHINE)/bin/strip.exe $(target.dir)/$(TARGET_BASENAME).exe
+
+.PHONY: $(cygwin.target.dir)/config.h
+
+$(cygwin.target.dir)/config.h:
+ -rm.exe -f ../../../../resources/install/windows/config.h
+ echo.exe -e '#define PRODUCTNAME "$(PRODUCTNAME)"' > $(cygwin.target.dir)/config.h
+
+$(cygwin.target.dir)/run.res: $(cygwin.target.dir)/config.h run.rc
+ $(WINDRES) -I../../../../resources/install/windows -I$(target.dir) run.rc -O coff -o $(target.dir)/run.res
diff --git a/src/native/windows/run/run.c b/src/native/windows/run/run.c index 0144105..4592437 100644 --- a/src/native/windows/run/run.c +++ b/src/native/windows/run/run.c @@ -8,7 +8,9 @@ #include "run.h"
#include <ctype.h> /* isspace */
+#include <jni.h>
#include <psapi.h> /* GetModuleFileNameEx */
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -16,6 +18,9 @@ #include <tlhelp32.h> /* CreateToolhelp32Snapshot */
#include "registry.h"
+#include "../setup/nls.h"
+
+#define JAVA_MAIN_CLASS _T("net.java.sip.communicator.launcher.SIPCommunicator")
/**
* The pipe through which the launcher is to communicate with the crash handler.
@@ -35,13 +40,14 @@ static LPSTR Run_cmdLine = NULL; */
static BOOL Run_launch = TRUE;
-static DWORD Run_addPath(LPCTSTR path);
+static DWORD Run_callStaticVoidMain(JNIEnv *jniEnv, BOOL *searchForJava);
static int Run_displayMessageBoxFromString(DWORD textId, DWORD_PTR *textArgs, LPCTSTR caption, UINT type);
static DWORD Run_equalsParentProcessExecutableFilePath(LPCTSTR executableFilePath, BOOL *equals);
static DWORD Run_getExecutableFilePath(LPTSTR *executableFilePath);
static DWORD Run_getJavaExeCommandLine(LPCTSTR javaExe, LPTSTR *commandLine);
static LPTSTR Run_getJavaLibraryPath();
static LONG Run_getJavaPathsFromRegKey(HKEY key, LPTSTR *runtimeLib, LPTSTR *javaHome);
+static DWORD Run_getJavaVMOptionStrings(size_t head, TCHAR separator, size_t tail, LPTSTR *optionStrings, jint *optionStringCount);
static LPTSTR Run_getLockFilePath();
static DWORD Run_getParentProcessId(DWORD *ppid);
static DWORD Run_handleLauncherExitCode(DWORD exitCode, LPCTSTR lockFilePath, LPCTSTR executableFilePath);
@@ -60,44 +66,133 @@ static DWORD Run_runJavaFromRuntimeLib(LPCTSTR runtimeLib, BOOL *searchForJava); static LPSTR Run_skipWhitespace(LPSTR str);
static DWORD
-Run_addPath(LPCTSTR path)
+Run_callStaticVoidMain(JNIEnv *jniEnv, BOOL *searchForJava)
{
- LPCTSTR envVarName = _T("PATH");
- TCHAR envVar[4096];
- DWORD envVarCapacity = sizeof(envVar) / sizeof(TCHAR);
- DWORD envVarLength
- = GetEnvironmentVariable(envVarName, envVar, envVarCapacity);
+ LPTSTR mainClassName;
+ jclass mainClass;
DWORD error;
- if (envVarLength)
+ mainClassName = _tcsdup(JAVA_MAIN_CLASS);
+ if (mainClassName)
{
- if (envVarLength >= envVarCapacity)
- error = ERROR_NOT_ENOUGH_MEMORY;
- else
+ LPTSTR ch;
+
+ for (ch = mainClassName; *ch; ch++)
+ if (_T('.') == *ch)
+ *ch = _T('/');
+ mainClass = (*jniEnv)->FindClass(jniEnv, mainClassName);
+ free(mainClassName);
+ }
+ else
+ mainClass = NULL;
+ if (mainClass)
+ {
+ jmethodID mainMethodID
+ = (*jniEnv)->GetStaticMethodID(
+ jniEnv,
+ mainClass,
+ "main",
+ "([Ljava/lang/String;)V");
+
+ if (mainMethodID)
{
- DWORD pathLength = _tcslen(path);
+ jclass stringClass
+ = (*jniEnv)->FindClass(jniEnv, "java/lang/String");
- if (envVarLength + 1 + pathLength + 1 > envVarCapacity)
- error = ERROR_NOT_ENOUGH_MEMORY;
- else
+ if (stringClass)
{
- LPTSTR str = envVar + envVarLength;
+ int argc = 0;
+ LPWSTR *argv = NULL;
- *str = _T(';');
- str++;
- _tcsncpy(str, path, pathLength);
- str += pathLength;
- *str = 0;
+ if (Run_cmdLine && strlen(Run_cmdLine))
+ {
+ LPWSTR cmdLineW = NLS_str2wstr(Run_cmdLine);
- if (SetEnvironmentVariable(envVarName, envVar))
- error = ERROR_SUCCESS;
+ if (cmdLineW)
+ {
+ argv = CommandLineToArgvW(cmdLineW, &argc);
+ free(cmdLineW);
+ error = argv ? ERROR_SUCCESS : GetLastError();
+ }
+ else
+ error = ERROR_NOT_ENOUGH_MEMORY;
+ }
else
- error = GetLastError();
+ error = ERROR_SUCCESS;
+ if (ERROR_SUCCESS == error)
+ {
+ jobjectArray mainArgs
+ = (*jniEnv)->NewObjectArray(
+ jniEnv,
+ argc, stringClass, NULL);
+
+ if (mainArgs)
+ {
+ int i;
+
+ for (i = 0; (ERROR_SUCCESS == error) && (i < argc); i++)
+ {
+ LPWSTR arg = *(argv + i);
+ jstring mainArg
+ = (*jniEnv)->NewString(
+ jniEnv,
+ arg, wcslen(arg));
+
+ if (mainArg)
+ {
+ (*jniEnv)->SetObjectArrayElement(
+ jniEnv,
+ mainArgs, i, mainArg);
+ if (JNI_TRUE
+ == (*jniEnv)->ExceptionCheck(jniEnv))
+ error = ERROR_FUNCTION_FAILED;
+ }
+ else
+ error = ERROR_NOT_ENOUGH_MEMORY;
+ }
+ if (argv)
+ {
+ LocalFree(argv);
+ argv = NULL;
+ }
+
+ if (ERROR_SUCCESS == error)
+ {
+ *searchForJava = FALSE;
+
+ /*
+ * The parent process will have to wait for and get
+ * the exit code of its child, not java.exe so it
+ * does not need telling who to wait for or get the
+ * exit code of.
+ */
+ if (INVALID_HANDLE_VALUE != Run_channel)
+ {
+ CloseHandle(Run_channel);
+ Run_channel = INVALID_HANDLE_VALUE;
+ }
+
+ (*jniEnv)->CallStaticVoidMethod(
+ jniEnv,
+ mainClass, mainMethodID, mainArgs);
+ }
+ }
+ else
+ error = ERROR_NOT_ENOUGH_MEMORY;
+
+ if (argv)
+ LocalFree(argv);
+ }
}
+ else
+ error = ERROR_CLASS_DOES_NOT_EXIST;
}
+ else
+ error = ERROR_INVALID_FUNCTION;
}
else
- error = GetLastError();
+ error = ERROR_CLASS_DOES_NOT_EXIST;
+
return error;
}
@@ -225,98 +320,14 @@ Run_getExecutableFilePath(LPTSTR *executableFilePath) static DWORD
Run_getJavaExeCommandLine(LPCTSTR javaExe, LPTSTR *commandLine)
{
- LPCTSTR classpath[]
- = {
- _T("lib\\felix.jar"),
- _T("lib\\jdic-all.jar"),
- _T("lib\\jdic_stub.jar"),
- _T("lib\\bcprovider.jar"),
- _T("sc-bundles\\sc-launcher.jar"),
- _T("sc-bundles\\util.jar"),
- NULL
- };
- LPTSTR javaLibraryPath = Run_getJavaLibraryPath();
- LPCTSTR properties[]
- = {
- _T("felix.config.properties"),
- _T("file:./lib/felix.client.run.properties"),
- _T("java.util.logging.config.file"),
- _T("lib/logging.properties"),
- _T("java.library.path"),
- javaLibraryPath,
- _T("jna.library.path"),
- javaLibraryPath,
- NULL
- };
- LPCTSTR scHomeDirNameProperty
- = _T("net.java.sip.communicator.SC_HOME_DIR_NAME");
- LPCTSTR scHomeDirNameValue = PRODUCTNAME;
- LPCTSTR mainClass
- = _T("net.java.sip.communicator.launcher.SIPCommunicator");
+ LPCTSTR mainClass = JAVA_MAIN_CLASS;
size_t javaExeLength;
- size_t classpathLength;
- size_t propertiesLength;
- size_t scHomeDirNamePropertyLength;
- size_t scHomeDirNameValueLength;
size_t mainClassLength;
size_t cmdLineLength;
DWORD error;
javaExeLength = _tcslen(javaExe);
- classpathLength = 0;
- {
- size_t i = 0;
-
- while (1)
- {
- LPCTSTR cp = classpath[i];
-
- if (cp)
- {
- classpathLength += _tcslen(cp);
- i++;
- }
- else
- break;
- }
- if (i)
- {
- classpathLength += 5; /* "-cp " */
- classpathLength += (i - 1); /* ';' */
- }
- }
- propertiesLength = 0;
- {
- size_t i = 0;
-
- while (1)
- {
- LPCTSTR property = properties[i];
-
- if (property)
- {
- i++;
- propertiesLength
- += (2 /* "-D" */
- + _tcslen(property)
- + 1 /* '=' */
- + _tcslen(properties[i])
- + 1 /* ' ' */);
- i++;
- }
- else
- break;
- }
- scHomeDirNamePropertyLength = _tcslen(scHomeDirNameProperty);
- scHomeDirNameValueLength = _tcslen(scHomeDirNameValue);
- propertiesLength
- += (2
- + scHomeDirNamePropertyLength
- + 2
- + scHomeDirNameValueLength
- + 2);
- }
mainClassLength = _tcslen(mainClass);
if (Run_cmdLine)
{
@@ -327,18 +338,14 @@ Run_getJavaExeCommandLine(LPCTSTR javaExe, LPTSTR *commandLine) else
cmdLineLength = 0;
- *commandLine
- = (LPTSTR)
- malloc(
- sizeof(TCHAR)
- * (javaExeLength
- + 1 /* ' ' */
- + classpathLength
- + propertiesLength
- + mainClassLength
- + cmdLineLength
- + 1 /* 0 */));
- if (*commandLine && javaLibraryPath)
+ error
+ = Run_getJavaVMOptionStrings(
+ javaExeLength + 1 /* ' ' */,
+ _T(' '),
+ mainClassLength + cmdLineLength,
+ commandLine,
+ NULL);
+ if (ERROR_SUCCESS == error)
{
LPTSTR str = *commandLine;
@@ -346,77 +353,9 @@ Run_getJavaExeCommandLine(LPCTSTR javaExe, LPTSTR *commandLine) str += javaExeLength;
*str = _T(' ');
str++;
- if (classpathLength)
- {
- size_t i;
-
- _tcscpy(str, _T("-cp "));
- str += 4;
- i = 0;
- while (1)
- {
- LPCTSTR cp = classpath[i];
- if (cp)
- {
- size_t length = _tcslen(cp);
+ str += _tcslen(str);
- _tcsncpy(str, cp, length);
- str += length;
- *str = _T(';');
- str++;
- i++;
- }
- else
- break;
- }
- str--; /* Drop the last ';'. */
- *str = _T(' ');
- str++;
- }
- if (propertiesLength)
- {
- size_t i = 0;
-
- while (1)
- {
- LPCTSTR property = properties[i];
-
- if (property)
- {
- size_t length;
- LPCTSTR value;
-
- _tcscpy(str, _T("-D"));
- str += 2;
- length = _tcslen(property);
- _tcsncpy(str, property, length);
- str += length;
- i++;
- *str = _T('=');
- str++;
- value = properties[i];
- length = _tcslen(value);
- _tcsncpy(str, value, length);
- str += length;
- i++;
- *str = _T(' ');
- str++;
- }
- else
- break;
- }
- _tcscpy(str, _T("-D"));
- str += 2;
- _tcsncpy(str, scHomeDirNameProperty, scHomeDirNamePropertyLength);
- str += scHomeDirNamePropertyLength;
- _tcscpy(str, _T("=\""));
- str += 2;
- _tcsncpy(str, scHomeDirNameValue, scHomeDirNameValueLength);
- str += scHomeDirNameValueLength;
- _tcscpy(str, _T("\" "));
- str += 2;
- }
_tcsncpy(str, mainClass, mainClassLength);
str += mainClassLength;
if (cmdLineLength)
@@ -428,14 +367,7 @@ Run_getJavaExeCommandLine(LPCTSTR javaExe, LPTSTR *commandLine) str += cmdLineLength;
}
*str = 0;
-
- error = ERROR_SUCCESS;
}
- else
- error = ERROR_OUTOFMEMORY;
-
- if (javaLibraryPath)
- free(javaLibraryPath);
return error;
}
@@ -444,13 +376,13 @@ static LPTSTR Run_getJavaLibraryPath()
{
LPCTSTR relativeJavaLibraryPath = _T("native");
- TCHAR javaLibraryPath[1 /* " */ + MAX_PATH + 1 /* " */ + 1];
+ TCHAR javaLibraryPath[MAX_PATH + 1];
DWORD javaLibraryPathCapacity
- = (sizeof(javaLibraryPath) - 2 /* "" */) / sizeof(TCHAR);
+ = sizeof(javaLibraryPath) / sizeof(TCHAR);
DWORD javaLibraryPathLength
= GetFullPathName(
relativeJavaLibraryPath,
- javaLibraryPathCapacity, javaLibraryPath + 1,
+ javaLibraryPathCapacity, javaLibraryPath,
NULL);
LPCTSTR dup;
@@ -459,10 +391,7 @@ Run_getJavaLibraryPath() {
LPTSTR str = javaLibraryPath;
- *str = _T('\"');
- str += (1 + javaLibraryPathLength);
- *str = _T('\"');
- str++;
+ str += javaLibraryPathLength;
*str = 0;
dup = javaLibraryPath;
@@ -524,6 +453,156 @@ Run_getJavaPathsFromRegKey(HKEY key, LPTSTR *runtimeLib, LPTSTR *javaHome) return error;
}
+static DWORD
+Run_getJavaVMOptionStrings
+ (size_t head, TCHAR separator, size_t tail,
+ LPTSTR *optionStrings, jint *optionStringCount)
+{
+ LPTSTR javaLibraryPath = Run_getJavaLibraryPath();
+ jint _optionStringCount = 0;
+ DWORD error;
+
+ if (javaLibraryPath)
+ {
+ LPCTSTR classpath[]
+ = {
+ _T("lib\\felix.jar"),
+ _T("lib\\jdic-all.jar"),
+ _T("lib\\jdic_stub.jar"),
+ _T("lib\\bcprovider.jar"),
+ _T("sc-bundles\\sc-launcher.jar"),
+ _T("sc-bundles\\util.jar"),
+ NULL
+ };
+ LPCTSTR properties[]
+ = {
+ _T("felix.config.properties"),
+ _T("file:./lib/felix.client.run.properties"),
+ _T("java.util.logging.config.file"),
+ _T("lib/logging.properties"),
+ _T("java.library.path"),
+ javaLibraryPath,
+ _T("jna.library.path"),
+ javaLibraryPath,
+ _T("net.java.sip.communicator.SC_HOME_DIR_NAME"),
+ PRODUCTNAME,
+ NULL
+ };
+
+ size_t classpathLength;
+ size_t propertiesLength;
+ BOOL quote = separator;
+
+ {
+ LPCTSTR cp;
+ size_t i = 0;
+
+ classpathLength = 0;
+ while ((cp = classpath[i++]))
+ classpathLength += (_tcslen(cp) + 1 /* ';' */);
+ if (classpathLength)
+ classpathLength += 18 /* "-Djava.class.path=" */;
+ }
+ {
+ LPCTSTR property;
+ size_t i = 0;
+
+ propertiesLength = 0;
+ while ((property = properties[i++]))
+ {
+ propertiesLength
+ += (2 /* "\"-D" */
+ + _tcslen(property)
+ + 1 /* '=' */
+ + _tcslen(properties[i++])
+ + 1 /* ' ' */);
+ if (quote)
+ propertiesLength += 2;
+ }
+ }
+
+ *optionStrings
+ = (LPTSTR)
+ malloc(
+ sizeof(TCHAR)
+ * (head
+ + classpathLength
+ + propertiesLength
+ + 1 /* 0 */
+ + tail));
+ if (*optionStrings)
+ {
+ LPTSTR str = (*optionStrings) + head;
+
+ if (classpathLength)
+ {
+ LPCTSTR cp;
+ size_t i = 0;
+
+ _tcscpy(str, _T("-Djava.class.path="));
+ str += 18;
+ while ((cp = classpath[i++]))
+ {
+ size_t length = _tcslen(cp);
+
+ _tcsncpy(str, cp, length);
+ str += length;
+ *str = _T(';');
+ str++;
+ }
+ str--; /* Drop the last ';'. */
+ *str = separator;
+ str++;
+
+ _optionStringCount++;
+ }
+ if (propertiesLength)
+ {
+ LPCTSTR property;
+ size_t i = 0;
+
+ while ((property = properties[i++]))
+ {
+ size_t length;
+ LPCTSTR value;
+
+ if (quote)
+ *str++ = _T('"');
+ _tcscpy(str, _T("-D"));
+ str += 2;
+ length = _tcslen(property);
+ _tcsncpy(str, property, length);
+ str += length;
+ *str++ = _T('=');
+
+ value = properties[i++];
+ length = _tcslen(value);
+ _tcsncpy(str, value, length);
+ str += length;
+ if (quote)
+ *str++ = _T('"');
+ *str++ = separator;
+
+ _optionStringCount++;
+ }
+ }
+ *str = 0;
+
+ if (optionStringCount)
+ *optionStringCount = _optionStringCount;
+ error = ERROR_SUCCESS;
+ }
+ else
+ error = ERROR_OUTOFMEMORY;
+
+ free(javaLibraryPath);
+ }
+ else
+ error = ERROR_OUTOFMEMORY;
+
+ return error;
+}
+
static LPTSTR
Run_getLockFilePath()
{
@@ -775,7 +854,7 @@ Run_runAsCrashHandlerWithPipe( commandLine,
commandLineLength,
commandLineFormat,
- (int) (*writePipe),
+ (int) (intptr_t) (*writePipe),
cmdLine);
if (commandLineLength < 0)
{
@@ -948,7 +1027,7 @@ Run_runAsLauncher(LPCTSTR executableFilePath, LPSTR cmdLine) commandLine += channelArgLength;
if (!isspace(*commandLine))
{
- HANDLE channel = (HANDLE) atoi(commandLine);
+ HANDLE channel = (HANDLE) (intptr_t) atoi(commandLine);
DWORD flags;
char ch;
@@ -1311,11 +1390,82 @@ Run_runJavaFromRegKey(HKEY key, BOOL *searchForJava) static DWORD
Run_runJavaFromRuntimeLib(LPCTSTR runtimeLib, BOOL *searchForJava)
{
- if (Run_isFile(runtimeLib))
+ HMODULE hRuntimeLib
+ = Run_isFile(runtimeLib) ? LoadLibrary(runtimeLib) : NULL;
+ DWORD error;
+
+ if (hRuntimeLib)
{
- /* TODO Auto-generated method stub */
+ typedef jint (*JNICreateJavaVMFunc)(JavaVM **, void **, void *);
+ JNICreateJavaVMFunc jniCreateJavaVM
+ = (JNICreateJavaVMFunc)
+ GetProcAddress(hRuntimeLib, "JNI_CreateJavaVM");
+
+ if (jniCreateJavaVM)
+ {
+ LPTSTR optionStrings = NULL;
+ jint optionStringCount = 0;
+
+ error
+ = Run_getJavaVMOptionStrings(
+ 0, 0, 0,
+ &optionStrings, &optionStringCount);
+ if (ERROR_SUCCESS == error)
+ {
+ JavaVMOption *options
+ = calloc(optionStringCount, sizeof(JavaVMOption));
+
+ if (options)
+ {
+ jint i;
+ LPTSTR optionString;
+ JavaVMInitArgs javaVMInitArgs;
+ JavaVM *javaVM;
+ JNIEnv *jniEnv;
+
+ for (i = 0, optionString = optionStrings;
+ i < optionStringCount;
+ i++, optionString += (_tcslen(optionString) + 1))
+ (options + i)->optionString = optionString;
+
+ javaVMInitArgs.ignoreUnrecognized = JNI_FALSE;
+ javaVMInitArgs.nOptions = optionStringCount;
+ javaVMInitArgs.options = options;
+ javaVMInitArgs.version = JNI_VERSION_1_2;
+ if (jniCreateJavaVM(
+ &javaVM,
+ (void **) &jniEnv,
+ &javaVMInitArgs))
+ error = ERROR_FUNCTION_FAILED;
+ else
+ {
+ free(options);
+ options = NULL;
+ free(optionStrings);
+ optionStrings = NULL;
+
+ error = Run_callStaticVoidMain(jniEnv, searchForJava);
+ if (JNI_TRUE == (*jniEnv)->ExceptionCheck(jniEnv))
+ (*jniEnv)->ExceptionClear(jniEnv);
+
+ (*javaVM)->DestroyJavaVM(javaVM);
+ }
+ if (options)
+ free(options);
+ }
+ else
+ error = ERROR_OUTOFMEMORY;
+ if (optionStrings)
+ free(optionStrings);
+ }
+ }
+ else
+ error = GetLastError();
+ FreeLibrary(hRuntimeLib);
}
- return ERROR_CALL_NOT_IMPLEMENTED;
+ else
+ error = GetLastError();
+ return error;
}
static LPSTR
@@ -1332,8 +1482,11 @@ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdLine, int cmdShow)
{
LPTSTR executableFilePath = NULL;
- DWORD error = Run_getExecutableFilePath(&executableFilePath);
+ DWORD error;
+
+ AttachConsole(ATTACH_PARENT_PROCESS);
+ error = Run_getExecutableFilePath(&executableFilePath);
if (ERROR_SUCCESS == error)
{
BOOL runAsLauncher = FALSE;
diff --git a/src/native/windows/setup/nls.c b/src/native/windows/setup/nls.c new file mode 100644 index 0000000..65eedc0 --- /dev/null +++ b/src/native/windows/setup/nls.c @@ -0,0 +1,75 @@ +/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+#include "nls.h"
+
+#include <stdlib.h>
+
+LPWSTR
+NLS_str2wstr(LPCSTR str)
+{
+ int wstrSize = MultiByteToWideChar(CP_THREAD_ACP, 0, str, -1, NULL, 0);
+ LPWSTR wstr;
+
+ if (wstrSize)
+ {
+ wstr = malloc(wstrSize * sizeof(WCHAR));
+ if (wstr)
+ {
+ wstrSize
+ = MultiByteToWideChar(
+ CP_THREAD_ACP,
+ 0,
+ str, -1,
+ wstr, wstrSize);
+ if (!wstrSize)
+ {
+ free(wstr);
+ wstr = NULL;
+ }
+ }
+ }
+ else
+ wstr = NULL;
+ return wstr;
+}
+
+LPSTR
+NLS_wstr2str(LPCWSTR wstr)
+{
+ int strSize
+ = WideCharToMultiByte(
+ CP_THREAD_ACP,
+ WC_NO_BEST_FIT_CHARS,
+ wstr, -1,
+ NULL, 0,
+ NULL, NULL);
+ LPSTR str;
+
+ if (strSize)
+ {
+ str = malloc(strSize);
+ if (str)
+ {
+ strSize
+ = WideCharToMultiByte(
+ CP_THREAD_ACP,
+ WC_NO_BEST_FIT_CHARS,
+ wstr, -1,
+ str, strSize,
+ NULL, NULL);
+ if (!strSize)
+ {
+ free(str);
+ str = NULL;
+ }
+ }
+ }
+ else
+ str = NULL;
+ return str;
+}
diff --git a/src/native/windows/setup/nls.h b/src/native/windows/setup/nls.h new file mode 100644 index 0000000..db971c6 --- /dev/null +++ b/src/native/windows/setup/nls.h @@ -0,0 +1,16 @@ +/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+
+#ifndef _ORG_JITSI_WINDOWS_SETUP_NLS_H_
+#define _ORG_JITSI_WINDOWS_SETUP_NLS_H_
+
+#include <windows.h>
+
+LPWSTR NLS_str2wstr(LPCSTR str);
+LPSTR NLS_wstr2str(LPCWSTR wstr);
+
+#endif /* #ifndef _ORG_JITSI_WINDOWS_SETUP_NLS_H_ */
diff --git a/src/native/windows/setup/setup.c b/src/native/windows/setup/setup.c index 67d57e3..f305a86 100644 --- a/src/native/windows/setup/setup.c +++ b/src/native/windows/setup/setup.c @@ -6,6 +6,7 @@ */
#include "lasterror.h"
+#include "nls.h"
#include "registry.h"
#include "setup.h"
@@ -75,10 +76,8 @@ static DWORD Setup_msiexec(); static DWORD Setup_parseCommandLine(LPTSTR cmdLine);
static LPSTR Setup_skipWhitespaceA(LPSTR str);
static LPWSTR Setup_skipWhitespaceW(LPWSTR str);
-static LPWSTR Setup_str2wstr(LPCSTR str);
static DWORD Setup_terminateUp2DateExe();
static DWORD Setup_waitForParentProcess();
-static LPSTR Setup_wstr2str(LPCWSTR wstr);
static DWORD Setup_xzdec(LPVOID ptr, DWORD size, HANDLE file);
#ifdef _UNICODE
@@ -285,7 +284,7 @@ Setup_executeBspatch(LPCTSTR path) #ifdef _UNICODE
newPath = wNewPath;
#else /* #ifdef _UNICODE */
- newPath = Setup_wstr2str(wNewPath);
+ newPath = NLS_wstr2str(wNewPath);
#endif /* #ifdef _UNICODE */
}
else
@@ -365,7 +364,7 @@ Setup_executeBspatch(LPCTSTR path) static DWORD
Setup_executeMsiA(LPCSTR path)
{
- LPWSTR wpath = Setup_str2wstr(path);
+ LPWSTR wpath = NLS_str2wstr(path);
DWORD error;
if (wpath)
@@ -1277,7 +1276,7 @@ Setup_getWinMainCmdLine(LPTSTR *winMainCmdLine) *winMainCmdLine = cmdLineW;
error = ERROR_SUCCESS;
#else /* #ifdef _UNICODE */
- *winMainCmdLine = Setup_wstr2str(cmdLineW);
+ *winMainCmdLine = NLS_wstr2str(cmdLineW);
if (*winMainCmdLine)
error = ERROR_SUCCESS;
else
@@ -1450,7 +1449,7 @@ Setup_parseCommandLine(LPTSTR cmdLine) //#ifdef _UNICODE
// if (cmdLine)
// {
-// commandLine = Setup_str2wstr(cmdLine);
+// commandLine = NLS_str2wstr(cmdLine);
// if (!commandLine)
// {
// error = ERROR_OUTOFMEMORY;
@@ -1554,7 +1553,7 @@ Setup_parseCommandLine(LPTSTR cmdLine) #ifdef _UNICODE
commandLineW = noAllowElevationCommandLine;
#else
- commandLineW = Setup_str2wstr(noAllowElevationCommandLine);
+ commandLineW = NLS_str2wstr(noAllowElevationCommandLine);
if (!commandLineW)
{
error = ERROR_OUTOFMEMORY;
@@ -1651,7 +1650,7 @@ Setup_parseCommandLine(LPTSTR cmdLine) #ifdef _UNICODE
Setup_commandLine = _wcsdup(noAllowElevationCommandLine);
#else
- Setup_commandLine = Setup_str2wstr(noAllowElevationCommandLine);
+ Setup_commandLine = NLS_str2wstr(noAllowElevationCommandLine);
#endif /* #ifdef _UNICODE */
if (Setup_commandLine)
{
@@ -1724,35 +1723,6 @@ DEFINE_SETUP_SKIPWHITESPACE(W, wchar_t, WSTR, iswspace) #undef _UNICODE
#endif /* #ifdef _UNICODE */
-static LPWSTR
-Setup_str2wstr(LPCSTR str)
-{
- int wstrSize = MultiByteToWideChar(CP_THREAD_ACP, 0, str, -1, NULL, 0);
- LPWSTR wstr;
-
- if (wstrSize)
- {
- wstr = malloc(wstrSize * sizeof(WCHAR));
- if (wstr)
- {
- wstrSize
- = MultiByteToWideChar(
- CP_THREAD_ACP,
- 0,
- str, -1,
- wstr, wstrSize);
- if (!wstrSize)
- {
- free(wstr);
- wstr = NULL;
- }
- }
- }
- else
- wstr = NULL;
- return wstr;
-}
-
static DWORD
Setup_terminateUp2DateExe()
{
@@ -1834,42 +1804,6 @@ Setup_waitForParentProcess() return error;
}
-static LPSTR
-Setup_wstr2str(LPCWSTR wstr)
-{
- int strSize
- = WideCharToMultiByte(
- CP_THREAD_ACP,
- WC_NO_BEST_FIT_CHARS,
- wstr, -1,
- NULL, 0,
- NULL, NULL);
- LPSTR str;
-
- if (strSize)
- {
- str = malloc(strSize);
- if (str)
- {
- strSize
- = WideCharToMultiByte(
- CP_THREAD_ACP,
- WC_NO_BEST_FIT_CHARS,
- wstr, -1,
- str, strSize,
- NULL, NULL);
- if (!strSize)
- {
- free(str);
- str = NULL;
- }
- }
- }
- else
- str = NULL;
- return str;
-}
-
static DWORD
Setup_xzdec(LPVOID ptr, DWORD size, HANDLE file)
{
|