bootstrap code migration
diff --git a/src/main/cpp/bootstrap/.dep.inc b/src/main/cpp/bootstrap/.dep.inc
new file mode 100755
index 0000000..4560e55
--- /dev/null
+++ b/src/main/cpp/bootstrap/.dep.inc
@@ -0,0 +1,5 @@
+# This code depends on make tool being used
+DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES}))
+ifneq (${DEPFILES},)
+include ${DEPFILES}
+endif
diff --git a/src/main/cpp/bootstrap/Makefile b/src/main/cpp/bootstrap/Makefile
new file mode 100644
index 0000000..ee8f7c1
--- /dev/null
+++ b/src/main/cpp/bootstrap/Makefile
@@ -0,0 +1,107 @@
+# 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.
+
+# Main targets can be executed directly, and they are:
+#
+# build build a specific configuration
+# clean remove built files from a configuration
+# clobber remove all built files
+# all build all configurations
+# help print help mesage
+#
+# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+# .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+# NOCDDL
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+RANLIB=ranlib
+
+
+
+# build
+build: .build-post-$(CONF)
+
+.build-pre:
+# Add your pre 'build' code here...
+
+.build-post-nbexec: .build-impl nbexecexe.cpp nbexecloader.h utilsfuncs.cpp nbexec_exe.rc
+ windres.exe -Ocoff nbexec_exe.rc nbexec_exe.res
+ g++ -s -mno-cygwin -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -DNBEXEC_DLL=\"nbexec.dll\" nbexecexe.cpp utilsfuncs.cpp nbexec_exe.res -o nbexec.exe
+ cp nbexec.exe ../../../nbbuild/netbeans/platform/lib/
+ cp nbexec.dll ../../../nbbuild/netbeans/platform/lib/
+
+.build-post-nbexec64: .build-impl nbexecexe.cpp nbexecloader.h utilsfuncs.cpp nbexec_exe.rc
+ x86_64-w64-mingw32-windres.exe -Ocoff nbexec_exe.rc nbexec_exe64.res
+ x86_64-w64-mingw32-g++.exe -m64 -s -mno-cygwin -Wl,--nxcompat -Wl,--dynamicbase -DNBEXEC_DLL=\"nbexec64.dll\" -static-libgcc -static-libstdc++ nbexecexe.cpp utilsfuncs.cpp nbexec_exe64.res -o nbexec64.exe
+ cp nbexec64.exe ../../../nbbuild/netbeans/platform/lib/
+ cp nbexec64.dll ../../../nbbuild/netbeans/platform/lib/
+
+
+
+# clean
+clean: .clean-post-$(CONF)
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post-nbexec: .clean-impl
+ rm -f nbexec_exe32.res nbexec32.exe
+
+.clean-post-nbexec64: .clean-impl
+ rm -f nbexec_exe64.res nbexec64.exe
+
+
+
+# clobber
+clobber: .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post: .clobber-impl
+# Add your post 'clobber' code here...
+
+
+
+# all
+all: .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post: .all-impl
+# Add your post 'all' code here...
+
+
+
+# help
+help: .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post: .help-impl
+# Add your post 'help' code here...
+
+
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
diff --git a/src/main/cpp/bootstrap/Makefile.mingw b/src/main/cpp/bootstrap/Makefile.mingw
new file mode 100644
index 0000000..302d778
--- /dev/null
+++ b/src/main/cpp/bootstrap/Makefile.mingw
@@ -0,0 +1,45 @@
+# 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.
+
+all: nbexec64.dll nbexec64.exe nbexec.dll nbexec.exe
+
+clean:
+ rm -f *.res *.exe *.dll
+
+nbexec64.res: nbexec.rc
+ x86_64-w64-mingw32-windres -onbexec64.res -Ocoff nbexec.rc
+
+nbexec64.dll: include/jni.h include/jni_types.h jvmlauncher.cpp nbexec.cpp platformlauncher.cpp utilsfuncs.cpp nbexec64.res
+ x86_64-w64-mingw32-gcc -s -shared -m64 -o nbexec64.dll -I include jvmlauncher.cpp nbexec.cpp platformlauncher.cpp utilsfuncs.cpp nbexec64.res -Wl,--no-insert-timestamp -static -lstdc++ -static-libstdc++ -static-libgcc
+
+nbexec_exe64.res: nbexec_exe.rc nbexec.exe.manifest
+ x86_64-w64-mingw32-windres -onbexec_exe64.res -Ocoff -DMANIFEST_FILE=nbexec.exe.manifest nbexec_exe.rc
+
+nbexec64.exe: nbexecexe.cpp utilsfuncs.cpp nbexec_exe64.res
+ x86_64-w64-mingw32-gcc -s -DNBEXEC_DLL='"nbexec64.dll"' -DARCHITECTURE=64 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -Wl,--no-insert-timestamp -mwindows nbexecexe.cpp utilsfuncs.cpp nbexec_exe64.res -onbexec64.exe -static -lstdc++ -static-libstdc++ -static-libgcc
+
+nbexec.res: nbexec.rc
+ i686-w64-mingw32-windres -onbexec.res -Ocoff nbexec.rc
+
+nbexec.dll: include/jni.h include/jni_types.h jvmlauncher.cpp nbexec.cpp platformlauncher.cpp utilsfuncs.cpp nbexec.res
+ i686-w64-mingw32-gcc -s -shared -o nbexec.dll -I include jvmlauncher.cpp nbexec.cpp platformlauncher.cpp utilsfuncs.cpp nbexec.res -static -Wl,--no-insert-timestamp -lstdc++ -static-libstdc++ -static-libgcc
+
+nbexec_exe.res: nbexec_exe.rc nbexec.exe.manifest
+ i686-w64-mingw32-windres -onbexec_exe.res -Ocoff -DMANIFEST_FILE=nbexec.exe.manifest nbexec_exe.rc
+
+nbexec.exe: nbexecexe.cpp utilsfuncs.cpp nbexec_exe.res
+ i686-w64-mingw32-gcc -s -DNBEXEC_DLL='"nbexec.dll"' -DARCHITECTURE=32 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -Wl,--no-insert-timestamp -mwindows nbexecexe.cpp utilsfuncs.cpp nbexec_exe.res -onbexec.exe -static -lstdc++ -static-libstdc++ -static-libgcc
diff --git a/src/main/cpp/bootstrap/argnames.h b/src/main/cpp/bootstrap/argnames.h
new file mode 100644
index 0000000..c4bdaba
--- /dev/null
+++ b/src/main/cpp/bootstrap/argnames.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef _ARGNAMES_H
+#define _ARGNAMES_H
+
+#define ARG_NAME_SEPAR_PROC "--fork-java"
+#define ARG_NAME_CONSOLE "--console"
+#define ARG_NAME_LAUNCHER_LOG "--trace"
+#define ARG_NAME_LA_START_APP "--la_start_app"
+#define ARG_NAME_LA_START_AU "--la_start_au"
+#define ARG_NAME_LA_PPID "--la_ppid"
+#define ARG_NAME_USER_DIR "--userdir"
+#define ARG_DEFAULT_USER_DIR_ROOT "--default_userdir_root"
+#define ARG_NAME_CACHE_DIR "--cachedir"
+#define ARG_NAME_CLUSTERS "--clusters"
+#define ARG_NAME_BOOTCLASS "--bootclass"
+#define ARG_NAME_JDKHOME "--jdkhome"
+#define ARG_NAME_CP_PREPEND "--cp:p"
+#define ARG_NAME_CP_APPEND "--cp:a"
+#define ARG_NAME_NOSPLASH "--nosplash"
+
+
+#endif /* _ARGNAMES_H */
+
diff --git a/src/main/cpp/bootstrap/include/README b/src/main/cpp/bootstrap/include/README
new file mode 100644
index 0000000..7641ada
--- /dev/null
+++ b/src/main/cpp/bootstrap/include/README
@@ -0,0 +1,18 @@
+# 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.
+
+These header files originate in the Apache Harmony project, tag 5.0m12a.
diff --git a/src/main/cpp/bootstrap/include/jni.h b/src/main/cpp/bootstrap/include/jni.h
new file mode 100644
index 0000000..16cf67b
--- /dev/null
+++ b/src/main/cpp/bootstrap/include/jni.h
@@ -0,0 +1,1838 @@
+/*
+ * 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.
+ */
+/**
+ * @file
+ * This file describes the JNI interface as per the JNI
+ * specification 1.5 available from Sun
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/jniTOC.html">specification</a>
+ * for details.
+ */
+
+#ifndef _JNI_H_
+#define _JNI_H_
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "jni_types.h"
+
+/*
+ * Supported JNI versions
+ */
+/**
+ * Constant which specifies JNI interface version 1.1
+ */
+#define JNI_VERSION_1_1 0x00010001
+/**
+ * Constant which specifies JNI interface version 1.2
+ */
+#define JNI_VERSION_1_2 0x00010002
+/**
+ * Constant which specifies JNI interface version 1.4
+ */
+#define JNI_VERSION_1_4 0x00010004
+
+/**
+ * JNI Native Method Interface table for use in C sources
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp23720">specification</a>
+ * for details
+ */
+struct JNINativeInterface_ {
+ void *reserved0;
+ void *reserved1;
+ void *reserved2;
+ void *reserved3;
+
+ jint (JNICALL *GetVersion)(JNIEnv *env);
+
+ jclass (JNICALL *DefineClass)
+ (JNIEnv *env, const char *name, jobject loader, const jbyte *buf,
+ jsize len);
+ jclass (JNICALL *FindClass)
+ (JNIEnv *env, const char *name);
+
+ jmethodID (JNICALL *FromReflectedMethod)
+ (JNIEnv *env, jobject method);
+ jfieldID (JNICALL *FromReflectedField)
+ (JNIEnv *env, jobject field);
+ jobject (JNICALL *ToReflectedMethod)
+ (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic);
+
+ jclass (JNICALL *GetSuperclass)
+ (JNIEnv *env, jclass sub);
+ jboolean (JNICALL *IsAssignableFrom)
+ (JNIEnv *env, jclass sub, jclass sup);
+ jobject (JNICALL *ToReflectedField)
+ (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic);
+
+ jint (JNICALL *Throw)
+ (JNIEnv *env, jthrowable obj);
+ jint (JNICALL *ThrowNew)
+ (JNIEnv *env, jclass clazz, const char *msg);
+ jthrowable (JNICALL *ExceptionOccurred)
+ (JNIEnv *env);
+ void (JNICALL *ExceptionDescribe)
+ (JNIEnv *env);
+ void (JNICALL *ExceptionClear)
+ (JNIEnv *env);
+ void (JNICALL *FatalError)
+ (JNIEnv *env, const char *msg);
+
+ jint (JNICALL *PushLocalFrame)
+ (JNIEnv *env, jint cap);
+ jobject (JNICALL *PopLocalFrame)
+ (JNIEnv *env, jobject res);
+
+ jobject (JNICALL *NewGlobalRef)
+ (JNIEnv *env, jobject lobj);
+ void (JNICALL *DeleteGlobalRef)
+ (JNIEnv *env, jobject gref);
+ void (JNICALL *DeleteLocalRef)
+ (JNIEnv *env, jobject obj);
+ jboolean (JNICALL *IsSameObject)
+ (JNIEnv *env, jobject obj1, jobject obj2);
+
+ jobject (JNICALL *NewLocalRef)
+ (JNIEnv *env, jobject ref);
+ jint (JNICALL *EnsureLocalCapacity)
+ (JNIEnv *env, jint);
+
+ jobject (JNICALL *AllocObject)
+ (JNIEnv *env, jclass clazz);
+ jobject (JNICALL *NewObject)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jobject (JNICALL *NewObjectV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jobject (JNICALL *NewObjectA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jclass (JNICALL *GetObjectClass)
+ (JNIEnv *env, jobject obj);
+ jboolean (JNICALL *IsInstanceOf)
+ (JNIEnv *env, jobject obj, jclass clazz);
+
+ jmethodID (JNICALL *GetMethodID)
+ (JNIEnv *env, jclass clazz, const char *name, const char *sig);
+
+ jobject (JNICALL *CallObjectMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jobject (JNICALL *CallObjectMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jobject (JNICALL *CallObjectMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args);
+
+ jboolean (JNICALL *CallBooleanMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jboolean (JNICALL *CallBooleanMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jboolean (JNICALL *CallBooleanMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args);
+
+ jbyte (JNICALL *CallByteMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jbyte (JNICALL *CallByteMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jbyte (JNICALL *CallByteMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args);
+
+ jchar (JNICALL *CallCharMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jchar (JNICALL *CallCharMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jchar (JNICALL *CallCharMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args);
+
+ jshort (JNICALL *CallShortMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jshort (JNICALL *CallShortMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jshort (JNICALL *CallShortMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args);
+
+ jint (JNICALL *CallIntMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jint (JNICALL *CallIntMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jint (JNICALL *CallIntMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args);
+
+ jlong (JNICALL *CallLongMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jlong (JNICALL *CallLongMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jlong (JNICALL *CallLongMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args);
+
+ jfloat (JNICALL *CallFloatMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jfloat (JNICALL *CallFloatMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jfloat (JNICALL *CallFloatMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args);
+
+ jdouble (JNICALL *CallDoubleMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ jdouble (JNICALL *CallDoubleMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ jdouble (JNICALL *CallDoubleMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args);
+
+ void (JNICALL *CallVoidMethod)
+ (JNIEnv *env, jobject obj, jmethodID methodID, ...);
+ void (JNICALL *CallVoidMethodV)
+ (JNIEnv *env, jobject obj, jmethodID methodID, va_list args);
+ void (JNICALL *CallVoidMethodA)
+ (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args);
+
+ jobject (JNICALL *CallNonvirtualObjectMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jobject (JNICALL *CallNonvirtualObjectMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jobject (JNICALL *CallNonvirtualObjectMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ jvalue * args);
+
+ jboolean (JNICALL *CallNonvirtualBooleanMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jboolean (JNICALL *CallNonvirtualBooleanMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jboolean (JNICALL *CallNonvirtualBooleanMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ jvalue * args);
+
+ jbyte (JNICALL *CallNonvirtualByteMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jbyte (JNICALL *CallNonvirtualByteMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jbyte (JNICALL *CallNonvirtualByteMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ jvalue *args);
+
+ jchar (JNICALL *CallNonvirtualCharMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jchar (JNICALL *CallNonvirtualCharMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jchar (JNICALL *CallNonvirtualCharMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ jvalue *args);
+
+ jshort (JNICALL *CallNonvirtualShortMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jshort (JNICALL *CallNonvirtualShortMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jshort (JNICALL *CallNonvirtualShortMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ jvalue *args);
+
+ jint (JNICALL *CallNonvirtualIntMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jint (JNICALL *CallNonvirtualIntMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jint (JNICALL *CallNonvirtualIntMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ jvalue *args);
+
+ jlong (JNICALL *CallNonvirtualLongMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jlong (JNICALL *CallNonvirtualLongMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jlong (JNICALL *CallNonvirtualLongMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ jvalue *args);
+
+ jfloat (JNICALL *CallNonvirtualFloatMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jfloat (JNICALL *CallNonvirtualFloatMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jfloat (JNICALL *CallNonvirtualFloatMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ jvalue *args);
+
+ jdouble (JNICALL *CallNonvirtualDoubleMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ jdouble (JNICALL *CallNonvirtualDoubleMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ jdouble (JNICALL *CallNonvirtualDoubleMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ jvalue *args);
+
+ void (JNICALL *CallNonvirtualVoidMethod)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...);
+ void (JNICALL *CallNonvirtualVoidMethodV)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ va_list args);
+ void (JNICALL *CallNonvirtualVoidMethodA)
+ (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID,
+ jvalue * args);
+
+ jfieldID (JNICALL *GetFieldID)
+ (JNIEnv *env, jclass clazz, const char *name, const char *sig);
+
+ jobject (JNICALL *GetObjectField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jboolean (JNICALL *GetBooleanField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jbyte (JNICALL *GetByteField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jchar (JNICALL *GetCharField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jshort (JNICALL *GetShortField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jint (JNICALL *GetIntField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jlong (JNICALL *GetLongField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jfloat (JNICALL *GetFloatField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+ jdouble (JNICALL *GetDoubleField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID);
+
+ void (JNICALL *SetObjectField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val);
+ void (JNICALL *SetBooleanField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val);
+ void (JNICALL *SetByteField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val);
+ void (JNICALL *SetCharField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val);
+ void (JNICALL *SetShortField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val);
+ void (JNICALL *SetIntField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jint val);
+ void (JNICALL *SetLongField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val);
+ void (JNICALL *SetFloatField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val);
+ void (JNICALL *SetDoubleField)
+ (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val);
+
+ jmethodID (JNICALL *GetStaticMethodID)
+ (JNIEnv *env, jclass clazz, const char *name, const char *sig);
+
+ jobject (JNICALL *CallStaticObjectMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jobject (JNICALL *CallStaticObjectMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jobject (JNICALL *CallStaticObjectMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jboolean (JNICALL *CallStaticBooleanMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jboolean (JNICALL *CallStaticBooleanMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jboolean (JNICALL *CallStaticBooleanMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jbyte (JNICALL *CallStaticByteMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jbyte (JNICALL *CallStaticByteMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jbyte (JNICALL *CallStaticByteMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jchar (JNICALL *CallStaticCharMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jchar (JNICALL *CallStaticCharMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jchar (JNICALL *CallStaticCharMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jshort (JNICALL *CallStaticShortMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jshort (JNICALL *CallStaticShortMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jshort (JNICALL *CallStaticShortMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jint (JNICALL *CallStaticIntMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jint (JNICALL *CallStaticIntMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jint (JNICALL *CallStaticIntMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jlong (JNICALL *CallStaticLongMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jlong (JNICALL *CallStaticLongMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jlong (JNICALL *CallStaticLongMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jfloat (JNICALL *CallStaticFloatMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jfloat (JNICALL *CallStaticFloatMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jfloat (JNICALL *CallStaticFloatMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
+
+ jdouble (JNICALL *CallStaticDoubleMethod)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, ...);
+ jdouble (JNICALL *CallStaticDoubleMethodV)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
+ jdouble (JNICALL *CallStaticDoubleMethodA)
+ (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
+
+ void (JNICALL *CallStaticVoidMethod)
+ (JNIEnv *env, jclass cls, jmethodID methodID, ...);
+ void (JNICALL *CallStaticVoidMethodV)
+ (JNIEnv *env, jclass cls, jmethodID methodID, va_list args);
+ void (JNICALL *CallStaticVoidMethodA)
+ (JNIEnv *env, jclass cls, jmethodID methodID, jvalue * args);
+
+ jfieldID (JNICALL *GetStaticFieldID)
+ (JNIEnv *env, jclass clazz, const char *name, const char *sig);
+ jobject (JNICALL *GetStaticObjectField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jboolean (JNICALL *GetStaticBooleanField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jbyte (JNICALL *GetStaticByteField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jchar (JNICALL *GetStaticCharField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jshort (JNICALL *GetStaticShortField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jint (JNICALL *GetStaticIntField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jlong (JNICALL *GetStaticLongField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jfloat (JNICALL *GetStaticFloatField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+ jdouble (JNICALL *GetStaticDoubleField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID);
+
+ void (JNICALL *SetStaticObjectField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value);
+ void (JNICALL *SetStaticBooleanField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value);
+ void (JNICALL *SetStaticByteField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value);
+ void (JNICALL *SetStaticCharField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value);
+ void (JNICALL *SetStaticShortField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value);
+ void (JNICALL *SetStaticIntField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value);
+ void (JNICALL *SetStaticLongField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value);
+ void (JNICALL *SetStaticFloatField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value);
+ void (JNICALL *SetStaticDoubleField)
+ (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value);
+
+ jstring (JNICALL *NewString)
+ (JNIEnv *env, const jchar *unicode, jsize len);
+ jsize (JNICALL *GetStringLength)
+ (JNIEnv *env, jstring str);
+ const jchar *(JNICALL *GetStringChars)
+ (JNIEnv *env, jstring str, jboolean *isCopy);
+ void (JNICALL *ReleaseStringChars)
+ (JNIEnv *env, jstring str, const jchar *chars);
+
+ jstring (JNICALL *NewStringUTF)
+ (JNIEnv *env, const char *utf);
+ jsize (JNICALL *GetStringUTFLength)
+ (JNIEnv *env, jstring str);
+ const char* (JNICALL *GetStringUTFChars)
+ (JNIEnv *env, jstring str, jboolean *isCopy);
+ void (JNICALL *ReleaseStringUTFChars)
+ (JNIEnv *env, jstring str, const char* chars);
+
+
+ jsize (JNICALL *GetArrayLength)
+ (JNIEnv *env, jarray array);
+
+ jobjectArray (JNICALL *NewObjectArray)
+ (JNIEnv *env, jsize len, jclass clazz, jobject init);
+ jobject (JNICALL *GetObjectArrayElement)
+ (JNIEnv *env, jobjectArray array, jsize index);
+ void (JNICALL *SetObjectArrayElement)
+ (JNIEnv *env, jobjectArray array, jsize index, jobject val);
+
+ jbooleanArray (JNICALL *NewBooleanArray)
+ (JNIEnv *env, jsize len);
+ jbyteArray (JNICALL *NewByteArray)
+ (JNIEnv *env, jsize len);
+ jcharArray (JNICALL *NewCharArray)
+ (JNIEnv *env, jsize len);
+ jshortArray (JNICALL *NewShortArray)
+ (JNIEnv *env, jsize len);
+ jintArray (JNICALL *NewIntArray)
+ (JNIEnv *env, jsize len);
+ jlongArray (JNICALL *NewLongArray)
+ (JNIEnv *env, jsize len);
+ jfloatArray (JNICALL *NewFloatArray)
+ (JNIEnv *env, jsize len);
+ jdoubleArray (JNICALL *NewDoubleArray)
+ (JNIEnv *env, jsize len);
+
+ jboolean * (JNICALL *GetBooleanArrayElements)
+ (JNIEnv *env, jbooleanArray array, jboolean *isCopy);
+ jbyte * (JNICALL *GetByteArrayElements)
+ (JNIEnv *env, jbyteArray array, jboolean *isCopy);
+ jchar * (JNICALL *GetCharArrayElements)
+ (JNIEnv *env, jcharArray array, jboolean *isCopy);
+ jshort * (JNICALL *GetShortArrayElements)
+ (JNIEnv *env, jshortArray array, jboolean *isCopy);
+ jint * (JNICALL *GetIntArrayElements)
+ (JNIEnv *env, jintArray array, jboolean *isCopy);
+ jlong * (JNICALL *GetLongArrayElements)
+ (JNIEnv *env, jlongArray array, jboolean *isCopy);
+ jfloat * (JNICALL *GetFloatArrayElements)
+ (JNIEnv *env, jfloatArray array, jboolean *isCopy);
+ jdouble * (JNICALL *GetDoubleArrayElements)
+ (JNIEnv *env, jdoubleArray array, jboolean *isCopy);
+
+ void (JNICALL *ReleaseBooleanArrayElements)
+ (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode);
+ void (JNICALL *ReleaseByteArrayElements)
+ (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode);
+ void (JNICALL *ReleaseCharArrayElements)
+ (JNIEnv *env, jcharArray array, jchar *elems, jint mode);
+ void (JNICALL *ReleaseShortArrayElements)
+ (JNIEnv *env, jshortArray array, jshort *elems, jint mode);
+ void (JNICALL *ReleaseIntArrayElements)
+ (JNIEnv *env, jintArray array, jint *elems, jint mode);
+ void (JNICALL *ReleaseLongArrayElements)
+ (JNIEnv *env, jlongArray array, jlong *elems, jint mode);
+ void (JNICALL *ReleaseFloatArrayElements)
+ (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode);
+ void (JNICALL *ReleaseDoubleArrayElements)
+ (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode);
+
+ void (JNICALL *GetBooleanArrayRegion)
+ (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf);
+ void (JNICALL *GetByteArrayRegion)
+ (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf);
+ void (JNICALL *GetCharArrayRegion)
+ (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf);
+ void (JNICALL *GetShortArrayRegion)
+ (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf);
+ void (JNICALL *GetIntArrayRegion)
+ (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf);
+ void (JNICALL *GetLongArrayRegion)
+ (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf);
+ void (JNICALL *GetFloatArrayRegion)
+ (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf);
+ void (JNICALL *GetDoubleArrayRegion)
+ (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf);
+
+ void (JNICALL *SetBooleanArrayRegion)
+ (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf);
+ void (JNICALL *SetByteArrayRegion)
+ (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf);
+ void (JNICALL *SetCharArrayRegion)
+ (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf);
+ void (JNICALL *SetShortArrayRegion)
+ (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf);
+ void (JNICALL *SetIntArrayRegion)
+ (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf);
+ void (JNICALL *SetLongArrayRegion)
+ (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf);
+ void (JNICALL *SetFloatArrayRegion)
+ (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf);
+ void (JNICALL *SetDoubleArrayRegion)
+ (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf);
+
+ jint (JNICALL *RegisterNatives)
+ (JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
+ jint nMethods);
+ jint (JNICALL *UnregisterNatives)
+ (JNIEnv *env, jclass clazz);
+
+ jint (JNICALL *MonitorEnter)
+ (JNIEnv *env, jobject obj);
+ jint (JNICALL *MonitorExit)
+ (JNIEnv *env, jobject obj);
+
+ jint (JNICALL *GetJavaVM)
+ (JNIEnv *env, JavaVM **vm);
+
+ void (JNICALL *GetStringRegion)
+ (JNIEnv *env, jstring, jsize, jsize, jchar*);
+ void (JNICALL *GetStringUTFRegion)
+ (JNIEnv *env, jstring, jsize, jsize, char*);
+
+ void* (JNICALL *GetPrimitiveArrayCritical)
+ (JNIEnv *env, jarray array, jboolean *isCopy);
+ void (JNICALL *ReleasePrimitiveArrayCritical)
+ (JNIEnv *env, jarray array, void* carray, jint mode);
+
+ const jchar* (JNICALL *GetStringCritical)
+ (JNIEnv *env, jstring s, jboolean* isCopy);
+ void (JNICALL *ReleaseStringCritical)
+ (JNIEnv *env, jstring s, const jchar* cstr);
+
+ jweak (JNICALL *NewWeakGlobalRef)
+ (JNIEnv *env, jobject obj);
+ void (JNICALL *DeleteWeakGlobalRef)
+ (JNIEnv *env, jweak obj);
+
+ jboolean (JNICALL *ExceptionCheck)
+ (JNIEnv *env);
+
+ jobject (JNICALL *NewDirectByteBuffer)
+ (JNIEnv* env, void* address, jlong capacity);
+ void* (JNICALL *GetDirectBufferAddress)
+ (JNIEnv* env, jobject buf);
+ jlong (JNICALL *GetDirectBufferCapacity)
+ (JNIEnv* env, jobject buf);
+};
+
+
+/**
+ * JNI Native Method Interface table for use in C++ sources
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp23720">specification</a>
+ * for details
+ */
+struct JNIEnv_External {
+ const struct JNINativeInterface_ *functions;
+
+#ifdef __cplusplus
+ jint GetVersion() {
+ return functions->GetVersion(this);
+ }
+ jclass DefineClass(const char *name, jobject loader, const jbyte *buf,
+ jsize len) {
+ return functions->DefineClass(this, name, loader, buf, len);
+ }
+ jclass FindClass(const char *name) {
+ return functions->FindClass(this, name);
+ }
+ jmethodID FromReflectedMethod(jobject method) {
+ return functions->FromReflectedMethod(this, method);
+ }
+ jfieldID FromReflectedField(jobject field) {
+ return functions->FromReflectedField(this, field);
+ }
+ jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) {
+ return functions->ToReflectedMethod(this, cls, methodID, isStatic);
+ }
+ jclass GetSuperclass(jclass sub) {
+ return functions->GetSuperclass(this, sub);
+ }
+ jboolean IsAssignableFrom(jclass sub, jclass sup) {
+ return functions->IsAssignableFrom(this, sub, sup);
+ }
+ jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) {
+ return functions->ToReflectedField(this, cls, fieldID, isStatic);
+ }
+
+ jint Throw(jthrowable obj) {
+ return functions->Throw(this, obj);
+ }
+ jint ThrowNew(jclass clazz, const char *msg) {
+ return functions->ThrowNew(this, clazz, msg);
+ }
+ jthrowable ExceptionOccurred() {
+ return functions->ExceptionOccurred(this);
+ }
+ void ExceptionDescribe() {
+ functions->ExceptionDescribe(this);
+ }
+ void ExceptionClear() {
+ functions->ExceptionClear(this);
+ }
+ void FatalError(const char *msg) {
+ functions->FatalError(this, msg);
+ }
+
+ jint PushLocalFrame(jint cap) {
+ return functions->PushLocalFrame(this, cap);
+ }
+ jobject PopLocalFrame(jobject res) {
+ return functions->PopLocalFrame(this, res);
+ }
+
+ jobject NewGlobalRef(jobject lobj) {
+ return functions->NewGlobalRef(this,lobj);
+ }
+ void DeleteGlobalRef(jobject gref) {
+ functions->DeleteGlobalRef(this,gref);
+ }
+ void DeleteLocalRef(jobject obj) {
+ functions->DeleteLocalRef(this, obj);
+ }
+
+ jboolean IsSameObject(jobject obj1, jobject obj2) {
+ return functions->IsSameObject(this,obj1,obj2);
+ }
+ jobject NewLocalRef(jobject ref) {
+ return functions->NewLocalRef(this, ref);
+ }
+
+ jint EnsureLocalCapacity(jint cap) {
+ return functions->EnsureLocalCapacity(this,cap);
+ }
+
+ jobject AllocObject(jclass clazz) {
+ return functions->AllocObject(this,clazz);
+ }
+ jobject NewObject(jclass clazz, jmethodID methodID, ...) {
+ va_list args;
+ jobject result;
+ va_start(args, methodID);
+ result = functions->NewObjectV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jobject NewObjectV(jclass clazz, jmethodID methodID,
+ va_list args) {
+ return functions->NewObjectV(this,clazz,methodID,args);
+ }
+ jobject NewObjectA(jclass clazz, jmethodID methodID,
+ jvalue *args) {
+ return functions->NewObjectA(this,clazz,methodID,args);
+ }
+
+ jclass GetObjectClass(jobject obj) {
+ return functions->GetObjectClass(this,obj);
+ }
+ jboolean IsInstanceOf(jobject obj, jclass clazz) {
+ return functions->IsInstanceOf(this,obj,clazz);
+ }
+
+ jmethodID GetMethodID(jclass clazz, const char *name,
+ const char *sig) {
+ return functions->GetMethodID(this,clazz,name,sig);
+ }
+
+ jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jobject result;
+ va_start(args,methodID);
+ result = functions->CallObjectMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jobject CallObjectMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallObjectMethodV(this,obj,methodID,args);
+ }
+ jobject CallObjectMethodA(jobject obj, jmethodID methodID,
+ jvalue * args) {
+ return functions->CallObjectMethodA(this,obj,methodID,args);
+ }
+
+ jboolean CallBooleanMethod(jobject obj,
+ jmethodID methodID, ...) {
+ va_list args;
+ jboolean result;
+ va_start(args,methodID);
+ result = functions->CallBooleanMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jboolean CallBooleanMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallBooleanMethodV(this,obj,methodID,args);
+ }
+ jboolean CallBooleanMethodA(jobject obj, jmethodID methodID,
+ jvalue * args) {
+ return functions->CallBooleanMethodA(this,obj,methodID, args);
+ }
+
+ jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jbyte result;
+ va_start(args,methodID);
+ result = functions->CallByteMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jbyte CallByteMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallByteMethodV(this,obj,methodID,args);
+ }
+ jbyte CallByteMethodA(jobject obj, jmethodID methodID,
+ jvalue * args) {
+ return functions->CallByteMethodA(this,obj,methodID,args);
+ }
+
+ jchar CallCharMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jchar result;
+ va_start(args,methodID);
+ result = functions->CallCharMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jchar CallCharMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallCharMethodV(this,obj,methodID,args);
+ }
+ jchar CallCharMethodA(jobject obj, jmethodID methodID,
+ jvalue * args) {
+ return functions->CallCharMethodA(this,obj,methodID,args);
+ }
+
+ jshort CallShortMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jshort result;
+ va_start(args,methodID);
+ result = functions->CallShortMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jshort CallShortMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallShortMethodV(this,obj,methodID,args);
+ }
+ jshort CallShortMethodA(jobject obj, jmethodID methodID,
+ jvalue * args) {
+ return functions->CallShortMethodA(this,obj,methodID,args);
+ }
+
+ jint CallIntMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jint result;
+ va_start(args,methodID);
+ result = functions->CallIntMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jint CallIntMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallIntMethodV(this,obj,methodID,args);
+ }
+ jint CallIntMethodA(jobject obj, jmethodID methodID,
+ jvalue * args) {
+ return functions->CallIntMethodA(this,obj,methodID,args);
+ }
+
+ jlong CallLongMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jlong result;
+ va_start(args,methodID);
+ result = functions->CallLongMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jlong CallLongMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallLongMethodV(this,obj,methodID,args);
+ }
+ jlong CallLongMethodA(jobject obj, jmethodID methodID,
+ jvalue * args) {
+ return functions->CallLongMethodA(this,obj,methodID,args);
+ }
+
+ jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jfloat result;
+ va_start(args,methodID);
+ result = functions->CallFloatMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jfloat CallFloatMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallFloatMethodV(this,obj,methodID,args);
+ }
+ jfloat CallFloatMethodA(jobject obj, jmethodID methodID,
+ jvalue * args) {
+ return functions->CallFloatMethodA(this,obj,methodID,args);
+ }
+
+ jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ jdouble result;
+ va_start(args,methodID);
+ result = functions->CallDoubleMethodV(this,obj,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jdouble CallDoubleMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ return functions->CallDoubleMethodV(this,obj,methodID,args);
+ }
+ jdouble CallDoubleMethodA(jobject obj, jmethodID methodID,
+ jvalue * args) {
+ return functions->CallDoubleMethodA(this,obj,methodID,args);
+ }
+
+ void CallVoidMethod(jobject obj, jmethodID methodID, ...) {
+ va_list args;
+ va_start(args,methodID);
+ functions->CallVoidMethodV(this,obj,methodID,args);
+ va_end(args);
+ }
+ void CallVoidMethodV(jobject obj, jmethodID methodID,
+ va_list args) {
+ functions->CallVoidMethodV(this,obj,methodID,args);
+ }
+ void CallVoidMethodA(jobject obj, jmethodID methodID,
+ jvalue * args) {
+ functions->CallVoidMethodA(this,obj,methodID,args);
+ }
+
+ jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jobject result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualObjectMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualObjectMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, jvalue * args) {
+ return functions->CallNonvirtualObjectMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jboolean result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualBooleanMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, jvalue * args) {
+ return functions->CallNonvirtualBooleanMethodA(this,obj,clazz,
+ methodID, args);
+ }
+
+ jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jbyte result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualByteMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualByteMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, jvalue * args) {
+ return functions->CallNonvirtualByteMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jchar CallNonvirtualCharMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jchar result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualCharMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualCharMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, jvalue * args) {
+ return functions->CallNonvirtualCharMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jshort CallNonvirtualShortMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jshort result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualShortMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualShortMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, jvalue * args) {
+ return functions->CallNonvirtualShortMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jint CallNonvirtualIntMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jint result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualIntMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jint CallNonvirtualIntMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualIntMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jint CallNonvirtualIntMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, jvalue * args) {
+ return functions->CallNonvirtualIntMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jlong CallNonvirtualLongMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jlong result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualLongMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallNonvirtualLongMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz,
+ jmethodID methodID, jvalue * args) {
+ return functions->CallNonvirtualLongMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jfloat result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualFloatMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz,
+ jmethodID methodID,
+ va_list args) {
+ return functions->CallNonvirtualFloatMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz,
+ jmethodID methodID,
+ jvalue * args) {
+ return functions->CallNonvirtualFloatMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jdouble result;
+ va_start(args,methodID);
+ result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz,
+ methodID,args);
+ va_end(args);
+ return result;
+ }
+ jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz,
+ jmethodID methodID,
+ va_list args) {
+ return functions->CallNonvirtualDoubleMethodV(this,obj,clazz,
+ methodID,args);
+ }
+ jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz,
+ jmethodID methodID,
+ jvalue * args) {
+ return functions->CallNonvirtualDoubleMethodA(this,obj,clazz,
+ methodID,args);
+ }
+
+ void CallNonvirtualVoidMethod(jobject obj, jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ va_start(args,methodID);
+ functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args);
+ va_end(args);
+ }
+ void CallNonvirtualVoidMethodV(jobject obj, jclass clazz,
+ jmethodID methodID,
+ va_list args) {
+ functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args);
+ }
+ void CallNonvirtualVoidMethodA(jobject obj, jclass clazz,
+ jmethodID methodID,
+ jvalue * args) {
+ functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args);
+ }
+
+ jfieldID GetFieldID(jclass clazz, const char *name,
+ const char *sig) {
+ return functions->GetFieldID(this,clazz,name,sig);
+ }
+
+ jobject GetObjectField(jobject obj, jfieldID fieldID) {
+ return functions->GetObjectField(this,obj,fieldID);
+ }
+ jboolean GetBooleanField(jobject obj, jfieldID fieldID) {
+ return functions->GetBooleanField(this,obj,fieldID);
+ }
+ jbyte GetByteField(jobject obj, jfieldID fieldID) {
+ return functions->GetByteField(this,obj,fieldID);
+ }
+ jchar GetCharField(jobject obj, jfieldID fieldID) {
+ return functions->GetCharField(this,obj,fieldID);
+ }
+ jshort GetShortField(jobject obj, jfieldID fieldID) {
+ return functions->GetShortField(this,obj,fieldID);
+ }
+ jint GetIntField(jobject obj, jfieldID fieldID) {
+ return functions->GetIntField(this,obj,fieldID);
+ }
+ jlong GetLongField(jobject obj, jfieldID fieldID) {
+ return functions->GetLongField(this,obj,fieldID);
+ }
+ jfloat GetFloatField(jobject obj, jfieldID fieldID) {
+ return functions->GetFloatField(this,obj,fieldID);
+ }
+ jdouble GetDoubleField(jobject obj, jfieldID fieldID) {
+ return functions->GetDoubleField(this,obj,fieldID);
+ }
+
+ void SetObjectField(jobject obj, jfieldID fieldID, jobject val) {
+ functions->SetObjectField(this,obj,fieldID,val);
+ }
+ void SetBooleanField(jobject obj, jfieldID fieldID,
+ jboolean val) {
+ functions->SetBooleanField(this,obj,fieldID,val);
+ }
+ void SetByteField(jobject obj, jfieldID fieldID,
+ jbyte val) {
+ functions->SetByteField(this,obj,fieldID,val);
+ }
+ void SetCharField(jobject obj, jfieldID fieldID,
+ jchar val) {
+ functions->SetCharField(this,obj,fieldID,val);
+ }
+ void SetShortField(jobject obj, jfieldID fieldID,
+ jshort val) {
+ functions->SetShortField(this,obj,fieldID,val);
+ }
+ void SetIntField(jobject obj, jfieldID fieldID,
+ jint val) {
+ functions->SetIntField(this,obj,fieldID,val);
+ }
+ void SetLongField(jobject obj, jfieldID fieldID,
+ jlong val) {
+ functions->SetLongField(this,obj,fieldID,val);
+ }
+ void SetFloatField(jobject obj, jfieldID fieldID,
+ jfloat val) {
+ functions->SetFloatField(this,obj,fieldID,val);
+ }
+ void SetDoubleField(jobject obj, jfieldID fieldID,
+ jdouble val) {
+ functions->SetDoubleField(this,obj,fieldID,val);
+ }
+
+ jmethodID GetStaticMethodID(jclass clazz, const char *name,
+ const char *sig) {
+ return functions->GetStaticMethodID(this,clazz,name,sig);
+ }
+
+ jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID,
+ ...) {
+ va_list args;
+ jobject result;
+ va_start(args,methodID);
+ result = functions->CallStaticObjectMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID,
+ va_list args) {
+ return functions->CallStaticObjectMethodV(this,clazz,methodID,args);
+ }
+ jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID,
+ jvalue *args) {
+ return functions->CallStaticObjectMethodA(this,clazz,methodID,args);
+ }
+
+ jboolean CallStaticBooleanMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jboolean result;
+ va_start(args,methodID);
+ result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jboolean CallStaticBooleanMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticBooleanMethodV(this,clazz,methodID,args);
+ }
+ jboolean CallStaticBooleanMethodA(jclass clazz,
+ jmethodID methodID, jvalue *args) {
+ return functions->CallStaticBooleanMethodA(this,clazz,methodID,args);
+ }
+
+ jbyte CallStaticByteMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jbyte result;
+ va_start(args,methodID);
+ result = functions->CallStaticByteMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jbyte CallStaticByteMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticByteMethodV(this,clazz,methodID,args);
+ }
+ jbyte CallStaticByteMethodA(jclass clazz,
+ jmethodID methodID, jvalue *args) {
+ return functions->CallStaticByteMethodA(this,clazz,methodID,args);
+ }
+
+ jchar CallStaticCharMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jchar result;
+ va_start(args,methodID);
+ result = functions->CallStaticCharMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jchar CallStaticCharMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticCharMethodV(this,clazz,methodID,args);
+ }
+ jchar CallStaticCharMethodA(jclass clazz,
+ jmethodID methodID, jvalue *args) {
+ return functions->CallStaticCharMethodA(this,clazz,methodID,args);
+ }
+
+ jshort CallStaticShortMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jshort result;
+ va_start(args,methodID);
+ result = functions->CallStaticShortMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jshort CallStaticShortMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticShortMethodV(this,clazz,methodID,args);
+ }
+ jshort CallStaticShortMethodA(jclass clazz,
+ jmethodID methodID, jvalue *args) {
+ return functions->CallStaticShortMethodA(this,clazz,methodID,args);
+ }
+
+ jint CallStaticIntMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jint result;
+ va_start(args,methodID);
+ result = functions->CallStaticIntMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jint CallStaticIntMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticIntMethodV(this,clazz,methodID,args);
+ }
+ jint CallStaticIntMethodA(jclass clazz,
+ jmethodID methodID, jvalue *args) {
+ return functions->CallStaticIntMethodA(this,clazz,methodID,args);
+ }
+
+ jlong CallStaticLongMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jlong result;
+ va_start(args,methodID);
+ result = functions->CallStaticLongMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jlong CallStaticLongMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticLongMethodV(this,clazz,methodID,args);
+ }
+ jlong CallStaticLongMethodA(jclass clazz,
+ jmethodID methodID, jvalue *args) {
+ return functions->CallStaticLongMethodA(this,clazz,methodID,args);
+ }
+
+ jfloat CallStaticFloatMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jfloat result;
+ va_start(args,methodID);
+ result = functions->CallStaticFloatMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jfloat CallStaticFloatMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticFloatMethodV(this,clazz,methodID,args);
+ }
+ jfloat CallStaticFloatMethodA(jclass clazz,
+ jmethodID methodID, jvalue *args) {
+ return functions->CallStaticFloatMethodA(this,clazz,methodID,args);
+ }
+
+ jdouble CallStaticDoubleMethod(jclass clazz,
+ jmethodID methodID, ...) {
+ va_list args;
+ jdouble result;
+ va_start(args,methodID);
+ result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args);
+ va_end(args);
+ return result;
+ }
+ jdouble CallStaticDoubleMethodV(jclass clazz,
+ jmethodID methodID, va_list args) {
+ return functions->CallStaticDoubleMethodV(this,clazz,methodID,args);
+ }
+ jdouble CallStaticDoubleMethodA(jclass clazz,
+ jmethodID methodID, jvalue *args) {
+ return functions->CallStaticDoubleMethodA(this,clazz,methodID,args);
+ }
+
+ void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) {
+ va_list args;
+ va_start(args,methodID);
+ functions->CallStaticVoidMethodV(this,cls,methodID,args);
+ va_end(args);
+ }
+ void CallStaticVoidMethodV(jclass cls, jmethodID methodID,
+ va_list args) {
+ functions->CallStaticVoidMethodV(this,cls,methodID,args);
+ }
+ void CallStaticVoidMethodA(jclass cls, jmethodID methodID,
+ jvalue * args) {
+ functions->CallStaticVoidMethodA(this,cls,methodID,args);
+ }
+
+ jfieldID GetStaticFieldID(jclass clazz, const char *name,
+ const char *sig) {
+ return functions->GetStaticFieldID(this,clazz,name,sig);
+ }
+ jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticObjectField(this,clazz,fieldID);
+ }
+ jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticBooleanField(this,clazz,fieldID);
+ }
+ jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticByteField(this,clazz,fieldID);
+ }
+ jchar GetStaticCharField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticCharField(this,clazz,fieldID);
+ }
+ jshort GetStaticShortField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticShortField(this,clazz,fieldID);
+ }
+ jint GetStaticIntField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticIntField(this,clazz,fieldID);
+ }
+ jlong GetStaticLongField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticLongField(this,clazz,fieldID);
+ }
+ jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticFloatField(this,clazz,fieldID);
+ }
+ jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) {
+ return functions->GetStaticDoubleField(this,clazz,fieldID);
+ }
+
+ void SetStaticObjectField(jclass clazz, jfieldID fieldID,
+ jobject value) {
+ functions->SetStaticObjectField(this,clazz,fieldID,value);
+ }
+ void SetStaticBooleanField(jclass clazz, jfieldID fieldID,
+ jboolean value) {
+ functions->SetStaticBooleanField(this,clazz,fieldID,value);
+ }
+ void SetStaticByteField(jclass clazz, jfieldID fieldID,
+ jbyte value) {
+ functions->SetStaticByteField(this,clazz,fieldID,value);
+ }
+ void SetStaticCharField(jclass clazz, jfieldID fieldID,
+ jchar value) {
+ functions->SetStaticCharField(this,clazz,fieldID,value);
+ }
+ void SetStaticShortField(jclass clazz, jfieldID fieldID,
+ jshort value) {
+ functions->SetStaticShortField(this,clazz,fieldID,value);
+ }
+ void SetStaticIntField(jclass clazz, jfieldID fieldID,
+ jint value) {
+ functions->SetStaticIntField(this,clazz,fieldID,value);
+ }
+ void SetStaticLongField(jclass clazz, jfieldID fieldID,
+ jlong value) {
+ functions->SetStaticLongField(this,clazz,fieldID,value);
+ }
+ void SetStaticFloatField(jclass clazz, jfieldID fieldID,
+ jfloat value) {
+ functions->SetStaticFloatField(this,clazz,fieldID,value);
+ }
+ void SetStaticDoubleField(jclass clazz, jfieldID fieldID,
+ jdouble value) {
+ functions->SetStaticDoubleField(this,clazz,fieldID,value);
+ }
+
+ jstring NewString(const jchar *unicode, jsize len) {
+ return functions->NewString(this,unicode,len);
+ }
+ jsize GetStringLength(jstring str) {
+ return functions->GetStringLength(this,str);
+ }
+ const jchar *GetStringChars(jstring str, jboolean *isCopy) {
+ return functions->GetStringChars(this,str,isCopy);
+ }
+ void ReleaseStringChars(jstring str, const jchar *chars) {
+ functions->ReleaseStringChars(this,str,chars);
+ }
+
+ jstring NewStringUTF(const char *utf) {
+ return functions->NewStringUTF(this,utf);
+ }
+ jsize GetStringUTFLength(jstring str) {
+ return functions->GetStringUTFLength(this,str);
+ }
+ const char* GetStringUTFChars(jstring str, jboolean *isCopy) {
+ return functions->GetStringUTFChars(this,str,isCopy);
+ }
+ void ReleaseStringUTFChars(jstring str, const char* chars) {
+ functions->ReleaseStringUTFChars(this,str,chars);
+ }
+
+ jsize GetArrayLength(jarray array) {
+ return functions->GetArrayLength(this,array);
+ }
+
+ jobjectArray NewObjectArray(jsize len, jclass clazz,
+ jobject init) {
+ return functions->NewObjectArray(this,len,clazz,init);
+ }
+ jobject GetObjectArrayElement(jobjectArray array, jsize index) {
+ return functions->GetObjectArrayElement(this,array,index);
+ }
+ void SetObjectArrayElement(jobjectArray array, jsize index,
+ jobject val) {
+ functions->SetObjectArrayElement(this,array,index,val);
+ }
+
+ jbooleanArray NewBooleanArray(jsize len) {
+ return functions->NewBooleanArray(this,len);
+ }
+ jbyteArray NewByteArray(jsize len) {
+ return functions->NewByteArray(this,len);
+ }
+ jcharArray NewCharArray(jsize len) {
+ return functions->NewCharArray(this,len);
+ }
+ jshortArray NewShortArray(jsize len) {
+ return functions->NewShortArray(this,len);
+ }
+ jintArray NewIntArray(jsize len) {
+ return functions->NewIntArray(this,len);
+ }
+ jlongArray NewLongArray(jsize len) {
+ return functions->NewLongArray(this,len);
+ }
+ jfloatArray NewFloatArray(jsize len) {
+ return functions->NewFloatArray(this,len);
+ }
+ jdoubleArray NewDoubleArray(jsize len) {
+ return functions->NewDoubleArray(this,len);
+ }
+
+ jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) {
+ return functions->GetBooleanArrayElements(this,array,isCopy);
+ }
+ jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) {
+ return functions->GetByteArrayElements(this,array,isCopy);
+ }
+ jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) {
+ return functions->GetCharArrayElements(this,array,isCopy);
+ }
+ jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) {
+ return functions->GetShortArrayElements(this,array,isCopy);
+ }
+ jint * GetIntArrayElements(jintArray array, jboolean *isCopy) {
+ return functions->GetIntArrayElements(this,array,isCopy);
+ }
+ jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) {
+ return functions->GetLongArrayElements(this,array,isCopy);
+ }
+ jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) {
+ return functions->GetFloatArrayElements(this,array,isCopy);
+ }
+ jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) {
+ return functions->GetDoubleArrayElements(this,array,isCopy);
+ }
+
+ void ReleaseBooleanArrayElements(jbooleanArray array,
+ jboolean *elems,
+ jint mode) {
+ functions->ReleaseBooleanArrayElements(this,array,elems,mode);
+ }
+ void ReleaseByteArrayElements(jbyteArray array,
+ jbyte *elems,
+ jint mode) {
+ functions->ReleaseByteArrayElements(this,array,elems,mode);
+ }
+ void ReleaseCharArrayElements(jcharArray array,
+ jchar *elems,
+ jint mode) {
+ functions->ReleaseCharArrayElements(this,array,elems,mode);
+ }
+ void ReleaseShortArrayElements(jshortArray array,
+ jshort *elems,
+ jint mode) {
+ functions->ReleaseShortArrayElements(this,array,elems,mode);
+ }
+ void ReleaseIntArrayElements(jintArray array,
+ jint *elems,
+ jint mode) {
+ functions->ReleaseIntArrayElements(this,array,elems,mode);
+ }
+ void ReleaseLongArrayElements(jlongArray array,
+ jlong *elems,
+ jint mode) {
+ functions->ReleaseLongArrayElements(this,array,elems,mode);
+ }
+ void ReleaseFloatArrayElements(jfloatArray array,
+ jfloat *elems,
+ jint mode) {
+ functions->ReleaseFloatArrayElements(this,array,elems,mode);
+ }
+ void ReleaseDoubleArrayElements(jdoubleArray array,
+ jdouble *elems,
+ jint mode) {
+ functions->ReleaseDoubleArrayElements(this,array,elems,mode);
+ }
+
+ void GetBooleanArrayRegion(jbooleanArray array,
+ jsize start, jsize len, jboolean *buf) {
+ functions->GetBooleanArrayRegion(this,array,start,len,buf);
+ }
+ void GetByteArrayRegion(jbyteArray array,
+ jsize start, jsize len, jbyte *buf) {
+ functions->GetByteArrayRegion(this,array,start,len,buf);
+ }
+ void GetCharArrayRegion(jcharArray array,
+ jsize start, jsize len, jchar *buf) {
+ functions->GetCharArrayRegion(this,array,start,len,buf);
+ }
+ void GetShortArrayRegion(jshortArray array,
+ jsize start, jsize len, jshort *buf) {
+ functions->GetShortArrayRegion(this,array,start,len,buf);
+ }
+ void GetIntArrayRegion(jintArray array,
+ jsize start, jsize len, jint *buf) {
+ functions->GetIntArrayRegion(this,array,start,len,buf);
+ }
+ void GetLongArrayRegion(jlongArray array,
+ jsize start, jsize len, jlong *buf) {
+ functions->GetLongArrayRegion(this,array,start,len,buf);
+ }
+ void GetFloatArrayRegion(jfloatArray array,
+ jsize start, jsize len, jfloat *buf) {
+ functions->GetFloatArrayRegion(this,array,start,len,buf);
+ }
+ void GetDoubleArrayRegion(jdoubleArray array,
+ jsize start, jsize len, jdouble *buf) {
+ functions->GetDoubleArrayRegion(this,array,start,len,buf);
+ }
+
+ void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
+ jboolean *buf) {
+ functions->SetBooleanArrayRegion(this,array,start,len,buf);
+ }
+ void SetByteArrayRegion(jbyteArray array, jsize start, jsize len,
+ jbyte *buf) {
+ functions->SetByteArrayRegion(this,array,start,len,buf);
+ }
+ void SetCharArrayRegion(jcharArray array, jsize start, jsize len,
+ jchar *buf) {
+ functions->SetCharArrayRegion(this,array,start,len,buf);
+ }
+ void SetShortArrayRegion(jshortArray array, jsize start, jsize len,
+ jshort *buf) {
+ functions->SetShortArrayRegion(this,array,start,len,buf);
+ }
+ void SetIntArrayRegion(jintArray array, jsize start, jsize len,
+ jint *buf) {
+ functions->SetIntArrayRegion(this,array,start,len,buf);
+ }
+ void SetLongArrayRegion(jlongArray array, jsize start, jsize len,
+ jlong *buf) {
+ functions->SetLongArrayRegion(this,array,start,len,buf);
+ }
+ void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
+ jfloat *buf) {
+ functions->SetFloatArrayRegion(this,array,start,len,buf);
+ }
+ void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
+ jdouble *buf) {
+ functions->SetDoubleArrayRegion(this,array,start,len,buf);
+ }
+
+ jint RegisterNatives(jclass clazz, const JNINativeMethod *methods,
+ jint nMethods) {
+ return functions->RegisterNatives(this,clazz,methods,nMethods);
+ }
+ jint UnregisterNatives(jclass clazz) {
+ return functions->UnregisterNatives(this,clazz);
+ }
+
+ jint MonitorEnter(jobject obj) {
+ return functions->MonitorEnter(this,obj);
+ }
+ jint MonitorExit(jobject obj) {
+ return functions->MonitorExit(this,obj);
+ }
+
+ jint GetJavaVM(JavaVM **vm) {
+ return functions->GetJavaVM(this,vm);
+ }
+
+ void GetStringRegion(jstring s, jsize off, jsize len, jchar* d) {
+ functions->GetStringRegion(this, s, off, len, d);
+ }
+ void GetStringUTFRegion(jstring s, jsize off, jsize len, char* d) {
+ functions->GetStringUTFRegion(this, s, off, len, d);
+ }
+
+ void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy) {
+ return functions->GetPrimitiveArrayCritical(this, array, isCopy);
+ }
+
+ void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode) {
+ functions->ReleasePrimitiveArrayCritical(this, array, carray, mode);
+ }
+
+ const jchar* GetStringCritical(jstring s, jboolean* isCopy) {
+ return functions->GetStringCritical(this, s, isCopy);
+ }
+ void ReleaseStringCritical(jstring s, const jchar* cstr) {
+ functions->ReleaseStringCritical(this, s, cstr);
+ }
+
+ jweak NewWeakGlobalRef(jobject obj) {
+ return functions->NewWeakGlobalRef(this, obj);
+ }
+
+ void DeleteWeakGlobalRef(jweak obj) {
+ functions->DeleteWeakGlobalRef(this, obj);
+ }
+
+ jboolean ExceptionCheck() {
+ return functions->ExceptionCheck(this);
+ }
+
+ jobject NewDirectByteBuffer(void *address, jlong capacity) {
+ return functions->NewDirectByteBuffer(this, address, capacity);
+ }
+ void *GetDirectBufferAddress(jobject buf) {
+ return functions->GetDirectBufferAddress(this, buf);
+ }
+ jlong GetDirectBufferCapacity(jobject buf) {
+ return functions->GetDirectBufferCapacity(this, buf);
+ }
+#endif
+
+};
+
+/**
+ * Structure which describes one Java VM invocation argument
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/invocation.html#wp16334">specification</a>
+ * for details.
+ */
+typedef struct JavaVMOption {
+ char *optionString;
+ void *extraInfo;
+} JavaVMOption;
+
+/**
+ * Structure which describes one Java VM invocation arguments for JNI
+ * interface version 1.2 and greater
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/invocation.html#wp16334">specification</a>
+ * for details.
+ */
+typedef struct JavaVMInitArgs {
+ jint version;
+ jint nOptions;
+ JavaVMOption *options;
+ jboolean ignoreUnrecognized;
+} JavaVMInitArgs;
+
+/**
+ * Structure which describes arguments for attaching a native thread to a Java VM
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/invocation.html#attach_current_thread">specification</a>
+ * for details.
+ */
+typedef struct JavaVMAttachArgs {
+ jint version;
+ char *name;
+ jobject group;
+} JavaVMAttachArgs;
+
+/**
+ * JNI Invocation Interface table for use in C sources
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/invocation.html#invocation_api_functions">
+ * specification</a> for details
+ */
+struct JNIInvokeInterface_ {
+ void* reserved0;
+ void* reserved1;
+ void* reserved2;
+
+ jint (JNICALL *DestroyJavaVM)(JavaVM*);
+
+ jint (JNICALL *AttachCurrentThread)(JavaVM*, void** penv, void* args);
+ jint (JNICALL *DetachCurrentThread)(JavaVM*);
+
+ jint (JNICALL *GetEnv)(JavaVM*, void** penv, jint ver);
+
+ jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM*, void** penv, void* args);
+};
+
+/**
+ * JNI Invocation Interface table for use in C++ sources
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/invocation.html#invocation_api_functions">
+ * specification</a> for details
+ */
+struct JavaVM_External {
+ const struct JNIInvokeInterface_* functions;
+
+#ifdef __cplusplus
+ jint DestroyJavaVM() {
+ return functions->DestroyJavaVM(this);
+ }
+
+ jint AttachCurrentThread(void** penv, void* args) {
+ return functions->AttachCurrentThread(this, penv, args);
+ }
+
+ jint DetachCurrentThread() {
+ return functions->DetachCurrentThread(this);
+ }
+
+ jint GetEnv(void** penv, jint ver) {
+ return functions->GetEnv(this, penv, ver);
+ }
+
+ jint AttachCurrentThreadAsDaemon(void** penv, void* args) {
+ return functions->AttachCurrentThreadAsDaemon(this, penv, args);
+ }
+
+#endif
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @def _JNI_EXPORT_
+ * Function attribute used when building VM from sources
+ */
+#ifdef BUILDING_VM
+#define _JNI_EXPORT_
+#else
+#define _JNI_EXPORT_ JNIIMPORT
+#endif
+
+/**
+ * Function to get the default VM arguments
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/invocation.html#wp16064">specification</a>
+ * for details.
+ */
+_JNI_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void * vm_args);
+
+/**
+ * Function to get an array of already created Java VMs in the current
+ * process
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/invocation.html#wp633">specification</a>
+ * for details.
+ */
+_JNI_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM ** vmBuf,
+ jsize bufLen,
+ jsize * nVMs);
+
+/**
+ * Creates Java VM in the current process
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/invocation.html#wp16334">specification</a>
+ * for details.
+ */
+_JNI_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM ** p_vm, JNIEnv ** p_env,
+ void * vm_args);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _JNI_H_ */
diff --git a/src/main/cpp/bootstrap/include/jni_types.h b/src/main/cpp/bootstrap/include/jni_types.h
new file mode 100644
index 0000000..a809ebb
--- /dev/null
+++ b/src/main/cpp/bootstrap/include/jni_types.h
@@ -0,0 +1,451 @@
+/*
+ * 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.
+ */
+
+#ifndef _JNI_TYPES_H_
+#define _JNI_TYPES_H_
+
+/**
+ * @file
+ * Types used in JNI and OPEN interfaces.
+ *
+ * For the most part JNI types are defined by Sun specification on
+ * Java Native Interface (JNI). See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html">specification</a>
+ * for details.
+ */
+
+/* The following documentation is both for windows and linux, so it
+ * resides outside of ifdef-endif block */
+/**
+ * @def JNIEXPORT
+ * Function attribute to make native JNI function exportable
+ */
+/**
+ * @def JNIIMPORT
+ * Function attribute used when building VM from sources
+ */
+/**
+ * @def JNICALL
+ * Function attribute to specify calling conventions that should be
+ * used for native JNI functions
+ */
+/**
+ * @typedef jlong
+ * Signed 64-bit long type equivalent to Java "long" type
+ */
+#if defined (_WIN32) || defined (__WIN32__) || defined (WIN32)
+
+#define JNIEXPORT __declspec(dllexport)
+#define JNIIMPORT __declspec(dllimport)
+#define JNICALL __stdcall
+
+typedef signed __int64 jlong;
+
+#else
+
+#define JNIEXPORT
+#define JNIIMPORT
+#define JNICALL
+
+typedef signed long long jlong;
+
+#endif
+
+/*
+ * Primitive types
+ */
+/**
+ * Unsigned 8-bit primitive boolean type equivalent to Java "boolean"
+ * type
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp428">specification</a>
+ * for details.
+ */
+typedef unsigned char jboolean;
+/**
+ * Signed 8-bit primitive byte type equivalent to Java "byte" type
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp428">specification</a>
+ * for details.
+ */
+typedef signed char jbyte;
+/**
+ * Unsigned 16-bit primitive char type equivalent to Java "char" type
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp428">specification</a>
+ * for details.
+ */
+typedef unsigned short jchar;
+/**
+ * Signed 16-bit primitive short type equivalent to Java "short" type
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp428">specification</a>
+ * for details.
+ */
+typedef signed short jshort;
+/**
+ * Signed 32-bit primitive integer type equivalent to Java "int" type
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp428">specification</a>
+ * for details.
+ */
+typedef signed int jint;
+/**
+ * Signed 32-bit primitive floating point type equivalent to Java
+ * "float" type
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp428">specification</a>
+ * for details.
+ */
+typedef float jfloat;
+/**
+ * Signed 64-bit primitive floating point type equivalent to Java
+ * "double" type
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp428">specification</a>
+ * for details.
+ */
+typedef double jdouble;
+/**
+ * Signed 32-bit primitive integer type used to describe sizes
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp428">specification</a>
+ * for details.
+ */
+typedef jint jsize;
+
+/*
+ * Java types
+ */
+struct _jobject;
+/**
+ * Reference type which describes a general Java object in native
+ * function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+typedef struct _jobject* jobject;
+/**
+ * Reference type which describes a java.lang.Class instance object in
+ * native function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+typedef jobject jclass;
+/**
+ * Reference type which describes a java.lang.String instance object
+ * in native function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+typedef jobject jstring;
+/**
+ * Reference type which describes a generic array instance object in
+ * native function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+typedef jobject jarray;
+/**
+ * Reference type which describes an array of java.lang.Object
+ * instances in native function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+ typedef jarray jobjectArray;
+/**
+ * Reference type which describes an array of booleans in native
+ * function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+ typedef jarray jbooleanArray;
+/**
+ * Reference type which describes an array of bytes type in native
+ * function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+ typedef jarray jbyteArray;
+/**
+ * Reference type which describes an array of chars type in native
+ * function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+ typedef jarray jcharArray;
+/**
+ * Reference type which describes an array of shorts type in native
+ * function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+ typedef jarray jshortArray;
+/**
+ * Reference type which describes an array of ints type in native
+ * function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+ typedef jarray jintArray;
+/**
+ * Reference type which describes an array of longs type in native
+ * function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+ typedef jarray jlongArray;
+/**
+ * Reference type which describes an array of floats type in native
+ * function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+ typedef jarray jfloatArray;
+/**
+ * Reference type which describes an array of doubles type in native
+ * function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+ typedef jarray jdoubleArray;
+/**
+ * Reference type which describes a java.lang.Throwable instance
+ * object in native function
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/types.html#wp15954">specification</a>
+ * for details.
+ */
+typedef jobject jthrowable;
+/**
+ * Reference type which describes a weak reference to a general object
+ *
+ * This type is the same as #jobject but the reference held in it
+ * is weak, so if the referred object is weakly reacheable, it may be
+ * garbage collected to VM.
+ */
+typedef jobject jweak;
+
+/**
+ * This union used to pass arguments to native functions when <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp4256">Call<type>MethodA</a>
+ * and <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp4796">CallStatic<type>MethodA</a>
+ * functions are used
+ *
+ * It consists of all possible primitive Java types plus #jobject, so
+ * it is possible to pass any kind of argument type through it.
+ */
+typedef union jvalue {
+ jboolean z;
+ jbyte b;
+ jchar c;
+ jshort s;
+ jint i;
+ jlong j;
+ jfloat f;
+ jdouble d;
+ jobject l;
+} jvalue;
+
+/**
+ * Type which describes an identfier of a field inside of class
+ *
+ * This type together with a #jclass reference uniquily identifies a
+ * field inside of the class described by #jclass.
+ */
+typedef struct _jfieldID* jfieldID;
+
+/**
+ * Type which describes an identfier of a method inside of class
+ *
+ * This type together with a #jclass reference uniquily identifies a
+ * method inside of the class described by #jclass.
+ */
+typedef struct _jmethodID* jmethodID;
+
+/*
+ * Constants
+ */
+
+/*
+ * Boolean constants
+ */
+/**
+ * Constant which defines boolean truth in native Java functions. It
+ * is equivalent to Java constant "true"
+ */
+#define JNI_FALSE 0
+/**
+ * Constant which defines boolean false in native Java functions. It
+ * is equivalent to Java constant "false"
+ */
+#define JNI_TRUE 1
+
+/*
+ * Return values
+ */
+/**
+ * Constant which describes success when returned by JNI API functions
+ */
+#define JNI_OK 0
+/**
+ * Constant which describes an error when returned by JNI API
+ * functions
+ */
+#define JNI_ERR (-1)
+/**
+ * Constant which describes a deatached thread condition when returned
+ * by JNI API functions
+ */
+#define JNI_EDETACHED (-2)
+/**
+ * Constant which describes wrong JNI interface verions when returned
+ * by JNI API functions
+ */
+#define JNI_EVERSION (-3)
+/**
+ * Constant which describes out of memory condition when returned by
+ * JNI API functions
+ */
+#define JNI_ENOMEM (-4)
+/**
+ * Constant which means that a limited resource already exists when
+ * returned by JNI API functions
+ */
+#define JNI_EEXIST (-5)
+/**
+ * Constant which means that an illegal argument value was passed to a
+ * JNI function
+ */
+#define JNI_EINVAL (-6)
+
+/*
+ * Release modes for working with arrays.
+ */
+/**
+ * Constant which means that an array region should be committed into
+ * memory. Used in Release<primitive type>ArrayElements functions
+ */
+#define JNI_COMMIT 1
+/**
+ * Constant which means that an array region should be discarded. Used
+ * in Release<primitive type>ArrayElements functions
+ */
+#define JNI_ABORT 2
+
+/*
+ * Used as a generic pointer to a function.
+ */
+/**
+ * Structure which describes a generic pointer to a native
+ * function. Used in <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html#wp17734">RegisterNatives</a>
+ * function.
+ */
+typedef struct {
+ char *name;
+ char *signature;
+ void *fnPtr;
+} JNINativeMethod;
+
+/*
+ * JNI Native Method Interface
+ */
+struct JNINativeInterface_;
+struct JNIEnv_External;
+
+#ifdef __cplusplus
+/**
+ * JNI API interface table type for usage in C++
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp16696">specification</a>
+ * for details. */
+typedef JNIEnv_External JNIEnv;
+#else
+/**
+ * JNI API interface table type for usage in C
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/design.html#wp16696">specification</a>
+ * for details. */
+typedef const struct JNINativeInterface_ *JNIEnv;
+#endif
+
+/*
+ * JNI Invocation Interface
+ */
+struct JNIInvokeInterface_;
+struct JavaVM_External;
+
+#ifdef __cplusplus
+/**
+ * Java VM interface table type for usage in C++
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/invocation.html#invocation_api_functions">specification</a>
+ * for details
+ */
+typedef JavaVM_External JavaVM;
+#else
+/**
+ * Java VM interface table type for usage in C
+ *
+ * See <a
+ * href="http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/invocation.html#invocation_api_functions">specification</a>
+ * for details
+ */
+typedef const struct JNIInvokeInterface_ *JavaVM;
+#endif
+
+#endif /* _JNI_TYPES_H_ */
diff --git a/src/main/cpp/bootstrap/jvmlauncher.cpp b/src/main/cpp/bootstrap/jvmlauncher.cpp
new file mode 100644
index 0000000..74bf1cc
--- /dev/null
+++ b/src/main/cpp/bootstrap/jvmlauncher.cpp
@@ -0,0 +1,454 @@
+/*
+ * 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.
+ */
+ /*
+ * Author: Tomas Holy
+ */
+
+#include "jvmlauncher.h"
+#include <assert.h>
+
+using namespace std;
+
+const char *JvmLauncher::JDK_KEY = "Software\\JavaSoft\\Java Development Kit";
+const char *JvmLauncher::JRE_KEY = "Software\\JavaSoft\\Java Runtime Environment";
+const char *JvmLauncher::JDK_POST9_KEY = "Software\\JavaSoft\\JDK";
+const char *JvmLauncher::JRE_POST9_KEY = "Software\\JavaSoft\\JRE";
+const char *JvmLauncher::CUR_VERSION_NAME = "CurrentVersion";
+const char *JvmLauncher::JAVA_HOME_NAME = "JavaHome";
+const char *JvmLauncher::JAVA_BIN_DIR = "\\bin";
+const char *JvmLauncher::JAVA_EXE_FILE = "\\bin\\java.exe";
+const char *JvmLauncher::JAVAW_EXE_FILE = "\\bin\\javaw.exe";
+const char *JvmLauncher::JAVA_CLIENT_DLL_FILE = "\\bin\\client\\jvm.dll";
+const char *JvmLauncher::JAVA_SERVER_DLL_FILE = "\\bin\\server\\jvm.dll";
+const char *JvmLauncher::JAVA_JRE_PREFIX = "\\jre";
+const char *JvmLauncher::JNI_CREATEVM_FUNC = "JNI_CreateJavaVM";
+
+extern void exitHook(int status);
+
+JvmLauncher::JvmLauncher()
+ : suppressConsole(false) {
+}
+
+JvmLauncher::JvmLauncher(const JvmLauncher& orig) {
+}
+
+JvmLauncher::~JvmLauncher() {
+}
+
+bool JvmLauncher::checkJava(const char *path, const char *prefix) {
+ assert(path);
+ assert(prefix);
+ logMsg("checkJava(%s)", path);
+ javaPath = path;
+ if (*javaPath.rbegin() == '\\') {
+ javaPath.erase(javaPath.length() - 1, 1);
+ }
+ javaExePath = javaPath + prefix + JAVA_EXE_FILE;
+ javawExePath = javaPath + prefix + JAVAW_EXE_FILE;
+ javaClientDllPath = javaPath + prefix + JAVA_CLIENT_DLL_FILE;
+ javaServerDllPath = javaPath + prefix + JAVA_SERVER_DLL_FILE;
+ if (!fileExists(javaClientDllPath.c_str())) {
+ javaClientDllPath = "";
+ }
+ if (!fileExists(javaServerDllPath.c_str())) {
+ javaServerDllPath = "";
+ }
+ javaBinPath = javaPath + prefix + JAVA_BIN_DIR;
+ if (fileExists(javaExePath.c_str()) || !javaClientDllPath.empty() || !javaServerDllPath.empty()) {
+ if (!fileExists(javawExePath.c_str())) {
+ logMsg("javaw.exe not exists, forcing java.exe");
+ javawExePath = javaExePath;
+ }
+ return true;
+ }
+
+ javaPath.clear();
+ javaBinPath.clear();
+ javaExePath.clear();
+ javawExePath.clear();
+ javaClientDllPath.clear();
+ javaServerDllPath.clear();
+ return false;
+}
+
+bool JvmLauncher::initialize(const char *javaPathOrMinVersion) {
+ logMsg("JvmLauncher::initialize()\n\tjavaPathOrMinVersion: %s", javaPathOrMinVersion);
+ assert(javaPathOrMinVersion);
+ if (isVersionString(javaPathOrMinVersion)) {
+ return findJava(javaPathOrMinVersion);
+ } else {
+ return (checkJava(javaPathOrMinVersion, JAVA_JRE_PREFIX) || checkJava(javaPathOrMinVersion, ""));
+ }
+}
+
+bool JvmLauncher::getJavaPath(string &path) {
+ logMsg("JvmLauncher::getJavaPath()");
+ path = javaPath;
+ return !javaPath.empty();
+}
+
+bool JvmLauncher::start(const char *mainClassName, const list<string> &args, const list<string> &options, bool &separateProcess, DWORD *retCode) {
+ assert(mainClassName);
+ logMsg("JvmLauncher::start()\n\tmainClassName: %s\n\tseparateProcess: %s",
+ mainClassName, separateProcess ? "true" : "false");
+ logMsg(" args:");
+ for (list<string>::const_iterator it = args.begin(); it != args.end(); ++it) {
+ logMsg("\t%s", it->c_str());
+ }
+ logMsg(" options:");
+ for (list<string>::const_iterator it = options.begin(); it != options.end(); ++it) {
+ logMsg("\t%s", it->c_str());
+ }
+
+ if (!javaExePath.empty() && javaClientDllPath.empty() && javaServerDllPath.empty()) {
+ logMsg("Found only java.exe at %s. No DLLs. Falling back to java.exe\n", javaExePath.c_str());
+ separateProcess = true;
+ } else {
+ if (javaExePath.empty() || (javaClientDllPath.empty() && javaServerDllPath.empty())) {
+ if (!initialize("")) {
+ return false;
+ }
+ }
+ }
+
+ if (!separateProcess) {
+ // both client/server found, check option which should be used
+ if (!javaClientDllPath.empty() && !javaServerDllPath.empty()) {
+ javaDllPath = findClientOption(options) ? javaClientDllPath : javaServerDllPath;
+ } else {
+ javaDllPath = javaClientDllPath.empty() ? javaServerDllPath : javaClientDllPath;
+ }
+
+ // it is necessary to absolutize dll path because current dir has to be
+ // temporarily changed for dll loading
+ char absoluteJavaDllPath[MAX_PATH] = "";
+ strncpy(absoluteJavaDllPath, javaDllPath.c_str(), MAX_PATH);
+ normalizePath(absoluteJavaDllPath, MAX_PATH);
+ javaDllPath = absoluteJavaDllPath;
+
+ logMsg("Java DLL path: %s", javaDllPath.c_str());
+ if (!canLoadJavaDll()) {
+ logMsg("Falling back to running Java in a separate process; DLL cannot be loaded (64-bit DLL?).");
+ separateProcess = true;
+ }
+ }
+
+ return separateProcess ? startOutProcJvm(mainClassName, args, options, retCode)
+ : startInProcJvm(mainClassName, args, options);
+}
+
+bool JvmLauncher::findClientOption(const list<string> &options) {
+ for (list<string>::const_iterator it = options.begin(); it != options.end(); ++it) {
+ if (*it == "-client") {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool JvmLauncher::canLoadJavaDll() {
+ // be prepared for stupid placement of msvcr71.dll in java installation
+ // (in java 1.6/1.7 jvm.dll is dynamically linked to msvcr71.dll which si placed
+ // in bin directory)
+ PrepareDllPath prepare(javaBinPath.c_str());
+ HMODULE hDll = LoadLibrary(javaDllPath.c_str());
+ if (hDll) {
+ FreeLibrary(hDll);
+ return true;
+ }
+ logErr(true, false, "Cannot load %s.", javaDllPath.c_str());
+ return false;
+}
+
+bool JvmLauncher::isVersionString(const char *str) {
+ char *end = 0;
+ strtod(str, &end);
+ return *end == '\0';
+}
+
+bool JvmLauncher::startInProcJvm(const char *mainClassName, const std::list<std::string> &args, const std::list<std::string> &options) {
+ class Jvm {
+ public:
+
+ Jvm(JvmLauncher *jvmLauncher)
+ : hDll(0)
+ , hSplash(0)
+ , jvm(0)
+ , env(0)
+ , jvmOptions(0)
+ , jvmLauncher(jvmLauncher)
+ {
+ }
+
+ ~Jvm() {
+ if (env && env->ExceptionOccurred()) {
+ env->ExceptionDescribe();
+ }
+
+ if (jvm) {
+ logMsg("Destroying JVM");
+ jvm->DestroyJavaVM();
+ }
+
+ if (jvmOptions) {
+ delete[] jvmOptions;
+ }
+
+ if (hDll) {
+ FreeLibrary(hDll);
+ }
+ if (hSplash) {
+ FreeLibrary(hSplash);
+ }
+ }
+
+ bool init(const list<string> &options) {
+ logMsg("JvmLauncher::Jvm::init()");
+ logMsg("LoadLibrary(\"%s\")", jvmLauncher->javaDllPath.c_str());
+ {
+ PrepareDllPath prepare(jvmLauncher->javaBinPath.c_str());
+ hDll = LoadLibrary(jvmLauncher->javaDllPath.c_str());
+ if (!hDll) {
+ logErr(true, true, "Cannot load %s.", jvmLauncher->javaDllPath.c_str());
+ return false;
+ }
+
+ string pref = jvmLauncher->javaBinPath;
+ pref += "\\splashscreen.dll";
+ const string splash = pref;
+ logMsg("Trying to load %s", splash.c_str());
+ hSplash = LoadLibrary(splash.c_str());
+ logMsg("Splash loaded as %d", hSplash);
+ }
+
+ CreateJavaVM createJavaVM = (CreateJavaVM) GetProcAddress(hDll, JNI_CREATEVM_FUNC);
+ if (!createJavaVM) {
+ logErr(true, true, "GetProcAddress for %s failed.", JNI_CREATEVM_FUNC);
+ return false;
+ }
+
+ logMsg("JVM options:");
+ jvmOptions = new JavaVMOption[options.size() + 1];
+ int i = 0;
+ for (list<string>::const_iterator it = options.begin(); it != options.end(); ++it, ++i) {
+ const string &option = *it;
+ logMsg("\t%s", option.c_str());
+ if (option.find("-splash:") == 0 && hSplash > 0) {
+ const string splash = option.substr(8);
+ logMsg("splash at %s", splash.c_str());
+
+ SplashInit splashInit = (SplashInit)GetProcAddress(hSplash, "SplashInit");
+ SplashLoadFile splashLoadFile = (SplashLoadFile)GetProcAddress(hSplash, "SplashLoadFile");
+
+ logMsg("splash init %d and load %d", splashInit, splashLoadFile);
+ if (splashInit && splashLoadFile) {
+ splashInit();
+ splashLoadFile(splash.c_str());
+ }
+ }
+ jvmOptions[i].optionString = (char *) option.c_str();
+ jvmOptions[i].extraInfo = 0;
+ }
+ JavaVMInitArgs jvmArgs;
+ jvmOptions[options.size()].optionString = (char *) "exit";
+ jvmOptions[options.size()].extraInfo = (void *) &exitHook;
+
+ jvmArgs.options = jvmOptions;
+ jvmArgs.nOptions = options.size() + 1;
+ jvmArgs.version = JNI_VERSION_1_4;
+ jvmArgs.ignoreUnrecognized = JNI_TRUE;
+
+ logMsg("Creating JVM...");
+ if (createJavaVM(&jvm, &env, &jvmArgs) < 0) {
+ logErr(false, true, "JVM creation failed");
+ return false;
+ }
+ logMsg("JVM created.");
+ return true;
+ }
+ typedef jint (CALLBACK *CreateJavaVM)(JavaVM **jvm, JNIEnv **env, void *args);
+ typedef void (CALLBACK *SplashInit)();
+ typedef int (CALLBACK *SplashLoadFile)(const char* file);
+
+ HMODULE hDll;
+ HMODULE hSplash;
+ JavaVM *jvm;
+ JNIEnv *env;
+ JavaVMOption *jvmOptions;
+ JvmLauncher *jvmLauncher;
+ };
+
+ Jvm jvm(this);
+ if (!jvm.init(options)) {
+ return false;
+ }
+
+ jclass mainClass = jvm.env->FindClass(mainClassName);
+ if (!mainClass) {
+ logErr(false, true, "Cannot find class %s.", mainClassName);
+ return false;
+ }
+
+ jmethodID mainMethod = jvm.env->GetStaticMethodID(mainClass, "main", "([Ljava/lang/String;)V");
+ if (!mainMethod) {
+ logErr(false, true, "Cannot get main method.");
+ return false;
+ }
+
+ jclass jclassString = jvm.env->FindClass("java/lang/String");
+ if (!jclassString) {
+ logErr(false, true, "Cannot find java/lang/String class");
+ return false;
+ }
+
+ jstring jstringArg = jvm.env->NewStringUTF("");
+ if (!jstringArg) {
+ logErr(false, true, "NewStringUTF() failed");
+ return false;
+ }
+
+ jobjectArray mainArgs = jvm.env->NewObjectArray(args.size(), jclassString, jstringArg);
+ if (!mainArgs) {
+ logErr(false, true, "NewObjectArray() failed");
+ return false;
+ }
+ int i = 0;
+ for (list<string>::const_iterator it = args.begin(); it != args.end(); ++it, ++i) {
+ const string &arg = *it;
+ const int len = 32*1024;
+ char utf8[len] = "";
+ if (convertAnsiToUtf8(arg.c_str(), utf8, len))
+ logMsg("Conversion to UTF8 failed");
+ jstring jstringArg = jvm.env->NewStringUTF(utf8);
+ if (!jstringArg) {
+ logErr(false, true, "NewStringUTF() failed");
+ return false;
+ }
+ jvm.env->SetObjectArrayElement(mainArgs, i, jstringArg);
+ }
+
+ jvm.env->CallStaticVoidMethod(mainClass, mainMethod, mainArgs);
+ return true;
+}
+
+
+bool JvmLauncher::startOutProcJvm(const char *mainClassName, const std::list<std::string> &args, const std::list<std::string> &options, DWORD *retCode) {
+ string cmdLine = '\"' + (suppressConsole ? javawExePath : javaExePath) + '\"';
+ cmdLine.reserve(32*1024);
+ for (list<string>::const_iterator it = options.begin(); it != options.end(); ++it) {
+ cmdLine += " \"";
+ cmdLine += *it;
+ cmdLine += "\"";
+ }
+
+ // mainClass and args
+ cmdLine += ' ';
+ cmdLine += mainClassName;
+ for (list<string>::const_iterator it = args.begin(); it != args.end(); ++it) {
+ if (javaClientDllPath.empty() && *it == "-client") {
+ logMsg("Removing -client option, client java dll not found.");
+ // remove client parameter, no client java found
+ continue;
+ }
+ cmdLine += " \"";
+ cmdLine += *it;
+ cmdLine += "\"";
+ }
+
+ logMsg("Command line:\n%s", cmdLine.c_str());
+ if (cmdLine.size() >= 32*1024) {
+ logErr(false, true, "Command line is too long. Length: %u. Maximum length: %u.", cmdLine.c_str(), 32*1024);
+ return false;
+ }
+
+ STARTUPINFO si = {0};
+ si.cb = sizeof (STARTUPINFO);
+ PROCESS_INFORMATION pi = {0};
+
+ char cmdLineStr[32*1024] = "";
+ strcpy(cmdLineStr, cmdLine.c_str());
+ if (!CreateProcess(NULL, cmdLineStr, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) {
+ logErr(true, true, "Failed to create process");
+ return false;
+ }
+
+ disableFolderVirtualization(pi.hProcess);
+ ResumeThread(pi.hThread);
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ if (retCode) {
+ GetExitCodeProcess(pi.hProcess, retCode);
+ }
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ return true;
+}
+
+bool JvmLauncher::findJava(const char *minJavaVersion) {
+ // scan for registry for jdk/jre version 9
+ if (findJava(JDK_POST9_KEY, "", minJavaVersion)) {
+ return true;
+ }
+ if (findJava(JRE_POST9_KEY, "", minJavaVersion)) {
+ return true;
+ }
+ if (findJava(JDK_KEY, JAVA_JRE_PREFIX, minJavaVersion)) {
+ return true;
+ }
+ if (findJava(JRE_KEY, "", minJavaVersion)) {
+ return true;
+ }
+ javaPath = "";
+ javaExePath = "";
+ javaClientDllPath = "";
+ javaServerDllPath = "";
+ javaBinPath = "";
+ return false;
+}
+
+bool JvmLauncher::findJava(const char *javaKey, const char *prefix, const char *minJavaVersion) {
+ logMsg("JvmLauncher::findJava()\n\tjavaKey: %s\n\tprefix: %s\n\tminJavaVersion: %s", javaKey, prefix, minJavaVersion);
+ string value;
+ bool result = false;
+ if (getStringFromRegistry(HKEY_LOCAL_MACHINE, javaKey, CUR_VERSION_NAME, value)) {
+ if (value >= minJavaVersion) {
+ string path;
+ if (getStringFromRegistry(HKEY_LOCAL_MACHINE, (string(javaKey) + "\\" + value).c_str(), JAVA_HOME_NAME, path)) {
+ if (*path.rbegin() == '\\') {
+ path.erase(path.length() - 1, 1);
+ }
+ result = checkJava(path.c_str(), prefix);
+ }
+ }
+ }
+ if(!result && isWow64()) {
+ if (getStringFromRegistry64bit(HKEY_LOCAL_MACHINE, javaKey, CUR_VERSION_NAME, value)) {
+ if (value >= minJavaVersion) {
+ string path;
+ if (getStringFromRegistry64bit(HKEY_LOCAL_MACHINE, (string(javaKey) + "\\" + value).c_str(), JAVA_HOME_NAME, path)) {
+ if (*path.rbegin() == '\\') {
+ path.erase(path.length() - 1, 1);
+ }
+ result = checkJava(path.c_str(), prefix);
+ }
+ }
+ }
+ }
+ // probably also need to check 32bit registry when launcher becomes 64-bit but is not the case now.
+ return result;
+}
diff --git a/src/main/cpp/bootstrap/jvmlauncher.h b/src/main/cpp/bootstrap/jvmlauncher.h
new file mode 100644
index 0000000..01f4e34
--- /dev/null
+++ b/src/main/cpp/bootstrap/jvmlauncher.h
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+ /*
+ * Author: Tomas Holy
+ */
+
+#ifndef _JVMLAUNCHER_H
+#define _JVMLAUNCHER_H
+
+#include <windows.h>
+#include <string>
+#include <list>
+#include "jni.h"
+#include "utilsfuncs.h"
+
+class JvmLauncher {
+ static const int MAX_ARGS_LEN = 32*1024;
+
+ static const char *JDK_KEY;
+ static const char *JRE_KEY;
+ // registry key change starting with version 9
+ static const char *JDK_POST9_KEY;
+ static const char *JRE_POST9_KEY;
+ static const char *CUR_VERSION_NAME;
+ static const char *JAVA_HOME_NAME;
+ static const char *JAVA_BIN_DIR;
+ static const char *JAVA_EXE_FILE;
+ static const char *JAVAW_EXE_FILE;
+ static const char *JAVA_CLIENT_DLL_FILE;
+ static const char *JAVA_SERVER_DLL_FILE;
+ static const char *JAVA_JRE_PREFIX;
+ static const char *JNI_CREATEVM_FUNC;
+
+public:
+ JvmLauncher();
+ virtual ~JvmLauncher();
+
+ bool initialize(const char *javaPathOrMinVersion);
+ bool getJavaPath(std::string &path);
+ bool start(const char *mainClassName, const std::list<std::string> &args, const std::list<std::string> &options, bool &separateProcess, DWORD *retCode);
+
+ void setSuppressConsole(bool val) {
+ suppressConsole = val;
+ }
+
+private:
+ JvmLauncher(const JvmLauncher& orig);
+
+ bool checkJava(const char *javaPath, const char *prefix);
+ bool findJava(const char *minJavaVersion);
+ bool findJava(const char *javaKey, const char *prefix, const char *minJavaVersion);
+ bool startOutProcJvm(const char *mainClassName, const std::list<std::string> &args, const std::list<std::string> &options, DWORD *retCode);
+ bool startInProcJvm(const char *mainClassName, const std::list<std::string> &args, const std::list<std::string> &options);
+ bool isVersionString(const char *str);
+ bool canLoadJavaDll();
+ bool findClientOption(const std::list<std::string> &options);
+
+private:
+ bool suppressConsole;
+ std::string javaExePath;
+ std::string javawExePath;
+ std::string javaDllPath;
+ std::string javaClientDllPath;
+ std::string javaServerDllPath;
+ std::string javaPath;
+ std::string javaBinPath;
+
+ class PrepareDllPath {
+ public:
+ PrepareDllPath(const char *dllDirectory)
+ : setDllDirectory(0) {
+ logMsg("PrepareDllPath: %s", dllDirectory);
+ oldCurDir[0] = '\0';
+
+ // SetDllDirectory is present since XP SP1, so we have to load it dynamically
+ HINSTANCE hKernel32 = GetModuleHandle("kernel32");
+ if (!hKernel32) {
+ logErr(true, false, "Cannot load kernel32.");
+ return;
+ }
+
+ LPFNSDD setDllDirectory = (LPFNSDD)GetProcAddress(hKernel32, "SetDllDirectoryA");
+ if (setDllDirectory) {
+ setDllDirectory(dllDirectory);
+ } else {
+ logErr(true, false, "Cannot find SetDllDirectoryA");
+ }
+ GetCurrentDirectory(MAX_PATH, oldCurDir);
+ SetCurrentDirectory(dllDirectory);
+ }
+ ~PrepareDllPath() {
+ if (setDllDirectory) {
+ setDllDirectory(NULL);
+ }
+ if (oldCurDir[0]) {
+ SetCurrentDirectory(oldCurDir);
+ }
+ }
+ private:
+ typedef BOOL (WINAPI *LPFNSDD)(LPCTSTR lpPathname);
+ LPFNSDD setDllDirectory;
+ char oldCurDir[MAX_PATH];
+ };
+};
+
+#endif /* _JVMLAUNCHER_H */
+
diff --git a/src/main/cpp/bootstrap/nbexec.cpp b/src/main/cpp/bootstrap/nbexec.cpp
new file mode 100644
index 0000000..47e490e
--- /dev/null
+++ b/src/main/cpp/bootstrap/nbexec.cpp
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+ /*
+ * Author: Tomas Holy
+ */
+
+#include "platformlauncher.h"
+#include "utilsfuncs.h"
+
+PlatformLauncher launcher;
+
+extern "C" BOOL APIENTRY DllMain(HANDLE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+ ) {
+ switch (ul_reason_for_call) {
+ case DLL_PROCESS_ATTACH:
+ break;
+ case DLL_THREAD_ATTACH:
+ break;
+ case DLL_THREAD_DETACH:
+ break;
+ case DLL_PROCESS_DETACH:
+ launcher.onExit();
+ break;
+ }
+ return TRUE;
+}
+
+volatile int exitStatus = 0;
+
+void exitHook(int status) {
+ exitStatus = status;
+ logMsg("Exit hook called with status %d", status);
+ // do not handle possible restarts, if we are just CLI-connecting to a running process.
+ if (status != -252) {
+ launcher.onExit();
+ }
+ logMsg("Exit hook terminated.");
+}
+
+#define NBEXEC_EXPORT extern "C" __declspec(dllexport)
+
+NBEXEC_EXPORT int startPlatform(int argc, char *argv[], const char *helpMsg) {
+ DWORD retCode = 0;
+ launcher.appendToHelp(helpMsg);
+ launcher.setSuppressConsole(!isConsoleAttached());
+ if (!launcher.start(argv, argc, &retCode)) {
+ return -1;
+ }
+ return retCode;
+}
+
+
diff --git a/src/main/cpp/bootstrap/nbexec.exe.manifest b/src/main/cpp/bootstrap/nbexec.exe.manifest
new file mode 100644
index 0000000..cfc9190
--- /dev/null
+++ b/src/main/cpp/bootstrap/nbexec.exe.manifest
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+
+ 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.
+
+-->
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity version="9.0.0.0"
+ processorArchitecture="X86"
+ name="nbexec.exe"
+ type="win32"/>
+
+<description>nbexec process</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="*"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+<!-- Identify the application security requirements. -->
+<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel
+ level="asInvoker"
+ uiAccess="false"/>
+ </requestedPrivileges>
+ </security>
+</trustInfo>
+<!-- NETBEANS-1227: Indicate the same HiDPI capabilities as javaw.exe from JDK 11. -->
+<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
+ <asmv3:windowsSettings xmlns:dpi1="http://schemas.microsoft.com/SMI/2005/WindowsSettings" xmlns:dpi2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
+ <dpi1:dpiAware>true/PM</dpi1:dpiAware>
+ <dpi2:dpiAwareness>PerMonitorV2, PerMonitor, system</dpi2:dpiAwareness>
+ </asmv3:windowsSettings>
+</asmv3:application>
+<!-- List of explicitly supported Windows versions. This is the list from
+ javaw.exe on JDK 8.0.172, which is the same as that of JDK 11ea. -->
+<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+ </application>
+</compatibility>
+</assembly>
diff --git a/src/main/cpp/bootstrap/nbexec.rc b/src/main/cpp/bootstrap/nbexec.rc
new file mode 100644
index 0000000..b0843af
--- /dev/null
+++ b/src/main/cpp/bootstrap/nbexec.rc
@@ -0,0 +1,26 @@
+/*
+ * 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 <winuser.h>
+
+#define FNAME "nbexec.dll"
+#define FILETYPE_ID 0x2L
+
+#include "version.rc"
+
diff --git a/src/main/cpp/bootstrap/nbexec_exe.rc b/src/main/cpp/bootstrap/nbexec_exe.rc
new file mode 100644
index 0000000..df75c0b
--- /dev/null
+++ b/src/main/cpp/bootstrap/nbexec_exe.rc
@@ -0,0 +1,29 @@
+/*
+ * 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 <winuser.h>
+
+#define FNAME "nbexec.exe"
+#define FILETYPE_ID 0x1L
+
+#include "version.rc"
+
+// Value MANIFEST_FILE id taken from windres parameter -DMANIFEST_FILE
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST MANIFEST_FILE
+
diff --git a/src/main/cpp/bootstrap/nbexecexe.cpp b/src/main/cpp/bootstrap/nbexecexe.cpp
new file mode 100644
index 0000000..181a365
--- /dev/null
+++ b/src/main/cpp/bootstrap/nbexecexe.cpp
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+ /*
+ * Author: Tomas Holy
+ */
+
+#include <windows.h>
+#include "nbexecloader.h"
+
+int main(int argc, char *argv[]) {
+ checkLoggingArg(argc, argv, true);
+ NBExecLoader loader;
+
+ // NBEXEC_DLL specified in preprocessor definitions
+ return loader.start(NBEXEC_DLL, argc - 1, argv + 1);
+}
diff --git a/src/main/cpp/bootstrap/nbexecloader.h b/src/main/cpp/bootstrap/nbexecloader.h
new file mode 100644
index 0000000..221a557
--- /dev/null
+++ b/src/main/cpp/bootstrap/nbexecloader.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+#ifndef _NBEXECLOADER_H
+#define _NBEXECLOADER_H
+
+#include "utilsfuncs.h"
+
+#define HELP_MSG \
+"\
+ --console suppress supppress console output\n\
+ --console new open new console for output\n\
+\n"
+
+class NBExecLoader {
+ typedef int (*StartPlatform)(int argc, char *argv[], const char *help);
+
+public:
+ NBExecLoader()
+ : hLib(0) {
+ }
+ ~NBExecLoader() {
+ if (hLib) {
+ FreeLibrary(hLib);
+ }
+ }
+ int start(const char *path, int argc, char *argv[]) {
+ if (!hLib) {
+ hLib = LoadLibrary(path);
+ if (!hLib) {
+ logErr(true, true, "Cannot load \"%s\".", path);
+ return -1;
+ }
+ }
+
+ StartPlatform startPlatform = (StartPlatform) GetProcAddress(hLib, "startPlatform");
+ if (!startPlatform) {
+ logErr(true, true, "Cannot start platform, failed to find startPlatform() in %s", path);
+ return -1;
+ }
+ logMsg("Starting platform...\n");
+ return startPlatform(argc, argv, HELP_MSG);
+ }
+
+private:
+ HMODULE hLib;
+};
+
+#endif /* _NBEXECLOADER_H */
+
diff --git a/src/main/cpp/bootstrap/nbproject/configurations.xml b/src/main/cpp/bootstrap/nbproject/configurations.xml
new file mode 100644
index 0000000..0121be8
--- /dev/null
+++ b/src/main/cpp/bootstrap/nbproject/configurations.xml
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<configurationDescriptor version="100">
+ <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
+ <logicalFolder name="HeaderFiles"
+ displayName="Header Files"
+ projectFiles="true">
+ <itemPath>argnames.h</itemPath>
+ <itemPath>jvmlauncher.h</itemPath>
+ <itemPath>platformlauncher.h</itemPath>
+ <itemPath>utilsfuncs.h</itemPath>
+ <itemPath>version.h</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ResourceFiles"
+ displayName="Resource Files"
+ projectFiles="true">
+ <itemPath>nbexec.exe.manifest</itemPath>
+ <itemPath>nbexec.rc</itemPath>
+ <itemPath>nbexec_exe.rc</itemPath>
+ <itemPath>version.rc</itemPath>
+ </logicalFolder>
+ <logicalFolder name="SourceFiles"
+ displayName="Source Files"
+ projectFiles="true">
+ <itemPath>jvmlauncher.cpp</itemPath>
+ <itemPath>nbexec.cpp</itemPath>
+ <itemPath>nbexecexe.cpp</itemPath>
+ <itemPath>nbexecloader.h</itemPath>
+ <itemPath>platformlauncher.cpp</itemPath>
+ <itemPath>utilsfuncs.cpp</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ </logicalFolder>
+ <projectmakefile>Makefile</projectmakefile>
+ <confs>
+ <conf name="nbexec" type="2">
+ <toolsSet>
+ <compilerSet>Cygwin|Cygwin</compilerSet>
+ <dependencyChecking>true</dependencyChecking>
+ <rebuildPropChanged>false</rebuildPropChanged>
+ </toolsSet>
+ <compileType>
+ <cTool>
+ <developmentMode>5</developmentMode>
+ <warningLevel>2</warningLevel>
+ </cTool>
+ <ccTool>
+ <developmentMode>5</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <architecture>1</architecture>
+ <incDir>
+ <pElem>C:/Program Files/Java/jdk1.8.0_77/include</pElem>
+ <pElem>C:/Program Files/Java/jdk1.8.0_77/include/win32</pElem>
+ </incDir>
+ <commandLine>-mno-cygwin</commandLine>
+ <preprocessorList>
+ <Elem>NBEXEC_DLL="nbexec.dll"</Elem>
+ </preprocessorList>
+ </ccTool>
+ <linkerTool>
+ <output>nbexec.dll</output>
+ <additionalDep>${OBJECTDIR}/nbexec.res</additionalDep>
+ <linkerLibItems>
+ <linkerOptionItem>${OBJECTDIR}/nbexec.res</linkerOptionItem>
+ </linkerLibItems>
+ <commandLine>-Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh</commandLine>
+ </linkerTool>
+ </compileType>
+ <item path="argnames.h" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="jvmlauncher.cpp" ex="false" tool="1" flavor2="0">
+ </item>
+ <item path="jvmlauncher.h" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="nbexec.cpp" ex="false" tool="1" flavor2="0">
+ </item>
+ <item path="nbexec.exe.manifest" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="nbexec.rc" ex="false" tool="3" flavor2="0">
+ <customTool>
+ <customToolCommandline>windres.exe -Ocoff nbexec.rc ${OBJECTDIR}/nbexec.res</customToolCommandline>
+ <customToolDescription>Compiling Resource files...</customToolDescription>
+ <customToolOutputs>${OBJECTDIR}/nbexec.res</customToolOutputs>
+ <customToolAdditionalDep>version.h</customToolAdditionalDep>
+ </customTool>
+ </item>
+ <item path="nbexec_exe.rc" ex="false" tool="3" flavor2="0">
+ <customTool>
+ <customToolDescription></customToolDescription>
+ </customTool>
+ </item>
+ <item path="nbexecexe.cpp" ex="false" tool="1" flavor2="0">
+ </item>
+ <item path="nbexecloader.h" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="platformlauncher.cpp" ex="false" tool="1" flavor2="0">
+ </item>
+ <item path="platformlauncher.h" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="utilsfuncs.cpp" ex="false" tool="1" flavor2="0">
+ </item>
+ <item path="utilsfuncs.h" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="version.h" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="version.rc" ex="false" tool="3" flavor2="0">
+ </item>
+ </conf>
+ <conf name="nbexec64" type="2">
+ <toolsSet>
+ <compilerSet>Cygwin64|Cygwin</compilerSet>
+ <dependencyChecking>true</dependencyChecking>
+ <rebuildPropChanged>false</rebuildPropChanged>
+ </toolsSet>
+ <compileType>
+ <cTool>
+ <developmentMode>5</developmentMode>
+ </cTool>
+ <ccTool>
+ <developmentMode>5</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <architecture>2</architecture>
+ <incDir>
+ <pElem>C:/Program Files/Java/jdk1.8.0_77/include</pElem>
+ <pElem>C:/Program Files/Java/jdk1.8.0_77/include/win32</pElem>
+ </incDir>
+ <commandLine>-mno-cygwin -static-libgcc -static-libstdc++</commandLine>
+ <preprocessorList>
+ <Elem>NBEXEC_DLL="nbexec64.dll"</Elem>
+ </preprocessorList>
+ </ccTool>
+ <linkerTool>
+ <output>nbexec64.dll</output>
+ <additionalDep>${OBJECTDIR}/nbexec64.res</additionalDep>
+ <linkerLibItems>
+ <linkerOptionItem>${OBJECTDIR}/nbexec64.res</linkerOptionItem>
+ </linkerLibItems>
+ <commandLine>-Wl,--nxcompat -Wl,--dynamicbase</commandLine>
+ </linkerTool>
+ </compileType>
+ <item path="argnames.h" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="jvmlauncher.cpp" ex="false" tool="1" flavor2="0">
+ </item>
+ <item path="jvmlauncher.h" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="nbexec.cpp" ex="false" tool="1" flavor2="0">
+ </item>
+ <item path="nbexec.exe.manifest" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="nbexec.rc" ex="false" tool="3" flavor2="0">
+ <customTool>
+ <customToolCommandline>x86_64-w64-mingw32-windres.exe -Ocoff nbexec.rc ${OBJECTDIR}/nbexec64.res</customToolCommandline>
+ <customToolDescription>Compiling Resource files...</customToolDescription>
+ <customToolOutputs>${OBJECTDIR}/nbexec64.res</customToolOutputs>
+ <customToolAdditionalDep>version.h</customToolAdditionalDep>
+ </customTool>
+ </item>
+ <item path="nbexec_exe.rc" ex="false" tool="3" flavor2="0">
+ <customTool>
+ <customToolDescription></customToolDescription>
+ </customTool>
+ </item>
+ <item path="nbexecexe.cpp" ex="false" tool="1" flavor2="0">
+ </item>
+ <item path="nbexecloader.h" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="platformlauncher.cpp" ex="false" tool="1" flavor2="0">
+ </item>
+ <item path="platformlauncher.h" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="utilsfuncs.cpp" ex="false" tool="1" flavor2="0">
+ </item>
+ <item path="utilsfuncs.h" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="version.h" ex="false" tool="3" flavor2="0">
+ </item>
+ <item path="version.rc" ex="false" tool="3" flavor2="0">
+ </item>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/src/main/cpp/bootstrap/nbproject/project.properties b/src/main/cpp/bootstrap/nbproject/project.properties
new file mode 100644
index 0000000..2456923
--- /dev/null
+++ b/src/main/cpp/bootstrap/nbproject/project.properties
@@ -0,0 +1,17 @@
+# 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.
+
diff --git a/src/main/cpp/bootstrap/nbproject/project.xml b/src/main/cpp/bootstrap/nbproject/project.xml
new file mode 100644
index 0000000..99f9274
--- /dev/null
+++ b/src/main/cpp/bootstrap/nbproject/project.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.cnd.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>Platform Launcher Win</name>
+ <make-project-type>0</make-project-type>
+ <c-extensions/>
+ <cpp-extensions>cpp</cpp-extensions>
+ <header-extensions>h</header-extensions>
+ <sourceEncoding>UTF-8</sourceEncoding>
+ <make-dep-projects/>
+ <sourceRootList/>
+ <confList>
+ <confElem>
+ <name>nbexec</name>
+ <type>2</type>
+ </confElem>
+ <confElem>
+ <name>nbexec64</name>
+ <type>2</type>
+ </confElem>
+ </confList>
+ <formatting>
+ <project-formatting-style>false</project-formatting-style>
+ </formatting>
+ </data>
+ </configuration>
+</project>
diff --git a/src/main/cpp/bootstrap/platformlauncher.cpp b/src/main/cpp/bootstrap/platformlauncher.cpp
new file mode 100644
index 0000000..8df954c
--- /dev/null
+++ b/src/main/cpp/bootstrap/platformlauncher.cpp
@@ -0,0 +1,731 @@
+/*
+ * 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.
+ */
+ /*
+ * Author: Tomas Holy
+ */
+
+#include "utilsfuncs.h"
+#include "platformlauncher.h"
+#include "argnames.h"
+
+volatile extern int exitStatus;
+
+using namespace std;
+
+const char *PlatformLauncher::HELP_MSG =
+"\nUsage: launcher {options} arguments\n\
+\n\
+General options:\n\
+ --help show this help\n\
+ --jdkhome <path> path to JDK\n\
+ -J<jvm_option> pass <jvm_option> to JVM\n\
+\n\
+ --cp:p <classpath> prepend <classpath> to classpath\n\
+ --cp:a <classpath> append <classpath> to classpath\n\
+\n\
+ --fork-java run java in separate process\n\
+ --trace <path> path for launcher log (for trouble shooting)\n\
+\n";
+
+const char *PlatformLauncher::REQ_JAVA_VERSION = "1.8";
+
+const char *PlatformLauncher::OPT_JDK_HOME = "-Djdk.home=";
+const char *PlatformLauncher::OPT_NB_PLATFORM_HOME = "-Dnetbeans.home=";
+const char *PlatformLauncher::OPT_NB_CLUSTERS = "-Dnetbeans.dirs=";
+const char *PlatformLauncher::OPT_NB_USERDIR = "-Dnetbeans.user=";
+const char *PlatformLauncher::OPT_DEFAULT_USERDIR_ROOT = "-Dnetbeans.default_userdir_root=";
+const char *PlatformLauncher::OPT_HEAP_DUMP = "-XX:+HeapDumpOnOutOfMemoryError";
+const char *PlatformLauncher::OPT_HEAP_DUMP_PATH = "-XX:HeapDumpPath=";
+const char *PlatformLauncher::OPT_KEEP_WORKING_SET_ON_MINIMIZE = "-Dsun.awt.keepWorkingSetOnMinimize=true";
+const char *PlatformLauncher::OPT_CLASS_PATH = "-Djava.class.path=";
+const char *PlatformLauncher::OPT_SPLASH = "-splash:";
+const char *PlatformLauncher::OPT_SPLASH_PATH = "\\var\\cache\\splash.png";
+
+const char *PlatformLauncher::HEAP_DUMP_PATH = "\\var\\log\\heapdump.hprof";
+const char *PlatformLauncher::RESTART_FILE_PATH = "\\var\\restart";
+
+const char *PlatformLauncher::UPDATER_MAIN_CLASS = "org/netbeans/updater/UpdaterFrame";
+const char *PlatformLauncher::IDE_MAIN_CLASS = "org/netbeans/Main";
+
+PlatformLauncher::PlatformLauncher()
+ : separateProcess(false)
+ , suppressConsole(false)
+ , heapDumpPathOptFound(false)
+ , nosplash(false)
+ , exiting(false) {
+}
+
+PlatformLauncher::PlatformLauncher(const PlatformLauncher& orig) {
+}
+
+PlatformLauncher::~PlatformLauncher() {
+}
+
+bool PlatformLauncher::start(char* argv[], int argc, DWORD *retCode) {
+ if (!checkLoggingArg(argc, argv, false) || !initPlatformDir() || !parseArgs(argc, argv)) {
+ return false;
+ }
+ disableFolderVirtualization(GetCurrentProcess());
+
+ if (jdkhome.empty()) {
+ if (!jvmLauncher.initialize(REQ_JAVA_VERSION)) {
+ logErr(false, true, "Cannot find Java %s or higher.", REQ_JAVA_VERSION);
+ return false;
+ }
+ }
+ jvmLauncher.getJavaPath(jdkhome);
+
+ deleteNewClustersFile();
+ prepareOptions();
+
+ if (nextAction.empty()) {
+ if (shouldAutoUpdateClusters(true)) {
+ // run updater
+ if (!run(true, retCode)) {
+ return false;
+ }
+ }
+
+ while (true) {
+ // run app
+ if (!run(false, retCode)) {
+ return false;
+ }
+
+ if (shouldAutoUpdateClusters(false)) {
+ // run updater
+ if (!run(true, retCode)) {
+ return false;
+ }
+ } else if (!restartRequested()) {
+ break;
+ }
+ }
+ } else {
+ if (nextAction == ARG_NAME_LA_START_APP) {
+ return run(false, retCode);
+ } else if (nextAction == ARG_NAME_LA_START_AU) {
+ if (shouldAutoUpdateClusters(false)) {
+ return run(true, retCode);
+ }
+ } else {
+ logErr(false, true, "We should not get here.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool PlatformLauncher::run(bool updater, DWORD *retCode) {
+ logMsg(updater ? "Starting updater..." : "Starting application...");
+ constructClassPath(updater);
+ const char *mainClass;
+ if (updater) {
+ mainClass = UPDATER_MAIN_CLASS;
+ nextAction = ARG_NAME_LA_START_APP;
+ } else {
+ DeleteFile((userDir + RESTART_FILE_PATH).c_str());
+ mainClass = bootclass.empty() ? IDE_MAIN_CLASS : bootclass.c_str();
+ nextAction = ARG_NAME_LA_START_AU;
+ }
+
+ string option = OPT_NB_CLUSTERS;
+ option += auClusters.empty() ? clusters : auClusters;
+ javaOptions.push_back(option);
+
+ option = OPT_CLASS_PATH;
+ option += classPath;
+ javaOptions.push_back(option);
+
+ jvmLauncher.setSuppressConsole(suppressConsole);
+ bool rc = jvmLauncher.start(mainClass, progArgs, javaOptions, separateProcess, retCode);
+ if (!separateProcess) {
+ exit(0);
+ }
+
+ javaOptions.pop_back();
+ javaOptions.pop_back();
+ return rc;
+}
+
+
+
+bool PlatformLauncher::initPlatformDir() {
+ char path[MAX_PATH] = "";
+ getCurrentModulePath(path, MAX_PATH);
+ logMsg("Module: %s", path);
+ char *bslash = strrchr(path, '\\');
+ if (!bslash) {
+ return false;
+ }
+ *bslash = '\0';
+ bslash = strrchr(path, '\\');
+ if (!bslash) {
+ return false;
+ }
+ *bslash = '\0';
+ clusters = platformDir = path;
+ logMsg("Platform dir: %s", platformDir.c_str());
+ return true;
+}
+
+bool PlatformLauncher::parseArgs(int argc, char *argv[]) {
+#define CHECK_ARG \
+ if (i+1 == argc) {\
+ logErr(false, true, "Argument is missing for \"%s\" option.", argv[i]);\
+ return false;\
+ }
+
+ logMsg("Parsing arguments:");
+ for (int i = 0; i < argc; i++) {
+ logMsg("\t%s", argv[i]);
+ }
+
+ for (int i = 0; i < argc; i++) {
+ if (strcmp(ARG_NAME_SEPAR_PROC, argv[i]) == 0) {
+ separateProcess = true;
+ logMsg("Run Java in separater process");
+ } else if (strcmp(ARG_NAME_LAUNCHER_LOG, argv[i]) == 0) {
+ CHECK_ARG;
+ i++;
+ } else if (strcmp(ARG_NAME_LA_START_APP, argv[i]) == 0
+ || strcmp(ARG_NAME_LA_START_AU, argv[i]) == 0) {
+ nextAction = argv[i];
+ logMsg("Next launcher action: %s", nextAction.c_str());
+ } else if (strcmp(ARG_NAME_LA_PPID, argv[i]) == 0) {
+ CHECK_ARG;
+ suppressConsole = false;
+ parentProcID = argv[++i];
+ logMsg("Parent process ID found: %s", parentProcID.c_str());
+ } else if (strcmp(ARG_NAME_USER_DIR, argv[i]) == 0) {
+ CHECK_ARG;
+ char tmp[MAX_PATH + 1] = {0};
+ strncpy(tmp, argv[++i], MAX_PATH);
+ if (strcmp(tmp, "memory") != 0 && !normalizePath(tmp, MAX_PATH)) {
+ logErr(false, true, "User directory path \"%s\" is not valid.", argv[i]);
+ return false;
+ }
+ userDir = tmp;
+ logMsg("User dir: %s", userDir.c_str());
+ } else if (strcmp(ARG_DEFAULT_USER_DIR_ROOT, argv[i]) == 0) {
+ CHECK_ARG;
+ char tmp[MAX_PATH + 1] = {0};
+ strncpy(tmp, argv[++i], MAX_PATH);
+ if (strcmp(tmp, "memory") != 0 && !normalizePath(tmp, MAX_PATH)) {
+ logErr(false, true, "Default User directory path \"%s\" is not valid.", argv[i]);
+ return false;
+ }
+ defaultUserDirRoot = tmp;
+ logMsg("Default Userdir root: %s", defaultUserDirRoot.c_str());
+ } else if (strcmp(ARG_NAME_CLUSTERS, argv[i]) == 0) {
+ CHECK_ARG;
+ clusters = argv[++i];
+ } else if (strcmp(ARG_NAME_BOOTCLASS, argv[i]) == 0) {
+ CHECK_ARG;
+ bootclass = argv[++i];
+ } else if (strcmp(ARG_NAME_JDKHOME, argv[i]) == 0) {
+ CHECK_ARG;
+ if (jdkhome.empty()) {
+ jdkhome = argv[++i];
+ if (!jvmLauncher.initialize(jdkhome.c_str())) {
+ logMsg("Cannot locate java installation in specified jdkhome: %s", jdkhome.c_str());
+ string errMsg = "Cannot locate java installation in specified jdkhome:\n";
+ errMsg += jdkhome;
+ errMsg += "\nDo you want to try to use default version?";
+ jdkhome = "";
+ if (::MessageBox(NULL, errMsg.c_str(), "Invalid jdkhome specified", MB_ICONQUESTION | MB_YESNO) == IDNO) {
+ return false;
+ }
+ }
+ } else {
+ i++;
+ }
+ } else if (strcmp(ARG_NAME_CP_PREPEND, argv[i]) == 0
+ || strcmp(ARG_NAME_CP_PREPEND + 1, argv[i]) == 0) {
+ CHECK_ARG;
+ cpBefore += argv[++i];
+ } else if (strcmp(ARG_NAME_CP_APPEND, argv[i]) == 0
+ || strcmp(ARG_NAME_CP_APPEND + 1, argv[i]) == 0
+ || strncmp(ARG_NAME_CP_APPEND + 1, argv[i], 3) == 0
+ || strncmp(ARG_NAME_CP_APPEND, argv[i], 4) == 0) {
+ CHECK_ARG;
+ cpAfter += argv[++i];
+ } else if (strncmp("-J", argv[i], 2) == 0) {
+ javaOptions.push_back(argv[i] + 2);
+ if (strncmp(argv[i] + 2, OPT_HEAP_DUMP_PATH, strlen(OPT_HEAP_DUMP_PATH)) == 0) {
+ heapDumpPathOptFound = true;
+ }
+ } else {
+ if (strcmp(argv[i], "-h") == 0
+ || strcmp(argv[i], "-help") == 0
+ || strcmp(argv[i], "--help") == 0
+ || strcmp(argv[i], "/?") == 0) {
+ printToConsole(HELP_MSG);
+ if (!appendHelp.empty()) {
+ printToConsole(appendHelp.c_str());
+ }
+ } else if (strcmp(ARG_NAME_NOSPLASH, argv[i]) == 0) {
+ nosplash = true;
+ }
+ progArgs.push_back(argv[i]);
+ }
+ }
+ return true;
+}
+
+bool PlatformLauncher::processAutoUpdateCL() {
+ logMsg("processAutoUpdateCL()...");
+ if (userDir.empty()) {
+ logMsg("\tuserdir empty, quiting");
+ return false;
+ }
+ string listPath = userDir;
+ listPath += "\\update\\download\\netbeans.dirs";
+
+ WIN32_FIND_DATA fd = {0};
+ HANDLE hFind = 0;
+ hFind = FindFirstFile(listPath.c_str(), &fd);
+ if (hFind == INVALID_HANDLE_VALUE) {
+ logMsg("File \"%s\" does not exist", listPath.c_str());
+ return false;
+ }
+ FindClose(hFind);
+
+ FILE *file = fopen(listPath.c_str(), "r");
+ if (!file) {
+ logErr(true, false, "Cannot open file %s", listPath.c_str());
+ return false;
+ }
+
+ int len = fd.nFileSizeLow + 1;
+ char *str = new char[len];
+ if (!fgets(str, len, file)) {
+ fclose(file);
+ delete[] str;
+ logErr(true, false, "Cannot read from file %s", listPath.c_str());
+ return false;
+ }
+ len = strlen(str) - 1;
+ if (str[len] == '\n') {
+ str[len] = '\0';
+ }
+
+ auClusters = str;
+ fclose(file);
+ delete[] str;
+ return true;
+}
+
+void PlatformLauncher::deleteNewClustersFile() {
+ logMsg("deleteNewClustersFile()...");
+ if (userDir.empty()) {
+ logMsg("\tuserdir empty, quiting");
+ return;
+ }
+ string listPath = userDir;
+ listPath += "\\update\\download\\netbeans.dirs";
+
+ if (fileExists(listPath.c_str())) {
+ DeleteFileA(listPath.c_str());
+ logMsg("%s file deleted.", listPath.c_str());
+ }
+}
+
+// check if new updater exists, if exists install it (replace old one) and remove ...\new_updater directory
+bool PlatformLauncher::checkForNewUpdater(const char *basePath) {
+ logMsg("checkForNewUpdater() at %s", basePath);
+ BOOL removeDir = false;
+ string srcPath = basePath;
+ srcPath += "\\update\\new_updater\\updater.jar";
+ WIN32_FIND_DATA fd = {0};
+ HANDLE hFind = FindFirstFile(srcPath.c_str(), &fd);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ logMsg("New updater found: %s", srcPath.c_str());
+ FindClose(hFind);
+ string destPath = basePath;
+ destPath += "\\modules\\ext\\updater.jar";
+ createPath(destPath.c_str());
+
+ int i = 0;
+ while (true) {
+ if (MoveFileEx(srcPath.c_str(), destPath.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
+ break;
+ }
+ if (exiting || ++i > 10) {
+ logErr(true, false, "Failed to move \"%s\" to \"%s\"", srcPath.c_str(), destPath.c_str());
+ return false;
+ }
+ logErr(true, false, "Failed to move \"%s\" to \"%s\", trying to wait", srcPath.c_str(), destPath.c_str());
+ Sleep(100);
+ }
+ logMsg("New updater successfully moved from \"%s\" to \"%s\"", srcPath.c_str(), destPath.c_str());
+ removeDir = true;
+ } else {
+ logMsg("No new updater at %s", srcPath.c_str());
+ }
+ string locPath = basePath;
+ locPath += "\\update\\new_updater\\updater_*.jar";
+ hFind = FindFirstFile(locPath.c_str(), &fd);
+ while (hFind != INVALID_HANDLE_VALUE) {
+ string destPath = basePath;
+ string name = fd.cFileName;
+ logMsg("New updater localization found: %s", name.c_str());
+ destPath += "\\modules\\ext\\locale\\";
+ destPath += name;
+
+ string fromPath = basePath;
+ fromPath += "\\update\\new_updater\\";
+ fromPath += name;
+
+ createPath(destPath.c_str());
+
+ int i = 0;
+ while (true) {
+ if (MoveFileEx(fromPath.c_str(), destPath.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
+ break;
+ }
+ if (exiting || ++i > 10) {
+ logErr(true, false, "Failed to move \"%s\" to \"%s\"", fromPath.c_str(), destPath.c_str());
+ return false;
+ }
+ logErr(true, false, "Failed to move \"%s\" to \"%s\", trying to wait", fromPath.c_str(), destPath.c_str());
+ Sleep(100);
+ }
+ logMsg("New updater successfully moved from \"%s\" to \"%s\"", fromPath.c_str(), destPath.c_str());
+ removeDir = true;
+
+ if (!FindNextFile(hFind, &fd)) {
+ break;
+ }
+ }
+ FindClose(hFind);
+
+ if (removeDir) {
+ srcPath.erase(srcPath.rfind('\\'));
+ logMsg("Removing directory \"%s\"", srcPath.c_str());
+ if (!RemoveDirectory(srcPath.c_str())) {
+ logErr(true, false, "Failed to remove directory \"%s\"", srcPath.c_str());
+ }
+ }
+ return true;
+}
+
+bool PlatformLauncher::shouldAutoUpdate(bool firstStart, const char *basePath) {
+ // The logic is following:
+ // if there is an NBM for installation then run updater
+ // unless it is not a first start and we asked to install later (on next start)
+
+ // then also check if last run left list of modules to disable/uninstall and
+ // did not mark them to be deactivated later (on next start)
+ string path = basePath;
+ path += "\\update\\download\\*.nbm";
+ logMsg("Checking for updates: %s", path.c_str());
+ WIN32_FIND_DATA fd;
+ HANDLE hFindNbms = FindFirstFile(path.c_str(), &fd);
+ if (hFindNbms != INVALID_HANDLE_VALUE) {
+ logMsg("Some updates found at %s", path.c_str());
+ FindClose(hFindNbms);
+ } else {
+ //also check for OSGi jars if *.nbm not found
+ path = basePath;
+ path += "\\update\\download\\*.jar";
+ hFindNbms = FindFirstFile(path.c_str(), &fd);
+ if (hFindNbms != INVALID_HANDLE_VALUE) {
+ logMsg("Some OSGi updates found at %s", path.c_str());
+ FindClose(hFindNbms);
+ }
+ }
+
+ path = basePath;
+ path += "\\update\\download\\install_later.xml";
+ HANDLE hFind = FindFirstFile(path.c_str(), &fd);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ logMsg("install_later.xml found: %s", path.c_str());
+ FindClose(hFind);
+ }
+
+ if (hFindNbms != INVALID_HANDLE_VALUE && (firstStart || hFind == INVALID_HANDLE_VALUE)) {
+ return true;
+ }
+
+ path = basePath;
+ path += "\\update\\deactivate\\deactivate_later.txt";
+ hFind = FindFirstFile(path.c_str(), &fd);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ logMsg("deactivate_later.txt found: %s", path.c_str());
+ FindClose(hFind);
+ }
+
+ if (firstStart || hFind == INVALID_HANDLE_VALUE) {
+ path = basePath;
+ path += "\\update\\deactivate\\to_disable.txt";
+ hFind = FindFirstFile(path.c_str(), &fd);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ logMsg("to_disable.txt found: %s", path.c_str());
+ FindClose(hFind);
+ return true;
+ }
+
+ path = basePath;
+ path += "\\update\\deactivate\\to_uninstall.txt";
+ hFind = FindFirstFile(path.c_str(), &fd);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ logMsg("to_uninstall.txt found: %s", path.c_str());
+ FindClose(hFind);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool PlatformLauncher::shouldAutoUpdateClusters(bool firstStart) {
+ bool runUpdater = false;
+ string cl = processAutoUpdateCL() ? auClusters : clusters;
+ checkForNewUpdater(platformDir.c_str());
+ runUpdater = shouldAutoUpdate(firstStart, platformDir.c_str());
+
+ const char delim = ';';
+ string::size_type start = cl.find_first_not_of(delim, 0);
+ string::size_type end = cl.find_first_of(delim, start);
+ while (string::npos != end || string::npos != start) {
+ string cluster = cl.substr(start, end - start);
+ checkForNewUpdater(cluster.c_str());
+ if (!runUpdater) {
+ runUpdater = shouldAutoUpdate(firstStart, cluster.c_str());
+ }
+ start = cl.find_first_not_of(delim, end);
+ end = cl.find_first_of(delim, start);
+ }
+
+ checkForNewUpdater(userDir.c_str());
+ if (!runUpdater) {
+ runUpdater = shouldAutoUpdate(firstStart, userDir.c_str());
+ }
+ return runUpdater;
+}
+
+void PlatformLauncher::prepareOptions() {
+ string option = OPT_JDK_HOME;
+ option += jdkhome;
+ javaOptions.push_back(option);
+
+ if (!nosplash) {
+ string splashPath = userDir;
+ splashPath += OPT_SPLASH_PATH;
+ if (fileExists(splashPath.c_str())) {
+ javaOptions.push_back(OPT_SPLASH + splashPath);
+ }
+ }
+
+ option = OPT_NB_PLATFORM_HOME;
+ option += platformDir;
+ javaOptions.push_back(option);
+
+ option = OPT_NB_USERDIR;
+ option += userDir;
+ javaOptions.push_back(option);
+
+ option = OPT_DEFAULT_USERDIR_ROOT;
+ option += defaultUserDirRoot;
+ javaOptions.push_back(option);
+
+ option = OPT_HEAP_DUMP;
+ javaOptions.push_back(option);
+
+ if (!heapDumpPathOptFound) {
+ option = OPT_HEAP_DUMP_PATH;
+ option += userDir;
+ option += HEAP_DUMP_PATH;
+ javaOptions.push_back(option);
+ // rename old heap dump to .old
+ string heapdumpfile = userDir + HEAP_DUMP_PATH;
+ if (fileExists(heapdumpfile.c_str())) {
+ string heapdumpfileold = heapdumpfile + ".old";
+ if (fileExists(heapdumpfileold.c_str())) {
+ DeleteFileA(heapdumpfileold.c_str());
+ }
+ MoveFile (heapdumpfile.c_str(), heapdumpfileold.c_str());
+ }
+ }
+
+ option = OPT_KEEP_WORKING_SET_ON_MINIMIZE;
+ javaOptions.push_back(option);
+}
+
+string & PlatformLauncher::constructClassPath(bool runUpdater) {
+ logMsg("constructClassPath()");
+ addedToCP.clear();
+ classPath = cpBefore;
+
+ addJarsToClassPathFrom(userDir.c_str());
+ addJarsToClassPathFrom(platformDir.c_str());
+
+ if (runUpdater) {
+ const char *baseUpdaterPath = userDir.c_str();
+ string updaterPath = userDir + "\\modules\\ext\\updater.jar";
+
+ // if user updater does not exist, use updater from platform
+ if (!fileExists(updaterPath.c_str())) {
+ baseUpdaterPath = platformDir.c_str();
+ updaterPath = platformDir + "\\modules\\ext\\updater.jar";
+ }
+
+ addToClassPath(updaterPath.c_str(), false);
+ addFilesToClassPath(baseUpdaterPath, "\\modules\\ext\\locale", "updater_*.jar");
+ }
+
+ addToClassPath((jdkhome + "\\lib\\dt.jar").c_str(), true);
+ addToClassPath((jdkhome + "\\lib\\tools.jar").c_str(), true);
+
+ if (!cpAfter.empty()) {
+ addToClassPath(cpAfter.c_str(), false);
+ }
+ logMsg("ClassPath: %s", classPath.c_str());
+ return classPath;
+}
+
+void PlatformLauncher::addJarsToClassPathFrom(const char *dir) {
+ addFilesToClassPath(dir, "lib\\patches", "*.jar");
+ addFilesToClassPath(dir, "lib\\patches", "*.zip");
+
+ addFilesToClassPath(dir, "lib", "*.jar");
+ addFilesToClassPath(dir, "lib", "*.zip");
+
+ addFilesToClassPath(dir, "lib\\locale", "*.jar");
+ addFilesToClassPath(dir, "lib\\locale", "*.zip");
+}
+
+void PlatformLauncher::addFilesToClassPath(const char *dir, const char *subdir, const char *pattern) {
+ logMsg("addFilesToClassPath()\n\tdir: %s\n\tsubdir: %s\n\tpattern: %s", dir, subdir, pattern);
+ string path = dir;
+ path += '\\';
+ path += subdir;
+ path += '\\';
+
+ WIN32_FIND_DATA fd = {0};
+ string patternPath = path + pattern;
+ HANDLE hFind = FindFirstFile(patternPath.c_str(), &fd);
+ if (hFind == INVALID_HANDLE_VALUE) {
+ logMsg("Nothing found (%s)", patternPath.c_str());
+ return;
+ }
+ do {
+ string name = subdir;
+ name += fd.cFileName;
+ string fullName = path + fd.cFileName;
+ if (addedToCP.insert(name).second) {
+ addToClassPath(fullName.c_str());
+ } else {
+ logMsg("\"%s\" already added, skipping \"%s\"", name.c_str(), fullName.c_str());
+ }
+ } while (FindNextFile(hFind, &fd));
+ FindClose(hFind);
+}
+
+void PlatformLauncher::addToClassPath(const char *path, bool onlyIfExists) {
+ logMsg("addToClassPath()\n\tpath: %s\n\tonlyIfExists: %s", path, onlyIfExists ? "true" : "false");
+ if (onlyIfExists && !fileExists(path)) {
+ return;
+ }
+
+ if (!classPath.empty()) {
+ classPath += ';';
+ }
+ classPath += path;
+}
+
+void PlatformLauncher::appendToHelp(const char *msg) {
+ if (msg) {
+ appendHelp = msg;
+ }
+}
+
+bool PlatformLauncher::restartRequested() {
+ return fileExists((userDir + RESTART_FILE_PATH).c_str());
+}
+
+void PlatformLauncher::onExit() {
+ logMsg("onExit()");
+ if (exitStatus == -252) {
+ logMsg("Exiting from CLI client, will not restart.");
+ return;
+ }
+
+ if (exiting) {
+ logMsg("Already exiting, no need to schedule restart");
+ return;
+ }
+
+ exiting = true;
+
+ if (separateProcess) {
+ logMsg("JVM in separate process, no need to restart");
+ return;
+ }
+
+ bool restart = (nextAction == ARG_NAME_LA_START_APP || (nextAction == ARG_NAME_LA_START_AU && shouldAutoUpdateClusters(false)));
+ if (!restart && restartRequested()) {
+ restart = true;
+ nextAction = ARG_NAME_LA_START_APP;
+ }
+
+ if (restart) {
+ string cmdLine = GetCommandLine();
+ logMsg("Old command line: %s", cmdLine.c_str());
+ string::size_type bslashPos = cmdLine.find_last_of('\\');
+ string::size_type pos = cmdLine.find(ARG_NAME_LA_START_APP);
+ if ((bslashPos == string::npos || bslashPos < pos) && pos != string::npos) {
+ cmdLine.erase(pos, strlen(ARG_NAME_LA_START_APP));
+ }
+ pos = cmdLine.find(ARG_NAME_LA_START_AU);
+ if ((bslashPos == string::npos || bslashPos < pos) && pos != string::npos) {
+ cmdLine.erase(pos, strlen(ARG_NAME_LA_START_AU));
+ }
+
+ if (*cmdLine.rbegin() != ' ') {
+ cmdLine += ' ';
+ }
+ if (!parentProcID.empty() && cmdLine.find(ARG_NAME_LA_PPID) == string::npos) {
+ cmdLine += ARG_NAME_LA_PPID;
+ cmdLine += ' ';
+ cmdLine += parentProcID;
+ }
+
+ if (*cmdLine.rbegin() != ' ') {
+ cmdLine += ' ';
+ }
+ cmdLine += nextAction;
+
+ logMsg("New command line: %s", cmdLine.c_str());
+ char cmdLineStr[32 * 1024] = "";
+ strcpy(cmdLineStr, cmdLine.c_str());
+ STARTUPINFO si = {0};
+ PROCESS_INFORMATION pi = {0};
+ si.cb = sizeof(STARTUPINFO);
+
+ if (!CreateProcess(NULL, cmdLineStr, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
+ logErr(true, true, "Failed to create process.");
+ return;
+ }
+ CloseHandle(pi.hThread);
+ CloseHandle(pi.hProcess);
+ }
+}
diff --git a/src/main/cpp/bootstrap/platformlauncher.h b/src/main/cpp/bootstrap/platformlauncher.h
new file mode 100644
index 0000000..07fe4d8
--- /dev/null
+++ b/src/main/cpp/bootstrap/platformlauncher.h
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+ /*
+ * Author: Tomas Holy
+ */
+
+#ifndef _PLATFORMLAUNCHER_H
+#define _PLATFORMLAUNCHER_H
+
+#include "jvmlauncher.h"
+#include <string>
+#include <list>
+#include <set>
+
+class PlatformLauncher {
+ static const char *REQ_JAVA_VERSION;
+ static const char *HELP_MSG;
+
+ static const char *HEAP_DUMP_PATH;
+ static const char *RESTART_FILE_PATH;
+
+ static const char *OPT_JDK_HOME;
+ static const char *OPT_NB_PLATFORM_HOME;
+ static const char *OPT_NB_CLUSTERS;
+ static const char *OPT_NB_USERDIR;
+ static const char *OPT_DEFAULT_USERDIR_ROOT;
+ static const char *OPT_HEAP_DUMP;
+ static const char *OPT_HEAP_DUMP_PATH;
+ static const char *OPT_KEEP_WORKING_SET_ON_MINIMIZE;
+ static const char *OPT_CLASS_PATH;
+ static const char *OPT_SPLASH;
+ static const char *OPT_SPLASH_PATH;
+
+ static const char *UPDATER_MAIN_CLASS;
+ static const char *IDE_MAIN_CLASS;
+
+
+public:
+ PlatformLauncher();
+ virtual ~PlatformLauncher();
+
+ bool start(char* argv[], int argc, DWORD *retCode);
+ void appendToHelp(const char *msg);
+ void onExit();
+
+ void setSuppressConsole(bool val) {
+ suppressConsole = val;
+ }
+
+private:
+ PlatformLauncher(const PlatformLauncher& orig);
+ bool parseArgs(int argc, char *argv[]);
+ bool initPlatformDir();
+ bool processAutoUpdateCL();
+ void deleteNewClustersFile();
+ bool checkForNewUpdater(const char *basePath);
+ bool shouldAutoUpdate(bool firstStart, const char *basePath);
+ bool shouldAutoUpdateClusters(bool firstStart);
+ void prepareOptions();
+ std::string & constructClassPath(bool runUpdater);
+ void addFilesToClassPath(const char *dir, const char *subdir, const char *pattern);
+ void addToClassPath(const char *path, bool onlyIfExists = false);
+ void addJarsToClassPathFrom(const char *dir);
+ bool run(bool updater, DWORD *retCode);
+ bool restartRequested();
+
+private:
+ bool separateProcess;
+ bool suppressConsole;
+ bool heapDumpPathOptFound;
+ bool nosplash;
+ bool exiting;
+ std::string platformDir;
+ std::string userDir;
+ std::string defaultUserDirRoot;
+ std::string clusters;
+ std::string bootclass;
+ std::string jdkhome;
+ std::string cpBefore;
+ std::string cpAfter;
+ std::string auClusters;
+ std::string nextAction;
+ std::string parentProcID;
+
+ std::list<std::string> javaOptions;
+ std::list<std::string> launcherOptions;
+ std::list<std::string> progArgs;
+ JvmLauncher jvmLauncher;
+ std::set<std::string> addedToCP;
+ std::string classPath;
+ std::string appendHelp;
+};
+
+#endif /* _PLATFORMLAUNCHER_H */
+
diff --git a/src/main/cpp/bootstrap/utilsfuncs.cpp b/src/main/cpp/bootstrap/utilsfuncs.cpp
new file mode 100644
index 0000000..2902b1e
--- /dev/null
+++ b/src/main/cpp/bootstrap/utilsfuncs.cpp
@@ -0,0 +1,449 @@
+/*
+ * 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.
+ */
+ /*
+ * Author: Tomas Holy
+ */
+
+#ifndef KEY_WOW64_64KEY
+#define KEY_WOW64_64KEY 0x0100
+#endif
+
+#include "utilsfuncs.h"
+#include "argnames.h"
+#include <tlhelp32.h>
+#include <windows.h>
+
+using namespace std;
+
+bool disableFolderVirtualization(HANDLE hProcess) {
+ OSVERSIONINFO osvi = {0};
+ osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+ if (GetVersionEx(&osvi) && osvi.dwMajorVersion == 6) // check it is Win VISTA
+ {
+ HANDLE hToken;
+ if (OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken)) {
+ DWORD tokenInfoVal = 0;
+ if (!SetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) 24, &tokenInfoVal, sizeof (DWORD))) {
+ // invalid token information class (24) is OK, it means there is no folder virtualization on current system
+ if (GetLastError() != ERROR_INVALID_PARAMETER) {
+ logErr(true, true, "Failed to set token information.");
+ return false;
+ }
+ }
+ CloseHandle(hToken);
+ } else {
+ logErr(true, true, "Failed to open process token.");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool getStringFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, string &value) {
+ return getStringFromRegistryEx(rootKey, keyName, valueName, value, false);
+}
+
+bool getStringFromRegistry64bit(HKEY rootKey, const char *keyName, const char *valueName, string &value) {
+ return getStringFromRegistryEx(rootKey, keyName, valueName, value, true);
+}
+
+
+
+bool getStringFromRegistryEx(HKEY rootKey, const char *keyName, const char *valueName, string &value, bool read64bit) {
+ logMsg("getStringFromRegistry()\n\tkeyName: %s\n\tvalueName: %s", keyName, valueName);
+ HKEY hKey = 0;
+ if (RegOpenKeyEx(rootKey, keyName, 0, KEY_READ | (read64bit ? KEY_WOW64_64KEY : 0), &hKey) == ERROR_SUCCESS) {
+ DWORD valSize = 4096;
+ DWORD type = 0;
+ char val[4096] = "";
+ if (RegQueryValueEx(hKey, valueName, 0, &type, (BYTE *) val, &valSize) == ERROR_SUCCESS
+ && type == REG_SZ) {
+ logMsg("%s: %s", valueName, val);
+ RegCloseKey(hKey);
+ value = val;
+ return true;
+ } else {
+ logErr(true, false, "RegQueryValueEx() failed.");
+ }
+ RegCloseKey(hKey);
+ } else {
+ logErr(true, false, "RegOpenKeyEx() failed.");
+ }
+ return false;
+}
+
+bool getDwordFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, DWORD &value) {
+ logMsg("getDwordFromRegistry()\n\tkeyName: %s\n\tvalueName: %s", keyName, valueName);
+ HKEY hKey = 0;
+ if (RegOpenKeyEx(rootKey, keyName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
+ DWORD valSize = sizeof(DWORD);
+ DWORD type = 0;
+ if (RegQueryValueEx(hKey, valueName, 0, &type, (BYTE *) &value, &valSize) == ERROR_SUCCESS
+ && type == REG_DWORD) {
+ logMsg("%s: %u", valueName, value);
+ RegCloseKey(hKey);
+ return true;
+ } else {
+ logErr(true, false, "RegQueryValueEx() failed.");
+ }
+ RegCloseKey(hKey);
+ } else {
+ logErr(true, false, "RegOpenKeyEx() failed.");
+ }
+ return false;
+}
+
+bool dirExists(const char *path) {
+ WIN32_FIND_DATA fd = {0};
+ HANDLE hFind = 0;
+ hFind = FindFirstFile(path, &fd);
+ if (hFind == INVALID_HANDLE_VALUE) {
+ logMsg("Dir \"%s\" does not exist", path);
+ return false;
+ }
+ logMsg("Dir \"%s\" exists", path);
+ FindClose(hFind);
+ return (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
+}
+
+bool fileExists(const char *path) {
+ WIN32_FIND_DATA fd = {0};
+ HANDLE hFind = 0;
+ hFind = FindFirstFile(path, &fd);
+ if (hFind == INVALID_HANDLE_VALUE) {
+ logMsg("File \"%s\" does not exist", path);
+ return false;
+ }
+
+ logMsg("File \"%s\" exists", path);
+ FindClose(hFind);
+ return true;
+}
+
+bool normalizePath(char *path, int len) {
+ char tmp[MAX_PATH] = "";
+ int i = 0;
+ while (path[i] && i < MAX_PATH - 1) {
+ tmp[i] = path[i] == '/' ? '\\' : path[i];
+ i++;
+ }
+ tmp[i] = '\0';
+ return _fullpath(path, tmp, len) != NULL;
+}
+
+bool createPath(const char *path) {
+ logMsg("Creating directory \"%s\"", path);
+ char dir[MAX_PATH] = "";
+ const char *sep = strchr(path, '\\');
+ while (sep) {
+ strncpy(dir, path, sep - path);
+ if (!CreateDirectory(dir, 0) && GetLastError() != ERROR_ALREADY_EXISTS) {
+ logErr(true, false, "Failed to create directory %s", dir);
+ return false;
+ }
+ sep = strchr(sep + 1, '\\');
+ }
+ return true;
+}
+
+
+char * getCurrentModulePath(char *path, int pathLen) {
+ MEMORY_BASIC_INFORMATION mbi;
+ static int dummy;
+ VirtualQuery(&dummy, &mbi, sizeof (mbi));
+ HMODULE hModule = (HMODULE) mbi.AllocationBase;
+ GetModuleFileName(hModule, path, pathLen);
+ return path;
+}
+
+char * skipWhitespaces(char *str) {
+ while (*str != '\0' && (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r')) {
+ str++;
+ }
+ return str;
+}
+
+char * trimWhitespaces(char *str) {
+ char *end = str + strlen(str) - 1;
+ while (end >= str && (*end == ' ' || *end == '\t' || *end == '\n' || *end == '\r')) {
+ *end = '\0';
+ end--;
+ }
+ return end;
+}
+
+char* getSysError(char *str, int strSize) {
+ int err = GetLastError();
+ LPTSTR lpMsgBuf;
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) & lpMsgBuf,
+ 0,
+ NULL
+ );
+ LPTSTR tmp = strchr(lpMsgBuf, '\r');
+ if (tmp != NULL) {
+ *tmp = '\0';
+ }
+
+ _snprintf(str, strSize, " %s (%u)", lpMsgBuf, err);
+ LocalFree(lpMsgBuf);
+ return str;
+}
+
+string gLogFileName;
+
+void logV(bool appendSysError, bool showMsgBox, const char *format, va_list args) {
+ char msg[4096] = "";
+ vsnprintf(msg, 4096, format, args);
+
+ if (appendSysError) {
+ char sysErr[512] = "";
+ getSysError(sysErr, 512);
+ strncat(msg, sysErr, 4096 - strlen(msg));
+ }
+
+ if (!gLogFileName.empty()) {
+ FILE *file = fopen(gLogFileName.c_str(), "a");
+ if (file) {
+ fprintf(file, "%s\n", msg);
+ fclose(file);
+ }
+ }
+
+ if (showMsgBox) {
+ ::MessageBox(NULL, msg, "Error", MB_OK | MB_ICONSTOP);
+ }
+}
+
+void logErr(bool appendSysError, bool showMsgBox, const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ logV(appendSysError, showMsgBox, format, args);
+}
+
+void logMsg(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ logV(false, false, format, args);
+}
+
+bool restarting(int argc, char *argv[]) {
+ for (int i = 0; i < argc; i++) {
+ if (strcmp(ARG_NAME_LA_START_APP, argv[i]) == 0 || strcmp(ARG_NAME_LA_START_AU, argv[i]) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool checkLoggingArg(int argc, char *argv[], bool delFile) {
+ for (int i = 0; i < argc; i++) {
+ if (strcmp(ARG_NAME_LAUNCHER_LOG, argv[i]) == 0) {
+ if (i + 1 == argc) {
+ logErr(false, true, "Argument is missing for \"%s\" option.", argv[i]);
+ return false;
+ }
+ gLogFileName = argv[++i];
+ // if we are restarting, keep log file
+ if (delFile && !restarting(argc, argv)) {
+ DeleteFile(gLogFileName.c_str());
+ }
+ break;
+ }
+ }
+ return true;
+}
+
+bool setupProcess(int &argc, char *argv[], DWORD &parentProcID, const char *attachMsg) {
+#define CHECK_ARG \
+ if (i+1 == argc) {\
+ logErr(false, true, "Argument is missing for \"%s\" option.", argv[i]);\
+ return false;\
+ }
+
+ parentProcID = 0;
+ DWORD cmdLineArgPPID = 0;
+ for (int i = 0; i < argc; i++) {
+ if (strcmp(ARG_NAME_CONSOLE, argv[i]) == 0) {
+ CHECK_ARG;
+ if (strcmp("new", argv[i + 1]) == 0){
+ AllocConsole();
+ } else if (strcmp("suppress", argv[i + 1]) == 0) {
+ // nothing, no console should be attached
+ } else {
+ logErr(false, true, "Invalid argument for \"%s\" option.", argv[i]);
+ return false;
+ }
+ // remove options
+ for (int k = i + 2; k < argc; k++) {
+ argv[k-2] = argv[k];
+ }
+ argc -= 2;
+ return true;
+ } else if (strcmp(ARG_NAME_LA_PPID, argv[i]) == 0) {
+ CHECK_ARG;
+ char *end = 0;
+ cmdLineArgPPID = strtoul(argv[++i], &end, 10);
+ if (cmdLineArgPPID == 0 && *end != '\0') {
+ logErr(false, true, "Invalid parameter for option %s", ARG_NAME_LA_PPID);
+ return false;
+ }
+ logMsg("Command line arg PPID: %u", cmdLineArgPPID);
+ break;
+ }
+ }
+#undef CHECK_ARG
+
+ // default, attach to parent process console if exists
+ // AttachConsole exists since WinXP, so be nice and do it dynamically
+ typedef BOOL (WINAPI *LPFAC)(DWORD dwProcessId);
+ HINSTANCE hKernel32 = GetModuleHandle("kernel32");
+ if (hKernel32) {
+ LPFAC attachConsole = (LPFAC) GetProcAddress(hKernel32, "AttachConsole");
+ if (attachConsole) {
+ if (cmdLineArgPPID) {
+ if (!attachConsole(cmdLineArgPPID)) {
+ logErr(true, false, "AttachConsole of PPID: %u failed.", cmdLineArgPPID);
+ }
+ } else {
+ if (!attachConsole((DWORD) -1)) {
+ logErr(true, false, "AttachConsole of PP failed.");
+ } else {
+ getParentProcessID(parentProcID);
+ if (attachMsg) {
+ printToConsole(attachMsg);
+ }
+ }
+ }
+ } else {
+ logErr(true, false, "GetProcAddress() for AttachConsole failed.");
+ }
+ }
+ return true;
+}
+
+bool isConsoleAttached() {
+ typedef HWND (WINAPI *GetConsoleWindowT)();
+ HINSTANCE hKernel32 = GetModuleHandle("kernel32");
+ if (hKernel32) {
+ GetConsoleWindowT getConsoleWindow = (GetConsoleWindowT) GetProcAddress(hKernel32, "GetConsoleWindow");
+ if (getConsoleWindow) {
+ if (getConsoleWindow() != NULL) {
+ logMsg("Console is attached.");
+ return true;
+ }
+ } else {
+ logErr(true, false, "GetProcAddress() for GetConsoleWindow failed.");
+ }
+ }
+ return false;
+}
+
+bool printToConsole(const char *msg) {
+ FILE *console = fopen("CON", "a");
+ if (!console) {
+ return false;
+ }
+ fprintf(console, "%s", msg);
+ fclose(console);
+ return false;
+}
+
+bool getParentProcessID(DWORD &id) {
+ typedef HANDLE (WINAPI * CreateToolhelp32SnapshotT)(DWORD, DWORD);
+ typedef BOOL (WINAPI * Process32FirstT)(HANDLE, LPPROCESSENTRY32);
+ typedef BOOL (WINAPI * Process32NextT)(HANDLE, LPPROCESSENTRY32);
+
+ HINSTANCE hKernel32 = GetModuleHandle("kernel32");
+ if (!hKernel32) {
+ return false;
+ }
+
+ CreateToolhelp32SnapshotT createToolhelp32Snapshot = (CreateToolhelp32SnapshotT) GetProcAddress(hKernel32, "CreateToolhelp32Snapshot");
+ Process32FirstT process32First = (Process32FirstT) GetProcAddress(hKernel32, "Process32First");
+ Process32NextT process32Next = (Process32NextT) GetProcAddress(hKernel32, "Process32Next");
+
+ if (createToolhelp32Snapshot == NULL || process32First == NULL || process32Next == NULL) {
+ logErr(true, false, "Failed to obtain Toolhelp32 functions.");
+ return false;
+ }
+
+ HANDLE hSnapshot = createToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (hSnapshot == INVALID_HANDLE_VALUE) {
+ logErr(true, false, "Failed to obtain process snapshot.");
+ return false;
+ }
+
+ PROCESSENTRY32 entry = {0};
+ entry.dwSize = sizeof (PROCESSENTRY32);
+ if (!process32First(hSnapshot, &entry)) {
+ CloseHandle(hSnapshot);
+ return false;
+ }
+
+ DWORD curID = GetCurrentProcessId();
+ logMsg("Current process ID: %u", curID);
+
+ do {
+ if (entry.th32ProcessID == curID) {
+ id = entry.th32ParentProcessID;
+ logMsg("Parent process ID: %u", id);
+ CloseHandle(hSnapshot);
+ return true;
+ }
+ } while (process32Next(hSnapshot, &entry));
+
+ CloseHandle(hSnapshot);
+ return false;
+}
+
+bool isWow64()
+{
+ BOOL IsWow64 = FALSE;
+ typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+ LPFN_ISWOW64PROCESS fnIsWow64Process;
+
+ fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
+
+ if (NULL != fnIsWow64Process)
+ {
+ if (!fnIsWow64Process(GetCurrentProcess(),&IsWow64))
+ {
+ // handle error
+ }
+ }
+ return IsWow64;
+}
+
+int convertAnsiToUtf8(const char *ansi, char *utf8, int utf8Len) {
+ const int len = 32*1024;
+ WCHAR tmp[len] = L"";
+ if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ansi, -1, tmp, len) == 0)
+ return -1;
+ if (WideCharToMultiByte(CP_UTF8, 0, tmp, -1, utf8, utf8Len, NULL, NULL) == 0)
+ return -1;
+ return 0;
+}
+
diff --git a/src/main/cpp/bootstrap/utilsfuncs.h b/src/main/cpp/bootstrap/utilsfuncs.h
new file mode 100644
index 0000000..6cf172a
--- /dev/null
+++ b/src/main/cpp/bootstrap/utilsfuncs.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+ /*
+ * Author: Tomas Holy
+ */
+
+#ifndef _UTILSFUNCS_H
+#define _UTILSFUNCS_H
+
+#include <windows.h>
+#include <string>
+
+bool isWow64();
+bool disableFolderVirtualization(HANDLE hProcess);
+bool getStringFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, std::string &value);
+bool getStringFromRegistryEx(HKEY rootKey, const char *keyName, const char *valueName, std::string &value,bool read64bit);
+bool getStringFromRegistry64bit(HKEY rootKey, const char *keyName, const char *valueName, std::string &value);
+bool getDwordFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, DWORD &value);
+bool dirExists(const char *path);
+bool fileExists(const char *path);
+bool normalizePath(char *path, int len);
+bool createPath(const char *path);
+char * getCurrentModulePath(char *path, int pathLen);
+char * skipWhitespaces(char *str);
+char * trimWhitespaces(char *str);
+void logMsg(const char *format, ...);
+void logErr(bool appendSysError, bool showMsgBox, const char *format, ...);
+bool checkLoggingArg(int argc, char *argv[], bool delFile);
+bool setupProcess(int &argc, char *argv[], DWORD &parentProcID, const char *attachMsg = 0);
+bool printToConsole(const char *msg);
+bool getParentProcessID(DWORD &id);
+bool isConsoleAttached();
+int convertAnsiToUtf8(const char *ansi, char *utf8, int utf8Len);
+
+#endif /* _UTILSFUNCS_H */
+
diff --git a/src/main/cpp/bootstrap/version.h b/src/main/cpp/bootstrap/version.h
new file mode 100644
index 0000000..63f0860
--- /dev/null
+++ b/src/main/cpp/bootstrap/version.h
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+#define COMPANY ""
+#define COMPONENT "NetBeans Platform Launcher"
+#define VER "9.0.0.0"
+#define FVER 9,0,0,0
+#define BUILD_ID "03062018"
+#define INTERNAL_NAME "nbexec"
+#define COPYRIGHT "Based on Apache NetBeans from the Apache Software Foundation and is licensed under Apache License Version 2.0"
+#define NAME "NetBeans Platform Launcher"
+
diff --git a/src/main/cpp/bootstrap/version.rc b/src/main/cpp/bootstrap/version.rc
new file mode 100644
index 0000000..7a516a4
--- /dev/null
+++ b/src/main/cpp/bootstrap/version.rc
@@ -0,0 +1,63 @@
+/*
+ * 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 <winuser.h>
+#include <winver.h>
+#include "version.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION FVER
+ PRODUCTVERSION FVER
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ // FILEOS 0x4 is Win32, 0x40004 is Win32 NT only
+ FILEOS 0x4L
+ // FILETYPE should be 0x1 for .exe and 0x2 for .dll
+ FILETYPE FILETYPE_ID
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName", COMPANY "\0"
+ VALUE "FileDescription", COMPONENT "\0"
+ VALUE "FileVersion", VER "\0"
+ VALUE "Full Version", BUILD_ID "\0"
+ VALUE "InternalName", INTERNAL_NAME "\0"
+ VALUE "LegalCopyright", COPYRIGHT "\0"
+ VALUE "OriginalFilename", FNAME "\0"
+ VALUE "ProductName", NAME "\0"
+ VALUE "ProductVersion", VER "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END