aboutsummaryrefslogtreecommitdiff
path: root/find_java
diff options
context:
space:
mode:
Diffstat (limited to 'find_java')
-rw-r--r--find_java/.gitignore6
-rw-r--r--find_java/NOTICE190
-rw-r--r--find_java/build.gradle47
-rwxr-xr-xfind_java/find_java.bat68
-rwxr-xr-xfind_java/find_java.exe.manifest33
-rwxr-xr-xfind_java/find_java.sln56
-rw-r--r--find_java/find_java_exe.vcxproj174
-rw-r--r--find_java/find_java_exe.vcxproj.filters36
-rw-r--r--find_java/find_java_lib.vcxproj135
-rw-r--r--find_java/find_java_lib.vcxproj.filters33
-rw-r--r--find_java/images/android_icon.icobin0 -> 300318 bytes
-rw-r--r--find_java/images/android_icon.rc2
-rwxr-xr-xfind_java/src/source/find_java.h45
-rw-r--r--find_java/src/source/find_java_exe.cpp237
-rwxr-xr-xfind_java/src/source/find_java_lib.cpp573
-rwxr-xr-xfind_java/src/source/utils.cpp202
-rwxr-xr-xfind_java/src/source/utils.h370
17 files changed, 2207 insertions, 0 deletions
diff --git a/find_java/.gitignore b/find_java/.gitignore
new file mode 100644
index 000000000..d15bd0cac
--- /dev/null
+++ b/find_java/.gitignore
@@ -0,0 +1,6 @@
+images/find_java_icon.o
+*.ncb
+*.suo
+*.user
+Debug
+Release
diff --git a/find_java/NOTICE b/find_java/NOTICE
new file mode 100644
index 000000000..7317ae2a7
--- /dev/null
+++ b/find_java/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2011, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/find_java/build.gradle b/find_java/build.gradle
new file mode 100644
index 000000000..b359e0a17
--- /dev/null
+++ b/find_java/build.gradle
@@ -0,0 +1,47 @@
+apply plugin: 'cpp'
+apply plugin: 'sdk-files'
+apply plugin: 'windows-setup'
+
+executables {
+ findJava {}
+}
+
+sources {
+ findJava {
+ cpp {
+ source {
+ srcDir "src/source"
+ include "**/*.cpp"
+ }
+ }
+ }
+}
+
+sdk {
+ windows {
+ item( { getExeName("windows32FindJavaExecutable") } ) {
+ into 'lib'
+ name 'find_java32.exe'
+ builtBy 'windows32FindJavaExecutable'
+ notice 'NOTICE'
+ }
+ item( { getExeName("windows64FindJavaExecutable") } ) {
+ into 'lib'
+ name 'find_java64.exe'
+ builtBy 'windows64FindJavaExecutable'
+ notice 'NOTICE'
+ }
+ item('find_java.bat') {
+ into 'lib'
+ notice 'NOTICE'
+ }
+ }
+}
+
+def getExeName(String name) {
+ // binaries will return a set of binaries
+ def binaries = executables.findJava.binaries.matching { it.name == name }
+ // calling .exeFile on the set returns an array with the result from each item in the set...
+ return binaries.executableFile.get(0)
+}
+
diff --git a/find_java/find_java.bat b/find_java/find_java.bat
new file mode 100755
index 000000000..01367c1d8
--- /dev/null
+++ b/find_java/find_java.bat
@@ -0,0 +1,68 @@
+@echo off
+rem Copyright (C) 2007 The Android Open Source Project
+rem
+rem Licensed under the Apache License, Version 2.0 (the "License");
+rem you may not use this file except in compliance with the License.
+rem You may obtain a copy of the License at
+rem
+rem http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+
+rem This script is called by the other batch files to find a suitable Java.exe
+rem to use. The script changes the "java_exe" env variable. The variable
+rem is left unset if Java.exe was not found.
+
+rem Useful links:
+rem Command-line reference:
+rem http://technet.microsoft.com/en-us/library/bb490890.aspx
+
+rem Query whether this system is 32-bit or 64-bit
+rem Note: Some users report that reg.exe is missing on their machine, so we
+rem check for that first, as we'd like to use it if we can.
+set sys_32=%SYSTEMROOT%\system32
+if exist %sys_32%\reg.exe (
+ rem This first-pass solution returns the correct architecture even if you
+ rem call this .bat file from a 32-bit process.
+ rem See also: http://stackoverflow.com/a/24590583/1299302
+ %sys_32%\reg query "HKLM\Hardware\Description\System\CentralProcessor\0"^
+ | %sys_32%\find /i "x86" > NUL && set arch_ext=32|| set arch_ext=64
+) else (
+ rem This fallback approach is simpler, but may misreport your architecture as
+ rem 32-bit if running from a 32-bit process. Still, it should serve to help
+ rem our users without reg.exe, at least.
+ if "%PROCESSOR_ARCHITECTURE%" == "x86" (set arch_ext=32) else (set arch_ext=64)
+)
+
+rem Check we have a valid Java.exe in the path. The return code will
+rem be 0 if the command worked or 1 if the exec failed (program not found).
+for /f "delims=" %%a in ('"%~dps0\find_java%arch_ext%.exe" -s') do set java_exe=%%a
+if not defined java_exe goto :CheckFailed
+
+:SearchJavaW
+rem Check if we can find a javaw.exe at the same location than java.exe.
+rem If that doesn't work, just fall back on the java.exe we just found.
+for /f "delims=" %%a in ('"%~dps0\find_java%arch_ext%.exe" -s -w') do set javaw_exe=%%a
+if not exist "%javaw_exe%" set javaw_exe=%java_exe%
+goto :EOF
+
+
+:CheckFailed
+echo.
+echo ERROR: No suitable Java found. In order to properly use the Android Developer
+echo Tools, you need a suitable version of Java JDK installed on your system.
+echo We recommend that you install the JDK version of JavaSE, available here:
+echo http://www.oracle.com/technetwork/java/javase/downloads
+echo.
+echo If you already have Java installed, you can define the JAVA_HOME environment
+echo variable in Control Panel / System / Avanced System Settings to point to the
+echo JDK folder.
+echo.
+echo You can find the complete Android SDK requirements here:
+echo http://developer.android.com/sdk/requirements.html
+echo.
+goto :EOF
diff --git a/find_java/find_java.exe.manifest b/find_java/find_java.exe.manifest
new file mode 100755
index 000000000..d949f07e9
--- /dev/null
+++ b/find_java/find_java.exe.manifest
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<!--
+ For details on the Assembly Manifest, please look here:
+ http://msdn.microsoft.com/en-us/library/aa374191(VS.85).aspx
+-->
+
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+
+ <application>
+ <!--The ID below indicates application support for Windows Vista -->
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
+ <!--The ID below indicates application support for Windows 7 -->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
+ </application>
+
+ <assemblyIdentity version="1.0.0.0"
+ processorArchitecture="x86"
+ name="Android.SDK.FindJava"
+ type="win32"
+ />
+
+ <description>Utility to find java.exe on the local system.</description>
+
+ <!-- Identify the application security requirements. -->
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false" />
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+</assembly>
diff --git a/find_java/find_java.sln b/find_java/find_java.sln
new file mode 100755
index 000000000..510ab9bbc
--- /dev/null
+++ b/find_java/find_java.sln
@@ -0,0 +1,56 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FindJavaLib", "find_java_lib.vcxproj", "{D194C98B-3FA4-4DAB-908A-16C03C15EC35}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FindJavaExe", "find_java_exe.vcxproj", "{F116176E-AE3E-42E6-9249-663F49FAAFAE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FindLock", "..\find_lock\find_lock_exe.vcxproj", "{42701EC1-6226-47FD-8817-57A3DEC7A1E2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdklauncher", "..\sdklauncher\sdklauncher.vcxproj", "{331EADA4-DC19-429D-AAD0-5B9632B4CBC1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|Win64 = Debug|Win64
+ Release|Win32 = Release|Win32
+ Release|Win64 = Release|Win64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D194C98B-3FA4-4DAB-908A-16C03C15EC35}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D194C98B-3FA4-4DAB-908A-16C03C15EC35}.Debug|Win32.Build.0 = Debug|Win32
+ {D194C98B-3FA4-4DAB-908A-16C03C15EC35}.Debug|Win64.ActiveCfg = Debug|x64
+ {D194C98B-3FA4-4DAB-908A-16C03C15EC35}.Debug|Win64.Build.0 = Debug|x64
+ {D194C98B-3FA4-4DAB-908A-16C03C15EC35}.Release|Win32.ActiveCfg = Release|Win32
+ {D194C98B-3FA4-4DAB-908A-16C03C15EC35}.Release|Win32.Build.0 = Release|Win32
+ {D194C98B-3FA4-4DAB-908A-16C03C15EC35}.Release|Win64.ActiveCfg = Release|x64
+ {D194C98B-3FA4-4DAB-908A-16C03C15EC35}.Release|Win64.Build.0 = Release|x64
+ {F116176E-AE3E-42E6-9249-663F49FAAFAE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F116176E-AE3E-42E6-9249-663F49FAAFAE}.Debug|Win32.Build.0 = Debug|Win32
+ {F116176E-AE3E-42E6-9249-663F49FAAFAE}.Debug|Win64.ActiveCfg = Debug|x64
+ {F116176E-AE3E-42E6-9249-663F49FAAFAE}.Debug|Win64.Build.0 = Debug|x64
+ {F116176E-AE3E-42E6-9249-663F49FAAFAE}.Release|Win32.ActiveCfg = Release|Win32
+ {F116176E-AE3E-42E6-9249-663F49FAAFAE}.Release|Win32.Build.0 = Release|Win32
+ {F116176E-AE3E-42E6-9249-663F49FAAFAE}.Release|Win64.ActiveCfg = Release|x64
+ {F116176E-AE3E-42E6-9249-663F49FAAFAE}.Release|Win64.Build.0 = Release|x64
+ {42701EC1-6226-47FD-8817-57A3DEC7A1E2}.Debug|Win32.ActiveCfg = Debug|Win32
+ {42701EC1-6226-47FD-8817-57A3DEC7A1E2}.Debug|Win32.Build.0 = Debug|Win32
+ {42701EC1-6226-47FD-8817-57A3DEC7A1E2}.Debug|Win64.ActiveCfg = Debug|x64
+ {42701EC1-6226-47FD-8817-57A3DEC7A1E2}.Debug|Win64.Build.0 = Debug|x64
+ {42701EC1-6226-47FD-8817-57A3DEC7A1E2}.Release|Win32.ActiveCfg = Release|Win32
+ {42701EC1-6226-47FD-8817-57A3DEC7A1E2}.Release|Win32.Build.0 = Release|Win32
+ {42701EC1-6226-47FD-8817-57A3DEC7A1E2}.Release|Win64.ActiveCfg = Release|x64
+ {42701EC1-6226-47FD-8817-57A3DEC7A1E2}.Release|Win64.Build.0 = Release|x64
+ {331EADA4-DC19-429D-AAD0-5B9632B4CBC1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {331EADA4-DC19-429D-AAD0-5B9632B4CBC1}.Debug|Win32.Build.0 = Debug|Win32
+ {331EADA4-DC19-429D-AAD0-5B9632B4CBC1}.Debug|Win64.ActiveCfg = Debug|x64
+ {331EADA4-DC19-429D-AAD0-5B9632B4CBC1}.Debug|Win64.Build.0 = Debug|x64
+ {331EADA4-DC19-429D-AAD0-5B9632B4CBC1}.Release|Win32.ActiveCfg = Release|Win32
+ {331EADA4-DC19-429D-AAD0-5B9632B4CBC1}.Release|Win32.Build.0 = Release|Win32
+ {331EADA4-DC19-429D-AAD0-5B9632B4CBC1}.Release|Win64.ActiveCfg = Release|x64
+ {331EADA4-DC19-429D-AAD0-5B9632B4CBC1}.Release|Win64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/find_java/find_java_exe.vcxproj b/find_java/find_java_exe.vcxproj
new file mode 100644
index 000000000..67ebf7120
--- /dev/null
+++ b/find_java/find_java_exe.vcxproj
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>FindJavaExe</ProjectName>
+ <ProjectGuid>{F116176E-AE3E-42E6-9249-663F49FAAFAE}</ProjectGuid>
+ <RootNamespace>FindJavaExe</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <UseOfMfc>Static</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <UseOfMfc>Static</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <UseOfMfc>Static</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <UseOfMfc>Static</UseOfMfc>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\..\out\host\windows-x86\$(Configuration)\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\..\out\host\windows-x64\$(Configuration)\$(ProjectName)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\..\out\host\windows-x86\$(Configuration)\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\..\out\host\windows-x64\$(Configuration)\$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\..\out\host\windows-x86\$(Configuration)\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\..\out\host\windows-x64\$(Configuration)\$(ProjectName)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\..\out\host\windows-x86\$(Configuration)\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\..\out\host\windows-x64\$(Configuration)\$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">find_java64</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">find_java64</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)32</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">find_java32</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ <AdditionalDependencies>user32.lib;advapi32.lib;shell32.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>user32.lib;advapi32.lib;shell32.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ <AdditionalDependencies>user32.lib;advapi32.lib;shell32.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <AdditionalDependencies>user32.lib;advapi32.lib;shell32.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="src\source\find_java_exe.cpp" />
+ <ClCompile Include="src\source\find_java_lib.cpp" />
+ <ClCompile Include="src\source\utils.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\source\find_java.h" />
+ <ClInclude Include="src\source\utils.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/find_java/find_java_exe.vcxproj.filters b/find_java/find_java_exe.vcxproj.filters
new file mode 100644
index 000000000..7cc0be161
--- /dev/null
+++ b/find_java/find_java_exe.vcxproj.filters
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="src\source\find_java_exe.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\source\utils.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\source\find_java_lib.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\source\find_java.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\source\utils.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/find_java/find_java_lib.vcxproj b/find_java/find_java_lib.vcxproj
new file mode 100644
index 000000000..7ca34990f
--- /dev/null
+++ b/find_java/find_java_lib.vcxproj
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>FindJavaLib</ProjectName>
+ <ProjectGuid>{D194C98B-3FA4-4DAB-908A-16C03C15EC35}</ProjectGuid>
+ <RootNamespace>FindJavaLib</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\..\out\host\windows-x86\$(Configuration)\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\..\out\host\windows-x64\$(Configuration)\$(ProjectName)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\..\out\host\windows-x86\$(Configuration)\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\..\out\host\windows-x64\$(Configuration)\$(ProjectName)\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\..\out\host\windows-x86\$(Configuration)\$(ProjectName)\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\..\out\host\windows-x64\$(Configuration)\$(ProjectName)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\..\out\host\windows-x86\$(Configuration)\$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\..\out\host\windows-x64\$(Configuration)\$(ProjectName)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="src\source\find_java_lib.cpp" />
+ <ClCompile Include="src\source\utils.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\source\find_java.h" />
+ <ClInclude Include="src\source\utils.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/find_java/find_java_lib.vcxproj.filters b/find_java/find_java_lib.vcxproj.filters
new file mode 100644
index 000000000..4bc439b7a
--- /dev/null
+++ b/find_java/find_java_lib.vcxproj.filters
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="src\source\find_java_lib.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\source\utils.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\source\find_java.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\source\utils.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/find_java/images/android_icon.ico b/find_java/images/android_icon.ico
new file mode 100644
index 000000000..bd2517901
--- /dev/null
+++ b/find_java/images/android_icon.ico
Binary files differ
diff --git a/find_java/images/android_icon.rc b/find_java/images/android_icon.rc
new file mode 100644
index 000000000..7ff37f23e
--- /dev/null
+++ b/find_java/images/android_icon.rc
@@ -0,0 +1,2 @@
+1 ICON "../images/android_icon.ico"
+1 RT_MANIFEST "../find_java.exe.manifest"
diff --git a/find_java/src/source/find_java.h b/find_java/src/source/find_java.h
new file mode 100755
index 000000000..49b5fd9f4
--- /dev/null
+++ b/find_java/src/source/find_java.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed 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 _H_FIND_JAVA
+#define _H_FIND_JAVA
+
+#ifdef _WIN32
+
+#include "utils.h"
+
+#define TO_JAVA_VERSION(major, minor) ((major) * 1000 + (minor))
+#define JAVA_MAJOR(version) ((version) / 1000)
+#define JAVA_MINOR(version) ((version) % 1000)
+
+// We currently search for a Java version for at least 1.6 by default
+#define MIN_JAVA_VERSION_MAJOR 1
+#define MIN_JAVA_VERSION_MINOR 6
+#define MIN_JAVA_VERSION TO_JAVA_VERSION(MIN_JAVA_VERSION_MAJOR, MIN_JAVA_VERSION_MINOR)
+
+int findJavaInPath(const CPath &path, CPath *outJavaPath, bool isJdk = false,
+ int minVersion = MIN_JAVA_VERSION);
+int findJavaInEnvPath(CPath *outJavaPath, bool isJdk = false,
+ int minVersion = MIN_JAVA_VERSION);
+int findJavaInRegistry(CPath *outJavaPath, bool isJdk = false,
+ int minVersion = MIN_JAVA_VERSION);
+int findJavaInProgramFiles(CPath *outJavaPath, bool isJdk = false,
+ int minVersion = MIN_JAVA_VERSION);
+
+bool getJavaVersion(CPath &javaPath, CString *outVersionStr, int *outVersionInt);
+
+#endif /* _WIN32 */
+#endif /* _H_FIND_JAVA */
diff --git a/find_java/src/source/find_java_exe.cpp b/find_java/src/source/find_java_exe.cpp
new file mode 100644
index 000000000..a8be377ef
--- /dev/null
+++ b/find_java/src/source/find_java_exe.cpp
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed 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.
+ */
+
+/*
+ * "find_java.exe", for Windows only.
+ * Tries to find a Java binary in a variety of places and prints the
+ * first one found on STDOUT and returns 0.
+ *
+ * If not found, returns error 1 with no message
+ * (unless ANDROID_SDKMAN_DEBUG or -d if set, in which case there's a message on STDERR).
+ *
+ * Implementation details:
+ * - We don't have access to ATL or MFC.
+ * - We don't want to pull in things like STL.
+ * - No Unicode/MBCS support for now.
+ *
+ * TODO for later version:
+ * - provide an env variable to let users override which version is being used.
+ * - if there's more than one java.exe found, enumerate them all.
+ * - and in that case take the one with the highest Java version number.
+ * - since that operation is expensive, do it only once and cache the result
+ * in a temp file. If the temp file is not found or the java binary no
+ * longer exists, re-run the enumaration.
+ */
+
+#ifdef _WIN32
+
+#include "utils.h"
+#include "find_java.h"
+#include <io.h>
+#include <fcntl.h>
+
+static int showHelpMessage() {
+ printf(
+ "Outputs the path of the first Java.exe found on the local system.\n"
+ "Returns code 0 when found, 1 when not found.\n"
+ "Options:\n"
+ "-h / -help : This help.\n"
+ "-t / -test : Internal test.\n"
+ "-e / -error : Print an error message to the console if Java.exe isn't found.\n"
+ "-j / -jdk : Only returns java.exe found in a JDK.\n"
+ "-s / -short : Print path in short DOS form.\n"
+ "-p / -path `dir` : A custom path to search first. Pass in JDK base dir if -j is set.\n"
+ "-w / -javaw : Search a matching javaw.exe; defaults to java.exe if not found.\n"
+ "-m / -minv # : Pass in a minimum version to use (default: 1.6).\n"
+ "-v / -version: Only prints the Java version found.\n"
+ );
+ return 2;
+}
+
+static void printError(const char *message) {
+
+ CString error;
+ error.setLastWin32Error(message);
+ printf(error.cstr());
+}
+
+static void testFindJava(bool isJdk, int minVersion) {
+
+ CPath javaPath("<not found>");
+ int v = findJavaInEnvPath(&javaPath, isJdk, minVersion);
+ printf(" findJavaInEnvPath: [%d] %s\n", v, javaPath.cstr());
+
+ javaPath.set("<not found>");
+ v = findJavaInRegistry(&javaPath, isJdk, minVersion);
+ printf(" findJavaInRegistry [%d] %s\n", v, javaPath.cstr());
+
+ javaPath.set("<not found>");
+ v = findJavaInProgramFiles(&javaPath, isJdk, minVersion);
+ printf(" findJavaInProgramFiles [%d] %s\n", v, javaPath.cstr());
+}
+
+static void testFindJava(int minVersion) {
+
+ printf("Searching for version %d.%d or newer...\n", JAVA_MAJOR(minVersion),
+ JAVA_MINOR(minVersion));
+
+ printf("\n");
+ printf("Searching for any java.exe:\n");
+ testFindJava(false, minVersion);
+
+ printf("\n");
+ printf("Searching for java.exe within a JDK:\n");
+ testFindJava(true, minVersion);
+}
+
+// Returns 0 on failure or a java version on success.
+int parseMinVersionArg(char* arg) {
+
+ int versionMajor = -1;
+ int versionMinor = -1;
+ if (sscanf(arg, "%d.%d", &versionMajor, &versionMinor) != 2) {
+ // -m arg is malformatted
+ return 0;
+ }
+ return TO_JAVA_VERSION(versionMajor, versionMinor);
+}
+
+int main(int argc, char* argv[]) {
+
+ gIsConsole = true; // tell utils to to print errors to stderr
+ gIsDebug = (getenv("ANDROID_SDKMAN_DEBUG") != NULL);
+ bool doShortPath = false;
+ bool doVersion = false;
+ bool doJavaW = false;
+ bool isJdk = false;
+ bool shouldPrintError = false;
+ int minVersion = MIN_JAVA_VERSION;
+ const char *customPathStr = NULL;
+
+ for (int i = 1; i < argc; i++) {
+ if (strncmp(argv[i], "-t", 2) == 0) {
+ testFindJava(minVersion);
+ return 0;
+
+ } else if (strncmp(argv[i], "-j", 2) == 0) {
+ isJdk = true;
+
+ } else if (strncmp(argv[i], "-e", 2) == 0) {
+ shouldPrintError = true;
+
+ } else if (strncmp(argv[i], "-p", 2) == 0) {
+ i++;
+ if (i == argc) {
+ return showHelpMessage();
+ }
+ customPathStr = argv[i];
+ } else if (strncmp(argv[i], "-d", 2) == 0) {
+ gIsDebug = true;
+
+ } else if (strncmp(argv[i], "-s", 2) == 0) {
+ doShortPath = true;
+
+ } else if (strncmp(argv[i], "-v", 2) == 0) {
+ doVersion = true;
+
+ } else if (strncmp(argv[i], "-m", 2) == 0) {
+ i++;
+ if (i == argc ||
+ ((minVersion = parseMinVersionArg(argv[i])) == 0)) {
+ return showHelpMessage();
+ }
+ }
+ else if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "-javaw") == 0) {
+ doJavaW = true;
+
+ }
+ else {
+ return showHelpMessage();
+ }
+ }
+
+ // Find the first suitable version of Java we can use.
+ CPath javaPath;
+
+ int version = 0;
+ if (customPathStr != NULL) {
+ CPath customPath(customPathStr);
+ version = findJavaInPath(customPath, &javaPath, isJdk, minVersion);
+ }
+ if (version == 0) {
+ version = findJavaInEnvPath(&javaPath, isJdk, minVersion);
+ }
+ if (version == 0) {
+ version = findJavaInRegistry(&javaPath, isJdk, minVersion);
+ }
+ if (version == 0) {
+ version = findJavaInProgramFiles(&javaPath, isJdk, minVersion);
+ }
+
+ if (version == 0) {
+ CString s;
+ s.setf("Failed to find Java %d.%d (or newer) on your system. ", JAVA_MAJOR(minVersion),
+ JAVA_MINOR(minVersion));
+
+ if (gIsDebug) {
+ fprintf(stderr, s.cstr());
+ }
+
+ if (shouldPrintError) {
+ printError(s.cstr());
+ }
+
+ return 1;
+ }
+ _ASSERT(!javaPath.isEmpty());
+
+ if (doShortPath) {
+ if (!javaPath.toShortPath(&javaPath)) {
+ CString s;
+ s.setf("Failed to convert path (%s) to a short DOS path. ", javaPath.cstr());
+ fprintf(stderr, s.cstr());
+
+ if (shouldPrintError) {
+ printError(s.cstr());
+ }
+
+ return 1;
+ }
+ }
+
+ if (doVersion) {
+ // Print version found. We already have the version as an integer
+ // so we don't need to run java -version a second time.
+ printf("%d.%d", JAVA_MAJOR(version), JAVA_MINOR(version));
+ return 0;
+ }
+
+ if (doJavaW) {
+ // Try to find a javaw.exe instead of java.exe at the same location.
+ CPath javawPath(javaPath);
+ javawPath.replaceName("java.exe", "javaw.exe");
+ // Only accept it if we can actually find the exec
+ if (javawPath.fileExists()) {
+ javaPath.set(javawPath.cstr());
+ }
+ }
+
+ // Print java.exe path found
+ printf(javaPath.cstr());
+ return 0;
+}
+
+#endif /* _WIN32 */
diff --git a/find_java/src/source/find_java_lib.cpp b/find_java/src/source/find_java_lib.cpp
new file mode 100755
index 000000000..fe50f8396
--- /dev/null
+++ b/find_java/src/source/find_java_lib.cpp
@@ -0,0 +1,573 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed 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.
+ */
+
+#ifdef _WIN32
+
+// Indicate we want at least all Windows Server 2003 (5.2) APIs.
+// Note: default is set by system/core/include/arch/windows/AndroidConfig.h to 0x0500
+// which is Win2K. However our minimum SDK tools requirement is Win XP (0x0501).
+// However we do need 0x0502 to get access to the WOW-64-32 constants for the
+// registry, except we'll need to be careful since they are not available on XP.
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0502
+// Indicate we want at least all IE 5 shell APIs
+#define _WIN32_IE 0x0500
+
+#include "find_java.h"
+#include <shlobj.h>
+#include <ctype.h>
+
+// Define some types missing in MingW
+#ifndef LSTATUS
+typedef LONG LSTATUS;
+#endif
+
+// Check to see if the application is running in 32-bit or 64-bit mode. In other words, this will
+// return false if you run a 32-bit build even on a 64-bit machine.
+static bool isApplication64() {
+ SYSTEM_INFO sysInfo;
+ GetSystemInfo(&sysInfo);
+
+ // Note: The constant name here is a bit misleading, as it actually covers all 64-bit processors
+ // and not just AMD.
+ // See also: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724958(v=vs.85).aspx
+ return (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64);
+}
+
+// Extract the first thing that looks like (digit.digit+).
+// Note: this will break when java reports a version with major > 9.
+// However it will reasonably cope with "1.10", if that ever happens.
+static bool extractJavaVersion(const char *start,
+ int length,
+ CString *outVersionStr,
+ int *outVersionInt) {
+ const char *end = start + length;
+ for (const char *c = start; c < end - 2; c++) {
+ if (isdigit(c[0]) &&
+ c[1] == '.' &&
+ isdigit(c[2])) {
+ const char *e = c+2;
+ while (isdigit(e[1])) {
+ e++;
+ }
+ if (outVersionStr != NULL) {
+ outVersionStr->set(c, e - c + 1);
+ }
+ if (outVersionInt != NULL) {
+ // add major * 1000, currently only 1 digit
+ int value = (*c - '0') * 1000;
+ // add minor
+ for (int m = 1; *e != '.'; e--, m *= 10) {
+ value += (*e - '0') * m;
+ }
+ *outVersionInt = value;
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+// Check if the passed in path is a path to a JDK
+static bool isJdkPath(const CPath &path) {
+
+ // If the files "bin/java.exe" and "lib/tools.jar" exist, we're probably a JDK.
+ CPath pathBin(path);
+ pathBin.addPath("bin");
+ pathBin.addPath("java.exe");
+
+ CPath pathTools(path);
+ pathTools.addPath("lib");
+ pathTools.addPath("tools.jar");
+
+ return (pathBin.fileExists() && pathTools.fileExists());
+}
+
+// Check whether we can find $PATH/java.exe.
+// inOutPath should be the directory where we're looking at.
+// In output, it will be the java path we tested.
+// Returns the java version integer found (e.g. 1006 for 1.6).
+// Return 0 in case of error.
+static int checkPath(CPath *inOutPath) {
+ inOutPath->addPath("java.exe");
+
+ int result = 0;
+ if (inOutPath->fileExists()) {
+ // Run java -version
+ // Reject the version if it's not at least our current minimum.
+ if (!getJavaVersion(*inOutPath, NULL /*versionStr*/, &result)) {
+ result = 0;
+ }
+ }
+
+ return result;
+}
+
+// Check whether we can find $PATH/bin/java.exe
+// Returns the Java version found (e.g. 1006 for 1.6) or 0 in case of error.
+static int checkBinPath(CPath *inOutPath) {
+ inOutPath->addPath("bin");
+ return checkPath(inOutPath);
+}
+
+// Test for the existence of java.exe in a custom path
+int findJavaInPath(const CPath &path, CPath *outJavaPath, bool isJdk, int minVersion) {
+ SetLastError(0);
+
+ int version = 0;
+ CPath temp(path);
+ if (!isJdk) {
+ version = checkPath(&temp);
+ }
+ else {
+ if (isJdkPath(temp)) {
+ version = checkBinPath(&temp);
+ }
+ }
+
+ if (version >= minVersion) {
+ if (gIsDebug) {
+ fprintf(stderr, "Java %d found in path: %s\n", version, temp.cstr());
+ }
+ *outJavaPath = temp;
+ return version;
+ }
+ return 0;
+}
+
+// Search java.exe in the environment
+int findJavaInEnvPath(CPath *outJavaPath, bool isJdk, int minVersion) {
+ SetLastError(0);
+
+ const char* envPath = getenv("JAVA_HOME");
+ if (envPath != NULL) {
+ CPath p(envPath);
+
+ if (!isJdk || isJdkPath(p)) {
+ int v = checkBinPath(&p);
+ if (v >= minVersion) {
+ if (gIsDebug) {
+ fprintf(stderr, "Java %d found via JAVA_HOME: %s\n", v, p.cstr());
+ }
+ *outJavaPath = p;
+ // As an optimization for runtime, if we find a suitable java
+ // version in JAVA_HOME we won't waste time looking at the PATH.
+ return v;
+ }
+ }
+ }
+
+ int currVersion = 0;
+ envPath = getenv("PATH");
+ if (!envPath) return currVersion;
+
+ // Otherwise look at the entries in the current path.
+ // If we find more than one, keep the one with the highest version.
+
+ CArray<CString> *paths = CString(envPath).split(';');
+ for(int i = 0; i < paths->size(); i++) {
+ CPath p((*paths)[i].cstr());
+
+ if (isJdk && !isJdkPath(p)) {
+ continue;
+ }
+
+ int v = checkPath(&p);
+ if (v >= minVersion && v > currVersion) {
+ if (gIsDebug) {
+ fprintf(stderr, "Java %d found via env PATH: %s\n", v, p.cstr());
+ }
+
+ currVersion = v;
+ *outJavaPath = p;
+ }
+ }
+
+ delete paths;
+ return currVersion;
+}
+
+// --------------
+
+static bool getRegValue(const char *keyPath,
+ const char *keyName,
+ REGSAM access,
+ CString *outValue) {
+ HKEY key;
+ LSTATUS status = RegOpenKeyExA(
+ HKEY_LOCAL_MACHINE, // hKey
+ keyPath, // lpSubKey
+ 0, // ulOptions
+ KEY_READ | access, // samDesired,
+ &key); // phkResult
+ if (status == ERROR_SUCCESS) {
+
+ LSTATUS ret = ERROR_MORE_DATA;
+ DWORD size = 4096; // MAX_PATH is 260, so 4 KB should be good enough
+ char* buffer = (char*) malloc(size);
+
+ while (ret == ERROR_MORE_DATA && size < (1<<16) /*64 KB*/) {
+ ret = RegQueryValueExA(
+ key, // hKey
+ keyName, // lpValueName
+ NULL, // lpReserved
+ NULL, // lpType
+ (LPBYTE) buffer, // lpData
+ &size); // lpcbData
+
+ if (ret == ERROR_MORE_DATA) {
+ size *= 2;
+ buffer = (char*) realloc(buffer, size);
+ } else {
+ buffer[size] = 0;
+ }
+ }
+
+ if (ret != ERROR_MORE_DATA) outValue->set(buffer);
+
+ free(buffer);
+ RegCloseKey(key);
+
+ return (ret != ERROR_MORE_DATA);
+ }
+
+ return false;
+}
+
+// Explore the registry to find a suitable version of Java.
+// Returns an int which is the version of Java found (e.g. 1006 for 1.6) and the
+// matching path in outJavaPath.
+// Returns 0 if nothing suitable was found.
+static int exploreJavaRegistry(const char *entry, REGSAM access, int minVersion,
+ CPath *outJavaPath) {
+
+ // Let's visit HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment [CurrentVersion]
+ CPath rootKey("SOFTWARE\\JavaSoft\\");
+ rootKey.addPath(entry);
+
+ int versionInt = 0;
+ CString currentVersion;
+ CPath subKey(rootKey);
+ if (getRegValue(subKey.cstr(), "CurrentVersion", access, &currentVersion)) {
+ // CurrentVersion should be something like "1.7".
+ // We want to read HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.7 [JavaHome]
+ subKey.addPath(currentVersion);
+ CPath javaHome;
+ if (getRegValue(subKey.cstr(), "JavaHome", access, &javaHome)) {
+ versionInt = checkBinPath(&javaHome);
+ if (versionInt >= 0) {
+ if (gIsDebug) {
+ fprintf(stderr,
+ "Java %d found via registry: %s\n",
+ versionInt, javaHome.cstr());
+ }
+ *outJavaPath = javaHome;
+ }
+ if (versionInt >= minVersion) {
+ // Heuristic: if the current version is good enough, stop here
+ return versionInt;
+ }
+ }
+ }
+
+ // Try again, but this time look at all the versions available
+ HKEY javaHomeKey;
+ LSTATUS status = RegOpenKeyExA(
+ HKEY_LOCAL_MACHINE, // hKey
+ "SOFTWARE\\JavaSoft", // lpSubKey
+ 0, // ulOptions
+ KEY_READ | access, // samDesired
+ &javaHomeKey); // phkResult
+ if (status == ERROR_SUCCESS) {
+ char name[256];
+ DWORD index = 0;
+ CPath javaHome;
+ for (LONG result = ERROR_SUCCESS; result == ERROR_SUCCESS; index++) {
+ DWORD nameLen = 255;
+ name[nameLen] = 0;
+ result = RegEnumKeyExA(
+ javaHomeKey, // hKey
+ index, // dwIndex
+ name, // lpName
+ &nameLen, // lpcName
+ NULL, // lpReserved
+ NULL, // lpClass
+ NULL, // lpcClass,
+ NULL); // lpftLastWriteTime
+ if (result == ERROR_SUCCESS && nameLen < 256) {
+ name[nameLen] = 0;
+ CPath subKey(rootKey);
+ subKey.addPath(name);
+
+ if (getRegValue(subKey.cstr(), "JavaHome", access, &javaHome)) {
+ int v = checkBinPath(&javaHome);
+ if (v > versionInt) {
+ if (gIsDebug) {
+ fprintf(stderr,
+ "Java %d found via registry: %s\n",
+ versionInt, javaHome.cstr());
+ }
+ *outJavaPath = javaHome;
+ versionInt = v;
+ }
+ }
+ }
+ }
+
+ RegCloseKey(javaHomeKey);
+ }
+
+ return 0;
+}
+
+static bool getMaxJavaInRegistry(const char *entry, REGSAM access, CPath *outJavaPath, int *inOutVersion) {
+ CPath path;
+ int version = exploreJavaRegistry(entry, access, *inOutVersion, &path);
+ if (version > *inOutVersion) {
+ *outJavaPath = path;
+ *inOutVersion = version;
+ return true;
+ }
+ return false;
+}
+
+int findJavaInRegistry(CPath *outJavaPath, bool isJdk, int minVersion) {
+ // Check the JRE first, then the JDK.
+ int version = minVersion - 1; // Inner methods check if they're greater than this version.
+ bool result = false;
+ result |= (!isJdk && getMaxJavaInRegistry("Java Runtime Environment", 0, outJavaPath, &version));
+ result |= getMaxJavaInRegistry("Java Development Kit", 0, outJavaPath, &version);
+
+ // Even if we're 64-bit, try again but check the 32-bit registry, looking for 32-bit java.
+ if (isApplication64()) {
+ result |= (!isJdk &&
+ getMaxJavaInRegistry("Java Runtime Environment", KEY_WOW64_32KEY, outJavaPath, &version));
+ result |= getMaxJavaInRegistry("Java Development Kit", KEY_WOW64_32KEY, outJavaPath, &version);
+ }
+
+ return result ? version : 0;
+}
+
+// --------------
+
+static bool checkProgramFiles(CPath *outJavaPath, int *inOutVersion, bool isJdk,
+ bool force32bit) {
+
+ char programFilesPath[MAX_PATH + 1];
+ int nFolder = force32bit ? CSIDL_PROGRAM_FILESX86 : CSIDL_PROGRAM_FILES;
+ HRESULT result = SHGetFolderPathA(
+ NULL, // hwndOwner
+ nFolder,
+ NULL, // hToken
+ SHGFP_TYPE_CURRENT, // dwFlags
+ programFilesPath); // pszPath
+ if (FAILED(result)) return false;
+
+ CPath path(programFilesPath);
+ path.addPath("Java");
+
+ // Do we have a C:\Program Files\Java directory?
+ if (!path.dirExists()) return false;
+
+ CPath glob(path);
+ glob.addPath("j*");
+
+ bool found = false;
+ WIN32_FIND_DATAA findData;
+ HANDLE findH = FindFirstFileA(glob.cstr(), &findData);
+ if (findH == INVALID_HANDLE_VALUE) return false;
+ do {
+ if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+ CPath temp(path);
+ temp.addPath(findData.cFileName);
+ // Check C:\Program Files\Java\j*\bin\java.exe
+
+ if (!isJdk || isJdkPath(temp)) {
+ int v = checkBinPath(&temp);
+ if (v > *inOutVersion) {
+ found = true;
+ *inOutVersion = v;
+ *outJavaPath = temp;
+ }
+ }
+ }
+ } while (!found && FindNextFileA(findH, &findData) != 0);
+ FindClose(findH);
+
+ return found;
+}
+
+int findJavaInProgramFiles(CPath *outJavaPath, bool isJdk, int minVersion) {
+
+ // Check the C:\Program Files directory
+ bool result = false;
+ int version = minVersion - 1; // Inner methods check if they're greater than this version.
+ result |= checkProgramFiles(outJavaPath, &version, isJdk, false);
+
+ // Even if we're 64-bit, try again but check the C:\Program Files (x86) directory, looking for
+ // 32-bit java.
+ if (isApplication64()) {
+ result |= checkProgramFiles(outJavaPath, &version, isJdk, true);
+ }
+
+ return result ? version : 0;
+}
+
+// --------------
+
+// Tries to invoke the java.exe at the given path and extract it's
+// version number.
+// - outVersionStr: if not null, will capture version as a string (e.g. "1.6")
+// - outVersionInt: if not null, will capture version as an int (major * 1000 + minor, e.g. 1006).
+bool getJavaVersion(CPath &javaPath, CString *outVersionStr, int *outVersionInt) {
+ bool result = false;
+
+ // Run "java -version", which outputs something like to *STDERR*:
+ //
+ // java version "1.6.0_29"
+ // Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
+ // Java HotSpot(TM) Client VM (build 20.4-b02, mixed mode, sharing)
+ //
+ // We want to capture the first line, and more exactly the "1.6" part.
+
+
+ CString cmd;
+ cmd.setf("\"%s\" -version", javaPath.cstr());
+
+ SECURITY_ATTRIBUTES saAttr;
+ STARTUPINFO startup;
+ PROCESS_INFORMATION pinfo;
+
+ // Want to inherit pipe handle
+ ZeroMemory(&saAttr, sizeof(saAttr));
+ saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ saAttr.bInheritHandle = TRUE;
+ saAttr.lpSecurityDescriptor = NULL;
+
+ // Create pipe for stdout
+ HANDLE stdoutPipeRd, stdoutPipeWt;
+ if (!CreatePipe(
+ &stdoutPipeRd, // hReadPipe,
+ &stdoutPipeWt, // hWritePipe,
+ &saAttr, // lpPipeAttributes,
+ 0)) { // nSize (0=default buffer size)
+ if (gIsConsole || gIsDebug) displayLastError("CreatePipe failed: ");
+ return false;
+ }
+ if (!SetHandleInformation(stdoutPipeRd, HANDLE_FLAG_INHERIT, 0)) {
+ if (gIsConsole || gIsDebug) displayLastError("SetHandleInformation failed: ");
+ return false;
+ }
+
+ ZeroMemory(&pinfo, sizeof(pinfo));
+
+ ZeroMemory(&startup, sizeof(startup));
+ startup.cb = sizeof(startup);
+ startup.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
+ startup.wShowWindow = SW_HIDE|SW_MINIMIZE;
+ // Capture both stderr and stdout
+ startup.hStdError = stdoutPipeWt;
+ startup.hStdOutput = stdoutPipeWt;
+ startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+
+ BOOL ok = CreateProcessA(
+ NULL, // program path
+ (LPSTR) cmd.cstr(), // command-line
+ NULL, // process handle is not inheritable
+ NULL, // thread handle is not inheritable
+ TRUE, // yes, inherit some handles
+ 0, // process creation flags
+ NULL, // use parent's environment block
+ NULL, // use parent's starting directory
+ &startup, // startup info, i.e. std handles
+ &pinfo);
+
+ if ((gIsConsole || gIsDebug) && !ok) displayLastError("CreateProcess failed: ");
+
+ // Close the write-end of the output pipe (we're only reading from it)
+ CloseHandle(stdoutPipeWt);
+
+ // Read from the output pipe. We don't need to read everything,
+ // the first line should be 'Java version "1.2.3_45"\r\n'
+ // so reading about 32 chars is all we need.
+ char first32[32 + 1];
+ int index = 0;
+ first32[0] = 0;
+
+ if (ok) {
+
+ #define SIZE 1024
+ char buffer[SIZE];
+ DWORD sizeRead = 0;
+
+ while (ok) {
+ // Keep reading in the same buffer location
+ ok = ReadFile(stdoutPipeRd, // hFile
+ buffer, // lpBuffer
+ SIZE, // DWORD buffer size to read
+ &sizeRead, // DWORD buffer size read
+ NULL); // overlapped
+ if (!ok || sizeRead == 0 || sizeRead > SIZE) break;
+
+ // Copy up to the first 32 characters
+ if (index < 32) {
+ DWORD n = 32 - index;
+ if (n > sizeRead) n = sizeRead;
+ // copy as lowercase to simplify checks later
+ for (char *b = buffer; n > 0; n--, b++, index++) {
+ char c = *b;
+ if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
+ first32[index] = c;
+ }
+ first32[index] = 0;
+ }
+ }
+
+ WaitForSingleObject(pinfo.hProcess, INFINITE);
+
+ DWORD exitCode;
+ if (GetExitCodeProcess(pinfo.hProcess, &exitCode)) {
+ // this should not return STILL_ACTIVE (259)
+ result = exitCode == 0;
+ }
+
+ CloseHandle(pinfo.hProcess);
+ CloseHandle(pinfo.hThread);
+ }
+ CloseHandle(stdoutPipeRd);
+
+ if (result && index > 0) {
+ // Look for a few keywords in the output however we don't
+ // care about specific ordering or case-senstiviness.
+ // We only captures roughtly the first line in lower case.
+ char *j = strstr(first32, "java");
+ if (!j) {
+ j = strstr(first32, "openjdk");
+ }
+ char *v = strstr(first32, "version");
+ if ((gIsConsole || gIsDebug) && (!j || !v)) {
+ fprintf(stderr, "Error: keywords 'java|openjdk version' not found in '%s'\n", first32);
+ }
+ if (j != NULL && v != NULL) {
+ result = extractJavaVersion(first32, index, outVersionStr, outVersionInt);
+ }
+ }
+
+ return result;
+}
+
+
+#endif /* _WIN32 */
diff --git a/find_java/src/source/utils.cpp b/find_java/src/source/utils.cpp
new file mode 100755
index 000000000..e2ce58f16
--- /dev/null
+++ b/find_java/src/source/utils.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed 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.
+ */
+
+#ifdef _WIN32
+
+#include "utils.h"
+
+#define _CRT_SECURE_NO_WARNINGS 1
+
+// Set to true to get some extra debug information
+bool gIsDebug = false;
+// Set to true to output errors to stderr (for a Console app)
+// or to false to output using msg box (for a Windows UI app)
+bool gIsConsole = false;
+
+// Displays a message in an ok+info dialog box.
+void msgBox(const char* text, ...) {
+ CString formatted;
+ va_list ap;
+ va_start(ap, text);
+ formatted.setv(text, ap);
+ va_end(ap);
+
+ MessageBoxA(NULL, formatted.cstr(), "Android SDK Manager", MB_OK | MB_ICONINFORMATION);
+}
+
+// Displays GetLastError prefixed with a description in an error dialog box
+void displayLastError(const char *description, ...) {
+ CString formatted;
+ va_list ap;
+ va_start(ap, description);
+ formatted.setv(description, ap);
+ va_end(ap);
+
+ CString error;
+ error.setLastWin32Error(NULL);
+ formatted.add("\r\n");
+ formatted.add(error.cstr());
+
+ if (gIsConsole) {
+ fprintf(stderr, "%s\n", formatted.cstr());
+ } else {
+ MessageBox(NULL, formatted.cstr(), "Android SDK Manager - Error", MB_OK | MB_ICONERROR);
+ }
+}
+
+// Executes the command line. Does not wait for the program to finish.
+// The return code is from CreateProcess (0 means failure), not the running app.
+int execNoWait(const char *app, const char *params, const char *workDir) {
+ STARTUPINFO startup;
+ PROCESS_INFORMATION pinfo;
+
+ ZeroMemory(&pinfo, sizeof(pinfo));
+
+ ZeroMemory(&startup, sizeof(startup));
+ startup.cb = sizeof(startup);
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_SHOWDEFAULT;
+
+ int ret = CreateProcessA(
+ (LPSTR) app, /* program path */
+ (LPSTR) params, /* command-line */
+ NULL, /* process handle is not inheritable */
+ NULL, /* thread handle is not inheritable */
+ TRUE, /* yes, inherit some handles */
+ 0, /* create flags */
+ NULL, /* use parent's environment block */
+ workDir, /* use parent's starting directory */
+ &startup, /* startup info, i.e. std handles */
+ &pinfo);
+
+ if (ret) {
+ CloseHandle(pinfo.hProcess);
+ CloseHandle(pinfo.hThread);
+ }
+
+ return ret;
+}
+
+// Executes command, waits for completion and returns exit code.
+// As indicated in MSDN for CreateProcess, callers should double-quote the program name
+// e.g. cmd="\"c:\program files\myapp.exe\" arg1 arg2";
+int execWait(const char *cmd) {
+ STARTUPINFO startup;
+ PROCESS_INFORMATION pinfo;
+
+ ZeroMemory(&pinfo, sizeof(pinfo));
+
+ ZeroMemory(&startup, sizeof(startup));
+ startup.cb = sizeof(startup);
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_HIDE|SW_MINIMIZE;
+
+ int ret = CreateProcessA(
+ NULL, /* program path */
+ (LPSTR) cmd, /* command-line */
+ NULL, /* process handle is not inheritable */
+ NULL, /* thread handle is not inheritable */
+ TRUE, /* yes, inherit some handles */
+ CREATE_NO_WINDOW, /* we don't want a console */
+ NULL, /* use parent's environment block */
+ NULL, /* use parent's starting directory */
+ &startup, /* startup info, i.e. std handles */
+ &pinfo);
+
+ int result = -1;
+ if (ret) {
+ WaitForSingleObject(pinfo.hProcess, INFINITE);
+
+ DWORD exitCode;
+ if (GetExitCodeProcess(pinfo.hProcess, &exitCode)) {
+ // this should not return STILL_ACTIVE (259)
+ result = exitCode;
+ }
+ CloseHandle(pinfo.hProcess);
+ CloseHandle(pinfo.hThread);
+ }
+
+ return result;
+}
+
+bool getModuleDir(CPath *outDir) {
+ CHAR programDir[MAX_PATH];
+ int ret = GetModuleFileName(NULL, programDir, sizeof(programDir));
+ if (ret != 0) {
+ // Remove the last segment to keep only the directory.
+ int pos = ret - 1;
+ while (pos > 0 && programDir[pos] != '\\') {
+ --pos;
+ }
+ outDir->set(programDir, pos);
+ return true;
+ }
+ return false;
+}
+
+// Disables the FS redirection done by WOW64.
+// Because this runs as a 32-bit app, Windows automagically remaps some
+// folder under the hood (e.g. "Programs Files(x86)" is mapped as "Program Files").
+// This prevents the app from correctly searching for java.exe in these folders.
+// The registry is also remapped. This method disables this redirection.
+// Caller should restore the redirection later by using revertWow64FsRedirection().
+PVOID disableWow64FsRedirection() {
+
+ // The call we want to make is the following:
+ // PVOID oldWow64Value;
+ // Wow64DisableWow64FsRedirection(&oldWow64Value);
+ // However that method may not exist (e.g. on XP non-64 systems) so
+ // we must not call it directly.
+
+ PVOID oldWow64Value = 0;
+
+ HMODULE hmod = LoadLibrary("kernel32.dll");
+ if (hmod != NULL) {
+ FARPROC proc = GetProcAddress(hmod, "Wow64DisableWow64FsRedirection");
+ if (proc != NULL) {
+ typedef BOOL (WINAPI *disableWow64FuncType)(PVOID *);
+ disableWow64FuncType funcPtr = (disableWow64FuncType)proc;
+ funcPtr(&oldWow64Value);
+ }
+
+ FreeLibrary(hmod);
+ }
+
+ return oldWow64Value;
+}
+
+// Reverts the redirection disabled in disableWow64FsRedirection.
+void revertWow64FsRedirection(PVOID oldWow64Value) {
+
+ // The call we want to make is the following:
+ // Wow64RevertWow64FsRedirection(oldWow64Value);
+ // However that method may not exist (e.g. on XP non-64 systems) so
+ // we must not call it directly.
+
+ HMODULE hmod = LoadLibrary("kernel32.dll");
+ if (hmod != NULL) {
+ FARPROC proc = GetProcAddress(hmod, "Wow64RevertWow64FsRedirection");
+ if (proc != NULL) {
+ typedef BOOL (WINAPI *revertWow64FuncType)(PVOID);
+ revertWow64FuncType funcPtr = (revertWow64FuncType)proc;
+ funcPtr(oldWow64Value);
+ }
+
+ FreeLibrary(hmod);
+ }
+}
+
+#endif /* _WIN32 */
diff --git a/find_java/src/source/utils.h b/find_java/src/source/utils.h
new file mode 100755
index 000000000..a65e6fe50
--- /dev/null
+++ b/find_java/src/source/utils.h
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed 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 _H_UTILS
+#define _H_UTILS
+
+#ifdef _WIN32
+
+#define _CRT_SECURE_NO_WARNINGS 1
+
+#include <direct.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <windows.h>
+
+// VS vs MINGW specific includes
+#ifdef USE_VS_CRT
+ #include <crtdbg.h> // for _ASSERT
+#else
+ #define _ASSERT(x) // undef
+#endif
+
+extern bool gIsDebug;
+extern bool gIsConsole;
+
+// An array that knows its own size. Not dynamically resizable.
+template <class T> class CArray {
+ T* mPtr;
+ int mSize;
+public:
+ explicit CArray(int size) {
+ mSize = size;
+ mPtr = new T[size];
+ }
+
+ ~CArray() {
+ if (mPtr != NULL) {
+ delete[] mPtr;
+ mPtr = NULL;
+ }
+ mSize = 0;
+ }
+
+ T& operator[](int i) {
+ _ASSERT(i >= 0 && i < mSize);
+ return mPtr[i];
+ }
+
+ int size() const {
+ return mSize;
+ }
+};
+
+// A simple string class wrapper.
+class CString {
+protected:
+ char *mStr;
+public:
+ CString() { mStr = NULL; }
+ CString(const CString &str) { mStr = NULL; set(str.mStr); }
+ explicit CString(const char *str) { mStr = NULL; set(str); }
+ CString(const char *start, size_t length) { mStr = NULL; set(start, length); }
+
+ CString& operator=(const CString &str) {
+ return set(str.cstr());
+ }
+
+ CString& set(const char *str) {
+ if (str != mStr) {
+ _free();
+ if (str != NULL) {
+ mStr = _strdup(str);
+ }
+ }
+ return *this;
+ }
+
+ CString& set(const char *start, size_t length) {
+ _free();
+ if (start != NULL) {
+ mStr = (char *)malloc(length + 1);
+ strncpy(mStr, start, length);
+ mStr[length] = 0;
+ }
+ return *this;
+ }
+
+ CString& setv(const char *str, va_list ap) {
+ _free();
+ // _vscprintf(str, ap) is only available with the MSVCRT, not MinGW.
+ // Instead we'll iterate till we have enough space to generate the string.
+ size_t len = strlen(str) + 1024;
+ mStr = (char *)malloc(len);
+ strcpy(mStr, str); // provide a default in case vsnprintf totally fails
+ for (int guard = 0; guard < 10; guard++) {
+ int ret = vsnprintf(mStr, len, str, ap);
+ if (ret == -1) {
+ // Some implementations don't give the proper size needed
+ // so double the space and try again.
+ len *= 2;
+ } else if (ret >= len) {
+ len = ret + 1;
+ } else {
+ // There was enough space to write.
+ break;
+ }
+ mStr = (char *)realloc((void *)mStr, len);
+ strcpy(mStr, str); // provide a default in case vsnprintf totally fails
+ }
+ return *this;
+ }
+
+ CString& setf(const char *str, ...) {
+ _free();
+ va_list ap;
+ va_start(ap, str);
+ setv(str, ap);
+ va_end(ap);
+ return *this;
+ }
+
+ virtual ~CString() { _free(); }
+
+ // Returns the C string owned by this CString. It will be
+ // invalid as soon as this CString is deleted or out of scope.
+ const char * cstr() const {
+ return mStr;
+ }
+
+ bool isEmpty() const {
+ return mStr == NULL || *mStr == 0;
+ }
+
+ size_t length() const {
+ return mStr == NULL ? 0 : strlen(mStr);
+ }
+
+ CString& add(const char *str) {
+ if (mStr == NULL) {
+ set(str);
+ } else {
+ mStr = (char *)realloc((void *)mStr, strlen(mStr) + strlen(str) + 1);
+ strcat(mStr, str);
+ }
+ return *this;
+ }
+
+ CString& add(const char *str, int length) {
+ if (mStr == NULL) {
+ set(str, length);
+ } else {
+ size_t l1 = strlen(mStr);
+ mStr = (char *)realloc((void *)mStr, l1 + length + 1);
+ strncpy(mStr + l1, str, length);
+ mStr[l1 + length] = 0;
+ }
+ return *this;
+ }
+
+ CArray<CString> * split(char sep) const {
+ if (mStr == NULL) {
+ return new CArray<CString>(0);
+ }
+ const char *last = NULL;
+ int n = 0;
+ for (const char *s = mStr; *s; s++) {
+ if (*s == sep && s != mStr && (last == NULL || s > last+1)) {
+ n++;
+ last = s;
+ }
+ }
+
+ CArray<CString> *result = new CArray<CString>(n);
+ last = NULL;
+ n = 0;
+ for (const char *s = mStr; *s; s++) {
+ if (*s == sep) {
+ if (s != mStr && (last == NULL || s > last+1)) {
+ const char *start = last ? last : mStr;
+ (*result)[n++].set(start, s-start);
+ }
+ last = s+1;
+ }
+ }
+
+ return result;
+ }
+
+ // Sets the string to the message matching Win32 GetLastError.
+ // If message is non-null, it is prepended to the last error string.
+ CString& setLastWin32Error(const char *message) {
+ DWORD err = GetLastError();
+ LPSTR errStr;
+ if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | /* dwFlags */
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, /* lpSource */
+ err, /* dwMessageId */
+ 0, /* dwLanguageId */
+ (LPSTR)&errStr, /* lpBuffer */
+ 0, /* nSize */
+ NULL) != 0) { /* va_list args */
+ if (message == NULL) {
+ setf("[%d] %s", err, errStr);
+ } else {
+ setf("%s[%d] %s", message, err, errStr);
+ }
+ LocalFree(errStr);
+ }
+ return *this;
+ }
+
+private:
+ void _free() {
+ if (mStr != NULL) {
+ free((void *)mStr);
+ mStr = NULL;
+ }
+ }
+
+};
+
+// A simple path class wrapper.
+class CPath : public CString {
+public:
+ CPath() : CString() { }
+ CPath(const CString &str) : CString(str) { }
+ CPath(const CPath &str) : CString(str) { }
+ explicit CPath(const char *str) : CString(str) { }
+ CPath(const char *start, int length) : CString(start, length) { }
+
+ CPath& operator=(const CPath &str) {
+ set(str.cstr());
+ return *this;
+ }
+
+ // Appends a path segment, adding a \ as necessary.
+ CPath& addPath(const CString &s) {
+ return addPath(s.cstr());
+ }
+
+ // Appends a path segment, adding a \ as necessary.
+ CPath& addPath(const char *s) {
+ _ASSERT(s != NULL);
+ if (s != NULL && s[0] != 0) {
+ size_t n = length();
+ if (n > 0 && s[0] != '\\' && mStr[n-1] != '\\') add("\\");
+ add(s);
+ }
+ return *this;
+ }
+
+ // Returns true if file exist and is not a directory.
+ // There's no garantee we have rights to access it.
+ bool fileExists() const {
+ if (mStr == NULL) return false;
+ DWORD attribs = GetFileAttributesA(mStr);
+ return attribs != INVALID_FILE_ATTRIBUTES &&
+ !(attribs & FILE_ATTRIBUTE_DIRECTORY);
+ }
+
+ // Returns true if file exist and is a directory.
+ // There's no garantee we have rights to access it.
+ bool dirExists() const {
+ if (mStr == NULL) return false;
+ DWORD attribs = GetFileAttributesA(mStr);
+ return attribs != INVALID_FILE_ATTRIBUTES &&
+ (attribs & FILE_ATTRIBUTE_DIRECTORY) != 0;
+ }
+
+ // Returns a copy of the directory portion of the path, if any
+ CPath dirName() const {
+ CPath result;
+ if (mStr != NULL) {
+ char *pos = strrchr(mStr, '\\');
+ if (pos != NULL) {
+ result.set(mStr, pos - mStr);
+ }
+ }
+ return result;
+ }
+
+ // Returns a pointer to the baseName part of the path.
+ // It becomes invalid if the path changes.
+ const char * baseName() const {
+ if (mStr != NULL) {
+ char *pos = strrchr(mStr, '\\');
+ if (pos != NULL) {
+ return pos + 1;
+ }
+ }
+ return NULL;
+ }
+
+ // If the path ends with the given searchName, replace in-place by the new name
+ void replaceName(const char *searchName, const char* newName) {
+ if (mStr == NULL) return;
+ size_t n = length();
+ size_t sn = strlen(searchName);
+ if (n < sn) return;
+ // if mStr ends with searchName
+ if (strcmp(mStr + n - sn, searchName) == 0) {
+ size_t sn2 = strlen(newName);
+ if (sn2 > sn) {
+ mStr = (char *)realloc((void *)mStr, n + sn2 - sn + 1);
+ }
+ strcpy(mStr + n - sn, newName);
+ mStr[n + sn2 - sn] = 0;
+ }
+ }
+
+ // Returns a copy of this path as a DOS short path in the destination.
+ // Returns true if the Win32 getShortPathName method worked.
+ // In case of error, returns false and does not change the destination.
+ // It's OK to invoke this->toShortPath(this).
+ bool toShortPath(CPath *dest) {
+ const char *longPath = mStr;
+ if (mStr == NULL) return false;
+
+ DWORD lenShort = (DWORD)strlen(longPath) + 1; // GetShortPathName deals with DWORDs
+ char * shortPath = (char *)malloc(lenShort);
+
+ DWORD length = GetShortPathName(longPath, shortPath, lenShort);
+ if (length > lenShort) {
+ // The buffer wasn't big enough, this is the size to use.
+ free(shortPath);
+ lenShort = length;
+ shortPath = (char *)malloc(length);
+ length = GetShortPathName(longPath, shortPath, lenShort);
+ }
+
+ if (length != 0) dest->set(shortPath);
+
+ free(shortPath);
+ return length != 0;
+ }
+};
+
+// Displays a message in an ok+info dialog box.
+void msgBox(const char* text, ...);
+
+// Displays GetLastError prefixed with a description in an error dialog box
+void displayLastError(const char *description, ...);
+
+// Executes the command line. Does not wait for the program to finish.
+// The return code is from CreateProcess (0 means failure), not the running app.
+int execNoWait(const char *app, const char *params, const char *workDir);
+
+// Executes command, waits for completion and returns exit code.
+// As indicated in MSDN for CreateProcess, callers should double-quote the program name
+// e.g. cmd="\"c:\program files\myapp.exe\" arg1 arg2";
+int execWait(const char *cmd);
+
+bool getModuleDir(CPath *outDir);
+
+#endif /* _WIN32 */
+#endif /* _H_UTILS */