diff --git a/harness/apisupport.harness/windows-launcher-src/Makefile.mingw b/harness/apisupport.harness/windows-launcher-src/Makefile.mingw
new file mode 100644
index 000000000000..866b30dd1e54
--- /dev/null
+++ b/harness/apisupport.harness/windows-launcher-src/Makefile.mingw
@@ -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.
+
+TMPFLD = ../../../../target/tmp/
+OFLD = ../../../../target/harness/
+
+all: prepfolder app64.exe app.exe
+
+prepfolder:
+ mkdir -p $(TMPFLD)
+ mkdir -p $(OFLD)
+
+clean:
+ rm -f *.res *.exe
+
+app64.res: app.rc app.exe.manifest
+ x86_64-w64-mingw32-windres -o$(TMPFLD)app64.res -Ocoff -DMANIFEST_FILE=app.exe.manifest app.rc
+
+app64.exe: app.cpp applauncher.cpp app64.res ../bootstrap/utilsfuncs.cpp
+ x86_64-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec64.dll"' -DARCHITECTURE=64 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh app.cpp -mwindows applauncher.cpp $(TMPFLD)app64.res ../bootstrap/utilsfuncs.cpp ../ide/nblauncher.cpp -I ../bootstrap/ -o$(OFLD)app64.exe -static -lstdc++ -static-libstdc++ -static-libgcc
+
+app.res: app.rc app.exe.manifest
+ i686-w64-mingw32-windres -o$(TMPFLD)app.res -Ocoff -DMANIFEST_FILE=app.exe.manifest app.rc
+
+app.exe: app.cpp applauncher.cpp app.res ../bootstrap/utilsfuncs.cpp
+ i686-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec.dll"' -DARCHITECTURE=32 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -mwindows app.cpp applauncher.cpp $(TMPFLD)app.res ../bootstrap/utilsfuncs.cpp ../ide/nblauncher.cpp -I ../bootstrap/ -o$(OFLD)app.exe -static -lstdc++ -static-libstdc++ -static-libgcc
+
diff --git a/harness/apisupport.harness/windows-launcher-src/app.cpp b/harness/apisupport.harness/windows-launcher-src/app.cpp
new file mode 100644
index 000000000000..840c8285e06e
--- /dev/null
+++ b/harness/apisupport.harness/windows-launcher-src/app.cpp
@@ -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.
+ */
+ /*
+ * Author: Tomas Holy
+ */
+
+
+#include "applauncher.h"
+
+int main(int argc, char *argv[]) {
+ AppLauncher launcher;
+ return launcher.start(argc - 1, argv + 1);
+}
diff --git a/harness/apisupport.harness/windows-launcher-src/app.exe.manifest b/harness/apisupport.harness/windows-launcher-src/app.exe.manifest
new file mode 100644
index 000000000000..c1843b229a94
--- /dev/null
+++ b/harness/apisupport.harness/windows-launcher-src/app.exe.manifest
@@ -0,0 +1,75 @@
+
+
+
+
+
+NBP application process
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UTF-8
+
+
+
+
+
+ true/PM
+ PerMonitorV2, PerMonitor, system
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/harness/apisupport.harness/windows-launcher-src/app.ico b/harness/apisupport.harness/windows-launcher-src/app.ico
new file mode 100644
index 000000000000..294cd704d198
Binary files /dev/null and b/harness/apisupport.harness/windows-launcher-src/app.ico differ
diff --git a/harness/apisupport.harness/windows-launcher-src/app.rc b/harness/apisupport.harness/windows-launcher-src/app.rc
new file mode 100644
index 000000000000..d52211e464c6
--- /dev/null
+++ b/harness/apisupport.harness/windows-launcher-src/app.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.
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+
+#include
+
+100 ICON "app.ico"
+
+// Value MANIFEST_FILE id taken from windres parameter -DMANIFEST_FILE
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST MANIFEST_FILE
diff --git a/harness/apisupport.harness/windows-launcher-src/applauncher.cpp b/harness/apisupport.harness/windows-launcher-src/applauncher.cpp
new file mode 100644
index 000000000000..1fa9d4ee8165
--- /dev/null
+++ b/harness/apisupport.harness/windows-launcher-src/applauncher.cpp
@@ -0,0 +1,141 @@
+/*
+ * 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 "applauncher.h"
+#include "../bootstrap/utilsfuncs.h"
+#include "../bootstrap/argnames.h"
+
+using namespace std;
+
+const char *AppLauncher::OPT_DEFAULT_USER_DIR = "default_userdir=";
+const char *AppLauncher::OPT_DEFAULT_CACHE_DIR = "default_cachedir=";
+const char *AppLauncher::OPT_DEFAULT_OPTIONS = "default_options=";
+const char *AppLauncher::OPT_EXTRA_CLUSTERS = "extra_clusters=";
+const char *AppLauncher::OPT_JDK_HOME = "jdkhome=";
+const char *AppLauncher::APPNAME_TOKEN = "${APPNAME}";
+const char *AppLauncher::CACHE_SUFFIX = "\\Cache\\";
+
+AppLauncher::AppLauncher() {
+}
+
+AppLauncher::AppLauncher(const AppLauncher& orig) {
+}
+
+AppLauncher::~AppLauncher() {
+}
+
+bool AppLauncher::initBaseNames() {
+ if (!NbLauncher::initBaseNames()) {
+ return false;
+ }
+
+ string pattern = baseDir + "\\platform*";
+ WIN32_FIND_DATA fd = {0};
+ HANDLE hFind;
+ hFind = FindFirstFile(pattern.c_str(), &fd);
+ if (hFind == INVALID_HANDLE_VALUE) {
+ logErr(false, true, "Cannot find 'platform*' folder!");
+ return false;
+ }
+
+ do {
+ if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ && fileExists((baseDir + '\\' + fd.cFileName + NbLauncher::NBEXEC_FILE_PATH).c_str())) {
+ platformDir = baseDir + '\\' + fd.cFileName;
+ break;
+ }
+ } while (FindNextFile(hFind, &fd));
+
+ FindClose(hFind);
+
+ if (platformDir.empty()) {
+ logErr(false, true, "Cannot find valid 'platform*' folder!");
+ return false;
+ }
+ return true;
+}
+
+bool AppLauncher::findUserDir(const char *str) {
+ logMsg("AppLauncher::findUserDir()");
+ if (!NbLauncher::findUserDir(str)) { // will set userDir and possibly userHome.
+ return false;
+ }
+ int pos = userDir.find(APPNAME_TOKEN);
+ if (pos != string::npos) {
+ userDir.replace(pos, strlen(APPNAME_TOKEN), appName);
+ }
+ return true;
+}
+
+bool AppLauncher::findCacheDir(const char *str) {
+ logMsg("AppLauncher::findCacheDir");
+ if (!NbLauncher::findCacheDir(str)) { // will set userDir and possibly userHome.
+ return false;
+ }
+ int pos = cacheDir.find(APPNAME_TOKEN);
+ if (pos != string::npos) {
+ cacheDir.replace(pos, strlen(APPNAME_TOKEN), appName);
+ }
+ return true;
+}
+
+const char * AppLauncher::getAppName() {
+ return appName.c_str();
+}
+
+void AppLauncher::addSpecificOptions(CmdArgs &args) {
+}
+
+void AppLauncher::adjustHeapSize() {
+}
+
+const char * AppLauncher::getDefUserDirOptName() {
+ return OPT_DEFAULT_USER_DIR;
+}
+
+const char * AppLauncher::getDefCacheDirOptName() {
+ return OPT_DEFAULT_CACHE_DIR;
+}
+
+const char * AppLauncher::getDefOptionsOptName() {
+ return OPT_DEFAULT_OPTIONS;
+}
+
+const char * AppLauncher::getExtraClustersOptName() {
+ return OPT_EXTRA_CLUSTERS;
+}
+
+const char * AppLauncher::getJdkHomeOptName() {
+ return OPT_JDK_HOME;
+}
+
+const char * AppLauncher::getCurrentDir() {
+ return baseDir.c_str();
+}
+
+std::string AppLauncher::constructApplicationDir(const std::string& dir, bool cache) {
+ if (cache) {
+ return dir + "\\" + getAppName() + CACHE_SUFFIX;
+ } else {
+ return dir + "\\" + getAppName() + "\\";
+ }
+}
diff --git a/harness/apisupport.harness/windows-launcher-src/applauncher.h b/harness/apisupport.harness/windows-launcher-src/applauncher.h
new file mode 100644
index 000000000000..b6002fd95b7b
--- /dev/null
+++ b/harness/apisupport.harness/windows-launcher-src/applauncher.h
@@ -0,0 +1,67 @@
+/*
+ * 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 _APPLAUNCHER_H
+#define _APPLAUNCHER_H
+
+#include
+#include
+
+#include "shlobj.h"
+#include "../ide/nblauncher.h"
+
+class AppLauncher : public NbLauncher {
+
+ static const char *OPT_DEFAULT_USER_DIR;
+ static const char *OPT_DEFAULT_CACHE_DIR;
+ static const char *OPT_DEFAULT_OPTIONS;
+ static const char *OPT_EXTRA_CLUSTERS;
+ static const char *OPT_JDK_HOME;
+ static const char *APPNAME_TOKEN;
+ static const char *REG_APPDATA_NAME;
+ static const char *CACHE_SUFFIX;
+
+public:
+ AppLauncher();
+ virtual ~AppLauncher();
+
+protected:
+ virtual bool initBaseNames();
+ virtual const char * getAppName();
+ virtual void addSpecificOptions(CmdArgs &args);
+ virtual void adjustHeapSize();
+ virtual bool findUserDir(const char *str);
+ virtual bool findCacheDir(const char *str);
+ virtual const char * getDefUserDirOptName();
+ virtual const char * getDefCacheDirOptName();
+ virtual const char * getDefOptionsOptName();
+ virtual const char * getExtraClustersOptName();
+ virtual const char * getJdkHomeOptName();
+ virtual const char * getCurrentDir();
+ virtual std::string constructApplicationDir(const std::string& dir, bool cache);
+
+private:
+ AppLauncher(const AppLauncher& orig);
+};
+
+#endif /* _NBLAUNCHER_H */
+
diff --git a/nb/ide.launcher/windows/Makefile.mingw b/nb/ide.launcher/windows/Makefile.mingw
new file mode 100644
index 000000000000..6db2f87fc281
--- /dev/null
+++ b/nb/ide.launcher/windows/Makefile.mingw
@@ -0,0 +1,40 @@
+# 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.
+
+TMPFLD = ../../../../target/tmp/
+OFLD = ../../../../target/ide/
+
+all: prepfolder netbeans64.exe netbeans.exe
+
+prepfolder:
+ mkdir -p $(TMPFLD)
+ mkdir -p $(OFLD)
+
+clean:
+ rm -f *.res *.exe
+
+netbeans64.res: netbeans.rc netbeans64.exe.manifest
+ x86_64-w64-mingw32-windres -o$(TMPFLD)netbeans64.res -Ocoff -DMANIFEST_FILE=netbeans64.exe.manifest netbeans.rc
+
+netbeans64.exe: netbeans.cpp nblauncher.cpp netbeans64.res ../bootstrap/utilsfuncs.cpp
+ x86_64-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec64.dll"' -DARCHITECTURE=64 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -mwindows netbeans.cpp nblauncher.cpp $(TMPFLD)netbeans64.res ../bootstrap/utilsfuncs.cpp -I ../bootstrap/ -o$(OFLD)netbeans64.exe -static -lstdc++ -static-libstdc++ -static-libgcc
+
+netbeans.res: netbeans.rc netbeans.exe.manifest
+ i686-w64-mingw32-windres -o$(TMPFLD)netbeans.res -Ocoff -DMANIFEST_FILE=netbeans.exe.manifest netbeans.rc
+
+netbeans.exe: netbeans.cpp nblauncher.cpp netbeans.res ../bootstrap/utilsfuncs.cpp
+ i686-w64-mingw32-gcc -s -DNBEXEC_DLL='"/lib/nbexec.dll"' -DARCHITECTURE=32 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -mwindows netbeans.cpp nblauncher.cpp $(TMPFLD)netbeans.res ../bootstrap/utilsfuncs.cpp -I ../bootstrap/ -o$(OFLD)netbeans.exe -static -lstdc++ -static-libstdc++ -static-libgcc
diff --git a/nb/ide.launcher/windows/cmdargs.h b/nb/ide.launcher/windows/cmdargs.h
new file mode 100644
index 000000000000..acf56a411e79
--- /dev/null
+++ b/nb/ide.launcher/windows/cmdargs.h
@@ -0,0 +1,119 @@
+/*
+ * 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 _CMDARGS_H
+#define _CMDARGS_H
+
+class CmdArgs {
+public:
+
+ CmdArgs(int _count) {
+ used = 0;
+ size = _count;
+ args = new char*[size];
+ memset(args, 0, size * sizeof (char*));
+ }
+
+ ~CmdArgs() {
+ if (args) {
+ for (int i = 0; i < size; i++) {
+ delete[] args[i];
+ }
+ delete[] args;
+ }
+ }
+
+ void add(const char *arg) {
+ if (used + 1 > size) {
+ int newSize = size + size / 2 + 1;
+ char **newArgs = new char*[newSize];
+ memcpy(newArgs, args, size * sizeof (char*));
+ memset(newArgs + size, 0, (newSize - size) * sizeof (char*));
+ delete[] args;
+ args = newArgs;
+ size = newSize;
+ }
+ args[used] = new char[strlen(arg) + 1];
+ strcpy(args[used++], arg);
+ }
+
+ void addCmdLine(const char *cmdLine) {
+ char arg[1024] = "";
+ bool inQuotes = false;
+ bool inText = false;
+ int i = 0;
+ int j = 0;
+ char c;
+ while (c = cmdLine[i]) {
+ if (inQuotes) {
+ if (c == '\"') {
+ inQuotes = false;
+ } else {
+ arg[j++] = c;
+ }
+ } else {
+ switch (c) {
+ case '\"':
+ inQuotes = true;
+ inText = true;
+ break;
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\r':
+ if (inText) {
+ arg[j] = '\0';
+ add(arg);
+ j = 0;
+ }
+ inText = false;
+ break;
+ default:
+ inText = true;
+ arg[j++] = c;
+ break;
+ }
+ }
+ i++;
+ }
+ if (j > 0) {
+ arg[j] = '\0';
+ add(arg);
+ }
+ }
+
+ int getCount() {
+ return used;
+ }
+
+ char **getArgs() {
+ return args;
+ }
+
+private:
+ int used;
+ int size;
+ char **args;
+};
+
+#endif /* _CMDARGS_H */
+
diff --git a/nb/ide.launcher/windows/nblauncher.cpp b/nb/ide.launcher/windows/nblauncher.cpp
new file mode 100644
index 000000000000..393e2cd81a27
--- /dev/null
+++ b/nb/ide.launcher/windows/nblauncher.cpp
@@ -0,0 +1,554 @@
+/*
+ * 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 _WIN32_WINNT
+#define _WIN32_WINNT 0x05010100
+#endif
+
+#include
+#include
+#include "nblauncher.h"
+#include "../bootstrap/utilsfuncs.h"
+#include "../bootstrap/argnames.h"
+#include "../bootstrap/nbexecloader.h"
+
+using namespace std;
+
+const char *NbLauncher::NBEXEC_FILE_PATH = NBEXEC_DLL;
+const char *NbLauncher::OPT_NB_DEFAULT_USER_DIR = "netbeans_default_userdir=";
+const char *NbLauncher::OPT_NB_DEFAULT_CACHE_DIR = "netbeans_default_cachedir=";
+const char *NbLauncher::OPT_NB_DEFAULT_OPTIONS = "netbeans_default_options=";
+const char *NbLauncher::OPT_NB_EXTRA_CLUSTERS = "netbeans_extraclusters=";
+const char *NbLauncher::OPT_NB_JDK_HOME = "netbeans_jdkhome=";
+const char *NbLauncher::ENV_USER_PROFILE = "USERPROFILE";
+const char *NbLauncher::HOME_TOKEN = "${HOME}";
+const char *NbLauncher::DEFAULT_USERDIR_ROOT_TOKEN = "${DEFAULT_USERDIR_ROOT}";
+const char *NbLauncher::DEFAULT_CACHEDIR_ROOT_TOKEN = "${DEFAULT_CACHEDIR_ROOT}";
+const char *NbLauncher::NETBEANS_DIRECTORY = "\\NetBeans\\";
+const char *NbLauncher::NETBEANS_CACHES_DIRECTORY = "\\NetBeans\\Cache\\";
+
+const char *NbLauncher::CON_ATTACH_MSG =
+"\n\nThe launcher has determined that the parent process has a console and will reuse it for its own console output.\n"
+"Closing the console will result in termination of the running program.\n"
+"Use '--console suppress' to suppress console output.\n"
+"Use '--console new' to create a separate console window.\n";
+
+const char *NbLauncher::staticOptions[] = {
+ "-J-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade",
+ "--branding",
+ "nb"
+};
+
+NbLauncher::NbLauncher() {
+}
+
+NbLauncher::NbLauncher(const NbLauncher& orig) {
+}
+
+NbLauncher::~NbLauncher() {
+}
+
+int NbLauncher::start(char *cmdLine) {
+ CmdArgs args(50);
+ args.addCmdLine(cmdLine);
+ return start(args.getCount(), args.getArgs());
+}
+
+int NbLauncher::start(int argc, char *argv[]) {
+ SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+
+ DWORD parentProcID = 0;
+ if (!checkLoggingArg(argc, argv, true) || !setupProcess(argc, argv, parentProcID, CON_ATTACH_MSG) || !initBaseNames() || !readClusterFile()) {
+ return -1;
+ }
+
+ parseConfigFile((baseDir + "\\etc\\" + getAppName() + ".conf").c_str());
+
+ if (!parseArgs(argc, argv)) {
+ return -1;
+ }
+ string oldUserDir = userDir;
+ parseConfigFile((userDir + "\\etc\\" + getAppName() + ".conf").c_str());
+ userDir = oldUserDir;
+
+ addExtraClusters();
+ string nbexecPath;
+ SetDllDirectory(baseDir.c_str());
+ if (dirExists(platformDir.c_str())) {
+ nbexecPath = platformDir;
+ } else {
+ nbexecPath = baseDir + '\\' + platformDir;
+ }
+ if (!dirExists(nbexecPath.c_str())) {
+ logErr(false, true, "Could not find platform cluster:\n%s", nbexecPath.c_str());
+ return false;
+ }
+
+ CmdArgs newArgs(argc + 20);
+ addSpecificOptions(newArgs);
+
+ if (!clusters.empty()) {
+ newArgs.add(ARG_NAME_CLUSTERS);
+ newArgs.add(clusters.c_str());
+ }
+ if (!userDir.empty()) {
+ newArgs.add(ARG_NAME_USER_DIR);
+ newArgs.add(userDir.c_str());
+ }
+ if (!defUserDirRoot.empty()) {
+ newArgs.add(ARG_DEFAULT_USER_DIR_ROOT);
+ newArgs.add(defUserDirRoot.c_str());
+ }
+ if (!cacheDir.empty() && !customUserDirFound) {
+ newArgs.add(ARG_NAME_CACHE_DIR);
+ newArgs.add(cacheDir.c_str());
+ }
+ if (!nbOptions.empty()) {
+ newArgs.addCmdLine(nbOptions.c_str());
+ }
+ for (int i = 0; i < argc; i++) {
+ newArgs.add(argv[i]);
+ }
+ if (!jdkHome.empty()) {
+ newArgs.add(ARG_NAME_JDKHOME);
+ newArgs.add(jdkHome.c_str());
+ }
+ if (parentProcID) {
+ newArgs.add(ARG_NAME_LA_PPID);
+ char tmp[16] = "";
+ newArgs.add(itoa(parentProcID, tmp, 10));
+ }
+ nbexecPath += NBEXEC_FILE_PATH;
+
+ const char *curDir = getCurrentDir();
+ if (curDir) {
+ char olddir[MAX_PATH];
+ DWORD rc = GetCurrentDirectory(MAX_PATH, olddir);
+ if (rc == 0) {
+ logErr(true, false, "Failed to get current directory");
+ } else {
+ string od = string(olddir);
+ od.insert(0, "-J-Dnetbeans.user.dir=");
+ newArgs.add(od.c_str());
+ }
+ logMsg("Changing current directory to: \"%s\"", curDir);
+ SetCurrentDirectory(curDir);
+ }
+
+ NBExecLoader loader;
+ return loader.start(nbexecPath.c_str(), newArgs.getCount(), newArgs.getArgs());
+}
+
+UINT GetAnsiCodePageForLocale(LCID lcid) {
+ // See https://devblogs.microsoft.com/oldnewthing/20161007-00/?p=94475
+ UINT acp;
+ int sizeInChars = sizeof(acp) / sizeof(TCHAR);
+ if (GetLocaleInfo(lcid,
+ LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
+ reinterpret_cast(&acp),
+ sizeInChars) != sizeInChars)
+ {
+ return 0;
+ }
+ return acp;
+}
+
+bool NbLauncher::initBaseNames() {
+ char path[MAX_PATH] = "";
+ getCurrentModulePath(path, MAX_PATH);
+ logMsg("Executable: %s", path);
+ char *bslash = strrchr(path, '\\');
+ if (!bslash) {
+ return false;
+ }
+ appName = bslash + 1;
+ appName.erase(appName.rfind('.'));
+
+ if (ARCHITECTURE == 64) {
+ appName = appName.erase(appName.length() - 2);
+ }
+
+ logMsg("Application name: %s", appName.c_str());
+
+ *bslash = '\0';
+ bslash = strrchr(path, '\\');
+ if (!bslash) {
+ return false;
+ }
+ *bslash = '\0';
+
+ /* Useful messages for debugging character set issues. On Java versions where
+ https://bugs.openjdk.org/browse/JDK-8272352 has been fixed, NetBeans should now run fine when
+ there are Unicode characters in the NetBeans installation path, the JDK path, the user/cache
+ directory paths, or in the java.io.tmpdir path (the latter sometimes being a problem for JNA,
+ which is used by FlatLAF). Since the JVM is started in-process via JNI, the Java environment
+ will inherit the UTF-8 code page setting that we have set in the launcher's application
+ manifest, without requiring the user to change regional settings in the Control Panel. (JEP 400
+ might eventually do something similar for the java.exe/javaw.exe executables. See
+ https://www.mail-archive.com/core-libs-dev@openjdk.java.net/msg80489.html .) */
+ logMsg("ANSI code page per GetACP() : %d", GetACP());
+ logMsg("ANSI code page per GetConsoleCP() : %d", GetConsoleCP());
+ logMsg("ANSI code page for GetThreadLocale() : %d", GetAnsiCodePageForLocale(GetThreadLocale()));
+ logMsg("ANSI code page for GetUserDefaultLCID() : %d", GetAnsiCodePageForLocale(GetUserDefaultLCID()));
+ logMsg("ANSI code page for GetSystemDefaultLCID(): %d", GetAnsiCodePageForLocale(GetSystemDefaultLCID()));
+
+ baseDir = path;
+
+ logMsg("Base dir: %s", baseDir.c_str());
+ return true;
+}
+
+void NbLauncher::addCluster(const char *cluster) {
+
+ class SetCurDir {
+ public:
+ SetCurDir(const char *dir) {
+ oldCurDir[0] = '\0';
+ DWORD rc = GetCurrentDirectory(MAX_PATH, oldCurDir);
+ if (rc == 0) {
+ logErr(true, false, "Failed to get current directory");
+ return;
+ }
+ if (rc > MAX_PATH) {
+ logMsg("Failed to get current directory, buffer is too small.");
+ return;
+ }
+ if (!SetCurrentDirectory(dir)) {
+ logErr(true, true, "Failed to set current directory to \"%s\"", dir);
+ oldCurDir[0] = '\0';
+ }
+ }
+
+ ~SetCurDir() {
+ if (oldCurDir[0]) {
+ if (!SetCurrentDirectory(oldCurDir)) {
+ logErr(true, true, "Failed to set current directory to \"%s\"", oldCurDir);
+ }
+ }
+ }
+ private:
+ char oldCurDir[MAX_PATH];
+ };
+
+ logMsg("addCluster: %s", cluster);
+ SetCurDir setCurDir(baseDir.c_str());
+ char clusterPath[MAX_PATH + 1] = {0};
+ strncpy(clusterPath, cluster, MAX_PATH);
+ if (!normalizePath(clusterPath, MAX_PATH)) {
+ logMsg("Invalid cluster path: %s", cluster);
+ return;
+ }
+ if (!clusters.empty()) {
+ clusters += ';';
+ }
+ logMsg("Adding cluster %s", clusterPath);
+ clusters += clusterPath;
+}
+
+void NbLauncher::addExtraClusters() {
+ logMsg("addExtraClusters()");
+ const char delim = ';';
+ string::size_type start = extraClusters.find_first_not_of(delim, 0);
+ string::size_type end = extraClusters.find_first_of(delim, start);
+ while (string::npos != end || string::npos != start) {
+ string cluster = extraClusters.substr(start, end - start);
+ addCluster(cluster.c_str());
+ start = extraClusters.find_first_not_of(delim, end);
+ end = extraClusters.find_first_of(delim, start);
+ }
+}
+
+bool NbLauncher::readClusterFile() {
+ clusters = "";
+ string clusterFile = baseDir + "\\etc\\" + getAppName() + ".clusters";
+ logMsg("readClusterFile() file: %s", clusterFile.c_str());
+
+ FILE* file = fopen(clusterFile.c_str(), "r");
+ if (!file) {
+ logErr(true, true, "Cannot open file \"%s\" for reading.", clusterFile.c_str());
+ return false;
+ }
+
+ char line[4096] = "";
+ while (fgets(line, sizeof(line), file)) {
+ char *str = skipWhitespaces(line);
+ if (*str == '#' || *str == '\0') {
+ continue;
+ }
+ char *pc = str;
+ while (*pc != '\0' && *pc != '\t' && *pc != '\n' && *pc != '\r') {
+ pc++;
+ }
+ *pc = '\0';
+
+ if (platformDir.empty()) {
+ char *slash = strrchr(str, '\\');
+ if (!slash) {
+ slash = strrchr(str, '/');
+ }
+ char *dir = slash ? slash + 1 : str;
+ if (strncmp(dir, "platform", strlen("platform")) == 0) {
+ platformDir = str;
+ } else {
+ addCluster(str);
+ }
+ } else {
+ addCluster(str);
+ }
+ }
+ bool ok = ferror(file) == 0;
+ if (!ok) {
+ logErr(true, true, "Error while reading file \"%s\".", clusterFile.c_str());
+ }
+ fclose(file);
+ return ok;
+}
+
+bool NbLauncher::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("parseArgs():");
+ for (int i = 0; i < argc; i++) {
+ logMsg("\t%s", argv[i]);
+ }
+ customUserDirFound = 0;
+ for (int i = 0; i < argc; i++) {
+ if (strcmp(ARG_NAME_USER_DIR, argv[i]) == 0) {
+ CHECK_ARG;
+ char tmp[MAX_PATH + 1] = {0};
+ strncpy(tmp, argv[++i], MAX_PATH);
+ if (!normalizePath(tmp, MAX_PATH)) {
+ logErr(false, true, "User directory path \"%s\" is not valid.", argv[i]);
+ return false;
+ }
+ customUserDirFound = 1;
+ userDir = tmp;
+ logMsg("User dir: %s", userDir.c_str());
+ }
+ if (strcmp(ARG_NAME_CACHE_DIR, argv[i]) == 0) {
+ CHECK_ARG;
+ char tmp[MAX_PATH + 1] = {0};
+ strncpy(tmp, argv[++i], MAX_PATH);
+ if (!normalizePath(tmp, MAX_PATH)) {
+ logErr(false, true, "Cache directory path \"%s\" is not valid.", argv[i]);
+ return false;
+ }
+ cacheDir = tmp;
+ logMsg("Cache dir: %s", cacheDir.c_str());
+ }
+ }
+ logMsg("parseArgs() finished");
+ return true;
+}
+
+bool NbLauncher::findUserDir(const char *str) {
+ logMsg("NbLauncher::findUserDir()");
+ if (strncmp(str, HOME_TOKEN, strlen(HOME_TOKEN)) == 0) {
+ if (userHome.empty()) {
+ char *userProfile = getenv(ENV_USER_PROFILE);
+ if (userProfile) {
+ userHome = userProfile;
+ } else {
+ TCHAR userHomeChar[MAX_PATH];
+ if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, userHomeChar))) {
+ return false;
+ }
+ userHome = userHomeChar;
+ userHome.erase(userHome.rfind('\\'));
+ }
+ logMsg("User home: %s", userHome.c_str());
+ }
+ userDir = userHome + (str + strlen(HOME_TOKEN));
+ } else if (strncmp(str, DEFAULT_USERDIR_ROOT_TOKEN, strlen(DEFAULT_USERDIR_ROOT_TOKEN)) == 0) {
+ std::string s = std::string("Replacing ") + DEFAULT_USERDIR_ROOT_TOKEN;
+ logMsg(s.c_str());
+ userDir = getDefaultUserDirRoot() + (str + strlen(DEFAULT_USERDIR_ROOT_TOKEN));
+ } else {
+ getDefaultUserDirRoot();
+ userDir = str;
+ }
+ return true;
+}
+
+bool NbLauncher::findCacheDir(const char *str) {
+ logMsg("NbLauncher::findCacheDir()");
+ if (strncmp(str, HOME_TOKEN, strlen(HOME_TOKEN)) == 0) {
+ if (userHome.empty()) {
+ char *userProfile = getenv(ENV_USER_PROFILE);
+ if (userProfile) {
+ userHome = userProfile;
+ } else {
+ TCHAR userHomeChar[MAX_PATH];
+ if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, userHomeChar))) {
+ return false;
+ }
+ userHome = userHomeChar;
+ userHome.erase(userHome.rfind('\\'));
+ }
+ logMsg("User home: %s", userHome.c_str());
+ }
+ cacheDir = userHome + (str + strlen(HOME_TOKEN));
+ } else if (strncmp(str, DEFAULT_CACHEDIR_ROOT_TOKEN, strlen(DEFAULT_CACHEDIR_ROOT_TOKEN)) == 0) {
+ std::string s = std::string("Replacing ") + DEFAULT_CACHEDIR_ROOT_TOKEN;
+ logMsg(s.c_str());
+ cacheDir = getDefaultCacheDirRoot() + (str + strlen(DEFAULT_CACHEDIR_ROOT_TOKEN));
+ } else {
+ getDefaultCacheDirRoot();
+ cacheDir = str;
+ }
+ return true;
+}
+
+string NbLauncher::getDefaultUserDirRoot() {
+ TCHAR defUserDirRootChar[MAX_PATH];
+ if (FAILED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, defUserDirRootChar))) {
+ return std::string();
+ }
+ defUserDirRoot = constructApplicationDir((string) defUserDirRootChar, false);
+ defUserDirRoot.erase(defUserDirRoot.rfind('\\'));
+ logMsg("Default Userdir Root: %s", defUserDirRoot.c_str());
+ return defUserDirRoot;
+}
+
+string NbLauncher::getDefaultCacheDirRoot() {
+ TCHAR defCacheDirRootChar[MAX_PATH];
+ if (FAILED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, defCacheDirRootChar))) {
+ return std::string();
+ }
+ defCacheDirRoot = constructApplicationDir((string) defCacheDirRootChar, true);
+ defCacheDirRoot.erase(defCacheDirRoot.rfind('\\'));
+ logMsg("Default Cachedir Root: %s", defCacheDirRoot.c_str());
+ return defCacheDirRoot;
+}
+
+bool NbLauncher::getOption(char *&str, const char *opt) {
+ if (strncmp(str, opt, strlen(opt)) == 0) {
+ str += strlen(opt);
+ char *end = trimWhitespaces(str);
+ if (*str == '"') {
+ str++;
+ }
+ if (end >= str && *end == '"') {
+ *end = '\0';
+ }
+ logMsg("Option found: %s%s", opt, str);
+ return true;
+ }
+ return false;
+}
+
+bool NbLauncher::parseConfigFile(const char* path) {
+ logMsg("parseConfigFile(%s)", path);
+ FILE *file = fopen(path, "r");
+ if (!file) {
+ logErr(true, false, "Cannot open file \"%s\" for reading.", path);
+ return false;
+ }
+
+ char line[4096] = "";
+ while (fgets(line, sizeof(line), file)) {
+ char *str = skipWhitespaces(line);
+ if (*str == '#') {
+ continue;
+ }
+ if (getOption(str, getDefUserDirOptName())) {
+ findUserDir(str);
+ logMsg("User dir: %s", userDir.c_str());
+ } else if (getOption(str, getDefCacheDirOptName())) {
+ findCacheDir(str);
+ logMsg("Cache dir: %s", cacheDir.c_str());
+ } else if (getOption(str, getDefOptionsOptName())) {
+ // replace \" by "
+ int len = strlen(str);
+ int k = 0;
+ for (int i = 0; i < len; i++) {
+ if (str[i] == '\\' && str[i+1] == '\"') {
+ continue;
+ }
+ str[k++] = str[i];
+ }
+ str[k] = '\0';
+ nbOptions = str;
+ logMsg("After replacement: %s", nbOptions.c_str());
+
+ } else if (getOption(str, getExtraClustersOptName())) {
+ extraClusters = str;
+ } else if (getOption(str, getJdkHomeOptName())) {
+ jdkHome = str;
+ }
+ }
+ bool ok = ferror(file) == 0;
+ if (!ok) {
+ logErr(true, false, "Error while reading file \"%s\".", path);
+ }
+ fclose(file);
+ return true;
+}
+
+typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
+
+const char * NbLauncher::getAppName() {
+ return "netbeans";
+}
+
+void NbLauncher::addSpecificOptions(CmdArgs &args) {
+ for (unsigned i = 0; i < sizeof (staticOptions) / sizeof (char*); i++) {
+ args.add(staticOptions[i]);
+ }
+}
+
+const char * NbLauncher::getDefUserDirOptName() {
+ return OPT_NB_DEFAULT_USER_DIR;
+}
+
+const char * NbLauncher::getDefCacheDirOptName() {
+ return OPT_NB_DEFAULT_CACHE_DIR;
+}
+
+
+const char * NbLauncher::getDefOptionsOptName() {
+ return OPT_NB_DEFAULT_OPTIONS;
+}
+
+const char * NbLauncher::getExtraClustersOptName() {
+ return OPT_NB_EXTRA_CLUSTERS;
+}
+
+const char * NbLauncher::getJdkHomeOptName() {
+ return OPT_NB_JDK_HOME;
+}
+
+const char * NbLauncher::getCurrentDir() {
+ return 0;
+}
+
+std::string NbLauncher::constructApplicationDir(const std::string& dir, bool cache) {
+ if (cache) {
+ return dir + NETBEANS_CACHES_DIRECTORY;
+ } else {
+ return dir + NETBEANS_DIRECTORY;
+ }
+}
diff --git a/nb/ide.launcher/windows/nblauncher.h b/nb/ide.launcher/windows/nblauncher.h
new file mode 100644
index 000000000000..469a21f4fa89
--- /dev/null
+++ b/nb/ide.launcher/windows/nblauncher.h
@@ -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.
+ */
+ /*
+ * Author: Tomas Holy
+ */
+
+#ifndef _NBLAUNCHER_H
+#define _NBLAUNCHER_H
+
+#include
+#include
+#include
+#include "cmdargs.h"
+
+class NbLauncher {
+protected:
+ static const char *NBEXEC_FILE_PATH;
+ static const char *OPT_NB_DEFAULT_USER_DIR;
+ static const char *OPT_NB_DEFAULT_CACHE_DIR;
+ static const char *OPT_NB_DEFAULT_OPTIONS;
+ static const char *OPT_NB_EXTRA_CLUSTERS;
+ static const char *OPT_NB_JDK_HOME;
+ static const char *REG_SHELL_FOLDERS_KEY;
+ static const char *HOME_TOKEN;
+ static const char *DEFAULT_USERDIR_ROOT_TOKEN;
+ static const char *DEFAULT_CACHEDIR_ROOT_TOKEN;
+ static const char *CON_ATTACH_MSG;
+ static const char *NETBEANS_DIRECTORY;
+ static const char *NETBEANS_CACHES_DIRECTORY;
+
+private:
+ static const char *ENV_USER_PROFILE;
+ static const char *REG_DESKTOP_NAME;
+ static const char *REG_DEFAULT_USERDIR_ROOT;
+ static const char *REG_DEFAULT_CACHEDIR_ROOT;
+ static const char* staticOptions[];
+
+ typedef int (*StartPlatform)(int argc, char *argv[]);
+
+public:
+ NbLauncher();
+ virtual ~NbLauncher();
+
+ int start(int argc, char *argv[]);
+ int start(char *cmdLine);
+
+protected:
+ virtual bool initBaseNames();
+ virtual void addSpecificOptions(CmdArgs &args);
+ virtual bool findUserDir(const char *str);
+ virtual bool findCacheDir(const char *str);
+ virtual const char * getAppName();
+ virtual const char * getDefUserDirOptName();
+ virtual const char * getDefCacheDirOptName();
+ virtual const char * getDefOptionsOptName();
+ virtual const char * getExtraClustersOptName();
+ virtual const char * getJdkHomeOptName();
+ virtual const char * getCurrentDir();
+ virtual std::string constructApplicationDir(const std::string& dir, bool cache);
+
+private:
+ NbLauncher(const NbLauncher& orig);
+ bool readClusterFile();
+ bool parseArgs(int argc, char *argv[]);
+ bool parseConfigFile(const char* path);
+ bool getOption(char *&str, const char *opt);
+ void addCluster(const char *cl);
+ void addExtraClusters();
+ std::string getDefaultUserDirRoot();
+ std::string getDefaultCacheDirRoot();
+
+protected:
+ std::string baseDir;
+ std::string appName;
+ std::string platformDir;
+ std::string userHome;
+ std::string userDir;
+ std::string cacheDir;
+ std::string defUserDirRoot;
+ std::string defCacheDirRoot;
+ std::string clusters;
+ std::string extraClusters;
+ std::string nbOptions;
+ std::string jdkHome;
+
+private:
+ bool customUserDirFound;
+};
+
+#endif /* _NBLAUNCHER_H */
+
diff --git a/nb/ide.launcher/windows/netbeans.cpp b/nb/ide.launcher/windows/netbeans.cpp
new file mode 100644
index 000000000000..c14972f5d3e0
--- /dev/null
+++ b/nb/ide.launcher/windows/netbeans.cpp
@@ -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.
+ */
+ /*
+ * Author: Tomas Holy
+ */
+
+
+#include "nblauncher.h"
+
+int main(int argc, char *argv[]) {
+ NbLauncher launcher;
+ return launcher.start(argc - 1, argv + 1);
+}
diff --git a/nb/ide.launcher/windows/netbeans.exe.manifest b/nb/ide.launcher/windows/netbeans.exe.manifest
new file mode 100644
index 000000000000..2dda7fb5081b
--- /dev/null
+++ b/nb/ide.launcher/windows/netbeans.exe.manifest
@@ -0,0 +1,77 @@
+
+
+
+
+
+NetBeans IDE process
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UTF-8
+
+
+
+
+
+
+ true/PM
+ PerMonitorV2, PerMonitor, system
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nb/ide.launcher/windows/netbeans.ico b/nb/ide.launcher/windows/netbeans.ico
new file mode 100644
index 000000000000..ec123c065723
Binary files /dev/null and b/nb/ide.launcher/windows/netbeans.ico differ
diff --git a/nb/ide.launcher/windows/netbeans.rc b/nb/ide.launcher/windows/netbeans.rc
new file mode 100644
index 000000000000..348a32085aba
--- /dev/null
+++ b/nb/ide.launcher/windows/netbeans.rc
@@ -0,0 +1,31 @@
+/*
+ * 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
+
+#include "version.rc"
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+
+100 ICON "netbeans.ico"
+
+// Value MANIFEST_FILE id taken from windres parameter -DMANIFEST_FILE
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST MANIFEST_FILE
+
diff --git a/nb/ide.launcher/windows/netbeans64.exe.manifest b/nb/ide.launcher/windows/netbeans64.exe.manifest
new file mode 100644
index 000000000000..b1d9a5f31d98
--- /dev/null
+++ b/nb/ide.launcher/windows/netbeans64.exe.manifest
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+NetBeans IDE process
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UTF-8
+
+
+
+
+
+ true/PM
+ PerMonitorV2, PerMonitor, system
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nb/ide.launcher/windows/version.h b/nb/ide.launcher/windows/version.h
new file mode 100644
index 000000000000..b1667b9caf7c
--- /dev/null
+++ b/nb/ide.launcher/windows/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 IDE"
+#define VER "12.5.0.0"
+#define FVER 12,5,0,0
+#define BUILD_ID "28062021"
+#define INTERNAL_NAME "netbeans"
+#define COPYRIGHT "Based on Apache NetBeans from the Apache Software Foundation and is licensed under Apache License Version 2.0"
+#define NAME "NetBeans IDE 12.5"
+
diff --git a/nb/ide.launcher/windows/version.rc b/nb/ide.launcher/windows/version.rc
new file mode 100644
index 000000000000..0bb79bf4688a
--- /dev/null
+++ b/nb/ide.launcher/windows/version.rc
@@ -0,0 +1,62 @@
+/*
+ * 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
+#include
+#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 0x1
+ 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 "ProductName", NAME "\0"
+ VALUE "ProductVersion", VER "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
diff --git a/platform/o.n.bootstrap/launcher/windows/Makefile.mingw b/platform/o.n.bootstrap/launcher/windows/Makefile.mingw
new file mode 100644
index 000000000000..0fd8e394f75c
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/Makefile.mingw
@@ -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.
+
+TMPFLD = ../../../../target/tmp/
+OFLD = ../../../../target/bootstrap/
+
+all: prepfolder nbexec64.dll nbexec64.exe nbexec.dll nbexec.exe
+
+prepfolder:
+ mkdir -p $(TMPFLD)
+ mkdir -p $(OFLD)
+
+clean:
+ rm -f *.res *.exe *.dll
+
+nbexec64.res: nbexec.rc
+ x86_64-w64-mingw32-windres -o$(TMPFLD)nbexec64.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 $(OFLD)nbexec64.dll -I include jvmlauncher.cpp nbexec.cpp platformlauncher.cpp utilsfuncs.cpp $(TMPFLD)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 -o$(TMPFLD)nbexec_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 $(TMPFLD)nbexec_exe64.res -o$(OFLD)nbexec64.exe -static -lstdc++ -static-libstdc++ -static-libgcc
+
+nbexec.res: nbexec.rc
+ i686-w64-mingw32-windres -o$(TMPFLD)nbexec.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 $(OFLD)nbexec.dll -I include jvmlauncher.cpp nbexec.cpp platformlauncher.cpp utilsfuncs.cpp $(TMPFLD)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 -o$(TMPFLD)nbexec_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 $(TMPFLD)nbexec_exe.res -o$(OFLD)nbexec.exe -static -lstdc++ -static-libstdc++ -static-libgcc
diff --git a/platform/o.n.bootstrap/launcher/windows/argnames.h b/platform/o.n.bootstrap/launcher/windows/argnames.h
new file mode 100644
index 000000000000..c4bdaba2353f
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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/platform/o.n.bootstrap/launcher/windows/include/README b/platform/o.n.bootstrap/launcher/windows/include/README
new file mode 100644
index 000000000000..7641ada3b1fd
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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/platform/o.n.bootstrap/launcher/windows/include/jni.h b/platform/o.n.bootstrap/launcher/windows/include/jni.h
new file mode 100644
index 000000000000..16cf67b457b4
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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 specification
+ * for details.
+ */
+
+#ifndef _JNI_H_
+#define _JNI_H_
+
+#include
+#include
+#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 specification
+ * 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 specification
+ * 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 specification
+ * 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 specification
+ * 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 specification
+ * for details.
+ */
+typedef struct JavaVMAttachArgs {
+ jint version;
+ char *name;
+ jobject group;
+} JavaVMAttachArgs;
+
+/**
+ * JNI Invocation Interface table for use in C sources
+ *
+ * See
+ * specification 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
+ * specification 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 specification
+ * 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 specification
+ * for details.
+ */
+_JNI_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM ** vmBuf,
+ jsize bufLen,
+ jsize * nVMs);
+
+/**
+ * Creates Java VM in the current process
+ *
+ * See specification
+ * 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/platform/o.n.bootstrap/launcher/windows/include/jni_types.h b/platform/o.n.bootstrap/launcher/windows/include/jni_types.h
new file mode 100644
index 000000000000..a809ebba8f33
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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 specification
+ * 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 specification
+ * for details.
+ */
+typedef unsigned char jboolean;
+/**
+ * Signed 8-bit primitive byte type equivalent to Java "byte" type
+ *
+ * See specification
+ * for details.
+ */
+typedef signed char jbyte;
+/**
+ * Unsigned 16-bit primitive char type equivalent to Java "char" type
+ *
+ * See specification
+ * for details.
+ */
+typedef unsigned short jchar;
+/**
+ * Signed 16-bit primitive short type equivalent to Java "short" type
+ *
+ * See specification
+ * for details.
+ */
+typedef signed short jshort;
+/**
+ * Signed 32-bit primitive integer type equivalent to Java "int" type
+ *
+ * See specification
+ * for details.
+ */
+typedef signed int jint;
+/**
+ * Signed 32-bit primitive floating point type equivalent to Java
+ * "float" type
+ *
+ * See specification
+ * for details.
+ */
+typedef float jfloat;
+/**
+ * Signed 64-bit primitive floating point type equivalent to Java
+ * "double" type
+ *
+ * See specification
+ * for details.
+ */
+typedef double jdouble;
+/**
+ * Signed 32-bit primitive integer type used to describe sizes
+ *
+ * See specification
+ * for details.
+ */
+typedef jint jsize;
+
+/*
+ * Java types
+ */
+struct _jobject;
+/**
+ * Reference type which describes a general Java object in native
+ * function
+ *
+ * See specification
+ * for details.
+ */
+typedef struct _jobject* jobject;
+/**
+ * Reference type which describes a java.lang.Class instance object in
+ * native function
+ *
+ * See specification
+ * for details.
+ */
+typedef jobject jclass;
+/**
+ * Reference type which describes a java.lang.String instance object
+ * in native function
+ *
+ * See specification
+ * for details.
+ */
+typedef jobject jstring;
+/**
+ * Reference type which describes a generic array instance object in
+ * native function
+ *
+ * See specification
+ * for details.
+ */
+typedef jobject jarray;
+/**
+ * Reference type which describes an array of java.lang.Object
+ * instances in native function
+ *
+ * See specification
+ * for details.
+ */
+ typedef jarray jobjectArray;
+/**
+ * Reference type which describes an array of booleans in native
+ * function
+ *
+ * See specification
+ * for details.
+ */
+ typedef jarray jbooleanArray;
+/**
+ * Reference type which describes an array of bytes type in native
+ * function
+ *
+ * See specification
+ * for details.
+ */
+ typedef jarray jbyteArray;
+/**
+ * Reference type which describes an array of chars type in native
+ * function
+ *
+ * See specification
+ * for details.
+ */
+ typedef jarray jcharArray;
+/**
+ * Reference type which describes an array of shorts type in native
+ * function
+ *
+ * See specification
+ * for details.
+ */
+ typedef jarray jshortArray;
+/**
+ * Reference type which describes an array of ints type in native
+ * function
+ *
+ * See specification
+ * for details.
+ */
+ typedef jarray jintArray;
+/**
+ * Reference type which describes an array of longs type in native
+ * function
+ *
+ * See specification
+ * for details.
+ */
+ typedef jarray jlongArray;
+/**
+ * Reference type which describes an array of floats type in native
+ * function
+ *
+ * See specification
+ * for details.
+ */
+ typedef jarray jfloatArray;
+/**
+ * Reference type which describes an array of doubles type in native
+ * function
+ *
+ * See specification
+ * for details.
+ */
+ typedef jarray jdoubleArray;
+/**
+ * Reference type which describes a java.lang.Throwable instance
+ * object in native function
+ *
+ * See specification
+ * 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 Call<type>MethodA
+ * and CallStatic<type>MethodA
+ * 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 ReleaseArrayElements functions
+ */
+#define JNI_COMMIT 1
+/**
+ * Constant which means that an array region should be discarded. Used
+ * in ReleaseArrayElements 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 RegisterNatives
+ * 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 specification
+ * for details. */
+typedef JNIEnv_External JNIEnv;
+#else
+/**
+ * JNI API interface table type for usage in C
+ *
+ * See specification
+ * 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 specification
+ * for details
+ */
+typedef JavaVM_External JavaVM;
+#else
+/**
+ * Java VM interface table type for usage in C
+ *
+ * See specification
+ * for details
+ */
+typedef const struct JNIInvokeInterface_ *JavaVM;
+#endif
+
+#endif /* _JNI_TYPES_H_ */
diff --git a/platform/o.n.bootstrap/launcher/windows/jvmlauncher.cpp b/platform/o.n.bootstrap/launcher/windows/jvmlauncher.cpp
new file mode 100644
index 000000000000..74bf1cc91932
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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
+
+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 &args, const list &options, bool &separateProcess, DWORD *retCode) {
+ assert(mainClassName);
+ logMsg("JvmLauncher::start()\n\tmainClassName: %s\n\tseparateProcess: %s",
+ mainClassName, separateProcess ? "true" : "false");
+ logMsg(" args:");
+ for (list::const_iterator it = args.begin(); it != args.end(); ++it) {
+ logMsg("\t%s", it->c_str());
+ }
+ logMsg(" options:");
+ for (list::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 &options) {
+ for (list::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 &args, const std::list &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 &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::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::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 &args, const std::list &options, DWORD *retCode) {
+ string cmdLine = '\"' + (suppressConsole ? javawExePath : javaExePath) + '\"';
+ cmdLine.reserve(32*1024);
+ for (list::const_iterator it = options.begin(); it != options.end(); ++it) {
+ cmdLine += " \"";
+ cmdLine += *it;
+ cmdLine += "\"";
+ }
+
+ // mainClass and args
+ cmdLine += ' ';
+ cmdLine += mainClassName;
+ for (list::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/platform/o.n.bootstrap/launcher/windows/jvmlauncher.h b/platform/o.n.bootstrap/launcher/windows/jvmlauncher.h
new file mode 100644
index 000000000000..01f4e3448c97
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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
+#include
+#include
+#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 &args, const std::list &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 &args, const std::list &options, DWORD *retCode);
+ bool startInProcJvm(const char *mainClassName, const std::list &args, const std::list &options);
+ bool isVersionString(const char *str);
+ bool canLoadJavaDll();
+ bool findClientOption(const std::list &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/platform/o.n.bootstrap/launcher/windows/nbexec.cpp b/platform/o.n.bootstrap/launcher/windows/nbexec.cpp
new file mode 100644
index 000000000000..47e490ebe465
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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/platform/o.n.bootstrap/launcher/windows/nbexec.exe.manifest b/platform/o.n.bootstrap/launcher/windows/nbexec.exe.manifest
new file mode 100644
index 000000000000..580bb41e424e
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/nbexec.exe.manifest
@@ -0,0 +1,75 @@
+
+
+
+
+
+nbexec process
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ UTF-8
+
+
+
+
+
+ true/PM
+ PerMonitorV2, PerMonitor, system
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/o.n.bootstrap/launcher/windows/nbexec.rc b/platform/o.n.bootstrap/launcher/windows/nbexec.rc
new file mode 100644
index 000000000000..b0843afe3b43
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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
+
+#define FNAME "nbexec.dll"
+#define FILETYPE_ID 0x2L
+
+#include "version.rc"
+
diff --git a/platform/o.n.bootstrap/launcher/windows/nbexec_exe.rc b/platform/o.n.bootstrap/launcher/windows/nbexec_exe.rc
new file mode 100644
index 000000000000..df75c0b3bd69
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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
+
+#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/platform/o.n.bootstrap/launcher/windows/nbexecexe.cpp b/platform/o.n.bootstrap/launcher/windows/nbexecexe.cpp
new file mode 100644
index 000000000000..181a365d1fb4
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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
+#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/platform/o.n.bootstrap/launcher/windows/nbexecloader.h b/platform/o.n.bootstrap/launcher/windows/nbexecloader.h
new file mode 100644
index 000000000000..221a55764c74
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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/platform/o.n.bootstrap/launcher/windows/platformlauncher.cpp b/platform/o.n.bootstrap/launcher/windows/platformlauncher.cpp
new file mode 100644
index 000000000000..76fc6fc204f7
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/platformlauncher.cpp
@@ -0,0 +1,735 @@
+/*
+ * 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 to JDK\n\
+ -J pass to JVM\n\
+\n\
+ --cp:p prepend to classpath\n\
+ --cp:a append to classpath\n\
+\n\
+ --fork-java run java in separate process\n\
+ --trace 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_JAVA_SECURITY_MANAGER_ALLOW = "-Djava.security.manager=allow";
+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);
+
+ option = OPT_JAVA_SECURITY_MANAGER_ALLOW;
+ 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/platform/o.n.bootstrap/launcher/windows/platformlauncher.h b/platform/o.n.bootstrap/launcher/windows/platformlauncher.h
new file mode 100644
index 000000000000..ac3e7be4b706
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/platformlauncher.h
@@ -0,0 +1,112 @@
+/*
+ * 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
+#include
+#include
+
+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_JAVA_SECURITY_MANAGER_ALLOW;
+ 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 javaOptions;
+ std::list launcherOptions;
+ std::list progArgs;
+ JvmLauncher jvmLauncher;
+ std::set addedToCP;
+ std::string classPath;
+ std::string appendHelp;
+};
+
+#endif /* _PLATFORMLAUNCHER_H */
+
diff --git a/platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp b/platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp
new file mode 100644
index 000000000000..16c6ce07d81d
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/utilsfuncs.cpp
@@ -0,0 +1,464 @@
+/*
+ * 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
+#include
+
+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;
+}
+
+void setConsoleCodepage() {
+ /* The Windows console (cmd) has its own code page setting that's usually different from the
+ system and user code page, e.g. on US Windows the console will use code page 437 while the
+ rest of the system uses 1252. Setting the console code page here to UTF-8 makes Unicode
+ characters printed from the application appear correctly. Since the launcher itself also runs
+ with UTF-8 as its code page (specified in the application manifest), this also makes log
+ messages from the launchers appear correctly, e.g. when printing paths that may have Unicode
+ characters in them. Note that if we attached to an existing console, the modified code page
+ setting will persist after the launcher exits. */
+ SetConsoleOutputCP(CP_UTF8);
+ SetConsoleCP(CP_UTF8);
+}
+
+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();
+ setConsoleCodepage();
+ } 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);
+ setConsoleCodepage();
+ 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/platform/o.n.bootstrap/launcher/windows/utilsfuncs.h b/platform/o.n.bootstrap/launcher/windows/utilsfuncs.h
new file mode 100644
index 000000000000..6cf172a24db5
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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
+#include
+
+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/platform/o.n.bootstrap/launcher/windows/version.h b/platform/o.n.bootstrap/launcher/windows/version.h
new file mode 100644
index 000000000000..26b4461403ba
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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 "12.5.0.0"
+#define FVER 12,5,0,0
+#define BUILD_ID "28062021"
+#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/platform/o.n.bootstrap/launcher/windows/version.rc b/platform/o.n.bootstrap/launcher/windows/version.rc
new file mode 100644
index 000000000000..7a516a4c5876
--- /dev/null
+++ b/platform/o.n.bootstrap/launcher/windows/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
+#include
+#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