Merge pull request #2 from ebarboni/initcommit
Initial commit preserving history
diff --git a/src/main/cpp/build.properties b/src/main/cpp/build.properties
new file mode 100644
index 0000000..5959d93
--- /dev/null
+++ b/src/main/cpp/build.properties
@@ -0,0 +1,68 @@
+#
+# 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.
+#
+
+#ignore.native=
+
+native.dist.dir=dist
+
+native.jnilib.dir=jnilib
+native.launcher.dir=launcher
+native.cleaner.dir=cleaner
+
+# Native Library properties
+native.jnilib.dir.windows=${native.jnilib.dir}/windows
+native.jnilib.dir.linux=${native.jnilib.dir}/linux
+native.jnilib.dir.solaris-x86=${native.jnilib.dir}/solaris-x86
+native.jnilib.dir.solaris-sparc=${native.jnilib.dir}/solaris-sparc
+native.jnilib.dir.macosx=${native.jnilib.dir}/macosx
+
+native.jnilib.file.windows.i386=windows-x86.dll
+native.jnilib.file.windows.amd64=windows-x64.dll
+native.jnilib.file.windows.ia64=windows-ia64.dll
+native.jnilib.file.linux.i386=linux.so
+native.jnilib.file.linux.amd64=linux-amd64.so
+native.jnilib.file.solaris-x86=solaris-x86.so
+native.jnilib.file.solaris-sparc=solaris-sparc.so
+native.jnilib.file.solaris-amd64=solaris-amd64.so
+native.jnilib.file.solaris-sparcv9=solaris-sparcv9.so
+native.jnilib.file.macosx=macosx.dylib
+
+
+# Native Launcher Properties
+native.launcher.windows.dir=${native.launcher.dir}/windows
+native.launcher.windows.stub.file=nlw.exe
+native.launcher.windows.stub.src=${native.launcher.windows.dir}/dist/${native.launcher.windows.stub.file}
+native.launcher.windows.stub.dst.dir=${native.launcher.windows.dir}
+native.launcher.windows.i18n.dir=${native.launcher.windows.dir}/i18n
+
+native.launcher.unix.dir=${native.launcher.dir}/unix
+native.launcher.unix.stub.file=launcher.sh
+native.launcher.unix.stub.src=${native.launcher.unix.dir}/src/${native.launcher.unix.stub.file}
+native.launcher.unix.stub.dst.dir=${native.launcher.unix.dir}
+native.launcher.unix.i18n.dir=${native.launcher.unix.dir}/i18n
+
+
+# Native on-exit cleaner properties
+native.cleaner.windows.dir=${native.cleaner.dir}/windows
+native.cleaner.windows.srcdir=${native.cleaner.windows.dir}/dist
+native.cleaner.windows.file=cleaner.exe
+
+native.cleaner.unix.dir=${native.cleaner.dir}/unix
+native.cleaner.unix.srcdir=${native.cleaner.unix.dir}/src
+native.cleaner.unix.file=cleaner.sh
diff --git a/src/main/cpp/build.xml b/src/main/cpp/build.xml
new file mode 100644
index 0000000..58c97a6
--- /dev/null
+++ b/src/main/cpp/build.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project name="native" default="default" basedir=".">
+ <property file="build.properties"/>
+
+ <!-- =======================================================================
+ NetBeans Installer engine specific targets
+ ======================================================================== -->
+
+ <!-- =======================================================================
+ Build native library
+ ======================================================================== -->
+ <target name="jnilib-init" depends="define-platform,init-platform"/>
+ <target name="jnilib-clean" depends="jnilib-init" unless="ignore.native">
+ <exec executable="make" dir="${jnilib.dir}">
+ <arg value="clean"/>
+ </exec>
+ </target>
+
+ <target name="jnilib-compile" depends="jnilib-init,jnilib-clean" unless="ignore.native">
+ <exec executable="make" dir="${jnilib.dir}">
+ <arg value="build"/>
+ </exec>
+ </target>
+ <target name="jnilib-build" depends="jnilib-init,jnilib-compile"/>
+
+ <!-- =======================================================================
+ Build launcher
+ ======================================================================== -->
+ <target name="launcher-init" depends="define-platform,init-platform"/>
+ <target name="launcher-clean" depends="launcher-init" unless="ignore.native">
+ <exec executable="make" dir="${launcher.dir}">
+ <arg value="clean"/>
+ </exec>
+ </target>
+
+ <target name="launcher-compile" depends="launcher-init,launcher-clean" if="is.windows" unless="ignore.native">
+ <exec executable="make" dir="${launcher.dir}">
+ <arg value="build"/>
+ </exec>
+ </target>
+ <target name="launcher-build" depends="launcher-init,launcher-compile"/>
+
+
+
+<!-- =======================================================================
+ Build cleaner
+ ======================================================================== -->
+ <target name="cleaner-init" depends="define-platform,init-platform"/>
+ <target name="cleaner-clean" depends="cleaner-init" unless="ignore.native">
+ <exec executable="make" dir="${cleaner.dir}">
+ <arg value="clean"/>
+ </exec>
+ </target>
+
+ <target name="cleaner-compile" depends="cleaner-init,cleaner-clean" if="is.windows" unless="ignore.native">
+ <exec executable="make" dir="${cleaner.dir}">
+ <arg value="build"/>
+ </exec>
+ </target>
+ <target name="cleaner-build" depends="cleaner-init,cleaner-compile"/>
+
+
+<!-- =======================================================================
+ Build all native resources
+ ======================================================================== -->
+
+ <target name="native-clean" depends="jnilib-clean,launcher-clean,cleaner-clean"/>
+ <target name="native-compile" depends="jnilib-compile,launcher-compile,cleaner-compile"/>
+ <target name="native-build" depends="jnilib-build,launcher-build,cleaner-build"/>
+
+ <target name="define-platform">
+ <condition property="is.windows">
+ <os family="windows"/>
+ </condition>
+ <condition property="is.linux">
+ <os name="Linux"/>
+ </condition>
+ <condition property="is.solaris-x86">
+ <os name="SunOS" arch="x86"/>
+ </condition>
+ <condition property="is.solaris-sparc">
+ <os name="SunOS" arch="sparc"/>
+ </condition>
+ <condition property="is.macosx">
+ <and>
+ <os family="mac"/>
+ <os family="unix"/>
+ </and>
+ </condition>
+ </target>
+
+ <target name="init-platform" depends="init-windows,init-linux,init-solaris-x86,init-solaris-sparc,init-macosx"/>
+
+ <target name="init-windows" if="is.windows">
+ <property name="jnilib.dir" value="${native.jnilib.dir.windows}"/>
+ <property name="jnilib.file" value="${native.jnilib.file.windows}"/>
+ <property name="launcher.dir" value="${native.launcher.windows.dir}"/>
+ <property name="cleaner.dir" value="${native.cleaner.windows.dir}"/>
+ </target>
+ <target name="init-linux" if="is.linux">
+ <property name="jnilib.dir" value="${native.jnilib.dir.linux}"/>
+ <property name="jnilib.file" value="${native.jnilib.file.linux}"/>
+ <property name="launcher.dir" value="${native.launcher.unix.dir}"/>
+ <property name="cleaner.dir" value="${native.cleaner.unix.dir}"/>
+ </target>
+ <target name="init-solaris-x86" if="is.solaris-x86">
+ <property name="jnilib.dir" value="${native.jnilib.dir.solaris-x86}"/>
+ <property name="jnilib.file" value="${native.jnilib.file.solaris-x86}"/>
+ <property name="launcher.dir" value="${native.launcher.unix.dir}"/>
+ <property name="cleaner.dir" value="${native.cleaner.unix.dir}"/>
+ </target>
+ <target name="init-solaris-sparc" if="is.solaris-sparc">
+ <property name="jnilib.dir" value="${native.jnilib.dir.solaris-sparc}"/>
+ <property name="jnilib.file" value="${native.jnilib.file.solaris-sparc}"/>
+ <property name="launcher.dir" value="${native.launcher.unix.dir}"/>
+ <property name="cleaner.dir" value="${native.cleaner.unix.dir}"/>
+ </target>
+ <target name="init-macosx" if="is.macosx">
+ <property name="jnilib.dir" value="${native.jnilib.dir.macosx}"/>
+ <property name="jnilib.file" value="${native.jnilib.file.macosx}"/>
+ <property name="launcher.dir" value="${native.launcher.unix.dir}"/>
+ <property name="cleaner.dir" value="${native.cleaner.unix.dir}"/>
+ </target>
+
+</project>
diff --git a/src/main/cpp/cleaner/unix/src/cleaner.sh b/src/main/cpp/cleaner/unix/src/cleaner.sh
new file mode 100644
index 0000000..cfae216
--- /dev/null
+++ b/src/main/cpp/cleaner/unix/src/cleaner.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+#
+# 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.
+#
+
+deleteFiles() {
+ testSymlinkErr=`test -L / > /dev/null`
+ if [ -z "$testSymlinkErr" ] ; then
+ isSymlink=-L
+ else
+ isSymlink=-h
+ fi
+
+ #wait for main thread to finish...
+ sleep 3
+ waitOnError=1
+ tryTimes=3
+ list="$1"
+ if [ -n "$list" ] && [ -f "$list" ] ; then
+ #echo "Using list file : $list"
+ itemsNumber=`wc -l $list | sed "s/^\ *//;s/\ .*//" 2>/dev/null`
+ #echo "Total items : $itemsNumber"
+ counter=1
+ try=$tryTimes
+ allitems=`cat "$list" 2>/dev/null`
+ if [ -f "$list" ] ; then
+ #echo "... remove cleaner list $list"
+ rm -f "$list"
+ fi
+ while [ $counter -le $itemsNumber ] ; do
+ file=`echo "$allitems" | sed -n "${counter}p" 2>/dev/null`
+ #echo "entry : $file"
+ result=1
+ if [ -n "$file" ] ; then
+ #echo "... file not zero"
+ if [ $isSymlink "$file" ] || [ -f "$file" ] ; then
+ # file or symlink
+ #echo "deleting [F] $file"
+ rm -f "$file" 2>/dev/null 1>&2
+ if [ $? -ne 0 ] ; then
+ #echo "... can't delete $file"
+ result=0
+ fi
+ elif [ -d "$file" ] ; then
+ # directory
+ #echo "deleting [D] $file"
+ rmdir "$file" 2>/dev/null 1>&2
+ if [ $? -ne 0 ] ; then
+ result=0
+ #echo "... can't delete $file"
+ fi
+ fi
+ fi
+ if [ 0 -eq $result ] ; then
+ # try to remove it again after a short wait
+ if [ $try -gt 0 ] ; then
+ try=`expr "$try" - 1`
+ sleep $waitOnError
+ else
+ #can`t delete.. skip it
+ result=1
+ fi
+
+ fi
+ if [ 1 -eq $result ] ; then
+ counter=`expr "$counter" + 1`
+ try=$tryTimes
+ fi
+ done
+ fi
+ if [ -f "$0" ] ; then
+ #echo "... remove cleaner itself $0"
+ rm -f "$0"
+ fi
+}
+
+deleteFiles "$@"
diff --git a/src/main/cpp/cleaner/windows/Makefile b/src/main/cpp/cleaner/windows/Makefile
new file mode 100644
index 0000000..98cf53c
--- /dev/null
+++ b/src/main/cpp/cleaner/windows/Makefile
@@ -0,0 +1,79 @@
+#
+# 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.
+#
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+RANLIB=ranlib
+
+
+# build
+build: .build-pre .build-impl .build-post
+
+.build-pre:
+# Add your pre 'build' code here...
+
+.build-post:
+# Add your post 'build' code here...
+
+
+# clean
+clean: .clean-pre .clean-impl .clean-post
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post:
+# Add your post 'clean' code here...
+
+
+# clobber
+clobber: .clobber-pre .clobber-impl .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post:
+# Add your post 'clobber' code here...
+
+
+# all
+all: .all-pre .all-impl .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post:
+# Add your post 'all' code here...
+
+
+# help
+help: .help-pre .help-impl .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post:
+# Add your post 'help' code here...
+
+
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
diff --git a/src/main/cpp/cleaner/windows/Makefile-vc b/src/main/cpp/cleaner/windows/Makefile-vc
new file mode 100644
index 0000000..b9edda9
--- /dev/null
+++ b/src/main/cpp/cleaner/windows/Makefile-vc
@@ -0,0 +1,59 @@
+#
+#
+
+
+!include <$(PLATFORM_SDK)/include/win32.mak>
+
+# define the compiler and linker for all the platforms
+CC32="$(VC_2005)\Bin\cl.exe"
+L32="$(VC_2005)\Bin\link.exe"
+
+BUILD_DIR32=.\build\32bit
+OUTPUT_FILE32=.\dist\cleaner.exe
+
+CC32_OPTS=/O1 /Os \
+ /I "$(VC_2005)\include" \
+ /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_CRT_SECURE_NO_DEPRECATE" \
+ /FD /GS-\
+ /Fo"$(BUILD_DIR32)\\" /Fd"$(BUILD_DIR32)\vc80.pdb" \
+ /W3 /nologo /c /Wp64 /TC /errorReport:prompt
+
+LINKING_LIBRARIES=\
+ shell32.lib \
+ kernel32.lib
+
+L32_OPTS=\
+ /OUT:$(OUTPUT_FILE32) \
+ /INCREMENTAL:NO \
+ /LIBPATH:"$(PLATFORM_SDK)\Lib" \
+ /MANIFEST:NO \
+ /NODEFAULTLIB \
+ /SUBSYSTEM:WINDOWS \
+ /OPT:REF /OPT:ICF \
+ /MACHINE:X86 \
+ /ERRORREPORT:PROMPT \
+ /ENTRY:WinMain \
+ $(LINKING_LIBRARIES)
+
+all: init build-32
+
+clean:
+
+
+init:
+ - md $(BUILD_DIR32)
+ - md .\dist
+
+ del /Q /S $(BUILD_DIR32)
+ del /Q $(OUTPUT_FILE32)
+
+build-32:
+ Set CPU=i386
+ Set Lib=%VC_2005%\Lib;%PLATFORM_SDK%\Lib;%Lib%
+ Set Include=%PLATFORM_SDK%\Include;%Include%
+ Set Path=%PLATFORM_SDK%\Bin;%PLATFORM_SDK%\Bin\WinNT;%VC_2005_PATH%;%path%
+ Set APPVER=5.01
+ Set TARGETOS=WINNT
+
+ $(CC32) $(CC32_OPTS) .\src\main.c
+ $(L32) $(L32_OPTS) $(BUILD_DIR32)\main.obj
diff --git a/src/main/cpp/cleaner/windows/nbproject/configurations.xml b/src/main/cpp/cleaner/windows/nbproject/configurations.xml
new file mode 100644
index 0000000..b16b628
--- /dev/null
+++ b/src/main/cpp/cleaner/windows/nbproject/configurations.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<configurationDescriptor version="35">
+ <logicalFolder name="root" displayName="root" projectFiles="true">
+ <logicalFolder name="SourceFiles"
+ displayName="Source Files"
+ projectFiles="true">
+ <itemPath>src/main.c</itemPath>
+ </logicalFolder>
+ <logicalFolder name="HeaderFiles"
+ displayName="Header Files"
+ projectFiles="true">
+ </logicalFolder>
+ <logicalFolder name="ResourceFiles"
+ displayName="Resource Files"
+ projectFiles="true">
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ </logicalFolder>
+ <projectmakefile>Makefile</projectmakefile>
+ <defaultConf>0</defaultConf>
+ <confs>
+ <conf name="Debug" type="1">
+ <toolsSet>
+ <compilerSet>Cygwin</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>3</platform>
+ </toolsSet>
+ <compileType>
+ <linkerTool>
+ <output>dist/cleaner</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerLibItems>
+ <linkerOptionItem>-lshell32 -lkernel32</linkerOptionItem>
+ </linkerLibItems>
+ <commandLine>-mno-cygwin -mwindows</commandLine>
+ </linkerTool>
+ </compileType>
+ <item path="src/main.c">
+ <itemTool>0</itemTool>
+ </item>
+ </conf>
+ <conf name="Release" type="1">
+ <toolsSet>
+ <compilerSet>Cygwin</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>3</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>5</developmentMode>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>5</developmentMode>
+ </ccCompilerTool>
+ <fortranCompilerTool>
+ <developmentMode>5</developmentMode>
+ </fortranCompilerTool>
+ <linkerTool>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="src/main.c">
+ <itemTool>0</itemTool>
+ </item>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/src/main/cpp/cleaner/windows/nbproject/project.properties b/src/main/cpp/cleaner/windows/nbproject/project.properties
new file mode 100644
index 0000000..3807b67
--- /dev/null
+++ b/src/main/cpp/cleaner/windows/nbproject/project.properties
@@ -0,0 +1,20 @@
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
diff --git a/src/main/cpp/cleaner/windows/nbproject/project.xml b/src/main/cpp/cleaner/windows/nbproject/project.xml
new file mode 100644
index 0000000..ded3e3c
--- /dev/null
+++ b/src/main/cpp/cleaner/windows/nbproject/project.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.cnd.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>NBI Native Cleaner : Windows</name>
+ <make-project-type>0</make-project-type>
+ </data>
+ </configuration>
+</project>
diff --git a/src/main/cpp/cleaner/windows/src/main.c b/src/main/cpp/cleaner/windows/src/main.c
new file mode 100644
index 0000000..43271ff
--- /dev/null
+++ b/src/main/cpp/cleaner/windows/src/main.c
@@ -0,0 +1,482 @@
+/*
+ * 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 <windows.h>
+#include <wchar.h>
+
+
+/*
+ * cleaner.exe
+ *
+ * Deletes a list of files/folders.
+ *
+ * The command line syntax is:
+ *
+ * arg1: File name containing a list of files/folders to delete.
+ *
+ * Requirements for arg1:
+ * - The arg1 file name MUST be fully qualified. (or be in the same directory
+ * as the cleaner.exe executable)
+ * - The file MUST use Windows line ending (CRLF)
+ * - The file MUST be encoded in UTF-16. The NBI Engine will produce
+ * this file in Java charset "UNICODE" which effectively means
+ * UCS-2 BigEndian BOM. Such file will work just fine.
+ * - Each line in the file is expected to contain a fully qualified file
+ * or folder name. The entry can be
+ * - a local file/folder name, e.g. "C:\foo\bar", up to a maximum of 32767
+ * chars and thus not subject to the original Windows limitation
+ * of 260 chars for a path name.
+ * - a UNC, e.g. "\\servername\sharename\foo\bar", subject to a
+ * restriction of 260 chars.
+ * - The list MUST be ordered so that the files in a folder are listed before
+ * the folder itself. (it is not possible to delete a non-empty folder)
+ *
+ * Method of working:
+ *
+ * 1. After launch the content of command line arg1 is read into memory
+ * as one big string.
+ * 2. The string is chopped into a list by separating at the LINE_SEPARATOR.
+ * 3. Sleep for 2 seconds to allow the launching process (the JVM) to exit.
+ * 4. Loop over the list of files/folder to delete. Each file-delete operation
+ * is spawned into a thread of its own up to a maximum of 64 threads.
+ * Therefore the delete operations happens in parallel rather than in sequence.
+ * If 64 threads have been spawned then wait for a thread to exit before
+ * spawning a new one. (therefore never more than 64 threads)
+ * For each file delete operation do the following:
+ * - Check to see if the file exists (by getting its attributes)
+ * - If file: delete file, if directory: delete directory (these are two
+ * different calls in the Win32 API).
+ * - Attempt to delete each file/dir up to 15 times sleeping for 200 ms
+ * between each attempt.
+ * 5. Wait for all file-delete threads to exit.
+ * 6. Delete self, i.e. the "cleaner.exe" executable.
+ * 7. End
+ *
+ * The arg1 file is not deleted. However it can be part of the list itself
+ * if need be.
+ *
+ * Author: Dmitry Lipin, 2007
+ *
+ *
+ *
+ * Changes after transition to Apache:
+ *
+ * 14-SEP-2019 Lars Bruun-Hansen (lbruun@apache.org) :
+ * Function comment headers added.
+ * Main comment header added.
+ *
+ */
+
+
+// Retry functionality:
+// SLEEP_DELAY : millis between each attempt at a file delete
+// MAX_ATTEMPTS : how many times to attempt to delete a file
+const DWORD SLEEP_DELAY = 200;
+const DWORD MAX_ATTEMPTS = 15;
+const DWORD THREAD_FINISHED = 100;
+
+// Number of milliseconds to sleep at launch of the application.
+const DWORD INITIAL_DELAY = 2000; // 2 seconds seems to be enough to finish java process
+
+const WCHAR * LINE_SEPARATOR = L"\r\n";
+const WCHAR * UNC_PREFIX = L"\\\\?\\"; // Prefix for extended-length path in Win32 API
+const WCHAR * UNC_STD_PREFIX = L"\\\\"; // Prefix for UNC paths, for example: \\servername\share\foo\bar
+const DWORD UNC_PREFIX_LENGTH = 4;
+
+#ifdef _MSC_VER
+#define ZERO(x,y) SecureZeroMemory((x),(y));
+#else
+#define ZERO(x,y) ZeroMemory((x),(y));
+#endif
+
+
+/*
+ * Search for the first occurrence of wcs2 within wcs1.
+ * Returns a pointer to the first occurrence if found.
+ * If not found, NULL is returned.
+ */
+WCHAR * search( const WCHAR * wcs1, const WCHAR * wcs2) {
+ WCHAR *cp = (WCHAR *) wcs1;
+ WCHAR *s1, *s2;
+
+ if ( !*wcs2) {
+ return (WCHAR *)wcs1;
+ }
+
+ while (*cp) {
+ s1 = cp;
+ s2 = (WCHAR *) wcs2;
+
+ while ( *s1 && *s2 && !(*s1-*s2) ) {
+ s1++, s2++;
+ }
+ if (!*s2) {
+ return(cp);
+ }
+ cp++;
+ }
+ return(NULL);
+}
+
+
+typedef struct _list {
+ WCHAR * item;
+ struct _list * next;
+} LIST;
+
+
+WCHAR * toWCHAR(char * charBuffer, DWORD size) {
+ DWORD i=0;
+ WCHAR * buffer;
+ BOOL hasBOM = (*charBuffer == '\xFF' && *(charBuffer+1) == '\xFE');
+ BOOL hasReverseBOM = (*charBuffer == '\xFE' && *(charBuffer+1) == '\xFF');
+
+ char * realStringPtr = charBuffer;
+ if (hasBOM || hasReverseBOM) {
+ size-= 2;
+ realStringPtr+= 2;
+ if(hasReverseBOM) {
+ char c;
+ for (i = 0 ; i < size/2 ; i++) {
+ c = charBuffer [2 * i] ;
+ charBuffer [2 * i] = charBuffer [2 * i + 1] ;
+ charBuffer [2 * i + 1] = c;
+ }
+ }
+ }
+
+ buffer = (WCHAR*) LocalAlloc(LPTR, sizeof(WCHAR) * (size/2+1));
+ ZERO(buffer, sizeof(WCHAR) * (size/2+1));
+ for(i=0;i<size/2;i++) {
+ realStringPtr[2*i] = (realStringPtr[2*i]) & 0xFF;
+ realStringPtr[2*i+1] = (realStringPtr[2*i+1])& 0xFF;
+ buffer [i] = ((unsigned char)realStringPtr[2*i]) + (((unsigned char)realStringPtr[2*i+1]) << 8);
+ }
+
+ return buffer;
+}
+
+/*
+ * Gets the number of lines in the input.
+ * (lines are expected to be separated by LINE_SEPARATOR)
+ */
+DWORD getLinesNumber(WCHAR *str) {
+ DWORD result = 0;
+ WCHAR *ptr = str;
+ WCHAR *ptr2 = str;
+ DWORD sepLength = lstrlenW(LINE_SEPARATOR);
+ if(ptr!=NULL) {
+ while((ptr2 = search(ptr, LINE_SEPARATOR))!=NULL) {
+ ptr = ptr2 + sepLength;
+ result++;
+
+ if(ptr==NULL) break;
+ }
+ if(ptr!=NULL && lstrlenW(ptr) > 0) {
+ result ++;
+ }
+ }
+ return result;
+}
+
+/*
+ * Produces a string array, 'list', from 'str' by splitting the string
+ * at each occurrence of LINE_SEPARATOR.
+ *
+ * [IN] str: the input
+ * [OUT] list: string array
+ * [OUT] number: number of elements in 'list'
+ *
+ */
+void getLines(WCHAR *str, WCHAR *** list, DWORD * number) {
+ WCHAR *ptr = str;
+ WCHAR *ptr2 = NULL;
+ DWORD length = 0;
+ DWORD sepLength = lstrlenW(LINE_SEPARATOR);
+ DWORD counter = 0;
+ *number = getLinesNumber(str);
+ *list = (WCHAR**) LocalAlloc(LPTR, sizeof(WCHAR*) * (*number));
+
+ if(ptr!=NULL) {
+ while(counter < (*number)) {
+ DWORD i = 0 ;
+ if((ptr2 = search(ptr, LINE_SEPARATOR))!=NULL) {
+ ptr2 = search(ptr, LINE_SEPARATOR) + sepLength;
+ length = lstrlenW(ptr) - lstrlenW(ptr2) - sepLength;
+ (*list) [counter ] = (WCHAR*) LocalAlloc(LPTR, sizeof(WCHAR*)*(length+1));
+ ZERO((*list) [counter ], sizeof(WCHAR*)*(length+1));
+ for(i=0;i<length;i++) {
+ (*list) [counter ][i]=ptr[i];
+ }
+ ptr = ptr2;
+ } else if((length = lstrlenW(ptr)) > 0) {
+ (*list)[counter ] = (WCHAR*) LocalAlloc(LPTR, sizeof(WCHAR*)*(length+1));
+ ZERO((*list) [counter ], sizeof(WCHAR*)*(length+1));
+ for(i=0;i<length;i++) {
+ (*list) [counter ][i]=ptr[i];
+ }
+ ptr = NULL;
+ }
+ counter++;
+ if(ptr==NULL) break;
+ }
+ }
+}
+
+/*
+ * Read file into memory.
+ */
+void readStringList(HANDLE fileHandle, WCHAR *** list, DWORD *number) {
+ DWORD size = GetFileSize(fileHandle, NULL); // hope it much less than 2GB
+ DWORD read = 0;
+ char * charBuffer = (char*) LocalAlloc(LPTR, sizeof(char) * (size + 2));
+ ZERO(charBuffer, sizeof(char) * (size + 2));
+
+ if(ReadFile(fileHandle, charBuffer, size, &read, 0) && read >=2) {
+ WCHAR * buffer = toWCHAR(charBuffer, size + 2);
+ getLines(buffer, list, number);
+ LocalFree(buffer);
+ }
+ LocalFree(charBuffer);
+}
+
+void deleteFile(WCHAR * filePath) {
+ BOOL canDelete = TRUE;
+ DWORD count = 0 ;
+ WIN32_FILE_ATTRIBUTE_DATA attrs;
+ DWORD filePathLength = lstrlenW(filePath);
+ DWORD prefixLength = (filePath == search(filePath, UNC_STD_PREFIX)) ? 0 : UNC_PREFIX_LENGTH;
+ DWORD length = filePathLength + prefixLength + 1;
+ WCHAR * file = (WCHAR*) LocalAlloc(LPTR, sizeof(WCHAR) * length);
+ DWORD i=0;
+ for(i=0;i<prefixLength;i++) {
+ file[i]=UNC_PREFIX[i];
+ }
+ for(i=0;i<filePathLength;i++) {
+ file[i+prefixLength] = filePath[i];
+ }
+
+ // Implementation note:
+ // GetFileAttributesExW() is used not only to get file attributes
+ // but also as a way to check if the file/dir (still) exist.
+
+ if(GetFileAttributesExW(file, GetFileExInfoStandard, &attrs)) {
+ if (attrs.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { // if read-only attrib is set
+ if (SetFileAttributesW(file, FILE_ATTRIBUTE_NORMAL) == 0) { // remove read-only attrib
+ // The read-only attrib could not be deleted. No point in continuing.
+ canDelete = FALSE;
+ }
+ }
+ if (canDelete) {
+ if (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ while ((!RemoveDirectoryW(file) || GetFileAttributesExW(file, GetFileExInfoStandard, &attrs)) &&
+ ((count++) < MAX_ATTEMPTS)) {
+ Sleep(SLEEP_DELAY);
+ }
+ } else {
+ while ((!DeleteFileW(file) || GetFileAttributesExW(file, GetFileExInfoStandard, &attrs)) &&
+ ((count++) < MAX_ATTEMPTS)) {
+ Sleep(SLEEP_DELAY);
+ }
+ }
+ }
+ }
+ LocalFree(file);
+}
+
+DWORD WINAPI deleteFileThread(void * ptr) {
+ WCHAR * file = (WCHAR*) ptr;
+ deleteFile(file);
+ return THREAD_FINISHED;
+}
+
+void getFreeIndexForNextThread(HANDLE * list, DWORD max, DWORD * counter) {
+ DWORD code = 0;
+ DWORD maxReached = 0;
+
+ while(1) {
+ if((*counter)==max) {
+ maxReached = 1;
+ *counter = 0;
+ }
+ code = 0;
+ if(list[*counter]==INVALID_HANDLE_VALUE) {
+ break;
+ } else if(GetExitCodeThread(list[*counter], &code)!=0 && code==THREAD_FINISHED) {
+ break;
+ } else {
+ *counter = (*counter) + 1;
+ if((*counter)==max && maxReached == 1) {
+ *counter = WaitForMultipleObjects(max, list, FALSE, INFINITE) - WAIT_OBJECT_0;
+ }
+ }
+ }
+}
+
+/*
+ * Deletes the the current executable. This is done by spawning a small
+ * .bat file which does the job. The .bat file even deletes itself when
+ * finished.
+ */
+#define BUFSIZE 512
+void removeItselfUsingCmd() {
+ char * currentFile = LocalAlloc(LPTR, sizeof(char) * BUFSIZE);
+ if (GetModuleFileNameA(0, currentFile, MAX_PATH)) {
+ char * tempFile = LocalAlloc(LPTR, sizeof(char) * BUFSIZE);
+ HANDLE hTempFile;
+ int index = 0;
+ int i = 0;
+ char cleanerSuffix [] = ".bat";
+ for( i = 0; i < (lstrlenA(currentFile) - lstrlenA(cleanerSuffix)); i++) {
+ tempFile[index++] = currentFile[i];
+ }
+ for(i=0;i<lstrlenA(cleanerSuffix);i++) {
+ tempFile[index++] = cleanerSuffix[i];
+ }
+ hTempFile = CreateFileA(tempFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hTempFile != INVALID_HANDLE_VALUE) {
+ char * command = LocalAlloc(LPTR, sizeof(char) * (lstrlenA(tempFile) + lstrlenA(currentFile) + 6));
+ DWORD bytesNumber = 0 ;
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ char * strings [4] = {
+ ":Repeat\n",
+ "del %1\n",
+ "if exist %1 goto Repeat\n",
+ "del %0\n",
+ };
+ for(i=0;i<4;i++) {
+ WriteFile(hTempFile, strings[i], lstrlenA(strings[i]), &bytesNumber, NULL);
+ }
+
+ CloseHandle(hTempFile);
+
+ ZERO( &si, sizeof(si) );
+ si.cb = sizeof(si);
+ ZERO( &pi, sizeof(pi) );
+ index=0;
+ command [index++]= '"';
+ for(i=0;i<lstrlenA(tempFile);i++) {
+ command [index++] = tempFile[i];
+ }
+ command[index++]= '"';
+ command[index++]= ' ';
+ command[index++]= '"';
+ for(i=0;i<lstrlenA(currentFile);i++) {
+ command [index++] = currentFile[i];
+ }
+ command[index++]= '"';
+ command[index++]= 0;
+
+ CreateProcess(0, command, 0, 0, FALSE, CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS, 0, 0, &si, &pi);
+ LocalFree(command);
+ CloseHandle( pi.hProcess );
+ CloseHandle( pi.hThread );
+ }
+ LocalFree(tempFile);
+ }
+ LocalFree(currentFile);
+
+}
+
+/*
+ * Changes directory to the directory where the currently executing
+ * executable is located.
+ */
+void changeCurrentDirectory() {
+ WCHAR * currentFile = LocalAlloc(LPTR, sizeof(WCHAR) * MAX_PATH);
+ if (GetModuleFileNameW(0, currentFile, MAX_PATH)) {
+ WCHAR * ptr = currentFile;
+ DWORD i=0;
+ DWORD len=0;
+ WCHAR * parent;
+ while(search(ptr, L"\\")!=NULL) {
+ ptr = search(ptr, L"\\") + 1;
+ }
+ len = lstrlenW(currentFile) - lstrlenW(ptr) - 1;
+ parent = LocalAlloc(LPTR, sizeof(WCHAR) * (len + 1));
+ for(i=0;i<len;i++) {
+ parent[i] = currentFile[i];
+ }
+ parent[len] = 0;
+ SetCurrentDirectoryW(parent);
+ LocalFree(parent);
+ }
+ LocalFree(currentFile);
+}
+
+// should be less or equals to MAXIMUM_WAIT_OBJECTS
+#define MAXIMUM_THREADS MAXIMUM_WAIT_OBJECTS
+
+int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hi, PSTR pszCmdLine, int nCmdShow) {
+//int main(void) {
+ int argumentsNumber = 0;
+ DWORD i=0;
+ DWORD threadCounter = 0;
+ DWORD dwThread;
+ WCHAR ** commandLine = CommandLineToArgvW(GetCommandLineW(), &argumentsNumber);
+ HANDLE * runningThreads = (HANDLE *) LocalAlloc(LPTR, sizeof(HANDLE) * MAXIMUM_THREADS);
+
+ for(i=0;i<MAXIMUM_THREADS;i++) {
+ runningThreads[i] = INVALID_HANDLE_VALUE;
+ }
+ changeCurrentDirectory();
+
+ if(argumentsNumber==2) {
+ WCHAR * filename = commandLine[1];
+ HANDLE fileList = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0);
+ if(fileList!=0) {
+ WCHAR ** files = NULL;
+ DWORD number = 0;
+ DWORD allThreadsUsed=0;
+ readStringList(fileList, &files, &number);
+ CloseHandle(fileList);
+
+ if(files!=NULL) {
+ Sleep(INITIAL_DELAY);
+ for(i=0;i<number;i++) {
+ WCHAR * file = files[i];
+ if(file!=NULL) {
+ if(lstrlenW(file)>0) {
+ getFreeIndexForNextThread(runningThreads, MAXIMUM_THREADS, &threadCounter);
+ runningThreads [threadCounter] = CreateThread( NULL, 0, &deleteFileThread, (LPVOID) file, 0, &dwThread );
+ threadCounter++;
+ if(threadCounter==MAXIMUM_THREADS) allThreadsUsed = 1;
+ }
+ }
+ }
+
+ WaitForMultipleObjects(allThreadsUsed ? MAXIMUM_THREADS : threadCounter,
+ runningThreads, TRUE, INFINITE);
+
+ for(i=0;i<number;i++) {
+ if(files[i]!=NULL) LocalFree(files[i]);
+ }
+
+ LocalFree(files);
+ }
+ }
+ }
+ LocalFree(commandLine);
+ LocalFree(runningThreads);
+ //removeItself();
+ removeItselfUsingCmd();
+ return 0;
+}
diff --git a/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.ncb b/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.ncb
new file mode 100644
index 0000000..9057eba
--- /dev/null
+++ b/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.ncb
@@ -0,0 +1 @@
+Microsoft C/C++ MSF 7.00
diff --git a/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.sln b/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.sln
new file mode 100644
index 0000000..659a421
--- /dev/null
+++ b/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual C++ Express 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NBI Native Cleaner", "NBI Native Cleaner.vcproj", "{0DB81F65-E9E6-4506-BE27-C020AAD1B04A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0DB81F65-E9E6-4506-BE27-C020AAD1B04A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0DB81F65-E9E6-4506-BE27-C020AAD1B04A}.Debug|Win32.Build.0 = Debug|Win32
+ {0DB81F65-E9E6-4506-BE27-C020AAD1B04A}.Release|Win32.ActiveCfg = Release|Win32
+ {0DB81F65-E9E6-4506-BE27-C020AAD1B04A}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.suo b/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.suo
new file mode 100644
index 0000000..189f7a2
--- /dev/null
+++ b/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.suo
Binary files differ
diff --git a/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.vcproj b/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.vcproj
new file mode 100644
index 0000000..dd72b1f
--- /dev/null
+++ b/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.vcproj
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="NBI Native Cleaner"
+ ProjectGUID="{0DB81F65-E9E6-4506-BE27-C020AAD1B04A}"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ FavorSizeOrSpeed="2"
+ AdditionalIncludeDirectories="C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE"
+ ExceptionHandling="0"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="0"
+ CompileAs="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Shell32.lib"
+ OutputFile="..\dist\cleaner.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="false"
+ AdditionalLibraryDirectories="C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Lib"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="true"
+ GenerateDebugInformation="false"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ EntryPointSymbol="WinMain"
+ TargetMachine="1"
+ ErrorReporting="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\src\main.c"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.vcproj.user b/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.vcproj.user
new file mode 100644
index 0000000..a5ca4f9
--- /dev/null
+++ b/src/main/cpp/cleaner/windows/vcproject/NBI Native Cleaner.vcproj.user
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><VisualStudioUserFile ProjectType="Visual C++" Version="8.00" ShowAllFiles="true"></VisualStudioUserFile>
\ No newline at end of file
diff --git a/src/main/cpp/jnilib/.common/src/CommonUtils.c b/src/main/cpp/jnilib/.common/src/CommonUtils.c
new file mode 100644
index 0000000..b66eccd
--- /dev/null
+++ b/src/main/cpp/jnilib/.common/src/CommonUtils.c
@@ -0,0 +1,384 @@
+/*
+ * 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 <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "CommonUtils.h"
+
+jbyteArray getStringBytes(JNIEnv* jEnv, jstring jString) {
+ jbyteArray result = NULL;
+
+ if (jString != NULL) {
+ jmethodID jGetBytesMethod = (*jEnv)->GetMethodID(jEnv, (*jEnv)->GetObjectClass(jEnv, jString), "getBytes", "()[B");
+
+ if (jGetBytesMethod != NULL) {
+ jbyteArray jBuffer = (jbyteArray) (*jEnv)->CallObjectMethod(jEnv, jString, jGetBytesMethod);
+
+ if (jBuffer != NULL) {
+ jsize jLength = (*jEnv)->GetArrayLength(jEnv, jBuffer);
+
+ result = (*jEnv)->NewByteArray(jEnv, jLength + 1);
+ if (jLength != 0) {
+ jbyte* jChars = (*jEnv)->GetByteArrayElements(jEnv, jBuffer, NULL);
+ (*jEnv)->SetByteArrayRegion(jEnv, result, 0, jLength, jChars);
+ (*jEnv)->ReleaseByteArrayElements(jEnv, jBuffer, jChars, JNI_ABORT);
+ }
+ (*jEnv)->DeleteLocalRef(jEnv, jBuffer);
+ }
+ //(*jEnv)->DeleteLocalRef(jEnv, getBytesMethod);
+ }
+ }
+
+ return result;
+}
+
+
+jstring newStringFromJByteArray(JNIEnv* jEnv, jbyteArray jByteArray, int length) {
+ jstring result = NULL;
+
+ jclass jStringClass = (*jEnv)->FindClass(jEnv, "java/lang/String");
+ if (jStringClass != NULL) {
+ jmethodID jStringConstructor = (*jEnv)->GetMethodID(jEnv, jStringClass, "<init>", "([BII)V");
+
+ if (jStringConstructor != NULL) {
+ result = (jstring) (*jEnv)->NewObject(jEnv, jStringClass, jStringConstructor, jByteArray, 0, length);
+ //(*jEnv)->DeleteLocalRef(jEnv, stringConstructor);
+ }
+ (*jEnv)->DeleteLocalRef(jEnv, jStringClass);
+ }
+
+ return result;
+}
+
+
+jstring newStringFromJCharArray(JNIEnv* jEnv, jcharArray jCharArray, int length) {
+ jstring result = NULL;
+
+ jclass jStringClass = (*jEnv)->FindClass(jEnv, "java/lang/String");
+ if (jStringClass != NULL) {
+ jmethodID jStringConstructor = (*jEnv)->GetMethodID(jEnv, jStringClass, "<init>", "([CII)V");
+
+ if (jStringConstructor != NULL) {
+ result = (jstring) (*jEnv)->NewObject(jEnv, jStringClass, jStringConstructor, jCharArray, 0, length);
+ }
+ (*jEnv)->DeleteLocalRef(jEnv, jStringClass);
+ }
+
+ return result;
+}
+
+jstring getString(JNIEnv* jEnv, const char* chars) {
+ return (jstring) getStringWithLength(jEnv, chars, (int) STRLEN(chars));
+}
+
+jstring getStringW(JNIEnv* jEnv, const wchar_t * chars) {
+ return (jstring) getStringWithLengthW(jEnv, chars, (int) WCSLEN(chars));
+}
+
+jstring getStringWithLength(JNIEnv* jEnv, const char* chars, int length) {
+ jstring result = NULL;
+
+ if (chars != NULL) {
+ if (length == 0) {
+ result = (*jEnv)->NewString(jEnv, (const jchar *) L"", 0);
+ } else {
+ jbyteArray jByteArray = (*jEnv)->NewByteArray(jEnv, length);
+
+ if (jByteArray != NULL) {
+ (*jEnv)->SetByteArrayRegion(jEnv, jByteArray, 0, length, (jbyte*) chars);
+ result = newStringFromJByteArray(jEnv, jByteArray, length);
+ (*jEnv)->DeleteLocalRef(jEnv, jByteArray);
+ }
+ }
+ }
+
+ return result;
+}
+
+
+jstring getStringWithLengthW(JNIEnv* jEnv, const wchar_t* chars, int length) {
+ jstring result = NULL;
+
+ if (chars != NULL) {
+ if (length == 0) {
+ result = (*jEnv)->NewString(jEnv, (const jchar *) L"", 0);
+ } else {
+ jcharArray jCharArray = (*jEnv)->NewCharArray(jEnv, length);
+
+ if (jCharArray != NULL) {
+ (*jEnv)->SetCharArrayRegion(jEnv, jCharArray, 0, length, (jchar*) chars);
+ result = newStringFromJCharArray(jEnv, jCharArray, length);
+ (*jEnv)->DeleteLocalRef(jEnv, jCharArray);
+ }
+ }
+ }
+
+ return result;
+}
+
+
+char* getChars(JNIEnv* jEnv, jstring jString) {
+ char* result = NULL;
+
+ jbyteArray jByteArray = getStringBytes(jEnv, jString);
+ if (jByteArray != NULL) {
+ jbyte* jBytes = (*jEnv)->GetByteArrayElements(jEnv, jByteArray, NULL);
+
+ long index = 0;
+ if (jBytes != NULL) {
+ int length = (int) STRLEN((char*) jBytes);
+
+ result = (char*) MALLOC(sizeof(char) * (length + 1));
+ if (result != NULL) {
+ ZERO(result, length);
+ STRNCPY(result, (char*) jBytes, length);
+ result[length] = 0;
+ }
+ (*jEnv)->ReleaseByteArrayElements(jEnv, jByteArray, jBytes, JNI_ABORT);
+ }
+ (*jEnv)->DeleteLocalRef(jEnv, jByteArray);
+ }
+
+ return result;
+}
+
+char* getStringFromMethod(JNIEnv* jEnv, jobject object, const char* methodName) {
+ char* result = NULL;
+
+ jclass clazz = (*jEnv)->GetObjectClass(jEnv, object);
+ if (clazz != NULL) {
+ jmethodID method = (*jEnv)->GetMethodID(jEnv, clazz, methodName, "()Ljava/lang/String;");
+ if (method != NULL) {
+ jstring string = (jstring) (*jEnv)->CallObjectMethod(jEnv, object, method);
+ if (string != NULL) {
+ result = getChars(jEnv, string);
+ (*jEnv)->DeleteLocalRef(jEnv, string);
+ }
+ //(*jEnv)->DeleteLocalRef(jEnv, method);
+ }
+ (*jEnv)->DeleteLocalRef(jEnv, clazz);
+ }
+
+ return result;
+}
+
+wchar_t * getWideStringFromMethod(JNIEnv* jEnv, jobject object, const char* methodName) {
+ wchar_t* result = NULL;
+
+ jclass clazz = (*jEnv)->GetObjectClass(jEnv, object);
+ if (clazz != NULL) {
+ jmethodID method = (*jEnv)->GetMethodID(jEnv, clazz, methodName, "()Ljava/lang/String;");
+ if (method != NULL) {
+ jstring string = (jstring) (*jEnv)->CallObjectMethod(jEnv, object, method);
+ if (string != NULL) {
+ result = getWideChars(jEnv, string);
+ (*jEnv)->DeleteLocalRef(jEnv, string);
+ }
+ //(*jEnv)->DeleteLocalRef(jEnv, method);
+ }
+ (*jEnv)->DeleteLocalRef(jEnv, clazz);
+ }
+
+ return result;
+}
+
+jboolean isInstanceOf(JNIEnv* jEnv, jobject object, const char* className) {
+ jboolean result = 0;
+ jclass clazz = clazz = (*jEnv)->FindClass(jEnv, className);
+
+ if (clazz != NULL) {
+ result = (*jEnv)->IsInstanceOf(jEnv, object, clazz);
+ (*jEnv)->DeleteLocalRef(jEnv, clazz);
+ }
+ return result;
+}
+
+jint getIntFromMethod(JNIEnv* jEnv, jobject object, const char* methodName) {
+ jint value = 0;
+
+ jclass clazz = (*jEnv)->GetObjectClass(jEnv, object);
+ if (clazz != NULL) {
+ jmethodID method = (*jEnv)->GetMethodID(jEnv, clazz, methodName, "()I");
+ if (method != NULL) {
+ value = (*jEnv)->CallIntMethod(jEnv, object, method);
+ }
+ (*jEnv)->DeleteLocalRef(jEnv, clazz);
+ }
+
+ return value;
+}
+
+void throwException(JNIEnv* jEnv, const char* message) {
+ jclass clazz = (*jEnv)->FindClass(jEnv, "org/netbeans/installer/utils/exceptions/NativeException");
+ if (clazz != NULL) {
+ (*jEnv)->ThrowNew(jEnv, clazz, message);
+ (*jEnv)->DeleteLocalRef(jEnv, clazz);
+ }
+}
+
+void writeLog(JNIEnv* jEnv, int level, const char* message) {
+ const char* prefix = "[jni] ";
+
+ jclass clazz = (*jEnv)->FindClass(jEnv, "org/netbeans/installer/utils/LogManager");
+ if (clazz != NULL) {
+ jmethodID method = (*jEnv)->GetStaticMethodID(jEnv, clazz, "log", "(ILjava/lang/String;)V");
+ if (method != NULL) {
+ jstring jMessage = NULL;
+ int prefix_length = STRLEN(prefix);
+ int message_length = STRLEN(message);
+ char* string = (char*) MALLOC(sizeof(char) * (prefix_length + message_length + 1));
+ int i = 0;
+ for(i=0;i<prefix_length;i++) {
+ string[i]=prefix[i];
+ }
+
+ for(i=0;i<message_length;i++) {
+ string[i + prefix_length]=message[i];
+ }
+ string[i+prefix_length + message_length] = '\0';
+
+
+ jMessage = getString(jEnv, string);
+
+ if (jMessage != NULL) {
+ (*jEnv)->CallStaticVoidMethod(jEnv, clazz, method, (jint) level, jMessage);
+ (*jEnv)->DeleteLocalRef(jEnv, jMessage);
+ }
+
+ FREE(string);
+ //(*jEnv)->DeleteLocalRef(jEnv, method);
+ }
+ (*jEnv)->DeleteLocalRef(jEnv, clazz);
+ }
+}
+
+int createDirs(JNIEnv* jEnv, jstring jPath) {
+ int result = 0;
+ jclass jFileClass = (*jEnv)->FindClass(jEnv, "java/io/File");
+ if (jFileClass != NULL) {
+ jmethodID jFileConstructor = (*jEnv)->GetMethodID(jEnv, jFileClass, "<init>", "(Ljava/lang/String;)V");
+ jmethodID jGetParentFileMethod = (*jEnv)->GetMethodID(jEnv, jFileClass, "getParentFile", "()Ljava/io/File;");
+ jmethodID jExistsMethod = (*jEnv)->GetMethodID(jEnv, jFileClass, "exists", "()Z");
+ jmethodID jMkdirsMethod = (*jEnv)->GetMethodID(jEnv, jFileClass, "mkdirs", "()Z");
+
+ if ((jFileConstructor != NULL) && (jGetParentFileMethod != NULL) && (jExistsMethod != NULL) && (jMkdirsMethod != NULL)) {
+ jobject jFile = (*jEnv)->NewObject(jEnv, jFileClass, jFileConstructor, jPath);
+ if (jFile != NULL ) {
+ if(!((*jEnv)->CallBooleanMethod(jEnv, jFile, jExistsMethod))) {
+ jobject jParent = (*jEnv)->CallObjectMethod(jEnv, jFile, jGetParentFileMethod);
+ if (jParent != NULL) {
+ result = (*jEnv)->CallBooleanMethod(jEnv, jParent, jExistsMethod);
+ if (!result) {
+ result = (*jEnv)->CallBooleanMethod(jEnv, jParent, jMkdirsMethod);
+ }
+ (*jEnv)->DeleteLocalRef(jEnv, jParent);
+ }
+ } else {
+ result = 1;
+ }
+ (*jEnv)->DeleteLocalRef(jEnv, jFile);
+ }
+ }
+ (*jEnv)->DeleteLocalRef(jEnv, jFileClass);
+ }
+ return result;
+}
+
+int mkdirs(JNIEnv* jEnv, const char *path) {
+ int result = 1;
+ jstring jPath = getString(jEnv, path);
+ if (jPath != NULL) {
+ result = createDirs(jEnv, jPath);
+ (*jEnv)->DeleteLocalRef(jEnv, jPath);
+ }
+ return result;
+}
+
+
+int mkdirsW(JNIEnv* jEnv, const wchar_t *path) {
+ int result = 1;
+ jstring jPath = getStringW(jEnv, path);
+ if (jPath != NULL) {
+ result = createDirs(jEnv, jPath);
+ (*jEnv)->DeleteLocalRef(jEnv, jPath);
+ }
+
+ return result;
+}
+
+
+
+unsigned char* getByteFromMultiString(JNIEnv *jEnv, jobjectArray jObjectArray, unsigned long* size) {
+ unsigned short * result = NULL;
+
+ int totalLength = 0;
+ unsigned int arrayLength = (*jEnv)->GetArrayLength(jEnv, jObjectArray);
+ jstring jString = NULL;
+
+ unsigned int i, j; // just counters
+
+ for (i = 0; i < arrayLength; i++) {
+ jString = (jstring) (*jEnv)->GetObjectArrayElement(jEnv, jObjectArray, i);
+ totalLength += (*jEnv)->GetStringLength(jEnv, jString) + 1;
+ }
+ totalLength++; // add null to the end of array
+
+ result = (unsigned short*) MALLOC(sizeof(unsigned short) * totalLength);
+ if (result != NULL) {
+ int index = 0 ;
+
+ for (i = 0; i < arrayLength; i++) {
+ jString = (jstring) (*jEnv)->GetObjectArrayElement(jEnv, jObjectArray, i);
+
+ if (jString != NULL) {
+ wchar_t * chars = getWideChars(jEnv, jString);
+ if (chars != NULL) {
+ for (j = 0; j < (WCSLEN(chars)); j++) {
+ result[index++] = chars[j];
+ }
+
+ FREE(chars);
+ }
+ }
+ result[index++] = '\0';
+ }
+ result[index++] = '\0'; //double \0 at the end
+ }
+ * size = sizeof(unsigned short) * totalLength;
+ return (unsigned char*)result;
+}
+
+wchar_t * getWideChars(JNIEnv *jEnv, jstring jString) {
+ if(jString==NULL) {
+ return NULL;
+ } else {
+ long length = (*jEnv)->GetStringLength( jEnv, jString);
+ const jchar * unicodeStr = (*jEnv)->GetStringChars( jEnv, jString, 0 );
+ wchar_t * copy = (wchar_t *) MALLOC(sizeof(wchar_t) * (length + 1));
+ ZERO(copy, sizeof(wchar_t)*(length + 1));
+ WCSNCPY(copy, (const wchar_t *) unicodeStr, length + 1);
+ (*jEnv)->ReleaseStringChars( jEnv, jString, unicodeStr);
+ return copy;
+ }
+
+}
diff --git a/src/main/cpp/jnilib/.common/src/CommonUtils.h b/src/main/cpp/jnilib/.common/src/CommonUtils.h
new file mode 100644
index 0000000..8824351
--- /dev/null
+++ b/src/main/cpp/jnilib/.common/src/CommonUtils.h
@@ -0,0 +1,122 @@
+/*
+ * 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 <jni.h>
+#include <wchar.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+#include <windows.h>
+#endif
+
+#ifndef _CommonUtils_H
+#define _CommonUtils_H
+
+
+#ifdef _MSC_VER
+#define FREE(x) { if((x)!=NULL) { LocalFree(x); (x)=NULL;}}
+#else
+#define FREE(x) { if((x)!=NULL) { free(x); (x)=NULL;}}
+#endif
+
+#ifdef _MSC_VER
+#define MALLOC(x) LocalAlloc(LPTR, x)
+#else
+#define MALLOC(x) malloc(x)
+#endif
+
+
+#ifdef _MSC_VER
+#define ZERO(x,y) SecureZeroMemory((x),(y))
+#else
+#define ZERO(x,y) memset((x),0,(y))
+#endif
+
+
+#ifdef _MSC_VER
+#define STRLEN(x) lstrlenA(x)
+#else
+#define STRLEN(x) strlen(x)
+#endif
+
+
+#ifdef _MSC_VER
+#define WCSLEN(x) ((unsigned long)lstrlenW(x))
+#else
+#define WCSLEN(x) ((unsigned long)wcslen(x))
+#endif
+
+
+#ifdef _MSC_VER
+#define STRNCPY(x,y,z) lstrcpynA((x),(y),(z))
+#else
+#define STRNCPY(x,y,z) strncpy((x),(y),(z))
+#endif
+
+#ifdef _MSC_VER
+#define WCSNCPY(x,y,z) lstrcpynW((x),(y),(z))
+#else
+#define WCSNCPY(x,y,z) wcsncpy((x),(y),(z))
+#endif
+
+
+#define LOG_DEBUG 4
+#define LOG_MESSAGE 3
+#define LOG_WARNING 2
+#define LOG_ERROR 1
+#define LOG_CRITICAL 0
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+jbyteArray getStringBytes(JNIEnv* jEnv, jstring jString);
+
+jstring newStringFromJByteArray(JNIEnv* jEnv, jbyteArray jByteArray, int length);
+jstring newStringFromJCharArray(JNIEnv* jEnv, jcharArray jCharArray, int length);
+
+jstring getString (JNIEnv* jEnv, const char* chars);
+jstring getStringW(JNIEnv* jEnv, const wchar_t * chars);
+
+
+jstring getStringWithLength(JNIEnv* jEnv, const char* chars, int length);
+jstring getStringWithLengthW(JNIEnv* jEnv, const wchar_t * chars, int length);
+
+char* getChars(JNIEnv* jEnv, jstring jString);
+wchar_t * getWideChars(JNIEnv *jEnv, jstring str);
+
+char* getStringFromMethod(JNIEnv* jEnv, jobject object, const char* methodName);
+wchar_t* getWideStringFromMethod(JNIEnv* jEnv, jobject object, const char* methodName) ;
+
+jint getIntFromMethod(JNIEnv* jEnv, jobject object, const char* methodName);
+
+jboolean isInstanceOf(JNIEnv* jEnv, jobject object, const char* className);
+
+void throwException(JNIEnv* jEnv, const char* message);
+
+void writeLog(JNIEnv* jEnv, int level, const char* message);
+
+int mkdirs (JNIEnv* jEnv, const char *path);
+int mkdirsW(JNIEnv* jEnv, const wchar_t *path);
+
+unsigned char* getByteFromMultiString(JNIEnv *jEnv, jobjectArray jObjectArray, unsigned long* size);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _CommonUtils_H */
diff --git a/src/main/cpp/jnilib/.unix/src/jni_UnixNativeUtils.c b/src/main/cpp/jnilib/.unix/src/jni_UnixNativeUtils.c
new file mode 100644
index 0000000..437e270
--- /dev/null
+++ b/src/main/cpp/jnilib/.unix/src/jni_UnixNativeUtils.c
@@ -0,0 +1,108 @@
+/*
+ * 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 <jni.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "../../.common/src/CommonUtils.h"
+#include "jni_UnixNativeUtils.h"
+
+
+jboolean statMode(const char *path, int *mode) {
+ struct stat sb;
+ if (stat(path, &sb) == 0) {
+ *mode = sb.st_mode;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
+JNIEXPORT jlong JNICALL Java_org_netbeans_installer_utils_system_UnixNativeUtils_getFreeSpace0(JNIEnv* jEnv, jobject jObject, jstring jPath) {
+ char* path = getChars(jEnv, jPath);
+ jlong result = 0;
+
+ struct statvfs fsstat;
+ if(memset(&fsstat, 0, sizeof(struct statvfs)) != NULL) {
+ if(statvfs(path, &fsstat) == 0) {
+ result = (jlong) fsstat.f_frsize;
+ result *= (jlong) fsstat.f_bfree;
+ }
+ }
+
+
+ FREE(path);
+ return result;
+}
+
+
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_UnixNativeUtils_setPermissions0(JNIEnv *jEnv, jobject jObject, jstring jPath, jint jMode, jint jChange) {
+ char* path = getChars(jEnv, jPath);
+ int currentMode = 0 ;
+ char * msg = NULL;
+ if(statMode(path, ¤tMode)) {
+ switch (jChange) {
+ case MODE_CHANGE_SET:
+ currentMode |= (S_IRWXU | S_IRWXG | S_IRWXO);
+ currentMode &= jMode;
+ break;
+ case MODE_CHANGE_ADD:
+ currentMode |= jMode;
+ break;
+ case MODE_CHANGE_REMOVE:
+ currentMode &= ~jMode;
+ break;
+ default:
+ msg = (char*) malloc(sizeof(char) * 60);
+ memset(msg, 0, sizeof(char) * 60);
+ sprintf(msg, "Selected change mode (%ld) is not supported", jChange);
+ throwException(jEnv, msg);
+ FREE(msg);
+ FREE(path);
+ return;
+ }
+ chmod(path, currentMode);
+ } else {
+ throwException(jEnv, "Can`t get file current permissions");
+ }
+ FREE(path);
+}
+
+
+JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_UnixNativeUtils_getPermissions0(JNIEnv *jEnv, jobject jObject, jstring jPath) {
+ char* path = getChars(jEnv, jPath);
+ int currentMode;
+ if(statMode(path, ¤tMode)) {
+ return currentMode & (S_IRWXU | S_IRWXG | S_IRWXO);
+ } else {
+ throwException(jEnv, "Can`t get file current permissions");
+ }
+
+ FREE(path);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_UnixNativeUtils_isCurrentUserAdmin0 (JNIEnv *jEnv, jobject jObject) {
+ return (geteuid()==0);
+}
diff --git a/src/main/cpp/jnilib/.unix/src/jni_UnixNativeUtils.h b/src/main/cpp/jnilib/.unix/src/jni_UnixNativeUtils.h
new file mode 100644
index 0000000..989e05d
--- /dev/null
+++ b/src/main/cpp/jnilib/.unix/src/jni_UnixNativeUtils.h
@@ -0,0 +1,83 @@
+/*
+ * 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 <jni.h>
+/* Header for class org_netbeans_installer_utils_system_UnixNativeUtils */
+
+#ifndef _Included_org_netbeans_installer_utils_system_UnixNativeUtils
+#define _Included_org_netbeans_installer_utils_system_UnixNativeUtils
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define MODE_RU 1L
+#define MODE_WU 2L
+#define MODE_EU 4L
+#define MODE_RG 8L
+#define MODE_WG 16L
+#define MODE_EG 32L
+#define MODE_RO 64L
+#define MODE_WO 128L
+#define MODE_EO 256L
+
+#define MODE_CHANGE_SET 1L
+#define MODE_CHANGE_ADD 2L
+#define MODE_CHANGE_REMOVE 4L
+
+
+
+/*
+ * Class: org_netbeans_installer_utils_system_UnixNativeUtils
+ * Method: getFreeSpace0
+ * Signature: (Ljava/lang/String;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_netbeans_installer_utils_system_UnixNativeUtils_getFreeSpace0
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_UnixNativeUtils
+ * Method: setPermission0
+ * Signature: (Ljava/lang/String;II)V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_UnixNativeUtils_setPermissions0
+ (JNIEnv *, jobject, jstring, jint, jint);
+
+/*
+ * Class: org_netbeans_installer_utils_system_UnixNativeUtils
+ * Method: getPermissions0
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_UnixNativeUtils_getPermissions0
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_UnixNativeUtils
+ * Method: isCurrentUserAdmin0
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_UnixNativeUtils_isCurrentUserAdmin0
+ (JNIEnv *, jobject);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/main/cpp/jnilib/linux/Makefile b/src/main/cpp/jnilib/linux/Makefile
new file mode 100644
index 0000000..516847d
--- /dev/null
+++ b/src/main/cpp/jnilib/linux/Makefile
@@ -0,0 +1,109 @@
+#
+# 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.
+#
+
+#
+# There exist several targets which are by default empty and which can be
+# used for execution of your targets. These targets are usually executed
+# before and after some main targets. They are:
+#
+# .build-pre: called before 'build' target
+# .build-post: called after 'build' target
+# .clean-pre: called before 'clean' target
+# .clean-post: called after 'clean' target
+# .clobber-pre: called before 'clobber' target
+# .clobber-post: called after 'clobber' target
+# .all-pre: called before 'all' target
+# .all-post: called after 'all' target
+# .help-pre: called before 'help' target
+# .help-post: called after 'help' target
+#
+# Targets beginning with '.' are not intended to be called on their own.
+#
+# Main targets can be executed directly, and they are:
+#
+# build build a specific configuration
+# clean remove built files from a configuration
+# clobber remove all built files
+# all build all configurations
+# help print help mesage
+#
+# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+# .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+RANLIB=ranlib
+
+
+# build
+build: .build-pre .build-impl .build-post
+
+.build-pre:
+# Add your pre 'build' code here...
+
+.build-post:
+# Add your post 'build' code here...
+
+
+# clean
+clean: .clean-pre .clean-impl .clean-post
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post:
+# Add your post 'clean' code here...
+
+
+# clobber
+clobber: .clobber-pre .clobber-impl .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post:
+# Add your post 'clobber' code here...
+
+
+# all
+all: .all-pre .all-impl .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post:
+# Add your post 'all' code here...
+
+
+# help
+help: .help-pre .help-impl .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post:
+# Add your post 'help' code here...
+
+
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
diff --git a/src/main/cpp/jnilib/linux/nbproject/configurations.xml b/src/main/cpp/jnilib/linux/nbproject/configurations.xml
new file mode 100644
index 0000000..9e8e8b1
--- /dev/null
+++ b/src/main/cpp/jnilib/linux/nbproject/configurations.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<configurationDescriptor version="35">
+ <logicalFolder name="root" displayName="root" projectFiles="true">
+ <logicalFolder name="SourceFiles"
+ displayName="Source Files"
+ projectFiles="true">
+ <itemPath>../.common/src/CommonUtils.c</itemPath>
+ <itemPath>../.unix/src/jni_UnixNativeUtils.c</itemPath>
+ </logicalFolder>
+ <logicalFolder name="HeaderFiles"
+ displayName="Header Files"
+ projectFiles="true">
+ <itemPath>../.common/src/CommonUtils.h</itemPath>
+ <itemPath>../.unix/src/jni_UnixNativeUtils.h</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ResourceFiles"
+ displayName="Resource Files"
+ projectFiles="true">
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ </logicalFolder>
+ <projectmakefile>Makefile</projectmakefile>
+ <defaultConf>0</defaultConf>
+ <confs>
+ <conf name="Debug" type="2">
+ <toolsSet>
+ <compilerSet>GNU</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>2</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/linux</directoryPath>
+ </includeDirectories>
+ <commandLine>-shared -m32 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/linux</directoryPath>
+ </includeDirectories>
+ <commandLine>-shared -m32 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/linux.so</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ <conf name="Release" type="2">
+ <toolsSet>
+ <compilerSet>GNU</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>2</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>5</developmentMode>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>5</developmentMode>
+ </ccCompilerTool>
+ <fortranCompilerTool>
+ <developmentMode>5</developmentMode>
+ </fortranCompilerTool>
+ <linkerTool>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ <conf name="Debug_amd64" type="2">
+ <toolsSet>
+ <compilerSet>GNU</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>2</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <sixtyfourBits>true</sixtyfourBits>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/linux</directoryPath>
+ </includeDirectories>
+ <commandLine>-shared -fPIC -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <sixtyfourBits>true</sixtyfourBits>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/linux</directoryPath>
+ </includeDirectories>
+ <commandLine>-shared -fPIC -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/linux-amd64.so</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/src/main/cpp/jnilib/linux/nbproject/project.properties b/src/main/cpp/jnilib/linux/nbproject/project.properties
new file mode 100644
index 0000000..3807b67
--- /dev/null
+++ b/src/main/cpp/jnilib/linux/nbproject/project.properties
@@ -0,0 +1,20 @@
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
diff --git a/src/main/cpp/jnilib/linux/nbproject/project.xml b/src/main/cpp/jnilib/linux/nbproject/project.xml
new file mode 100644
index 0000000..4e61d3b
--- /dev/null
+++ b/src/main/cpp/jnilib/linux/nbproject/project.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.cnd.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>NBI Native Library: Linux</name>
+ <make-project-type>0</make-project-type>
+ </data>
+ </configuration>
+</project>
diff --git a/src/main/cpp/jnilib/macosx/Makefile b/src/main/cpp/jnilib/macosx/Makefile
new file mode 100644
index 0000000..516847d
--- /dev/null
+++ b/src/main/cpp/jnilib/macosx/Makefile
@@ -0,0 +1,109 @@
+#
+# 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.
+#
+
+#
+# There exist several targets which are by default empty and which can be
+# used for execution of your targets. These targets are usually executed
+# before and after some main targets. They are:
+#
+# .build-pre: called before 'build' target
+# .build-post: called after 'build' target
+# .clean-pre: called before 'clean' target
+# .clean-post: called after 'clean' target
+# .clobber-pre: called before 'clobber' target
+# .clobber-post: called after 'clobber' target
+# .all-pre: called before 'all' target
+# .all-post: called after 'all' target
+# .help-pre: called before 'help' target
+# .help-post: called after 'help' target
+#
+# Targets beginning with '.' are not intended to be called on their own.
+#
+# Main targets can be executed directly, and they are:
+#
+# build build a specific configuration
+# clean remove built files from a configuration
+# clobber remove all built files
+# all build all configurations
+# help print help mesage
+#
+# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+# .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+RANLIB=ranlib
+
+
+# build
+build: .build-pre .build-impl .build-post
+
+.build-pre:
+# Add your pre 'build' code here...
+
+.build-post:
+# Add your post 'build' code here...
+
+
+# clean
+clean: .clean-pre .clean-impl .clean-post
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post:
+# Add your post 'clean' code here...
+
+
+# clobber
+clobber: .clobber-pre .clobber-impl .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post:
+# Add your post 'clobber' code here...
+
+
+# all
+all: .all-pre .all-impl .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post:
+# Add your post 'all' code here...
+
+
+# help
+help: .help-pre .help-impl .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post:
+# Add your post 'help' code here...
+
+
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
diff --git a/src/main/cpp/jnilib/macosx/nbproject/configurations.xml b/src/main/cpp/jnilib/macosx/nbproject/configurations.xml
new file mode 100644
index 0000000..50ab41e
--- /dev/null
+++ b/src/main/cpp/jnilib/macosx/nbproject/configurations.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<configurationDescriptor version="45">
+ <logicalFolder name="root" displayName="root" projectFiles="true">
+ <logicalFolder name="HeaderFiles"
+ displayName="Header Files"
+ projectFiles="true">
+ <itemPath>../.common/src/CommonUtils.h</itemPath>
+ <itemPath>../.unix/src/jni_UnixNativeUtils.h</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ResourceFiles"
+ displayName="Resource Files"
+ projectFiles="true">
+ </logicalFolder>
+ <logicalFolder name="SourceFiles"
+ displayName="Source Files"
+ projectFiles="true">
+ <itemPath>../.common/src/CommonUtils.c</itemPath>
+ <itemPath>../.unix/src/jni_UnixNativeUtils.c</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ </logicalFolder>
+ <sourceEncoding>UTF-8</sourceEncoding>
+ <projectmakefile>Makefile</projectmakefile>
+ <confs>
+ <conf name="Debug" type="2">
+ <toolsSet>
+ <compilerSet>GNU|GNU</compilerSet>
+ <platform>4</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/Library/Java/Home/include</directoryPath>
+ </includeDirectories>
+ <commandLine>-arch i386 -arch ppc -arch ppc64 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -dynamiclib</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/Library/Java/Home/include</directoryPath>
+ </includeDirectories>
+ <commandLine>-arch i386 -arch ppc -arch ppc64 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -dynamiclib</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/macosx.dylib</output>
+ <linkerLibItems>
+ </linkerLibItems>
+ <commandLine>-Wl,-syslibroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc -arch ppc64 -arch x86_64</commandLine>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ <conf name="Release" type="2">
+ <toolsSet>
+ <compilerSet>GNU|GNU</compilerSet>
+ <platform>4</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>5</developmentMode>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>5</developmentMode>
+ </ccCompilerTool>
+ <fortranCompilerTool>
+ <developmentMode>5</developmentMode>
+ </fortranCompilerTool>
+ <linkerTool>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/src/main/cpp/jnilib/macosx/nbproject/project.properties b/src/main/cpp/jnilib/macosx/nbproject/project.properties
new file mode 100644
index 0000000..3807b67
--- /dev/null
+++ b/src/main/cpp/jnilib/macosx/nbproject/project.properties
@@ -0,0 +1,20 @@
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
diff --git a/src/main/cpp/jnilib/macosx/nbproject/project.xml b/src/main/cpp/jnilib/macosx/nbproject/project.xml
new file mode 100644
index 0000000..1825876
--- /dev/null
+++ b/src/main/cpp/jnilib/macosx/nbproject/project.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.cnd.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>NBI Native Library: MacOS X</name>
+ <make-project-type>0</make-project-type>
+ <make-dep-projects/>
+ </data>
+ </configuration>
+</project>
diff --git a/src/main/cpp/jnilib/solaris-sparc/Makefile b/src/main/cpp/jnilib/solaris-sparc/Makefile
new file mode 100644
index 0000000..516847d
--- /dev/null
+++ b/src/main/cpp/jnilib/solaris-sparc/Makefile
@@ -0,0 +1,109 @@
+#
+# 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.
+#
+
+#
+# There exist several targets which are by default empty and which can be
+# used for execution of your targets. These targets are usually executed
+# before and after some main targets. They are:
+#
+# .build-pre: called before 'build' target
+# .build-post: called after 'build' target
+# .clean-pre: called before 'clean' target
+# .clean-post: called after 'clean' target
+# .clobber-pre: called before 'clobber' target
+# .clobber-post: called after 'clobber' target
+# .all-pre: called before 'all' target
+# .all-post: called after 'all' target
+# .help-pre: called before 'help' target
+# .help-post: called after 'help' target
+#
+# Targets beginning with '.' are not intended to be called on their own.
+#
+# Main targets can be executed directly, and they are:
+#
+# build build a specific configuration
+# clean remove built files from a configuration
+# clobber remove all built files
+# all build all configurations
+# help print help mesage
+#
+# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+# .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+RANLIB=ranlib
+
+
+# build
+build: .build-pre .build-impl .build-post
+
+.build-pre:
+# Add your pre 'build' code here...
+
+.build-post:
+# Add your post 'build' code here...
+
+
+# clean
+clean: .clean-pre .clean-impl .clean-post
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post:
+# Add your post 'clean' code here...
+
+
+# clobber
+clobber: .clobber-pre .clobber-impl .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post:
+# Add your post 'clobber' code here...
+
+
+# all
+all: .all-pre .all-impl .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post:
+# Add your post 'all' code here...
+
+
+# help
+help: .help-pre .help-impl .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post:
+# Add your post 'help' code here...
+
+
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
diff --git a/src/main/cpp/jnilib/solaris-sparc/nbproject/configurations.xml b/src/main/cpp/jnilib/solaris-sparc/nbproject/configurations.xml
new file mode 100644
index 0000000..98c3b5c
--- /dev/null
+++ b/src/main/cpp/jnilib/solaris-sparc/nbproject/configurations.xml
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<configurationDescriptor version="35">
+ <logicalFolder name="root" displayName="root" projectFiles="true">
+ <logicalFolder name="SourceFiles"
+ displayName="Source Files"
+ projectFiles="true">
+ <itemPath>../.common/src/CommonUtils.c</itemPath>
+ <itemPath>../.unix/src/jni_UnixNativeUtils.c</itemPath>
+ </logicalFolder>
+ <logicalFolder name="HeaderFiles"
+ displayName="Header Files"
+ projectFiles="true">
+ <itemPath>../.common/src/CommonUtils.h</itemPath>
+ <itemPath>../.unix/src/jni_UnixNativeUtils.h</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ResourceFiles"
+ displayName="Resource Files"
+ projectFiles="true">
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ </logicalFolder>
+ <projectmakefile>Makefile</projectmakefile>
+ <defaultConf>0</defaultConf>
+ <confs>
+ <conf name="Debug" type="2">
+ <toolsSet>
+ <compilerSet>Sun12</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>0</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-m32 -shared -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -xO2 -Xa</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-m32 -shared -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -xO2 -Xa</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/solaris-sparc.so</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerNorunpath>false</linkerNorunpath>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ <conf name="Release" type="2">
+ <toolsSet>
+ <compilerSet>GNU</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>0</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>5</developmentMode>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>5</developmentMode>
+ </ccCompilerTool>
+ <fortranCompilerTool>
+ <developmentMode>5</developmentMode>
+ </fortranCompilerTool>
+ <linkerTool>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ <conf name="Debug_x64" type="2">
+ <toolsSet>
+ <compilerSet>Sun12</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>0</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <sixtyfourBits>true</sixtyfourBits>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-fPIC -shared -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -xO2 -Xa</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <sixtyfourBits>true</sixtyfourBits>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-fPIC -shared -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -xO2 -Xa</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/solaris-sparcv9.so</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerNorunpath>false</linkerNorunpath>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ <conf name="Debug_gnu" type="2">
+ <toolsSet>
+ <compilerSet>GNU</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>0</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-m32 -fPIC -shared -static-libgcc -mimpure-text -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-m32 -fPIC -shared -static-libgcc -mimpure-text -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/solaris-sparc.so</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerNorunpath>false</linkerNorunpath>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ <conf name="Debug_x64_gnu" type="2">
+ <toolsSet>
+ <compilerSet>GNU</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>0</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <sixtyfourBits>true</sixtyfourBits>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-fPIC -shared -static-libgcc -mimpure-text -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <sixtyfourBits>true</sixtyfourBits>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-fPIC -shared -static-libgcc -mimpure-text -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/solaris-sparcv9.so</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerNorunpath>false</linkerNorunpath>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/src/main/cpp/jnilib/solaris-sparc/nbproject/project.properties b/src/main/cpp/jnilib/solaris-sparc/nbproject/project.properties
new file mode 100644
index 0000000..3807b67
--- /dev/null
+++ b/src/main/cpp/jnilib/solaris-sparc/nbproject/project.properties
@@ -0,0 +1,20 @@
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
diff --git a/src/main/cpp/jnilib/solaris-sparc/nbproject/project.xml b/src/main/cpp/jnilib/solaris-sparc/nbproject/project.xml
new file mode 100644
index 0000000..c6febe0
--- /dev/null
+++ b/src/main/cpp/jnilib/solaris-sparc/nbproject/project.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.cnd.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>NBI Native Library: Solaris Sparc</name>
+ <make-project-type>0</make-project-type>
+ </data>
+ </configuration>
+</project>
diff --git a/src/main/cpp/jnilib/solaris-x86/Makefile b/src/main/cpp/jnilib/solaris-x86/Makefile
new file mode 100644
index 0000000..516847d
--- /dev/null
+++ b/src/main/cpp/jnilib/solaris-x86/Makefile
@@ -0,0 +1,109 @@
+#
+# 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.
+#
+
+#
+# There exist several targets which are by default empty and which can be
+# used for execution of your targets. These targets are usually executed
+# before and after some main targets. They are:
+#
+# .build-pre: called before 'build' target
+# .build-post: called after 'build' target
+# .clean-pre: called before 'clean' target
+# .clean-post: called after 'clean' target
+# .clobber-pre: called before 'clobber' target
+# .clobber-post: called after 'clobber' target
+# .all-pre: called before 'all' target
+# .all-post: called after 'all' target
+# .help-pre: called before 'help' target
+# .help-post: called after 'help' target
+#
+# Targets beginning with '.' are not intended to be called on their own.
+#
+# Main targets can be executed directly, and they are:
+#
+# build build a specific configuration
+# clean remove built files from a configuration
+# clobber remove all built files
+# all build all configurations
+# help print help mesage
+#
+# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+# .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+RANLIB=ranlib
+
+
+# build
+build: .build-pre .build-impl .build-post
+
+.build-pre:
+# Add your pre 'build' code here...
+
+.build-post:
+# Add your post 'build' code here...
+
+
+# clean
+clean: .clean-pre .clean-impl .clean-post
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post:
+# Add your post 'clean' code here...
+
+
+# clobber
+clobber: .clobber-pre .clobber-impl .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post:
+# Add your post 'clobber' code here...
+
+
+# all
+all: .all-pre .all-impl .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post:
+# Add your post 'all' code here...
+
+
+# help
+help: .help-pre .help-impl .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post:
+# Add your post 'help' code here...
+
+
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
diff --git a/src/main/cpp/jnilib/solaris-x86/nbproject/configurations.xml b/src/main/cpp/jnilib/solaris-x86/nbproject/configurations.xml
new file mode 100644
index 0000000..18c1468
--- /dev/null
+++ b/src/main/cpp/jnilib/solaris-x86/nbproject/configurations.xml
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<configurationDescriptor version="35">
+ <logicalFolder name="root" displayName="root" projectFiles="true">
+ <logicalFolder name="SourceFiles"
+ displayName="Source Files"
+ projectFiles="true">
+ <itemPath>../.common/src/CommonUtils.c</itemPath>
+ <itemPath>../.unix/src/jni_UnixNativeUtils.c</itemPath>
+ </logicalFolder>
+ <logicalFolder name="HeaderFiles"
+ displayName="Header Files"
+ projectFiles="true">
+ <itemPath>../.common/src/CommonUtils.h</itemPath>
+ <itemPath>../.unix/src/jni_UnixNativeUtils.h</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ResourceFiles"
+ displayName="Resource Files"
+ projectFiles="true">
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ </logicalFolder>
+ <projectmakefile>Makefile</projectmakefile>
+ <defaultConf>0</defaultConf>
+ <confs>
+ <conf name="Debug" type="2">
+ <toolsSet>
+ <compilerSet>Sun12</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>1</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-m32 -fPIC -shared -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -xO2 -Xa</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-m32 -fPIC -shared -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -xO2 -Xa</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/solaris-x86.so</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerNorunpath>false</linkerNorunpath>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ <conf name="Release" type="2">
+ <toolsSet>
+ <compilerSet>GNU</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>0</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>5</developmentMode>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>5</developmentMode>
+ </ccCompilerTool>
+ <fortranCompilerTool>
+ <developmentMode>5</developmentMode>
+ </fortranCompilerTool>
+ <linkerTool>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ <conf name="Debug_x64" type="2">
+ <toolsSet>
+ <compilerSet>Sun12</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>1</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <sixtyfourBits>true</sixtyfourBits>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-KPIC -shared -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -xO2 -Xa</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <sixtyfourBits>true</sixtyfourBits>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-KPIC -shared -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -xO2 -Xa</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/solaris-amd64.so</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerNorunpath>false</linkerNorunpath>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ <conf name="Debug_gnu" type="2">
+ <toolsSet>
+ <compilerSet>GNU</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>1</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-m32 -fPIC -static-libgcc -shared -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-m32 -fPIC -static-libgcc -shared -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/solaris-x86.so</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerNorunpath>false</linkerNorunpath>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ <conf name="Debug_x64_gnu" type="2">
+ <toolsSet>
+ <compilerSet>GNU</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>1</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <sixtyfourBits>true</sixtyfourBits>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-fPIC -static-libgcc -shared -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <sixtyfourBits>true</sixtyfourBits>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/solaris</directoryPath>
+ </includeDirectories>
+ <commandLine>-fPIC -static-libgcc -shared -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/solaris-amd64.so</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerNorunpath>false</linkerNorunpath>
+ <linkerLibItems>
+ </linkerLibItems>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.unix/src/jni_UnixNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/src/main/cpp/jnilib/solaris-x86/nbproject/project.properties b/src/main/cpp/jnilib/solaris-x86/nbproject/project.properties
new file mode 100644
index 0000000..3807b67
--- /dev/null
+++ b/src/main/cpp/jnilib/solaris-x86/nbproject/project.properties
@@ -0,0 +1,20 @@
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
diff --git a/src/main/cpp/jnilib/solaris-x86/nbproject/project.xml b/src/main/cpp/jnilib/solaris-x86/nbproject/project.xml
new file mode 100644
index 0000000..fdb4477
--- /dev/null
+++ b/src/main/cpp/jnilib/solaris-x86/nbproject/project.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.cnd.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>NBI Native Library: Solaris X86</name>
+ <make-project-type>0</make-project-type>
+ </data>
+ </configuration>
+</project>
diff --git a/src/main/cpp/jnilib/windows/Makefile b/src/main/cpp/jnilib/windows/Makefile
new file mode 100644
index 0000000..516847d
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/Makefile
@@ -0,0 +1,109 @@
+#
+# 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.
+#
+
+#
+# There exist several targets which are by default empty and which can be
+# used for execution of your targets. These targets are usually executed
+# before and after some main targets. They are:
+#
+# .build-pre: called before 'build' target
+# .build-post: called after 'build' target
+# .clean-pre: called before 'clean' target
+# .clean-post: called after 'clean' target
+# .clobber-pre: called before 'clobber' target
+# .clobber-post: called after 'clobber' target
+# .all-pre: called before 'all' target
+# .all-post: called after 'all' target
+# .help-pre: called before 'help' target
+# .help-post: called after 'help' target
+#
+# Targets beginning with '.' are not intended to be called on their own.
+#
+# Main targets can be executed directly, and they are:
+#
+# build build a specific configuration
+# clean remove built files from a configuration
+# clobber remove all built files
+# all build all configurations
+# help print help mesage
+#
+# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+# .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+RANLIB=ranlib
+
+
+# build
+build: .build-pre .build-impl .build-post
+
+.build-pre:
+# Add your pre 'build' code here...
+
+.build-post:
+# Add your post 'build' code here...
+
+
+# clean
+clean: .clean-pre .clean-impl .clean-post
+
+.clean-pre:
+# Add your pre 'clean' code here...
+
+.clean-post:
+# Add your post 'clean' code here...
+
+
+# clobber
+clobber: .clobber-pre .clobber-impl .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post:
+# Add your post 'clobber' code here...
+
+
+# all
+all: .all-pre .all-impl .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post:
+# Add your post 'all' code here...
+
+
+# help
+help: .help-pre .help-impl .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post:
+# Add your post 'help' code here...
+
+
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
diff --git a/src/main/cpp/jnilib/windows/Makefile-vc b/src/main/cpp/jnilib/windows/Makefile-vc
new file mode 100644
index 0000000..131aee1
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/Makefile-vc
@@ -0,0 +1,76 @@
+#
+#
+
+
+!include <$(PLATFORM_SDK)/include/win32.mak>
+
+# define the compiler and linker for all the platforms
+CC32="$(VC_2005)\Bin\cl.exe"
+L32="$(VC_2005)\Bin\link.exe"
+
+CC32_OPTS=/O1 /Os /I "$(VC_2005)\include" /I "$(PLATFORM_SDK)\Include" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "NBIJNILIBRARY_EXPORTS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_STATIC_CPPLIB" /D "_LITTLE_ENDIAN" /D "_WINDLL" /FD /MT /Fo".\build\32bit\\" /W3 /WX /c /Wp64 /Gd /TC
+L32_OPTS=/OUT:".\dist\windows-x86.dll" /INCREMENTAL:NO /LIBPATH:"$(PLATFORM_SDK)\Lib" /LIBPATH:"$(VC_2005)\lib" /DLL /MANIFEST:NO /IGNOREIDL /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /MACHINE:X86 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
+
+
+CC64="$(PLATFORM_SDK)\Bin\win64\x86\AMD64\cl.exe"
+L64="$(PLATFORM_SDK)\Bin\win64\x86\AMD64\link.exe"
+
+CC64_OPTS=/O1 /Os /I "$(VC_2005)\include" /I "$(PLATFORM_SDK)\Include" /I "$(PLATFORM_SDK)\Include\win64\crt\amd64" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "NBIJNILIBRARY_EXPORTS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_STATIC_CPPLIB" /D "_LITTLE_ENDIAN" /D "_WINDLL" /FD /MT /Fo".\build\64bit\\" /W3 /c /Wp64 /Gd /TC
+L64_OPTS=/OUT:".\dist\windows-x64.dll" /INCREMENTAL:NO /LIBPATH:"$(PLATFORM_SDK)\Lib\amd64" /LIBPATH:"$(VC_2005)\lib" /DLL /MANIFEST:NO /IGNOREIDL /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /MACHINE:AMD64 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib bufferoverflowU.lib
+
+CCIA64="$(PLATFORM_SDK)\Bin\win64\cl.exe"
+LIA64="$(PLATFORM_SDK)\Bin\win64\link.exe"
+
+CCIA64_OPTS=/O1 /Os /I "$(VC_2005)\include" /I "$(PLATFORM_SDK)\Include" /I "$(PLATFORM_SDK)\Include\win64\crt\amd64" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "NBIJNILIBRARY_EXPORTS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_STATIC_CPPLIB" /D "_LITTLE_ENDIAN" /D "_WINDLL" /FD /MT /Fo".\build\ia64\\" /W3 /c /Wp64 /Gd /TC
+LIA64_OPTS=/OUT:".\dist\windows-ia64.dll" /INCREMENTAL:NO /LIBPATH:"$(PLATFORM_SDK)\Lib\ia64" /LIBPATH:"$(VC_2005)\lib" /DLL /MANIFEST:NO /IGNOREIDL /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /MACHINE:IA64 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib bufferoverflowU.lib
+
+
+all: init build-32 build-64 build-ia64
+
+init:
+ - md .\build\32bit
+ - md .\build\64bit
+ - md .\build\ia64
+ - md .\dist
+
+ del /Q /S build
+
+ del /Q .\dist\windows-x86.*
+ del /Q .\dist\windows-x64.*
+ del /Q .\dist\windows-ia64.*
+
+build-32:
+ Set CPU=i386
+ Set Lib=%PLATFORM_SDK%\Lib;%Lib%
+ Set Include=%PLATFORM_SDK%\Include;%Include%
+ Set Path=%PLATFORM_SDK%\Bin;%PLATFORM_SDK%\Bin\WinNT;%VC_2005_PATH%;%path%
+ Set APPVER=5.01
+ Set TARGETOS=WINNT
+
+ $(CC32) $(CC32_OPTS) .\src\WindowsUtils.c .\src\jni_WindowsRegistry.c .\src\jni_WindowsNativeUtils.c .\..\.common\src\CommonUtils.c
+ $(L32) $(L32_OPTS) ".\build\32bit\WindowsUtils.obj" ".\build\32bit\jni_WindowsRegistry.obj" ".\build\32bit\jni_WindowsNativeUtils.obj" ".\build\32bit\CommonUtils.obj"
+
+
+build-64:
+ Set CPU=AMD64
+ Set Lib=%PLATFORM_SDK%\Lib\AMD64;%PLATFORM_SDK%\Lib\AMD64\atlmfc;
+ Set Include=%PLATFORM_SDK%\Include;%PLATFORM_SDK%\Include\crt;%PLATFORM_SDK%\Include\crt\sys;%PLATFORM_SDK%\Include\mfc;%PLATFORM_SDK%\Include\atl
+ Set Path=%PLATFORM_SDK%\Bin\Win64\x86\AMD64;%PLATFORM_SDK%\Bin;%PLATFORM_SDK%\Bin\WinNT;%path%
+ Set APPVER=5.02
+ Set TARGETOS=WINNT
+
+ $(CC64) $(CC64_OPTS) .\src\WindowsUtils.c .\src\jni_WindowsRegistry.c .\src\jni_WindowsNativeUtils.c .\..\.common\src\CommonUtils.c
+ $(L64) $(L64_OPTS) ".\build\64bit\WindowsUtils.obj" ".\build\64bit\jni_WindowsRegistry.obj" ".\build\64bit\jni_WindowsNativeUtils.obj" ".\build\64bit\CommonUtils.obj"
+
+
+build-ia64:
+ Set CPU=IA64
+ Set Lib=%PLATFORM_SDK%\Lib\IA64;%PLATFORM_SDK%\Lib\IA64\atlmfc;
+ Set Include=%PLATFORM_SDK%\Include;%PLATFORM_SDK%\Include\crt;%PLATFORM_SDK%\Include\crt\sys;%PLATFORM_SDK%\Include\mfc;%PLATFORM_SDK%\Include\atl
+ Set Path=%PLATFORM_SDK%\Bin\Win64;%PLATFORM_SDK%\Bin;%PLATFORM_SDK%\Bin\WinNT;%path%
+ Set APPVER=5.02
+ Set TARGETOS=WINNT
+
+ $(CCIA64) $(CCIA64_OPTS) .\src\WindowsUtils.c .\src\jni_WindowsRegistry.c .\src\jni_WindowsNativeUtils.c .\..\.common\src\CommonUtils.c
+ $(LIA64) $(LIA64_OPTS) ".\build\ia64\WindowsUtils.obj" ".\build\ia64\jni_WindowsRegistry.obj" ".\build\ia64\jni_WindowsNativeUtils.obj" ".\build\ia64\CommonUtils.obj"
+
diff --git a/src/main/cpp/jnilib/windows/Makefile-vc-wo-crt b/src/main/cpp/jnilib/windows/Makefile-vc-wo-crt
new file mode 100644
index 0000000..e344b28
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/Makefile-vc-wo-crt
@@ -0,0 +1,79 @@
+#
+#
+
+
+!include <$(PLATFORM_SDK)/include/win32.mak>
+
+# define the compiler and linker for all the platforms
+CC32="$(VC_2005)\Bin\cl.exe"
+L32="$(VC_2005)\Bin\link.exe"
+
+L32_LIBS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
+CC32_OPTS=/GS- /O1 /Os /I "$(VC_2005)\include" /I "$(PLATFORM_SDK)\Include" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "NBIJNILIBRARY_EXPORTS" /D "_LITTLE_ENDIAN" /D "_WINDLL" /FD /MD /Fo".\build\32bit\\" /W3 /WX /c /Wp64 /Gd /TC
+L32_OPTS=/NOENTRY /NODEFAULTLIB /OUT:".\dist\windows-x86.dll" /INCREMENTAL:NO /LIBPATH:"$(PLATFORM_SDK)\Lib" /LIBPATH:"$(VC_2005)\lib" /DLL /MANIFEST:NO /IGNOREIDL /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /MACHINE:X86 $(L32_LIBS)
+
+
+CC64="$(PLATFORM_SDK)\Bin\win64\x86\AMD64\cl.exe"
+L64="$(PLATFORM_SDK)\Bin\win64\x86\AMD64\link.exe"
+
+L64_LIBS=$(L32_LIBS)
+CC64_OPTS=/O1 /Os /GS- /I "$(VC_2005)\include" /I "$(PLATFORM_SDK)\Include" /I "$(PLATFORM_SDK)\Include\win64\crt\amd64" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "NBIJNILIBRARY_EXPORTS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_LITTLE_ENDIAN" /D "_WINDLL" /FD /MD /Fo".\build\64bit\\" /W3 /c /Wp64 /Gd /TC
+L64_OPTS=/NOENTRY /NODEFAULTLIB /OUT:".\dist\windows-x64.dll" /INCREMENTAL:NO /LIBPATH:"$(PLATFORM_SDK)\Lib\amd64" /LIBPATH:"$(VC_2005)\lib" /DLL /MANIFEST:NO /IGNOREIDL /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /MACHINE:AMD64 $(L64_LIBS)
+
+CCIA64="$(PLATFORM_SDK)\Bin\win64\cl.exe"
+LIA64="$(PLATFORM_SDK)\Bin\win64\link.exe"
+
+LIA64_LIBS=$(L32_LIBS)
+CCIA64_OPTS=/O1 /Os /GS- /I "$(VC_2005)\include" /I "$(PLATFORM_SDK)\Include" /I "$(PLATFORM_SDK)\Include\win64\crt\amd64" /I "$(JAVA_HOME)\include" /I "$(JAVA_HOME)\include\win32" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "NBIJNILIBRARY_EXPORTS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_LITTLE_ENDIAN" /D "_WINDLL" /FD /MD /Fo".\build\ia64\\" /W3 /c /Wp64 /Gd /TC
+LIA64_OPTS=/NOENTRY /NODEFAULTLIB /OUT:".\dist\windows-ia64.dll" /INCREMENTAL:NO /LIBPATH:"$(PLATFORM_SDK)\Lib\ia64" /LIBPATH:"$(VC_2005)\lib" /DLL /MANIFEST:NO /IGNOREIDL /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /MACHINE:IA64 $(LIA64_LIBS)
+
+
+all: init build-32 build-64 build-ia64
+
+init:
+ - md .\build\32bit
+ - md .\build\64bit
+ - md .\build\ia64
+ - md .\dist
+
+ del /Q /S build
+
+ del /Q .\dist\windows-x86.*
+ del /Q .\dist\windows-x64.*
+ del /Q .\dist\windows-ia64.*
+
+build-32:
+ Set CPU=i386
+ Set Lib=%PLATFORM_SDK%\Lib;%Lib%
+ Set Include=%PLATFORM_SDK%\Include;%Include%
+ Set Path=%PLATFORM_SDK%\Bin;%PLATFORM_SDK%\Bin\WinNT;%VC_2005_PATH%;%path%
+ Set APPVER=5.01
+ Set TARGETOS=WINNT
+
+ $(CC32) $(CC32_OPTS) .\src\WindowsUtils.c .\src\jni_WindowsRegistry.c .\src\jni_WindowsNativeUtils.c .\..\.common\src\CommonUtils.c
+ $(L32) $(L32_OPTS) ".\build\32bit\WindowsUtils.obj" ".\build\32bit\jni_WindowsRegistry.obj" ".\build\32bit\jni_WindowsNativeUtils.obj" ".\build\32bit\CommonUtils.obj"
+
+
+build-64:
+ Set CPU=AMD64
+ Set Lib=%PLATFORM_SDK%\Lib\AMD64;%PLATFORM_SDK%\Lib\AMD64\atlmfc;
+ Set Include=%PLATFORM_SDK%\Include;%PLATFORM_SDK%\Include\crt;%PLATFORM_SDK%\Include\crt\sys;%PLATFORM_SDK%\Include\mfc;%PLATFORM_SDK%\Include\atl
+ Set Path=%PLATFORM_SDK%\Bin\Win64\x86\AMD64;%PLATFORM_SDK%\Bin;%PLATFORM_SDK%\Bin\WinNT;%path%
+ Set APPVER=5.02
+ Set TARGETOS=WINNT
+
+ $(CC64) $(CC64_OPTS) .\src\WindowsUtils.c .\src\jni_WindowsRegistry.c .\src\jni_WindowsNativeUtils.c .\..\.common\src\CommonUtils.c
+ $(L64) $(L64_OPTS) ".\build\64bit\WindowsUtils.obj" ".\build\64bit\jni_WindowsRegistry.obj" ".\build\64bit\jni_WindowsNativeUtils.obj" ".\build\64bit\CommonUtils.obj"
+
+
+build-ia64:
+ Set CPU=IA64
+ Set Lib=%PLATFORM_SDK%\Lib\IA64;%PLATFORM_SDK%\Lib\IA64\atlmfc;
+ Set Include=%PLATFORM_SDK%\Include;%PLATFORM_SDK%\Include\crt;%PLATFORM_SDK%\Include\crt\sys;%PLATFORM_SDK%\Include\mfc;%PLATFORM_SDK%\Include\atl
+ Set Path=%PLATFORM_SDK%\Bin\Win64;%PLATFORM_SDK%\Bin;%PLATFORM_SDK%\Bin\WinNT;%path%
+ Set APPVER=5.02
+ Set TARGETOS=WINNT
+
+ $(CCIA64) $(CCIA64_OPTS) .\src\WindowsUtils.c .\src\jni_WindowsRegistry.c .\src\jni_WindowsNativeUtils.c .\..\.common\src\CommonUtils.c
+ $(LIA64) $(LIA64_OPTS) ".\build\ia64\WindowsUtils.obj" ".\build\ia64\jni_WindowsRegistry.obj" ".\build\ia64\jni_WindowsNativeUtils.obj" ".\build\ia64\CommonUtils.obj"
+
diff --git a/src/main/cpp/jnilib/windows/nbproject/configurations.xml b/src/main/cpp/jnilib/windows/nbproject/configurations.xml
new file mode 100644
index 0000000..b7731b5
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/nbproject/configurations.xml
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<configurationDescriptor version="35">
+ <logicalFolder name="root" displayName="root" projectFiles="true">
+ <logicalFolder name="SourceFiles"
+ displayName="Source Files"
+ projectFiles="true">
+ <itemPath>../.common/src/CommonUtils.c</itemPath>
+ <itemPath>src/jni_WindowsNativeUtils.c</itemPath>
+ <itemPath>src/jni_WindowsRegistry.c</itemPath>
+ <itemPath>src/WindowsUtils.c</itemPath>
+ </logicalFolder>
+ <logicalFolder name="HeaderFiles"
+ displayName="Header Files"
+ projectFiles="true">
+ <itemPath>../.common/src/CommonUtils.h</itemPath>
+ <itemPath>src/jni_WindowsNativeUtils.h</itemPath>
+ <itemPath>src/jni_WindowsRegistry.h</itemPath>
+ <itemPath>src/WindowsUtils.h</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ResourceFiles"
+ displayName="Resource Files"
+ projectFiles="true">
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ </logicalFolder>
+ <projectmakefile>Makefile</projectmakefile>
+ <defaultConf>0</defaultConf>
+ <confs>
+ <conf name="Default-32bit" type="2">
+ <toolsSet>
+ <compilerSet>Cygwin</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>3</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/win32</directoryPath>
+ </includeDirectories>
+ <commandLine>-mno-cygwin</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include\win32</directoryPath>
+ </includeDirectories>
+ <commandLine>-mno-cygwin</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/windows.dll</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerLibItems>
+ <linkerOptionItem>-lole32</linkerOptionItem>
+ <linkerOptionItem>-luuid</linkerOptionItem>
+ </linkerLibItems>
+ <commandLine>-Wl,--add-stdcall-alias</commandLine>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="src/WindowsUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="src/WindowsUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="src/jni_WindowsNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="src/jni_WindowsNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="src/jni_WindowsRegistry.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="src/jni_WindowsRegistry.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ <conf name="Default-64bit" type="2">
+ <toolsSet>
+ <compilerSet>Cygwin</compilerSet>
+ <cRequired>true</cRequired>
+ <cppRequired>true</cppRequired>
+ <fortranRequired>false</fortranRequired>
+ <platform>3</platform>
+ </toolsSet>
+ <compileType>
+ <cCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include/win32</directoryPath>
+ </includeDirectories>
+ <commandLine>-mno-cygwin</commandLine>
+ </cCompilerTool>
+ <ccCompilerTool>
+ <developmentMode>0</developmentMode>
+ <stripSymbols>true</stripSymbols>
+ <includeDirectories>
+ <directoryPath>/usr/java/include</directoryPath>
+ <directoryPath>/usr/java/include\win32</directoryPath>
+ </includeDirectories>
+ <commandLine>-mno-cygwin</commandLine>
+ </ccCompilerTool>
+ <linkerTool>
+ <output>dist/windows.dll</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerLibItems>
+ <linkerOptionItem>-lole32</linkerOptionItem>
+ <linkerOptionItem>-luuid</linkerOptionItem>
+ </linkerLibItems>
+ <commandLine>-Wl,--add-stdcall-alias</commandLine>
+ </linkerTool>
+ </compileType>
+ <item path="../.common/src/CommonUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="../.common/src/CommonUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="src/WindowsUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="src/WindowsUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="src/jni_WindowsNativeUtils.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="src/jni_WindowsNativeUtils.h">
+ <itemTool>3</itemTool>
+ </item>
+ <item path="src/jni_WindowsRegistry.c">
+ <itemTool>0</itemTool>
+ </item>
+ <item path="src/jni_WindowsRegistry.h">
+ <itemTool>3</itemTool>
+ </item>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/src/main/cpp/jnilib/windows/nbproject/project.properties b/src/main/cpp/jnilib/windows/nbproject/project.properties
new file mode 100644
index 0000000..3807b67
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/nbproject/project.properties
@@ -0,0 +1,20 @@
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
diff --git a/src/main/cpp/jnilib/windows/nbproject/project.xml b/src/main/cpp/jnilib/windows/nbproject/project.xml
new file mode 100644
index 0000000..1aa64eb
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/nbproject/project.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.cnd.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>NBI Native Library: Windows</name>
+ <make-project-type>0</make-project-type>
+ </data>
+ </configuration>
+</project>
diff --git a/src/main/cpp/jnilib/windows/src/WindowsUtils.c b/src/main/cpp/jnilib/windows/src/WindowsUtils.c
new file mode 100644
index 0000000..fe4972d
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/src/WindowsUtils.c
@@ -0,0 +1,146 @@
+/*
+ * 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 <jni.h>
+#include <windows.h>
+#include <winreg.h>
+#include <winnt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+
+#include "../../.common/src/CommonUtils.h"
+#include "WindowsUtils.h"
+#include "jni_WindowsRegistry.h"
+
+HKEY getHKEY(jint jSection) {
+ switch (jSection) {
+ case org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_CLASSES_ROOT:
+ return HKEY_CLASSES_ROOT;
+ case org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_CURRENT_USER:
+ return HKEY_CURRENT_USER;
+ case org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_LOCAL_MACHINE:
+ return HKEY_LOCAL_MACHINE;
+ case org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_USERS:
+ return HKEY_USERS;
+ case org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_CURRENT_CONFIG:
+ return HKEY_CURRENT_CONFIG;
+ case org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_DYN_DATA:
+ return HKEY_DYN_DATA;
+ case org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_PERFORMANCE_DATA:
+ return HKEY_PERFORMANCE_DATA;
+ default:
+ return NULL;
+ }
+}
+
+LONG getMode(jint jmode) {
+ switch (jmode) {
+ case org_netbeans_installer_utils_system_windows_WindowsRegistry_MODE_DEFAULT:
+ return 0L;
+ case org_netbeans_installer_utils_system_windows_WindowsRegistry_MODE_32BIT:
+ return KEY_WOW64_32KEY;
+ case org_netbeans_installer_utils_system_windows_WindowsRegistry_MODE_64BIT:
+ return KEY_WOW64_64KEY;
+ default:
+ return 0L;
+ }
+}
+
+
+int queryValue(int mode, HKEY section, const unsigned short* key, const unsigned short* name, DWORD* type, DWORD* size, byte** value, int expand) {
+ int result = 1;
+
+ HKEY hkey = 0;
+ int tempType = 0;
+ int tempSize = 0;
+ byte* tempValue = NULL;
+
+ if (RegOpenKeyExW(section, key, 0, KEY_QUERY_VALUE | mode, &hkey) == ERROR_SUCCESS) {
+ if (RegQueryValueExW(hkey, name, NULL, (LPDWORD) &tempType, NULL, (LPDWORD) &tempSize) == ERROR_SUCCESS) {
+ tempValue = (byte*) MALLOC(tempSize + 8);
+
+ if (tempValue != NULL) {
+ ZERO(tempValue, tempSize + 8);
+
+ if (RegQueryValueExW(hkey, name, NULL, (LPDWORD) &tempType, tempValue, (LPDWORD) &tempSize) == ERROR_SUCCESS) {
+ if (expand && (tempType == REG_EXPAND_SZ)) {
+ int expandedSize = (int) WCSLEN((unsigned short*) tempValue) + 2;
+ byte* expandedValue = (byte*) MALLOC(expandedSize * sizeof(wchar_t));
+ int expandedCharsNumber = 0;
+ ZERO(expandedValue, expandedSize);
+ expandedCharsNumber = ExpandEnvironmentStringsW((unsigned short*) tempValue, (unsigned short*) expandedValue, tempSize);
+ if (expandedCharsNumber > tempSize) {
+ FREE(expandedValue);
+ expandedValue = (byte*) MALLOC(expandedCharsNumber * sizeof(wchar_t));
+ expandedCharsNumber = ExpandEnvironmentStringsW((unsigned short*) tempValue, (unsigned short*) expandedValue, expandedCharsNumber);
+ }
+
+ FREE(tempValue);
+ tempValue = expandedValue;
+ }
+ } else {
+ FREE(tempValue);
+ result = 0;
+ }
+ }
+ } else {
+ result = 0;
+ }
+ } else {
+ result = 0;
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ if (type != NULL) {
+ *type = tempType;
+ }
+ if (size != NULL) {
+ *size = tempSize;
+ }
+ if ((value != NULL) && (tempValue != NULL)) {
+ *value = tempValue;
+ }
+
+ return result;
+}
+
+int setValue(int mode, HKEY section, const unsigned short* key, const unsigned short* name, DWORD type, const byte* data, int size, int expand) {
+ int result = 1;
+
+ HKEY hkey = 0;
+
+ if (RegOpenKeyExW(section, key, 0, KEY_SET_VALUE | mode, &hkey) == ERROR_SUCCESS) {
+ if (!(RegSetValueExW(hkey, name, 0, type, data, size) == ERROR_SUCCESS)) {
+ result = 0;
+ }
+ } else {
+ result = 0;
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ return result;
+}
diff --git a/src/main/cpp/jnilib/windows/src/WindowsUtils.h b/src/main/cpp/jnilib/windows/src/WindowsUtils.h
new file mode 100644
index 0000000..947c63e
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/src/WindowsUtils.h
@@ -0,0 +1,48 @@
+/*
+ * 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 <jni.h>
+#include <windows.h>
+#include <winreg.h>
+#include <winnt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+
+#include "../../.common/src/CommonUtils.h"
+
+#ifndef _WindowsUtils_H
+#define _WindowsUtils_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HKEY getHKEY(jint jSection);
+
+int queryValue(int mode, HKEY section, const unsigned short * key, const unsigned short * name, DWORD* type, DWORD* size, byte** value, int expand);
+
+int setValue(int mode, HKEY section, const unsigned short * key, const unsigned short * name, DWORD type, const byte* data, int size, int expand);
+
+LONG getMode(jint jmode);
+#ifdef __cplusplus
+}
+#endif
+#endif // _WindowsUtils_H
diff --git a/src/main/cpp/jnilib/windows/src/jni_WindowsNativeUtils.c b/src/main/cpp/jnilib/windows/src/jni_WindowsNativeUtils.c
new file mode 100644
index 0000000..6d7c60b
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/src/jni_WindowsNativeUtils.c
@@ -0,0 +1,400 @@
+/*
+ * 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 <jni.h>
+#include <windows.h>
+#include <lmcons.h>
+#include <shlguid.h>
+#include <shlobj.h>
+
+#include "../../.common/src/CommonUtils.h"
+#include "WindowsUtils.h"
+#include "jni_WindowsNativeUtils.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// Functions
+
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_isCurrentUserAdmin0(JNIEnv* jEnv, jobject jObject) {
+ BOOL result = FALSE;
+
+ PACL pACL = NULL;
+ PSID psidAdmin = NULL;
+ HANDLE token = NULL;
+ HANDLE duplToken = NULL;
+ PSECURITY_DESCRIPTOR adminDescriptor = NULL;
+
+ SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
+ DWORD aclSize;
+
+ const DWORD ACCESS_READ = 1;
+ const DWORD ACCESS_WRITE = 2;
+
+ GENERIC_MAPPING mapping;
+
+ PRIVILEGE_SET ps;
+ DWORD status;
+ DWORD structSize = sizeof(PRIVILEGE_SET);
+
+ // MS KB 118626
+ while (TRUE) {
+ if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &token)) {
+ if (GetLastError() != ERROR_NO_TOKEN) {
+ throwException(jEnv, "Native error");
+ break;
+ }
+
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &token)) {
+ throwException(jEnv, "Native error");
+ break;
+ }
+ }
+
+ if (!DuplicateToken(token, SecurityImpersonation, &duplToken)) {
+ throwException(jEnv, "Native error");
+ break;
+ }
+
+ if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) {
+ throwException(jEnv, "Native error");
+ break;
+ }
+
+ adminDescriptor = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
+ if (adminDescriptor == NULL) {
+ throwException(jEnv, "Native error");
+ break;
+ }
+ if (!InitializeSecurityDescriptor(adminDescriptor, SECURITY_DESCRIPTOR_REVISION)) {
+ throwException(jEnv, "Native error");
+ break;
+ }
+
+ aclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD);
+
+ pACL = (PACL) LocalAlloc(LPTR, aclSize);
+ if (pACL == NULL) {
+ throwException(jEnv, "Native error");
+ break;
+ }
+ if (!InitializeAcl(pACL, aclSize, ACL_REVISION2)) {
+ throwException(jEnv, "Native error");
+ break;
+ }
+
+ if (!AddAccessAllowedAce(pACL, ACL_REVISION2, ACCESS_READ | ACCESS_WRITE , psidAdmin)) {
+ throwException(jEnv, "Native error");
+ break;
+ }
+ if (!SetSecurityDescriptorDacl(adminDescriptor, TRUE, pACL, FALSE)) {
+ throwException(jEnv, "Native error");
+ break;
+ }
+
+ SetSecurityDescriptorGroup(adminDescriptor, psidAdmin, FALSE);
+ SetSecurityDescriptorOwner(adminDescriptor, psidAdmin, FALSE);
+
+ if (!IsValidSecurityDescriptor(adminDescriptor)) {
+ throwException(jEnv, "Native error");
+ break;
+ }
+
+ mapping.GenericRead = ACCESS_READ;
+ mapping.GenericWrite = ACCESS_WRITE;
+ mapping.GenericExecute = 0;
+ mapping.GenericAll = ACCESS_READ | ACCESS_WRITE;
+
+ if (!AccessCheck(adminDescriptor, duplToken, ACCESS_READ, &mapping, &ps, &structSize, &status, &result)) {
+ throwException(jEnv, "Native error");
+ break;
+ }
+
+ break;
+ }
+
+ if (pACL) {
+ LocalFree(pACL);
+ }
+ if (adminDescriptor) {
+ LocalFree(adminDescriptor);
+ }
+ if (psidAdmin) {
+ FreeSid(psidAdmin);
+ }
+ if (duplToken) {
+ CloseHandle(duplToken);
+ }
+ if (token) {
+ CloseHandle(token);
+ }
+
+ return result;
+}
+
+JNIEXPORT jlong JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_getFreeSpace0(JNIEnv* jEnv, jobject jObject, jstring jPath) {
+ WCHAR* path = getWideChars(jEnv, jPath);
+ jlong size = 0;
+ typedef struct int64s { unsigned long Low, High; } int64t;
+ int64t bytes;
+ if (GetDiskFreeSpaceExW(path, (PULARGE_INTEGER) &bytes, NULL, NULL)) {
+ unsigned long h = bytes.High;
+ // workaround of using missing _allmul function
+ // replace multiplication by sum
+ // (2^32 * high + low) = 2^32 + 2^32 + ... (bytes.High times total) + bytes.Low
+ // can be relatively expensive on big sizes (peta bytes and more)
+ while(h > 0) {
+ h--;
+ size+=4294967296L;
+ }
+ size+= bytes.Low;
+ } else {
+ throwException(jEnv, "Native error");
+ }
+
+ FREE(path);
+
+ return size;
+}
+
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_createShortcut0(JNIEnv* jEnv, jobject jObject, jobject jShortcut) {
+ unsigned short *shortcutPath = getWideStringFromMethod(jEnv, jShortcut, "getPath");
+ unsigned short *targetPath = getWideStringFromMethod(jEnv, jShortcut, "getTargetPath");
+ unsigned short *description = getWideStringFromMethod(jEnv, jShortcut, "getDescription");
+ unsigned short *iconPath = getWideStringFromMethod(jEnv, jShortcut, "getIconPath");
+ jint iconIndex = getIntFromMethod (jEnv, jShortcut, "getIconIndex");
+ unsigned short *workingDirectory = getWideStringFromMethod(jEnv, jShortcut, "getWorkingDirectoryPath");
+ unsigned short *arguments = getWideStringFromMethod(jEnv, jShortcut, "getArgumentsString");
+
+ HRESULT tempResult;
+ IShellLinkW* shell;
+
+ HRESULT comStart = CoInitialize(NULL);
+ int errorCode = 0;
+
+ tempResult = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (void **) &shell);
+
+ if (SUCCEEDED(tempResult)) {
+ IPersistFile *persistFile;
+ // we will save the shell link in persistent storage
+ tempResult = shell->lpVtbl->QueryInterface(shell, &IID_IPersistFile, (void **) &persistFile);
+
+ if (SUCCEEDED(tempResult)) {
+ tempResult = shell->lpVtbl->SetPath(shell, targetPath);
+ if (!SUCCEEDED(tempResult)) {
+ throwException(jEnv, "Native error (-2)");
+ errorCode = -2;
+ }
+ // make sure description length is less than MAX_PATH
+ if ((errorCode == 0) && (description != NULL)) {
+ if (WCSLEN(description) < MAX_PATH) {
+ if (!SUCCEEDED(shell->lpVtbl->SetDescription(shell, description))) {
+ throwException(jEnv, "Native error (-3)");
+ errorCode = -3;
+ }
+ } else {
+ unsigned short *desc = (unsigned short *) MALLOC(sizeof(unsigned short) * MAX_PATH);
+ ZERO(desc, sizeof(unsigned short) * MAX_PATH);
+ desc = WCSNCPY(desc, description, MAX_PATH);
+ if (!SUCCEEDED(shell->lpVtbl->SetDescription(shell, desc))) {
+ throwException(jEnv, "Native error (-4)");
+ errorCode = -4;
+ }
+ FREE(desc);
+ }
+ }
+ if ((errorCode == 0) && (arguments != NULL)) {
+ if (!SUCCEEDED(shell->lpVtbl->SetArguments(shell, arguments))) {
+ throwException(jEnv, "Native error (-5)");
+ errorCode = -5;
+ }
+ }
+ if ((errorCode == 0) && (workingDirectory != NULL)) {
+ if (!SUCCEEDED(shell->lpVtbl->SetWorkingDirectory(shell, workingDirectory))) {
+ throwException(jEnv, "Native error (-6)");
+ errorCode = -6;
+ }
+ }
+ if ((errorCode == 0) && (iconPath != NULL)) {
+ if (!SUCCEEDED(shell->lpVtbl->SetIconLocation(shell, iconPath, iconIndex))) {
+ throwException(jEnv, "Native error (-7)");
+ errorCode = -7;
+ }
+ }
+ // use normal window.
+ if (errorCode == 0) {
+ if (!SUCCEEDED(shell->lpVtbl->SetShowCmd(shell, SW_NORMAL))) {
+ throwException(jEnv, "Native error (-8)");
+ errorCode = -8;
+ }
+ }
+ if (errorCode == 0) {
+ if (mkdirsW(jEnv, shortcutPath)) {
+ if (!SUCCEEDED(persistFile->lpVtbl->Save(persistFile, shortcutPath, TRUE))) {
+ throwException(jEnv, "Native error (-9)");
+ errorCode = -9;
+ }
+ } else {
+ throwException(jEnv, "Native error (-10)");
+ errorCode = -10;
+ }
+ }
+
+ if (errorCode == 0) {
+ persistFile->lpVtbl->Release(persistFile);
+ }
+ } else {
+ throwException(jEnv, "Native error (-11)");
+ errorCode = -11;
+ }
+ shell->lpVtbl->Release(shell);
+ } else {
+ throwException(jEnv, "Native error (-12)");
+ errorCode = -12;
+ }
+
+ if (comStart == S_OK) {
+ CoUninitialize();
+ }
+
+ FREE(shortcutPath);
+ FREE(targetPath);
+ FREE(description);
+ FREE(iconPath);
+ FREE(workingDirectory);
+ FREE(arguments);
+}
+
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_deleteFileOnReboot0(JNIEnv* jEnv, jobject jObject, jstring jPath) {
+ unsigned short * path = getWideChars(jEnv, jPath);
+
+ if (!MoveFileExW(path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)) {
+ throwException(jEnv, "Native error");
+ }
+
+ FREE(path);
+}
+
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_createProcessWithoutHandles0(JNIEnv* jEnv, jobject jObject, jstring jCommand) {
+ unsigned short * command = getWideChars(jEnv, jCommand);
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+
+ ZERO(&si, sizeof(si));
+ si.cb = sizeof(si);
+ ZERO(&pi, sizeof(pi));
+ if(!CreateProcessW(NULL, // executable name - use command line
+ command, // command line
+ NULL, // process security attribute
+ NULL, // thread security attribute
+ FALSE, // inherits system handles
+ 0, // no creation flags
+ NULL, // use parent's environment block
+ NULL, // use parent's starting directory
+ &si, // (in) startup information
+ &pi)) { // (out) process information
+ throwException(jEnv, "Cannot create process.\n");
+ }
+
+
+ FREE(command);
+}
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_notifyAssociationChanged0(JNIEnv *jEnv, jobject jObj) {
+ SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_notifyEnvironmentChanged0(JNIEnv *jEnv, jobject jObj) {
+ /* maximum 1 sec timeout for each window in the system */
+ DWORD dwReturnValue = 0;
+ LRESULT result = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) "Environment", SMTO_ABORTIFHUNG, 1000, (PDWORD_PTR) &dwReturnValue);
+ return (result!=0);
+}
+
+
+JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_checkAccessTokenAccessLevel0(JNIEnv *jEnv, jobject jObj, jstring jPath, jint jLevel) {
+ unsigned short * path = getWideChars(jEnv, jPath);
+ PSECURITY_DESCRIPTOR pSD;
+ DWORD nLength;
+
+ PRIVILEGE_SET PrivilegeSet;
+ DWORD PrivSetSize = sizeof (PRIVILEGE_SET);
+
+ HANDLE hToken;
+
+ GENERIC_MAPPING GenericMapping;
+ DWORD DesiredAccess = (DWORD) jLevel ;
+
+ BOOL bAccessGranted;
+ DWORD GrantedAccess;
+
+ // create memory for storing user's security descriptor
+ GetFileSecurityW(path, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, NULL, 0, &nLength);
+
+ pSD = (PSECURITY_DESCRIPTOR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength);
+
+ if (pSD == NULL) {
+ throwException(jEnv, "Unable to allocate memory to store security descriptor.\n");
+ return -1;
+ }
+ // Get the security descriptor
+ if (!GetFileSecurityW(path, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, pSD, nLength, &nLength)) {
+ throwException(jEnv, "Unable to obtain security descriptor.\n");
+ FREE(path);
+ return (-3);
+ }
+ FREE(path);
+
+ /* Perform security impersonation of the user and open */
+ /* the resulting thread token. */
+ if (!ImpersonateSelf(SecurityImpersonation)) {
+ throwException(jEnv, "Unable to perform security impersonation.\n");
+ HeapFree(GetProcessHeap(), 0, pSD);
+ return (-4);
+ }
+
+ if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, FALSE, &hToken)) {
+ throwException(jEnv, "Unable to get current thread's token.\n");
+ HeapFree(GetProcessHeap(), 0, pSD);
+ return (-5);
+ }
+ RevertToSelf();
+
+ ZERO(&GenericMapping, sizeof (GENERIC_MAPPING));
+
+ DesiredAccess = DesiredAccess | STANDARD_RIGHTS_READ;
+ GenericMapping.GenericRead = FILE_GENERIC_READ;
+
+ if(jLevel & FILE_WRITE_DATA) {
+ GenericMapping.GenericWrite = FILE_GENERIC_WRITE;
+ }
+
+ MapGenericMask(&DesiredAccess, &GenericMapping);
+
+ /* Perform access check using the token. */
+ if (!AccessCheck(pSD, hToken, DesiredAccess, &GenericMapping, &PrivilegeSet, &PrivSetSize, &GrantedAccess, &bAccessGranted)) {
+ throwException(jEnv, "Unable to perform access check.\n");
+ CloseHandle(hToken);
+ HeapFree(GetProcessHeap(), 0, pSD);
+ return (-6);
+ }
+ /* Clean up. */
+ HeapFree(GetProcessHeap(), 0, pSD);
+ CloseHandle(hToken);
+ return (bAccessGranted);
+}
+
+
diff --git a/src/main/cpp/jnilib/windows/src/jni_WindowsNativeUtils.h b/src/main/cpp/jnilib/windows/src/jni_WindowsNativeUtils.h
new file mode 100644
index 0000000..9ea87e7
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/src/jni_WindowsNativeUtils.h
@@ -0,0 +1,109 @@
+/*
+ * 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 <jni.h>
+/* Header for class org_netbeans_installer_utils_system_WindowsNativeUtils */
+
+#ifndef _Included_org_netbeans_installer_utils_system_WindowsNativeUtils
+#define _Included_org_netbeans_installer_utils_system_WindowsNativeUtils
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef org_netbeans_installer_utils_system_WindowsNativeUtils_MIN_UID_INDEX
+#define org_netbeans_installer_utils_system_WindowsNativeUtils_MIN_UID_INDEX 1L
+
+#undef org_netbeans_installer_utils_system_WindowsNativeUtils_MAX_UID_INDEX
+#define org_netbeans_installer_utils_system_WindowsNativeUtils_MAX_UID_INDEX 100L
+
+/*
+ * Class: org_netbeans_installer_utils_system_WindowsNativeUtils
+ * Method: isCurrentUserAdmin0
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_isCurrentUserAdmin0
+ (JNIEnv *, jobject);
+
+/*
+ * Class: org_netbeans_installer_utils_system_WindowsNativeUtils
+ * Method: getFreeSpace0
+ * Signature: (Ljava/lang/String;)J
+ */
+JNIEXPORT jlong JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_getFreeSpace0
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_WindowsNativeUtils
+ * Method: createShortcut0
+ * Signature: (Lorg/netbeans/installer/utils/system/shortcut/FileShortcut;)V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_createShortcut0
+ (JNIEnv *, jobject, jobject);
+
+
+/*
+ * Class: org_netbeans_installer_utils_system_WindowsNativeUtils
+ * Method: deleteFileOnReboot0
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_deleteFileOnReboot0
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_WindowsNativeUtils
+ * Method: createProcessWithoutHandles0
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_createProcessWithoutHandles0
+ (JNIEnv *, jobject, jstring);
+
+
+/*
+ * Class: org_netbeans_installer_utils_system_WindowsNativeUtils
+ * Method: notifyAssociationChanged0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_notifyAssociationChanged0
+ (JNIEnv *, jobject);
+
+
+/*
+ * Class: org_netbeans_installer_utils_system_WindowsNativeUtils
+ * Method: checkAccessTokenAccessLevel0
+ * Signature: (Ljava/lang/String;I)I
+ */
+JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_checkAccessTokenAccessLevel0
+ (JNIEnv *, jobject, jstring, jint);
+
+
+/*
+ * Class: org_netbeans_installer_utils_system_WindowsNativeUtils
+ * Method: notifyEnvironmentChanged0
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_WindowsNativeUtils_notifyEnvironmentChanged0
+ (JNIEnv *, jobject);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/main/cpp/jnilib/windows/src/jni_WindowsRegistry.c b/src/main/cpp/jnilib/windows/src/jni_WindowsRegistry.c
new file mode 100644
index 0000000..3608bf0
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/src/jni_WindowsRegistry.c
@@ -0,0 +1,632 @@
+/*
+ * 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 <jni.h>
+#include <windows.h>
+#include <winreg.h>
+#include <winnt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+
+#include "../../.common/src/CommonUtils.h"
+#include "WindowsUtils.h"
+#include "jni_WindowsRegistry.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// Globals
+
+// maximum length of a registry value
+const DWORD MAX_LEN_VALUE_NAME = 16383;
+
+////////////////////////////////////////////////////////////////////////////////
+// Functions
+
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_checkKeyAccess0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey, jint jLevel) {
+ HKEY hkey = 0;
+ unsigned short * key = getWideChars(jEnv, jKey);
+
+ jboolean result = FALSE;
+ REGSAM access = (jLevel==0) ? KEY_READ : KEY_ALL_ACCESS;
+ result = (RegOpenKeyExW(getHKEY(jSection), key, 0, access | getMode(jMode), &hkey) == ERROR_SUCCESS);
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(key);
+
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_valueExists0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey, jstring jName) {
+ HKEY hkey = 0;
+ unsigned short * key = getWideChars(jEnv, jKey);
+ unsigned short * value = getWideChars(jEnv, jName);
+ jboolean result = FALSE;
+ if (RegOpenKeyExW(getHKEY(jSection), key, 0, KEY_QUERY_VALUE | getMode(jMode), &hkey) == ERROR_SUCCESS) {
+ result = (RegQueryValueExW(hkey, value, NULL, NULL, NULL, NULL) == ERROR_SUCCESS);
+ } else {
+ throwException(jEnv, "Cannot open key");
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+ FREE(key);
+ FREE(value);
+
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_keyEmpty0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey) {
+ HKEY hkey = 0;
+ unsigned short* key = getWideChars(jEnv, jKey);
+
+ DWORD subkeys = 1;
+ DWORD values = 1;
+ if (RegOpenKeyExW(getHKEY(jSection), key, 0, KEY_READ | getMode(jMode), &hkey) == ERROR_SUCCESS) {
+ if (RegQueryInfoKeyW(hkey, NULL, NULL, NULL, &subkeys, NULL, NULL, &values, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
+ throwException(jEnv, "Cannot read key data");
+ }
+ } else {
+ throwException(jEnv, "Cannot open key");
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(key);
+
+ return (values + subkeys == 0);
+}
+
+JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_countSubKeys0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey) {
+ HKEY hkey = 0;
+ unsigned short* key = getWideChars(jEnv, jKey);
+
+ DWORD count = 0;
+ if (RegOpenKeyExW(getHKEY(jSection), key, 0, KEY_READ | getMode(jMode), &hkey) == ERROR_SUCCESS) {
+ if(RegQueryInfoKeyW(hkey, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
+ throwException(jEnv, "Cannot read key data");
+ }
+ } else {
+ throwException(jEnv, "Cannot open key");
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(key);
+
+ return count;
+}
+
+JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_countValues0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey) {
+ HKEY hkey = 0;
+ unsigned short* key = getWideChars(jEnv, jKey);
+
+ DWORD count = 0;
+ if (RegOpenKeyExW(getHKEY(jSection), key, 0, KEY_READ | getMode(jMode), &hkey) == ERROR_SUCCESS) {
+ if (RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
+ throwException(jEnv, "Cannot read key data");
+ }
+ } else {
+ throwException(jEnv, "Cannot open key");
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(key);
+
+ return count;
+}
+
+JNIEXPORT jobjectArray JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getSubkeyNames0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey) {
+ HKEY hkey = 0;
+ unsigned short* key = getWideChars(jEnv, jKey);
+ DWORD number = 0;
+ int err = 0;
+ int index = 0 ;
+
+ unsigned short* buffer = (unsigned short*) MALLOC(sizeof(char) * MAX_LEN_VALUE_NAME);
+
+ jobjectArray result = NULL;
+ if (RegOpenKeyExW(getHKEY(jSection), key, 0, KEY_READ | getMode(jMode), &hkey) == ERROR_SUCCESS) {
+ if (RegQueryInfoKeyW(hkey, NULL, NULL, NULL, &number, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
+ jclass stringClazz = (*jEnv)->FindClass(jEnv, "java/lang/String");
+ result = (*jEnv)->NewObjectArray(jEnv, number, stringClazz, NULL);
+
+ do {
+ DWORD size = MAX_LEN_VALUE_NAME;
+ buffer[0] = 0;
+
+ err = RegEnumKeyExW(hkey, index, buffer, &size, NULL, NULL, NULL, NULL);
+ if (err == ERROR_SUCCESS) {
+ (*jEnv)->SetObjectArrayElement(jEnv, result, index, getStringW(jEnv, buffer));
+ } else {
+ if (err != ERROR_NO_MORE_ITEMS) {
+ throwException(jEnv, "Cannot get key names");
+ }
+ }
+
+ index++;
+ } while (err == ERROR_SUCCESS);
+ } else {
+ throwException(jEnv, "Cannot read key data");
+ }
+ } else {
+ throwException(jEnv, "Cannot open key");
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(key);
+ FREE(buffer);
+
+ return result;
+}
+
+JNIEXPORT jobjectArray JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getValueNames0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey) {
+ HKEY hkey = 0;
+ unsigned short* key = getWideChars(jEnv, jKey);
+ DWORD valuesCount = 0;
+ int err = 0;
+ int index = 0;
+
+ unsigned short* buffer = (unsigned short*) MALLOC(sizeof(char) * MAX_LEN_VALUE_NAME);
+
+ jobjectArray result = NULL;
+ if (RegOpenKeyExW(getHKEY(jSection), key, 0, KEY_QUERY_VALUE | getMode(jMode), &hkey) == ERROR_SUCCESS) {
+ if (RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, &valuesCount, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
+ jclass stringClazz = (*jEnv)->FindClass(jEnv, "java/lang/String");
+ result = (*jEnv)->NewObjectArray(jEnv, valuesCount, stringClazz, NULL);
+
+ do {
+ DWORD size = MAX_LEN_VALUE_NAME;
+ buffer[0] = 0;
+
+ err = RegEnumValueW(hkey, index, buffer, &size, NULL, NULL, NULL, NULL);
+ if (err == ERROR_SUCCESS) {
+ (*jEnv)->SetObjectArrayElement(jEnv, result, index, getStringW(jEnv, buffer));
+ } else {
+ if (err != ERROR_NO_MORE_ITEMS) {
+ throwException(jEnv, "Cannot get value names");
+ }
+ }
+
+ index++;
+ } while (err == ERROR_SUCCESS);
+ } else {
+ throwException(jEnv, "Cannot read key data");
+ }
+ } else {
+ throwException(jEnv, "Cannot open key");
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(key);
+ FREE(buffer);
+
+ return result;
+}
+
+JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getValueType0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey, jstring jName) {
+ HKEY hkey =0;
+ unsigned short* key = getWideChars(jEnv, jKey);
+ unsigned short* value = getWideChars(jEnv, jName);
+
+ DWORD type = REG_NONE;
+ if (RegOpenKeyExW(getHKEY(jSection), key, 0, KEY_QUERY_VALUE | getMode(jMode), &hkey) == ERROR_SUCCESS) {
+ if (RegQueryValueExW(hkey, value, NULL, &type, NULL, NULL) != ERROR_SUCCESS) {
+ throwException(jEnv, "Cannot read value");
+ }
+ } else {
+ throwException(jEnv, "Cannot open key");
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(key);
+ FREE(value);
+
+ return type;
+}
+
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_createKey0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jParent, jstring jChild) {
+ HKEY hkey = 0;
+ HKEY newKey = 0;
+ unsigned short* parent = getWideChars(jEnv, jParent);
+ unsigned short* child = getWideChars(jEnv, jChild);
+
+ if (RegOpenKeyExW(getHKEY(jSection), parent, 0, KEY_CREATE_SUB_KEY | getMode(jMode), &hkey) == ERROR_SUCCESS) {
+ LONG result = RegCreateKeyExW(hkey, child, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE | getMode(jMode), NULL, &newKey, NULL);
+ if (result == ERROR_SUCCESS) {
+ if (newKey != 0) {
+ RegCloseKey(newKey);
+ }
+ } else if (result == ERROR_ACCESS_DENIED) {
+ throwException(jEnv, "Could not create a new key (access denied)");
+ } else {
+ throwException(jEnv, "Could not create a new key");
+ }
+ } else {
+ throwException(jEnv, "Could not open the parent key");
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(parent);
+ FREE(child);
+}
+
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_deleteKey0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jParent, jstring jChild) {
+ HKEY hkey = 0;
+ unsigned short* jParentS = getWideChars(jEnv, jParent);
+ unsigned short* jChildS = getWideChars(jEnv, jChild);
+
+
+ if (RegOpenKeyExW(getHKEY(jSection), jParentS, 0, KEY_READ | KEY_WRITE | getMode(jMode), &hkey) == ERROR_SUCCESS) {
+ LONG mode = getMode(jMode);
+ if(mode==0) {
+ if (RegDeleteKeyW(hkey, jChildS) != ERROR_SUCCESS) {
+ throwException(jEnv, "Could not delete key");
+ }
+ } else {
+ typedef LONG (WINAPI *LPFN_REGDELETEKEYEXW) (HKEY, LPCWSTR, REGSAM, DWORD);
+ LPFN_REGDELETEKEYEXW regDeleteKeyExW;
+ HMODULE hModule = GetModuleHandle(TEXT("advapi32.dll"));
+ if(hModule == NULL) {
+ hModule = LoadLibraryA("advapi32.dll");
+ }
+ regDeleteKeyExW = (LPFN_REGDELETEKEYEXW) GetProcAddress(hModule,"RegDeleteKeyExW");
+ if (NULL != regDeleteKeyExW) {
+ if (regDeleteKeyExW(hkey, jChildS, mode, 0) != ERROR_SUCCESS) {
+ throwException(jEnv, "Could not delete key");
+ }
+ } else {
+ throwException(jEnv, "Cannot load function RegDeleteKeyExW");
+ }
+ }
+ } else {
+ throwException(jEnv, "Could not open the parent key");
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(jParentS);
+ FREE(jChildS);
+}
+
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_deleteValue0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey, jstring jName) {
+ HKEY hkey = 0;
+ unsigned short* key = getWideChars(jEnv, jKey);
+ unsigned short* value = getWideChars(jEnv, jName);
+
+ if (RegOpenKeyExW(getHKEY(jSection), key, 0, KEY_SET_VALUE | getMode(jMode) , &hkey) == ERROR_SUCCESS) {
+ if (RegDeleteValueW(hkey, value) != ERROR_SUCCESS) {
+ throwException(jEnv, "Cannot delete value");
+ }
+ } else {
+ throwException(jEnv, "Canont open key");
+ }
+
+ if(hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(key);
+ FREE(value);
+}
+
+JNIEXPORT jstring JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getStringValue0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey, jstring jName, jboolean jExpand) {
+ unsigned short* key = getWideChars(jEnv, jKey);
+ unsigned short* name = getWideChars(jEnv, jName);
+ DWORD type = REG_NONE;
+ byte* value = NULL;
+
+ jstring result = NULL;
+
+ if (queryValue(getMode(jMode), getHKEY(jSection), key, name, &type, NULL, &value, jExpand)) {
+ if (type == REG_SZ || type == REG_EXPAND_SZ) {
+ result = getStringW(jEnv, (unsigned short*) value);
+ } else {
+ throwException(jEnv, "Value has wrong type");
+ }
+ } else {
+ throwException(jEnv, "Cannot read value");
+ }
+
+ FREE(key);
+ FREE(name);
+ FREE(value);
+
+ return result;
+}
+
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_setStringValue0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey, jstring jName, jstring jValue, jboolean jExpand) {
+ unsigned short* key = getWideChars(jEnv, jKey);
+ unsigned short* name = getWideChars(jEnv, jName);
+ unsigned short* value = getWideChars(jEnv, jValue);
+
+ if (!setValue(getMode(jMode), getHKEY(jSection), key, name, jExpand ? REG_EXPAND_SZ : REG_SZ, (byte*) value, ((int) WCSLEN(value)) * sizeof(unsigned short), 0)) {
+ throwException(jEnv, "Could not set value");
+ }
+
+ FREE(key);
+ FREE(name);
+ FREE(value);
+}
+
+JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_get32BitValue0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey, jstring jName) {
+ HKEY hkey = 0;
+ unsigned short* key = getWideChars(jEnv, jKey);
+ unsigned short* value = getWideChars(jEnv, jName);
+
+ jint result = -1;
+ if(RegOpenKeyExW(getHKEY(jSection), key, 0, KEY_QUERY_VALUE | getMode(jMode), &hkey) == ERROR_SUCCESS) {
+ DWORD dwType = 0;
+ DWORD dwValue = 0;
+ DWORD dwBufSize = sizeof(dwValue);
+
+ if (RegQueryValueExW(hkey, value, NULL, &dwType, (LPBYTE) &dwValue, &dwBufSize) == ERROR_SUCCESS) {
+ if ((dwType == REG_DWORD) || (dwType == REG_DWORD_BIG_ENDIAN)) {
+ result = dwValue;
+ } else {
+ throwException(jEnv, "Value is of wrong type");
+ }
+ } else {
+ throwException(jEnv, "Cannot read key data");
+ }
+ } else {
+ throwException(jEnv, "Could not open key");
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(key);
+ FREE(value);
+
+ return result;
+}
+
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_set32BitValue0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey, jstring jName, jint jValue) {
+ unsigned short* key = getWideChars(jEnv, jKey);
+ unsigned short* name = getWideChars(jEnv, jName);
+ DWORD dword = (DWORD) jValue;
+ LPBYTE byteValue = (LPBYTE) &dword;
+
+ if (!setValue(getMode(jMode),getHKEY(jSection), key, name, REG_DWORD, byteValue, sizeof(dword), 0)) {
+ throwException(jEnv, "Cannot set value");
+ }
+
+ FREE(key);
+ FREE(name);
+}
+
+JNIEXPORT jobjectArray JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getMultiStringValue0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey, jstring jName) {
+ HKEY hkey = 0;
+ unsigned short* key = getWideChars(jEnv, jKey);
+ unsigned short* value = getWideChars(jEnv, jName);
+
+ int i, start, count, cnt;
+ LONG regErr = 0;
+ unsigned short* data = 0;
+ jstring string;
+ jclass strClass;
+ DWORD dwType;
+ DWORD size = 0;
+
+ jarray result = 0;
+ if(RegOpenKeyExW(getHKEY(jSection), key, 0, KEY_QUERY_VALUE | getMode(jMode), &hkey) == ERROR_SUCCESS) {
+ if (RegQueryValueExW(hkey, value, NULL, &dwType, NULL, &size) == ERROR_SUCCESS) {
+ if (dwType == REG_MULTI_SZ) {
+ data = (unsigned short*) LocalAlloc(LPTR, size + 8);
+
+ if (data != NULL) {
+ if (RegQueryValueExW(hkey, value, NULL, &dwType, (byte*) data, &size) == ERROR_SUCCESS) {
+ for (count = 0, i = 0; i < (int) size; i++) {
+ if (data[i] == '\0') { // \0 - end of a single string
+ count++;
+ if (data[i + 1] == '\0') { // two \0 's in a row - end of all strings
+ break;
+ }
+ }
+ }
+
+ strClass = (*jEnv)->FindClass(jEnv, "java/lang/String");
+ if (strClass != NULL) {
+ result = (*jEnv)->NewObjectArray(jEnv, (jsize) count, strClass, NULL);
+ if (result != NULL) {
+ for (cnt = 0, start = 0, i = 0; (i < (int) size) && (cnt < count); i++) {
+ if (data[i] == '\0') {
+ string = getStringWithLengthW(jEnv, &data[start], i - start);
+
+ if (string != NULL) {
+ (*jEnv)->SetObjectArrayElement(jEnv, (jobjectArray) result, (jsize) cnt++, string);
+
+ start = i + 1;
+ if (data[start] == '\0') {
+ break;
+ }
+ } else {
+ throwException(jEnv, "Cannot create an array element");
+ break;
+ }
+ }
+ }
+ } else {
+ throwException(jEnv, "Cannot create resulting array");
+ }
+ } else {
+ throwException(jEnv, "Cannot find java.lang.String");
+ }
+ } else {
+ throwException(jEnv, "Cannot read value data");
+ }
+ FREE(data);
+ } else {
+ throwException(jEnv, "Cannot allocate memory for value");
+ }
+ } else {
+ throwException(jEnv, "Value is of wrong type");
+ }
+ } else {
+ throwException(jEnv, "Cannot read key data");
+ }
+ } else {
+ throwException(jEnv, "Cannot open key");
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(key);
+ FREE(value);
+
+ return (jobjectArray) result;
+}
+
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_setMultiStringValue0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey, jstring jName, jobjectArray jValue) {
+ unsigned short* key = getWideChars(jEnv, jKey);
+ unsigned short* name = getWideChars(jEnv, jName);
+ DWORD size = 0;
+ BYTE* data = getByteFromMultiString(jEnv, jValue, &size);
+
+ if (!setValue(getMode(jMode),getHKEY(jSection), key, name, REG_MULTI_SZ, data, size, 0)) {
+ throwException(jEnv, "Cannot set value");
+ }
+
+ FREE(key);
+ FREE(name);
+ FREE(data);
+}
+
+JNIEXPORT jbyteArray JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getBinaryValue0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey, jstring jName) {
+ HKEY hkey = 0;
+ unsigned short* key = getWideChars(jEnv, jKey);
+ unsigned short* value = getWideChars(jEnv, jName);
+
+ jbyteArray result = NULL;
+ if (RegOpenKeyExW(getHKEY(jSection), key, 0, KEY_QUERY_VALUE | getMode(jMode), &hkey) == ERROR_SUCCESS) {
+ DWORD dwType = 0;
+ DWORD dwValue = 0;
+ DWORD size = 0;
+ BYTE* data = NULL;
+
+ if (RegQueryValueExW(hkey, value, NULL, &dwType, NULL, &size) == ERROR_SUCCESS) {
+ if (dwType == REG_BINARY || dwType == REG_NONE) {
+ data = (BYTE*) LocalAlloc(LPTR, size + 8);
+ if (RegQueryValueExW(hkey, value, NULL, &dwType, (BYTE*) data, &size) == ERROR_SUCCESS) {
+ if (data != NULL) {
+ result = (*jEnv)->NewByteArray(jEnv, (jsize) size);
+ (*jEnv)->SetByteArrayRegion(jEnv, result, 0, (jsize) size, (jbyte*) data);
+ }
+ } else {
+ throwException(jEnv, "Could not read key data");
+ }
+ FREE(data);
+ } else {
+ throwException(jEnv, "Value is of wrong type");
+ }
+ } else {
+ throwException(jEnv, "Could not read key data");
+ }
+ } else {
+ throwException(jEnv, "Could not open key");
+ }
+
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+
+ FREE(key);
+ FREE(value);
+
+ return result;
+}
+
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_setBinaryValue0(JNIEnv *jEnv, jobject jObject, jint jMode, jint jSection, jstring jKey, jstring jName, jbyteArray jValue) {
+ unsigned short* key = getWideChars(jEnv, jKey);
+ unsigned short* name = getWideChars(jEnv, jName);
+ BYTE* data = (BYTE*) (*jEnv)->GetByteArrayElements(jEnv, jValue, 0);
+ DWORD length = (*jEnv)->GetArrayLength(jEnv, jValue);
+
+ if (!setValue(getMode(jMode),getHKEY(jSection), key, name, REG_BINARY, data, length, 0)) {
+ throwException(jEnv, "Cannot set value");
+ }
+
+ FREE(key);
+ FREE(name);
+ if (data != NULL) {
+ (*jEnv)->ReleaseByteArrayElements(jEnv, jValue, (jbyte*) data, JNI_ABORT);
+ }
+}
+
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_setNoneValue0(JNIEnv *jEnv, jobject jobj, jint jMode, jint jSection, jstring jKey, jstring jName, jbyteArray jValue) {
+ unsigned short* key = getWideChars(jEnv, jKey);
+ unsigned short* name = getWideChars(jEnv, jName);
+ BYTE* data = (BYTE*) (*jEnv)->GetByteArrayElements(jEnv, jValue, 0);
+ DWORD length = (*jEnv)->GetArrayLength(jEnv, jValue);
+
+ if (!setValue(getMode(jMode),getHKEY(jSection), key, name, REG_NONE, data, length, 0)) {
+ throwException(jEnv, "Cannot set value");
+ }
+
+ FREE(key);
+ FREE(name);
+ if (data != NULL) {
+ (*jEnv)->ReleaseByteArrayElements(jEnv, jValue, (jbyte*) data, JNI_ABORT);
+ }
+}
+
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_IsWow64Process0(JNIEnv *jEnv, jobject jObject) {
+ typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
+ LPFN_ISWOW64PROCESS fnIsWow64Process;
+ BOOL IsWow64 = FALSE;
+
+ fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
+
+ if (NULL != fnIsWow64Process)
+ {
+ if (!fnIsWow64Process(GetCurrentProcess(),&IsWow64))
+ {
+ }
+ }
+ return IsWow64;
+}
diff --git a/src/main/cpp/jnilib/windows/src/jni_WindowsRegistry.h b/src/main/cpp/jnilib/windows/src/jni_WindowsRegistry.h
new file mode 100644
index 0000000..1bf9add
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/src/jni_WindowsRegistry.h
@@ -0,0 +1,266 @@
+/*
+ * 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 <jni.h>
+/* Header for class org_netbeans_installer_utils_system_windows_WindowsRegistry */
+
+#ifndef _Included_org_netbeans_installer_utils_system_windows_WindowsRegistry
+#define _Included_org_netbeans_installer_utils_system_windows_WindowsRegistry
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_CLASSES_ROOT
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_CLASSES_ROOT 0L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_CURRENT_USER
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_CURRENT_USER 1L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_LOCAL_MACHINE
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_LOCAL_MACHINE 2L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_USERS
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_USERS 3L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_CURRENT_CONFIG
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_CURRENT_CONFIG 4L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_DYN_DATA
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_DYN_DATA 5L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_PERFORMANCE_DATA
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_PERFORMANCE_DATA 6L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_PERFORMANCE_NLSTEXT
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_PERFORMANCE_NLSTEXT 7L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_PERFORMANCE_TEXT
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_HKEY_PERFORMANCE_TEXT 8L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_HKCR
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_HKCR 0L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_HKCU
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_HKCU 1L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_HKLM
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_HKLM 2L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_NONE
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_NONE 0L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_SZ
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_SZ 1L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_EXPAND_SZ
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_EXPAND_SZ 2L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_BINARY
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_BINARY 3L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_DWORD_LITTLE_ENDIAN
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_DWORD_LITTLE_ENDIAN 4L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_DWORD
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_DWORD 4L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_DWORD_BIG_ENDIAN
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_DWORD_BIG_ENDIAN 5L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_LINK
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_LINK 6L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_MULTI_SZ
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_MULTI_SZ 7L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_RESOURCE_LIST
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_RESOURCE_LIST 8L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_FULL_RESOURCE_DESCRIPTOR
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_FULL_RESOURCE_DESCRIPTOR 9L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_RESOURCE_REQUIREMENTS_LIST
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_RESOURCE_REQUIREMENTS_LIST 10L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_QWORD_LITTLE_ENDIAN
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_QWORD_LITTLE_ENDIAN 11L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_QWORD
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_REG_QWORD 11L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_MODE_DEFAULT
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_MODE_DEFAULT 0L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_MODE_32BIT
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_MODE_32BIT 1L
+#undef org_netbeans_installer_utils_system_windows_WindowsRegistry_MODE_64BIT
+#define org_netbeans_installer_utils_system_windows_WindowsRegistry_MODE_64BIT 2L
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: checkKeyAccess0
+ * Signature: (IILjava/lang/String;I;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_checkKeyAccess0
+ (JNIEnv *, jobject, jint, jint, jstring, jint);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: valueExists0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_valueExists0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: keyEmpty0
+ * Signature: (IILjava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_keyEmpty0
+ (JNIEnv *, jobject, jint, jint, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: countSubKeys0
+ * Signature: (IILjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_countSubKeys0
+ (JNIEnv *, jobject, jint, jint, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: countValues0
+ * Signature: (IILjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_countValues0
+ (JNIEnv *, jobject, jint, jint, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: getSubkeyNames0
+ * Signature: (IILjava/lang/String;)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getSubkeyNames0
+ (JNIEnv *, jobject, jint, jint, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: getValueNames0
+ * Signature: (IILjava/lang/String;)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getValueNames0
+ (JNIEnv *, jobject, jint, jint, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: getValueType0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getValueType0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: createKey0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_createKey0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: deleteKey0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_deleteKey0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: deleteValue0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_deleteValue0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: getStringValue0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getStringValue0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring, jboolean);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: setStringValue0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_setStringValue0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring, jstring, jboolean);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: get32BitValue0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_get32BitValue0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: set32BitValue0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;I)V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_set32BitValue0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring, jint);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: getMultiStringValue0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getMultiStringValue0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: setMultiStringValue0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_setMultiStringValue0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring, jobjectArray);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: getBinaryValue0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_getBinaryValue0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: setBinaryValue0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;[B)V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_setBinaryValue0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring, jbyteArray);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: setNoneValue0
+ * Signature: (IILjava/lang/String;Ljava/lang/String;[B)V
+ */
+JNIEXPORT void JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_setNoneValue0
+ (JNIEnv *, jobject, jint, jint, jstring, jstring, jbyteArray);
+
+/*
+ * Class: org_netbeans_installer_utils_system_windows_WindowsRegistry
+ * Method: IsWow64Process0
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_netbeans_installer_utils_system_windows_WindowsRegistry_IsWow64Process0
+ (JNIEnv *, jobject);
+
+
+#ifndef KEY_WOW64_32KEY
+#define KEY_WOW64_32KEY 0x0200
+#endif
+#ifndef KEY_WOW64_64KEY
+#define KEY_WOW64_64KEY 0x0100
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.ncb b/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.ncb
new file mode 100644
index 0000000..9057eba
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.ncb
@@ -0,0 +1 @@
+Microsoft C/C++ MSF 7.00
diff --git a/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.sln b/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.sln
new file mode 100644
index 0000000..4410e6f
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual C++ Express 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NBI JNI Library", "NBI JNI Library.vcproj", "{AF9FBB45-6887-41CE-8DC2-915C5FB2AD45}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Default-32bit|Windows = Default-32bit|Windows
+ Default-64bit|Windows = Default-64bit|Windows
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {AF9FBB45-6887-41CE-8DC2-915C5FB2AD45}.Default-32bit|Windows.ActiveCfg = Default-32bit|Win32
+ {AF9FBB45-6887-41CE-8DC2-915C5FB2AD45}.Default-32bit|Windows.Build.0 = Default-32bit|Win32
+ {AF9FBB45-6887-41CE-8DC2-915C5FB2AD45}.Default-64bit|Windows.ActiveCfg = Default-32bit|Win32
+ {AF9FBB45-6887-41CE-8DC2-915C5FB2AD45}.Default-64bit|Windows.Build.0 = Default-32bit|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.suo b/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.suo
new file mode 100644
index 0000000..8a45057
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.suo
Binary files differ
diff --git a/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.vcproj b/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.vcproj
new file mode 100644
index 0000000..4cbd1b7
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.vcproj
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="NBI JNI Library"
+ ProjectGUID="{AF9FBB45-6887-41CE-8DC2-915C5FB2AD45}"
+ RootNamespace="NBI JNI Library"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Default-32bit|Win32"
+ OutputDirectory="Default-32bit"
+ IntermediateDirectory="Default-32bit"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ UseUnicodeResponseFiles="true"
+ Optimization="1"
+ FavorSizeOrSpeed="2"
+ AdditionalIncludeDirectories=""C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include";"C:\Program Files\Java\jdk1.5.0_11\include";"C:\Program Files\Java\jdk1.5.0_11\include\win32""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;NBIJNILIBRARY_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_STATIC_CPPLIB;_LITTLE_ENDIAN"
+ MinimalRebuild="false"
+ ExceptionHandling="0"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="0"
+ DisableLanguageExtensions="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ WarnAsError="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="0"
+ CallingConvention="0"
+ CompileAs="1"
+ ShowIncludes="false"
+ OmitDefaultLibName="false"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ UseLibraryDependencyInputs="false"
+ ShowProgress="1"
+ OutputFile="..\dist\windows-x86.dll"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Lib""
+ GenerateManifest="false"
+ IgnoreEmbeddedIDL="true"
+ GenerateDebugInformation="false"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Default-64bit|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ UseUnicodeResponseFiles="true"
+ Optimization="1"
+ FavorSizeOrSpeed="2"
+ AdditionalIncludeDirectories=""C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include";"C:\Program Files\Java\jdk1.5.0_11\include";"C:\Program Files\Java\jdk1.5.0_11\include\win32""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;NBIJNILIBRARY_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_STATIC_CPPLIB;_LITTLE_ENDIAN"
+ MinimalRebuild="false"
+ ExceptionHandling="0"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="0"
+ DisableLanguageExtensions="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ WarnAsError="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="0"
+ CallingConvention="0"
+ CompileAs="1"
+ ShowIncludes="false"
+ OmitDefaultLibName="false"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkLibraryDependencies="false"
+ UseLibraryDependencyInputs="false"
+ ShowProgress="0"
+ OutputFile="..\dist\windows-x64.dll"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories=""C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Lib""
+ GenerateManifest="false"
+ IgnoreEmbeddedIDL="true"
+ GenerateDebugInformation="false"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\.common\src\CommonUtils.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\jni_WindowsNativeUtils.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\jni_WindowsRegistry.h"
+ >
+ </File>
+ <File
+ RelativePath="..\src\WindowsUtils.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\.common\src\CommonUtils.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\jni_WindowsNativeUtils.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\jni_WindowsRegistry.c"
+ >
+ </File>
+ <File
+ RelativePath="..\src\WindowsUtils.c"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.vcproj.user b/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.vcproj.user
new file mode 100644
index 0000000..a5ca4f9
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/vcproject/NBI JNI Library.vcproj.user
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><VisualStudioUserFile ProjectType="Visual C++" Version="8.00" ShowAllFiles="true"></VisualStudioUserFile>
\ No newline at end of file
diff --git a/src/main/cpp/jnilib/windows/vcproject/vc80.idb b/src/main/cpp/jnilib/windows/vcproject/vc80.idb
new file mode 100644
index 0000000..3169052
--- /dev/null
+++ b/src/main/cpp/jnilib/windows/vcproject/vc80.idb
Binary files differ
diff --git a/src/main/cpp/launcher/unix/i18n/launcher.properties b/src/main/cpp/launcher/unix/i18n/launcher.properties
new file mode 100644
index 0000000..73e6c6e
--- /dev/null
+++ b/src/main/cpp/launcher/unix/i18n/launcher.properties
@@ -0,0 +1,51 @@
+#
+# 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.
+#
+
+nlu.jvm.notfoundmessage=Java SE Development Kit (JDK) was not found on this computer\nJDK 8 is required for installing the NetBeans IDE. Make sure that the JDK is properly installed and run installer again.\nYou can specify valid JDK location using {0} installer argument.\n\nTo download the JDK, visit http://www.oracle.com/technetwork/java/javase/downloads
+nlu.jvm.usererror=Java Runtime Environment (JRE) was not found at the specified location {0}
+nlu.jvm.uncompatible=Unsupported JVM version at {0}.\nTry to specify another JVM location using parameter {1}
+nlu.freespace=There is not enough free disk space to extract installation data\n{0} MB of free disk space is required in a temporary folder.\nClean up the disk space and run installer again. You can specify a temporary folder with sufficient disk space using {1} installer argument
+nlu.integrity=\nInstaller file {0} seems to be corrupted
+nlu.missing.external.resource=Can`t run NetBeans Installer.\nAn external file with necessary data is required but missing:\n{0}
+nlu.cannot.create.tmpdir=Cannot create temporary directory {0}
+nlu.cannot.extract.bundled.jvm=Cannot prepare bundled JVM to run the installer.\nMost probably the bundled JVM is not compatible with the current platform.\nSee FAQ at http://wiki.netbeans.org/FaqUnableToPrepareBundledJdk for more information.
+nlu.cannot.unpack.jvm.file=Cannot unpack file {0}
+nlu.error.verify.bundled.jvm=Cannot verify bundled JVM, try to search JVM on the system
+
+nlu.running=Running the installer wizard...
+nlu.starting=Configuring the installer...
+nlu.extracting=Extracting installation data...
+nlu.prepare.jvm=Preparing bundled JVM ...
+nlu.jvm.search=Searching for JVM on the system...
+
+nlu.msg.usage=\nUsage:
+nlu.arg.javahome=\t{0}\t<dir>\tUsing java from <dir> for running application
+nlu.arg.verbose=\t{0}\t\tUse verbose output
+nlu.arg.output=\t{0}\t<out>\tRedirect all output to file <out>
+nlu.arg.disable.space.check=\t{0}\t\tDisable free space check
+nlu.arg.extract=\t{0}\t[dir]\tExtract all bundled data to <dir>.\n\t\t\t\tIf <dir> is not specified then extract to the current directory
+nlu.arg.tempdir=\t{0}\t<dir>\tUse <dir> for extracting temporary data
+nlu.arg.cpa=\t{0} <cp>\tAppend classpath with <cp>
+nlu.arg.cpp=\t{0} <cp>\tPrepend classpath with <cp>
+nlu.arg.locale=\t{0}\t<locale>\tOverride default locale with specified <locale>
+nlu.arg.silent=\t{0}\t\tRun installer silently
+nlu.arg.help=\t{0}\t\tShow this help
+
+
+nlu.java.application.name.macosx=NetBeans IDE Installer
diff --git a/src/main/cpp/launcher/unix/src/launcher.sh b/src/main/cpp/launcher/unix/src/launcher.sh
new file mode 100644
index 0000000..5a6fc13
--- /dev/null
+++ b/src/main/cpp/launcher/unix/src/launcher.sh
@@ -0,0 +1,1665 @@
+#!/bin/sh
+#
+# 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.
+#
+
+ARG_JAVAHOME="--javahome"
+ARG_VERBOSE="--verbose"
+ARG_OUTPUT="--output"
+ARG_EXTRACT="--extract"
+ARG_JAVA_ARG_PREFIX="-J"
+ARG_TEMPDIR="--tempdir"
+ARG_CLASSPATHA="--classpath-append"
+ARG_CLASSPATHP="--classpath-prepend"
+ARG_HELP="--help"
+ARG_SILENT="--silent"
+ARG_NOSPACECHECK="--nospacecheck"
+ARG_LOCALE="--locale"
+
+USE_DEBUG_OUTPUT=0
+PERFORM_FREE_SPACE_CHECK=1
+SILENT_MODE=0
+EXTRACT_ONLY=0
+SHOW_HELP_ONLY=0
+LOCAL_OVERRIDDEN=0
+APPEND_CP=
+PREPEND_CP=
+LAUNCHER_APP_ARGUMENTS=
+LAUNCHER_JVM_ARGUMENTS=
+ERROR_OK=0
+ERROR_TEMP_DIRECTORY=2
+ERROR_TEST_JVM_FILE=3
+ERROR_JVM_NOT_FOUND=4
+ERROR_JVM_UNCOMPATIBLE=5
+ERROR_EXTRACT_ONLY=6
+ERROR_INPUTOUPUT=7
+ERROR_FREESPACE=8
+ERROR_INTEGRITY=9
+ERROR_MISSING_RESOURCES=10
+ERROR_JVM_EXTRACTION=11
+ERROR_JVM_UNPACKING=12
+ERROR_VERIFY_BUNDLED_JVM=13
+
+VERIFY_OK=1
+VERIFY_NOJAVA=2
+VERIFY_UNCOMPATIBLE=3
+
+MSG_ERROR_JVM_NOT_FOUND="nlu.jvm.notfoundmessage"
+MSG_ERROR_USER_ERROR="nlu.jvm.usererror"
+MSG_ERROR_JVM_UNCOMPATIBLE="nlu.jvm.uncompatible"
+MSG_ERROR_INTEGRITY="nlu.integrity"
+MSG_ERROR_FREESPACE="nlu.freespace"
+MSG_ERROP_MISSING_RESOURCE="nlu.missing.external.resource"
+MSG_ERROR_TMPDIR="nlu.cannot.create.tmpdir"
+
+MSG_ERROR_EXTRACT_JVM="nlu.cannot.extract.bundled.jvm"
+MSG_ERROR_UNPACK_JVM_FILE="nlu.cannot.unpack.jvm.file"
+MSG_ERROR_VERIFY_BUNDLED_JVM="nlu.error.verify.bundled.jvm"
+
+MSG_RUNNING="nlu.running"
+MSG_STARTING="nlu.starting"
+MSG_EXTRACTING="nlu.extracting"
+MSG_PREPARE_JVM="nlu.prepare.jvm"
+MSG_JVM_SEARCH="nlu.jvm.search"
+MSG_ARG_JAVAHOME="nlu.arg.javahome"
+MSG_ARG_VERBOSE="nlu.arg.verbose"
+MSG_ARG_OUTPUT="nlu.arg.output"
+MSG_ARG_EXTRACT="nlu.arg.extract"
+MSG_ARG_TEMPDIR="nlu.arg.tempdir"
+MSG_ARG_CPA="nlu.arg.cpa"
+MSG_ARG_CPP="nlu.arg.cpp"
+MSG_ARG_DISABLE_FREE_SPACE_CHECK="nlu.arg.disable.space.check"
+MSG_ARG_LOCALE="nlu.arg.locale"
+MSG_ARG_SILENT="nlu.arg.silent"
+MSG_ARG_HELP="nlu.arg.help"
+MSG_USAGE="nlu.msg.usage"
+
+isSymlink=
+
+entryPoint() {
+ initSymlinkArgument
+ CURRENT_DIRECTORY=`pwd`
+ LAUNCHER_NAME=`echo $0`
+ parseCommandLineArguments "$@"
+ initializeVariables
+ setLauncherLocale
+ debugLauncherArguments "$@"
+ if [ 1 -eq $SHOW_HELP_ONLY ] ; then
+ showHelp
+ fi
+
+ message "$MSG_STARTING"
+ createTempDirectory
+ checkFreeSpace "$TOTAL_BUNDLED_FILES_SIZE" "$LAUNCHER_EXTRACT_DIR"
+
+ extractJVMData
+ if [ 0 -eq $EXTRACT_ONLY ] ; then
+ searchJava
+ fi
+
+ extractBundledData
+ verifyIntegrity
+
+ if [ 0 -eq $EXTRACT_ONLY ] ; then
+ executeMainClass
+ else
+ exitProgram $ERROR_OK
+ fi
+}
+
+initSymlinkArgument() {
+ testSymlinkErr=`test -L / 2>&1 > /dev/null`
+ if [ -z "$testSymlinkErr" ] ; then
+ isSymlink=-L
+ else
+ isSymlink=-h
+ fi
+}
+
+debugLauncherArguments() {
+ debug "Launcher Command : $0"
+ argCounter=1
+ while [ $# != 0 ] ; do
+ debug "... argument [$argCounter] = $1"
+ argCounter=`expr "$argCounter" + 1`
+ shift
+ done
+}
+isLauncherCommandArgument() {
+ case "$1" in
+ $ARG_VERBOSE | $ARG_NOSPACECHECK | $ARG_OUTPUT | $ARG_HELP | $ARG_JAVAHOME | $ARG_TEMPDIR | $ARG_EXTRACT | $ARG_SILENT | $ARG_LOCALE | $ARG_CLASSPATHP | $ARG_CLASSPATHA)
+ echo 1
+ ;;
+ *)
+ echo 0
+ ;;
+ esac
+}
+
+parseCommandLineArguments() {
+ while [ $# != 0 ]
+ do
+ case "$1" in
+ $ARG_VERBOSE)
+ USE_DEBUG_OUTPUT=1;;
+ $ARG_NOSPACECHECK)
+ PERFORM_FREE_SPACE_CHECK=0
+ parseJvmAppArgument "$1"
+ ;;
+ $ARG_OUTPUT)
+ if [ -n "$2" ] ; then
+ OUTPUT_FILE="$2"
+ if [ -f "$OUTPUT_FILE" ] ; then
+ # clear output file first
+ rm -f "$OUTPUT_FILE" > /dev/null 2>&1
+ touch "$OUTPUT_FILE"
+ fi
+ shift
+ fi
+ ;;
+ $ARG_HELP)
+ SHOW_HELP_ONLY=1
+ ;;
+ $ARG_JAVAHOME)
+ if [ -n "$2" ] ; then
+ LAUNCHER_JAVA="$2"
+ shift
+ fi
+ ;;
+ $ARG_TEMPDIR)
+ if [ -n "$2" ] ; then
+ LAUNCHER_JVM_TEMP_DIR="$2"
+ shift
+ fi
+ ;;
+ $ARG_EXTRACT)
+ EXTRACT_ONLY=1
+ if [ -n "$2" ] && [ `isLauncherCommandArgument "$2"` -eq 0 ] ; then
+ LAUNCHER_EXTRACT_DIR="$2"
+ shift
+ else
+ LAUNCHER_EXTRACT_DIR="$CURRENT_DIRECTORY"
+ fi
+ ;;
+ $ARG_SILENT)
+ SILENT_MODE=1
+ parseJvmAppArgument "$1"
+ ;;
+ $ARG_LOCALE)
+ SYSTEM_LOCALE="$2"
+ LOCAL_OVERRIDDEN=1
+ parseJvmAppArgument "$1"
+ ;;
+ $ARG_CLASSPATHP)
+ if [ -n "$2" ] ; then
+ if [ -z "$PREPEND_CP" ] ; then
+ PREPEND_CP="$2"
+ else
+ PREPEND_CP="$2":"$PREPEND_CP"
+ fi
+ shift
+ fi
+ ;;
+ $ARG_CLASSPATHA)
+ if [ -n "$2" ] ; then
+ if [ -z "$APPEND_CP" ] ; then
+ APPEND_CP="$2"
+ else
+ APPEND_CP="$APPEND_CP":"$2"
+ fi
+ shift
+ fi
+ ;;
+
+ *)
+ parseJvmAppArgument "$1"
+ esac
+ shift
+ done
+}
+
+setLauncherLocale() {
+ if [ 0 -eq $LOCAL_OVERRIDDEN ] ; then
+ SYSTEM_LOCALE="$LANG"
+ debug "Setting initial launcher locale from the system : $SYSTEM_LOCALE"
+ else
+ debug "Setting initial launcher locale using command-line argument : $SYSTEM_LOCALE"
+ fi
+
+ LAUNCHER_LOCALE="$SYSTEM_LOCALE"
+
+ if [ -n "$LAUNCHER_LOCALE" ] ; then
+ # check if $LAUNCHER_LOCALE is in UTF-8
+ if [ 0 -eq $LOCAL_OVERRIDDEN ] ; then
+ removeUTFsuffix=`echo "$LAUNCHER_LOCALE" | sed "s/\.UTF-8//"`
+ isUTF=`ifEquals "$removeUTFsuffix" "$LAUNCHER_LOCALE"`
+ if [ 1 -eq $isUTF ] ; then
+ #set launcher locale to the default if the system locale name doesn`t containt UTF-8
+ LAUNCHER_LOCALE=""
+ fi
+ fi
+
+ localeChanged=0
+ localeCounter=0
+ while [ $localeCounter -lt $LAUNCHER_LOCALES_NUMBER ] ; do
+ localeVar="$""LAUNCHER_LOCALE_NAME_$localeCounter"
+ arg=`eval "echo \"$localeVar\""`
+ if [ -n "$arg" ] ; then
+ # if not a default locale
+ # $comp length shows the difference between $SYSTEM_LOCALE and $arg
+ # the less the length the less the difference and more coincedence
+
+ comp=`echo "$SYSTEM_LOCALE" | sed -e "s/^${arg}//"`
+ length1=`getStringLength "$comp"`
+ length2=`getStringLength "$LAUNCHER_LOCALE"`
+ if [ $length1 -lt $length2 ] ; then
+ # more coincidence between $SYSTEM_LOCALE and $arg than between $SYSTEM_LOCALE and $arg
+ compare=`ifLess "$comp" "$LAUNCHER_LOCALE"`
+
+ if [ 1 -eq $compare ] ; then
+ LAUNCHER_LOCALE="$arg"
+ localeChanged=1
+ debug "... setting locale to $arg"
+ fi
+ if [ -z "$comp" ] ; then
+ # means that $SYSTEM_LOCALE equals to $arg
+ break
+ fi
+ fi
+ else
+ comp="$SYSTEM_LOCALE"
+ fi
+ localeCounter=`expr "$localeCounter" + 1`
+ done
+ if [ $localeChanged -eq 0 ] ; then
+ #set default
+ LAUNCHER_LOCALE=""
+ fi
+ fi
+
+
+ debug "Final Launcher Locale : $LAUNCHER_LOCALE"
+}
+
+escapeBackslash() {
+ echo "$1" | sed "s/\\\/\\\\\\\/g"
+}
+
+ifLess() {
+ arg1=`escapeBackslash "$1"`
+ arg2=`escapeBackslash "$2"`
+ compare=`awk 'END { if ( a < b ) { print 1 } else { print 0 } }' a="$arg1" b="$arg2" < /dev/null`
+ echo $compare
+}
+
+formatVersion() {
+ formatted=`echo "$1" | sed "s/-ea//g;s/-rc[0-9]*//g;s/-beta[0-9]*//g;s/-preview[0-9]*//g;s/-dp[0-9]*//g;s/-alpha[0-9]*//g;s/-fcs//g;s/_/./g;s/-/\./g"`
+ formatted=`echo "$formatted" | sed "s/^\(\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\)\)\.b\([0-9][0-9]*\)/\1\.0\.\5/g"`
+ formatted=`echo "$formatted" | sed "s/\.b\([0-9][0-9]*\)/\.\1/g"`
+ echo "$formatted"
+
+}
+
+compareVersions() {
+ current1=`formatVersion "$1"`
+ current2=`formatVersion "$2"`
+ compresult=
+ #0 - equals
+ #-1 - less
+ #1 - more
+
+ while [ -z "$compresult" ] ; do
+ value1=`echo "$current1" | sed "s/\..*//g"`
+ value2=`echo "$current2" | sed "s/\..*//g"`
+
+
+ removeDots1=`echo "$current1" | sed "s/\.//g"`
+ removeDots2=`echo "$current2" | sed "s/\.//g"`
+
+ if [ 1 -eq `ifEquals "$current1" "$removeDots1"` ] ; then
+ remainder1=""
+ else
+ remainder1=`echo "$current1" | sed "s/^$value1\.//g"`
+ fi
+ if [ 1 -eq `ifEquals "$current2" "$removeDots2"` ] ; then
+ remainder2=""
+ else
+ remainder2=`echo "$current2" | sed "s/^$value2\.//g"`
+ fi
+
+ current1="$remainder1"
+ current2="$remainder2"
+
+ if [ -z "$value1" ] || [ 0 -eq `ifNumber "$value1"` ] ; then
+ value1=0
+ fi
+ if [ -z "$value2" ] || [ 0 -eq `ifNumber "$value2"` ] ; then
+ value2=0
+ fi
+ if [ "$value1" -gt "$value2" ] ; then
+ compresult=1
+ break
+ elif [ "$value2" -gt "$value1" ] ; then
+ compresult=-1
+ break
+ fi
+
+ if [ -z "$current1" ] && [ -z "$current2" ] ; then
+ compresult=0
+ break
+ fi
+ done
+ echo $compresult
+}
+
+ifVersionLess() {
+ compareResult=`compareVersions "$1" "$2"`
+ if [ -1 -eq $compareResult ] ; then
+ echo 1
+ else
+ echo 0
+ fi
+}
+
+ifVersionGreater() {
+ compareResult=`compareVersions "$1" "$2"`
+ if [ 1 -eq $compareResult ] ; then
+ echo 1
+ else
+ echo 0
+ fi
+}
+
+ifGreater() {
+ arg1=`escapeBackslash "$1"`
+ arg2=`escapeBackslash "$2"`
+
+ compare=`awk 'END { if ( a > b ) { print 1 } else { print 0 } }' a="$arg1" b="$arg2" < /dev/null`
+ echo $compare
+}
+
+ifEquals() {
+ arg1=`escapeBackslash "$1"`
+ arg2=`escapeBackslash "$2"`
+
+ compare=`awk 'END { if ( a == b ) { print 1 } else { print 0 } }' a="$arg1" b="$arg2" < /dev/null`
+ echo $compare
+}
+
+ifNumber()
+{
+ result=0
+ if [ -n "$1" ] ; then
+ num=`echo "$1" | sed 's/[0-9]*//g' 2>/dev/null`
+ if [ -z "$num" ] ; then
+ result=1
+ fi
+ fi
+ echo $result
+}
+getStringLength() {
+ strlength=`awk 'END{ print length(a) }' a="$1" < /dev/null`
+ echo $strlength
+}
+
+resolveRelativity() {
+ if [ 1 -eq `ifPathRelative "$1"` ] ; then
+ echo "$CURRENT_DIRECTORY"/"$1" | sed 's/\"//g' 2>/dev/null
+ else
+ echo "$1"
+ fi
+}
+
+ifPathRelative() {
+ param="$1"
+ removeRoot=`echo "$param" | sed "s/^\\\///" 2>/dev/null`
+ echo `ifEquals "$param" "$removeRoot"` 2>/dev/null
+}
+
+
+initializeVariables() {
+ debug "Launcher name is $LAUNCHER_NAME"
+ systemName=`uname`
+ debug "System name is $systemName"
+ isMacOSX=`ifEquals "$systemName" "Darwin"`
+ isSolaris=`ifEquals "$systemName" "SunOS"`
+ if [ 1 -eq $isSolaris ] ; then
+ POSSIBLE_JAVA_EXE_SUFFIX="$POSSIBLE_JAVA_EXE_SUFFIX_SOLARIS"
+ else
+ POSSIBLE_JAVA_EXE_SUFFIX="$POSSIBLE_JAVA_EXE_SUFFIX_COMMON"
+ fi
+ if [ 1 -eq $isMacOSX ] ; then
+ # set default userdir and cachedir on MacOS
+ DEFAULT_USERDIR_ROOT="${HOME}/Library/Application Support/NetBeans"
+ DEFAULT_CACHEDIR_ROOT="${HOME}/Library/Caches/NetBeans"
+ else
+ # set default userdir and cachedir on unix systems
+ DEFAULT_USERDIR_ROOT=${HOME}/.netbeans
+ DEFAULT_CACHEDIR_ROOT=${HOME}/.cache/netbeans
+ fi
+ systemInfo=`uname -a 2>/dev/null`
+ debug "System Information:"
+ debug "$systemInfo"
+ debug ""
+ DEFAULT_DISK_BLOCK_SIZE=512
+ LAUNCHER_TRACKING_SIZE=$LAUNCHER_STUB_SIZE
+ LAUNCHER_TRACKING_SIZE_BYTES=`expr "$LAUNCHER_STUB_SIZE" \* "$FILE_BLOCK_SIZE"`
+ getLauncherLocation
+}
+
+parseJvmAppArgument() {
+ param="$1"
+ arg=`echo "$param" | sed "s/^-J//"`
+ argEscaped=`escapeString "$arg"`
+
+ if [ "$param" = "$arg" ] ; then
+ LAUNCHER_APP_ARGUMENTS="$LAUNCHER_APP_ARGUMENTS $argEscaped"
+ else
+ LAUNCHER_JVM_ARGUMENTS="$LAUNCHER_JVM_ARGUMENTS $argEscaped"
+ fi
+}
+
+getLauncherLocation() {
+ # if file path is relative then prepend it with current directory
+ LAUNCHER_FULL_PATH=`resolveRelativity "$LAUNCHER_NAME"`
+ debug "... normalizing full path"
+ LAUNCHER_FULL_PATH=`normalizePath "$LAUNCHER_FULL_PATH"`
+ debug "... getting dirname"
+ LAUNCHER_DIR=`dirname "$LAUNCHER_FULL_PATH"`
+ debug "Full launcher path = $LAUNCHER_FULL_PATH"
+ debug "Launcher directory = $LAUNCHER_DIR"
+}
+
+getLauncherSize() {
+ lsOutput=`ls -l --block-size=1 "$LAUNCHER_FULL_PATH" 2>/dev/null`
+ if [ $? -ne 0 ] ; then
+ #default block size
+ lsOutput=`ls -l "$LAUNCHER_FULL_PATH" 2>/dev/null`
+ fi
+ echo "$lsOutput" | awk ' { print $5 }' 2>/dev/null
+}
+
+verifyIntegrity() {
+ size=`getLauncherSize`
+ extractedSize=$LAUNCHER_TRACKING_SIZE_BYTES
+ if [ 1 -eq `ifNumber "$size"` ] ; then
+ debug "... check integrity"
+ debug "... minimal size : $extractedSize"
+ debug "... real size : $size"
+
+ if [ $size -lt $extractedSize ] ; then
+ debug "... integration check FAILED"
+ message "$MSG_ERROR_INTEGRITY" `normalizePath "$LAUNCHER_FULL_PATH"`
+ exitProgram $ERROR_INTEGRITY
+ fi
+ debug "... integration check OK"
+ fi
+}
+showHelp() {
+ msg0=`message "$MSG_USAGE"`
+ msg1=`message "$MSG_ARG_JAVAHOME $ARG_JAVAHOME"`
+ msg2=`message "$MSG_ARG_TEMPDIR $ARG_TEMPDIR"`
+ msg3=`message "$MSG_ARG_EXTRACT $ARG_EXTRACT"`
+ msg4=`message "$MSG_ARG_OUTPUT $ARG_OUTPUT"`
+ msg5=`message "$MSG_ARG_VERBOSE $ARG_VERBOSE"`
+ msg6=`message "$MSG_ARG_CPA $ARG_CLASSPATHA"`
+ msg7=`message "$MSG_ARG_CPP $ARG_CLASSPATHP"`
+ msg8=`message "$MSG_ARG_DISABLE_FREE_SPACE_CHECK $ARG_NOSPACECHECK"`
+ msg9=`message "$MSG_ARG_LOCALE $ARG_LOCALE"`
+ msg10=`message "$MSG_ARG_SILENT $ARG_SILENT"`
+ msg11=`message "$MSG_ARG_HELP $ARG_HELP"`
+ out "$msg0"
+ out "$msg1"
+ out "$msg2"
+ out "$msg3"
+ out "$msg4"
+ out "$msg5"
+ out "$msg6"
+ out "$msg7"
+ out "$msg8"
+ out "$msg9"
+ out "$msg10"
+ out "$msg11"
+ exitProgram $ERROR_OK
+}
+
+exitProgram() {
+ if [ 0 -eq $EXTRACT_ONLY ] ; then
+ if [ -n "$LAUNCHER_EXTRACT_DIR" ] && [ -d "$LAUNCHER_EXTRACT_DIR" ]; then
+ debug "Removing directory $LAUNCHER_EXTRACT_DIR"
+ rm -rf "$LAUNCHER_EXTRACT_DIR" > /dev/null 2>&1
+ fi
+ fi
+ debug "exitCode = $1"
+ exit $1
+}
+
+debug() {
+ if [ $USE_DEBUG_OUTPUT -eq 1 ] ; then
+ timestamp=`date '+%Y-%m-%d %H:%M:%S'`
+ out "[$timestamp]> $1"
+ fi
+}
+
+out() {
+
+ if [ -n "$OUTPUT_FILE" ] ; then
+ printf "%s\n" "$@" >> "$OUTPUT_FILE"
+ elif [ 0 -eq $SILENT_MODE ] ; then
+ printf "%s\n" "$@"
+ fi
+}
+
+message() {
+ msg=`getMessage "$@"`
+ out "$msg"
+}
+
+
+createTempDirectory() {
+ if [ 0 -eq $EXTRACT_ONLY ] ; then
+ if [ -z "$LAUNCHER_JVM_TEMP_DIR" ] ; then
+ if [ 0 -eq $EXTRACT_ONLY ] ; then
+ if [ -n "$TEMP" ] && [ -d "$TEMP" ] ; then
+ debug "TEMP var is used : $TEMP"
+ LAUNCHER_JVM_TEMP_DIR="$TEMP"
+ elif [ -n "$TMP" ] && [ -d "$TMP" ] ; then
+ debug "TMP var is used : $TMP"
+ LAUNCHER_JVM_TEMP_DIR="$TMP"
+ elif [ -n "$TEMPDIR" ] && [ -d "$TEMPDIR" ] ; then
+ debug "TEMPDIR var is used : $TEMPDIR"
+ LAUNCHER_JVM_TEMP_DIR="$TEMPDIR"
+ elif [ -d "/tmp" ] ; then
+ debug "Using /tmp for temp"
+ LAUNCHER_JVM_TEMP_DIR="/tmp"
+ else
+ debug "Using home dir for temp"
+ LAUNCHER_JVM_TEMP_DIR="$HOME"
+ fi
+ else
+ #extract only : to the curdir
+ LAUNCHER_JVM_TEMP_DIR="$CURRENT_DIRECTORY"
+ fi
+ fi
+ # if temp dir does not exist then try to create it
+ if [ ! -d "$LAUNCHER_JVM_TEMP_DIR" ] ; then
+ mkdir -p "$LAUNCHER_JVM_TEMP_DIR" > /dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ message "$MSG_ERROR_TMPDIR" "$LAUNCHER_JVM_TEMP_DIR"
+ exitProgram $ERROR_TEMP_DIRECTORY
+ fi
+ fi
+ debug "Launcher TEMP ROOT = $LAUNCHER_JVM_TEMP_DIR"
+ subDir=`date '+%u%m%M%S'`
+ subDir=`echo ".nbi-$subDir.tmp"`
+ LAUNCHER_EXTRACT_DIR="$LAUNCHER_JVM_TEMP_DIR/$subDir"
+ else
+ #extracting to the $LAUNCHER_EXTRACT_DIR
+ debug "Launcher Extracting ROOT = $LAUNCHER_EXTRACT_DIR"
+ fi
+
+ if [ ! -d "$LAUNCHER_EXTRACT_DIR" ] ; then
+ mkdir -p "$LAUNCHER_EXTRACT_DIR" > /dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ message "$MSG_ERROR_TMPDIR" "$LAUNCHER_EXTRACT_DIR"
+ exitProgram $ERROR_TEMP_DIRECTORY
+ fi
+ else
+ debug "$LAUNCHER_EXTRACT_DIR is directory and exist"
+ fi
+ debug "Using directory $LAUNCHER_EXTRACT_DIR for extracting data"
+}
+extractJVMData() {
+ debug "Extracting testJVM file data..."
+ extractTestJVMFile
+ debug "Extracting bundled JVMs ..."
+ extractJVMFiles
+ debug "Extracting JVM data done"
+}
+extractBundledData() {
+ message "$MSG_EXTRACTING"
+ debug "Extracting bundled jars data..."
+ extractJars
+ debug "Extracting other data..."
+ extractOtherData
+ debug "Extracting bundled data finished..."
+}
+
+setTestJVMClasspath() {
+ testjvmname=`basename "$TEST_JVM_PATH"`
+ removeClassSuffix=`echo "$testjvmname" | sed 's/\.class$//'`
+ notClassFile=`ifEquals "$testjvmname" "$removeClassSuffix"`
+
+ if [ -d "$TEST_JVM_PATH" ] ; then
+ TEST_JVM_CLASSPATH="$TEST_JVM_PATH"
+ debug "... testJVM path is a directory"
+ elif [ $isSymlink "$TEST_JVM_PATH" ] && [ $notClassFile -eq 1 ] ; then
+ TEST_JVM_CLASSPATH="$TEST_JVM_PATH"
+ debug "... testJVM path is a link but not a .class file"
+ else
+ if [ $notClassFile -eq 1 ] ; then
+ debug "... testJVM path is a jar/zip file"
+ TEST_JVM_CLASSPATH="$TEST_JVM_PATH"
+ else
+ debug "... testJVM path is a .class file"
+ TEST_JVM_CLASSPATH=`dirname "$TEST_JVM_PATH"`
+ fi
+ fi
+ debug "... testJVM classpath is : $TEST_JVM_CLASSPATH"
+}
+
+extractTestJVMFile() {
+ TEST_JVM_PATH=`resolveResourcePath "TEST_JVM_FILE"`
+ extractResource "TEST_JVM_FILE"
+ setTestJVMClasspath
+
+}
+
+installJVM() {
+ message "$MSG_PREPARE_JVM"
+ jvmFile=`resolveRelativity "$1"`
+ jvmDir=`dirname "$jvmFile"`/_jvm
+ debug "JVM Directory : $jvmDir"
+ mkdir "$jvmDir" > /dev/null 2>&1
+ if [ $? != 0 ] ; then
+ message "$MSG_ERROR_EXTRACT_JVM"
+ exitProgram $ERROR_JVM_EXTRACTION
+ fi
+ chmod +x "$jvmFile" > /dev/null 2>&1
+ jvmFileEscaped=`escapeString "$jvmFile"`
+ jvmDirEscaped=`escapeString "$jvmDir"`
+ cd "$jvmDir"
+ runCommand "$jvmFileEscaped"
+ ERROR_CODE=$?
+
+ cd "$CURRENT_DIRECTORY"
+
+ if [ $ERROR_CODE != 0 ] ; then
+ message "$MSG_ERROR_EXTRACT_JVM"
+ exitProgram $ERROR_JVM_EXTRACTION
+ fi
+
+ files=`find "$jvmDir" -name "*.jar.pack.gz" -print`
+ debug "Packed files : $files"
+ f="$files"
+ fileCounter=1;
+ while [ -n "$f" ] ; do
+ f=`echo "$files" | sed -n "${fileCounter}p" 2>/dev/null`
+ debug "... next file is $f"
+ if [ -n "$f" ] ; then
+ debug "... packed file = $f"
+ unpacked=`echo "$f" | sed s/\.pack\.gz//`
+ debug "... unpacked file = $unpacked"
+ fEsc=`escapeString "$f"`
+ uEsc=`escapeString "$unpacked"`
+ cmd="$jvmDirEscaped/bin/unpack200 -r $fEsc $uEsc"
+ runCommand "$cmd"
+ if [ $? != 0 ] ; then
+ message "$MSG_ERROR_UNPACK_JVM_FILE" "$f"
+ exitProgram $ERROR_JVM_UNPACKING
+ fi
+ fi
+ fileCounter=`expr "$fileCounter" + 1`
+ done
+
+ verifyJVM "$jvmDir"
+ if [ -z "$LAUNCHER_JAVA_EXE" ] ; then
+ message "$MSG_ERROR_VERIFY_BUNDLED_JVM"
+ exitProgram $ERROR_VERIFY_BUNDLED_JVM
+ fi
+}
+
+resolveResourcePath() {
+ resourcePrefix="$1"
+ resourceVar="$""$resourcePrefix""_PATH"
+ resourceName=`eval "echo \"$resourceVar\""`
+ resourcePath=`resolveString "$resourceName"`
+ echo "$resourcePath"
+
+}
+
+resolveResourceSize() {
+ resourcePrefix="$1"
+ resourceVar="$""$resourcePrefix""_SIZE"
+ resourceSize=`eval "echo \"$resourceVar\""`
+ echo "$resourceSize"
+}
+
+resolveResourceMd5() {
+ resourcePrefix="$1"
+ resourceVar="$""$resourcePrefix""_MD5"
+ resourceMd5=`eval "echo \"$resourceVar\""`
+ echo "$resourceMd5"
+}
+
+resolveResourceType() {
+ resourcePrefix="$1"
+ resourceVar="$""$resourcePrefix""_TYPE"
+ resourceType=`eval "echo \"$resourceVar\""`
+ echo "$resourceType"
+}
+
+extractResource() {
+ debug "... extracting resource"
+ resourcePrefix="$1"
+ debug "... resource prefix id=$resourcePrefix"
+ resourceType=`resolveResourceType "$resourcePrefix"`
+ debug "... resource type=$resourceType"
+ if [ $resourceType -eq 0 ] ; then
+ resourceSize=`resolveResourceSize "$resourcePrefix"`
+ debug "... resource size=$resourceSize"
+ resourcePath=`resolveResourcePath "$resourcePrefix"`
+ debug "... resource path=$resourcePath"
+ extractFile "$resourceSize" "$resourcePath"
+ resourceMd5=`resolveResourceMd5 "$resourcePrefix"`
+ debug "... resource md5=$resourceMd5"
+ checkMd5 "$resourcePath" "$resourceMd5"
+ debug "... done"
+ fi
+ debug "... extracting resource finished"
+
+}
+
+extractJars() {
+ counter=0
+ while [ $counter -lt $JARS_NUMBER ] ; do
+ extractResource "JAR_$counter"
+ counter=`expr "$counter" + 1`
+ done
+}
+
+extractOtherData() {
+ counter=0
+ while [ $counter -lt $OTHER_RESOURCES_NUMBER ] ; do
+ extractResource "OTHER_RESOURCE_$counter"
+ counter=`expr "$counter" + 1`
+ done
+}
+
+extractJVMFiles() {
+ javaCounter=0
+ debug "... total number of JVM files : $JAVA_LOCATION_NUMBER"
+ while [ $javaCounter -lt $JAVA_LOCATION_NUMBER ] ; do
+ extractResource "JAVA_LOCATION_$javaCounter"
+ javaCounter=`expr "$javaCounter" + 1`
+ done
+}
+
+
+processJarsClasspath() {
+ JARS_CLASSPATH=""
+ jarsCounter=0
+ while [ $jarsCounter -lt $JARS_NUMBER ] ; do
+ resolvedFile=`resolveResourcePath "JAR_$jarsCounter"`
+ debug "... adding jar to classpath : $resolvedFile"
+ if [ ! -f "$resolvedFile" ] && [ ! -d "$resolvedFile" ] && [ ! $isSymlink "$resolvedFile" ] ; then
+ message "$MSG_ERROP_MISSING_RESOURCE" "$resolvedFile"
+ exitProgram $ERROR_MISSING_RESOURCES
+ else
+ if [ -z "$JARS_CLASSPATH" ] ; then
+ JARS_CLASSPATH="$resolvedFile"
+ else
+ JARS_CLASSPATH="$JARS_CLASSPATH":"$resolvedFile"
+ fi
+ fi
+
+ jarsCounter=`expr "$jarsCounter" + 1`
+ done
+ debug "Jars classpath : $JARS_CLASSPATH"
+}
+
+extractFile() {
+ start=$LAUNCHER_TRACKING_SIZE
+ size=$1 #absolute size
+ name="$2" #relative part
+ fullBlocks=`expr $size / $FILE_BLOCK_SIZE`
+ fullBlocksSize=`expr "$FILE_BLOCK_SIZE" \* "$fullBlocks"`
+ oneBlocks=`expr $size - $fullBlocksSize`
+ oneBlocksStart=`expr "$start" + "$fullBlocks"`
+
+ checkFreeSpace $size "$name"
+ LAUNCHER_TRACKING_SIZE_BYTES=`expr "$LAUNCHER_TRACKING_SIZE" \* "$FILE_BLOCK_SIZE"`
+
+ if [ 0 -eq $diskSpaceCheck ] ; then
+ dir=`dirname "$name"`
+ message "$MSG_ERROR_FREESPACE" "$size" "$ARG_TEMPDIR"
+ exitProgram $ERROR_FREESPACE
+ fi
+
+ if [ 0 -lt "$fullBlocks" ] ; then
+ # file is larger than FILE_BLOCK_SIZE
+ dd if="$LAUNCHER_FULL_PATH" of="$name" \
+ bs="$FILE_BLOCK_SIZE" count="$fullBlocks" skip="$start"\
+ > /dev/null 2>&1
+ LAUNCHER_TRACKING_SIZE=`expr "$LAUNCHER_TRACKING_SIZE" + "$fullBlocks"`
+ LAUNCHER_TRACKING_SIZE_BYTES=`expr "$LAUNCHER_TRACKING_SIZE" \* "$FILE_BLOCK_SIZE"`
+ fi
+ if [ 0 -lt "$oneBlocks" ] ; then
+ dd if="$LAUNCHER_FULL_PATH" of="$name.tmp.tmp" bs="$FILE_BLOCK_SIZE" count=1\
+ skip="$oneBlocksStart"\
+ > /dev/null 2>&1
+
+ dd if="$name.tmp.tmp" of="$name" bs=1 count="$oneBlocks" seek="$fullBlocksSize"\
+ > /dev/null 2>&1
+
+ rm -f "$name.tmp.tmp"
+ LAUNCHER_TRACKING_SIZE=`expr "$LAUNCHER_TRACKING_SIZE" + 1`
+
+ LAUNCHER_TRACKING_SIZE_BYTES=`expr "$LAUNCHER_TRACKING_SIZE_BYTES" + "$oneBlocks"`
+ fi
+}
+
+md5_program=""
+no_md5_program_id="no_md5_program"
+
+initMD5program() {
+ if [ -z "$md5_program" ] ; then
+ type digest >> /dev/null 2>&1
+ if [ 0 -eq $? ] ; then
+ md5_program="digest -a md5"
+ else
+ type md5sum >> /dev/null 2>&1
+ if [ 0 -eq $? ] ; then
+ md5_program="md5sum"
+ else
+ type gmd5sum >> /dev/null 2>&1
+ if [ 0 -eq $? ] ; then
+ md5_program="gmd5sum"
+ else
+ type md5 >> /dev/null 2>&1
+ if [ 0 -eq $? ] ; then
+ md5_program="md5 -q"
+ else
+ md5_program="$no_md5_program_id"
+ fi
+ fi
+ fi
+ fi
+ debug "... program to check: $md5_program"
+ fi
+}
+
+checkMd5() {
+ name="$1"
+ md5="$2"
+ if [ 32 -eq `getStringLength "$md5"` ] ; then
+ #do MD5 check
+ initMD5program
+ if [ 0 -eq `ifEquals "$md5_program" "$no_md5_program_id"` ] ; then
+ debug "... check MD5 of file : $name"
+ debug "... expected md5: $md5"
+ realmd5=`$md5_program "$name" 2>/dev/null | sed "s/ .*//g"`
+ debug "... real md5 : $realmd5"
+ if [ 32 -eq `getStringLength "$realmd5"` ] ; then
+ if [ 0 -eq `ifEquals "$md5" "$realmd5"` ] ; then
+ debug "... integration check FAILED"
+ message "$MSG_ERROR_INTEGRITY" `normalizePath "$LAUNCHER_FULL_PATH"`
+ exitProgram $ERROR_INTEGRITY
+ fi
+ else
+ debug "... looks like not the MD5 sum"
+ fi
+ fi
+ fi
+}
+searchJavaEnvironment() {
+ if [ -z "$LAUNCHER_JAVA_EXE" ] ; then
+ # search java in the environment
+
+ ptr="$POSSIBLE_JAVA_ENV"
+ while [ -n "$ptr" ] && [ -z "$LAUNCHER_JAVA_EXE" ] ; do
+ argJavaHome=`echo "$ptr" | sed "s/:.*//"`
+ back=`echo "$argJavaHome" | sed "s/\\\//\\\\\\\\\//g"`
+ end=`echo "$ptr" | sed "s/${back}://"`
+ argJavaHome=`echo "$back" | sed "s/\\\\\\\\\//\\\//g"`
+ ptr="$end"
+ eval evaluated=`echo \\$$argJavaHome` > /dev/null
+ if [ -n "$evaluated" ] ; then
+ debug "EnvVar $argJavaHome=$evaluated"
+ verifyJVM "$evaluated"
+ fi
+ done
+ fi
+}
+
+installBundledJVMs() {
+ if [ -z "$LAUNCHER_JAVA_EXE" ] ; then
+ # search bundled java in the common list
+ javaCounter=0
+ while [ $javaCounter -lt $JAVA_LOCATION_NUMBER ] && [ -z "$LAUNCHER_JAVA_EXE" ] ; do
+ fileType=`resolveResourceType "JAVA_LOCATION_$javaCounter"`
+
+ if [ $fileType -eq 0 ] ; then # bundled->install
+ argJavaHome=`resolveResourcePath "JAVA_LOCATION_$javaCounter"`
+ installJVM "$argJavaHome"
+ fi
+ javaCounter=`expr "$javaCounter" + 1`
+ done
+ fi
+}
+
+searchJavaOnMacOs() {
+ if [ -x "/usr/libexec/java_home" ]; then
+ javaOnMacHome=`/usr/libexec/java_home --failfast`
+ fi
+
+ if [ ! -x "$javaOnMacHome/bin/java" -a -f "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java" ] ; then
+ javaOnMacHome=`echo "/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home"`
+ fi
+
+ verifyJVM "$javaOnMacHome"
+}
+
+searchJavaSystemDefault() {
+ if [ -z "$LAUNCHER_JAVA_EXE" ] ; then
+ debug "... check default java in the path"
+ java_bin=`which java 2>&1`
+ if [ $? -eq 0 ] && [ -n "$java_bin" ] ; then
+ remove_no_java_in=`echo "$java_bin" | sed "s/no java in//g"`
+ if [ 1 -eq `ifEquals "$remove_no_java_in" "$java_bin"` ] && [ -f "$java_bin" ] ; then
+ debug "... java in path found: $java_bin"
+ # java is in path
+ java_bin=`resolveSymlink "$java_bin"`
+ debug "... java real path: $java_bin"
+ parentDir=`dirname "$java_bin"`
+ if [ -n "$parentDir" ] ; then
+ parentDir=`dirname "$parentDir"`
+ if [ -n "$parentDir" ] ; then
+ debug "... java home path: $parentDir"
+ parentDir=`resolveSymlink "$parentDir"`
+ debug "... java home real path: $parentDir"
+ verifyJVM "$parentDir"
+ fi
+ fi
+ fi
+ fi
+ fi
+}
+
+searchJavaSystemPaths() {
+ if [ -z "$LAUNCHER_JAVA_EXE" ] ; then
+ # search java in the common system paths
+ javaCounter=0
+ while [ $javaCounter -lt $JAVA_LOCATION_NUMBER ] && [ -z "$LAUNCHER_JAVA_EXE" ] ; do
+ fileType=`resolveResourceType "JAVA_LOCATION_$javaCounter"`
+ argJavaHome=`resolveResourcePath "JAVA_LOCATION_$javaCounter"`
+
+ debug "... next location $argJavaHome"
+
+ if [ $fileType -ne 0 ] ; then # bundled JVMs have already been proceeded
+ argJavaHome=`escapeString "$argJavaHome"`
+ locations=`ls -d -1 $argJavaHome 2>/dev/null`
+ nextItem="$locations"
+ itemCounter=1
+ while [ -n "$nextItem" ] && [ -z "$LAUNCHER_JAVA_EXE" ] ; do
+ nextItem=`echo "$locations" | sed -n "${itemCounter}p" 2>/dev/null`
+ debug "... next item is $nextItem"
+ nextItem=`removeEndSlashes "$nextItem"`
+ if [ -n "$nextItem" ] ; then
+ if [ -d "$nextItem" ] || [ $isSymlink "$nextItem" ] ; then
+ debug "... checking item : $nextItem"
+ verifyJVM "$nextItem"
+ fi
+ fi
+ itemCounter=`expr "$itemCounter" + 1`
+ done
+ fi
+ javaCounter=`expr "$javaCounter" + 1`
+ done
+ fi
+}
+
+searchJavaUserDefined() {
+ if [ -z "$LAUNCHER_JAVA_EXE" ] ; then
+ if [ -n "$LAUNCHER_JAVA" ] ; then
+ verifyJVM "$LAUNCHER_JAVA"
+
+ if [ $VERIFY_UNCOMPATIBLE -eq $verifyResult ] ; then
+ message "$MSG_ERROR_JVM_UNCOMPATIBLE" "$LAUNCHER_JAVA" "$ARG_JAVAHOME"
+ exitProgram $ERROR_JVM_UNCOMPATIBLE
+ elif [ $VERIFY_NOJAVA -eq $verifyResult ] ; then
+ message "$MSG_ERROR_USER_ERROR" "$LAUNCHER_JAVA"
+ exitProgram $ERROR_JVM_NOT_FOUND
+ fi
+ fi
+ fi
+}
+
+searchJavaInstallFolder() {
+ installFolder="`dirname \"$0\"`"
+ installFolder="`( cd \"$installFolder\" && pwd )`"
+ installFolder="$installFolder/bin/jre"
+ tempJreFolder="$TEST_JVM_CLASSPATH/_jvm"
+
+ if [ -d "$installFolder" ] ; then
+ #copy nested JRE to temp folder
+ cp -r "$installFolder" "$tempJreFolder"
+
+ verifyJVM "$tempJreFolder"
+ fi
+}
+
+searchJava() {
+ message "$MSG_JVM_SEARCH"
+ if [ ! -f "$TEST_JVM_CLASSPATH" ] && [ ! $isSymlink "$TEST_JVM_CLASSPATH" ] && [ ! -d "$TEST_JVM_CLASSPATH" ]; then
+ debug "Cannot find file for testing JVM at $TEST_JVM_CLASSPATH"
+ message "$MSG_ERROR_JVM_NOT_FOUND" "$ARG_JAVAHOME"
+ exitProgram $ERROR_TEST_JVM_FILE
+ else
+ searchJavaInstallFolder
+ searchJavaUserDefined
+ installBundledJVMs
+ searchJavaEnvironment
+ searchJavaSystemDefault
+ searchJavaSystemPaths
+ if [ 1 -eq $isMacOSX ] ; then
+ searchJavaOnMacOs
+ fi
+ fi
+
+ if [ -z "$LAUNCHER_JAVA_EXE" ] ; then
+ message "$MSG_ERROR_JVM_NOT_FOUND" "$ARG_JAVAHOME"
+ exitProgram $ERROR_JVM_NOT_FOUND
+ fi
+}
+
+normalizePath() {
+ argument="$1"
+
+ # replace all /./ to /
+ while [ 0 -eq 0 ] ; do
+ testArgument=`echo "$argument" | sed 's/\/\.\//\//g' 2> /dev/null`
+ if [ -n "$testArgument" ] && [ 0 -eq `ifEquals "$argument" "$testArgument"` ] ; then
+ # something changed
+ argument="$testArgument"
+ else
+ break
+ fi
+ done
+
+ # replace XXX/../YYY to 'dirname XXX'/YYY
+ while [ 0 -eq 0 ] ; do
+ beforeDotDot=`echo "$argument" | sed "s/\/\.\.\/.*//g" 2> /dev/null`
+ if [ 0 -eq `ifEquals "$beforeDotDot" "$argument"` ] && [ 0 -eq `ifEquals "$beforeDotDot" "."` ] && [ 0 -eq `ifEquals "$beforeDotDot" ".."` ] ; then
+ esc=`echo "$beforeDotDot" | sed "s/\\\//\\\\\\\\\//g"`
+ afterDotDot=`echo "$argument" | sed "s/^$esc\/\.\.//g" 2> /dev/null`
+ parent=`dirname "$beforeDotDot"`
+ argument=`echo "$parent""$afterDotDot"`
+ else
+ break
+ fi
+ done
+
+ # replace XXX/.. to 'dirname XXX'
+ while [ 0 -eq 0 ] ; do
+ beforeDotDot=`echo "$argument" | sed "s/\/\.\.$//g" 2> /dev/null`
+ if [ 0 -eq `ifEquals "$beforeDotDot" "$argument"` ] && [ 0 -eq `ifEquals "$beforeDotDot" "."` ] && [ 0 -eq `ifEquals "$beforeDotDot" ".."` ] ; then
+ argument=`dirname "$beforeDotDot"`
+ else
+ break
+ fi
+ done
+
+ # remove /. a the end (if the resulting string is not zero)
+ testArgument=`echo "$argument" | sed 's/\/\.$//' 2> /dev/null`
+ if [ -n "$testArgument" ] ; then
+ argument="$testArgument"
+ fi
+
+ # replace more than 2 separators to 1
+ testArgument=`echo "$argument" | sed 's/\/\/*/\//g' 2> /dev/null`
+ if [ -n "$testArgument" ] ; then
+ argument="$testArgument"
+ fi
+
+ echo "$argument"
+}
+
+resolveSymlink() {
+ pathArg="$1"
+ while [ $isSymlink "$pathArg" ] ; do
+ ls=`ls -ld "$pathArg"`
+ link=`expr "$ls" : '^.*-> \(.*\)$' 2>/dev/null`
+
+ if expr "$link" : '^/' 2> /dev/null >/dev/null; then
+ pathArg="$link"
+ else
+ pathArg="`dirname "$pathArg"`"/"$link"
+ fi
+ pathArg=`normalizePath "$pathArg"`
+ done
+ echo "$pathArg"
+}
+
+verifyJVM() {
+ javaTryPath=`normalizePath "$1"`
+ verifyJavaHome "$javaTryPath"
+ if [ $VERIFY_OK -ne $verifyResult ] ; then
+ savedResult=$verifyResult
+
+ if [ 0 -eq $isMacOSX ] ; then
+ #check private jre
+ javaTryPath="$javaTryPath""/jre"
+ verifyJavaHome "$javaTryPath"
+ else
+ #check MacOSX Home dir
+ javaTryPath="$javaTryPath""/Home"
+ verifyJavaHome "$javaTryPath"
+ fi
+
+ if [ $VERIFY_NOJAVA -eq $verifyResult ] ; then
+ verifyResult=$savedResult
+ fi
+ fi
+}
+
+removeEndSlashes() {
+ arg="$1"
+ tryRemove=`echo "$arg" | sed 's/\/\/*$//' 2>/dev/null`
+ if [ -n "$tryRemove" ] ; then
+ arg="$tryRemove"
+ fi
+ echo "$arg"
+}
+
+checkJavaHierarchy() {
+ # return 0 on no java
+ # return 1 on jre
+ # return 2 on jdk
+
+ tryJava="$1"
+ javaHierarchy=0
+ if [ -n "$tryJava" ] ; then
+ if [ -d "$tryJava" ] || [ $isSymlink "$tryJava" ] ; then # existing directory or a isSymlink
+ javaBin="$tryJava"/"bin"
+
+ if [ -d "$javaBin" ] || [ $isSymlink "$javaBin" ] ; then
+ javaBinJavac="$javaBin"/"javac"
+ if [ -f "$javaBinJavac" ] || [ $isSymlink "$javaBinJavac" ] ; then
+ #definitely JDK as the JRE doesn`t contain javac
+ javaHierarchy=2
+ else
+ #check if we inside JRE
+ javaBinJava="$javaBin"/"java"
+ if [ -f "$javaBinJava" ] || [ $isSymlink "$javaBinJava" ] ; then
+ javaHierarchy=1
+ fi
+ fi
+ fi
+ fi
+ fi
+ if [ 0 -eq $javaHierarchy ] ; then
+ debug "... no java there"
+ elif [ 1 -eq $javaHierarchy ] ; then
+ debug "... JRE there"
+ elif [ 2 -eq $javaHierarchy ] ; then
+ debug "... JDK there"
+ fi
+}
+
+verifyJavaHome() {
+ verifyResult=$VERIFY_NOJAVA
+ java=`removeEndSlashes "$1"`
+ debug "... verify : $java"
+
+ java=`resolveSymlink "$java"`
+ debug "... real path : $java"
+
+ checkJavaHierarchy "$java"
+
+ if [ 0 -ne $javaHierarchy ] ; then
+ testJVMclasspath=`escapeString "$TEST_JVM_CLASSPATH"`
+ testJVMclass=`escapeString "$TEST_JVM_CLASS"`
+
+ pointer="$POSSIBLE_JAVA_EXE_SUFFIX"
+ while [ -n "$pointer" ] && [ -z "$LAUNCHER_JAVA_EXE" ]; do
+ arg=`echo "$pointer" | sed "s/:.*//"`
+ back=`echo "$arg" | sed "s/\\\//\\\\\\\\\//g"`
+ end=`echo "$pointer" | sed "s/${back}://"`
+ arg=`echo "$back" | sed "s/\\\\\\\\\//\\\//g"`
+ pointer="$end"
+ javaExe="$java/$arg"
+
+ if [ -x "$javaExe" ] ; then
+ javaExeEscaped=`escapeString "$javaExe"`
+ command="$javaExeEscaped -classpath $testJVMclasspath $testJVMclass"
+
+ debug "Executing java verification command..."
+ debug "$command"
+ output=`eval "$command" 2>/dev/null`
+ javaVersion=`echo "$output" | sed "2d;3d;4d;5d"`
+ javaVmVersion=`echo "$output" | sed "1d;3d;4d;5d"`
+ vendor=`echo "$output" | sed "1d;2d;4d;5d"`
+ osname=`echo "$output" | sed "1d;2d;3d;5d"`
+ osarch=`echo "$output" | sed "1d;2d;3d;4d"`
+
+ debug "Java :"
+ debug " executable = {$javaExe}"
+ debug " javaVersion = {$javaVersion}"
+ debug " javaVmVersion = {$javaVmVersion}"
+ debug " vendor = {$vendor}"
+ debug " osname = {$osname}"
+ debug " osarch = {$osarch}"
+ comp=0
+
+ if [ -n "$javaVersion" ] && [ -n "$javaVmVersion" ] && [ -n "$vendor" ] && [ -n "$osname" ] && [ -n "$osarch" ] ; then
+ debug "... seems to be java indeed"
+ javaVersionEsc=`escapeBackslash "$javaVersion"`
+ javaVmVersionEsc=`escapeBackslash "$javaVmVersion"`
+ javaVersion=`awk 'END { idx = index(b,a); if(idx!=0) { print substr(b,idx,length(b)) } else { print a } }' a="$javaVersionEsc" b="$javaVmVersionEsc" < /dev/null`
+
+ #remove build number
+ javaVersion=`echo "$javaVersion" | sed 's/-.*$//;s/\ .*//'`
+ verifyResult=$VERIFY_UNCOMPATIBLE
+
+ if [ -n "$javaVersion" ] ; then
+ debug " checking java version = {$javaVersion}"
+ javaCompCounter=0
+
+ while [ $javaCompCounter -lt $JAVA_COMPATIBLE_PROPERTIES_NUMBER ] && [ -z "$LAUNCHER_JAVA_EXE" ] ; do
+ comp=1
+ setJavaCompatibilityProperties_$javaCompCounter
+ debug "Min Java Version : $JAVA_COMP_VERSION_MIN"
+ debug "Max Java Version : $JAVA_COMP_VERSION_MAX"
+ debug "Java Vendor : $JAVA_COMP_VENDOR"
+ debug "Java OS Name : $JAVA_COMP_OSNAME"
+ debug "Java OS Arch : $JAVA_COMP_OSARCH"
+
+ if [ -n "$JAVA_COMP_VERSION_MIN" ] ; then
+ compMin=`ifVersionLess "$javaVersion" "$JAVA_COMP_VERSION_MIN"`
+ if [ 1 -eq $compMin ] ; then
+ comp=0
+ fi
+ fi
+
+ if [ -n "$JAVA_COMP_VERSION_MAX" ] ; then
+ compMax=`ifVersionGreater "$javaVersion" "$JAVA_COMP_VERSION_MAX"`
+ if [ 1 -eq $compMax ] ; then
+ comp=0
+ fi
+ fi
+ if [ -n "$JAVA_COMP_VENDOR" ] ; then
+ debug " checking vendor = {$vendor}, {$JAVA_COMP_VENDOR}"
+ subs=`echo "$vendor" | sed "s/${JAVA_COMP_VENDOR}//"`
+ if [ `ifEquals "$subs" "$vendor"` -eq 1 ] ; then
+ comp=0
+ debug "... vendor incompatible"
+ fi
+ fi
+
+ if [ -n "$JAVA_COMP_OSNAME" ] ; then
+ debug " checking osname = {$osname}, {$JAVA_COMP_OSNAME}"
+ subs=`echo "$osname" | sed "s/${JAVA_COMP_OSNAME}//"`
+
+ if [ `ifEquals "$subs" "$osname"` -eq 1 ] ; then
+ comp=0
+ debug "... osname incompatible"
+ fi
+ fi
+ if [ -n "$JAVA_COMP_OSARCH" ] ; then
+ debug " checking osarch = {$osarch}, {$JAVA_COMP_OSARCH}"
+ subs=`echo "$osarch" | sed "s/${JAVA_COMP_OSARCH}//"`
+
+ if [ `ifEquals "$subs" "$osarch"` -eq 1 ] ; then
+ comp=0
+ debug "... osarch incompatible"
+ fi
+ fi
+ if [ $comp -eq 1 ] ; then
+ LAUNCHER_JAVA_EXE="$javaExe"
+ LAUNCHER_JAVA="$java"
+ verifyResult=$VERIFY_OK
+ fi
+ debug " compatible = [$comp]"
+ javaCompCounter=`expr "$javaCompCounter" + 1`
+ done
+ fi
+ fi
+ fi
+ done
+ fi
+}
+
+checkFreeSpace() {
+ size="$1"
+ path="$2"
+
+ if [ ! -d "$path" ] && [ ! $isSymlink "$path" ] ; then
+ # if checking path is not an existing directory - check its parent dir
+ path=`dirname "$path"`
+ fi
+
+ diskSpaceCheck=0
+
+ if [ 0 -eq $PERFORM_FREE_SPACE_CHECK ] ; then
+ diskSpaceCheck=1
+ else
+ # get size of the atomic entry (directory)
+ freeSpaceDirCheck="$path"/freeSpaceCheckDir
+ debug "Checking space in $path (size = $size)"
+ mkdir -p "$freeSpaceDirCheck"
+ # POSIX compatible du return size in 1024 blocks
+ du --block-size=$DEFAULT_DISK_BLOCK_SIZE "$freeSpaceDirCheck" 1>/dev/null 2>&1
+
+ if [ $? -eq 0 ] ; then
+ debug " getting POSIX du with 512 bytes blocks"
+ atomicBlock=`du --block-size=$DEFAULT_DISK_BLOCK_SIZE "$freeSpaceDirCheck" | awk ' { print $A }' A=1 2>/dev/null`
+ else
+ debug " getting du with default-size blocks"
+ atomicBlock=`du "$freeSpaceDirCheck" | awk ' { print $A }' A=1 2>/dev/null`
+ fi
+ rm -rf "$freeSpaceDirCheck"
+ debug " atomic block size : [$atomicBlock]"
+
+ isBlockNumber=`ifNumber "$atomicBlock"`
+ if [ 0 -eq $isBlockNumber ] ; then
+ out "Can\`t get disk block size"
+ exitProgram $ERROR_INPUTOUPUT
+ fi
+ requiredBlocks=`expr \( "$1" / $DEFAULT_DISK_BLOCK_SIZE \) + $atomicBlock` 1>/dev/null 2>&1
+ if [ `ifNumber $1` -eq 0 ] ; then
+ out "Can\`t calculate required blocks size"
+ exitProgram $ERROR_INPUTOUPUT
+ fi
+ # get free block size
+ column=4
+ df -P --block-size="$DEFAULT_DISK_BLOCK_SIZE" "$path" 1>/dev/null 2>&1
+ if [ $? -eq 0 ] ; then
+ # gnu df, use POSIX output
+ debug " getting GNU POSIX df with specified block size $DEFAULT_DISK_BLOCK_SIZE"
+ availableBlocks=`df -P --block-size="$DEFAULT_DISK_BLOCK_SIZE" "$path" | sed "1d" | awk ' { print $A }' A=$column 2>/dev/null`
+ else
+ # try POSIX output
+ df -P "$path" 1>/dev/null 2>&1
+ if [ $? -eq 0 ] ; then
+ debug " getting POSIX df with 512 bytes blocks"
+ availableBlocks=`df -P "$path" | sed "1d" | awk ' { print $A }' A=$column 2>/dev/null`
+ # try Solaris df from xpg4
+ elif [ -x /usr/xpg4/bin/df ] ; then
+ debug " getting xpg4 df with default-size blocks"
+ availableBlocks=`/usr/xpg4/bin/df -P "$path" | sed "1d" | awk ' { print $A }' A=$column 2>/dev/null`
+ # last chance to get free space
+ else
+ debug " getting df with default-size blocks"
+ availableBlocks=`df "$path" | sed "1d" | awk ' { print $A }' A=$column 2>/dev/null`
+ fi
+ fi
+ debug " available blocks : [$availableBlocks]"
+ if [ `ifNumber "$availableBlocks"` -eq 0 ] ; then
+ out "Can\`t get the number of the available blocks on the system"
+ exitProgram $ERROR_INPUTOUTPUT
+ fi
+
+ # compare
+ debug " required blocks : [$requiredBlocks]"
+
+ if [ $availableBlocks -gt $requiredBlocks ] ; then
+ debug "... disk space check OK"
+ diskSpaceCheck=1
+ else
+ debug "... disk space check FAILED"
+ fi
+ fi
+ if [ 0 -eq $diskSpaceCheck ] ; then
+ mbDownSize=`expr "$size" / 1024 / 1024`
+ mbUpSize=`expr "$size" / 1024 / 1024 + 1`
+ mbSize=`expr "$mbDownSize" \* 1024 \* 1024`
+ if [ $size -ne $mbSize ] ; then
+ mbSize="$mbUpSize"
+ else
+ mbSize="$mbDownSize"
+ fi
+
+ message "$MSG_ERROR_FREESPACE" "$mbSize" "$ARG_TEMPDIR"
+ exitProgram $ERROR_FREESPACE
+ fi
+}
+
+prepareClasspath() {
+ debug "Processing external jars ..."
+ processJarsClasspath
+
+ LAUNCHER_CLASSPATH=""
+ if [ -n "$JARS_CLASSPATH" ] ; then
+ if [ -z "$LAUNCHER_CLASSPATH" ] ; then
+ LAUNCHER_CLASSPATH="$JARS_CLASSPATH"
+ else
+ LAUNCHER_CLASSPATH="$LAUNCHER_CLASSPATH":"$JARS_CLASSPATH"
+ fi
+ fi
+
+ if [ -n "$PREPEND_CP" ] ; then
+ debug "Appending classpath with [$PREPEND_CP]"
+ PREPEND_CP=`resolveString "$PREPEND_CP"`
+
+ if [ -z "$LAUNCHER_CLASSPATH" ] ; then
+ LAUNCHER_CLASSPATH="$PREPEND_CP"
+ else
+ LAUNCHER_CLASSPATH="$PREPEND_CP":"$LAUNCHER_CLASSPATH"
+ fi
+ fi
+ if [ -n "$APPEND_CP" ] ; then
+ debug "Appending classpath with [$APPEND_CP]"
+ APPEND_CP=`resolveString "$APPEND_CP"`
+ if [ -z "$LAUNCHER_CLASSPATH" ] ; then
+ LAUNCHER_CLASSPATH="$APPEND_CP"
+ else
+ LAUNCHER_CLASSPATH="$LAUNCHER_CLASSPATH":"$APPEND_CP"
+ fi
+ fi
+ debug "Launcher Classpath : $LAUNCHER_CLASSPATH"
+}
+
+resolvePropertyStrings() {
+ args="$1"
+ escapeReplacedString="$2"
+ propertyStart=`echo "$args" | sed "s/^.*\\$P{//"`
+ propertyValue=""
+ propertyName=""
+
+ #Resolve i18n strings and properties
+ if [ 0 -eq `ifEquals "$propertyStart" "$args"` ] ; then
+ propertyName=`echo "$propertyStart" | sed "s/}.*//" 2>/dev/null`
+ if [ -n "$propertyName" ] ; then
+ propertyValue=`getMessage "$propertyName"`
+
+ if [ 0 -eq `ifEquals "$propertyValue" "$propertyName"` ] ; then
+ propertyName="\$P{$propertyName}"
+ args=`replaceString "$args" "$propertyName" "$propertyValue" "$escapeReplacedString"`
+ fi
+ fi
+ fi
+
+ echo "$args"
+}
+
+
+resolveLauncherSpecialProperties() {
+ args="$1"
+ escapeReplacedString="$2"
+ propertyValue=""
+ propertyName=""
+ propertyStart=`echo "$args" | sed "s/^.*\\$L{//"`
+
+
+ if [ 0 -eq `ifEquals "$propertyStart" "$args"` ] ; then
+ propertyName=`echo "$propertyStart" | sed "s/}.*//" 2>/dev/null`
+
+
+ if [ -n "$propertyName" ] ; then
+ case "$propertyName" in
+ "nbi.launcher.tmp.dir")
+ propertyValue="$LAUNCHER_EXTRACT_DIR"
+ ;;
+ "nbi.launcher.java.home")
+ propertyValue="$LAUNCHER_JAVA"
+ ;;
+ "nbi.launcher.user.home")
+ propertyValue="$HOME"
+ ;;
+ "nbi.launcher.parent.dir")
+ propertyValue="$LAUNCHER_DIR"
+ ;;
+ *)
+ propertyValue="$propertyName"
+ ;;
+ esac
+ if [ 0 -eq `ifEquals "$propertyValue" "$propertyName"` ] ; then
+ propertyName="\$L{$propertyName}"
+ args=`replaceString "$args" "$propertyName" "$propertyValue" "$escapeReplacedString"`
+ fi
+ fi
+ fi
+ echo "$args"
+}
+
+resolveString() {
+ args="$1"
+ escapeReplacedString="$2"
+ last="$args"
+ repeat=1
+
+ while [ 1 -eq $repeat ] ; do
+ repeat=1
+ args=`resolvePropertyStrings "$args" "$escapeReplacedString"`
+ args=`resolveLauncherSpecialProperties "$args" "$escapeReplacedString"`
+ if [ 1 -eq `ifEquals "$last" "$args"` ] ; then
+ repeat=0
+ fi
+ last="$args"
+ done
+ echo "$args"
+}
+
+replaceString() {
+ initialString="$1"
+ fromString="$2"
+ toString="$3"
+ if [ -n "$4" ] && [ 0 -eq `ifEquals "$4" "false"` ] ; then
+ toString=`escapeString "$toString"`
+ fi
+ fromString=`echo "$fromString" | sed "s/\\\//\\\\\\\\\//g" 2>/dev/null`
+ toString=`echo "$toString" | sed "s/\\\//\\\\\\\\\//g" 2>/dev/null`
+ replacedString=`echo "$initialString" | sed "s/${fromString}/${toString}/g" 2>/dev/null`
+ echo "$replacedString"
+}
+
+prepareJVMArguments() {
+ debug "Prepare JVM arguments... "
+
+ jvmArgCounter=0
+ debug "... resolving string : $LAUNCHER_JVM_ARGUMENTS"
+ LAUNCHER_JVM_ARGUMENTS=`resolveString "$LAUNCHER_JVM_ARGUMENTS" true`
+ debug "... resolved string : $LAUNCHER_JVM_ARGUMENTS"
+ while [ $jvmArgCounter -lt $JVM_ARGUMENTS_NUMBER ] ; do
+ argumentVar="$""JVM_ARGUMENT_$jvmArgCounter"
+ arg=`eval "echo \"$argumentVar\""`
+ debug "... jvm argument [$jvmArgCounter] [initial] : $arg"
+ arg=`resolveString "$arg"`
+ debug "... jvm argument [$jvmArgCounter] [resolved] : $arg"
+ arg=`escapeString "$arg"`
+ debug "... jvm argument [$jvmArgCounter] [escaped] : $arg"
+ LAUNCHER_JVM_ARGUMENTS="$LAUNCHER_JVM_ARGUMENTS $arg"
+ jvmArgCounter=`expr "$jvmArgCounter" + 1`
+ done
+ if [ ! -z "${DEFAULT_USERDIR_ROOT}" ] ; then
+ debug "DEFAULT_USERDIR_ROOT: $DEFAULT_USERDIR_ROOT"
+ LAUNCHER_JVM_ARGUMENTS="$LAUNCHER_JVM_ARGUMENTS -Dnetbeans.default_userdir_root=\"${DEFAULT_USERDIR_ROOT}\""
+ fi
+ if [ ! -z "${DEFAULT_CACHEDIR_ROOT}" ] ; then
+ debug "DEFAULT_CACHEDIR_ROOT: $DEFAULT_CACHEDIR_ROOT"
+ LAUNCHER_JVM_ARGUMENTS="$LAUNCHER_JVM_ARGUMENTS -Dnetbeans.default_cachedir_root=\"${DEFAULT_CACHEDIR_ROOT}\""
+ fi
+
+ debug "Final JVM arguments : $LAUNCHER_JVM_ARGUMENTS"
+}
+
+prepareAppArguments() {
+ debug "Prepare Application arguments... "
+
+ appArgCounter=0
+ debug "... resolving string : $LAUNCHER_APP_ARGUMENTS"
+ LAUNCHER_APP_ARGUMENTS=`resolveString "$LAUNCHER_APP_ARGUMENTS" true`
+ debug "... resolved string : $LAUNCHER_APP_ARGUMENTS"
+ while [ $appArgCounter -lt $APP_ARGUMENTS_NUMBER ] ; do
+ argumentVar="$""APP_ARGUMENT_$appArgCounter"
+ arg=`eval "echo \"$argumentVar\""`
+ debug "... app argument [$appArgCounter] [initial] : $arg"
+ arg=`resolveString "$arg"`
+ debug "... app argument [$appArgCounter] [resolved] : $arg"
+ arg=`escapeString "$arg"`
+ debug "... app argument [$appArgCounter] [escaped] : $arg"
+ LAUNCHER_APP_ARGUMENTS="$LAUNCHER_APP_ARGUMENTS $arg"
+ appArgCounter=`expr "$appArgCounter" + 1`
+ done
+ debug "Final application arguments : $LAUNCHER_APP_ARGUMENTS"
+}
+
+
+runCommand() {
+ cmd="$1"
+ debug "Running command : $cmd"
+ if [ -n "$OUTPUT_FILE" ] ; then
+ #redirect all stdout and stderr from the running application to the file
+ eval "$cmd" >> "$OUTPUT_FILE" 2>&1
+ elif [ 1 -eq $SILENT_MODE ] ; then
+ # on silent mode redirect all out/err to null
+ eval "$cmd" > /dev/null 2>&1
+ elif [ 0 -eq $USE_DEBUG_OUTPUT ] ; then
+ # redirect all output to null
+ # do not redirect errors there but show them in the shell output
+ eval "$cmd" > /dev/null
+ else
+ # using debug output to the shell
+ # not a silent mode but a verbose one
+ eval "$cmd"
+ fi
+ return $?
+}
+
+executeMainClass() {
+ prepareClasspath
+ prepareJVMArguments
+ prepareAppArguments
+ debug "Running main jar..."
+ message "$MSG_RUNNING"
+ classpathEscaped=`escapeString "$LAUNCHER_CLASSPATH"`
+ mainClassEscaped=`escapeString "$MAIN_CLASS"`
+ launcherJavaExeEscaped=`escapeString "$LAUNCHER_JAVA_EXE"`
+ tmpdirEscaped=`escapeString "$LAUNCHER_JVM_TEMP_DIR"`
+
+ command="$launcherJavaExeEscaped $LAUNCHER_JVM_ARGUMENTS -Djava.io.tmpdir=$tmpdirEscaped -classpath $classpathEscaped $mainClassEscaped $LAUNCHER_APP_ARGUMENTS"
+
+ debug "Running command : $command"
+ runCommand "$command"
+ exitCode=$?
+ debug "... java process finished with code $exitCode"
+ exitProgram $exitCode
+}
+
+escapeString() {
+ echo "$1" | sed "s/\\\/\\\\\\\/g;s/\ /\\\\ /g;s/\"/\\\\\"/g;s/(/\\\\\(/g;s/)/\\\\\)/g;" # escape spaces, commas and parentheses
+}
+
+getMessage() {
+ getLocalizedMessage_$LAUNCHER_LOCALE $@
+}
+
+POSSIBLE_JAVA_ENV="JAVA:JAVA_HOME:JAVAHOME:JAVA_PATH:JAVAPATH:JDK:JDK_HOME:JDKHOME:ANT_JAVA:"
+POSSIBLE_JAVA_EXE_SUFFIX_SOLARIS="bin/java:bin/sparcv9/java:"
+POSSIBLE_JAVA_EXE_SUFFIX_COMMON="bin/java:"
diff --git a/src/main/cpp/launcher/windows/.dep.inc b/src/main/cpp/launcher/windows/.dep.inc
new file mode 100644
index 0000000..4560e55
--- /dev/null
+++ b/src/main/cpp/launcher/windows/.dep.inc
@@ -0,0 +1,5 @@
+# This code depends on make tool being used
+DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES}))
+ifneq (${DEPFILES},)
+include ${DEPFILES}
+endif
diff --git a/src/main/cpp/launcher/windows/Makefile b/src/main/cpp/launcher/windows/Makefile
new file mode 100644
index 0000000..1debec6
--- /dev/null
+++ b/src/main/cpp/launcher/windows/Makefile
@@ -0,0 +1,109 @@
+#
+# 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.
+#
+
+#
+# There exist several targets which are by default empty and which can be
+# used for execution of your targets. These targets are usually executed
+# before and after some main targets. They are:
+#
+# .build-pre: called before 'build' target
+# .build-post: called after 'build' target
+# .clean-pre: called before 'clean' target
+# .clean-post: called after 'clean' target
+# .clobber-pre: called before 'clobber' target
+# .clobber-post: called after 'clobber' target
+# .all-pre: called before 'all' target
+# .all-post: called after 'all' target
+# .help-pre: called before 'help' target
+# .help-post: called after 'help' target
+#
+# Targets beginning with '.' are not intended to be called on their own.
+#
+# Main targets can be executed directly, and they are:
+#
+# build build a specific configuration
+# clean remove built files from a configuration
+# clobber remove all built files
+# all build all configurations
+# help print help mesage
+#
+# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
+# .help-impl are implemented in nbproject/makefile-impl.mk.
+#
+
+# Environment
+MKDIR=mkdir
+CP=cp
+CCADMIN=CCadmin
+RANLIB=ranlib
+RESCOMP=windres
+
+
+# build
+build: .build-pre .build-impl .build-post
+
+.build-pre:
+ mkdir -p build
+ windres -I resources -o build/icon.o -i resources/res.rc
+
+.build-post:
+# Add your post 'build' code here...
+
+
+# clean
+clean: .clean-pre .clean-impl .clean-post
+
+.clean-pre:
+ rm -rf build/icon.o
+
+.clean-post:
+# Add your post 'clean' code here...
+
+
+# clobber
+clobber: .clobber-pre .clobber-impl .clobber-post
+
+.clobber-pre:
+# Add your pre 'clobber' code here...
+
+.clobber-post:
+# Add your post 'clobber' code here...
+
+
+# all
+all: .all-pre .all-impl .all-post
+
+.all-pre:
+# Add your pre 'all' code here...
+
+.all-post:
+# Add your post 'all' code here...
+
+
+# help
+help: .help-pre .help-impl .help-post
+
+.help-pre:
+# Add your pre 'help' code here...
+
+.help-post:
+# Add your post 'help' code here...
+
+# include project implementation makefile
+include nbproject/Makefile-impl.mk
diff --git a/src/main/cpp/launcher/windows/Makefile-vc b/src/main/cpp/launcher/windows/Makefile-vc
new file mode 100644
index 0000000..78bc631
--- /dev/null
+++ b/src/main/cpp/launcher/windows/Makefile-vc
@@ -0,0 +1,92 @@
+#
+#
+
+
+!include <$(PLATFORM_SDK)/include/win32.mak>
+
+# define the compiler and linker for all the platforms
+CC32="$(VC_2005)\Bin\cl.exe"
+L32="$(VC_2005)\Bin\link.exe"
+MT32="$(PLATFORM_SDK)\Bin\mt.exe"
+RC32="$(VC_2005)\Bin\rc.exe"
+
+BUILD_DIR32=.\build\32bit
+OUTPUT_FILE32=.\dist\nlw.exe
+MANIFEST_FILE32=.\resources\nlw.exe.manifest
+#Alternative manifest file - read more in resources\res.rc
+#MANIFEST_FILE32=.\resources\nlw-alt.exe.manifest
+
+SOURCE_FILES=\
+ .\src\ExtractUtils.c \
+ .\src\FileUtils.c \
+ .\src\JavaUtils.c \
+ .\src\Launcher.c \
+ .\src\Main.c \
+ .\src\ProcessUtils.c \
+ .\src\RegistryUtils.c \
+ .\src\StringUtils.c \
+ .\src\SystemUtils.c
+
+
+CC32_OPTS=/O1 /Os \
+ /I "$(VC_2005)\include" \
+ /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_CRT_SECURE_NO_DEPRECATE" \
+ /FD /EHsc /MT \
+ /Fo"$(BUILD_DIR32)\\" /Fd"$(BUILD_DIR32)\vc80.pdb" \
+ /W3 /nologo /c /Wp64 /TC /errorReport:prompt
+
+LINKING_LIBRARIES=\
+ user32.lib\
+ gdi32.lib \
+ comdlg32.lib \
+ comctl32.lib \
+ advapi32.lib\
+ shell32.lib \
+ ole32.lib \
+ oleaut32.lib \
+ userenv.lib \
+ libcmt.lib \
+ kernel32.lib
+
+L32_OPTS=\
+ /OUT:$(OUTPUT_FILE32) \
+ /INCREMENTAL:NO \
+ /LIBPATH:"$(PLATFORM_SDK)\Lib" \
+ /MANIFEST \
+ /MANIFESTFILE:"$(BUILD_DIR32)\nlw.exe.intermediate.manifest" \
+ /NODEFAULTLIB \
+ /SUBSYSTEM:WINDOWS \
+ /OPT:REF /OPT:ICF \
+ /MACHINE:X86 \
+ /ERRORREPORT:PROMPT \
+ $(LINKING_LIBRARIES)
+
+
+RC32_OPTS=\
+ /I ".\resources" /fo $(BUILD_DIR32)\resources.obj
+
+
+all: init build-32
+
+clean:
+
+
+init:
+ - md $(BUILD_DIR32)
+ - md .\dist
+
+ del /Q /S $(BUILD_DIR32)
+ del /Q $(OUTPUT_FILE32)
+
+build-32:
+ Set CPU=i386
+ Set Lib=%VC_2005%\Lib;%PLATFORM_SDK%\Lib;%Lib%
+ Set Include=%PLATFORM_SDK%\Include;%Include%
+ Set Path=%PLATFORM_SDK%\Bin;%PLATFORM_SDK%\Bin\WinNT;%VC_2005_PATH%;%path%
+ Set APPVER=5.01
+ Set TARGETOS=WINNT
+
+ $(CC32) $(CC32_OPTS) $(SOURCE_FILES)
+ $(RC32) $(RC32_OPTS) resources/res.rc
+ $(L32) $(L32_OPTS) $(BUILD_DIR32)\ExtractUtils.obj $(BUILD_DIR32)\FileUtils.obj $(BUILD_DIR32)\JavaUtils.obj $(BUILD_DIR32)\Launcher.obj $(BUILD_DIR32)\Main.obj $(BUILD_DIR32)\ProcessUtils.obj $(BUILD_DIR32)\RegistryUtils.obj $(BUILD_DIR32)\StringUtils.obj $(BUILD_DIR32)\SystemUtils.obj $(BUILD_DIR32)\resources.obj
+ $(MT32) /outputresource:"$(OUTPUT_FILE32);#1" -manifest $(MANIFEST_FILE32) $(BUILD_DIR32)\nlw.exe.intermediate.manifest
diff --git a/src/main/cpp/launcher/windows/Makefile-vc-wo-crt b/src/main/cpp/launcher/windows/Makefile-vc-wo-crt
new file mode 100644
index 0000000..6a693f5
--- /dev/null
+++ b/src/main/cpp/launcher/windows/Makefile-vc-wo-crt
@@ -0,0 +1,92 @@
+#
+#
+
+
+!include <$(PLATFORM_SDK)/include/win32.mak>
+
+# define the compiler and linker for all the platforms
+CC32="$(VC_2005)\Bin\cl.exe"
+L32="$(VC_2005)\Bin\link.exe"
+MT32="$(PLATFORM_SDK)\Bin\mt.exe"
+RC32="$(VC_2005)\Bin\rc.exe"
+
+BUILD_DIR32=.\build\32bit
+OUTPUT_FILE32=.\dist\nlw.exe
+MANIFEST_FILE32=.\resources\nlw.exe.manifest
+#Alternative manifest file - read more in resources\res.rc
+#MANIFEST_FILE32=.\resources\nlw-alt.exe.manifest
+
+SOURCE_FILES=\
+ .\src\ExtractUtils.c \
+ .\src\FileUtils.c \
+ .\src\JavaUtils.c \
+ .\src\Launcher.c \
+ .\src\Main.c \
+ .\src\ProcessUtils.c \
+ .\src\RegistryUtils.c \
+ .\src\StringUtils.c \
+ .\src\SystemUtils.c
+
+
+CC32_OPTS=/O1 /Os \
+ /I "$(VC_2005)\include" \
+ /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_CRT_SECURE_NO_DEPRECATE" \
+ /FD /EHsc /GS- \
+ /Fo"$(BUILD_DIR32)\\" /Fd"$(BUILD_DIR32)\vc80.pdb" \
+ /W3 /nologo /c /Wp64 /TC /errorReport:prompt
+
+LINKING_LIBRARIES=\
+ user32.lib\
+ gdi32.lib \
+ comdlg32.lib \
+ comctl32.lib \
+ advapi32.lib\
+ shell32.lib \
+ ole32.lib \
+ oleaut32.lib \
+ userenv.lib \
+ kernel32.lib \
+
+L32_OPTS=\
+ /OUT:$(OUTPUT_FILE32) \
+ /INCREMENTAL:NO \
+ /LIBPATH:"$(PLATFORM_SDK)\Lib" \
+ /MANIFEST \
+ /MANIFESTFILE:"$(BUILD_DIR32)\nlw.exe.intermediate.manifest" \
+ /NODEFAULTLIB \
+ /SUBSYSTEM:WINDOWS \
+ /OPT:REF /OPT:ICF \
+ /MACHINE:X86 \
+ /ERRORREPORT:PROMPT \
+ /ENTRY:MyMain \
+ $(LINKING_LIBRARIES)
+
+
+RC32_OPTS=\
+ /I ".\resources" /fo $(BUILD_DIR32)\resources.obj
+
+
+all: init build-32
+
+clean:
+
+
+init:
+ - md $(BUILD_DIR32)
+ - md .\dist
+
+ del /Q /S $(BUILD_DIR32)
+ del /Q $(OUTPUT_FILE32)
+
+build-32:
+ Set CPU=i386
+ Set Lib=%VC_2005%\Lib;%PLATFORM_SDK%\Lib;%Lib%
+ Set Include=%PLATFORM_SDK%\Include;%Include%
+ Set Path=%PLATFORM_SDK%\Bin;%PLATFORM_SDK%\Bin\WinNT;%VC_2005_PATH%;%path%
+ Set APPVER=5.01
+ Set TARGETOS=WINNT
+
+ $(CC32) $(CC32_OPTS) $(SOURCE_FILES)
+ $(RC32) $(RC32_OPTS) resources/res.rc
+ $(L32) $(L32_OPTS) $(BUILD_DIR32)\ExtractUtils.obj $(BUILD_DIR32)\FileUtils.obj $(BUILD_DIR32)\JavaUtils.obj $(BUILD_DIR32)\Launcher.obj $(BUILD_DIR32)\Main.obj $(BUILD_DIR32)\ProcessUtils.obj $(BUILD_DIR32)\RegistryUtils.obj $(BUILD_DIR32)\StringUtils.obj $(BUILD_DIR32)\SystemUtils.obj $(BUILD_DIR32)\resources.obj
+ $(MT32) /outputresource:"$(OUTPUT_FILE32);#1" -manifest $(MANIFEST_FILE32) $(BUILD_DIR32)\nlw.exe.intermediate.manifest
diff --git a/src/main/cpp/launcher/windows/i18n/launcher.properties b/src/main/cpp/launcher/windows/i18n/launcher.properties
new file mode 100644
index 0000000..70f24c5
--- /dev/null
+++ b/src/main/cpp/launcher/windows/i18n/launcher.properties
@@ -0,0 +1,54 @@
+#
+# 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.
+#
+
+nlw.jvm.notfoundmessage=Java SE Development Kit (JDK) was not found on this computer\nJDK 8 or newer is required for installing the NetBeans IDE. Make sure that the JDK is properly installed and run installer again. You can specify valid JDK location using {0} installer argument.\n\nTo download the JDK, visit http://www.oracle.com/technetwork/java/javase/downloads
+nlw.jvm.usererror=Java Runtime Environment (JRE) was not found\nThere is no JRE at the specified location {0}
+nlw.jvm.unsupportedversion=Unsupported Java VM version\nThe Java VM at {0} has the unsupported version
+nlw.freespace=There is not enough free disk space to extract installation data\n{0} MB of free disk space is required in a temporary folder. Clean up the disk space and run installer again. You can specify a temporary folder with sufficient disk space using {1} installer argument
+nlw.tmpdir=Can't create temporary directory\nThe temporary directory for extracting data {0} was not created
+nlw.integrity=Installer file is corrupted\nInstaller file {0} seems to be corrupted
+nlw.output.error=Data extraction error\nCan't create file {0}!\nThe following error occured :\n{1}
+nlw.java.process.error=An error occured while running java process\n{0}
+nlw.missing.external.resource=Can`t run NetBeans Installer.\nAn external file with necessary data is required but missing:\n{0}
+nlw.bundled.jvm.extract.error=Cannot prepare bundled JVM to run the installer.\nMost probably the bundled JVM is not compatible with the current platform.
+nlw.bundled.jvm.verify.error=An error occured while verifying bundled JVM.\nMost probably the bundled JVM is not compatible with the current platform.
+
+nlw.arg.output={0} <output-file>\n\tRedirect output to file <output-file>
+nlw.arg.javahome={0} <javahomedir>\n\tRun jar file using JVM from <javahomedir>
+nlw.arg.verbose={0}\n\tUse verbose output
+nlw.arg.tempdir={0} <temp-dir>\n\tUse <temp-dir> for extracting data
+nlw.arg.extract={0} [directory]\n\tExtract all bundled data to the specific directory.\n\tIf directory is not specified then extract to the current directory
+nlw.arg.classpatha={0} <classpath>\n\tAppend classpath with <classpath>
+nlw.arg.classpathp={0} <classpath>\n\tPrepend classpath with <classpath>
+nlw.arg.disable.space.check={0}\n\tDisable free space check
+nlw.arg.locale={0} <locale>\n\tOverride system default locale with <locale>
+nlw.arg.silent={0} \n\tRun installer silently
+nlw.arg.help={0}\n\tShow help message
+
+
+nlw.msg.create.tmpdir=Creating temporary directory ...
+nlw.msg.extract=Extracting data ...
+nlw.msg.jvmsearch=Finding JVM on your system ...
+nlw.msg.setoptions=Setting command options ...
+nlw.msg.running=Running JVM ...
+nlw.msg.title=Please wait while the launcher prepares data to run the installer ...
+nlw.msg.messagebox.title=Apache NetBeans IDE Installer
+nlw.msg.progress.title=Configuring the installer ...
+nlw.msg.button.error=Exit Installer
+nlw.msg.main.title=Apache NetBeans IDE Installer
diff --git a/src/main/cpp/launcher/windows/nbproject/configurations.xml b/src/main/cpp/launcher/windows/nbproject/configurations.xml
new file mode 100644
index 0000000..095caed
--- /dev/null
+++ b/src/main/cpp/launcher/windows/nbproject/configurations.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<configurationDescriptor version="84">
+ <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
+ <logicalFolder name="HeaderFiles"
+ displayName="Header Files"
+ projectFiles="true">
+ <itemPath>src/Errors.h</itemPath>
+ <itemPath>src/ExtractUtils.h</itemPath>
+ <itemPath>src/FileUtils.h</itemPath>
+ <itemPath>src/JavaUtils.h</itemPath>
+ <itemPath>src/Launcher.h</itemPath>
+ <itemPath>src/Main.h</itemPath>
+ <itemPath>src/ProcessUtils.h</itemPath>
+ <itemPath>src/RegistryUtils.h</itemPath>
+ <itemPath>src/StringUtils.h</itemPath>
+ <itemPath>src/SystemUtils.h</itemPath>
+ <itemPath>src/Types.h</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ResourceFiles"
+ displayName="Resource Files"
+ projectFiles="true">
+ <itemPath>resources/res.rc</itemPath>
+ </logicalFolder>
+ <logicalFolder name="SourceFiles"
+ displayName="Source Files"
+ projectFiles="true">
+ <itemPath>src/ExtractUtils.c</itemPath>
+ <itemPath>src/FileUtils.c</itemPath>
+ <itemPath>src/JavaUtils.c</itemPath>
+ <itemPath>src/Launcher.c</itemPath>
+ <itemPath>src/Main.c</itemPath>
+ <itemPath>src/ProcessUtils.c</itemPath>
+ <itemPath>src/RegistryUtils.c</itemPath>
+ <itemPath>src/StringUtils.c</itemPath>
+ <itemPath>src/SystemUtils.c</itemPath>
+ </logicalFolder>
+ <logicalFolder name="ExternalFiles"
+ displayName="Important Files"
+ projectFiles="false">
+ <itemPath>Makefile</itemPath>
+ </logicalFolder>
+ </logicalFolder>
+ <projectmakefile>Makefile</projectmakefile>
+ <confs>
+ <conf name="Debug" type="1">
+ <toolsSet>
+ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
+ <compilerSet>Cygwin|Cygwin</compilerSet>
+ </toolsSet>
+ <compileType>
+ <cTool>
+ <stripSymbols>true</stripSymbols>
+ <commandLine>-mno-cygwin</commandLine>
+ <warningLevel>3</warningLevel>
+ </cTool>
+ <ccTool>
+ <stripSymbols>true</stripSymbols>
+ </ccTool>
+ <linkerTool>
+ <output>dist/nlw</output>
+ <stripSymbols>true</stripSymbols>
+ <linkerLibItems>
+ <linkerOptionItem>-lole32 -luuid -lkernel32 -lcomctl32 -luserenv</linkerOptionItem>
+ </linkerLibItems>
+ <commandLine>-mwindows -mno-cygwin build/icon.o</commandLine>
+ </linkerTool>
+ </compileType>
+ </conf>
+ <conf name="Release" type="1">
+ <toolsSet>
+ <remote-sources-mode>LOCAL_SOURCES</remote-sources-mode>
+ <compilerSet>Cygwin|Cygwin</compilerSet>
+ </toolsSet>
+ <compileType>
+ <cTool>
+ <developmentMode>5</developmentMode>
+ </cTool>
+ <ccTool>
+ <developmentMode>5</developmentMode>
+ </ccTool>
+ <fortranCompilerTool>
+ <developmentMode>5</developmentMode>
+ </fortranCompilerTool>
+ </compileType>
+ </conf>
+ </confs>
+</configurationDescriptor>
diff --git a/src/main/cpp/launcher/windows/nbproject/project.properties b/src/main/cpp/launcher/windows/nbproject/project.properties
new file mode 100644
index 0000000..3807b67
--- /dev/null
+++ b/src/main/cpp/launcher/windows/nbproject/project.properties
@@ -0,0 +1,20 @@
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
diff --git a/src/main/cpp/launcher/windows/nbproject/project.xml b/src/main/cpp/launcher/windows/nbproject/project.xml
new file mode 100644
index 0000000..017b77b
--- /dev/null
+++ b/src/main/cpp/launcher/windows/nbproject/project.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.cnd.makeproject</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/make-project/1">
+ <name>NBI Native Launcher : Windows</name>
+ <make-project-type>0</make-project-type>
+ <c-extensions>c</c-extensions>
+ <cpp-extensions/>
+ <header-extensions>h</header-extensions>
+ <sourceEncoding>UTF-8</sourceEncoding>
+ <make-dep-projects/>
+ <sourceRootList/>
+ <confList>
+ <confElem>
+ <name>Debug</name>
+ <type>1</type>
+ </confElem>
+ <confElem>
+ <name>Release</name>
+ <type>1</type>
+ </confElem>
+ </confList>
+ </data>
+ </configuration>
+</project>
diff --git a/src/main/cpp/launcher/windows/resources/icon.ico b/src/main/cpp/launcher/windows/resources/icon.ico
new file mode 100644
index 0000000..ec123c0
--- /dev/null
+++ b/src/main/cpp/launcher/windows/resources/icon.ico
Binary files differ
diff --git a/src/main/cpp/launcher/windows/resources/nlw-alt.exe.manifest b/src/main/cpp/launcher/windows/resources/nlw-alt.exe.manifest
new file mode 100644
index 0000000..62fb856
--- /dev/null
+++ b/src/main/cpp/launcher/windows/resources/nlw-alt.exe.manifest
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="nlw" type="win32"/>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
\ No newline at end of file
diff --git a/src/main/cpp/launcher/windows/resources/nlw.exe.manifest b/src/main/cpp/launcher/windows/resources/nlw.exe.manifest
new file mode 100644
index 0000000..a22dcb9
--- /dev/null
+++ b/src/main/cpp/launcher/windows/resources/nlw.exe.manifest
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="nlw" type="win32"/>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="requireAdministrator"/>
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
\ No newline at end of file
diff --git a/src/main/cpp/launcher/windows/resources/res.rc b/src/main/cpp/launcher/windows/resources/res.rc
new file mode 100644
index 0000000..012c85e
--- /dev/null
+++ b/src/main/cpp/launcher/windows/resources/res.rc
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+
+// Uncomment the following lines to add special "Vista" manifest under Cygwin using GCC and WINDRES
+// Seems that tools from MS Platform SDK/MS VS C++ 2005 EE (C compiler, resource compiler and manifest tool) ignore that
+// (so you can leave that uncommented for both tools at once) but I haven`t check that much.
+// PS. Currently uncommented - seems to be working with GCC compiler (checked by Martin Sladecek)
+#define RT_MANIFEST 24
+#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
+
+
+// Using of nlw.exe.manifest means that on Vista every installer/uninstaller (launcher, in general) invocation would require admin privileges which user would be asked for (evaluation dialog).
+// In that case the executable icon would have "shield" mark.
+// Using of nlw-alt.exe.manifest means that on Vista evaluation dialog is not displayed. To run it with admin right user have to execute "Run as Administrator" explicitely.
+// Without the build-it manifest the following issue can occur (reported Martin Sladecek):
+// When launcher would have "instal" in its name (uninstall.exe for instance), then - due to UAC and it`s method of checking "installer-like" names and code stamps - it would be executed with Administrator`s environment - it is would be different from the user that performed the installation.
+// Only one of the following lines should be commented, the other one should be uncommented.
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "nlw.exe.manifest"
+//CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "nlw-alt.exe.manifest"
+
+100 ICON DISCARDABLE "icon.ico"
+
diff --git a/src/main/cpp/launcher/windows/src/Errors.h b/src/main/cpp/launcher/windows/src/Errors.h
new file mode 100644
index 0000000..7955823
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/Errors.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.
+ */
+
+#ifndef _Errors_H
+#define _Errors_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define ERROR_OK 0
+#define ERROR_INTEGRITY 1000
+#define ERROR_FREESPACE 1001
+#define ERROR_INPUTOUPUT 1002
+#define ERROR_JVM_UNCOMPATIBLE 1003
+#define ERROR_JVM_NOT_FOUND 1004
+#define ERROR_ON_EXECUTE_PROCESS 1005
+#define ERROR_PROCESS_TIMEOUT 1006
+#define ERROR_USER_TERMINATED 1007
+#define EXTERNAL_RESOURCE_MISSING 1008
+#define ERROR_BUNDLED_JVM_EXTRACTION 1009
+#define ERROR_BUNDLED_JVM_VERIFICATION 1010
+
+#define EXIT_CODE_EVENTS_INITIALIZATION_ERROR 1022
+#define EXIT_CODE_GUI_INITIALIZATION_ERROR 1023
+#define EXIT_CODE_STUB 1024
+#define EXIT_CODE_SYSTEM_ERROR 1025
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _Errors_H */
+
diff --git a/src/main/cpp/launcher/windows/src/ExtractUtils.c b/src/main/cpp/launcher/windows/src/ExtractUtils.c
new file mode 100644
index 0000000..edbfa55
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/ExtractUtils.c
@@ -0,0 +1,761 @@
+/*
+ * 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 <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "FileUtils.h"
+#include "StringUtils.h"
+#include "SystemUtils.h"
+#include "JavaUtils.h"
+#include "RegistryUtils.h"
+#include "ExtractUtils.h"
+#include "Launcher.h"
+#include "Main.h"
+
+const DWORD STUB_FILL_SIZE = 450000;
+
+void skipLauncherStub(LauncherProperties * props, DWORD stubSize) {
+ HANDLE hFileRead = props->handler;
+
+ if(hFileRead!=INVALID_HANDLE_VALUE) {
+ // just read stub data.. no need to write it anywhere
+ DWORD read = 0;
+ char * offsetbuf = newpChar(stubSize);
+ DWORD sizeLeft = stubSize;
+ while(ReadFile(hFileRead, offsetbuf, sizeLeft, &read, 0) && sizeLeft && read) {
+ sizeLeft-=read;
+ addProgressPosition(props, read);
+ if(sizeLeft==0) break;
+ if(read==0) { // we need some more bytes to read but we can`t to read
+ props->status = ERROR_INTEGRITY;
+ break;
+ }
+ }
+ FREE(offsetbuf);
+ }
+}
+
+
+void skipStub(LauncherProperties * props) {
+ if(props->isOnlyStub) {
+ WCHAR * os;
+ props->status = EXIT_CODE_STUB;
+ os = appendStringW(NULL, L"It`s only the launcher stub.\nOS: ");
+ if(is9x()) os = appendStringW(os, L"Windows 9x");
+ if(isNT()) os = appendStringW(os, L"Windows NT");
+ if(is2k()) os = appendStringW(os, L"Windows 2000");
+ if(isXP()) os = appendStringW(os, L"Windows XP");
+ if(is2003()) os = appendStringW(os, L"Windows 2003");
+ if(isVista()) os = appendStringW(os, L"Windows Vista");
+ if(is2008()) os = appendStringW(os, L"Windows 2008");
+ if(is7()) os = appendStringW(os, L"Windows 7");
+ if(IsWow64) os = appendStringW(os, L" x64");
+ showMessageW(props, os , 0);
+ FREE(os);
+ } else {
+ skipLauncherStub(props, STUB_FILL_SIZE);
+ if(!isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 1,
+ "Error! Can`t process launcher stub", 1);
+ showErrorW(props, INTEGRITY_ERROR_PROP, 1, props->exeName);
+ }
+ }
+}
+
+void modifyRestBytes(SizedString* rest, DWORD start) {
+
+ DWORD len = rest->length - start;
+ char * restBytesNew = NULL;
+
+ if(len>0) {
+ DWORD i;
+ restBytesNew = newpChar(len);
+ for(i=start;i<rest->length;i++) {
+ restBytesNew[i-start] = (rest->bytes) [i];
+ }
+ }
+ FREE(rest->bytes);
+ rest->bytes = restBytesNew;
+ rest->length = len;
+}
+
+DWORD readStringFromBuf(SizedString *rest, SizedString * result, DWORD isUnicode) {
+ if((rest->length)!=0) {
+ // we have smth in the restBytes that we have read but haven`t yet proceeded
+ DWORD i=0;
+ for(i=0;i<rest->length;i++) {
+ DWORD check = ((rest->bytes)[i]==0);
+ if(isUnicode) {
+ if ( (i/2)*2==i) {// i is even
+ check = check && (i < rest->length-1 && ((rest->bytes)[i+1]==0));
+ } else {
+ check = 0;
+ }
+ }
+ if( check ) { // we have found null character in the rest bytes
+ result->bytes = appendStringN(NULL, 0, rest->bytes, i);
+ result->length = i;
+ modifyRestBytes(rest, i + 1 + isUnicode);
+ return ERROR_OK;
+ }
+ }
+ //here we have found no \0 character in the rest of bytes...
+ }
+ return ERROR_INPUTOUPUT;
+}
+
+void readString(LauncherProperties * props, SizedString * result, DWORD isUnicode) {
+ DWORD * status = & props->status;
+ HANDLE hFileRead = props->handler;
+ SizedString * rest = props->restOfBytes;
+ DWORD bufferSize = props->bufsize;
+ DWORD read=0;
+ char * buf = NULL;
+
+ if(*status != ERROR_OK ) return;
+
+ if(readStringFromBuf(rest, result, isUnicode)==ERROR_OK) {
+ return;
+ }
+
+ //we need to read file for more data to find \0 character...
+
+ buf = newpChar(bufferSize);
+
+ while (ReadFile(hFileRead, buf, bufferSize, &read, 0) && read) {
+ addProgressPosition(props, read);
+ rest->bytes = appendStringN(rest->bytes, rest->length, buf, read);
+ rest->length = rest->length + read;
+ if(readStringFromBuf(rest, result, isUnicode)==ERROR_OK) {
+ //if(result->bytes!=NULL) {
+ //we have find \0 character
+ break;
+ }
+ ZERO(buf, sizeof(char) * bufferSize);
+ if(read==0) { // we have nothing to read.. smth wrong
+ *status = ERROR_INTEGRITY;
+ break;
+ }
+ }
+ FREE(buf);
+ return;
+}
+
+
+
+void readNumber(LauncherProperties * props, DWORD * result) {
+ if(isOK(props)) {
+
+ SizedString * numberString = createSizedString();
+ DWORD i =0;
+ DWORD number = 0;
+
+ readString(props, numberString, 0);
+ if(!isOK(props)) {
+ freeSizedString(&numberString);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1,
+ "Error!! Can`t read number string. Most probably integrity error.", 1);
+ return;
+ }
+
+ if(numberString->bytes==NULL) {
+ freeSizedString(&numberString);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1,
+ "Error!! Can`t read number string (it can`t be NULL). Most probably integrity error.", 1);
+ props->status = ERROR_INTEGRITY;
+ return;
+ }
+
+
+ for(;i<numberString->length;i++) {
+ char c = numberString->bytes[i];
+ if(c>='0' && c<='9') {
+ number = number * 10 + (c - '0');
+ } else if(c==0) {
+ // we have reached the end of number section
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1,
+ "Can`t read number from string (it contains zero character):", 1);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, numberString->bytes, 1);
+ props->status = ERROR_INTEGRITY;
+ break;
+ } else {
+ // unexpected...
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1,
+ "Can`t read number from string (unexpected error):", 1);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, numberString->bytes, 1);
+ props->status = ERROR_INTEGRITY;
+ break;
+ }
+ }
+ freeSizedString(&numberString);
+ *result = number;
+ }
+}
+
+void readStringWithDebugW(LauncherProperties * props, WCHAR ** dest, char * paramName) {
+ SizedString *sizedStr = createSizedString();
+ if(paramName!=NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Reading ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, paramName, 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " : ", 0);
+ }
+ readString(props, sizedStr, 1);
+ if(!isOK(props)) {
+ freeSizedString(&sizedStr);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0,
+ "[ERROR] Can`t read string !! Seems to be integrity error", 1);
+ return;
+ }
+ *dest = createWCHAR(sizedStr);
+ freeSizedString(&sizedStr);
+ if(paramName!=NULL) {
+ if((*dest)!=NULL) {
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, *dest, 1);
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "NULL", 1);
+ }
+ }
+ return;
+}
+
+void readStringWithDebugA(LauncherProperties * props, char ** dest, char * paramName) {
+ SizedString *sizedStr = createSizedString();
+
+ if(paramName!=NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Reading ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, paramName, 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " : ", 0);
+ }
+ readString( props, sizedStr, 0);
+ if(!isOK(props)) {
+ freeSizedString(&sizedStr);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0,
+ "[ERROR] Can`t read string!!! Seems to be integritiy error", 1);
+ return;
+ }
+ *dest = appendString(NULL, sizedStr->bytes);
+ if(paramName!=NULL) {
+ if((*dest)==NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "NULL", 1);
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, *dest, 1);
+ }
+ }
+ freeSizedString(&sizedStr);
+ return;
+}
+
+
+void readNumberWithDebug(LauncherProperties * props, DWORD * dest, char * paramName) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Reading ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, paramName, 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " : ", 0);
+ readNumber(props, dest);
+
+ if(!isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0,
+ "[ERROR] Can`t read number !!! Seems to be integrity error", 1);
+ return;
+ }
+ writeDWORD(props, OUTPUT_LEVEL_DEBUG, 0, NULL, *dest, 1);
+ return;
+}
+void readBigNumberWithDebug(LauncherProperties * props, int64t * dest, char * paramName) {
+ DWORD low = 0;
+ DWORD high = 0;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Reading ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, paramName, 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " : ", 0);
+
+ readNumber(props, &low);
+ if(isOK(props)) {
+ readNumber(props, &high);
+ }
+ if(!isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0,
+ "[ERROR] Can`t read number !!! Seems to be integrity error", 1);
+ return;
+ }
+ dest->High = high;
+ dest->Low = low;
+ writeint64t(props, OUTPUT_LEVEL_DEBUG, 0, "", dest, 1);
+}
+
+// returns: ERROR_OK, ERROR_INPUTOUPUT, ERROR_INTEGRITY
+void extractDataToFile(LauncherProperties * props, WCHAR *output, int64t * fileSize, DWORD expectedCRC ) {
+ if(isOK(props)) {
+ DWORD * status = & props->status;
+ HANDLE hFileRead = props->handler;
+ int64t * size = fileSize;
+ DWORD counter = 0;
+ DWORD crc32 = -1L;
+ HANDLE hFileWrite = CreateFileW(output, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, hFileRead);
+
+ if (hFileWrite == INVALID_HANDLE_VALUE) {
+ WCHAR * err;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "[ERROR] Can`t create file ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, output, 1);
+
+ err = getErrorDescription(GetLastError());
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Error description : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, err, 1);
+
+ showErrorW(props, OUTPUT_ERROR_PROP, 2, output, err);
+ FREE(err);
+ *status = ERROR_INPUTOUPUT;
+ return;
+ }
+ if(props->restOfBytes->length!=0 && props->restOfBytes->bytes!=NULL) {
+ //check if the data stored in restBytes is more than we neen
+ // rest bytes contains much less than int64t so we operate here only bith low bits of size
+ DWORD restBytesToWrite = (compare(size, props->restOfBytes->length)> 0 ) ? props->restOfBytes->length : size->Low;
+ DWORD usedBytes = restBytesToWrite;
+
+ char *ptr = props->restOfBytes->bytes;
+
+ DWORD write = 0;
+ while (restBytesToWrite >0) {
+ WriteFile(hFileWrite, ptr, restBytesToWrite, &write, 0);
+ update_crc32(&crc32, ptr, write);
+ restBytesToWrite -= write;
+ ptr +=write;
+ }
+ modifyRestBytes(props->restOfBytes, usedBytes);
+ minus(size, usedBytes);
+
+ }
+
+
+ if(compare(size, 0) > 0 ) {
+ DWORD bufferSize = props->bufsize;
+ char * buf = newpChar(bufferSize);
+ DWORD bufsize = (compare(size, bufferSize) > 0) ? bufferSize : size->Low;
+ DWORD read = 0 ;
+ // printf("Using buffer size: %u/%u\n", bufsize, bufferSize);
+ while (ReadFile(hFileRead, buf, bufsize, &read, 0) && read && compare(size, 0) > 0) {
+ addProgressPosition(props, read);
+ WriteFile(hFileWrite, buf, read, &read, 0);
+ update_crc32(&crc32, buf, read);
+
+ minus(size, read);
+
+ if((compare(size, bufsize)<0) && (compare(size, 0)>0) ) {
+ bufsize = size->Low;
+ }
+ ZERO(buf, sizeof(char) * bufferSize);
+ if(compare(size, 0)==0) {
+ break;
+ }
+ if((counter ++) % 20 == 0) {
+ if(isTerminated(props)) break;
+ }
+
+ }
+ if((compare(size, 0)>0 || read==0) && !isTerminated(props)) {
+ // we could not read requested size
+ * status = ERROR_INTEGRITY;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1,
+ "Can`t read data from file : not enought data", 1);
+ }
+ FREE(buf);
+ }
+ CloseHandle(hFileWrite);
+ crc32=~crc32;
+ if(isOK(props) && crc32!=expectedCRC) {
+ writeDWORD(props, OUTPUT_LEVEL_DEBUG, 0, "expected CRC : ", expectedCRC, 1);
+ writeDWORD(props, OUTPUT_LEVEL_DEBUG, 0, "real CRC : ", crc32, 1);
+ * status = ERROR_INTEGRITY;
+
+ }
+ }
+}
+
+//returns : ERROR_OK, ERROR_INTEGRITY, ERROR_FREE_SPACE
+void extractFileToDir(LauncherProperties * props, WCHAR ** resultFile) {
+ WCHAR * fileName = NULL;
+ int64t * fileLength = NULL;
+ DWORD crc = 0;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Extracting file ...", 1);
+ readStringWithDebugW( props, & fileName, "file name");
+
+ fileLength = newint64_t(0, 0);
+ readBigNumberWithDebug( props, fileLength, "file length ");
+
+ readNumberWithDebug( props, &crc, "CRC32");
+
+ if(!isOK(props)) return;
+
+ if(fileName!=NULL) {
+ DWORD i=0;
+ WCHAR * dir;
+ resolveString(props, &fileName);
+
+ for(i=0;i<getLengthW(fileName);i++) {
+ if(fileName[i]==L'/') {
+ fileName[i]=L'\\';
+ }
+ }
+
+ dir = getParentDirectory(fileName);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " ... extract to directory = ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, dir, 1);
+
+ checkFreeSpace(props, dir, fileLength);
+ FREE(dir);
+ if(isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " ... starting data extraction", 1);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " ... output file is ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, fileName, 1);
+ extractDataToFile(props, fileName, fileLength, crc);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " ... extraction finished", 1);
+ *resultFile = fileName;
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " ... data extraction canceled", 1);
+ }
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Error! File name can`t be null. Seems to be integrity error!", 1);
+ *resultFile = NULL;
+ props -> status = ERROR_INTEGRITY;
+ }
+ FREE(fileLength);
+ return;
+}
+
+
+void loadI18NStrings(LauncherProperties * props) {
+ DWORD i=0;
+ DWORD j=0;
+ //read number of locales
+
+ DWORD numberOfLocales = 0;
+ DWORD numberOfProperties = 0;
+
+ readNumberWithDebug(props, &numberOfLocales, "number of locales");
+ if(!isOK(props)) return;
+ if(numberOfLocales==0) {
+ props->status = ERROR_INTEGRITY;
+ return ;
+ }
+
+
+ readNumberWithDebug( props, &numberOfProperties, "i18n properties");
+ if(!isOK(props)) return;
+ if(numberOfProperties==0) {
+ props->status = ERROR_INTEGRITY;
+ return ;
+ }
+
+ props->i18nMessages = (I18NStrings * ) LocalAlloc(LPTR, sizeof(I18NStrings) * numberOfProperties);
+
+ props->I18N_PROPERTIES_NUMBER = numberOfProperties;
+ props->i18nMessages->properties = newppChar(props->I18N_PROPERTIES_NUMBER);
+ props->i18nMessages->strings = newppWCHAR(props->I18N_PROPERTIES_NUMBER);
+
+ for(i=0; isOK(props) && i<numberOfProperties;i++) {
+ // read property name as ASCII
+ char * propName = NULL;
+ char * number = DWORDtoCHARN(i,2);
+ props->i18nMessages->properties[i] = NULL;
+ props->i18nMessages->strings[i] = NULL;
+ propName = appendString(NULL, "property name ");
+
+ propName = appendString(propName, number);
+ FREE(number);
+
+ readStringWithDebugA(props, & (props->i18nMessages->properties[i]), propName);
+ FREE(propName);
+ }
+ if(isOK(props)) {
+
+ DWORD isLocaleMatches;
+ WCHAR * localeName;
+ WCHAR * currentLocale = getLocaleName();
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Current System Locale : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, currentLocale, 1);
+
+ if(props->userDefinedLocale!=NULL) { // using user-defined locale via command-line parameter
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "[CMD Argument] Try to use locale ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, props->userDefinedLocale, 1);
+ FREE(currentLocale);
+ currentLocale = appendStringW(NULL, props->userDefinedLocale);
+ }
+
+ for(j=0;j<numberOfLocales;j++) { // for all locales in file...
+ // read locale name as UNICODE ..
+ // it should be like en_US or smth like that
+ localeName = NULL;
+ readStringWithDebugW(props, &localeName, "locale name");
+ if(!isOK(props)) break;
+
+ isLocaleMatches = (localeName==NULL) ? 1 :
+ searchW(currentLocale, localeName) != NULL;
+
+ //read properties names and value
+ for(i=0;i<numberOfProperties;i++) {
+ // read property value as UNICODE
+
+ WCHAR * value = NULL;
+ char * s1 = DWORDtoCHAR(i + 1);
+ char * s2 = DWORDtoCHAR(numberOfProperties);
+ char * s3 = appendString(NULL , "value ");
+ s3 = appendString(s3 , s1);
+ s3 = appendString(s3, "/");
+ s3 = appendString(s3, s2);
+ FREE(s1);
+ FREE(s2);
+ readStringWithDebugW(props, &value, s3);
+
+ FREE(s3);
+ if(!isOK(props)) break;
+ if(isLocaleMatches) {
+ //it is a know property
+ FREE(props->i18nMessages->strings[i]);
+ props->i18nMessages->strings[i] = appendStringW(NULL, value);
+ }
+ FREE(value);
+ }
+ FREE(localeName);
+ }
+ FREE(currentLocale);
+ }
+}
+
+LauncherResource * newLauncherResource() {
+ LauncherResource * file = (LauncherResource *) LocalAlloc(LPTR, sizeof(LauncherResource));
+ file->path=NULL;
+ file->resolved=NULL;
+ file->type=0;
+ return file;
+}
+WCHARList * newWCHARList(DWORD number) {
+ WCHARList * list = (WCHARList*) LocalAlloc(LPTR, sizeof(WCHARList));
+ list->size = number;
+ if(number>0) {
+ DWORD i=0;
+ list->items = newppWCHAR(number);
+ for(i=0;i<number;i++) {
+ list->items[i] = NULL;
+ }
+ } else {
+ list->items = NULL;
+ }
+ return list;
+}
+
+void freeWCHARList(WCHARList ** plist) {
+ WCHARList * list;
+ list = * plist;
+ if(list!=NULL) {
+ DWORD i=0;
+ if(list->items!=NULL) {
+ for(i=0;i<list->size;i++) {
+ FREE(list->items[i]);
+ }
+ FREE(list->items);
+ }
+ FREE(*plist);
+ }
+}
+
+LauncherResourceList * newLauncherResourceList(DWORD number) {
+ LauncherResourceList * list = (LauncherResourceList*) LocalAlloc(LPTR, sizeof(LauncherResourceList));
+ list->size = number;
+ if(number > 0) {
+ DWORD i=0;
+
+ list->items = (LauncherResource**) LocalAlloc(LPTR, sizeof(LauncherResource*) * number);
+ for(i=0;i<number;i++) {
+ list->items[i] = NULL;
+ }
+ } else {
+ list->items = NULL;
+ }
+ return list;
+}
+
+void freeLauncherResource(LauncherResource ** file) {
+ if(*file!=NULL) {
+ FREE((*file)->path);
+ FREE((*file)->resolved);
+ FREE(*file);
+
+ }
+}
+
+
+void extractLauncherResource(LauncherProperties * props, LauncherResource ** file, char * name) {
+ char * typeStr = appendString(appendString(NULL, name), " type");
+ * file = newLauncherResource();
+
+ readNumberWithDebug( props, & ((*file)->type) , typeStr);
+
+ if(isOK(props)) {
+ FREE(typeStr);
+
+ if((*file)->type==0) { //bundled
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... file is bundled", 1);
+ extractFileToDir(props, & ((*file)->path));
+ if(!isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Error extracting file!", 1);
+ return;
+ } else {
+ (*file)->resolved = appendStringW(NULL, (*file)->path);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "file was succesfully extracted to ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, (*file)->path, 1);
+ }
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... file is external", 1);
+ readStringWithDebugW(props, & ((*file)->path), name);
+ if(!isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Error reading ", 1);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, name, 1);
+ }
+ }
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Error reading ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, typeStr, 0);
+ FREE(typeStr);
+ }
+}
+
+void readWCHARList(LauncherProperties * props, WCHARList ** list, char * name) {
+ DWORD number = 0;
+ DWORD i =0;
+ char * numberStr = appendString(appendString(NULL, "number of "), name);
+
+ * list = NULL;
+ readNumberWithDebug(props, &number, numberStr);
+ FREE(numberStr);
+
+ if(!isOK(props)) return;
+
+ * list = newWCHARList(number);
+ for(i=0;i < (*list)->size ;i++) {
+ char * nextStr = appendString(appendString(NULL, "next item in "), name);
+ readStringWithDebugW(props, &((*list)->items[i]), nextStr);
+ FREE(nextStr);
+ if(!isOK(props)) return;
+ }
+}
+void readLauncherResourceList(LauncherProperties * props, LauncherResourceList ** list, char * name) {
+ DWORD num = 0;
+ DWORD i=0;
+ char * numberStr = appendString(appendString(NULL, "number of "), name);
+ readNumberWithDebug(props, &num, numberStr);
+ FREE(numberStr);
+ if(!isOK(props)) return;
+
+ * list = newLauncherResourceList(num);
+ for(i=0;i<(*list)->size;i++) {
+ extractLauncherResource(props, & ((*list)->items[i]), "launcher resource");
+ if(!isOK(props)) {
+ char * str = appendString(appendString(NULL, "Error processing "), name);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, str, 1);
+ FREE(str);
+ break;
+ }
+ }
+}
+
+void readLauncherProperties(LauncherProperties * props) {
+ DWORD i=0;
+ char * str = NULL;
+
+ readWCHARList(props, &(props->jvmArguments), "jvm arguments");
+ if(!isOK(props)) return;
+
+ readWCHARList(props, &(props->appArguments), "app arguments");
+ if(!isOK(props)) return;
+
+ readStringWithDebugW(props, &(props->mainClass), "Main Class");
+ if(!isOK(props)) return;
+
+ readStringWithDebugW(props, &(props->testJVMClass), "TestJVM Class");
+ if(!isOK(props)) return;
+
+ readNumberWithDebug( props, &(props->compatibleJavaNumber),
+ "compatible java");
+ if(!isOK(props)) return;
+
+
+
+ if ( props->compatibleJavaNumber > 0 ) {
+ props->compatibleJava = (JavaCompatible **) LocalAlloc(LPTR, sizeof(JavaCompatible *) * props->compatibleJavaNumber);
+ for(i=0;i<props->compatibleJavaNumber;i++) {
+
+ props->compatibleJava [i] = newJavaCompatible() ;
+
+ readStringWithDebugA(props, &str, "min java version");
+ if(!isOK(props)) return;
+ props->compatibleJava[i]->minVersion = getJavaVersionFromString(str, &props->status);
+ FREE(str);
+ if(!isOK(props)) return;
+
+ str = NULL;
+ readStringWithDebugA(props, &str, "max java version");
+ if(!isOK(props)) return;
+ props->compatibleJava[i]->maxVersion = getJavaVersionFromString(str, &props->status);
+ FREE(str);
+ if(!isOK(props)) return;
+
+ readStringWithDebugA(props, &(props->compatibleJava[i]->vendor) ,
+ "vendor");
+ if(!isOK(props)) return;
+
+ readStringWithDebugA(props, &(props->compatibleJava[i]->osName) ,
+ "os name");
+ if(!isOK(props)) return;
+
+ readStringWithDebugA(props, &(props->compatibleJava[i]->osArch) ,
+ "os arch");
+ if(!isOK(props)) return;
+
+ }
+ }
+ readNumberWithDebug( props, &props->bundledNumber, "bundled files");
+ readBigNumberWithDebug(props, props->bundledSize, "bundled size");
+}
+
+void extractJVMData(LauncherProperties * props) {
+ if(isOK(props)) {
+
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Extracting JVM data... ", 1);
+ extractLauncherResource(props, &(props->testJVMFile), "testJVM file");
+ if(!isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Error extracting testJVM file!", 1);
+ return ;
+ }
+
+ readLauncherResourceList(props, &(props->jvms), "JVMs");
+ }
+}
+
+void extractData(LauncherProperties *props) {
+ if(isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Extracting Bundled data... ", 1);
+ readLauncherResourceList(props, &(props->jars), "bundled and external files");
+ if(isOK(props)) {
+ readLauncherResourceList(props, &(props->other), "other data");
+ }
+ }
+}
diff --git a/src/main/cpp/launcher/windows/src/ExtractUtils.h b/src/main/cpp/launcher/windows/src/ExtractUtils.h
new file mode 100644
index 0000000..f816df8
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/ExtractUtils.h
@@ -0,0 +1,50 @@
+/*
+ * 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 _ExtractUtils_H
+#define _ExtractUtils_H
+
+#include <windows.h>
+#include "StringUtils.h"
+#include "JavaUtils.h"
+#include "Errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ extern const DWORD STUB_FILL_SIZE;
+
+ void skipStub(LauncherProperties * props);
+
+ void loadI18NStrings(LauncherProperties * props);
+
+ WCHARList * newWCHARList(DWORD number) ;
+ void readLauncherProperties(LauncherProperties * props);
+ void freeWCHARList(WCHARList ** plist);
+ void freeLauncherResource(LauncherResource ** file);
+
+ void extractJVMData(LauncherProperties * props);
+ void extractData(LauncherProperties *props);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ExtractUtils_H */
diff --git a/src/main/cpp/launcher/windows/src/FileUtils.c b/src/main/cpp/launcher/windows/src/FileUtils.c
new file mode 100644
index 0000000..6c36fd6
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/FileUtils.c
@@ -0,0 +1,593 @@
+/*
+ * 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 <windows.h>
+#include <wchar.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <userenv.h>
+#include "FileUtils.h"
+#include "StringUtils.h"
+
+HANDLE stdoutHandle = INVALID_HANDLE_VALUE;
+HANDLE stderrHandle = INVALID_HANDLE_VALUE;
+
+DWORD newLine = 1;
+const WCHAR * FILE_SEP = L"\\";
+
+const long CRC32_TABLE[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535,
+ 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd,
+ 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d,
+ 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+ 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac,
+ 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab,
+ 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+ 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb,
+ 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea,
+ 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce,
+ 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+ 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409,
+ 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739,
+ 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268,
+ 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0,
+ 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8,
+ 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+ 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703,
+ 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7,
+ 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae,
+ 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6,
+ 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d,
+ 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5,
+ 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+ 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+void writeTimeStamp(HANDLE hd, DWORD need) {
+ DWORD written;
+ if(need==1) {
+ SYSTEMTIME t;
+ char * yearStr;
+ char * monthStr;
+ char * dayStr;
+ char * hourStr;
+ char * minuteStr;
+ char * secondStr;
+ char * msStr;
+ char * result = NULL;
+ GetLocalTime(&t);
+ yearStr = word2charN(t.wYear,2);
+ monthStr = word2charN(t.wMonth,2);
+ dayStr = word2charN(t.wDay,2);
+ hourStr = word2charN(t.wHour,2);
+ minuteStr = word2charN(t.wMinute,2);
+ secondStr = word2charN(t.wSecond,2);
+ msStr = word2charN(t.wMilliseconds,3);
+
+ result = appendString(NULL, "[");
+ result = appendString(result, yearStr);
+ result = appendString(result, "-");
+ result = appendString(result, monthStr);
+ result = appendString(result, "-");
+ result = appendString(result, dayStr);
+ result = appendString(result, " ");
+ result = appendString(result, hourStr);
+ result = appendString(result, ":");
+ result = appendString(result, minuteStr);
+ result = appendString(result, ":");
+ result = appendString(result, secondStr);
+ result = appendString(result, ".");
+ result = appendString(result, msStr);
+ result = appendString(result, "]> ");
+
+ WriteFile(hd, result, sizeof(char) * getLengthA(result), & written, NULL);
+ FREE(result);
+ FREE(yearStr);
+ FREE(monthStr);
+ FREE(dayStr);
+
+ FREE(hourStr);
+ FREE(minuteStr);
+ FREE(secondStr);
+ FREE(msStr);
+ }
+}
+
+void writeMessageA(LauncherProperties * props, DWORD level, DWORD isErr, const char * message, DWORD needEndOfLine) {
+ if(level>=props->outputLevel) {
+ HANDLE hd = (isErr) ? props->stderrHandle : props->stdoutHandle;
+ DWORD written;
+ writeTimeStamp(hd, newLine);
+ WriteFile(hd, message, sizeof(char) * getLengthA(message), & written, NULL);
+ if(needEndOfLine>0) {
+ newLine = 0;
+ while((needEndOfLine--)>0) {
+ writeMessageA(props, level, isErr, "\r\n", 0);
+ newLine = 1;
+ }
+ flushHandle(hd);
+ } else {
+ newLine = 0;
+ }
+ }
+}
+
+void writeMessageW(LauncherProperties * props, DWORD level, DWORD isErr, const WCHAR * message, DWORD needEndOfLine) {
+ if ( level >= props->outputLevel ) {
+ char * msg = toChar(message);
+ writeMessageA(props, level, isErr, msg, needEndOfLine);
+ FREE(msg);
+ }
+}
+void writeDWORD(LauncherProperties * props, DWORD level, DWORD isErr, const char * message, DWORD value, DWORD needEndOfLine) {
+ char * dwordStr = DWORDtoCHAR(value);
+ writeMessageA(props, level, isErr, message, 0);
+ writeMessageA(props, level, isErr, dwordStr, needEndOfLine);
+ FREE(dwordStr);
+}
+
+void writeint64t(LauncherProperties * props, DWORD level, DWORD isErr, const char * message, int64t * value, DWORD needEndOfLine) {
+ char * str = int64ttoCHAR(value);
+ writeMessageA(props, level, isErr, message, 0);
+ writeMessageA(props, level, isErr, str, needEndOfLine);
+ FREE(str);
+}
+void writeErrorA(LauncherProperties * props, DWORD level, DWORD isErr, const char * message, const WCHAR * param, DWORD errorCode) {
+ WCHAR * err = getErrorDescription(errorCode);
+ writeMessageA(props, level, isErr, message, 0);
+ writeMessageW(props, level, isErr, param, 1);
+ writeMessageW(props, level, isErr, err, 1);
+ FREE(err);
+}
+
+void flushHandle(HANDLE hd) {
+ FlushFileBuffers(hd);
+}
+
+int64t * getFreeSpace(WCHAR *path) {
+ int64t bytes;
+ int64t * result = newint64_t(0, 0);
+ WCHAR * dst = appendStringW(NULL, path);
+
+ while(!fileExists(dst)) {
+ WCHAR * parent = getParentDirectory(dst);
+ FREE(dst);
+ dst = parent;
+ if(dst==NULL) break;
+ }
+ if(dst==NULL) return result; // no parent ? strange
+ if (GetDiskFreeSpaceExW(dst, (PULARGE_INTEGER) &bytes, NULL, NULL)) {
+ result->High = bytes.High;
+ result->Low = bytes.Low;
+ }
+ FREE(dst);
+ return result;
+}
+
+void checkFreeSpace(LauncherProperties * props, WCHAR * tmpDir, int64t * size) {
+ if(props->checkForFreeSpace) {
+ int64t * space = getFreeSpace(tmpDir);
+ DWORD result = 0;
+ result = ((space->High > size->High) ||
+ (space->High == size->High && space->Low >= size->Low));
+
+ if(!result) {
+ WCHAR * available = NULL;
+ WCHAR * str = NULL;
+ WCHAR * required = NULL;
+ available = int64ttoWCHAR(space);
+ required = int64ttoWCHAR(size);
+ str = appendStringW(str, L"Not enough free space in ");
+ str = appendStringW(str, tmpDir);
+ str = appendStringW(str, L", available=");
+ str = appendStringW(str, available);
+ str = appendStringW(str, L", required=");
+ str = appendStringW(str, required);
+
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 1, str, 1);
+ FREE(str);
+ FREE(available);
+ FREE(required);
+ props->status = ERROR_FREESPACE;
+ }
+ FREE(space);
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... free space checking is disabled", 1);
+ }
+}
+
+DWORD fileExists(WCHAR *path) {
+ WIN32_FILE_ATTRIBUTE_DATA attrs;
+ return GetFileAttributesExW(path, GetFileExInfoStandard, &attrs);
+}
+
+DWORD isDirectory(WCHAR *path) {
+ WIN32_FILE_ATTRIBUTE_DATA attrs;
+ if(GetFileAttributesExW(path, GetFileExInfoStandard, &attrs)) {
+ return (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
+ }
+ else {
+ return 0;
+ }
+}
+WCHAR * getParentDirectory(WCHAR * dir) {
+ WCHAR * ptr = dir;
+ WCHAR * res = NULL;
+ while(1) {
+ if(searchW(ptr, FILE_SEP)==NULL) {
+ break;
+ }
+ ptr = searchW(ptr, FILE_SEP) + 1;
+ }
+ res = appendStringNW(NULL, 0, dir, getLengthW(dir) - getLengthW(ptr) - 1);
+ return res;
+}
+WCHAR * normalizePath(WCHAR * dir) {
+ WCHAR * directory = NULL;
+ WCHAR * ptr1, *ptr2, *ptr3;
+ DWORD i=0;
+ DWORD len;
+ ptr1 = searchW(dir, L":\\");
+ ptr2 = searchW(dir, L":/");
+ ptr3 = searchW(dir, L"\\\\");
+ if(ptr1==NULL && ptr2==NULL && dir!=ptr3) { //relative path
+ directory = appendStringW(getCurrentDirectory(), FILE_SEP);
+ directory = appendStringW(directory, dir);
+ } else {
+ directory = appendStringW(NULL, dir);
+ }
+ len = getLengthW(directory);
+
+ for(i=0;i<len;i++) {
+ if(directory[i]=='/') directory[i] = '\\';
+ }
+ return directory;
+}
+
+void createDirectory(LauncherProperties * props, WCHAR * directory) {
+
+ WCHAR * parent;
+ // now directory is the absolute path with normalized slashes
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Getting parent directory of ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, directory, 1);
+
+ parent = getParentDirectory(directory);
+
+ if(parent!=NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " parent = ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, parent, 1);
+
+ if(!fileExists(parent)) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... doesn`t exist. Create it...", 1);
+ createDirectory(props, parent);
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " ... exist. ", 1);
+ }
+ if(isOK(props)) {
+ DWORD parentAttrs = GetFileAttributesW(parent);
+ if(parentAttrs == INVALID_FILE_ATTRIBUTES) {
+ props-> status = ERROR_INPUTOUPUT;
+ } else {
+ SECURITY_ATTRIBUTES secattr;
+ int64t * minSize = newint64_t(0, 0);
+
+ secattr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ secattr.lpSecurityDescriptor = 0;
+ secattr.bInheritHandle = 1;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... creating directory itself... ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 1, directory, 1);
+
+ checkFreeSpace(props, parent, minSize);
+ FREE(minSize);
+
+ if(isOK(props)) {
+ props->status = (CreateDirectoryExW(parent, directory, &secattr)) ? ERROR_OK : ERROR_INPUTOUPUT;
+ if(!isOK(props)) {
+ props->status = (CreateDirectoryW(directory, &secattr)) ? ERROR_OK : ERROR_INPUTOUPUT;
+ }
+ props->status = (fileExists(directory)) ? ERROR_OK : ERROR_INPUTOUPUT;
+
+ if(isOK(props)) {
+ SetFileAttributesW(directory, parentAttrs);
+ } else {
+ writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t create directory : ", directory, GetLastError());
+ }
+ }
+ }
+ }
+ FREE(parent);
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " parent is NULL ", 1);
+ props-> status = ERROR_INPUTOUPUT;
+ }
+}
+
+#define a 16807 /* multiplier */
+#define m 2147483647L /* 2**31 - 1 */
+#define q 127773L /* m div a */
+#define r 2836 /* m mod a */
+
+long nextRandDigit(long seed)
+{
+ unsigned long lo, hi;
+
+ lo = a * (long)(seed & 0xFFFF);
+ hi = a * (long)((unsigned long)seed >> 16);
+ lo += (hi & 0x7FFF) << 16;
+ if (lo > m)
+ {
+ lo &= m;
+ ++lo;
+ }
+ lo += hi >> 15;
+ if (lo > m)
+ {
+ lo &= m;
+ ++lo;
+ }
+ return (long)lo;
+}
+
+void createTempDirectory(LauncherProperties * props, WCHAR * argTempDir, DWORD createRndSubDir) {
+ WCHAR * t = (argTempDir!=NULL) ? appendStringW(NULL, argTempDir) : getSystemTemporaryDirectory();
+
+ WCHAR * nbiTmp = normalizePath(t);
+ FREE(t);
+ if(createRndSubDir) {
+ WCHAR * randString = newpWCHAR(6);
+ DWORD i=0;
+ DWORD initValue = GetTickCount() & 0x7FFFFFFF;
+ long value = (long) initValue;
+ nbiTmp = appendStringW(nbiTmp, L"\\NBI");
+
+ for(i=0;i<5;i++) {
+ value = nextRandDigit(value);
+ randString[i] = '0' + (WCHAR) (value% 10);
+ }
+ nbiTmp = appendStringW(appendStringW(nbiTmp, randString), L".tmp");
+ FREE(randString);
+ }
+
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Using temp directory for extracting data : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, nbiTmp, 1);
+
+ if(fileExists(nbiTmp) ) {
+ if(!isDirectory(nbiTmp)) {
+ props->status = ERROR_INPUTOUPUT;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, ".. exists but not a directory", 1);
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Output directory already exist so don`t create it", 1);
+ }
+ }
+ else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "creating directory...", 1);
+ createDirectory(props, nbiTmp);
+ if(isOK(props)) {
+ props->tmpDirCreated = 1;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Directory created : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, nbiTmp, 1);
+ // set hidden attribute
+ if(createRndSubDir) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Setting hidden attributes to ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 1, nbiTmp, 1);
+
+ SetFileAttributesW(nbiTmp, GetFileAttributesW(nbiTmp) | FILE_ATTRIBUTE_HIDDEN);
+ }
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t create nbi temp directory : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 1, nbiTmp, 1);
+ }
+ }
+ props->tmpDir = nbiTmp;
+ return;
+}
+
+
+void deleteDirectory(LauncherProperties * props, WCHAR * dir) {
+ DWORD attrs = GetFileAttributesW(dir);
+ DWORD dwError;
+ DWORD count = 0 ;
+ if(attrs==INVALID_FILE_ATTRIBUTES) {
+ writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t get attributes of the dir : ", dir, GetLastError());
+ return;
+ }
+ if(!SetFileAttributesW(dir, attrs & FILE_ATTRIBUTE_NORMAL)) {
+ writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t set attributes of the dir : ", dir, GetLastError());
+ }
+
+
+ if(attrs & FILE_ATTRIBUTE_DIRECTORY) {
+ WIN32_FIND_DATAW FindFileData;
+ HANDLE hFind = INVALID_HANDLE_VALUE;
+
+ WCHAR * DirSpec = appendStringW(appendStringW(NULL, dir), L"\\*" );
+
+ // Find the first file in the directory.
+ hFind = FindFirstFileW(DirSpec, &FindFileData);
+
+ if (hFind == INVALID_HANDLE_VALUE) {
+ writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t file with pattern ", DirSpec, GetLastError());
+ }
+ else {
+ // List all the other files in the directory.
+ while (FindNextFileW(hFind, &FindFileData) != 0) {
+ if(lstrcmpW(FindFileData.cFileName, L".")!=0 &&
+ lstrcmpW(FindFileData.cFileName, L"..")!=0 ) {
+ WCHAR * child = appendStringW(appendStringW(appendStringW(NULL, dir), FILE_SEP), FindFileData.cFileName);
+ deleteDirectory(props, child);
+ FREE(child);
+ }
+ }
+
+ dwError = GetLastError();
+ FindClose(hFind);
+ if (dwError != ERROR_NO_MORE_FILES) {
+ writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t find file with pattern : ", DirSpec, dwError);
+ }
+ }
+
+ // 20 tries in 2 seconds to delete the directory
+ while(!RemoveDirectoryW(dir) && count++ < 20) Sleep(100);
+ FREE(DirSpec);
+ }
+ else {
+ // 20 tries in 2 seconds to delete the file
+ while(!DeleteFileW(dir) && count++ < 20) Sleep(100);
+ }
+}
+
+
+
+
+WCHAR * getSystemTemporaryDirectory() {
+ WCHAR * expanded = newpWCHAR(MAX_PATH);
+ DWORD result;
+ if(GetTempPathW(MAX_PATH, expanded)!=0) {
+ return expanded;
+ }
+
+ result = GetEnvironmentVariableW(L"TEMP", expanded, MAX_PATH);
+ if(result<=0 || result>MAX_PATH) {
+ //writeOutputLn("Can`t find variable TEMP");
+ result = GetEnvironmentVariableW(L"TMP", expanded, MAX_PATH);
+ if(result<=0 || result>MAX_PATH) {
+ //writeOutputLn("Can`t find variable TMP");
+ result = GetEnvironmentVariableW(L"USERPROFILE", expanded, MAX_PATH);
+ if(result>0 && result<=MAX_PATH) {
+ expanded = appendStringW(expanded, L"\\Local Settings\\Temp");
+ } else{
+ WCHAR * curdir = getCurrentDirectory();
+ ZERO(expanded, sizeof(WCHAR) * MAX_PATH);
+ lstrcpynW(expanded, curdir, MAX_PATH);
+ FREE(curdir);
+ }
+ }
+ }
+ return expanded;
+}
+
+WCHAR * getExePath() {
+ WCHAR * szPath = newpWCHAR(MAX_PATH);
+
+ if( !GetModuleFileNameW( NULL, szPath, MAX_PATH ) ) {
+ FREE(szPath);
+ return NULL;
+ } else {
+ return szPath;//appendStringNW(NULL, 0, szPath, getLengthW(szPath));
+ }
+}
+
+
+WCHAR * getExeName() {
+ WCHAR * szPath = newpWCHAR(MAX_PATH);
+ WCHAR * result = NULL;
+ if(GetModuleFileNameW( NULL, szPath, MAX_PATH )) {
+ WCHAR * lastSlash = szPath;
+ while(searchW(lastSlash, FILE_SEP)!=NULL) {
+ lastSlash = searchW(lastSlash, FILE_SEP) + 1;
+ }
+ result = appendStringW(NULL, lastSlash);
+ }
+ FREE(szPath);
+ return result;
+}
+
+WCHAR * getExeDirectory() {
+ WCHAR * szPath = newpWCHAR(MAX_PATH);
+ WCHAR * result = NULL;
+ if(GetModuleFileNameW( NULL, szPath, MAX_PATH )) {
+ WCHAR * lastSlash = szPath;
+ while(searchW(lastSlash, FILE_SEP)!=NULL) {
+ lastSlash = searchW(lastSlash, FILE_SEP) + 1;
+ }
+ result = appendStringNW(NULL, 0 , szPath,
+ getLengthW(szPath) - getLengthW(lastSlash) - 1);
+ }
+ FREE(szPath);
+ return result;
+}
+
+WCHAR * getCurrentDirectory() {
+ WCHAR * buf = newpWCHAR(MAX_PATH);
+
+ if(GetCurrentDirectoryW(MAX_PATH, buf)!=0) {
+ return buf;
+ } else {
+ FREE(buf);
+ return NULL;
+ }
+}
+WCHAR * getCurrentUserHome() {
+ HANDLE hUser;
+ WCHAR * buf = NULL;
+ if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hUser)) {
+ DWORD size = MAX_PATH;
+ buf = newpWCHAR(MAX_PATH);
+ GetUserProfileDirectoryW(hUser, buf, &size);
+ if (size > MAX_PATH) {
+ FREE(buf);
+ buf = newpWCHAR(size + 1);
+ if(!GetUserProfileDirectoryW(hUser, buf, &size)) {
+ FREE(buf);
+ }
+ }
+ CloseHandle(hUser);
+ }
+ if(buf==NULL) {
+ DWORD size = MAX_PATH;
+ buf = newpWCHAR(size);
+ size = GetEnvironmentVariableW(L"USERPROFILE", buf, MAX_PATH);
+ if( size > MAX_PATH) {
+ FREE(buf);
+ buf = newpWCHAR(size + 1);
+ GetEnvironmentVariableW(L"USERPROFILE", buf, size);
+ } else if (size==0) {
+ FREE(buf);
+ }
+ }
+ return buf;
+}
+int64t * getFileSize(WCHAR * path) {
+ WIN32_FILE_ATTRIBUTE_DATA wfad;
+ int64t * res = newint64_t(0, 0);
+ if (GetFileAttributesExW(path,
+ GetFileExInfoStandard,
+ &wfad)) {
+ res->Low = wfad.nFileSizeLow;
+ res->High = wfad.nFileSizeHigh ;
+ }
+ return res;
+}
+
+void update_crc32(DWORD * crc, char *ptr, DWORD size) {
+ while( size-- ) *crc = CRC32_TABLE[(unsigned char) (*crc^*ptr++)] ^ (*crc>>8);
+}
diff --git a/src/main/cpp/launcher/windows/src/FileUtils.h b/src/main/cpp/launcher/windows/src/FileUtils.h
new file mode 100644
index 0000000..0b01ace
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/FileUtils.h
@@ -0,0 +1,68 @@
+/*
+ * 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 _FileUtils_H
+#define _FileUtils_H
+
+#include <windows.h>
+#include "Errors.h"
+#include "Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OUTPUT_LEVEL_DEBUG 0
+#define OUTPUT_LEVEL_NORMAL 1
+
+
+ extern const WCHAR * FILE_SEP;
+ extern const long CRC32_TABLE[256];
+ void update_crc32(DWORD * crc32, char * buf, DWORD size);
+ int64t * getFreeSpace(WCHAR *path);
+ int64t * getFileSize(WCHAR * path);
+ void checkFreeSpace(LauncherProperties * props, WCHAR * tmpDir, int64t * size);
+ WCHAR * getParentDirectory(WCHAR * dir);
+ void createDirectory(LauncherProperties * props, WCHAR * directory);
+ void createTempDirectory(LauncherProperties * props, WCHAR * argTempDir, DWORD createRndSubDir);
+ void deleteDirectory(LauncherProperties * props,WCHAR * dir);
+ WCHAR * getExePath();
+ WCHAR * getExeName();
+ WCHAR * getExeDirectory();
+
+ WCHAR * getSystemTemporaryDirectory();
+ DWORD isDirectory(WCHAR *path);
+ WCHAR * getCurrentDirectory();
+ WCHAR * getCurrentUserHome();
+
+
+ void writeMessageW(LauncherProperties * props, DWORD level,DWORD isErr, const WCHAR * message, DWORD needEndOfLine);
+ void writeMessageA(LauncherProperties * props,DWORD level, DWORD isErr, const char * message, DWORD needEndOfLine);
+ void writeErrorA(LauncherProperties * props,DWORD level, DWORD isErr, const char * message, const WCHAR * param, DWORD errorCode);
+ void writeDWORD(LauncherProperties * props,DWORD level, DWORD isErr, const char * message, DWORD value, DWORD needEndOfLine);
+ void writeint64t(LauncherProperties * props,DWORD level, DWORD isErr, const char * message, int64t * value, DWORD needEndOfLine);
+
+ void flushHandle(HANDLE hd);
+ DWORD fileExists(WCHAR * path);
+
+ #ifdef __cplusplus
+}
+#endif
+
+#endif /* _FileUtils_H */
diff --git a/src/main/cpp/launcher/windows/src/JavaUtils.c b/src/main/cpp/launcher/windows/src/JavaUtils.c
new file mode 100644
index 0000000..9e4245e
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/JavaUtils.c
@@ -0,0 +1,796 @@
+/*
+ * 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 <wchar.h>
+#include <stdio.h>
+#include "JavaUtils.h"
+#include "RegistryUtils.h"
+#include "StringUtils.h"
+#include "SystemUtils.h"
+#include "FileUtils.h"
+#include "ProcessUtils.h"
+#include "Launcher.h"
+#include "Main.h"
+
+const DWORD JAVA_VERIFICATION_PROCESS_TIMEOUT = 10000; // 10sec
+const DWORD UNPACK200_EXTRACTION_TIMEOUT = 60000; //60 seconds on each file
+const DWORD JAVA_VERIFICATION_PROCESS_PRIORITY = NORMAL_PRIORITY_CLASS;
+const WCHAR * JAVA_EXE_SUFFIX = L"\\bin\\java.exe";
+const WCHAR * UNPACK200_EXE_SUFFIX = L"\\bin\\unpack200.exe";
+const WCHAR * JAVA_LIB_SUFFIX = L"\\lib";
+const WCHAR * PACK_GZ_SUFFIX = L".pack.gz";
+const WCHAR * JAR_PACK_GZ_SUFFIX = L".jar.pack.gz";
+
+const DWORD JVM_EXTRACTION_TIMEOUT = 180000; //180sec
+
+WCHAR * JAVA_REGISTRY_KEYS [] = {
+ L"SOFTWARE\\JavaSoft\\Java Runtime Environment",
+ L"SOFTWARE\\JavaSoft\\Java Development Kit",
+ L"SOFTWARE\\JavaSoft\\JDK",
+ L"SOFTWARE\\JRockit\\Java Runtime Environment",
+ L"SOFTWARE\\JRockit\\Java Development Kit",
+ L"SOFTWARE\\IBM\\Java Runtime Environment",
+ L"SOFTWARE\\IBM\\Java2 Runtime Environment",
+ L"SOFTWARE\\IBM\\Java Development Kit",
+};
+WCHAR * JAVA_HOME = L"JavaHome";
+WCHAR * CURRENT_VERSION = L"CurrentVersion";
+
+WCHAR * getJavaHomeValue(WCHAR *parentkey, WCHAR *subkey, BOOL access64key) {
+ return getStringValuePC(HKEY_LOCAL_MACHINE, parentkey, subkey, JAVA_HOME, access64key);
+}
+
+
+WCHAR * getTestJVMFileName(WCHAR * testJVMFile) {
+ WCHAR * filePtr = testJVMFile;
+ WCHAR * testJavaClass = NULL;
+
+ if(filePtr!=NULL) {
+ WCHAR * dotClass = NULL;
+ while(searchW(filePtr, L"\\")!=NULL) {
+ filePtr = searchW(filePtr, L"\\");
+ filePtr++;
+ }
+ dotClass = searchW(filePtr, L".class");
+
+ if(dotClass!=NULL) {
+ testJavaClass = appendStringNW(NULL, 0, filePtr, getLengthW(filePtr) - getLengthW(dotClass));
+ }
+ }
+ return testJavaClass;
+}
+
+
+//returns 0 if equals, 1 if first > second, -1 if first < second
+char compareJavaVersion(JavaVersion * first, JavaVersion * second) {
+ if(first==NULL) return (second==NULL) ? 0 : -1;
+ if(second==NULL) return -1;
+ if(first->major == second->major) {
+ if(first->minor == second->minor) {
+ if(first->micro == second->micro) {
+ if(first->update == second->update) return 0;
+ return (first->update > second->update) ? 1 : -1;
+ }
+ return (first->micro > second->micro) ? 1 : -1;
+ }
+ return (first->minor > second->minor) ? 1 : -1;
+ } else {
+ return (first->major > second->major) ? 1 : -1;
+ }
+}
+DWORD isJavaCompatible(JavaProperties *currentJava, JavaCompatible ** compatibleJava, DWORD number) {
+ JavaVersion * current = currentJava->version;
+ DWORD i = 0 ;
+
+ for(i=0;i<number;i++) {
+ DWORD check = 1;
+
+ check = (compareJavaVersion(current, compatibleJava[i]->minVersion) >= 0 &&
+ compareJavaVersion(current, compatibleJava[i]->maxVersion) <= 0) ? check : 0;
+
+ if (check) {
+ if(compatibleJava[i]->vendor!=NULL) {
+ check = (searchA(currentJava->vendor, compatibleJava[i]->vendor) != NULL) ? check : 0;
+ }
+ if (compatibleJava[i]->osName!=NULL) {
+ check = (searchA(currentJava->osName, compatibleJava[i]->osName)!=NULL) ? check : 0;
+ }
+
+ if (compatibleJava[i]->osArch!=NULL) {
+ check = (searchA(currentJava->osArch, compatibleJava[i]->osArch)!=NULL) ? check : 0;
+ }
+ if(check) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+JavaVersion * getJavaVersionFromString(char * string, DWORD * result) {
+ JavaVersion *vers = NULL;
+ if(getLengthA(string)<3) {
+ return vers;
+ }
+
+ const char *p = string;
+
+ // get major
+ long major = 0;
+ while(*p!=0) {
+ char c = *p++;
+ if(c>='0' && c<='9') {
+ major = (major) * 10 + c - '0';
+ if (major > 999) return vers;
+ continue;
+ } else if(c=='.' || c=='+'){
+ break;
+ } else{
+ return vers;
+ }
+ }
+
+ // get minor
+ long minor = 0;
+ while(*p!=0) {
+ char c = *p;
+ if(c>='0' && c<='9') {
+ minor = (minor) * 10 + c - '0';
+ p++;
+ continue;
+ }
+ break;
+ }
+
+ *result = ERROR_OK;
+ vers = (JavaVersion*) LocalAlloc(LPTR, sizeof(JavaVersion));
+ vers->major = major;
+ vers->minor = minor;
+ vers->micro = 0;
+ vers->update = 0;
+ ZERO(vers->build, 128);
+
+ if(p[0]=='.') { // micro...
+ p++;
+ while(*p!=0) {
+ char c = *p;
+ if(c>='0' && c<='9') {
+ vers->micro = (vers->micro) * 10 + c - '0';
+ p++;
+ continue;
+ } else if(c=='_') {//update
+ p++;
+ while((c = *p) != 0) {
+ p++;
+ if(c>='0' && c<='9') {
+ vers->update = (vers->update) * 10 + c - '0';
+ continue;
+ } else {
+ break;
+ }
+ }
+ } else {
+ if(*p!=0) p++;
+ }
+ if(c=='-' && *p!=0) { // build number
+ lstrcpyn(vers->build, p, min(127, getLengthA(p)+1));
+ }
+ break;
+ }
+ }
+ return vers;
+}
+
+DWORD getJavaPropertiesFromOutput(LauncherProperties * props, char *str, JavaProperties ** javaProps) {
+ DWORD separators = getLineSeparatorNumber(str);
+ DWORD result = ERROR_INPUTOUPUT;
+ * javaProps = NULL;
+ if(separators == TEST_JAVA_PARAMETERS) {
+ char * start;
+ char * end;
+ char * javaVersion;
+ char * javaVmVersion;
+ char * javaVendor;
+ char * osName;
+ char * osArch;
+ char * string;
+ JavaVersion * vers;
+
+ start = str;
+ end = searchA(start, "\n");
+
+ javaVersion = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " java.version = ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, javaVersion, 1);
+ start = end + 1;
+ end = searchA(start, "\n");
+
+
+ javaVmVersion = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " java.vm.version = ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, javaVmVersion, 1);
+ start = end + 1;
+ end = searchA(start, "\n");
+
+ javaVendor = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " java.vendor = ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, javaVendor, 1);
+ start = end + 1;
+ end = searchA(start, "\n");
+
+ osName = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " os.name = ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, osName, 1);
+ start = end + 1;
+ end = searchA(start, "\n");
+
+ osArch = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " os.arch = ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, osArch, 2);
+
+ string = javaVersion;
+
+
+ if(javaVmVersion!=NULL) {
+ string = searchA(javaVmVersion, javaVersion);
+ if(string==NULL) {
+ string = javaVersion;
+ }
+ }
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... getting java version from string : ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, string, 1);
+
+ vers = getJavaVersionFromString(string, & result);
+ if(javaProps != NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... some java there", 1);
+ * javaProps = (JavaProperties *) LocalAlloc(LPTR, sizeof(JavaProperties));
+ (*javaProps)->version = vers;
+ (*javaProps)->vendor = javaVendor;
+ (*javaProps)->osName = osName;
+ (*javaProps)->osArch = osArch;
+ (*javaProps)->javaHome = NULL;
+ (*javaProps)->javaExe = NULL;
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... no java there", 1);
+ FREE(javaVendor);
+ FREE(osName);
+ FREE(osArch);
+ }
+ FREE(javaVmVersion);
+ FREE(javaVersion);
+ }
+ return result;
+}
+
+
+void getJavaProperties(WCHAR * location, LauncherProperties * props, JavaProperties ** javaProps) {
+ WCHAR *testJavaClass = props->testJVMClass;
+ WCHAR *javaExecutable = getJavaResource(location, JAVA_EXE_SUFFIX);
+ WCHAR *libDirectory = getJavaResource(location, JAVA_LIB_SUFFIX);
+
+ if(fileExists(javaExecutable) && testJavaClass!=NULL && isDirectory(libDirectory)) {
+ WCHAR * command = NULL;
+ HANDLE hRead;
+ HANDLE hWrite;
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... java hierarchy there", 1);
+ // <location>\bin\java.exe exists
+
+
+ appendCommandLineArgument(&command, javaExecutable);
+ appendCommandLineArgument(&command, L"-classpath");
+ appendCommandLineArgument(&command, props->testJVMFile->resolved);
+ appendCommandLineArgument(&command, testJavaClass);
+
+
+ CreatePipe(&hRead, &hWrite, NULL, 0);
+ // Start the child process.
+ executeCommand(props, command, NULL, JAVA_VERIFICATION_PROCESS_TIMEOUT, hWrite, INVALID_HANDLE_VALUE, JAVA_VERIFICATION_PROCESS_PRIORITY);
+ if(props->status!= ERROR_ON_EXECUTE_PROCESS && props->status!= ERROR_PROCESS_TIMEOUT) {
+ char * output = readHandle(hRead);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " output :\n", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, output, 1);
+
+ props->status = getJavaPropertiesFromOutput(props, output, javaProps);
+ if(props->status == ERROR_OK) {
+ (*javaProps)->javaHome = appendStringW(NULL, location);
+ (*javaProps)->javaExe = appendStringW(NULL, javaExecutable);
+ }
+ FREE(output);
+ } else if(props->status == ERROR_PROCESS_TIMEOUT) {
+ // java verification process finished by time out
+ props->status = ERROR_INPUTOUPUT;
+ }
+ FREE(command);
+ CloseHandle(hWrite);
+ CloseHandle(hRead);
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... not a java hierarchy", 1);
+ props->status = ERROR_INPUTOUPUT;
+ }
+ FREE(libDirectory);
+ FREE(javaExecutable);
+}
+
+
+
+char * getJavaVersionFormatted(const JavaProperties * javaProps) {
+ char *result = NULL;
+ if(javaProps!=NULL) {
+ JavaVersion * version = javaProps->version;
+ if(version!=NULL) {
+ char * majorStr = long2char(version->major);
+ char * minorStr = long2char(version->minor);
+ char * microStr = long2char(version->micro);
+ result = appendString(result, majorStr);
+ result = appendString(result, ".");
+ result = appendString(result, minorStr);
+ result = appendString(result, ".");
+ result = appendString(result, microStr);
+ FREE(majorStr);
+ FREE(minorStr);
+ FREE(microStr);
+
+ if(version->update!=0) {
+ char * updateStr = long2charN(version->update, 2);
+ result = appendString(result, "_");
+ result = appendString(result, updateStr);
+ FREE(updateStr);
+ }
+ if(getLengthA(version->build) > 0) {
+ result = appendString(result, "-");
+ result = appendString(result, version->build);
+ }
+ }
+ }
+ return result;
+}
+
+
+JavaCompatible * newJavaCompatible() {
+ JavaCompatible * props = (JavaCompatible *) LocalAlloc(LPTR, sizeof(JavaCompatible));
+ props->minVersion = NULL;
+ props->maxVersion = NULL;
+ props->vendor = NULL;
+ props->osName = NULL;
+ return props;
+}
+
+void freeJavaProperties(JavaProperties ** props) {
+ if(*props!=NULL) {
+ FREE((*props)->version);
+ FREE((*props)->javaHome);
+ FREE((*props)->javaExe);
+ FREE((*props)->vendor);
+ FREE(*props);
+ }
+}
+
+WCHAR * getJavaResource(WCHAR * location, const WCHAR * suffix) {
+ return appendStringW(appendStringW(NULL, location), suffix);
+}
+
+
+void searchCurrentJavaRegistry(LauncherProperties * props, BOOL access64key) {
+ DWORD i=0;
+ WCHAR ** keys = JAVA_REGISTRY_KEYS;
+ DWORD k=0;
+ WCHAR * buffer = newpWCHAR(MAX_LEN_VALUE_NAME);
+ HKEY rootKeys [2] = {HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER};
+ DWORD rootKeysNumber = sizeof(rootKeys)/sizeof(HKEY);
+ DWORD keysNumber = sizeof(JAVA_REGISTRY_KEYS)/sizeof(WCHAR*);
+ DWORD status = ERROR_OK;
+
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in CurrentVersion values...", 1);
+
+
+ for ( k = 0; k < rootKeysNumber; k++) {
+ for(i=0; i < keysNumber;i++) {
+ if(isTerminated(props)) {
+ return;
+ }
+ else {
+
+ WCHAR * value = getStringValue(rootKeys[k], keys[i], CURRENT_VERSION, access64key);
+ if(value!=NULL) {
+ WCHAR *javaHome = getStringValuePC(rootKeys[k], keys[i], value, JAVA_HOME, access64key);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, (rootKeys[k]==HKEY_LOCAL_MACHINE) ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER", 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, keys[i], 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, CURRENT_VERSION, 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "->", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, value, 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "[", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, JAVA_HOME, 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "] = ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaHome, 1);
+
+ FREE(value);
+ trySetCompatibleJava(javaHome, props);
+ FREE(javaHome);
+ if(props->java!=NULL) {
+ FREE(buffer);
+ return;
+ }
+ }
+ }
+ }
+ }
+
+
+ // we found no CurrentVersion java... just search for other possible keys
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in other values...", 1);
+
+
+ for(k=0;k<rootKeysNumber;k++) {
+ for(i=0;i<keysNumber;i++) {
+ HKEY hkey = 0;
+ DWORD index = 0 ;
+ if (RegOpenKeyExW(rootKeys[k], keys[i], 0, KEY_READ | ((access64key && IsWow64) ? KEY_WOW64_64KEY : 0), &hkey) == ERROR_SUCCESS) {
+ DWORD number = 0;
+ if (RegQueryInfoKeyW(hkey, NULL, NULL, NULL, &number, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
+ DWORD err = 0;
+ do {
+
+ DWORD size = MAX_LEN_VALUE_NAME;
+ buffer[0] = 0;
+ err = RegEnumKeyExW(hkey, index, buffer, &size, NULL, NULL, NULL, NULL);
+ if (err == ERROR_SUCCESS) {
+ WCHAR * javaHome = getJavaHomeValue(keys[i], buffer, access64key);
+ status = ERROR_OK;
+
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, (rootKeys[k]==HKEY_LOCAL_MACHINE) ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER", 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, keys[i], 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, buffer, 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "[", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, JAVA_HOME, 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "] = ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaHome, 1);
+
+ trySetCompatibleJava(javaHome, props);
+ FREE(javaHome);
+ if(props->java!=NULL) {
+ i = keysNumber; // to the end of cycles
+ k = rootKeysNumber;
+ break;
+ }
+
+ }
+ index++;
+ } while (err == ERROR_SUCCESS);
+ }
+ }
+ if (hkey != 0) {
+ RegCloseKey(hkey);
+ }
+ }
+ }
+ FREE(buffer);
+ return;
+}
+
+
+void searchJavaFromEnvVariables(LauncherProperties * props) {
+ static WCHAR * ENVS [] = {
+ L"JAVA_HOME",
+ L"JAVAHOME",
+ L"JAVA_PATH",
+ L"JDK_HOME",
+ L"JDKHOME",
+ L"ANT_JAVA",
+ L"JAVA",
+ L"JDK"
+ };
+
+ WCHAR buffer [MAX_PATH];
+
+ int size = sizeof(ENVS)/sizeof(WCHAR *);
+ int i=0;
+ int ret;
+
+ for(i=0;i<size;i++) {
+ if(isTerminated(props)) return;
+ buffer[0]='\0';
+ ret = GetEnvironmentVariableW((WCHAR *) ENVS[i], (WCHAR *) buffer, MAX_PATH);
+ if (ret > 0 && ret <= MAX_PATH) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " <", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, ENVS[i], 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "> = ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, buffer, 1);
+ trySetCompatibleJava(buffer, props);
+ if(props->java!=NULL) {
+ break;
+ }
+ }
+ }
+}
+
+
+
+
+void unpackJars(LauncherProperties * props, WCHAR * jvmDir, WCHAR * startDir, WCHAR * unpack200exe) {
+ DWORD attrs;
+ DWORD dwError;
+ DWORD count = 0 ;
+
+ if(!isOK(props)) return;
+ attrs = GetFileAttributesW(startDir);
+ if(attrs==INVALID_FILE_ATTRIBUTES) {
+ writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t get attributes of the file : ", startDir, GetLastError());
+ return;
+ }
+ if(attrs & FILE_ATTRIBUTE_DIRECTORY) { // is directory
+ WIN32_FIND_DATAW FindFileData;
+ HANDLE hFind = INVALID_HANDLE_VALUE;
+
+ WCHAR * DirSpec = appendStringW(appendStringW(NULL, startDir), L"\\*" );
+
+ // Find the first file in the directory.
+ hFind = FindFirstFileW(DirSpec, &FindFileData);
+
+ if (hFind == INVALID_HANDLE_VALUE) {
+ writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t file with pattern ", DirSpec, GetLastError());
+ }
+ else {
+ // List all the other files in the directory.
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... listing directory ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, startDir, 1);
+
+ while (FindNextFileW(hFind, &FindFileData) != 0 && isOK(props)) {
+ if(lstrcmpW(FindFileData.cFileName, L".")!=0 &&
+ lstrcmpW(FindFileData.cFileName, L"..")!=0) {
+ WCHAR * child = NULL;
+
+ child = appendStringW(appendStringW(appendStringW(NULL, startDir), FILE_SEP), FindFileData.cFileName);
+ if(isDirectory(child)) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... directory : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, child, 1);
+ unpackJars(props, jvmDir, child, unpack200exe);
+ } else if(searchW(FindFileData.cFileName, JAR_PACK_GZ_SUFFIX)!=NULL) {
+ WCHAR * jarName = appendStringW(appendStringW(
+ appendStringW(NULL, startDir), FILE_SEP),
+ appendStringNW(NULL, 0, FindFileData.cFileName,
+ getLengthW(FindFileData.cFileName) - getLengthW(PACK_GZ_SUFFIX)));
+ WCHAR * unpackCommand = NULL;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... packed jar : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, child, 1);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... jar name : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, jarName, 1);
+
+
+ appendCommandLineArgument(&unpackCommand, unpack200exe);
+ appendCommandLineArgument(&unpackCommand, L"-r"); // remove input file
+ appendCommandLineArgument(&unpackCommand, child);
+ appendCommandLineArgument(&unpackCommand, jarName);
+
+ executeCommand(props, unpackCommand, NULL, UNPACK200_EXTRACTION_TIMEOUT, props->stdoutHandle, props->stderrHandle, NORMAL_PRIORITY_CLASS);
+ FREE(unpackCommand);
+ if(!isOK(props)) {
+ if(props->status==ERROR_PROCESS_TIMEOUT) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... could not unpack file : timeout", 1);
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... an error occured unpacking the file", 1);
+ }
+ props->exitCode = props->status;
+ }
+ FREE(jarName);
+ }
+ FREE(child);
+ }
+ }
+
+ dwError = GetLastError();
+ FindClose(hFind);
+ if (dwError != ERROR_NO_MORE_FILES) {
+ writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t find file with pattern : ", DirSpec, dwError);
+ }
+ }
+ FREE(DirSpec);
+ }
+
+}
+void installJVM(LauncherProperties * props, LauncherResource *jvm) {
+ WCHAR * command = NULL;
+ WCHAR * jvmDir = getParentDirectory(jvm->resolved);
+
+ jvmDir = appendStringW(jvmDir, L"\\_jvm");
+ createDirectory(props, jvmDir);
+ if(!isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... cannot create dir for JVM extraction :", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 1, jvmDir, 1);
+ FREE(jvmDir);
+ return;
+ }
+
+ appendCommandLineArgument(&command, jvm->resolved);
+ appendCommandLineArgument(&command, L"-d");
+ appendCommandLineArgument(&command, jvmDir);
+
+ executeCommand(props, command, jvmDir, JVM_EXTRACTION_TIMEOUT, props->stdoutHandle, props->stderrHandle, NORMAL_PRIORITY_CLASS);
+ FREE(command);
+ if(!isOK(props)) {
+ if(props->status==ERROR_PROCESS_TIMEOUT) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... could not extract JVM : timeout", 1);
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... an error occured during running JVM extraction file", 1);
+ }
+ props->exitCode = props->status;
+ } else {
+ WCHAR * unpack200exe = appendStringW(appendStringW(NULL, jvmDir), UNPACK200_EXE_SUFFIX);
+ if(fileExists(unpack200exe)) {
+ unpackJars(props, jvmDir, jvmDir, unpack200exe);
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... no unpack200 command", 1);
+ props->status = ERROR_BUNDLED_JVM_EXTRACTION;
+ }
+ if(!isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Could not unpack200 the JVM jars", 1);
+ }
+ FREE(unpack200exe);
+ }
+ FREE(jvm->resolved);
+ jvm->resolved = jvmDir;
+}
+
+void installBundledJVMs(LauncherProperties * props) {
+ if ( props->jvms->size > 0 ) {
+ DWORD i=0;
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... search for bundled JVMs", 1);
+ for(i=0;i<props->jvms->size; i++) {
+ if(props->jvms->items[i]->type==0 && !isTerminated(props)) {
+ resolvePath(props, props->jvms->items[i]);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... install bundled JVM ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, props->jvms->items[i]->resolved, 1);
+ installJVM(props, props->jvms->items[i]);
+ if(isTerminated(props)) return;
+ if(isOK(props)) {
+ trySetCompatibleJava(props->jvms->items[i]->resolved, props);
+ if(props->java!=NULL) {
+ break;
+ } else {
+ props->status = ERROR_BUNDLED_JVM_VERIFICATION;
+ return;
+ }
+ }
+ else {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... error occured during JVM extraction", 1);
+ props->status = ERROR_BUNDLED_JVM_EXTRACTION;
+ return;
+ }
+ }
+ }
+ }
+}
+void searchJavaInstallationFolder(LauncherProperties * props) {
+ char executablePath [MAX_PATH];
+ GetModuleFileName(0, executablePath, MAX_PATH);
+ char * pch = strrchr(executablePath, '\\');
+ char installationFolder [MAX_PATH]= "";
+ int i = 0;
+ int end = (int) (pch - executablePath);
+ printf("%i", end);
+ for(i; i < end; i++) {
+ installationFolder[i] = executablePath[i];
+ }
+ strcat(installationFolder, "\\bin\\jre");
+
+ // check if JRE is in installation folder
+ WCHAR * nestedJreFolder = toWCHAR(installationFolder);
+ if (!fileExists(nestedJreFolder)) {
+ // if not exists - return
+ return;
+ }
+
+ // if exists - copy to temp folder to run uninstaller on that jvm
+ // to be able to delete jvm in installation folder
+ WCHAR * tempJreFolder = NULL;
+ tempJreFolder = appendStringW(tempJreFolder, props->testJVMFile->resolved);
+ tempJreFolder = appendStringW(tempJreFolder, L"\\_jvm\\");
+
+ WCHAR * command = NULL;
+ appendCommandLineArgument(&command, L"xcopy");
+ appendCommandLineArgument(&command, nestedJreFolder);
+ appendCommandLineArgument(&command, tempJreFolder);
+ appendCommandLineArgument(&command, L"/e");
+ appendCommandLineArgument(&command, L"/y");
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Copying nested JRE to temp folder", 0);
+
+ executeCommand(props, command, NULL, JVM_EXTRACTION_TIMEOUT, props->stdoutHandle, props->stderrHandle, NORMAL_PRIORITY_CLASS);
+
+ if (fileExists(tempJreFolder)) {
+ trySetCompatibleJava(tempJreFolder, props);
+ }
+}
+void searchJavaSystemLocations(LauncherProperties * props) {
+ if ( props->jvms->size > 0 ) {
+ DWORD i=0;
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search jvm using some predefined locations", 1);
+ for(i=0;i<props->jvms->size && !isTerminated(props);i++) {
+ resolvePath(props, props->jvms->items[i]);
+ if(props->jvms->items[i]->type!=0) { // bundled JVMs are already checked
+ trySetCompatibleJava(props->jvms->items[i]->resolved, props);
+ if(props->java!=NULL) {
+ break;
+ }
+ }
+ }
+ }
+}
+void findSystemJava(LauncherProperties *props) {
+ // install bundled JVMs if any
+ if(isTerminated(props)) return;
+ installBundledJVMs(props);
+
+ if(!isOK(props) || isTerminated(props)) return;
+ // search in <installation folder>/bin/jre
+ if(props->java==NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in installation folder", 1);
+ searchJavaInstallationFolder(props);
+ }
+ // search JVM in the system paths
+ if(props->java==NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in the system paths", 1);
+ searchJavaSystemLocations(props);
+ }
+
+ if(isTerminated(props)) return;
+ if(props->java==NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in environment variables", 1);
+ searchJavaFromEnvVariables(props);
+ }
+
+ // search JVM in the registry
+ if(isTerminated(props)) return;
+ if(props->java==NULL) {
+ if(IsWow64) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in 64-bit registry", 1);
+ searchCurrentJavaRegistry(props, 1);
+ }
+ if(props->java==NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in 32-bit registry", 1);
+ searchCurrentJavaRegistry(props, 0);
+ }
+ }
+}
+
+
+void printJavaProperties(LauncherProperties * props, JavaProperties * javaProps) {
+ if(javaProps!=NULL) {
+ char * jv = getJavaVersionFormatted(javaProps);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Current Java:", 1);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " javaHome: ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->javaHome, 1);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " javaExe: ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->javaExe, 1);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " version: ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, jv, 1);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " vendor: ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->vendor, 1);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " os.name: ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->osName, 1);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " os.arch: ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->osArch, 1);
+ FREE(jv);
+ }
+}
diff --git a/src/main/cpp/launcher/windows/src/JavaUtils.h b/src/main/cpp/launcher/windows/src/JavaUtils.h
new file mode 100644
index 0000000..fa9109d
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/JavaUtils.h
@@ -0,0 +1,64 @@
+/*
+ * 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 _JavaUtils_H
+#define _JavaUtils_H
+
+#include <windows.h>
+#include "Launcher.h"
+#include "Types.h"
+#include "Errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// java.version
+// java.vm.version
+// java.vendor
+// os.name
+// os.arch
+#define TEST_JAVA_PARAMETERS 5
+#define MAX_LEN_VALUE_NAME 16383
+
+WCHAR * getJavaResource(WCHAR * location, const WCHAR * suffix);
+
+void getJavaProperties(WCHAR * location, LauncherProperties * props, JavaProperties ** javaProps);
+
+void findSystemJava(LauncherProperties * props);
+
+JavaVersion * getJavaVersionFromString(char * string, DWORD * result);
+
+char compareJavaVersion(JavaVersion * first, JavaVersion * second);
+
+DWORD isJavaCompatible(JavaProperties *currentJava, JavaCompatible ** compatibleJava, DWORD number);
+
+void printJavaProperties(LauncherProperties * props, JavaProperties * javaProps);
+
+void freeJavaProperties(JavaProperties ** props);
+
+void installJVM(LauncherProperties * props, LauncherResource *jvm);
+
+JavaCompatible * newJavaCompatible();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _JavaUtils_H */
diff --git a/src/main/cpp/launcher/windows/src/Launcher.c b/src/main/cpp/launcher/windows/src/Launcher.c
new file mode 100644
index 0000000..95bdcbd
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/Launcher.c
@@ -0,0 +1,1009 @@
+/*
+ * 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 <windows.h>
+#include <wchar.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <shellapi.h>
+#include "FileUtils.h"
+#include "StringUtils.h"
+#include "JavaUtils.h"
+#include "RegistryUtils.h"
+#include "Launcher.h"
+#include "ProcessUtils.h"
+#include "StringUtils.h"
+#include "ExtractUtils.h"
+#include "Main.h"
+#include "shlobj.h"
+
+const DWORD NUMBER_OF_HELP_ARGUMENTS = 11;
+const DWORD READ_WRITE_BUFSIZE = 65536;
+const WCHAR * outputFileArg = L"--output";
+const WCHAR * javaArg = L"--javahome";
+const WCHAR * debugArg = L"--verbose";
+const WCHAR * tempdirArg = L"--tempdir";
+const WCHAR * classPathPrepend = L"--classpath-prepend";
+const WCHAR * classPathAppend = L"--classpath-append";
+const WCHAR * extractArg = L"--extract";
+const WCHAR * helpArg = L"--help";
+const WCHAR * helpOtherArg = L"/?";
+const WCHAR * silentArg = L"--silent";
+const WCHAR * nospaceCheckArg = L"--nospacecheck";
+const WCHAR * localeArg = L"--locale";
+
+const WCHAR * javaParameterPrefix = L"-J";
+
+const WCHAR * NEW_LINE = L"\n";
+
+const WCHAR * CLASSPATH_SEPARATOR = L";";
+const WCHAR * CLASS_SUFFIX = L".class";
+
+
+DWORD isLauncherArgument(LauncherProperties * props, WCHAR * value) {
+ DWORD i=0;
+ for(i=0;i<props->launcherCommandArguments->size;i++) {
+ if(lstrcmpW(props->launcherCommandArguments->items[i], value)==0) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+DWORD getArgumentIndex(LauncherProperties * props, const WCHAR *arg, DWORD removeArgument) {
+ WCHARList *cmd = props->commandLine;
+ DWORD i=0;
+ for(i=0;i<cmd->size;i++) {
+ if(cmd->items[i]!=NULL) { // argument has not been cleaned yet
+ if(lstrcmpW(arg, cmd->items[i])==0) { //argument is the same as the desired
+ if(removeArgument) FREE(cmd->items[i]); // free it .. we don`t need it anymore
+ return i;
+ }
+ }
+ }
+ return cmd->size;
+}
+
+DWORD argumentExists(LauncherProperties * props, const WCHAR *arg, DWORD removeArgument) {
+ DWORD index = getArgumentIndex(props, arg, removeArgument);
+ return (index < props->commandLine->size);
+
+}
+WCHAR * getArgumentValue(LauncherProperties * props, const WCHAR *arg, DWORD removeArgument, DWORD mandatory) {
+ WCHARList *cmd = props->commandLine;
+ WCHAR * result = NULL;
+ DWORD i = getArgumentIndex(props, arg, removeArgument);
+ if((i+1) < cmd->size) {
+ //we have at least one more argument
+ if(mandatory || !isLauncherArgument(props, cmd->items[i+1])) {
+ result = appendStringW(NULL, cmd->items[i+1]);
+ if(removeArgument) FREE(cmd->items[i+1]);
+ }
+ }
+ return result;
+}
+
+
+void setOutputFile(LauncherProperties * props, WCHAR *path) {
+ HANDLE out = INVALID_HANDLE_VALUE ;
+
+ out = CreateFileW(path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, CREATE_ALWAYS, 0, 0);
+ if(out!=INVALID_HANDLE_VALUE) {
+ SetStdHandle(STD_OUTPUT_HANDLE, out);
+ SetStdHandle(STD_ERROR_HANDLE, out);
+ props->stdoutHandle = out;
+ props->stderrHandle = out;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "[CMD Argument] Redirect output to file : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, path, 1);
+ } else {
+ WCHAR * err = NULL;
+ DWORD code = GetLastError();
+ props->status = ERROR_INPUTOUPUT;
+ writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "[CMD Argument] Can`t create file: ", path, code);
+ err = getErrorDescription(code);
+ showMessageW(props, L"Can`t redirect output to file!\n\nRequested file : %s\n%s", 2, path, err);
+ FREE(err);
+ }
+}
+
+void setOutput(LauncherProperties * props) {
+ WCHAR * file = props->userDefinedOutput;
+ if(file!=NULL) {
+ DWORD exists = fileExists(file);
+ if((exists && !isDirectory(file) )|| !exists) {
+ setOutputFile(props, file);
+ }
+ }
+
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0,
+ (props->outputLevel == OUTPUT_LEVEL_DEBUG) ?
+ "[CMD Argument] Using debug output." :
+ "Using normal output." , 1);
+
+}
+
+
+void loadLocalizationStrings(LauncherProperties *props) {
+
+ // load localized messages
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Loading I18N Strings.", 1);
+ loadI18NStrings(props);
+
+ if(!isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 1, "Error! Can`t load i18n strings!!", 1);
+ showErrorW(props, INTEGRITY_ERROR_PROP, 1, props->exeName);
+ }
+}
+
+void readDefaultRoots(LauncherProperties *props) {
+ TCHAR appDataValueTChar[MAX_PATH];
+ TCHAR localAppDataValueTChar[MAX_PATH];
+ SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, appDataValueTChar);
+ SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, localAppDataValueTChar);
+ WCHAR* appDataValue = toWCHAR(appDataValueTChar);
+ WCHAR* localAppDataValue = toWCHAR(localAppDataValueTChar);
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Reading Default Userdir and Cachedir roots...", 1);
+
+ props->defaultUserDirRoot = appendStringW(appDataValue, toWCHAR("\\NetBeans"));
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "defaultUserDirRoot: ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, props->defaultUserDirRoot, 1);
+
+ props->defaultCacheDirRoot = appendStringW(localAppDataValue, toWCHAR("\\NetBeans\\Cache"));
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "defaultCacheDirRoot: ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, props->defaultCacheDirRoot, 1);
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "End of Reading Default Roots.", 1);
+}
+
+void createTMPDir(LauncherProperties * props) {
+ WCHAR * argTempDir = NULL;
+ DWORD createRndSubDir = 1;
+
+ if((argTempDir = props->userDefinedExtractDir) !=NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "[CMD Argument] Extract data to directory: ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 1, argTempDir, 1);
+ createRndSubDir = 0;
+ } else if((argTempDir = props->userDefinedTempDir) !=NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "[CMD Argument] Using tmp directory: ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, argTempDir, 1);
+ }
+
+ createTempDirectory(props, argTempDir, createRndSubDir);
+ if(!isOK(props)) {
+ showErrorW(props, CANT_CREATE_TEMP_DIR_PROP, 1, props->tmpDir);
+ }
+}
+
+void checkExtractionStatus(LauncherProperties *props) {
+ if(props->status == ERROR_FREESPACE) {
+ DWORD hiMB = props->bundledSize->High;
+ DWORD lowMB = props->bundledSize->Low;
+ DWORD hiMult = (hiMB!=0) ? ((MAXDWORD / 1024) + 1) / 1024 : 0;
+ DWORD dw = hiMult * hiMB + lowMB / (1024 * 1024) + 1;
+ WCHAR * size = DWORDtoWCHAR(dw);
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Not enought free space !", 1);
+ showErrorW(props, NOT_ENOUGH_FREE_SPACE_PROP, 2, size, tempdirArg);
+ FREE(size);
+ }
+ else if(props->status == ERROR_INTEGRITY) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t extract data from bundle. Seems to be integrirty error!", 1);
+ showErrorW(props, INTEGRITY_ERROR_PROP, 1, props->exeName);
+ }
+}
+
+
+void trySetCompatibleJava(WCHAR * location, LauncherProperties * props) {
+ if(isTerminated(props)) return;
+ if(location!=NULL) {
+ JavaProperties * javaProps = NULL;
+
+ if(inList(props->alreadyCheckedJava, location)) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... already checked location ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, location, 1);
+ // return here and don`t proceed with private jre checking since it`s already checked as well
+ return;
+ } else {
+ props->alreadyCheckedJava = addStringToList(props->alreadyCheckedJava, location);
+ }
+
+ getJavaProperties(location, props, &javaProps);
+
+ if(isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... some java at ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, location, 1);
+ // some java there, check compatibility
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... checking compatibility of java : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->javaHome, 1);
+ if(isJavaCompatible(javaProps, props->compatibleJava, props->compatibleJavaNumber)) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... compatible", 1);
+ props->java = javaProps;
+ } else {
+ props->status = ERROR_JVM_UNCOMPATIBLE;
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... uncompatible", 1);
+ freeJavaProperties(&javaProps);
+ }
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... no java at ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, location, 1);
+ if (props->status==ERROR_INPUTOUPUT) {
+ props->status = ERROR_JVM_NOT_FOUND;
+ }
+ }
+
+ if(props->status == ERROR_JVM_NOT_FOUND) { // check private JRE
+ //DWORD privateJreStatus = props->status;
+ WCHAR * privateJre = appendStringW(NULL, location);
+ privateJre = appendStringW(privateJre, L"\\jre");
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... check private jre at ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, privateJre, 1);
+
+ if(inList(props->alreadyCheckedJava, privateJre)) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... already checked location ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, privateJre, 1);
+ } else {
+ props->alreadyCheckedJava = addStringToList(props->alreadyCheckedJava, privateJre);
+
+ getJavaProperties(privateJre, props, &javaProps);
+ if(isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... checking compatibility of private jre : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->javaHome, 1);
+ if(isJavaCompatible(javaProps, props->compatibleJava, props->compatibleJavaNumber)) {
+ props->java = javaProps;
+ props->status = ERROR_OK;
+ } else {
+ freeJavaProperties(&javaProps);
+ props->status = ERROR_JVM_UNCOMPATIBLE;
+ }
+ } else if (props->status==ERROR_INPUTOUPUT) {
+ props->status = ERROR_JVM_NOT_FOUND;
+ }
+ }
+ FREE(privateJre);
+ }
+ } else {
+ props->status = ERROR_JVM_NOT_FOUND;
+ }
+}
+
+void resolveTestJVM(LauncherProperties * props) {
+ WCHAR * testJVMFile = NULL;
+ WCHAR * testJVMClassPath = NULL;
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Resolving testJVM classpath...", 1);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... first step : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, props->testJVMFile->path, 1);
+ resolvePath(props, props->testJVMFile);
+ testJVMFile = props->testJVMFile->resolved;
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... second : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, props->testJVMFile->resolved, 1);
+
+
+ if(isDirectory(testJVMFile)) { // the directory of the class file is set
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... testJVM is : directory ", 1);
+ testJVMClassPath = appendStringW(NULL, testJVMFile);
+ } else { // testJVMFile is either .class file or .jar/.zip file with the neccessary class file
+ WCHAR * dir = getParentDirectory(testJVMFile);
+ WCHAR * ptr = testJVMFile;
+ do {
+ ptr = searchW(ptr, CLASS_SUFFIX); // check if ptr contains .class
+ if(ptr==NULL) { // .jar or .zip file
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... testJVM is : ZIP/JAR file", 1);
+ testJVMClassPath = appendStringW(NULL, testJVMFile);
+ break;
+ }
+ ptr += getLengthW(CLASS_SUFFIX); // shift to the right after the ".class"
+
+ if(ptr==NULL || getLengthW(ptr)==0) { // .class was at the end of the ptr
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... testJVM is : .class file ", 1);
+ testJVMClassPath = appendStringW(NULL, dir);
+ break;
+ }
+ } while(1);
+ FREE(dir);
+ }
+
+ FREE(props->testJVMFile->resolved);
+ props->testJVMFile->resolved = testJVMClassPath;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... resolved : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, props->testJVMFile->resolved, 1);
+}
+
+void findSuitableJava(LauncherProperties * props) {
+ if(!isOK(props)) return;
+
+ //resolve testJVM file
+ resolveTestJVM(props);
+
+ if(!fileExists(props->testJVMFile->resolved)) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 1, "Can`t find TestJVM classpath : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 1, props->testJVMFile->resolved, 1);
+ showErrorW(props, JVM_NOT_FOUND_PROP, 1, javaArg);
+ props->status = ERROR_JVM_NOT_FOUND;
+ return;
+ } else if(!isTerminated(props)) {
+
+ // try to get java location from command line arguments
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "", 1);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Finding JAVA...", 1);
+
+ //WCHAR * java = NULL;
+
+ if(props->userDefinedJavaHome!=NULL) { // using user-defined JVM via command-line parameter
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "[CMD Argument] Try to use java from ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, props->userDefinedJavaHome, 1);
+
+ trySetCompatibleJava(props->userDefinedJavaHome, props);
+ if( props->status == ERROR_JVM_NOT_FOUND || props->status == ERROR_JVM_UNCOMPATIBLE) {
+ const char * prop = (props->status == ERROR_JVM_NOT_FOUND) ?
+ JVM_USER_DEFINED_ERROR_PROP :
+ JVM_UNSUPPORTED_VERSION_PROP;
+ showErrorW(props, prop, 1, props->userDefinedJavaHome);
+ }
+ } else { // no user-specified java argument
+ findSystemJava(props);
+ if( props->java ==NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... no java was found", 1);
+ if(props->status == ERROR_BUNDLED_JVM_EXTRACTION) {
+ showErrorW(props, BUNDLED_JVM_EXTRACT_ERROR_PROP, 1, javaArg);
+ } else if(props->status == ERROR_BUNDLED_JVM_VERIFICATION) {
+ showErrorW(props, BUNDLED_JVM_VERIFY_ERROR_PROP, 1, javaArg);
+ } else {
+ showErrorW(props, JVM_NOT_FOUND_PROP, 1, javaArg);
+ props->status = ERROR_JVM_NOT_FOUND;
+ }
+ }
+ }
+
+ if(props->java!=NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 1, "Compatible jvm was found on the system", 1);
+ printJavaProperties(props, props->java);
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 1, "No compatible jvm was found on the system", 1);
+ }
+ }
+ return;
+}
+
+
+
+void resolveLauncherStringProperty(LauncherProperties * props, WCHAR ** result) {
+ if(*result!=NULL) {
+ WCHAR * propStart = searchW(*result, L"$P{");
+ if(propStart!=NULL) {
+ WCHAR * propEnd = searchW(propStart + 3, L"}");
+ if(propEnd!=NULL) {
+ WCHAR * propName;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... resolving string property", 1);
+ propName = appendStringNW(NULL, 0, propStart + 3 ,
+ getLengthW(propStart + 3) - getLengthW(propEnd));
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... property name is : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, propName, 1);
+
+ if(propName!=NULL) {
+ char * name = toChar(propName);
+ const WCHAR * propValue = getI18nProperty(props, name);
+ if(propValue!=NULL) {
+ WCHAR * tmp = appendStringNW(NULL, 0, *result, getLengthW(*result) - getLengthW(propStart));
+ tmp = appendStringW(tmp, propValue);
+ tmp = appendStringW(tmp, propEnd + 1);
+ FREE(*result);
+ *result = tmp;
+ }
+ FREE(name);
+ FREE(propName);
+ }
+ }
+ }
+ }
+}
+
+void resolveLauncherProperties(LauncherProperties * props, WCHAR **result) {
+ if(*result != NULL) {
+ WCHAR * propStart = searchW(*result, L"$L{");
+ if(propStart!=NULL) {
+ WCHAR * propEnd = searchW(propStart + 3, L"}");
+ if(propEnd!=NULL) {
+ WCHAR * propName = appendStringNW(NULL, 0, propStart + 3 , getLengthW(propStart + 3) - getLengthW(propEnd));
+ if(propName!=NULL) {
+ WCHAR * propValue = NULL;
+
+ if(lstrcmpW(propName, L"nbi.launcher.tmp.dir")==0) {
+ propValue = appendStringW(NULL, props->tmpDir); // launcher tmpdir
+ } else if(lstrcmpW(propName, L"nbi.launcher.java.home")==0) {
+ if(props->java!=NULL) {
+ propValue = appendStringW(NULL, props->java->javaHome); // relative to javahome
+ }
+ } else if(lstrcmpW(propName, L"nbi.launcher.user.home")==0) {
+ propValue = getCurrentUserHome();
+ } else if(lstrcmpW(propName, L"nbi.launcher.parent.dir")==0) {
+ propValue = appendStringW(NULL, props->exeDir); // launcher parent
+ }
+
+
+ if(propValue!=NULL) {
+ WCHAR * tmp = appendStringNW(NULL, 0, *result, getLengthW(*result) - getLengthW(propStart));
+ tmp = appendStringW(tmp, propValue);
+ tmp = appendStringW(tmp, propEnd + 1);
+ FREE(*result);
+ FREE(propValue);
+ *result = tmp;
+ }
+ }
+ }
+ }
+ }
+
+}
+
+void resolveString(LauncherProperties * props, WCHAR ** result) {
+ WCHAR * tmp = NULL;
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Resolving string : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, *result, 1);
+ do {
+ FREE(tmp);
+ tmp = appendStringW(NULL, *result);
+ //writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... step 1 : ", 0);
+ //writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, *result, 1);
+ resolveLauncherProperties(props, result);
+ //writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... step 2 : ", 0);
+ //writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, *result, 1);
+ resolveLauncherStringProperty(props, result);
+ //writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... step 3 : ", 0);
+ //writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, *result, 1);
+ } while(lstrcmpW(tmp, *result)!=0);
+
+ FREE(tmp);
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, ".... resolved : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, *result, 1);
+}
+
+void resolvePath(LauncherProperties * props, LauncherResource * file) {
+ WCHAR * result = NULL;
+ DWORD i=0;
+
+ if(file==NULL) return;
+ if(file->resolved!=NULL) return;
+
+ file->resolved = appendStringW(NULL, file->path);
+ resolveString(props, & (file->resolved));
+
+ for(i=0;i<getLengthW(file->resolved);i++) {
+ if(file->resolved[i]==L'/') {
+ file->resolved[i]=L'\\';
+ }
+ }
+}
+
+void setClasspathElements(LauncherProperties * props) {
+ if(isOK(props)) {
+ WCHAR * preCP = NULL;
+ WCHAR * appCP = NULL;
+ WCHAR *tmp = NULL;
+ DWORD i = 0 ;
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Modifying classpath ...", 1);
+ // add some libraries to the beginning of the classpath
+ while((preCP = getArgumentValue(props, classPathPrepend, 1, 1))!=NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... adding entry to the beginning of classpath : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, preCP, 1);
+ if (props->classpath != NULL) {
+ preCP = appendStringW(preCP, CLASSPATH_SEPARATOR);
+ }
+ //WCHAR *last = props->classpath;
+ resolveString(props, &preCP);
+ tmp = appendStringW(preCP, props->classpath);
+ FREE(props->classpath);
+ props->classpath = tmp;
+ }
+
+
+ for(i=0;i<props->jars->size;i++) {
+ WCHAR * resolvedCpEntry = NULL;
+ resolvePath(props, props->jars->items[i]);
+ resolvedCpEntry = props->jars->items[i]->resolved;
+ if(!fileExists(resolvedCpEntry)) {
+ props->status = EXTERNAL_RESOURCE_MISSING;
+ showErrorW(props, EXTERNAL_RESOURE_LACK_PROP, 1, resolvedCpEntry);
+ return;
+ }
+ if (props->classpath != NULL) {
+ props->classpath = appendStringW(props->classpath, CLASSPATH_SEPARATOR);
+ }
+ props->classpath = appendStringW(props->classpath, resolvedCpEntry);
+ }
+
+ // add some libraries to the end of the classpath
+ while((appCP = getArgumentValue(props, classPathAppend, 1, 1))!=NULL) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... adding entry to the end of classpath : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, appCP, 1);
+ if (props->classpath != NULL) {
+ props->classpath = appendStringW(props->classpath, CLASSPATH_SEPARATOR);
+ }
+ resolveString(props, &appCP);
+ props->classpath = appendStringW(props->classpath, appCP);
+ FREE(appCP);
+ }
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... finished", 1);
+ }
+}
+
+void setAdditionalArguments(LauncherProperties * props) {
+ if(isOK(props)) {
+ WCHARList * cmd = props->commandLine;
+ WCHAR ** javaArgs;
+ WCHAR ** appArgs;
+ DWORD i=0;
+ DWORD jArg = 0; // java arguments number
+ DWORD aArg = 0; // app arguments number
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0,
+ "Parsing rest of command line arguments to add them to java or application parameters... ", 1);
+
+ // get number for array creation
+ for(i=0;i<cmd->size;i++) {
+ if(cmd->items[i]!=NULL) {
+ if(searchW(cmd->items[i], javaParameterPrefix)!=NULL) {
+ jArg++;
+ } else {
+ aArg++;
+ }
+ }
+ }
+
+ // handle DefaultUserDirRoot, DefaultCacheDirRoot - increasing array size
+ jArg = jArg + 2;
+
+ //fill the array
+ if(jArg>0) {
+ int size = jArg + props->jvmArguments->size;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, DWORDtoCHAR(size), 1);
+ javaArgs = newppWCHAR(jArg + props->jvmArguments->size);
+ for (i=0;i<props->jvmArguments->size;i++) {
+ javaArgs[i] = props->jvmArguments->items[i];
+ }
+ FREE(props->jvmArguments->items);
+
+ // cont. handle DefaultUserDirRoot, DefaultCacheDirRoot
+ // * add -Dnetbeans.default_userdir_root
+ // * add -Dnetbeans.default_cachedir_root
+ javaArgs[i-2] = appendStringW(toWCHAR("-Dnetbeans.default_userdir_root="), props->defaultUserDirRoot);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Added an JVM argument: ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, javaArgs[i-2], 1);
+
+ javaArgs[i-1] = appendStringW(toWCHAR("-Dnetbeans.default_cachedir_root="), props->defaultCacheDirRoot);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Added an JVM argument: ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, javaArgs[i-1], 1);
+ } else {
+ javaArgs = NULL;
+ }
+
+ if(aArg>0) {
+ appArgs = newppWCHAR(aArg + props->appArguments->size);
+ for (i=0; i < props->appArguments->size; i++) {
+ appArgs [i]= props->appArguments->items[i];
+ }
+ FREE(props->appArguments->items);
+ } else {
+ appArgs = NULL;
+ }
+ jArg = aArg = 0;
+
+ for(i=0;i<cmd->size;i++) {
+ if(cmd->items[i]!=NULL) {
+ if(searchW(cmd->items[i], javaParameterPrefix)!=NULL) {
+ javaArgs [ props->jvmArguments->size + jArg] = appendStringW(NULL, cmd->items[i] + getLengthW(javaParameterPrefix));
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... adding JVM argument : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, javaArgs [ props->jvmArguments->size + jArg], 1);
+ jArg ++ ;
+ } else {
+ appArgs [ props->appArguments->size + aArg] = appendStringW(NULL, cmd->items[i]);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... adding APP argument : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, appArgs [ props->appArguments->size + aArg], 1);
+ aArg++;
+ }
+ FREE(cmd->items[i]);
+ }
+ }
+ props->appArguments->size = props->appArguments->size + aArg;
+ props->jvmArguments->size = props->jvmArguments->size + jArg;
+ if(props->jvmArguments->items==NULL) props->jvmArguments->items = javaArgs;
+ if(props->appArguments->items==NULL) props->appArguments->items = appArgs;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... resolving jvm arguments", 1);
+ for(i=0;i<props->jvmArguments->size;i++) {
+ resolveString(props, &props->jvmArguments->items[i]);
+ }
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... resolving app arguments", 1);
+ for(i=0;i<props->appArguments->size;i++) {
+ resolveString(props, &props->appArguments->items[i]);
+ }
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... finished parsing parameters", 1);
+ }
+}
+void appendCommandLineArgument( WCHAR ** command, const WCHAR * arg) {
+ WCHAR * escapedString = escapeString(arg);
+ *command = appendStringW(*command, escapedString);
+ FREE(escapedString);
+ *command = appendStringW(*command, L" ");
+}
+
+void setLauncherCommand(LauncherProperties *props) {
+ if(!isOK(props)) return;
+
+ if(props->java==NULL) {
+ props->status = ERROR_JVM_NOT_FOUND;
+ return;
+ } else {
+ WCHAR * command = NULL;
+ WCHAR * javaIOTmpdir = NULL;
+ DWORD i = 0;
+
+ appendCommandLineArgument(&command, props->java->javaExe);
+ command = appendStringW(command, L"-Djava.io.tmpdir=");
+ javaIOTmpdir = getParentDirectory(props->tmpDir);
+ appendCommandLineArgument(&command, javaIOTmpdir);
+ FREE(javaIOTmpdir);
+
+
+ for(i=0;i<props->jvmArguments->size;i++) {
+ appendCommandLineArgument(&command, props->jvmArguments->items[i]);
+ }
+
+ appendCommandLineArgument(&command, L"-classpath");
+ appendCommandLineArgument(&command, props->classpath);
+ appendCommandLineArgument(&command, props->mainClass);
+
+ for(i=0;i<props->appArguments->size; i++) {
+ appendCommandLineArgument(&command, props->appArguments->items[i]);
+ }
+ props->command = command;
+ }
+}
+
+void executeMainClass(LauncherProperties * props) {
+ if(isOK(props) && !isTerminated(props)) {
+ int64t * minSize = newint64_t(0, 0);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Executing main class", 1);
+ checkFreeSpace(props, props->tmpDir, minSize);
+ if(isOK(props)) {
+ HANDLE hErrorRead;
+ HANDLE hErrorWrite;
+ char * error = NULL;
+
+ CreatePipe(&hErrorRead, &hErrorWrite, NULL, 0);
+ hideLauncherWindows(props);
+ executeCommand(props, props->command, NULL, INFINITE, props->stdoutHandle, hErrorWrite, NORMAL_PRIORITY_CLASS);
+ if(!isOK(props)) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... an error occured during JVM running main class", 1);
+ props->exitCode = props->status;
+ } else {
+ char * s = DWORDtoCHAR(props->exitCode);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... main class has finished its work. Exit code is ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, s, 1);
+ FREE(s);
+ }
+
+ error = readHandle(hErrorRead);
+ if(getLengthA(error)>1) {
+ DWORD showMessage = 0;
+ char * ptr = error;
+ while(ptr!=NULL) {
+ //Bug #105165 and #194242
+ if((searchA(ptr, "Picked up ") == NULL && searchA(ptr, "fatal: Not a git repository") == NULL) && getLengthA(ptr) > 1) {
+ showMessage = 1;
+ break;
+ }
+ ptr = searchA(ptr, "\n");
+ if(ptr!=NULL) ptr++;
+ }
+
+ if(showMessage && props->exitCode != 0) {
+ WCHAR * errorW = toWCHAR(error);
+ showMessageW(props, getI18nProperty(props, JAVA_PROCESS_ERROR_PROP), 1, errorW);
+ FREE(errorW);
+ } else {
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 1, error, 1);
+ }
+ }
+ CloseHandle(hErrorWrite);
+ CloseHandle(hErrorRead);
+ FREE(error);
+ Sleep(1);
+ } else {
+ props->status = ERROR_FREESPACE;
+ props->exitCode = props->status;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... there is not enough space in tmp dir to execute main jar", 1);
+ }
+ FREE(minSize);
+ }
+}
+
+DWORD isOnlyHelp(LauncherProperties * props) {
+ if(argumentExists(props, helpArg, 1) || argumentExists(props, helpOtherArg, 1)) {
+
+ WCHARList * help = newWCHARList(NUMBER_OF_HELP_ARGUMENTS);
+ DWORD counter = 0;
+ WCHAR * helpString = NULL;
+
+ help->items[counter++] = formatMessageW(getI18nProperty(props, ARG_JAVA_PROP), 1, javaArg);
+ help->items[counter++] = formatMessageW(getI18nProperty(props, ARG_TMP_PROP), 1, tempdirArg);
+ help->items[counter++] = formatMessageW(getI18nProperty(props, ARG_EXTRACT_PROP), 1, extractArg);
+ help->items[counter++] = formatMessageW(getI18nProperty(props, ARG_OUTPUT_PROPERTY), 1, outputFileArg);
+ help->items[counter++] = formatMessageW(getI18nProperty(props, ARG_DEBUG_PROP), 1, debugArg);
+ help->items[counter++] = formatMessageW(getI18nProperty(props, ARG_CPA_PROP), 1, classPathAppend);
+ help->items[counter++] = formatMessageW(getI18nProperty(props, ARG_CPP_PROP), 1, classPathPrepend);
+ help->items[counter++] = formatMessageW(getI18nProperty(props, ARG_DISABLE_SPACE_CHECK), 1, nospaceCheckArg);
+ help->items[counter++] = formatMessageW(getI18nProperty(props, ARG_LOCALE_PROP), 1, localeArg);
+ help->items[counter++] = formatMessageW(getI18nProperty(props, ARG_SILENT_PROP), 1, silentArg);
+ help->items[counter++] = formatMessageW(getI18nProperty(props, ARG_HELP_PROP), 1, helpArg);
+
+
+ for(counter=0;counter<NUMBER_OF_HELP_ARGUMENTS;counter++) {
+ helpString = appendStringW(appendStringW(helpString, help->items[counter]), NEW_LINE);
+ }
+ freeWCHARList(&help);
+ showMessageW(props, helpString, 0);
+ FREE(helpString);
+ return 1;
+ }
+ return 0;
+}
+
+DWORD isSilent(LauncherProperties * props) {
+ return props->silentMode;
+}
+
+WCHARList * getCommandlineArguments() {
+ int argumentsNumber = 0;
+ int i=0;
+ WCHAR ** commandLine = CommandLineToArgvW(GetCommandLineW(), &argumentsNumber);
+ // the first is always the running program.. we don`t need it
+ // it is that same as GetModuleFileNameW says
+ WCHARList * commandsList = newWCHARList((DWORD) (argumentsNumber - 1) );
+ for(i=0;i<argumentsNumber - 1;i++) {
+ commandsList->items[i] = appendStringW(NULL, commandLine[i + 1]);
+ }
+
+ LocalFree(commandLine);
+ return commandsList;
+}
+
+
+LauncherProperties * createLauncherProperties() {
+ LauncherProperties *props = (LauncherProperties*)LocalAlloc(LPTR, sizeof(LauncherProperties));
+ DWORD c = 0;
+ props->launcherCommandArguments = newWCHARList(11);
+ props->launcherCommandArguments->items[c++] = appendStringW(NULL, outputFileArg);
+ props->launcherCommandArguments->items[c++] = appendStringW(NULL, javaArg);
+ props->launcherCommandArguments->items[c++] = appendStringW(NULL, debugArg);
+ props->launcherCommandArguments->items[c++] = appendStringW(NULL, tempdirArg);
+ props->launcherCommandArguments->items[c++] = appendStringW(NULL, classPathPrepend);
+ props->launcherCommandArguments->items[c++] = appendStringW(NULL, classPathAppend);
+ props->launcherCommandArguments->items[c++] = appendStringW(NULL, extractArg);
+ props->launcherCommandArguments->items[c++] = appendStringW(NULL, helpArg);
+ props->launcherCommandArguments->items[c++] = appendStringW(NULL, helpOtherArg);
+ props->launcherCommandArguments->items[c++] = appendStringW(NULL, silentArg);
+ props->launcherCommandArguments->items[c++] = appendStringW(NULL, nospaceCheckArg);
+
+ props->jvmArguments = NULL;
+ props->appArguments = NULL;
+ props->extractOnly = 0;
+ props->mainClass = NULL;
+ props->testJVMClass = NULL;
+ props->classpath = NULL;
+ props->jars = NULL;
+ props->testJVMFile = NULL;
+ props->tmpDir = NULL;
+ props->tmpDirCreated = 0;
+ props->compatibleJava=NULL;
+ props->compatibleJavaNumber=0;
+ props->java = NULL;
+ props->command = NULL;
+ props->jvms = NULL;
+ props->other = NULL;
+ props->alreadyCheckedJava = NULL;
+ props->exePath = getExePath();
+ props->exeName = getExeName();
+ props->exeDir = getExeDirectory();
+ props->handler = CreateFileW(props->exePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ props->bundledSize = newint64_t(0, 0);
+ props->bundledNumber = 0;
+ props->commandLine = getCommandlineArguments();
+ props->status = ERROR_OK;
+ props->exitCode = 0;
+ props->outputLevel = argumentExists(props, debugArg, 1) ? OUTPUT_LEVEL_DEBUG : OUTPUT_LEVEL_NORMAL;
+ props->stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
+ props->stderrHandle = GetStdHandle(STD_ERROR_HANDLE);
+ props->bufsize = READ_WRITE_BUFSIZE;
+ props->restOfBytes = createSizedString();
+ props->I18N_PROPERTIES_NUMBER = 0;
+ props->i18nMessages = NULL;
+ props->userDefinedJavaHome = getArgumentValue(props, javaArg, 1, 1);
+ props->userDefinedTempDir = getArgumentValue(props, tempdirArg, 1, 1);
+ props->userDefinedLocale = getArgumentValue(props, localeArg, 0, 1);
+ props->userDefinedExtractDir = NULL;
+ props->extractOnly = 0;
+
+ if(argumentExists(props, extractArg, 0)) {
+ props->userDefinedExtractDir = getArgumentValue(props, extractArg, 1, 0);
+ if(props->userDefinedExtractDir==NULL) {// next argument is null or another launcher argument
+ props->userDefinedExtractDir = getCurrentDirectory();
+ }
+ props->extractOnly = 1;
+ }
+ props->userDefinedOutput = getArgumentValue(props, outputFileArg, 1, 1);
+ props->checkForFreeSpace = !argumentExists(props, nospaceCheckArg, 0);
+ props->silentMode = argumentExists(props, silentArg, 0);
+ props->launcherSize = getFileSize(props->exePath);
+ props->isOnlyStub = (compare(props->launcherSize, STUB_FILL_SIZE) < 0);
+ return props;
+}
+void freeLauncherResourceList(LauncherResourceList ** list) {
+ if(*list!=NULL) {
+ if((*list)->items!=NULL) {
+ DWORD i=0;
+ for(i=0;i<(*list)->size;i++) {
+ freeLauncherResource(&((*list)->items[i]));
+ }
+ FREE((*list)->items);
+ }
+ FREE((*list));
+ }
+}
+
+
+void freeLauncherProperties(LauncherProperties **props) {
+ if((*props)!=NULL) {
+ DWORD i=0;
+ writeMessageA(*props, OUTPUT_LEVEL_DEBUG, 0, "Closing launcher properties", 1);
+ freeWCHARList(& ( (*props)->appArguments));
+ freeWCHARList(& ( (*props)->jvmArguments));
+
+ FREE((*props)->mainClass);
+ FREE((*props)->testJVMClass);
+ FREE((*props)->classpath);
+ freeLauncherResourceList(&((*props)->jars));
+
+ freeLauncherResourceList(&((*props)->jvms));
+
+ freeLauncherResourceList(&((*props)->other));
+
+ freeLauncherResource(&((*props)->testJVMFile));
+
+ FREE((*props)->tmpDir);
+ for(i=0;i<(*props)->compatibleJavaNumber;i++) {
+ JavaCompatible * jc = (*props)->compatibleJava[i];
+ if(jc!=NULL) {
+ FREE(jc->minVersion);
+ FREE(jc->maxVersion);
+ FREE(jc->vendor);
+ FREE(jc->osName);
+ FREE(jc->osArch);
+ FREE((*props)->compatibleJava[i]);
+ }
+ }
+ freeStringList(&((*props)->alreadyCheckedJava));
+ FREE((*props)->compatibleJava);
+ freeJavaProperties(&((*props)->java));
+ FREE((*props)->userDefinedJavaHome);
+ FREE((*props)->userDefinedTempDir);
+ FREE((*props)->userDefinedExtractDir);
+ FREE((*props)->userDefinedOutput);
+ FREE((*props)->userDefinedLocale);
+ FREE((*props)->command);
+ FREE((*props)->exePath);
+ FREE((*props)->exeDir);
+ FREE((*props)->exeName);
+ FREE((*props)->bundledSize);
+ FREE((*props)->launcherSize);
+ freeSizedString(&((*props)->restOfBytes));
+
+ flushHandle((*props)->stdoutHandle);
+ flushHandle((*props)->stderrHandle);
+ CloseHandle((*props)->stdoutHandle);
+ CloseHandle((*props)->stderrHandle);
+
+ freeI18NMessages((*props));
+ freeWCHARList(& ((*props)->launcherCommandArguments));
+ freeWCHARList(& ((*props)->commandLine));
+ CloseHandle((*props)->handler);
+
+ FREE((*props));
+ }
+ return;
+}
+void printStatus(LauncherProperties * props) {
+ char * s = DWORDtoCHAR(props->status);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... EXIT status : ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, s, 1);
+ FREE(s);
+ s = DWORDtoCHAR(props->exitCode);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... EXIT code : ", 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, s, 1);
+ FREE(s);
+}
+
+void processLauncher(LauncherProperties * props) {
+ setOutput(props);
+ if(!isOK(props) || isTerminated(props)) return;
+
+ setProgressRange(props, props->launcherSize);
+ if(!isOK(props) || isTerminated(props)) return;
+
+ skipStub(props);
+ if(!isOK(props) || isTerminated(props)) return;
+
+ readDefaultRoots(props);
+ if(!isOK(props) || isTerminated(props)) return;
+
+ loadLocalizationStrings(props);
+ if(!isOK(props) || isTerminated(props)) return;
+
+ if(isOnlyHelp(props)) return;
+
+ setProgressTitleString(props, getI18nProperty(props, MSG_PROGRESS_TITLE));
+ setMainWindowTitle(props, getI18nProperty(props, MAIN_WINDOW_TITLE));
+ showLauncherWindows(props);
+ if(!isOK(props) || isTerminated(props)) return;
+
+ readLauncherProperties(props);
+ checkExtractionStatus(props);
+ if(!isOK(props) || isTerminated(props)) return;
+
+ if(props->bundledNumber > 0) {
+ createTMPDir(props);
+ if(isOK(props)) {
+ checkFreeSpace(props, props->tmpDir, props->bundledSize);
+ checkExtractionStatus(props);
+ }
+ }
+
+ if (isOK(props) ){
+ extractJVMData(props);
+ checkExtractionStatus(props);
+ if (isOK(props) && !props->extractOnly && !isTerminated(props)) {
+ findSuitableJava(props);
+ }
+
+ if (isOK(props) && !isTerminated(props)) {
+ extractData(props);
+ checkExtractionStatus(props);
+ if (isOK(props) && (props->java!=NULL) && !isTerminated(props)) {
+ setClasspathElements(props);
+ if(isOK(props) && (props->java!=NULL) && !isTerminated(props)) {
+ setAdditionalArguments(props);
+ setLauncherCommand(props);
+ Sleep(500);
+ executeMainClass(props);
+ }
+ }
+ }
+ }
+
+ if(!props->extractOnly && props->tmpDirCreated) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... deleting temporary directory ", 1);
+ deleteDirectory(props, props->tmpDir);
+ }
+
+}
diff --git a/src/main/cpp/launcher/windows/src/Launcher.h b/src/main/cpp/launcher/windows/src/Launcher.h
new file mode 100644
index 0000000..d062795
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/Launcher.h
@@ -0,0 +1,53 @@
+/*
+ * 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 _Launcher_H
+#define _Launcher_H
+
+#include <windows.h>
+#include "Errors.h"
+#include "JavaUtils.h"
+#include "Types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ extern const WCHAR * NEW_LINE;
+
+ LauncherProperties * createLauncherProperties();
+ void freeLauncherProperties(LauncherProperties ** props);
+
+ void printStatus(LauncherProperties * props);
+ void trySetCompatibleJava(WCHAR * location, LauncherProperties * props);
+ DWORD isSilent(LauncherProperties * props);
+ DWORD isLauncherArgument(LauncherProperties * props, WCHAR * value);
+ void processLauncher(LauncherProperties * props);
+
+ void resolvePath(LauncherProperties * props, LauncherResource * file);
+ void resolveString(LauncherProperties * props, WCHAR ** result);
+ void resolveLauncherProperties(LauncherProperties * props, WCHAR **result);
+ void appendCommandLineArgument( WCHAR ** command, const WCHAR * arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _Launcher_H */
diff --git a/src/main/cpp/launcher/windows/src/Main.c b/src/main/cpp/launcher/windows/src/Main.c
new file mode 100644
index 0000000..5a819ee
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/Main.c
@@ -0,0 +1,672 @@
+/*
+ * 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 <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <commctrl.h>
+#include "Launcher.h"
+#include "FileUtils.h"
+#include "StringUtils.h"
+#include "SystemUtils.h"
+#include "ExtractUtils.h"
+#include "Main.h"
+
+#define HAVE_WCHAR_H 1
+
+char mainClassName[80] = "Main NBI Window Class";
+char mainTitle [80] = "NBI Launcher";
+char showMessageTitle [] = "\n<ShowMessage>\n";
+HWND hwndPB = NULL;
+HWND hwndMain = NULL;
+HWND hwndErrorDetail = NULL;
+HWND hwndErrorTitle = NULL;
+HWND hwndButton = NULL;
+HWND hwndProgressTitle = NULL;
+
+HINSTANCE globalInstance = NULL;
+int64t * totalProgressSize = NULL;
+int64t * currentProgressSize = NULL;
+long steps = 1000;
+long lastCheckedStep = 0;
+int iCmdShowGlobal = 0;
+
+HANDLE initializationSuccess = NULL;
+HANDLE initializationFailed = NULL;
+HANDLE closingWindowsRequired = NULL;
+HANDLE closingWindowsConfirmed = NULL;
+HANDLE buttonPressed = NULL;
+
+#define BTN_EXIT 254
+
+LRESULT CALLBACK WndProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) {
+ switch (umsg) {
+ case WM_CLOSE:
+ SetEvent(closingWindowsRequired);
+ DestroyWindow(hwndPB);
+ DestroyWindow(hwndProgressTitle);
+ DestroyWindow(hwndErrorDetail);
+ DestroyWindow(hwndErrorTitle);
+ DestroyWindow(hwndButton);
+ DestroyWindow(hwnd);
+ return 0;
+
+ case WM_DESTROY:
+ UnregisterClass(mainClassName, globalInstance);
+ PostQuitMessage(0);
+ return 0;
+ case WM_COMMAND:
+ if(LOWORD(wParam)==BTN_EXIT) {
+ SetEvent(buttonPressed);
+ return 0;
+ }
+ }
+ return DefWindowProc(hwnd, umsg, wParam, lParam);
+}
+
+void initMainWindow(LauncherProperties * props, HINSTANCE hInstance) {
+ if(!isSilent(props)) {
+ int systemWidth = GetSystemMetrics(SM_CXSCREEN);
+ int systemHeight = GetSystemMetrics(SM_CYSCREEN);
+
+ int w = 460;
+ int h = 200;
+ int x = (systemWidth - w)/2;
+ int y = (systemHeight - h)/2;
+
+ InitCommonControls();
+
+ hwndMain = CreateWindow(mainClassName, mainTitle,
+ //WS_OVERLAPPED | WS_EX_TOOLWINDOW,
+ WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX /* | WS_THICKFRAME | WS_MAXIMIZEBOX*/
+ ,
+ x, y, w, h, NULL, NULL, hInstance, NULL);
+ }
+}
+
+void initErrorTitleWindow(LauncherProperties *props, HINSTANCE hInstance) {
+ if(!isSilent(props)) {
+ RECT rcClient;
+ int cyVScroll;
+ cyVScroll = GetSystemMetrics(SM_CYVSCROLL);
+ GetClientRect(hwndMain, &rcClient);
+ hwndErrorTitle = CreateWindowExW(0, WC_STATICW, WC_STATICW, WS_CHILD,
+ rcClient.left + 10, 15, rcClient.right - 20, 20, hwndMain, NULL, hInstance, NULL);
+ if (hwndErrorTitle) {
+ HFONT hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
+ LOGFONT lfTitle;
+ HFONT titleFont;
+
+ GetObject(hFont, sizeof(lfTitle), &lfTitle);
+ lfTitle.lfWeight = FW_ULTRABOLD;//OLD;
+ lfTitle.lfHeight = lfTitle.lfHeight + 2 ;
+ lfTitle.lfWidth = 0;
+ titleFont = CreateFontIndirect(&lfTitle);
+ SendMessage(hwndErrorTitle, WM_SETFONT, (WPARAM) titleFont , FALSE);
+ //DeleteObject(titleFont );
+ setErrorTitleString(props, NULL);
+ }
+ }
+}
+
+void initErrorDetailWindow(LauncherProperties *props, HINSTANCE hInstance) {
+ if(!isSilent(props)) {
+ RECT rcClient;
+ int cyVScroll;
+ cyVScroll = GetSystemMetrics(SM_CYVSCROLL);
+ GetClientRect(hwndMain, &rcClient);
+ hwndErrorDetail = CreateWindowExW(0, WC_STATICW, WC_STATICW, WS_CHILD ,
+ rcClient.left + 10, 40, rcClient.right - 20, 80,
+ hwndMain, NULL, hInstance, NULL);
+ if (hwndErrorDetail) {
+ LOGFONT lfDetail;
+ HFONT detailFont;
+ HFONT hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
+ GetObject(hFont, sizeof(lfDetail), &lfDetail);
+ lfDetail.lfHeight = lfDetail.lfHeight + 2;
+ lfDetail.lfWidth = 0;
+ detailFont = CreateFontIndirect(&lfDetail);
+ SendMessage(hwndErrorDetail, WM_SETFONT, (WPARAM) detailFont, FALSE);
+ //DeleteObject(detailFont);
+ setErrorDetailString(props, NULL);
+ }
+ }
+}
+
+void initProgressTitleWindow(LauncherProperties *props, HINSTANCE hInstance) {
+ if(!isSilent(props)) {
+ RECT rcClient;
+ int cyVScroll;
+ int height = 20;
+ cyVScroll = GetSystemMetrics(SM_CYVSCROLL);
+ GetClientRect(hwndMain, &rcClient);
+ hwndProgressTitle = CreateWindowExW(0, WC_STATICW, WC_STATICW, WS_CHILD | WS_VISIBLE ,
+ rcClient.left + 10, (rcClient.bottom - cyVScroll)/2 - height, rcClient.right - 20, height,
+ hwndMain, NULL, hInstance, NULL);
+ if (hwndProgressTitle) {
+ LOGFONT lfTitle;
+ HFONT progressTitleFont;
+ HFONT hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
+ GetObject(hFont, sizeof(lfTitle), &lfTitle);
+ lfTitle.lfHeight = lfTitle.lfHeight + 2;
+ lfTitle.lfWidth = 0;
+ progressTitleFont = CreateFontIndirect(&lfTitle);
+ SendMessage(hwndProgressTitle, WM_SETFONT, (WPARAM) progressTitleFont, FALSE);
+ //DeleteObject(detailFont);
+ setProgressTitleString(props, NULL);
+ }
+ }
+}
+
+void initProgressWindow(LauncherProperties * props, HINSTANCE hInstance) {
+ if(!isSilent(props)) {
+ RECT rcClient;
+ int cyVScroll;
+ cyVScroll = GetSystemMetrics(SM_CYVSCROLL);
+ GetClientRect(hwndMain, &rcClient);
+ hwndPB = CreateWindowExW(0, PROGRESS_CLASSW, NULL, WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
+ rcClient.left + 10, (rcClient.bottom - cyVScroll)/2 , rcClient.right - 20, cyVScroll,
+ hwndMain, NULL, hInstance, NULL);
+ totalProgressSize->Low = 100;
+ totalProgressSize->High = 0;
+ }
+}
+
+void initExitButton(LauncherProperties * props, HINSTANCE hInstance) {
+ if(!isSilent(props)) {
+ RECT rcClient;
+ //int cyVScroll = GetSystemMetrics(SM_CYVSCROLL);
+ int buttonWidth = 180;
+ int buttonHeight = 25;
+
+ GetClientRect(hwndMain, &rcClient);
+ hwndButton = CreateWindowExW(0, WC_BUTTONW, NULL,
+ WS_CHILD | BS_DEFPUSHBUTTON | WS_TABSTOP | BS_PUSHBUTTON ,
+ rcClient.right - 20 - buttonWidth, rcClient.bottom - 10 - buttonHeight, buttonWidth, buttonHeight,
+ hwndMain, (HMENU)BTN_EXIT, hInstance, 0);
+ if (hwndButton) {
+ LOGFONT lfButton;
+ HFONT buttonFont;
+ HFONT hFont = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
+ GetObject(hFont, sizeof(lfButton), &lfButton);
+ lfButton.lfHeight = lfButton.lfHeight + 2;
+ lfButton.lfWidth = 0;
+ buttonFont = CreateFontIndirect(&lfButton);
+ SendMessage(hwndButton, WM_SETFONT, (WPARAM) buttonFont, FALSE);
+ SetFocus(hwndButton);
+ //DeleteObject(detailFont);
+ setButtonString(props, NULL);
+ UpdateWindow(hwndButton);
+ }
+ }
+}
+
+void showErrorW(LauncherProperties * props, const char * error, const DWORD varArgsNumber, ...) {
+
+ WCHAR * errorTitle = NULL;
+ WCHAR * errorMessage = NULL;
+ DWORD totalLength = 0;
+ DWORD counter=0;
+ WCHAR * result = NULL;
+ va_list ap;
+
+ getI18nPropertyTitleDetail(props, error, & errorTitle, &errorMessage);
+ totalLength=getLengthW(errorMessage);
+
+ va_start(ap, varArgsNumber);
+
+ while((counter++)<varArgsNumber) {
+ WCHAR * arg = va_arg( ap, WCHAR * );
+ totalLength+=getLengthW(arg);
+ }
+ va_end(ap);
+ result = newpWCHAR(totalLength + 1);
+ va_start(ap, varArgsNumber);
+ if(errorMessage!=NULL) {
+ wvsprintfW(result, errorMessage, ap);
+ }
+ va_end(ap);
+
+ if(!isSilent(props)) {
+ HANDLE * events = (HANDLE *) LocalAlloc(LPTR, sizeof(HANDLE)*2);
+
+ hide(props, hwndProgressTitle);
+ hide(props, hwndPB);
+ setErrorDetailString(props, result);
+ setErrorTitleString(props, errorTitle);
+ setButtonString(props, getI18nProperty(props, EXIT_BUTTON_PROP));
+ show(props, hwndErrorDetail);
+ show(props, hwndErrorTitle);
+ show(props, hwndButton);
+
+ events[0] = buttonPressed;
+ events[1] = closingWindowsRequired;
+ WaitForMultipleObjects(2, events, FALSE, INFINITE);
+ FREE(events);
+ }
+ FREE(result);
+ FREE(errorTitle);
+ FREE(errorMessage);
+}
+
+BOOL InitInstance(LauncherProperties * props, HINSTANCE hInstance, int iCmdShow, HWND * MainWindowHandle) {
+ if(isSilent(props)) return TRUE;
+ iCmdShowGlobal = iCmdShow;
+
+ initMainWindow(props, hInstance);
+ if(!hwndMain) return FALSE;
+
+ initErrorTitleWindow(props, hInstance);
+ if(!hwndErrorTitle) return FALSE;
+
+ initErrorDetailWindow(props, hInstance);
+ if(!hwndErrorDetail) return FALSE;
+
+ initProgressWindow(props, hInstance);
+ if (! hwndPB) return FALSE;
+
+ initProgressTitleWindow(props, hInstance);
+ if (! hwndPB) return FALSE;
+
+ initExitButton(props, hInstance);
+ if (! hwndButton) return FALSE;
+
+ UpdateWindow(hwndMain);
+ * MainWindowHandle = hwndMain;
+ return TRUE;
+}
+
+void messageLoop(LauncherProperties * props){
+ if(!isSilent(props)) {
+ MSG message;
+ while(GetMessage(&message, NULL, 0, 0) > 0) {
+ if(!IsDialogMessage(hwndMain, & message)) {
+ TranslateMessage(&message);
+ DispatchMessage(&message);
+ }
+ }
+ }
+}
+
+BOOL InitApplication(LauncherProperties * props, HINSTANCE hInstance) {
+ if(isSilent(props)) {
+ return TRUE;
+ }
+ else {
+
+ WNDCLASSEX wndclass;
+ wndclass.style = CS_HREDRAW | CS_VREDRAW;
+ wndclass.lpfnWndProc = (WNDPROC)WndProc;
+ wndclass.cbSize = sizeof(WNDCLASSEX);
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(100));
+ wndclass.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL),
+ MAKEINTRESOURCE(100),
+ IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+ wndclass.hInstance = hInstance;
+ wndclass.hCursor = LoadCursor( 0, IDC_ARROW );
+ wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = mainClassName;
+ return RegisterClassEx(&wndclass);
+ }
+}
+
+
+DWORD isTerminated(LauncherProperties * props) {
+ if(props->status == ERROR_USER_TERMINATED) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... already terminated", 1);
+ return 1;
+ }
+ if (WAIT_OBJECT_0 == WaitForSingleObject(closingWindowsRequired, 0)) {
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... terminate signal!", 1);
+ props->status = ERROR_USER_TERMINATED;
+ return 1;
+ }
+ return 0;
+}
+
+void addProgressPosition(LauncherProperties * props, DWORD add) {
+ if(isSilent(props)) return;
+ if ( add > 0 ) {
+ int64t *mult1 = NULL;
+ int64t *mult2 = NULL;
+ int64t *currMult = NULL;
+ int comp1 = 0;
+ int comp2 = 0;
+ int goout = 0;
+
+ plus(currentProgressSize, add);
+ do {
+ multiply(mult1 = newint64_t(totalProgressSize->Low, totalProgressSize->High), lastCheckedStep);
+ multiply(mult2 = newint64_t(totalProgressSize->Low, totalProgressSize->High), lastCheckedStep + 1);
+ multiply(currMult = newint64_t(currentProgressSize->Low, currentProgressSize->High), steps);
+ comp1 = compareInt64t(currMult, mult1);
+
+ if (comp1 == 0) {
+ goout = 1;
+ } else {
+ comp2 = compareInt64t(currMult, mult2);
+ if (comp2 == 0) {
+ lastCheckedStep++;
+ goout = 1;
+ } else if (comp1 > 0 && comp2 < 0) {
+ goout = 1;
+ } else {
+ lastCheckedStep++;
+ }
+ }
+ FREE(mult1);
+ FREE(mult2);
+ FREE(currMult);
+ if(lastCheckedStep >= steps) {
+ lastCheckedStep = steps;
+ goout = 1;
+ }
+ } while (!goout);
+ SendMessage(hwndPB, PBM_SETPOS, lastCheckedStep, 0);
+ }
+}
+
+void setProgressRange(LauncherProperties * props, int64t * range) {
+ if(isSilent(props)) return;
+ totalProgressSize->Low = range->Low;
+ totalProgressSize->High = range->High;
+ currentProgressSize->Low = 0;
+ currentProgressSize->High = 0;
+ lastCheckedStep = 0;
+ SendMessage(hwndPB, PBM_SETRANGE, 0, MAKELPARAM(0, steps));
+ SendMessage(hwndPB, PBM_SETSTEP, 1, 0);
+}
+
+void hide(LauncherProperties * props, HWND hwnd) {
+ if(!isSilent(props) && hwndMain != NULL && hwnd!=NULL ) {
+ ShowWindow(hwnd, SW_HIDE);
+ UpdateWindow(hwnd);
+ }
+}
+void show(LauncherProperties * props, HWND hwnd) {
+ if(!isSilent(props) && hwndMain != NULL && hwnd!=NULL ) {
+ ShowWindow(hwnd, iCmdShowGlobal);
+ UpdateWindow(hwnd);
+ }
+}
+
+void setProgressTitleString(LauncherProperties * props, const WCHAR * message) {
+ if(isSilent(props)) return;
+ SetWindowTextW(hwndProgressTitle, message);
+ UpdateWindow(hwndProgressTitle);
+ UpdateWindow(hwndMain);
+}
+
+void setErrorTitleString(LauncherProperties * props, const WCHAR * message) {
+ if(isSilent(props)) return;
+ SetWindowTextW(hwndErrorTitle, message);
+ UpdateWindow(hwndErrorTitle);
+ UpdateWindow(hwndMain);
+}
+
+void setErrorDetailString(LauncherProperties * props, const WCHAR * message) {
+ if(isSilent(props)) return;
+ SetWindowTextW(hwndErrorDetail, message);
+ UpdateWindow(hwndErrorDetail);
+ UpdateWindow(hwndMain);
+}
+
+void setButtonString(LauncherProperties * props, const WCHAR * message) {
+ if(isSilent(props)) return;
+ SetWindowTextW(hwndButton, message);
+ UpdateWindow(hwndButton);
+ UpdateWindow(hwndMain);
+}
+
+void setMainWindowTitle(LauncherProperties * props, const WCHAR * message) {
+ if(isSilent(props)) return;
+ SetWindowTextW(hwndMain, message);
+ UpdateWindow(hwndMain);
+}
+
+void closeLauncherWindows(LauncherProperties * props) {
+ if(isSilent(props)) return;
+ SendMessage(hwndMain, WM_CLOSE, 0, 0);
+}
+
+
+void hideLauncherWindows(LauncherProperties * props) {
+ if(isSilent(props)) return;
+ if(hwndMain != NULL) {
+ ShowWindow(hwndMain, HIDE_WINDOW);
+ UpdateWindow(hwndMain);
+ }
+}
+
+
+void showLauncherWindows(LauncherProperties * props) {
+ if(isSilent(props)) return;
+ ShowWindow(hwndMain, iCmdShowGlobal);
+ SetForegroundWindow(hwndMain);
+ UpdateWindow(hwndMain);
+}
+
+void showMessageW(LauncherProperties * props, const WCHAR* message, const DWORD varArgsNumber, ...) {
+ DWORD totalLength = getLengthW(message);
+ va_list ap;
+ DWORD counter=0;
+ WCHAR * result = NULL;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, showMessageTitle, 0);
+
+ va_start(ap, varArgsNumber);
+
+ while((counter++)<varArgsNumber) {
+ WCHAR * arg = va_arg( ap, WCHAR * );
+ totalLength+=getLengthW(arg);
+ }
+ va_end(ap);
+
+ result = newpWCHAR(totalLength + 1);
+ va_start(ap, varArgsNumber);
+ wvsprintfW(result, message, ap);
+ va_end(ap);
+ writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, result, 1);
+ if(!isSilent(props)) {
+ hideLauncherWindows(props);
+ MessageBoxW(hwndMain, result, getI18nProperty(props, MSG_MESSAGEBOX_TITLE), MB_OK);
+ }
+}
+
+/*
+void showMessageA(LauncherProperties * props, const char* message, const DWORD varArgsNumber, ...) {
+ DWORD totalLength = getLengthA(message);
+ va_list ap;
+ DWORD counter=0;
+ char * result = NULL;
+
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, showMessageTitle, 0);
+ va_start(ap, varArgsNumber);
+ while((counter++)<varArgsNumber) {
+ char * arg = va_arg( ap, char * );
+ totalLength+=getLengthA(arg);
+ }
+ va_end(ap);
+
+ result = newpChar(totalLength + 1);
+ va_start(ap, varArgsNumber);
+ vsprintf(result, message, ap);
+ va_end(ap);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, result, 1);
+
+ if(!isSilent(props)) {
+ char * prop = toChar(getI18nProperty(props, MSG_MESSAGEBOX_TITLE));
+ MessageBoxA(hwndMain, result, prop, MB_OK);
+ FREE(prop);
+ }
+
+}
+*/
+/*
+ * WCHAR* GetStringFromStringTable( UINT uStringID ) {
+ * WCHAR *pwchMem, *pwchCur;
+ * UINT idRsrcBlk = uStringID / 16 + 1;
+ * int strIndex = uStringID % 16;
+ * HINSTANCE hModule = NULL;
+ * HRSRC hResource = NULL;
+ * int i=0;
+ * LANGID lang = LANGIDFROMLCID(GetUserDefaultLCID());
+ *
+ * hResource = FindResourceExW( GetModuleHandleW(NULL), (LPWSTR)RT_STRING,
+ * MAKEINTRESOURCEW(idRsrcBlk), lang);
+ *
+ * if( hResource != NULL ) {
+ * pwchMem = (WCHAR *)LoadResource( hModule, hResource );
+ *
+ * if( pwchMem != NULL ) {
+ * pwchCur = pwchMem;
+ * for(i = 0; i<16; i++ ) {
+ * if( *pwchCur ) {
+ * int cchString = *pwchCur; // String size in characters.
+ * pwchCur++;
+ * if( i == strIndex ) {
+ * WCHAR * tmp = appendStringNW(NULL, 0, pwchCur, cchString);
+ * return tmp;
+ * }
+ * pwchCur += cchString;
+ * }
+ * else
+ * pwchCur++;
+ * }
+ * }
+ * }
+ * return NULL;
+ *
+ * }*/
+
+
+
+
+DWORD WINAPI launcherThread(void * ptr) {
+ HANDLE * events = (HANDLE *) LocalAlloc(LPTR, sizeof(HANDLE)*2);
+ DWORD result;
+ events[0] = initializationSuccess;
+ events[1] = initializationFailed;
+ result = WaitForMultipleObjects(2, events, FALSE, INFINITE);
+
+ FREE(events);
+
+ if (result == WAIT_OBJECT_0) {
+ LauncherProperties * props = (LauncherProperties*) ptr;
+ processLauncher(props);
+ SetEvent(closingWindowsConfirmed);
+ closeLauncherWindows(props);
+ }
+ return 0;
+}
+
+
+void createLauncherThread(LauncherProperties *props) {
+ DWORD threadId;
+ if(CreateThread( NULL, 0, &launcherThread, (LPVOID) props, 0, &threadId )==NULL) {
+ SetEvent(closingWindowsConfirmed);
+ }
+}
+
+DWORD createGui(LauncherProperties* props, HINSTANCE hInstance, HINSTANCE hi, int nCmdShow) {
+ if (!InitApplication(props, hInstance)) {
+ SetEvent(initializationFailed);
+ return 0;
+ } else if (!InitInstance(props, hInstance, nCmdShow, & hwndMain)) {
+ SetEvent(initializationFailed);
+ return 0;
+ } else {
+ SetEvent(initializationSuccess);
+ }
+ return 1;
+}
+
+
+DWORD createEvents() {
+ initializationSuccess = CreateEventW(NULL, TRUE, FALSE, NULL);
+ if(initializationSuccess==NULL) {
+ return 0;
+ }
+ initializationFailed = CreateEventW(NULL, TRUE, FALSE, NULL);
+ if(initializationFailed==NULL) {
+ return 0;
+ }
+ buttonPressed = CreateEventW(NULL, TRUE, FALSE, NULL);
+ if(buttonPressed ==NULL) {
+ return 0;
+ }
+ closingWindowsRequired = CreateEventW(NULL, TRUE, FALSE, NULL);
+ if(closingWindowsRequired ==NULL) {
+ return 0;
+ }
+ closingWindowsConfirmed = CreateEventW(NULL, TRUE, FALSE, NULL);
+ if(closingWindowsConfirmed ==NULL) {
+ return 0;
+ }
+
+ return 1;
+}
+
+int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hi, LPSTR lpCmdLine, int nCmdShow) {
+ DWORD exitCode = 1;
+ DWORD status = ERROR_OK;
+
+ totalProgressSize = newint64_t(0,0);
+ currentProgressSize = newint64_t(0,0);
+ globalInstance = hInstance;
+ UNREFERENCED_PARAMETER(lpCmdLine);
+ initWow64();
+ if(is9x()) {
+ MessageBoxA(0, "Windows 9X platform is not supported", "Message", MB_OK);
+ status = EXIT_CODE_SYSTEM_ERROR;
+ } else {
+ if(!createEvents()) {
+ status = EXIT_CODE_EVENTS_INITIALIZATION_ERROR;
+ } else {
+ LauncherProperties * props = createLauncherProperties();
+ createLauncherThread(props);
+ if(!createGui(props, hInstance, hi, nCmdShow)) {
+ status = EXIT_CODE_GUI_INITIALIZATION_ERROR;
+ } else {
+ messageLoop(props);
+ WaitForSingleObject(closingWindowsConfirmed, INFINITE);
+ }
+
+ status = props->status;
+ exitCode = props->exitCode;
+ printStatus(props);
+ freeLauncherProperties(&props);
+ }
+ }
+ FREE(currentProgressSize);
+ FREE(totalProgressSize);
+ return (status==ERROR_OK) ? exitCode : status;
+}
+
+int WINAPI MyMain(void) {
+ int exitCode;
+ STARTUPINFO StartupInfo;
+ StartupInfo.dwFlags = 0;
+ GetStartupInfo( &StartupInfo );
+ exitCode = WinMain(GetModuleHandle(NULL), NULL, NULL, StartupInfo.dwFlags & STARTF_USESHOWWINDOW ? StartupInfo.wShowWindow : SW_SHOWDEFAULT);
+ ExitProcess(exitCode);
+ return exitCode;
+}
diff --git a/src/main/cpp/launcher/windows/src/Main.h b/src/main/cpp/launcher/windows/src/Main.h
new file mode 100644
index 0000000..57c81ef
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/Main.h
@@ -0,0 +1,58 @@
+/*
+ * 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 _Main_H
+#define _Main_H
+
+#include <wchar.h>
+#include "Errors.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void addProgressPosition(LauncherProperties *props,DWORD add);
+void setProgressRange(LauncherProperties *props, int64t * size);
+void setErrorDetailString(LauncherProperties *props,const WCHAR * message);
+void setErrorTitleString(LauncherProperties *props,const WCHAR * message);
+void setButtonString(LauncherProperties *props,const WCHAR * message);
+void setProgressTitleString(LauncherProperties *props,const WCHAR * message);
+void setMainWindowTitle(LauncherProperties * props, const WCHAR * message);
+
+void showLauncherWindows(LauncherProperties *props);
+void closeLauncherWindows(LauncherProperties *props);
+void hideLauncherWindows(LauncherProperties *props);
+
+void hide(LauncherProperties *props,HWND hwnd);
+void show(LauncherProperties *props,HWND hwnd);
+
+DWORD isTerminated(LauncherProperties * props);
+
+void showErrorW(LauncherProperties *props, const char * error, const DWORD varArgsNumber, ...);
+
+void showMessageW(LauncherProperties *props,const WCHAR* message, const DWORD number, ...);
+//void showMessageA(LauncherProperties *props,const char * message, const DWORD varArgsNumber, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _Main_H */
+
diff --git a/src/main/cpp/launcher/windows/src/ProcessUtils.c b/src/main/cpp/launcher/windows/src/ProcessUtils.c
new file mode 100644
index 0000000..0fcd9dd
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/ProcessUtils.c
@@ -0,0 +1,221 @@
+/*
+ * 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 "ProcessUtils.h"
+#include "StringUtils.h"
+#include "FileUtils.h"
+
+
+const DWORD DEFAULT_PROCESS_TIMEOUT = 30000; //30 sec
+
+DWORD readBuf(HANDLE hRead, WCHAR * buf, DWORD * bytesRead, HANDLE hWrite) {
+ ReadFile(hRead, buf, STREAM_BUF_LENGTH - 1, bytesRead, NULL);
+
+ if((*bytesRead)>0 && hWrite!=INVALID_HANDLE_VALUE) {
+ DWORD bytesWritten = 0;
+ WriteFile(hWrite, buf, (*bytesRead), &bytesWritten, 0);
+ }
+ ZERO(buf, sizeof(buf));
+ return 0;
+}
+
+DWORD readNextData(HANDLE hRead, WCHAR * buf, HANDLE hWrite) {
+ DWORD bytesRead;
+ DWORD bytesAvailable;
+ ZERO(buf, sizeof(buf));
+
+ PeekNamedPipe(hRead, buf, STREAM_BUF_LENGTH - 1, &bytesRead, &bytesAvailable, NULL);
+ if (bytesRead != 0) {
+ ZERO(buf, sizeof(buf));
+ if (bytesAvailable >= STREAM_BUF_LENGTH) {
+ while (bytesRead >= STREAM_BUF_LENGTH-1) {
+ readBuf(hRead, buf, &bytesRead, hWrite);
+ }
+ }
+ else {
+ readBuf(hRead, buf, &bytesRead, hWrite);
+ }
+ return bytesRead;
+ }
+ return 0;
+}
+
+// get already running process stdout
+DWORD readProcessStream(PROCESS_INFORMATION pi, HANDLE currentProcessStdin, HANDLE currentProcessStdout, HANDLE currentProcessStderr, DWORD timeOut, HANDLE hWriteInput, HANDLE hWriteOutput, HANDLE hWriteError) {
+ DWORD started = GetTickCount();
+ WCHAR buf[STREAM_BUF_LENGTH];
+ DWORD exitCode=0;
+ DWORD outRead =0;
+ DWORD errRead =0;
+ DWORD inRead =0;
+ while(1) {
+ outRead = readNextData(currentProcessStdout, buf, hWriteOutput);
+ errRead = readNextData(currentProcessStderr, buf, hWriteError);
+ inRead = readNextData(hWriteInput, buf, currentProcessStdin);
+ GetExitCodeProcess(pi.hProcess, &exitCode);
+ if (exitCode != STILL_ACTIVE) break;
+
+ if(outRead == 0 && errRead==0 && inRead==0 && timeOut!=INFINITE) {
+ if((GetTickCount() - started) > timeOut) break;
+ }
+ //avoid extra using of CPU resources
+ Sleep(1);
+ }
+ return exitCode;
+}
+char * readHandle(HANDLE hRead) {
+ char * output = NULL;
+ char * buf = newpChar(STREAM_BUF_LENGTH);
+ DWORD total = 0;
+ DWORD read;
+ DWORD bytesRead;
+ DWORD bytesAvailable;
+
+ while(1) {
+ PeekNamedPipe(hRead, buf, STREAM_BUF_LENGTH - 1, &bytesRead, &bytesAvailable, NULL);
+ if(bytesAvailable==0) break;
+ ReadFile(hRead, buf, STREAM_BUF_LENGTH - 1, &read, NULL);
+ if(read==0) break;
+ output = appendStringN(output, total, buf, read);
+ total+=read;
+ }
+ FREE(buf);
+ return output;
+}
+
+
+
+
+// run process and get its standart output
+// command - executing command
+// timeLimitMillis - timeout of the process running without any output
+// dir - working directory
+// return ERROR_ON_EXECUTE_PROCESS for serios error
+// return ERROR_PROCESS_TIMEOUT for timeout
+
+void executeCommand(LauncherProperties * props, WCHAR * command, WCHAR * dir, DWORD timeLimitMillis, HANDLE hWriteOutput, HANDLE hWriteError, DWORD priority) {
+ STARTUPINFOW si;
+ SECURITY_ATTRIBUTES sa;
+ SECURITY_DESCRIPTOR sd;
+ PROCESS_INFORMATION pi;
+
+ HANDLE newProcessInput;
+ HANDLE newProcessOutput;
+ HANDLE newProcessError;
+
+ HANDLE currentProcessStdout;
+ HANDLE currentProcessStdin;
+ HANDLE currentProcessStderr;
+
+ WCHAR * directory;
+
+ InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
+ SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
+ sa.lpSecurityDescriptor = &sd;
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.bInheritHandle = TRUE;
+
+
+ if (!CreatePipe(&newProcessInput, ¤tProcessStdin, &sa, 0)) {
+ writeErrorA(props, OUTPUT_LEVEL_NORMAL, 1, "Can`t create pipe for input. ", NULL , GetLastError());
+ props->status = ERROR_ON_EXECUTE_PROCESS;
+ return;
+ }
+
+ if (!CreatePipe(¤tProcessStdout, &newProcessOutput, &sa, 0)) {
+ writeErrorA(props, OUTPUT_LEVEL_NORMAL, 1, "Can`t create pipe for output. ", NULL , GetLastError());
+ CloseHandle(newProcessInput);
+ CloseHandle(currentProcessStdin);
+ props->status = ERROR_ON_EXECUTE_PROCESS;
+ return;
+ }
+
+ if (!CreatePipe(¤tProcessStderr, &newProcessError, &sa, 0)) {
+ writeErrorA(props, OUTPUT_LEVEL_NORMAL, 1, "Can`t create pipe for error. ", NULL , GetLastError());
+ CloseHandle(newProcessInput);
+ CloseHandle(currentProcessStdin);
+ CloseHandle(newProcessOutput);
+ CloseHandle(currentProcessStdout);
+ props->status = ERROR_ON_EXECUTE_PROCESS;
+ return;
+ }
+
+
+ GetStartupInfoW(&si);
+
+ si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
+ si.wShowWindow = SW_HIDE;
+ si.hStdOutput = newProcessOutput;
+ si.hStdError = newProcessError;
+ si.hStdInput = newProcessInput;
+
+ directory = (dir!=NULL) ? dir : getCurrentDirectory();
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Create new process: ", 1);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " command : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, command, 1);
+ writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, " directory : ", 0);
+ writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, directory, 1);
+
+ props->exitCode = ERROR_OK;
+ if (CreateProcessW(NULL, command, NULL, NULL, TRUE,
+ CREATE_NEW_CONSOLE | CREATE_NO_WINDOW | CREATE_DEFAULT_ERROR_MODE | priority,
+ NULL, directory, &si, &pi)) {
+ // TODO
+ // Check whether volder virtualization can brake things and provide method to disable it if necessary
+ // I am not sure whether we need it off or on.
+ // http://www.netbeans.org/issues/show_bug.cgi?id=122186
+ DWORD timeOut = ((timeLimitMillis<=0) ? DEFAULT_PROCESS_TIMEOUT: timeLimitMillis);
+ props->status = ERROR_OK;
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... process created", 1);
+
+ props->exitCode = readProcessStream(pi, currentProcessStdin, currentProcessStdout, currentProcessStderr, timeOut, newProcessInput, hWriteOutput, hWriteError);
+
+ if(props->exitCode==STILL_ACTIVE) {
+ //actually we have reached the timeout of the process and need to terminate it
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... process is timeouted", 1);
+ GetExitCodeProcess(pi.hProcess, & (props->exitCode));
+
+ if(props->exitCode==STILL_ACTIVE) {
+ TerminateProcess(pi.hProcess, 0);
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... terminate process", 1);
+ //Terminating process...It worked too much without any stdout/stdin/stderr
+ props->status = ERROR_PROCESS_TIMEOUT;//terminated by timeout
+ }
+ } else {
+ //application finished its work... succesfully or not - it doesn`t matter
+ writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... process finished his work", 1);
+ }
+ CloseHandle(pi.hThread);
+ CloseHandle(pi.hProcess);
+ } else {
+ writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "... can`t create process.", NULL, GetLastError());
+ props->status = ERROR_ON_EXECUTE_PROCESS;
+ }
+
+
+ CloseHandle(newProcessInput);
+ CloseHandle(newProcessOutput);
+ CloseHandle(newProcessError);
+ CloseHandle(currentProcessStdin);
+ CloseHandle(currentProcessStdout);
+ CloseHandle(currentProcessStderr);
+}
+
+
+
diff --git a/src/main/cpp/launcher/windows/src/ProcessUtils.h b/src/main/cpp/launcher/windows/src/ProcessUtils.h
new file mode 100644
index 0000000..f553b20
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/ProcessUtils.h
@@ -0,0 +1,48 @@
+/*
+ * 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 _ProcessUtils_H
+#define _ProcessUtils_H
+
+#include <windows.h>
+#include <stdio.h>
+#include "Errors.h"
+#include "Types.h"
+#include "ExtractUtils.h"
+#include "FileUtils.h"
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ #define STREAM_BUF_LENGTH 1024
+
+ extern const DWORD DEFAULT_PROCESS_TIMEOUT;
+
+ char * readHandle(HANDLE hRead);
+
+ void executeCommand(LauncherProperties * props, WCHAR * command, WCHAR * dir, DWORD timeLimitMillis, HANDLE hWriteOutput, HANDLE hWriteError, DWORD priority);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ProcessUtils_H */
diff --git a/src/main/cpp/launcher/windows/src/RegistryUtils.c b/src/main/cpp/launcher/windows/src/RegistryUtils.c
new file mode 100644
index 0000000..e60bd60
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/RegistryUtils.c
@@ -0,0 +1,60 @@
+/*
+ * 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 "RegistryUtils.h"
+#include "StringUtils.h"
+#include "SystemUtils.h"
+#include "FileUtils.h"
+
+WCHAR * getStringValue(HKEY root, WCHAR *key, WCHAR *valueName, BOOL access64key) {
+
+ HKEY hkey = 0 ;
+ WCHAR *result = NULL;
+ DWORD type = 0;
+ DWORD size = 0;
+ byte* value = NULL;
+
+ if(RegOpenKeyExW(root, key, 0, KEY_READ | ((access64key && IsWow64) ? KEY_WOW64_64KEY : 0), &hkey) == ERROR_SUCCESS) {
+
+ if (RegQueryValueExW(hkey, valueName, NULL, &type, NULL, &size) == ERROR_SUCCESS) {
+
+ value = (byte*) LocalAlloc(LPTR,(size + 1) * sizeof(WCHAR));
+ ZERO(value, sizeof(WCHAR) * (size + 1));
+ if (RegQueryValueExW(hkey, valueName, NULL, &type, value, &size) == ERROR_SUCCESS) {
+ if(type == REG_SZ) {
+ result = (WCHAR *)value;
+ }
+ }
+ if(result==NULL) {
+ FREE(value);
+ }
+ }
+ }
+
+ if(hkey!=0) {
+ RegCloseKey(hkey);
+ }
+ return result;
+}
+WCHAR * getStringValuePC(HKEY root, WCHAR *parentkey, WCHAR *childkey, WCHAR *valueName, BOOL access64key) {
+ WCHAR * key = appendStringW(appendStringW(appendStringW(NULL, parentkey), L"\\"), childkey);
+ WCHAR *value = getStringValue(root, key, valueName, access64key);
+ FREE(key);
+ return value;
+}
diff --git a/src/main/cpp/launcher/windows/src/RegistryUtils.h b/src/main/cpp/launcher/windows/src/RegistryUtils.h
new file mode 100644
index 0000000..c9851b0
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/RegistryUtils.h
@@ -0,0 +1,44 @@
+/*
+ * 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 _RegistryUtils_H
+#define _RegistryUtils_H
+
+#include <windows.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+WCHAR * getStringValue(HKEY root, WCHAR *key, WCHAR *valueName, BOOL access64key);
+WCHAR * getStringValuePC(HKEY root, WCHAR *parentkey, WCHAR *childkey, WCHAR *valueName, BOOL access64key);
+
+#ifndef KEY_WOW64_32KEY
+#define KEY_WOW64_32KEY 0x0200
+#endif
+#ifndef KEY_WOW64_64KEY
+#define KEY_WOW64_64KEY 0x0100
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RegistryUtils_H */
diff --git a/src/main/cpp/launcher/windows/src/StringUtils.c b/src/main/cpp/launcher/windows/src/StringUtils.c
new file mode 100644
index 0000000..cf0423b
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/StringUtils.c
@@ -0,0 +1,794 @@
+/*
+ * 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 <wchar.h>
+#include <windows.h>
+#include <winnls.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "StringUtils.h"
+
+
+
+const char * JVM_NOT_FOUND_PROP = "nlw.jvm.notfoundmessage";
+const char * JVM_USER_DEFINED_ERROR_PROP = "nlw.jvm.usererror";
+
+const char * JVM_UNSUPPORTED_VERSION_PROP = "nlw.jvm.unsupportedversion";
+const char * NOT_ENOUGH_FREE_SPACE_PROP = "nlw.freespace";
+const char * CANT_CREATE_TEMP_DIR_PROP = "nlw.tmpdir";
+const char * INTEGRITY_ERROR_PROP = "nlw.integrity";
+const char * OUTPUT_ERROR_PROP = "nlw.output.error";
+const char * JAVA_PROCESS_ERROR_PROP = "nlw.java.process.error";
+const char * EXTERNAL_RESOURE_LACK_PROP = "nlw.missing.external.resource";
+const char * BUNDLED_JVM_EXTRACT_ERROR_PROP = "nlw.bundled.jvm.extract.error";
+const char * BUNDLED_JVM_VERIFY_ERROR_PROP = "nlw.bundled.jvm.verify.error";
+
+const char * ARG_OUTPUT_PROPERTY = "nlw.arg.output";
+const char * ARG_JAVA_PROP = "nlw.arg.javahome";
+const char * ARG_DEBUG_PROP = "nlw.arg.verbose";
+const char * ARG_TMP_PROP = "nlw.arg.tempdir";
+const char * ARG_CPA_PROP = "nlw.arg.classpatha";
+const char * ARG_CPP_PROP = "nlw.arg.classpathp";
+const char * ARG_EXTRACT_PROP = "nlw.arg.extract";
+const char * ARG_DISABLE_SPACE_CHECK = "nlw.arg.disable.space.check";
+const char * ARG_LOCALE_PROP = "nlw.arg.locale";
+const char * ARG_SILENT_PROP = "nlw.arg.silent";
+const char * ARG_HELP_PROP = "nlw.arg.help";
+
+const char * MSG_CREATE_TMPDIR = "nlw.msg.create.tmpdir";
+const char * MSG_EXTRACT_DATA = "nlw.msg.extract";
+const char * MSG_JVM_SEARCH = "nlw.msg.jvmsearch";
+const char * MSG_SET_OPTIONS = "nlw.msg.setoptions";
+const char * MSG_RUNNING = "nlw.msg.running";
+const char * MSG_TITLE = "nlw.msg.title";
+const char * MSG_MESSAGEBOX_TITLE = "nlw.msg.messagebox.title";
+const char * MSG_PROGRESS_TITLE = "nlw.msg.progress.title";
+
+const char * EXIT_BUTTON_PROP = "nlw.msg.button.error" ;
+const char * MAIN_WINDOW_TITLE = "nlw.msg.main.title" ;
+
+
+
+
+//adds string the the initial string and modifies totalWCHARs and capacity
+// initial - the beginning of the string
+// size - pointer to the value that contains the length of the initial string
+// It is modified to store returning string length
+// addString - additional string
+//
+
+
+void freeI18NMessages(LauncherProperties * props) {
+ if(props->i18nMessages!=NULL) {
+ DWORD i=0;
+
+ for(i=0;i<props->I18N_PROPERTIES_NUMBER;i++) {
+ FREE(props->i18nMessages->properties[i]);
+ FREE(props->i18nMessages->strings[i]);
+ }
+ FREE(props->i18nMessages->properties);
+ FREE(props->i18nMessages->strings);
+ FREE(props->i18nMessages);
+ }
+}
+
+char * searchA(const char * wcs1, const char * wcs2) {
+ char *cp = (char *) wcs1;
+ char *s1, *s2;
+
+ if ( !*wcs2) {
+ return (char *)wcs1;
+ }
+
+ while (*cp) {
+ s1 = cp;
+ s2 = (char *) wcs2;
+
+ while ( *s1 && *s2 && !(*s1-*s2) ) {
+ s1++, s2++;
+ }
+ if (!*s2) {
+ return(cp);
+ }
+ cp++;
+ }
+ return(NULL);
+}
+
+WCHAR * searchW(const WCHAR * wcs1, const WCHAR * wcs2) {
+ WCHAR *cp = (WCHAR *) wcs1;
+ WCHAR *s1, *s2;
+
+ if ( !*wcs2) {
+ return (WCHAR *)wcs1;
+ }
+
+ while (*cp) {
+ s1 = cp;
+ s2 = (WCHAR *) wcs2;
+
+ while ( *s1 && *s2 && !(*s1-*s2) ) {
+ s1++, s2++;
+ }
+ if (!*s2) {
+ return(cp);
+ }
+ cp++;
+ }
+ return(NULL);
+}
+
+void getI18nPropertyTitleDetail(LauncherProperties * props, const char * name, WCHAR ** title, WCHAR ** detail) {
+ const WCHAR * prop = getI18nProperty(props,name);
+ WCHAR * detailStringSep = searchW(prop, L"\n");
+
+ if(detailStringSep == NULL) {
+ *title = appendStringW(NULL, prop);
+ *detail = NULL;
+ } else {
+ DWORD dif = getLengthW(prop) - getLengthW(detailStringSep);
+ *title = appendStringNW(NULL, 0, prop, dif);
+ *detail = appendStringW(NULL, prop + (dif + 1));
+ }
+}
+const WCHAR * getI18nProperty(LauncherProperties * props, const char * name) {
+ if(name==NULL) return NULL;
+ if(name!=NULL && props->i18nMessages!=NULL) {
+ DWORD i;
+ for(i=0;i<props->I18N_PROPERTIES_NUMBER;i++) {
+ char * pr = props->i18nMessages->properties[i];
+ if(pr!=NULL) { // hope so it`s true
+ if(lstrcmpA(name, pr)==0) {
+ return props->i18nMessages->strings[i];
+ }
+ }
+ }
+ }
+ return getDefaultString(name);
+}
+
+WCHAR * getDefaultString(const char *name) {
+ if(lstrcmpA(name, JVM_NOT_FOUND_PROP)==0) {
+ return L"Can`t find suitable JVM. Specify it with %s argument";
+ } else if(lstrcmpA(name, NOT_ENOUGH_FREE_SPACE_PROP)==0) {
+ return L"Not enought free space at %s";
+ } else if(lstrcmpA(name, CANT_CREATE_TEMP_DIR_PROP)==0) {
+ return L"Can`t create temp directory %s";
+ } else if(lstrcmpA(name, INTEGRITY_ERROR_PROP)==0) {
+ return L"Integrity error. File %s is corrupted";
+ } else if(lstrcmpA(name, JVM_USER_DEFINED_ERROR_PROP)==0) {
+ return L"Can`t find JVM at %s";
+ } else if(lstrcmpA(name, JVM_UNSUPPORTED_VERSION_PROP)==0) {
+ return L"Unsupported JVM at %s";
+ } else if(lstrcmpA(name, OUTPUT_ERROR_PROP)==0) {
+ return L"Can`t create file %s.\nError: %s";
+ } else if(lstrcmpA(name, JAVA_PROCESS_ERROR_PROP)==0) {
+ return L"Java error:\n%s";
+ } else if(lstrcmpA(name, ARG_JAVA_PROP)==0) {
+ return L"%s Using specified JVM";
+ } else if(lstrcmpA(name, ARG_OUTPUT_PROPERTY)==0) {
+ return L"%s Output all stdout/stderr to the file";
+ } else if(lstrcmpA(name, ARG_DEBUG_PROP)==0) {
+ return L"%s Use verbose output";
+ } else if(lstrcmpA(name, ARG_TMP_PROP)==0) {
+ return L"%s Use specified temporary dir for extracting data";
+ } else if(lstrcmpA(name, ARG_CPA_PROP)==0) {
+ return L"%s Append classpath";
+ } else if(lstrcmpA(name, ARG_CPP_PROP)==0) {
+ return L"%s Prepend classpath";
+ } else if(lstrcmpA(name, ARG_EXTRACT_PROP)==0) {
+ return L"%s Extract all data";
+ } else if(lstrcmpA(name, ARG_HELP_PROP)==0) {
+ return L"%s Using this help";
+ } else if(lstrcmpA(name, ARG_DISABLE_SPACE_CHECK)==0) {
+ return L"%s Disable free space check";
+ } else if(lstrcmpA(name, ARG_LOCALE_PROP )==0) {
+ return L"%s Use specified locale for messagess";
+ } else if(lstrcmpA(name, ARG_SILENT_PROP )==0) {
+ return L"%s Run silently";
+ } else if(lstrcmpA(name, MSG_CREATE_TMPDIR)==0) {
+ return L"Creating tmp directory...";
+ } else if(lstrcmpA(name, MSG_EXTRACT_DATA)==0) {
+ return L"Extracting data...";
+ } else if(lstrcmpA(name, MSG_JVM_SEARCH)==0) {
+ return L"Finding JVM...";
+ } else if(lstrcmpA(name, MSG_RUNNING)==0) {
+ return L"Running JVM...";
+ } else if(lstrcmpA(name, MSG_SET_OPTIONS)==0) {
+ return L"Setting command options...";
+ } else if(lstrcmpA(name, MSG_MESSAGEBOX_TITLE)==0) {
+ return L"Message";
+ } else if(lstrcmpA(name, MSG_PROGRESS_TITLE)==0) {
+ return L"Running";
+ } else if(lstrcmpA(name, EXIT_BUTTON_PROP)==0) {
+ return L"Exit";
+ } else if(lstrcmpA(name, MAIN_WINDOW_TITLE)==0) {
+ return L"NBI Launcher";
+ } else if(lstrcmpA(name, EXTERNAL_RESOURE_LACK_PROP)==0) {
+ return L"Can`t run launcher\nThe following file is missing : %s";
+ } else if(lstrcmpA(name, BUNDLED_JVM_EXTRACT_ERROR_PROP)==0) {
+ return L"Can`t run prepare bundled JVM";
+ } else if(lstrcmpA(name, BUNDLED_JVM_VERIFY_ERROR_PROP)==0) {
+ return L"Can`t run verify bundled JVM";
+ }
+ return NULL;
+}
+
+DWORD getLengthA(const char * message) {
+ return (message!=NULL) ? lstrlenA(message) : 0;
+}
+
+DWORD getLengthW(const WCHAR * message) {
+ return (message!=NULL) ? lstrlenW(message) : 0;
+}
+
+//adds string the the initial string
+char * appendStringN(char * initial, DWORD initialLength, const char * addString, DWORD addStringLength) {
+ DWORD length = initialLength + addStringLength + 1;
+ if (length > 1) {
+ char * tmp = newpChar(length+1);
+ DWORD i=0;
+ if(initialLength!=0) {
+ for(i=0;i<initialLength;i++) {
+ tmp[i]=initial[i];
+ }
+ FREE(initial);
+ }
+ for(i=0;i<addStringLength;i++) {
+ tmp[i+initialLength] = addString[i];
+ }
+
+ return tmp;
+ } else {
+ return NULL;
+ }
+}
+
+char * appendString(char * initial, const char * addString) {
+ return appendStringN(initial, getLengthA(initial), addString, getLengthA(addString));
+}
+
+
+//adds string the the initial string
+WCHAR * appendStringNW(WCHAR * initial, DWORD initialLength, const WCHAR * addString, DWORD addStringLength) {
+
+ DWORD length = initialLength + addStringLength + 1;
+ if(length>1) {
+
+ WCHAR * tmp = newpWCHAR(length+1);
+ DWORD i=0;
+
+ if(initialLength!=0) {
+ for(i=0;i<initialLength;i++) {
+ tmp[i]=initial[i];
+ }
+ FREE(initial);
+ }
+
+ for(i=0;i<addStringLength;i++) {
+ tmp[i+initialLength] = addString[i];
+ }
+ tmp[length] = 0;
+
+ return tmp;
+ } else {
+
+ return NULL;
+ }
+}
+
+WCHAR * appendStringW(WCHAR * initial, const WCHAR * addString) {
+ return appendStringNW(initial, getLengthW(initial), addString, getLengthW(addString));
+}
+
+WCHAR * escapeString(const WCHAR * string) {
+ DWORD length = getLengthW(string);
+ WCHAR *result = newpWCHAR(length * 2 + 4);
+ DWORD i=0;
+ DWORD r=0;
+ DWORD bsCounter = 0;
+ int quoting = searchW(string, L" ") || searchW(string, L"\t");
+ if(quoting) {
+ result[r++] = '\"';
+ }
+ for(i=0;i<length;i++) {
+ const WCHAR c = string[i];
+ switch(c) {
+ case '\\' :
+ bsCounter++;
+ break;
+ case '"':
+ bsCounter++;
+ do {
+ result[r++] = '\\';
+ bsCounter--;
+ } while(bsCounter>0);
+ default:
+ bsCounter = 0;
+ break;
+ }
+ result[r++] = c;
+ }
+ if(quoting) {
+ while(bsCounter>0) {
+ result[r++] = '\\';
+ bsCounter--;
+ }
+ result[r++] = '\"';
+ }
+ result[r] = '\0';
+ return result;
+}
+
+char * DWORDtoCHARN(DWORD value, int fillZeros) {
+ int digits = 0;
+ DWORD tmpValue = value;
+ int i = 0;
+ char * str;
+
+ do {
+ digits++;
+ tmpValue = tmpValue / 10;
+ } while(tmpValue!=0);
+ tmpValue = value;
+ if(digits < fillZeros) {
+ digits = fillZeros;
+ }
+ str = (char*) LocalAlloc(LPTR, sizeof(char)*(digits +1));
+ str[digits] = '\0';
+ for(i=0;i<digits;i++) {
+ str [digits - i - 1] = '0' + (char) (tmpValue - ((tmpValue / 10) * 10));
+ tmpValue = tmpValue / 10;
+ }
+ return str;
+}
+
+WCHAR * DWORDtoWCHARN(DWORD value, int fillZeros) {
+ int digits = 0;
+ DWORD tmpValue = value;
+ int i = 0;
+ WCHAR * str;
+
+ do {
+ digits++;
+ tmpValue = tmpValue / 10;
+ } while(tmpValue!=0);
+ tmpValue = value;
+ if(digits < fillZeros) {
+ digits = fillZeros;
+ }
+
+ str = (WCHAR*) LocalAlloc(LPTR, sizeof(WCHAR)*(digits +1));
+ str[digits] = L'\0';
+ for(i=0;i<digits;i++) {
+ str [digits - i - 1] = L'0' + (WCHAR) (tmpValue - ((tmpValue / 10) * 10));
+ tmpValue = tmpValue / 10;
+ }
+ return str;
+}
+WCHAR * DWORDtoWCHAR(DWORD value) {
+ return DWORDtoWCHARN(value, 0);
+}
+
+char * DWORDtoCHAR(DWORD value) {
+ return DWORDtoCHARN(value,0);
+}
+
+char * long2charN(long value, int fillZeros) {
+ int digits = 0;
+ long tmpValue = value;
+ int i = 0;
+ char * str;
+
+ do {
+ digits++;
+ tmpValue = tmpValue / 10;
+ } while(tmpValue!=0);
+ tmpValue = value;
+ if(digits < fillZeros) {
+ digits = fillZeros;
+ }
+ str = (char*) LocalAlloc(LPTR, sizeof(char)*(digits +1));
+ str[digits] = '\0';
+ for(i=0;i<digits;i++) {
+ str [digits - i - 1] = '0' + (char) (tmpValue - ((tmpValue / 10) * 10));
+ tmpValue = tmpValue / 10;
+ }
+ return str;
+}
+
+char * long2char(long value) {
+ return long2charN(value,0);
+}
+
+char * word2charN(WORD value, int fillZeros) {
+ int digits = 0;
+ WORD tmpValue = value;
+ int i = 0;
+ char * str;
+
+ do {
+ digits++;
+ tmpValue = tmpValue / 10;
+ } while(tmpValue!=0);
+ tmpValue = value;
+ if(digits < fillZeros) {
+ digits = fillZeros;
+ }
+ str = (char*) LocalAlloc(LPTR, sizeof(char)*(digits +1));
+ str[digits] = '\0';
+ for(i=0;i<digits;i++) {
+ str [digits - i - 1] = '0' + (char) (tmpValue - ((tmpValue / 10) * 10));
+ tmpValue = tmpValue / 10;
+ }
+ return str;
+}
+
+char * word2char(WORD value) {
+ return word2charN(value,0);
+}
+
+char * int64ttoCHAR(int64t* value) {
+ if(value->High==0) {
+ return DWORDtoCHAR(value->Low);
+ } else {
+ char * high = DWORDtoCHAR(value->High);
+ char * low = DWORDtoCHAR(value->Low);
+ DWORD highLength = getLengthA(high);
+ DWORD lowLength = getLengthA(low);
+
+ char * str = newpChar(highLength + lowLength + 9);
+ DWORD i = 0;
+ str[0] = '[';
+ str[1] = 'H';
+ str[2] = ']';
+ str[3] = '[';
+ str[4] = 'L';
+ str[5] = ']';
+ str[6] = '=';
+
+ for(i = 0; i < highLength; i++) {
+ str [7 + i] = high[i];
+ }
+ str [7 + highLength] =L',';
+ for(i = 0; i < lowLength;i++) {
+ str [8 + highLength + i] = low[i];
+ }
+ str [8 + highLength + lowLength] = '\0';
+ FREE(high);
+ FREE(low);
+ return str;
+ }
+}
+WCHAR * int64ttoWCHAR(int64t*value) {
+ if(value->High==0) {
+ return DWORDtoWCHAR(value->Low);
+ } else {
+ WCHAR * high = DWORDtoWCHAR(value->High);
+ WCHAR * low = DWORDtoWCHAR(value->Low);
+ DWORD highLength = getLengthW(high);
+ DWORD lowLength = getLengthW(low);
+
+ WCHAR * str = newpWCHAR(highLength + lowLength + 9);
+ DWORD i = 0;
+ str[0] = L'[';
+ str[1] = L'H';
+ str[2] = L']';
+ str[3] = L'[';
+ str[4] = L'L';
+ str[5] = L']';
+ str[6] = L'=';
+
+ for(i = 0; i < highLength;i++) {
+ str [7 + i] = high[i];
+ }
+ str [7 + highLength] = L',';
+ for(i = 0; i < lowLength;i++) {
+ str [8 + highLength + i] = low[i];
+ }
+ str [8 + highLength + lowLength] = L'\0';
+ FREE(high);
+ FREE(low);
+ return str;
+ }
+}
+
+void freeStringList(StringListEntry **ss) {
+ while ( (*ss) !=NULL) {
+ StringListEntry * tmp = (*ss)->next;
+ FREE((*ss)->string);
+ FREE((*ss));
+ * ss = tmp;
+ }
+}
+
+DWORD inList(StringListEntry * top, WCHAR * str) {
+ StringListEntry * tmp = top;
+ while(tmp!=NULL) {
+ if(lstrcmpW(tmp->string, str)==0) {
+ return 1;
+ }
+ tmp = tmp->next;
+ }
+ return 0;
+}
+
+StringListEntry * addStringToList(StringListEntry * top, WCHAR * str) {
+ StringListEntry * ss = (StringListEntry*) LocalAlloc(LPTR,sizeof(StringListEntry));
+ ss->string = appendStringW(NULL, str);
+ ss->next = top;
+ return ss;
+}
+
+
+DWORD getLineSeparatorNumber(char *str) {
+ DWORD result = 0;
+ char *ptr = str;
+ if(ptr!=NULL) {
+ while((ptr = searchA(ptr, "\n"))!=NULL) {
+ ptr++;
+ result++;
+ if(ptr==NULL) break;
+ }
+ }
+ return result;
+}
+
+char *toCharN(const WCHAR * string, DWORD n) {
+ DWORD len = 0;
+ DWORD length = 0;
+ char * str = NULL;
+ if(string==NULL) return NULL;
+ //static DWORD excludeCodepages [] = { 50220, 50221, 50222, 50225, 50227, 50229, 52936, 54936, 57002, 57003, 57004, 57005, 57006, 57007, 57008, 57009, 57010, 57011, 65000, 42};
+ //int symbols = 0;
+ len = getLengthW(string);
+ if(n<len) len = n;
+ length = WideCharToMultiByte(CP_ACP, 0, string, len, NULL, 0, 0, NULL);
+ str = newpChar(length+1);
+ WideCharToMultiByte(CP_ACP, 0, string, len, str, length, 0, NULL);
+ return str;
+}
+
+char * toChar(const WCHAR * string) {
+ return toCharN(string, getLengthW(string));
+}
+
+WCHAR *createWCHAR(SizedString * sz) {
+ char * str = sz->bytes;
+ DWORD len = sz->length;
+ int unicodeFlags;
+ DWORD i;
+ char * string = NULL;
+ char * ptr = NULL;
+ WCHAR * wstr = NULL;
+ if(str==NULL) return NULL;
+ //static DWORD excludeCodepages [] = { 50220, 50221, 50222, 50225, 50227, 50229, 52936, 54936, 57002, 57003, 57004, 57005, 57006, 57007, 57008, 57009, 57010, 57011, 65000, 42};
+
+ string = appendStringN(NULL, 0 , str, len);
+ ptr = string;
+ unicodeFlags = -1 ;
+ if(len>=2) {
+ BOOL hasBOM = (*ptr == '\xFF' && *(ptr+1) == '\xFE');
+ BOOL hasReverseBOM = (*ptr == '\xFE' && *(ptr+1) == '\xFF');
+
+ if (IsTextUnicode(string, len, &unicodeFlags) || hasBOM || hasReverseBOM) {
+ //text is unicode
+ len-= 2;
+ ptr+= 2;
+ if (unicodeFlags & IS_TEXT_UNICODE_REVERSE_SIGNATURE || hasReverseBOM) {
+ //we need to change bytes order
+ char c;
+ for (i = 0 ; i < len/2 ; i++) {
+ c = ptr [2 * i] ;
+ ptr [2 * i] = ptr [2 * i + 1] ;
+ ptr [2 * i + 1] = c;
+ }
+ }
+ }
+
+ }
+ wstr = newpWCHAR(len/2+1);
+
+ for(i=0;i<len/2;i++) {
+ ptr[2*i] = (ptr[2*i]) & 0xFF;
+ ptr[2*i+1] = (ptr[2*i+1])& 0xFF;
+ wstr[i] = ((unsigned char) ptr[2*i]) + (((unsigned char)ptr[2*i+1]) << 8);
+ }
+
+ FREE(string);
+ return wstr;
+}
+WCHAR *toWCHARn(char * str, DWORD n) {
+ DWORD len = 0;
+ DWORD length = 0;
+ WCHAR * wstr = NULL;
+ if(str==NULL) return NULL;
+ //static DWORD excludeCodepages [] = { 50220, 50221, 50222, 50225, 50227, 50229, 52936, 54936, 57002, 57003, 57004, 57005, 57006, 57007, 57008, 57009, 57010, 57011, 65000, 42};
+ len = getLengthA(str);
+ if(n<len) len = n;
+ length = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
+ wstr = newpWCHAR(length+1);
+ MultiByteToWideChar(CP_ACP, 0, str, len, wstr, length);
+ return wstr;
+}
+
+WCHAR * toWCHAR( char *string) {
+ return toWCHARn(string, getLengthA(string));
+}
+
+SizedString * createSizedString() {
+ SizedString * s = (SizedString*)LocalAlloc(LPTR,sizeof(SizedString));
+ s->bytes = NULL;
+ s->length = 0;
+ return s;
+}
+
+void freeSizedString(SizedString ** s) {
+ if(*s!=NULL) {
+ FREE((*s)->bytes);
+ FREE((*s));
+ *s = NULL;
+ }
+}
+
+
+WCHAR * getLocaleName() {
+ LANGID langID = LANGIDFROMLCID(GetUserDefaultLCID());
+ LCID localeID = MAKELCID(langID, SORT_DEFAULT);
+ const DWORD MAX_LENGTH = 512;
+ WCHAR * lang = newpWCHAR(MAX_LENGTH);
+ WCHAR * country = newpWCHAR(MAX_LENGTH);
+ WCHAR * locale = NULL;
+ GetLocaleInfoW(localeID, LOCALE_SISO639LANGNAME, lang, MAX_LENGTH);
+ GetLocaleInfoW(localeID, LOCALE_SISO3166CTRYNAME, country, MAX_LENGTH);
+ locale = appendStringW(appendStringW(appendStringW(NULL, lang), L"_"), country);
+ FREE(country);
+ FREE(lang);
+ return locale;
+}
+
+WCHAR * newpWCHAR(DWORD length) {
+ WCHAR * res = (WCHAR*) LocalAlloc(LPTR,sizeof(WCHAR) * length);
+ ZERO(res, length * sizeof(WCHAR));
+ return res;
+}
+WCHAR ** newppWCHAR(DWORD length) {
+ return (WCHAR**) LocalAlloc(LPTR,sizeof(WCHAR *) * length);
+}
+
+
+char * newpChar(DWORD length) {
+ char * res = (char*) LocalAlloc(LPTR,sizeof(char) * length);
+ ZERO(res, length * sizeof(char));
+ return res;
+}
+
+char ** newppChar(DWORD length) {
+ return (char**) LocalAlloc(LPTR,sizeof(char*) * length);
+}
+
+int compare(int64t * size, DWORD value) {
+ if (size->High > 0) return 1;
+
+ if (size->Low > value)
+ return 1;
+ else if(size->Low == value)
+ return 0;
+ else //if(size->Low < value)
+ return -1;
+}
+int compareInt64t(int64t * a1, int64t * a2) {
+ if (a1->High > a2->High) {
+ return 1;
+ } else if(a1->High == a2->High) {
+ if (a1->Low > a2->Low) {
+ return 1;
+ } else if(a1->Low == a2->Low) {
+ return 0;
+ }
+ }
+ return -1;
+}
+
+void plus(int64t * size, DWORD value) {
+ if(value!=0) {
+ if((MAXDWORD - size->Low) >= (value - 1)) {
+ size->Low = size->Low + value;
+ } else {
+ size->High = size->High + 1;
+ size->Low = value - (MAXDWORD - size->Low) - 1;
+ }
+ }
+}
+void multiply(int64t * size, DWORD value) {
+ if(value==0) {
+ size->Low = 0;
+ size->High = 0;
+ } else {
+ DWORD i = 0;
+ DWORD low = size->Low;
+ DWORD high = size->High;
+ size->High = 0;
+ for(; i < value - 1 ; i++) {
+ plus(size, low);
+ }
+ size->High += high * value;
+ }
+}
+
+void minus(int64t * size, DWORD value) {
+ if(value!=0) {
+ if(size->Low < value) {
+ size->High = size->High -1;
+ size->Low = size->Low + (MAXDWORD - value) + 1;
+ } else {
+ size->Low = size->Low - value;
+ }}
+}
+int64t * newint64_t(DWORD low, DWORD high) {
+ int64t * res = (int64t *) LocalAlloc(LPTR,sizeof(int64t));
+ res->Low = low;
+ res->High = high;
+ return res;
+}
+WCHAR * getErrorDescription(DWORD dw) {
+ WCHAR * lpMsgBuf;
+ WCHAR * lpDisplayBuf = NULL;
+ WCHAR * res = DWORDtoWCHAR(dw);
+
+ FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &lpMsgBuf, 0, NULL );
+
+ lpDisplayBuf = appendStringW(lpDisplayBuf, L"Error code (");
+ lpDisplayBuf = appendStringW(lpDisplayBuf, res);
+ lpDisplayBuf = appendStringW(lpDisplayBuf, L"): ");
+ lpDisplayBuf = appendStringW(lpDisplayBuf, lpMsgBuf);
+
+ FREE(lpMsgBuf);
+ FREE(res);
+
+ return lpDisplayBuf;
+
+}
+
+WCHAR * formatMessageW(const WCHAR* message, const DWORD varArgsNumber, ...) {
+ DWORD totalLength=getLengthW(message);
+ DWORD counter=0;
+ WCHAR * result = NULL;
+
+ va_list ap;
+ va_start(ap, varArgsNumber);
+
+ while((counter++)<varArgsNumber) {
+ WCHAR * arg = va_arg( ap, WCHAR * );
+ totalLength+=getLengthW(arg);
+ }
+ va_end(ap);
+
+ result = newpWCHAR(totalLength + 1);
+ va_start(ap, varArgsNumber);
+ wvsprintfW(result, message, ap);
+ va_end(ap);
+ return result;
+}
+
+DWORD isOK(LauncherProperties * props) {
+ return (props->status == ERROR_OK);
+}
diff --git a/src/main/cpp/launcher/windows/src/StringUtils.h b/src/main/cpp/launcher/windows/src/StringUtils.h
new file mode 100644
index 0000000..9cf775c
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/StringUtils.h
@@ -0,0 +1,149 @@
+/*
+ * 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 _StringUtils_H
+#define _StringUtils_H
+
+#include <windows.h>
+#include <stdarg.h>
+#include "Types.h"
+#include "Errors.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char * JVM_NOT_FOUND_PROP;
+extern const char * JVM_USER_DEFINED_ERROR_PROP;
+extern const char * JVM_UNSUPPORTED_VERSION_PROP;
+extern const char * NOT_ENOUGH_FREE_SPACE_PROP;
+extern const char * CANT_CREATE_TEMP_DIR_PROP;
+extern const char * INTEGRITY_ERROR_PROP;
+extern const char * OUTPUT_ERROR_PROP;
+extern const char * JAVA_PROCESS_ERROR_PROP;
+extern const char * EXTERNAL_RESOURE_LACK_PROP;
+extern const char * BUNDLED_JVM_EXTRACT_ERROR_PROP;
+extern const char * BUNDLED_JVM_VERIFY_ERROR_PROP;
+extern const char * ARG_OUTPUT_PROPERTY;
+extern const char * ARG_JAVA_PROP;
+extern const char * ARG_DEBUG_PROP;
+extern const char * ARG_TMP_PROP;
+extern const char * ARG_CPA_PROP;
+extern const char * ARG_CPP_PROP;
+extern const char * ARG_EXTRACT_PROP;
+extern const char * ARG_DISABLE_SPACE_CHECK;
+extern const char * ARG_LOCALE_PROP;
+extern const char * ARG_SILENT_PROP;
+extern const char * ARG_HELP_PROP;
+extern const char * MSG_CREATE_TMPDIR;
+extern const char * MSG_EXTRACT_DATA;
+extern const char * MSG_JVM_SEARCH;
+extern const char * MSG_SET_OPTIONS;
+extern const char * MSG_RUNNING;
+extern const char * MSG_TITLE;
+extern const char * MSG_MESSAGEBOX_TITLE;
+extern const char * MSG_PROGRESS_TITLE;
+extern const char * EXIT_BUTTON_PROP;
+extern const char * MAIN_WINDOW_TITLE;
+
+#define FREE(x) { \
+ if((x)!=NULL) {\
+ LocalFree(x); \
+ (x)=NULL;\
+ }\
+}
+
+
+#ifdef _MSC_VER
+#define ZERO(x,y) SecureZeroMemory((x),(y));
+#else
+#define ZERO(x,y) ZeroMemory((x),(y));
+#endif
+
+
+
+
+
+ void freeI18NMessages(LauncherProperties * props);
+
+ void getI18nPropertyTitleDetail(LauncherProperties * props, const char * name, WCHAR ** title, WCHAR ** detail);
+ const WCHAR * getI18nProperty(LauncherProperties * props, const char * name);
+ WCHAR * getDefaultString(const char *name);
+
+ WCHAR * addString(WCHAR * initial, WCHAR *addString, long number, WCHAR * totalWCHARs, WCHAR * capacity);
+ char * appendStringN(char * initial, DWORD initialLength, const char * addString, DWORD addStringLength);
+ WCHAR * appendStringNW(WCHAR * initial, DWORD initialLength, const WCHAR * addString, DWORD addStringLength);
+ char * appendString(char * initial, const char * addString);
+ WCHAR * appendStringW(WCHAR * initial, const WCHAR * addString);
+ WCHAR * escapeString(const WCHAR * string);
+
+ void freeStringList(StringListEntry **s);
+ StringListEntry * addStringToList(StringListEntry * top, WCHAR * str);
+ DWORD inList(StringListEntry * top, WCHAR * str);
+
+ char *toChar(const WCHAR * string);
+ char *toCharN(const WCHAR * string, DWORD length);
+ WCHAR * toWCHAR(char * string);
+ WCHAR * toWCHARn(char * string, DWORD length);
+
+ WCHAR *createWCHAR(SizedString * sz);
+
+ SizedString * createSizedString();
+ char * int64ttoCHAR(int64t*);
+ WCHAR * int64ttoWCHAR(int64t*);
+ char * DWORDtoCHAR(DWORD);
+ char * DWORDtoCHARN(DWORD,int);
+
+ WCHAR * DWORDtoWCHAR(DWORD);
+ WCHAR * DWORDtoWCHARN(DWORD,int);
+
+ char * long2char(long value);
+ char * long2charN(long value,int fillZeros);
+
+ char * word2char(WORD value);
+ char * word2charN(WORD value,int fillZeros);
+
+ void freeSizedString(SizedString ** s);
+
+ WCHAR * getLocaleName();
+
+ WCHAR * newpWCHAR(DWORD length);
+ char * newpChar(DWORD length);
+ WCHAR * searchW( const WCHAR * wcs1, const WCHAR * wcs2);
+ char * searchA(const char* str1, const char * str2);
+
+ WCHAR ** newppWCHAR(DWORD length);
+ char ** newppChar(DWORD length);
+ int64t * newint64_t(DWORD low, DWORD high);
+ int compare(int64t * size, DWORD value);
+ int compareInt64t(int64t * a1, int64t * a2);
+ void plus(int64t * size, DWORD value);
+ void multiply(int64t * size, DWORD value);
+ void minus(int64t * size, DWORD value);
+ DWORD getLineSeparatorNumber(char *str);
+ DWORD getLengthA(const char * message);
+ DWORD getLengthW(const WCHAR * message);
+
+ WCHAR * getErrorDescription(DWORD dw);
+ WCHAR * formatMessageW(const WCHAR* message, const DWORD varArgsNumber, ...);
+ DWORD isOK(LauncherProperties * props);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _StringUtils_H */
diff --git a/src/main/cpp/launcher/windows/src/SystemUtils.c b/src/main/cpp/launcher/windows/src/SystemUtils.c
new file mode 100644
index 0000000..c8b423e
--- /dev/null
+++ b/src/main/cpp/launcher/windows/src/SystemUtils.c
@@ -0,0 +1,100 @@
+/*
+ * 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 <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "SystemUtils.h"
+
+BOOL IsWow64 = FALSE;
+
+void getOSVersion(DWORD *id, DWORD *major, DWORD *minor, DWORD *productType) {
+ OSVERSIONINFOEX ver;
+ ver.dwOSVersionInfoSize = sizeof(ver);
+ GetVersionEx((OSVERSIONINFO *) &ver);
+ *id = ver.dwPlatformId;
+ *major = ver.dwMajorVersion;
+ *minor = ver.dwMinorVersion;
+ *productType = ver.wProductType;
+ return;
+}
+
+DWORD is9x() {
+ DWORD id, major, minor, type;
+ getOSVersion(& id, & major, & minor, & type);
+ return (id == VER_PLATFORM_WIN32_WINDOWS) ? 1 : 0;
+}
+DWORD isNT() {
+ DWORD id, major, minor, type;
+ getOSVersion(& id, & major, & minor, & type);
+ return (id == VER_PLATFORM_WIN32_NT && major == 4 && minor == 0) ? 1 : 0;
+}