Revert "Remove unused project."

This reverts commit eaada771a6e62ca494a625ce1b060f1a94fa9877.

Reason for revert: Breaks build_test and other builds
Bug: 155862492

Change-Id: I1a14b84d54b05596ec250b31ae56e437cf49fd81
diff --git a/find_java2/.gitignore b/find_java2/.gitignore
new file mode 100644
index 0000000..3117960
--- /dev/null
+++ b/find_java2/.gitignore
@@ -0,0 +1,10 @@
+ipch
+*.aps
+*.sdf
+*.opensdf
+*.suo
+*.filters
+*.user
+Debug
+Release
+
diff --git a/find_java2/FindJava2.sln b/find_java2/FindJava2.sln
new file mode 100755
index 0000000..459e3a7
--- /dev/null
+++ b/find_java2/FindJava2.sln
@@ -0,0 +1,28 @@
+

+Microsoft Visual Studio Solution File, Format Version 12.00

+# Visual Studio 2013

+VisualStudioVersion = 12.0.30723.0

+MinimumVisualStudioVersion = 10.0.40219.1

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinLauncher2", "WinLauncher2\WinLauncher2.vcxproj", "{64980924-B76E-4E00-90A4-647E67CEB050}"

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FindJava2", "FindJava2\FindJava2.vcxproj", "{E696008D-A1B8-4434-B6B4-24ED251B1676}"

+EndProject

+Global

+	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|Win32 = Debug|Win32

+		Release|Win32 = Release|Win32

+	EndGlobalSection

+	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{64980924-B76E-4E00-90A4-647E67CEB050}.Debug|Win32.ActiveCfg = Debug|Win32

+		{64980924-B76E-4E00-90A4-647E67CEB050}.Debug|Win32.Build.0 = Debug|Win32

+		{64980924-B76E-4E00-90A4-647E67CEB050}.Release|Win32.ActiveCfg = Release|Win32

+		{64980924-B76E-4E00-90A4-647E67CEB050}.Release|Win32.Build.0 = Release|Win32

+		{E696008D-A1B8-4434-B6B4-24ED251B1676}.Debug|Win32.ActiveCfg = Debug|Win32

+		{E696008D-A1B8-4434-B6B4-24ED251B1676}.Debug|Win32.Build.0 = Debug|Win32

+		{E696008D-A1B8-4434-B6B4-24ED251B1676}.Release|Win32.ActiveCfg = Release|Win32

+		{E696008D-A1B8-4434-B6B4-24ED251B1676}.Release|Win32.Build.0 = Release|Win32

+	EndGlobalSection

+	GlobalSection(SolutionProperties) = preSolution

+		HideSolutionNode = FALSE

+	EndGlobalSection

+EndGlobal

diff --git a/find_java2/FindJava2/FindJava2.cpp b/find_java2/FindJava2/FindJava2.cpp
new file mode 100755
index 0000000..1435e1b
--- /dev/null
+++ b/find_java2/FindJava2/FindJava2.cpp
@@ -0,0 +1,199 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+#include "stdafx.h"

+#include "FindJava2.h"

+#include "utils.h"

+#include "JavaFinder.h"

+#include "FindJava2Dlg.h"

+

+#ifdef _DEBUG

+#define new DEBUG_NEW

+#endif

+

+// The one and only MFC application object

+class CFindJava2App : public CWinApp {

+public:

+    CFindJava2App() {

+    }

+

+    // Set CWinApp default registry key. Must be consistent with all apps using findjava2.

+    void initRegistryKey() {

+        SetRegistryKey(_T("Android-FindJava2"));

+    }

+};

+

+CFindJava2App theApp;

+

+using namespace std;

+

+int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) {

+

+    // Init utils; use default app name based on VERSIONINFO.FileDescription

+    initUtils(NULL);

+

+    // initialize MFC and print and error on failure

+    HMODULE hModule = ::GetModuleHandle(NULL);

+    if (hModule == NULL) {

+        displayLastError(_T("Fatal Error: "));

+        return -2;

+    }

+    if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0)) {

+        displayLastError(_T("Fatal Error: "));

+        return -3;

+    }

+

+    theApp.initRegistryKey();

+

+    gIsConsole = true; // tell utils to to print errors to stderr

+    gIsDebug = (getenv("ANDROID_SDKMAN_DEBUG") != NULL);

+

+    // Parse command line

+    bool doTests = false;

+    bool doShortPath = false;

+    bool doVersion = false;

+    bool doJavaW = false;

+    bool doForceUi = false;

+    bool doJava1_7 = false;

+

+    for (int i = 1; i < argc; i++) {

+        if (_tcsnccmp(argv[i], _T("-t"), 2) == 0) {

+            doTests = true;

+

+        } else if (_tcsnccmp(argv[i], _T("-d"), 2) == 0) {

+            gIsDebug = true;

+

+        } else if (_tcsnccmp(argv[i], _T("-s"), 2) == 0) {

+            doShortPath = true;

+

+        } else if (_tcsnccmp(argv[i], _T("-v"), 2) == 0) {

+            doVersion = true;

+

+        } else if (_tcsnccmp(argv[i], _T("-f"), 2) == 0) {

+            doForceUi = true;

+

+        } else if (_tcsnccmp(argv[i], _T("-7"), 2) == 0) {

+            doJava1_7 = true;

+

+        } else if (_tcscmp(argv[i], _T("-w")) == 0 || _tcscmp(argv[i], _T("-javaw")) == 0) {

+            doJavaW = true;

+

+        } else {

+            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"

+                "-f / -force  : Force UI selection.\n"

+                "-7           : Java 1.7 minimum instead of 1.6.\n"

+                "-s / -short  : Print path in short DOS form.\n"

+                "-w / -javaw  : Search a matching javaw.exe; defaults to java.exe if not found.\n"

+                "-v / -version: Only prints the Java version found.\n"

+                );

+            return 2;

+        }

+    }

+

+

+    CJavaFinder javaFinder(JAVA_VERS_TO_INT(1, doJava1_7 ? 7 : 6));

+    CJavaPath javaPath = javaFinder.getRegistryPath();

+

+    if (doTests) {

+        std::set<CJavaPath> paths;

+        javaFinder.findJavaPaths(&paths);

+        bool regPrinted = false;

+        for (const CJavaPath &p : paths) {

+            bool isReg = (p == javaPath);

+            if (isReg) {

+                regPrinted = true;

+            }

+            _tprintf(_T("%c [%s] %s\n"), isReg ? '*' : ' ', p.getVersion(), p.mPath);

+        }

+

+        if (!regPrinted && !javaPath.isEmpty()) {

+            const CJavaPath &p = javaPath;

+            _tprintf(_T("* [%s] %s\n"), p.getVersion(), p.mPath);

+        }

+        return 0;

+    }

+

+    if (doForceUi || javaPath.isEmpty()) {

+        CFindJava2Dlg dlg;

+        dlg.setJavaFinder(&javaFinder);

+        INT_PTR nResponse = dlg.DoModal();

+

+        if (nResponse == IDOK) {

+            // Get java path selected by user and save into registry for later re-use

+            javaPath = dlg.getSelectedPath();

+            javaFinder.setRegistryPath(javaPath);

+        } else if (nResponse == -1) {   // MFC boilerplate

+            TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n");

+            return 1;

+        }

+    }

+

+    if (javaPath.isEmpty()) {

+        fprintf(stderr, "No java.exe path found");

+        return 1;

+    }

+

+    if (doShortPath) {

+        PVOID oldWow64Value = disableWow64FsRedirection();

+        if (!javaPath.toShortPath()) {

+            revertWow64FsRedirection(&oldWow64Value);

+            _ftprintf(stderr,

+                    _T("Failed to convert path to a short DOS path: %s\n"),

+                    javaPath.mPath);

+            return 1;

+        }

+        revertWow64FsRedirection(&oldWow64Value);

+    }

+

+    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.

+        _tprintf(_T("%s"), javaPath.getVersion());

+        return 0;

+    }

+

+    if (doJavaW) {

+        // Try to find a javaw.exe instead of java.exe at the same location.

+        CPath javawPath = javaPath.mPath;

+        javawPath.RemoveFileSpec();

+        javawPath.Append(_T("javaw.exe"));

+        javawPath.Canonicalize();

+

+        // Only accept it if we can actually find the exec

+        PVOID oldWow64Value = disableWow64FsRedirection();

+        bool exists = javawPath.FileExists() == TRUE; // skip BOOL-to-bool warning

+        revertWow64FsRedirection(&oldWow64Value);

+

+        if (!exists) {

+            _ftprintf(stderr,

+                    _T("Failed to find javaw at: %s\n"),

+                    javawPath);

+            return 1;

+        }

+

+        javaPath.mPath = javawPath;

+    }

+

+    // Print java.exe path found

+    _tprintf(_T("%s"), javaPath.mPath);

+    return 0;

+

+}

diff --git a/find_java2/FindJava2/FindJava2.h b/find_java2/FindJava2/FindJava2.h
new file mode 100755
index 0000000..a144bfc
--- /dev/null
+++ b/find_java2/FindJava2/FindJava2.h
@@ -0,0 +1,19 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+#pragma once

+

+#include "resource.h"

diff --git a/find_java2/FindJava2/FindJava2.rc b/find_java2/FindJava2/FindJava2.rc
new file mode 100755
index 0000000..ff767c6
--- /dev/null
+++ b/find_java2/FindJava2/FindJava2.rc
@@ -0,0 +1,142 @@
+// Microsoft Visual C++ generated resource script.

+//

+#include "resource.h"

+

+#define APSTUDIO_READONLY_SYMBOLS

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 2 resource.

+//

+#include "afxres.h"

+

+/////////////////////////////////////////////////////////////////////////////

+#undef APSTUDIO_READONLY_SYMBOLS

+

+/////////////////////////////////////////////////////////////////////////////

+// English (United States) resources

+

+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)

+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

+

+#ifdef APSTUDIO_INVOKED

+/////////////////////////////////////////////////////////////////////////////

+//

+// TEXTINCLUDE

+//

+

+1 TEXTINCLUDE 

+BEGIN

+    "resource.h\0"

+END

+

+2 TEXTINCLUDE 

+BEGIN

+    "#include ""afxres.h""\r\n"

+    "\0"

+END

+

+3 TEXTINCLUDE 

+BEGIN

+    "\r\n"

+    "\0"

+END

+

+#endif    // APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Version

+//

+

+VS_VERSION_INFO VERSIONINFO

+ FILEVERSION 1,0,0,1

+ PRODUCTVERSION 1,0,0,1

+ FILEFLAGSMASK 0x3fL

+#ifdef _DEBUG

+ FILEFLAGS 0x1L

+#else

+ FILEFLAGS 0x0L

+#endif

+ FILEOS 0x40004L

+ FILETYPE 0x1L

+ FILESUBTYPE 0x0L

+BEGIN

+    BLOCK "StringFileInfo"

+    BEGIN

+        BLOCK "040904b0"

+        BEGIN

+            VALUE "CompanyName", "Android"

+            VALUE "FileDescription", "Find Java for Android SDK"

+            VALUE "FileVersion", "2.0.0.1"

+            VALUE "InternalName", "FindJava2.exe"

+            VALUE "LegalCopyright", "(c) Android.  All rights reserved."

+            VALUE "OriginalFilename", "FindJava2.exe"

+            VALUE "ProductName", "Android SDK"

+            VALUE "ProductVersion", "2.0.0.1"

+        END

+    END

+    BLOCK "VarFileInfo"

+    BEGIN

+        VALUE "Translation", 0x409, 1200

+    END

+END

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Dialog

+//

+

+IDD_FINDJAVA2_DIALOG DIALOGEX 0, 0, 317, 196

+STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME

+EXSTYLE WS_EX_APPWINDOW

+CAPTION "Find Java 2 for Android"

+FONT 8, "MS Shell Dlg", 0, 0, 0x1

+BEGIN

+    DEFPUSHBUTTON   "Start",IDOK,205,174,50,14

+    PUSHBUTTON      "Quit",IDCANCEL,260,174,50,14

+    PUSHBUTTON      "Add...",IDC_BUTTON_ADD,7,174,50,14

+    LTEXT           "Select which version of Java to use:",IDC_STATIC,7,7,116,8

+    CONTROL         "",IDC_PATH_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,18,300,150

+END

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// DESIGNINFO

+//

+

+#ifdef APSTUDIO_INVOKED

+GUIDELINES DESIGNINFO

+BEGIN

+    IDD_FINDJAVA2_DIALOG, DIALOG

+    BEGIN

+    END

+END

+#endif    // APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Icon

+//

+

+// Icon with lowest ID value placed first to ensure application icon

+// remains consistent on all systems.

+IDI_ANDROID_ICON        ICON                    "..\\android_icon.ico"

+#endif    // English (United States) resources

+/////////////////////////////////////////////////////////////////////////////

+

+

+

+#ifndef APSTUDIO_INVOKED

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 3 resource.

+//

+

+

+/////////////////////////////////////////////////////////////////////////////

+#endif    // not APSTUDIO_INVOKED

+

diff --git a/find_java2/FindJava2/FindJava2.vcxproj b/find_java2/FindJava2/FindJava2.vcxproj
new file mode 100755
index 0000000..3c9ac4e
--- /dev/null
+++ b/find_java2/FindJava2/FindJava2.vcxproj
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project DefaultTargets="Build" ToolsVersion="12.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="Release|Win32">

+      <Configuration>Release</Configuration>

+      <Platform>Win32</Platform>

+    </ProjectConfiguration>

+  </ItemGroup>

+  <PropertyGroup Label="Globals">

+    <ProjectGuid>{E696008D-A1B8-4434-B6B4-24ED251B1676}</ProjectGuid>

+    <Keyword>Win32Proj</Keyword>

+    <RootNamespace>FindJava2</RootNamespace>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>true</UseDebugLibraries>

+    <PlatformToolset>v120</PlatformToolset>

+    <CharacterSet>Unicode</CharacterSet>

+    <UseOfMfc>Dynamic</UseOfMfc>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>false</UseDebugLibraries>

+    <PlatformToolset>v120</PlatformToolset>

+    <WholeProgramOptimization>true</WholeProgramOptimization>

+    <CharacterSet>Unicode</CharacterSet>

+    <UseOfMfc>Dynamic</UseOfMfc>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

+  <ImportGroup Label="ExtensionSettings">

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <PropertyGroup Label="UserMacros" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <LinkIncremental>true</LinkIncremental>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <LinkIncremental>false</LinkIncremental>

+  </PropertyGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <ClCompile>

+      <PrecompiledHeader>Use</PrecompiledHeader>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>Disabled</Optimization>

+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <AdditionalDependencies>version.lib</AdditionalDependencies>

+    </Link>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <PrecompiledHeader>Use</PrecompiledHeader>

+      <Optimization>MaxSpeed</Optimization>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <IntrinsicFunctions>true</IntrinsicFunctions>

+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+    </ClCompile>

+    <Link>

+      <SubSystem>Console</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

+      <AdditionalDependencies>version.lib</AdditionalDependencies>

+    </Link>

+  </ItemDefinitionGroup>

+  <ItemGroup>

+    <ClInclude Include="..\src\FindJava2Dlg.h" />

+    <ClInclude Include="..\src\JavaFinder.h" />

+    <ClInclude Include="..\src\JavaPath.h" />

+    <ClInclude Include="..\src\utils.h" />

+    <ClInclude Include="FindJava2.h" />

+    <ClInclude Include="Resource.h" />

+    <ClInclude Include="stdafx.h" />

+    <ClInclude Include="targetver.h" />

+  </ItemGroup>

+  <ItemGroup>

+    <ClCompile Include="..\src\FindJava2Dlg.cpp" />

+    <ClCompile Include="..\src\JavaFinder.cpp" />

+    <ClCompile Include="..\src\JavaPath.cpp" />

+    <ClCompile Include="..\src\utils.cpp" />

+    <ClCompile Include="FindJava2.cpp" />

+    <ClCompile Include="stdafx.cpp">

+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>

+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>

+    </ClCompile>

+  </ItemGroup>

+  <ItemGroup>

+    <ResourceCompile Include="FindJava2.rc" />

+  </ItemGroup>

+  <ItemGroup>

+    <Image Include="..\android_icon.ico" />

+  </ItemGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+  <ImportGroup Label="ExtensionTargets">

+  </ImportGroup>

+</Project>
\ No newline at end of file
diff --git a/find_java2/FindJava2/resource.h b/find_java2/FindJava2/resource.h
new file mode 100755
index 0000000..1d5f98f
--- /dev/null
+++ b/find_java2/FindJava2/resource.h
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}

+// Microsoft Visual C++ generated include file.

+// Used by FindJava2.rc

+//

+#define IDI_ANDROID_ICON                5

+#define IDD_FINDJAVA2_DIALOG            102

+#define IDC_BUTTON_ADD                  1000

+#define IDC_PATH_LIST                   1001

+

+// Next default values for new objects

+// 

+#ifdef APSTUDIO_INVOKED

+#ifndef APSTUDIO_READONLY_SYMBOLS

+#define _APS_NEXT_RESOURCE_VALUE        101

+#define _APS_NEXT_COMMAND_VALUE         40001

+#define _APS_NEXT_CONTROL_VALUE         1000

+#define _APS_NEXT_SYMED_VALUE           101

+#endif

+#endif

diff --git a/find_java2/FindJava2/stdafx.cpp b/find_java2/FindJava2/stdafx.cpp
new file mode 100755
index 0000000..3baa67f
--- /dev/null
+++ b/find_java2/FindJava2/stdafx.cpp
@@ -0,0 +1,24 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+// stdafx.cpp : source file that includes just the standard includes

+// FindJava2.pch will be the pre-compiled header

+// stdafx.obj will contain the pre-compiled type information

+

+#include "stdafx.h"

+

+// TODO: reference any additional headers you need in STDAFX.H

+// and not in this file

diff --git a/find_java2/FindJava2/stdafx.h b/find_java2/FindJava2/stdafx.h
new file mode 100755
index 0000000..7230def
--- /dev/null
+++ b/find_java2/FindJava2/stdafx.h
@@ -0,0 +1,55 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+// stdafx.h : include file for standard system include files,

+// or project specific include files that are used frequently,

+// but are changed infrequently.

+

+#pragma once

+

+#include "targetver.h"

+

+

+#define _CRT_SECURE_NO_WARNINGS

+

+#include <stdio.h>

+#include <tchar.h>

+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // some CString constructors will be explicit

+#define _AFX_NO_MFC_CONTROLS_IN_DIALOGS         // remove support for MFC controls in dialogs

+

+#ifndef VC_EXTRALEAN

+#define VC_EXTRALEAN            // Exclude rarely-used stuff from Windows headers

+#endif

+

+#include <afx.h>

+#include <afxwin.h>         // MFC core and standard components

+#include <afxext.h>         // MFC extensions

+#ifndef _AFX_NO_OLE_SUPPORT

+#include <afxdtctl.h>           // MFC support for Internet Explorer 4 Common Controls

+#endif

+#ifndef _AFX_NO_AFXCMN_SUPPORT

+#include <afxcmn.h>                     // MFC support for Windows Common Controls

+#endif // _AFX_NO_AFXCMN_SUPPORT

+

+#include <iostream>

+

+

+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // some CString constructors will be explicit

+

+#include <atlbase.h>

+#include <atlstr.h>

+

+// TODO: reference additional headers your program requires here

diff --git a/find_java2/FindJava2/targetver.h b/find_java2/FindJava2/targetver.h
new file mode 100755
index 0000000..fc6d20b
--- /dev/null
+++ b/find_java2/FindJava2/targetver.h
@@ -0,0 +1,24 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+#pragma once

+

+// Including SDKDDKVer.h defines the highest available Windows platform.

+

+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and

+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.

+

+#include <SDKDDKVer.h>

diff --git a/find_java2/WinLauncher2/Resource.h b/find_java2/WinLauncher2/Resource.h
new file mode 100755
index 0000000..c3b2e0f
--- /dev/null
+++ b/find_java2/WinLauncher2/Resource.h
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}

+// Microsoft Visual C++ generated include file.

+// Used by WinLauncher2.rc

+//

+#define IDI_ANDROID_ICON                5

+#define IDD_FINDJAVA2_DIALOG            102

+#define IDC_BUTTON_ADD                  1000

+#define IDC_PATH_LIST                   1001

+

+// Next default values for new objects

+// 

+#ifdef APSTUDIO_INVOKED

+#ifndef APSTUDIO_READONLY_SYMBOLS

+#define _APS_NEXT_RESOURCE_VALUE        130

+#define _APS_NEXT_COMMAND_VALUE         32771

+#define _APS_NEXT_CONTROL_VALUE         1000

+#define _APS_NEXT_SYMED_VALUE           101

+#endif

+#endif

diff --git a/find_java2/WinLauncher2/WinLauncher2.rc b/find_java2/WinLauncher2/WinLauncher2.rc
new file mode 100755
index 0000000..bee2edf
--- /dev/null
+++ b/find_java2/WinLauncher2/WinLauncher2.rc
@@ -0,0 +1,174 @@
+// Microsoft Visual C++ generated resource script.

+//

+#include "resource.h"

+

+#define APSTUDIO_READONLY_SYMBOLS

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 2 resource.

+//

+#ifndef APSTUDIO_INVOKED

+#include "targetver.h"

+#endif

+#include "afxres.h"

+#include "verrsrc.h"

+

+/////////////////////////////////////////////////////////////////////////////

+#undef APSTUDIO_READONLY_SYMBOLS

+

+/////////////////////////////////////////////////////////////////////////////

+// English (United States) resources

+

+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)

+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

+

+#ifdef APSTUDIO_INVOKED

+/////////////////////////////////////////////////////////////////////////////

+//

+// TEXTINCLUDE

+//

+

+1 TEXTINCLUDE 

+BEGIN

+    "resource.h\0"

+END

+

+2 TEXTINCLUDE 

+BEGIN

+    "#ifndef APSTUDIO_INVOKED\r\n"

+    "#include ""targetver.h""\r\n"

+    "#endif\r\n"

+    "#include ""afxres.h""\r\n"

+    "#include ""verrsrc.h""\r\n"

+    "\0"

+END

+

+3 TEXTINCLUDE 

+BEGIN

+    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"

+    "#define _AFX_NO_OLE_RESOURCES\r\n"

+    "#define _AFX_NO_TRACKER_RESOURCES\r\n"

+    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"

+    "\r\n"

+    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"

+    "LANGUAGE 9, 1\r\n"

+    "#include ""res\\WinLauncher2.rc2""  // non-Microsoft Visual C++ edited resources\r\n"

+    "#include ""afxres.rc""      // Standard components\r\n"

+    "#if !defined(_AFXDLL)\r\n"

+    "#include ""afxribbon.rc""   // MFC ribbon and control bar resources\r\n"

+    "#endif\r\n"

+    "#endif\r\n"

+    "\0"

+END

+

+#endif    // APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Version

+//

+

+VS_VERSION_INFO VERSIONINFO

+ FILEVERSION 2,0,0,1

+ PRODUCTVERSION 2,0,0,1

+ FILEFLAGSMASK 0x3fL

+#ifdef _DEBUG

+ FILEFLAGS 0x1L

+#else

+ FILEFLAGS 0x0L

+#endif

+ FILEOS 0x40004L

+ FILETYPE 0x1L

+ FILESUBTYPE 0x0L

+BEGIN

+    BLOCK "StringFileInfo"

+    BEGIN

+        BLOCK "040904b0"

+        BEGIN

+            VALUE "CompanyName", "Android"

+            VALUE "FileDescription", "Android Studio Windows Launcher"

+            VALUE "FileVersion", "2.0.0.1"

+            VALUE "InternalName", "WinLauncher2.exe"

+            VALUE "LegalCopyright", "(c) Android.  All rights reserved."

+            VALUE "OriginalFilename", "WinLauncher2.exe"

+            VALUE "ProductName", "Android SDK"

+            VALUE "ProductVersion", "2.0.0.1"

+        END

+    END

+    BLOCK "VarFileInfo"

+    BEGIN

+        VALUE "Translation", 0x409, 1200

+    END

+END

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Dialog

+//

+

+IDD_FINDJAVA2_DIALOG DIALOGEX 0, 0, 317, 197

+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU

+EXSTYLE WS_EX_APPWINDOW

+CAPTION "Find Java 2 for Android"

+FONT 8, "MS Shell Dlg", 0, 0, 0x1

+BEGIN

+    DEFPUSHBUTTON   "Start",IDOK,205,174,50,14

+    PUSHBUTTON      "Quit",IDCANCEL,260,174,50,14

+    PUSHBUTTON      "Add...",IDC_BUTTON_ADD,7,174,50,14

+    LTEXT           "Select which version of Java to use:",IDC_STATIC,7,7,116,8

+    CONTROL         "",IDC_PATH_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,18,300,150

+END

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Icon

+//

+

+// Icon with lowest ID value placed first to ensure application icon

+// remains consistent on all systems.

+IDI_ANDROID_ICON        ICON                    "..\\android_icon.ico"

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// DESIGNINFO

+//

+

+#ifdef APSTUDIO_INVOKED

+GUIDELINES DESIGNINFO

+BEGIN

+    IDD_FINDJAVA2_DIALOG, DIALOG

+    BEGIN

+        BOTTOMMARGIN, 196

+    END

+END

+#endif    // APSTUDIO_INVOKED

+

+#endif    // English (United States) resources

+/////////////////////////////////////////////////////////////////////////////

+

+

+

+#ifndef APSTUDIO_INVOKED

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 3 resource.

+//

+#define _AFX_NO_SPLITTER_RESOURCES

+#define _AFX_NO_OLE_RESOURCES

+#define _AFX_NO_TRACKER_RESOURCES

+#define _AFX_NO_PROPERTY_RESOURCES

+

+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)

+LANGUAGE 9, 1

+#include "afxres.rc"      // Standard components

+#if !defined(_AFXDLL)

+#include "afxribbon.rc"   // MFC ribbon and control bar resources

+#endif

+#endif

+

+/////////////////////////////////////////////////////////////////////////////

+#endif    // not APSTUDIO_INVOKED

+

diff --git a/find_java2/WinLauncher2/WinLauncher2.vcxproj b/find_java2/WinLauncher2/WinLauncher2.vcxproj
new file mode 100755
index 0000000..9dfdca7
--- /dev/null
+++ b/find_java2/WinLauncher2/WinLauncher2.vcxproj
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project DefaultTargets="Build" ToolsVersion="12.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="Release|Win32">

+      <Configuration>Release</Configuration>

+      <Platform>Win32</Platform>

+    </ProjectConfiguration>

+  </ItemGroup>

+  <PropertyGroup Label="Globals">

+    <ProjectGuid>{64980924-B76E-4E00-90A4-647E67CEB050}</ProjectGuid>

+    <RootNamespace>WinLauncher2</RootNamespace>

+    <Keyword>MFCProj</Keyword>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>true</UseDebugLibraries>

+    <PlatformToolset>v120</PlatformToolset>

+    <CharacterSet>Unicode</CharacterSet>

+    <UseOfMfc>Dynamic</UseOfMfc>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">

+    <ConfigurationType>Application</ConfigurationType>

+    <UseDebugLibraries>false</UseDebugLibraries>

+    <PlatformToolset>v120</PlatformToolset>

+    <WholeProgramOptimization>true</WholeProgramOptimization>

+    <CharacterSet>Unicode</CharacterSet>

+    <UseOfMfc>Dynamic</UseOfMfc>

+  </PropertyGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

+  <ImportGroup Label="ExtensionSettings">

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />

+  </ImportGroup>

+  <PropertyGroup Label="UserMacros" />

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <LinkIncremental>true</LinkIncremental>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <LinkIncremental>false</LinkIncremental>

+  </PropertyGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

+    <ClCompile>

+      <PrecompiledHeader>Use</PrecompiledHeader>

+      <WarningLevel>Level3</WarningLevel>

+      <Optimization>Disabled</Optimization>

+      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+    </ClCompile>

+    <Link>

+      <SubSystem>Windows</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <AdditionalDependencies>version.lib</AdditionalDependencies>

+    </Link>

+    <Midl>

+      <MkTypLibCompatible>false</MkTypLibCompatible>

+      <ValidateAllParameters>true</ValidateAllParameters>

+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+    </Midl>

+    <ResourceCompile>

+      <Culture>0x0409</Culture>

+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+    </ResourceCompile>

+  </ItemDefinitionGroup>

+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

+    <ClCompile>

+      <WarningLevel>Level3</WarningLevel>

+      <PrecompiledHeader>Use</PrecompiledHeader>

+      <Optimization>MaxSpeed</Optimization>

+      <FunctionLevelLinking>true</FunctionLevelLinking>

+      <IntrinsicFunctions>true</IntrinsicFunctions>

+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>$(ProjectDir);$(SolutionDir)\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+    </ClCompile>

+    <Link>

+      <SubSystem>Windows</SubSystem>

+      <GenerateDebugInformation>true</GenerateDebugInformation>

+      <EnableCOMDATFolding>true</EnableCOMDATFolding>

+      <OptimizeReferences>true</OptimizeReferences>

+      <AdditionalDependencies>version.lib</AdditionalDependencies>

+    </Link>

+    <Midl>

+      <MkTypLibCompatible>false</MkTypLibCompatible>

+      <ValidateAllParameters>true</ValidateAllParameters>

+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+    </Midl>

+    <ResourceCompile>

+      <Culture>0x0409</Culture>

+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>

+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>

+    </ResourceCompile>

+  </ItemDefinitionGroup>

+  <ItemGroup>

+    <ClInclude Include="..\src\FindJava2Dlg.h" />

+    <ClInclude Include="..\src\JavaFinder.h" />

+    <ClInclude Include="..\src\JavaPath.h" />

+    <ClInclude Include="..\src\utils.h" />

+    <ClInclude Include="..\src\WinLauncher2App.h" />

+    <ClInclude Include="Resource.h" />

+    <ClInclude Include="stdafx.h" />

+    <ClInclude Include="targetver.h" />

+  </ItemGroup>

+  <ItemGroup>

+    <ClCompile Include="..\src\FindJava2Dlg.cpp" />

+    <ClCompile Include="..\src\JavaFinder.cpp" />

+    <ClCompile Include="..\src\JavaPath.cpp" />

+    <ClCompile Include="..\src\utils.cpp" />

+    <ClCompile Include="..\src\WinLauncher2App.cpp" />

+    <ClCompile Include="stdafx.cpp">

+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>

+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>

+    </ClCompile>

+  </ItemGroup>

+  <ItemGroup>

+    <ResourceCompile Include="WinLauncher2.rc" />

+  </ItemGroup>

+  <ItemGroup>

+    <Image Include="..\android_icon.ico" />

+  </ItemGroup>

+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+  <ImportGroup Label="ExtensionTargets">

+  </ImportGroup>

+</Project>
\ No newline at end of file
diff --git a/find_java2/WinLauncher2/res/WinLauncher2.ico b/find_java2/WinLauncher2/res/WinLauncher2.ico
new file mode 100755
index 0000000..d56fbcd
--- /dev/null
+++ b/find_java2/WinLauncher2/res/WinLauncher2.ico
Binary files differ
diff --git a/find_java2/WinLauncher2/stdafx.cpp b/find_java2/WinLauncher2/stdafx.cpp
new file mode 100755
index 0000000..00a69d2
--- /dev/null
+++ b/find_java2/WinLauncher2/stdafx.cpp
@@ -0,0 +1,24 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+

+// stdafx.cpp : source file that includes just the standard includes

+// WinLauncher2.pch will be the pre-compiled header

+// stdafx.obj will contain the pre-compiled type information

+

+#include "stdafx.h"

+

+

diff --git a/find_java2/WinLauncher2/stdafx.h b/find_java2/WinLauncher2/stdafx.h
new file mode 100755
index 0000000..86caf00
--- /dev/null
+++ b/find_java2/WinLauncher2/stdafx.h
@@ -0,0 +1,66 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+// stdafx.h : include file for standard system include files,

+// or project specific include files that are used frequently,

+// but are changed infrequently

+

+#pragma once

+

+#ifndef VC_EXTRALEAN

+#define VC_EXTRALEAN            // Exclude rarely-used stuff from Windows headers

+#endif

+

+#include "targetver.h"

+

+#define _CRT_SECURE_NO_WARNINGS

+

+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // some CString constructors will be explicit

+

+// turns off MFC's hiding of some common and often safely ignored warning messages

+#define _AFX_ALL_WARNINGS

+

+#include <afxwin.h>         // MFC core and standard components

+#include <afxext.h>         // MFC extensions

+

+

+#include <afxdisp.h>        // MFC Automation classes

+

+

+

+#ifndef _AFX_NO_OLE_SUPPORT

+#include <afxdtctl.h>           // MFC support for Internet Explorer 4 Common Controls

+#endif

+#ifndef _AFX_NO_AFXCMN_SUPPORT

+#include <afxcmn.h>             // MFC support for Windows Common Controls

+#endif // _AFX_NO_AFXCMN_SUPPORT

+

+#include <afxcontrolbars.h>     // MFC support for ribbons and control bars

+

+

+

+

+#ifdef _UNICODE

+#if defined _M_IX86

+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")

+#elif defined _M_X64

+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")

+#else

+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

+#endif

+#endif

+

+

diff --git a/find_java2/WinLauncher2/targetver.h b/find_java2/WinLauncher2/targetver.h
new file mode 100755
index 0000000..fc6d20b
--- /dev/null
+++ b/find_java2/WinLauncher2/targetver.h
@@ -0,0 +1,24 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+#pragma once

+

+// Including SDKDDKVer.h defines the highest available Windows platform.

+

+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and

+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.

+

+#include <SDKDDKVer.h>

diff --git a/find_java2/android_icon.ico b/find_java2/android_icon.ico
new file mode 100755
index 0000000..354bd5d
--- /dev/null
+++ b/find_java2/android_icon.ico
Binary files differ
diff --git a/find_java2/src/FindJava2Dlg.cpp b/find_java2/src/FindJava2Dlg.cpp
new file mode 100755
index 0000000..fbdd899
--- /dev/null
+++ b/find_java2/src/FindJava2Dlg.cpp
@@ -0,0 +1,268 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+

+#include "stdafx.h"

+#include "utils.h"

+#include "FindJava2Dlg.h"

+#include "afxdialogex.h"

+#include <atlpath.h>                            // ATL CPath

+

+#ifdef _DEBUG

+#define new DEBUG_NEW

+#endif

+

+#define COL_PATH 1

+

+

+CFindJava2Dlg::CFindJava2Dlg(CWnd* pParent /*=NULL*/)

+    : CDialog(CFindJava2Dlg::IDD, pParent), mSelectedIndex(-1) {

+    m_hIcon = AfxGetApp()->LoadIcon(IDI_ANDROID_ICON);

+}

+

+void CFindJava2Dlg::DoDataExchange(CDataExchange* pDX) {

+    CDialog::DoDataExchange(pDX);

+    DDX_Control(pDX, IDC_PATH_LIST, mPathsListCtrl);

+    DDX_Control(pDX, IDOK, mOkButton);

+}

+

+BEGIN_MESSAGE_MAP(CFindJava2Dlg, CDialog)

+    ON_WM_PAINT()

+    ON_WM_QUERYDRAGICON()

+    ON_BN_CLICKED(IDC_BUTTON_ADD, &CFindJava2Dlg::OnBnClickedButtonAdd)

+    ON_NOTIFY(NM_CLICK, IDC_PATH_LIST, &CFindJava2Dlg::OnNMClickPathList)

+    ON_NOTIFY(LVN_ITEMCHANGED, IDC_PATH_LIST, &CFindJava2Dlg::OnLvnItemchangedPathList)

+END_MESSAGE_MAP()

+

+

+// -----

+// CFindJava2Dlg message handlers

+

+BOOL CFindJava2Dlg::OnInitDialog() {

+    CDialog::OnInitDialog();

+

+    SetWindowText(getAppName());

+

+    // Set the icon for this dialog.  The framework does this automatically

+    //  when the application's main window is not a dialog

+    SetIcon(m_hIcon, TRUE);			// Set big icon

+    SetIcon(m_hIcon, FALSE);		// Set small icon

+

+    // Initialize list controls

+    mPathsListCtrl.SetExtendedStyle(

+        mPathsListCtrl.GetExtendedStyle() |

+        LVS_EX_CHECKBOXES | 

+        LVS_EX_FULLROWSELECT | 

+        LVS_EX_GRIDLINES);

+

+    // We want 2 columns: Java version and path

+    mPathsListCtrl.InsertColumn(0, _T("Version"), LVCFMT_RIGHT, 60,  0);

+    mPathsListCtrl.InsertColumn(1, _T("Path"),     LVCFMT_LEFT, 386, 0);

+

+    mJavaFinder->findJavaPaths(&mPaths);

+    fillPathsList();

+    adjustButtons();

+

+    return TRUE;  // return TRUE  unless you set the focus to a control

+}

+

+// If you add a minimize button to your dialog, you will need the code below

+// to draw the icon.  For MFC applications using the document/view model,

+// this is automatically done for you by the framework.

+// [Note: MFC boilerplate, keep as-is]

+void CFindJava2Dlg::OnPaint() {

+    if (IsIconic()) {

+        CPaintDC dc(this); // device context for painting

+

+        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

+

+        // Center icon in client rectangle

+        int cxIcon = GetSystemMetrics(SM_CXICON);

+        int cyIcon = GetSystemMetrics(SM_CYICON);

+        CRect rect;

+        GetClientRect(&rect);

+        int x = (rect.Width() - cxIcon + 1) / 2;

+        int y = (rect.Height() - cyIcon + 1) / 2;

+

+        // Draw the icon

+        dc.DrawIcon(x, y, m_hIcon);

+    } else {

+        CDialog::OnPaint();

+    }

+}

+

+// The system calls this function to obtain the cursor to display while the user drags

+// the minimized window. [Note: MFC boilerplate, keep as-is]

+HCURSOR CFindJava2Dlg::OnQueryDragIcon() {

+    return static_cast<HCURSOR>(m_hIcon);

+}

+

+// Button add has been pressed; use file dialog and add path if it's a valid java.exe

+void CFindJava2Dlg::OnBnClickedButtonAdd() {

+    CFileDialog fileDlg(

+        TRUE,           // true=open dialog,  false=save-as dialog

+        _T("exe"),      // lpszDefExt 

+        _T("java.exe"), // lpszFileName 

+        OFN_FILEMUSTEXIST || OFN_PATHMUSTEXIST,

+        NULL,           // lpszFilter

+        this);          // pParentWnd

+

+    if (fileDlg.DoModal() == IDOK) {

+        CString path = fileDlg.GetPathName();

+

+        CJavaPath javaPath;

+        if (!mJavaFinder->checkJavaPath(path, &javaPath)) {

+            CString msg;

+            if (javaPath.mVersion > 0) {

+                msg.Format(_T("Insufficient Java Version found: expected %s, got %s"), 

+                           CJavaPath(mJavaFinder->getMinVersion(), CPath()).getVersion(),

+                           javaPath.getVersion());

+            } else {

+                msg.Format(_T("No valid Java Version found for %s"), path);

+            }

+            AfxMessageBox(msg, MB_OK);

+

+        } else {

+            if (mPaths.find(javaPath) == mPaths.end()) {

+                // Path isn't known yet so add it and refresh the list.

+                mPaths.insert(javaPath);

+                fillPathsList();

+            }

+

+            // Select item in list and set mSelectedIndex

+            selectPath(-1 /*index*/, &javaPath);

+        }

+    }

+}

+

+// An item in the list has been selected, select checkmark and set mSelectedIndex.

+void CFindJava2Dlg::OnNMClickPathList(NMHDR *pNMHDR, LRESULT *pResult) {

+    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);

+    int index = pNMItemActivate->iItem;

+    selectPath(index, nullptr);

+    *pResult = TRUE;

+}

+

+// An item in the list has changed, toggle checkmark as needed.

+void CFindJava2Dlg::OnLvnItemchangedPathList(NMHDR *pNMHDR, LRESULT *pResult) {

+    *pResult = FALSE;

+    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);

+

+    if ((pNMLV->uChanged & LVIF_STATE) != 0) {

+        // Item's state has changed. Check the selection to see if it needs to be adjusted.

+        int index = pNMLV->iItem;

+

+        UINT oldState = pNMLV->uOldState;

+        UINT newState = pNMLV->uNewState;

+

+        if ((oldState & LVIS_STATEIMAGEMASK) != 0 || (newState & LVIS_STATEIMAGEMASK) != 0) {

+            // Checkbox uses the STATEIMAGE: 1 for unchecked, 2 for checked.

+            // Checkbox is checked when (old/new-state & state-image-mask) == INDEXTOSTATEIMAGEMASK(2).

+

+            bool oldChecked = (oldState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK(2);

+            bool newChecked = (newState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK(2);

+

+            if (oldChecked && !newChecked && index == mSelectedIndex) {

+                mSelectedIndex = -1;

+                adjustButtons();

+            } else if (!oldChecked && newChecked && index != mSelectedIndex) {

+                // Uncheck any checked rows if any

+                for (int n = mPathsListCtrl.GetItemCount() - 1; n >= 0; --n) {

+                    if (n != index && mPathsListCtrl.GetCheck(n)) {

+                        mPathsListCtrl.SetCheck(n, FALSE);

+                    }

+                }

+

+                mSelectedIndex = index;

+                adjustButtons();

+            }

+            // We handled this case, don't dispatch it further

+            *pResult = TRUE;

+        }

+    }

+}

+

+// -----

+

+const CJavaPath& CFindJava2Dlg::getSelectedPath() {

+    int i = 0;

+    for (const CJavaPath &p : mPaths) {

+        if (i == mSelectedIndex) {

+            return p;

+        }

+        ++i;

+    }

+

+    return CJavaPath::sEmpty;

+}

+

+

+void CFindJava2Dlg::fillPathsList() {

+    mPathsListCtrl.DeleteAllItems();

+    int index = 0;

+

+    for (const CJavaPath& pv : mPaths) {

+        mPathsListCtrl.InsertItem(index, pv.getVersion());        // column 0 = version

+        mPathsListCtrl.SetItemText(index, COL_PATH, pv.mPath);    // column 1 = path

+        mPathsListCtrl.SetCheck(index, mSelectedIndex == index);

+        ++index;

+    }

+}

+

+// Checks the given index if valid. Unchecks all other items.

+//

+// If index >= 0, it is used to select that item from the ListControl.

+// Otherwise if path != nullptr, it is used to find the item and select it.

+//

+// Side effect: in both cases, mSelectedIndex is set to the matching index or -1.

+//

+// If index is invalid and path isn't in the mPaths list, all items are unselected

+// so calling this with (0, nullptr) will clear the current selection.

+void CFindJava2Dlg::selectPath(int index, const CJavaPath *path) {

+

+    const CJavaPath *foundPath;

+    // If index is not defined, find the given path in the internal list.

+    // If path is not defined, find its index in the internal list.

+    int i = 0;

+    int n = mPathsListCtrl.GetItemCount();

+    for (const CJavaPath &p : mPaths) {

+        if (index < 0 && path != nullptr && p == *path) {

+            index = i;

+            foundPath = path;

+        } else if (index == i) {

+            foundPath = &p;

+        }

+

+        // uncheck any marked path

+        if (i != index && i < n && mPathsListCtrl.GetCheck(i)) {

+            mPathsListCtrl.SetCheck(i, FALSE);

+        }

+

+        ++i;

+    }

+

+    mSelectedIndex = index;

+    if (index >= 0 && index <= n) {

+        mPathsListCtrl.SetCheck(index, TRUE);

+    }

+

+    adjustButtons();

+}

+

+void CFindJava2Dlg::adjustButtons() {

+    int n = mPathsListCtrl.GetItemCount();

+    mOkButton.EnableWindow(mSelectedIndex >= 0 && mSelectedIndex < n);

+}

diff --git a/find_java2/src/FindJava2Dlg.h b/find_java2/src/FindJava2Dlg.h
new file mode 100755
index 0000000..7e0943c
--- /dev/null
+++ b/find_java2/src/FindJava2Dlg.h
@@ -0,0 +1,64 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+#pragma once

+#include "afxwin.h"

+#include "JavaFinder.h"

+

+#include "resource.h"		// main symbols

+

+

+// CFindJava2Dlg dialog

+class CFindJava2Dlg : public CDialog {

+    // Construction

+public:

+    CFindJava2Dlg(CWnd* pParent = NULL);	// standard constructor

+

+    void setJavaFinder(CJavaFinder *javaFinder) { mJavaFinder = javaFinder;  }

+    const CJavaPath& getSelectedPath();

+

+    // Dialog Data

+    enum { IDD = IDD_FINDJAVA2_DIALOG };

+

+protected:

+    virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support

+

+

+    // Implementation

+protected:

+    HICON m_hIcon;

+

+    // Generated message map functions

+    virtual BOOL OnInitDialog();

+    afx_msg void OnPaint();

+    afx_msg HCURSOR OnQueryDragIcon();

+    DECLARE_MESSAGE_MAP()

+

+    afx_msg void OnBnClickedButtonAdd();

+    afx_msg void OnNMClickPathList(NMHDR *pNMHDR, LRESULT *pResult);

+    afx_msg void OnLvnItemchangedPathList(NMHDR *pNMHDR, LRESULT *pResult);

+

+private:

+    std::set<CJavaPath> mPaths;

+    int mSelectedIndex;

+    CJavaFinder *mJavaFinder;

+    CListCtrl mPathsListCtrl;

+    CButton mOkButton;

+

+    void fillPathsList();

+    void adjustButtons();

+    void selectPath(int index = -1, const CJavaPath *path = nullptr);

+};

diff --git a/find_java2/src/JavaFinder.cpp b/find_java2/src/JavaFinder.cpp
new file mode 100755
index 0000000..60a2e23
--- /dev/null
+++ b/find_java2/src/JavaFinder.cpp
@@ -0,0 +1,594 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+#include "stdafx.h"

+#include "JavaFinder.h"

+#include "utils.h"

+

+#include <algorithm>        // std::sort and std::unique

+

+#define  _CRT_SECURE_NO_WARNINGS

+

+// --------------

+

+#define JF_REGISTRY_KEY         _T("Software\\Android\\FindJava2")

+#define JF_REGISTRY_VALUE_PATH  _T("JavaPath")

+#define JF_REGISTRY_VALUE_VERS  _T("JavaVers")

+

+// --------------

+

+

+// 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 TCHAR *start,

+                               int length,

+                               CString *outVersionStr,

+                               int *outVersionInt) {

+    const TCHAR *end = start + length;

+    for (const TCHAR *c = start; c < end - 2; c++) {

+        if (isdigit(c[0]) &&

+            c[1] == '.' &&

+            isdigit(c[2])) {

+            const TCHAR *e = c + 2;

+            while (isdigit(e[1])) {

+                e++;

+            }

+            outVersionStr->SetString(c, e - c + 1);

+

+            // major is currently only 1 digit

+            int major = (*c - '0');

+            // add minor

+            int minor = 0;

+            for (int m = 1; *e != '.'; e--, m *= 10) {

+                minor += (*e - '0') * m;

+            }

+            *outVersionInt = JAVA_VERS_TO_INT(major, minor);

+            return true;

+        }

+    }

+    return false;

+}

+

+// Tries to invoke the java.exe at the given path and extract it's

+// version number.

+// - outVersionStr: not null, will capture version as a string (e.g. "1.6")

+// - outVersionInt: not null, will capture version as an int (see JavaPath.h).

+bool getJavaVersion(CPath &javaPath, CString *outVersionStr, int *outVersionInt) {

+    bool result = false;

+

+    // Run "java -version", which outputs something to *STDERR* like this:

+    //

+    // 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.Format(_T("\"%s\" -version"), (LPCTSTR) javaPath);

+

+    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)

+        // In FindJava2, we do not report these errors. Leave commented for reference.

+        // // if (gIsConsole || gIsDebug) displayLastError("CreatePipe failed: ");

+        return false;

+    }

+    if (!SetHandleInformation(stdoutPipeRd, HANDLE_FLAG_INHERIT, 0)) {

+        // In FindJava2, we do not report these errors. Leave commented for reference.

+        // // 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 = CreateProcess(

+        NULL,                   // program path

+        (LPTSTR)((LPCTSTR) cmd),// 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);

+

+    // In FindJava2, we do not report these errors. Leave commented for reference.

+    // // 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.

+    TCHAR 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

+            // Note: ReadFile uses a char buffer, not a TCHAR one.

+            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 capture roughtly the first line in lower case.

+        TCHAR *j = _tcsstr(first32, _T("java"));

+        TCHAR *v = _tcsstr(first32, _T("version"));

+        // In FindJava2, we do not report these errors. Leave commented for reference.

+        // // if ((gIsConsole || gIsDebug) && (!j || !v)) {

+        // //     fprintf(stderr, "Error: keywords 'java version' not found in '%s'\n", first32);

+        // // }

+        if (j != NULL && v != NULL) {

+            result = extractJavaVersion(first32, index, outVersionStr, outVersionInt);

+        }

+    }

+

+    return result;

+}

+

+// --------------

+

+// Checks 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) {

+

+    // Append java.exe to path if not already present

+    CString &p = (CString&)*inOutPath;

+    int n = p.GetLength();

+    if (n < 9 || p.Right(9).CompareNoCase(_T("\\java.exe")) != 0) {

+        inOutPath->Append(_T("java.exe"));

+    }

+

+    int result = 0;

+    PVOID oldWow64Value = disableWow64FsRedirection();

+    if (inOutPath->FileExists()) {

+        // Run java -version

+        // Reject the version if it's not at least our current minimum.

+        CString versionStr;

+        if (!getJavaVersion(*inOutPath, &versionStr, &result)) {

+            result = 0;

+        }

+    }

+

+    revertWow64FsRedirection(oldWow64Value);

+    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) {

+

+    // Append bin to path if not already present

+    CString &p = (CString&)*inOutPath;

+    int n = p.GetLength();

+    if (n < 4 || p.Right(4).CompareNoCase(_T("\\bin")) != 0) {

+        inOutPath->Append(_T("bin"));

+    }

+

+    return checkPath(inOutPath);

+}

+

+// Search java.exe in the environment

+static void findJavaInEnvPath(std::set<CJavaPath> *outPaths) {

+    ::SetLastError(0);

+

+    const TCHAR* envPath = _tgetenv(_T("JAVA_HOME"));

+    if (envPath != NULL) {

+        CPath p(envPath);

+        int v = checkBinPath(&p);

+        if (v > 0) {

+            outPaths->insert(CJavaPath(v, p));

+        }

+    }

+

+    envPath = _tgetenv(_T("PATH"));

+    if (envPath != NULL) {

+        // Otherwise look at the entries in the current path.

+        // If we find more than one, keep the one with the highest version.

+        CString pathTokens(envPath);

+        int curPos = 0;

+        CString tok;

+        do {

+            tok = pathTokens.Tokenize(_T(";"), curPos);

+            if (!tok.IsEmpty()) {

+                CPath p(tok);

+                int v = checkPath(&p);

+                if (v > 0) {

+                    outPaths->insert(CJavaPath(v, p));

+                }

+            }

+        } while (!tok.IsEmpty());

+    }

+}

+

+

+// --------------

+

+static bool getRegValue(const TCHAR *keyPath,

+                        const TCHAR *keyName,

+                        REGSAM access,

+                        CString *outValue) {

+    HKEY key;

+    LSTATUS status = RegOpenKeyEx(

+        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

+        TCHAR* buffer = (TCHAR*)malloc(size);

+

+        while (ret == ERROR_MORE_DATA && size < (1 << 16) /*64 KB*/) {

+            ret = RegQueryValueEx(

+                key,                // hKey

+                keyName,            // lpValueName

+                NULL,               // lpReserved

+                NULL,               // lpType

+                (LPBYTE)buffer,     // lpData

+                &size);             // lpcbData

+

+            if (ret == ERROR_MORE_DATA) {

+                size *= 2;

+                buffer = (TCHAR*)realloc(buffer, size);

+            } else {

+                buffer[size] = 0;

+            }

+        }

+

+        if (ret != ERROR_MORE_DATA) {

+            outValue->SetString(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 TCHAR *entry, REGSAM access, std::set<CJavaPath> *outPaths) {

+

+    // Let's visit HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment [CurrentVersion]

+    CPath rootKey(_T("SOFTWARE\\JavaSoft\\"));

+    rootKey.Append(entry);

+

+    CString currentVersion;

+    CPath subKey(rootKey);

+    if (getRegValue(subKey, _T("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.Append(currentVersion);

+        CString value;

+        if (getRegValue(subKey, _T("JavaHome"), access, &value)) {

+            CPath javaHome(value);

+            int v = checkBinPath(&javaHome);

+            if (v > 0) {

+                outPaths->insert(CJavaPath(v, javaHome));

+            }

+        }

+    }

+

+    // Try again, but this time look at all the versions available

+    HKEY javaHomeKey;

+    LSTATUS status = RegOpenKeyEx(

+        HKEY_LOCAL_MACHINE,         // hKey

+        _T("SOFTWARE\\JavaSoft"),   // lpSubKey

+        0,                          // ulOptions

+        KEY_READ | access,          // samDesired

+        &javaHomeKey);              // phkResult

+    if (status == ERROR_SUCCESS) {

+        TCHAR name[MAX_PATH + 1];

+        DWORD index = 0;

+        CPath javaHome;

+        for (LONG result = ERROR_SUCCESS; result == ERROR_SUCCESS; index++) {

+            DWORD nameLen = MAX_PATH;

+            name[nameLen] = 0;

+            result = RegEnumKeyEx(

+                javaHomeKey,  // hKey

+                index,        // dwIndex

+                name,         // lpName

+                &nameLen,     // lpcName

+                NULL,         // lpReserved

+                NULL,         // lpClass

+                NULL,         // lpcClass,

+                NULL);        // lpftLastWriteTime

+            if (result == ERROR_SUCCESS && nameLen < MAX_PATH) {

+                name[nameLen] = 0;

+                CPath subKey(rootKey);

+                subKey.Append(name);

+

+                CString value;

+                if (getRegValue(subKey, _T("JavaHome"), access, &value)) {

+                    CPath javaHome(value);

+                    int v = checkBinPath(&javaHome);

+                    if (v > 0) {

+                        outPaths->insert(CJavaPath(v, javaHome));

+                    }

+                }

+            }

+        }

+

+        RegCloseKey(javaHomeKey);

+    }

+

+    return 0;

+}

+

+static void findJavaInRegistry(std::set<CJavaPath> *outPaths) {

+    // We'll do the registry test 3 times: first using the default mode,

+    // then forcing the use of the 32-bit registry then forcing the use of

+    // 64-bit registry. On Windows 2k, the 2 latter will fail since the

+    // flags are not supported. On a 32-bit OS the 64-bit is obviously

+    // useless and the 2 first tests should be equivalent so we just

+    // need the first case.

+

+    // Check the JRE first, then the JDK.

+    exploreJavaRegistry(_T("Java Runtime Environment"), 0, outPaths);

+    exploreJavaRegistry(_T("Java Development Kit"), 0, outPaths);

+

+    // Get the app sysinfo state (the one hidden by WOW64)

+    SYSTEM_INFO sysInfo;

+    GetSystemInfo(&sysInfo);

+    WORD programArch = sysInfo.wProcessorArchitecture;

+    // Check the real sysinfo state (not the one hidden by WOW64) for x86

+    GetNativeSystemInfo(&sysInfo);

+    WORD actualArch = sysInfo.wProcessorArchitecture;

+

+    // Only try to access the WOW64-32 redirected keys on a 64-bit system.

+    // There's no point in doing this on a 32-bit system.

+    if (actualArch == PROCESSOR_ARCHITECTURE_AMD64) {

+        if (programArch != PROCESSOR_ARCHITECTURE_INTEL) {

+            // If we did the 32-bit case earlier, don't do it twice.

+            exploreJavaRegistry(_T("Java Runtime Environment"), KEY_WOW64_32KEY, outPaths);

+            exploreJavaRegistry(_T("Java Development Kit"),     KEY_WOW64_32KEY, outPaths);

+

+        } else if (programArch != PROCESSOR_ARCHITECTURE_AMD64) {

+            // If we did the 64-bit case earlier, don't do it twice.

+            exploreJavaRegistry(_T("Java Runtime Environment"), KEY_WOW64_64KEY, outPaths);

+            exploreJavaRegistry(_T("Java Development Kit"),     KEY_WOW64_64KEY, outPaths);

+        }

+    }

+}

+

+// --------------

+

+static void checkProgramFiles(std::set<CJavaPath> *outPaths) {

+

+    TCHAR programFilesPath[MAX_PATH + 1];

+    HRESULT result = SHGetFolderPath(

+        NULL,                       // hwndOwner

+        CSIDL_PROGRAM_FILES,        // nFolder

+        NULL,                       // hToken

+        SHGFP_TYPE_CURRENT,         // dwFlags

+        programFilesPath);          // pszPath

+

+    CPath path(programFilesPath);

+    path.Append(_T("Java"));

+

+    // Do we have a C:\\Program Files\\Java directory?

+    if (!path.IsDirectory()) {

+        return;

+    }

+

+    CPath glob(path);

+    glob.Append(_T("j*"));

+

+    WIN32_FIND_DATA findData;

+    HANDLE findH = FindFirstFile(glob, &findData);

+    if (findH == INVALID_HANDLE_VALUE) {

+        return;

+    }

+    do {

+        if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {

+            CPath temp(path);

+            temp.Append(findData.cFileName);

+            // Check C:\\Program Files[x86]\\Java\\j*\\bin\\java.exe

+            int v = checkBinPath(&temp);

+            if (v > 0) {

+                outPaths->insert(CJavaPath(v, temp));

+            }

+        }

+    } while (FindNextFile(findH, &findData) != 0);

+    FindClose(findH);

+}

+

+static void findJavaInProgramFiles(std::set<CJavaPath> *outPaths) {

+    // Check the C:\\Program Files (x86) directory

+    // With WOW64 fs redirection in place by default, we should get the x86

+    // version on a 64-bit OS since this app is a 32-bit itself.

+    checkProgramFiles(outPaths);

+

+    // Check the real sysinfo state (not the one hidden by WOW64) for x86

+    SYSTEM_INFO sysInfo;

+    GetNativeSystemInfo(&sysInfo);

+

+    if (sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {

+        // On a 64-bit OS, try again by disabling the fs redirection so

+        // that we can try the real C:\\Program Files directory.

+        PVOID oldWow64Value = disableWow64FsRedirection();

+        checkProgramFiles(outPaths);

+        revertWow64FsRedirection(oldWow64Value);

+    }

+}

+

+//------

+

+

+CJavaFinder::CJavaFinder(int minVersion) : mMinVersion(minVersion) {

+}

+

+

+CJavaFinder::~CJavaFinder() {

+}

+

+/*

+ * Checks whether there's a recorded path in the registry and whether

+ * this path still points to a valid Java executable.

+ * Returns false if any of these do not match,

+ * Returns true if both condition match,

+ * outPath contains the result path when returning true.

+*/

+CJavaPath CJavaFinder::getRegistryPath() {

+    CString existing;

+    CRegKey rk;

+

+    if (rk.Open(HKEY_CURRENT_USER, JF_REGISTRY_KEY, KEY_READ) == ERROR_SUCCESS) {

+        ULONG sLen = MAX_PATH;

+        TCHAR s[MAX_PATH + 1];

+        if (rk.QueryStringValue(JF_REGISTRY_VALUE_PATH, s, &sLen) == ERROR_SUCCESS) {

+            existing.SetString(s);

+        }

+        rk.Close();

+    }

+

+    if (!existing.IsEmpty()) {

+        CJavaPath javaPath;

+        if (checkJavaPath(existing, &javaPath)) {

+            return javaPath;

+        }

+    }

+

+    return CJavaPath::sEmpty;

+}

+

+bool CJavaFinder::setRegistryPath(const CJavaPath &javaPath) {

+    CRegKey rk;

+

+    if (rk.Create(HKEY_CURRENT_USER, JF_REGISTRY_KEY) == ERROR_SUCCESS) {

+        bool ok = rk.SetStringValue(JF_REGISTRY_VALUE_PATH, javaPath.mPath, REG_SZ) == ERROR_SUCCESS &&

+                  rk.SetStringValue(JF_REGISTRY_VALUE_VERS, javaPath.getVersion(), REG_SZ) == ERROR_SUCCESS;

+        rk.Close();

+        return ok;

+    }

+

+    return false;

+}

+

+void CJavaFinder::findJavaPaths(std::set<CJavaPath> *paths) {

+    findJavaInEnvPath(paths);

+    findJavaInProgramFiles(paths);

+    findJavaInRegistry(paths);

+

+    // Exclude any entries that do not match the minimum version.

+    // The set is going to be fairly small so it's easier to do it here

+    // than add the filter logic in all the static methods above.

+    if (mMinVersion > 0) {

+        for (auto it = paths->begin(); it != paths->end(); ) {

+            if (it->mVersion < mMinVersion) {

+                it = paths->erase(it);  // C++11 set.erase returns an iterator to the *next* element

+            } else {

+                ++it;

+            }

+        }

+    }

+}

+

+bool CJavaFinder::checkJavaPath(const CString &path, CJavaPath *outPath) {

+    CPath p(path);

+

+    // try this path (if it ends with java.exe) or path\\java.exe

+    int v = checkPath(&p);

+    if (v == 0) {

+        // reset path and try path\\bin\\java.exe

+        p = CPath(path);

+        v = checkBinPath(&p);

+    }

+

+    if (v > 0) {

+        outPath->set(v, p);

+        return v >= mMinVersion;

+    }

+

+    return false;

+}

+

diff --git a/find_java2/src/JavaFinder.h b/find_java2/src/JavaFinder.h
new file mode 100755
index 0000000..c22b008
--- /dev/null
+++ b/find_java2/src/JavaFinder.h
@@ -0,0 +1,52 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+#pragma once

+

+

+#include <set>                                  // STL std::set

+#include "JavaPath.h"

+

+class CJavaFinder {

+public:

+    // Creates a new JavaFinder.

+    // minVersion to accept, using JAVA_VERS_TO_INT macro. 0 to accept everything.

+    CJavaFinder(int minVersion = 0);

+    ~CJavaFinder();

+

+    int getMinVersion() const { return mMinVersion;  }

+

+    // Returns the path recorded in the registry.

+    // If there is no path or it is no longer valid, returns an empty string.

+    CJavaPath getRegistryPath();

+

+    // Sets the given path as the default to use in the registry.

+    // Returns true on success.

+    bool setRegistryPath(const CJavaPath &javaPath);

+

+    // Scans the registry, the environment and program files for potential Java.exe locations.

+    // Fills the given set with the tuples (version, path) found, guaranteed sorted and unique.

+    void findJavaPaths(std::set<CJavaPath> *paths);

+

+    // Checks the given path for a given java.exe.

+    // Input path variation tried are: path as-is, path/java.exe or path/bin/java.exe.

+    // Places the java path and version in outPath;

+    // Returns true if a java path was found *and* its version is at least mMinVersion.

+    bool checkJavaPath(const CString &path, CJavaPath *outPath);

+

+private:

+    int mMinVersion;

+};

diff --git a/find_java2/src/JavaPath.cpp b/find_java2/src/JavaPath.cpp
new file mode 100755
index 0000000..ebe30c5
--- /dev/null
+++ b/find_java2/src/JavaPath.cpp
@@ -0,0 +1,97 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+#include "stdafx.h"

+#include "JavaPath.h"

+#include "utils.h"

+

+#define  _CRT_SECURE_NO_WARNINGS

+

+// --------------

+

+const CJavaPath CJavaPath::sEmpty = CJavaPath();

+

+CJavaPath::CJavaPath(int version, CPath path) : mVersion(version), mPath(path) {

+    mPath.Canonicalize();

+}

+

+bool CJavaPath::isEmpty() const {

+    return mVersion <= 0;

+}

+

+void CJavaPath::clear() {

+    mVersion = 0;

+    mPath = CPath();

+}

+

+void CJavaPath::set(int version, CPath path) {

+    mVersion = version;

+    mPath = path;

+    mPath.Canonicalize();

+}

+

+CString CJavaPath::getVersion() const {

+    CString s;

+    s.Format(_T("%d.%d"), JAVA_MAJOR(mVersion), JAVA_MINOR(mVersion));

+    return s;

+}

+

+

+bool CJavaPath::toShortPath() {

+    const TCHAR *longPath = mPath;

+    if (longPath == nullptr) {

+        return false;

+    }

+

+    DWORD lenShort = _tcslen(longPath) + 1;

+    TCHAR *shortPath = (TCHAR *)malloc(lenShort * sizeof(TCHAR));

+

+    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 = (TCHAR *)malloc(length);

+        length = GetShortPathName(longPath, shortPath, lenShort);

+    }

+

+    if (length != 0) {

+        mPath = CPath(shortPath);

+    }

+

+    free(shortPath);

+    return length != 0;

+}

+

+bool CJavaPath::operator< (const CJavaPath& rhs) const {

+    if (mVersion != rhs.mVersion) {

+        // sort in reverse order on the version

+        return rhs.mVersion > mVersion;

+    }

+    // sort in normal order on the path

+    const CString &pl = mPath;

+    const CString &pr = rhs.mPath;

+    return pl.Compare(pr) < 0;

+}

+

+bool CJavaPath::operator== (const CJavaPath& rhs) const {

+    if (mVersion == rhs.mVersion) {

+        const CString &pl = mPath;

+        const CString &pr = rhs.mPath;

+        return pl.Compare(pr) == 0;

+    }

+    return false;

+}

diff --git a/find_java2/src/JavaPath.h b/find_java2/src/JavaPath.h
new file mode 100755
index 0000000..b7f40a5
--- /dev/null
+++ b/find_java2/src/JavaPath.h
@@ -0,0 +1,57 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+#pragma once

+

+#include <atlpath.h>                            // ATL CPath

+

+

+// Transforms a Java major.minor number (e.g. "1.7") to internal int value (1007)

+#define JAVA_VERS_TO_INT(major, minor)  ((major) * 1000 + (minor))

+// Extracts the major part from the internal int major.minor number

+#define JAVA_MAJOR(majorMinor)          ((majorMinor) / 1000)

+// Extracts the minor part from the internal int major.minor number

+#define JAVA_MINOR(majorMinor)          ((majorMinor) % 1000)

+

+

+struct CJavaPath {

+    int mVersion;

+    CPath mPath;

+

+    // Static empty path that can be returned as a reference.

+    static const CJavaPath sEmpty;

+

+    CJavaPath() : mVersion(0) {}

+    CJavaPath(int version, CPath path);

+    void set(int version, CPath path);

+

+    // Returns true if path/version is empty/0

+    bool isEmpty() const;

+

+    // Clears path and version to 0

+    void clear();

+

+    // Converts the internal path into a short DOS path.

+    // Returns true if this was possible and false if the conversion failed.

+    bool toShortPath();

+

+    // Returns the version formatted as a string (e.g. "1.7" instead of 1007.)

+    CString getVersion() const;

+

+    // Operators < and == for this to be suitable in an ordered std::set

+    bool operator<  (const CJavaPath& rhs) const;

+    bool operator== (const CJavaPath& rhs) const;

+};

diff --git a/find_java2/src/WinLauncher2App.cpp b/find_java2/src/WinLauncher2App.cpp
new file mode 100755
index 0000000..392ad9e
--- /dev/null
+++ b/find_java2/src/WinLauncher2App.cpp
@@ -0,0 +1,154 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+

+#include "stdafx.h"

+#include "WinLauncher2App.h"

+

+#include "utils.h"

+#include "JavaFinder.h"

+#include "FindJava2Dlg.h"

+

+#ifdef _DEBUG

+#define new DEBUG_NEW

+#endif

+

+

+// CWinLauncher2App

+

+BEGIN_MESSAGE_MAP(CWinLauncher2App, CWinApp)

+    ON_COMMAND(ID_HELP, &CWinApp::OnHelp)

+END_MESSAGE_MAP()

+

+

+// The one and only CWinLauncher2App object

+CWinLauncher2App theApp;

+

+class CLauncherCmdLineInfo : public CCommandLineInfo {

+public:

+    bool mDoHelp;

+    bool mDoForceUi;

+    bool mDoJava1_7;

+    CString mFilename;

+

+    CLauncherCmdLineInfo() : mDoHelp(false), mDoForceUi(false), mDoJava1_7(false) {}

+

+    virtual void ParseParam(const TCHAR* pszParam, BOOL bFlag, BOOL bLast) {

+        // Expected command line:

+        // /h | help  : msg box with command line arguments

+        // /f | force : force UI selection

+        // /7         : require java 1.7

+        // path-to-launch

+

+        if (!bFlag) {

+            mFilename = pszParam;

+        } else if (_tcsnccmp(pszParam, _T("h"), 2) == 0) {

+            mDoHelp = true;

+        } else if (_tcsnccmp(pszParam, _T("f"), 2) == 0) {

+            mDoForceUi = true;

+        } else if (_tcsnccmp(pszParam, _T("7"), 2) == 0) {

+            mDoJava1_7 = true;

+        }

+    }

+};

+

+

+CWinLauncher2App::CWinLauncher2App() {

+    // support Restart Manager

+    m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;

+

+    // TODO: add construction code here,

+    // Place all significant initialization in InitInstance

+}

+

+BOOL CWinLauncher2App::InitInstance() {

+    // InitCommonControlsEx() is required on Windows XP if an application

+    // manifest specifies use of ComCtl32.dll version 6 or later to enable

+    // visual styles.  Otherwise, any window creation will fail.

+    INITCOMMONCONTROLSEX InitCtrls;

+    InitCtrls.dwSize = sizeof(InitCtrls);

+    // Set this to include all the common control classes you want to use

+    // in your application.

+    InitCtrls.dwICC = ICC_WIN95_CLASSES;

+    InitCommonControlsEx(&InitCtrls);

+

+    CWinApp::InitInstance();

+    AfxEnableControlContainer();

+

+    // Create the shell manager, in case the dialog contains

+    // any shell tree view or shell list view controls.

+    CShellManager *pShellManager = new CShellManager;

+

+    // Activate "Windows Native" visual manager for enabling themes in MFC controls

+    CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

+

+    // Set CWinApp default registry key. Must be consistent with all apps using findjava2.

+    SetRegistryKey(_T("Android-FindJava2"));

+

+    // Use VERSIONINFO.FileDescription as the canonical app name

+    initUtils(NULL);

+

+    CLauncherCmdLineInfo cmdLine;

+    ParseCommandLine(cmdLine);

+

+    if (cmdLine.mDoHelp) {

+        const TCHAR *msg =

+            _T("WinLauncher2 [/7|/f|/h]\r\n")

+            _T("/7 : Requires Java 1.7 instead of 1.6\r\n")

+            _T("/f : Force UI\r\n")

+            _T("/h : Help\r\n");

+            AfxMessageBox(msg);

+        return FALSE; // quit without starting MFC app msg loop

+    }

+

+    CJavaFinder javaFinder(JAVA_VERS_TO_INT(1, cmdLine.mDoJava1_7 ? 7 : 6));

+    CJavaPath javaPath = javaFinder.getRegistryPath();

+    if (cmdLine.mDoForceUi || javaPath.isEmpty()) {

+        javaPath.clear();

+

+        CFindJava2Dlg dlg;

+        dlg.setJavaFinder(&javaFinder);

+        m_pMainWnd = &dlg;

+        INT_PTR nResponse = dlg.DoModal();

+

+        if (nResponse == IDOK) {

+            // Use choice selected by user and save in registry.

+            javaPath = dlg.getSelectedPath();

+            javaFinder.setRegistryPath(javaPath);

+        } else if (nResponse == IDCANCEL) {

+            // Canceled by user, exit silently.

+        } else if (nResponse == -1) {

+            TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n");

+        }

+    }

+

+    if (!javaPath.isEmpty()) {

+        // TODO actually launch configured app instead of just printing path.

+        CString msg(_T("PLACEHOLDER TODO run app using "));

+        msg.Append(javaPath.mPath);

+        AfxMessageBox(msg);

+    }

+

+    // Delete the shell manager created above.

+    if (pShellManager != NULL) {

+        delete pShellManager;

+    }

+

+    // Since the dialog has been closed, return FALSE so that we exit the

+    // application, rather than start the application's message pump.

+    return FALSE;

+}

+

diff --git a/find_java2/src/WinLauncher2App.h b/find_java2/src/WinLauncher2App.h
new file mode 100755
index 0000000..11aca97
--- /dev/null
+++ b/find_java2/src/WinLauncher2App.h
@@ -0,0 +1,43 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+#pragma once

+

+#ifndef __AFXWIN_H__

+	#error "include 'stdafx.h' before including this file for PCH"

+#endif

+

+#include "resource.h"		// main symbols

+

+

+// CWinLauncher2App:

+// See WinLauncher2.cpp for the implementation of this class

+//

+

+class CWinLauncher2App : public CWinApp {

+public:

+	CWinLauncher2App();

+

+// Overrides

+public:

+	virtual BOOL InitInstance();

+

+// Implementation

+

+	DECLARE_MESSAGE_MAP()

+};

+

+extern CWinLauncher2App theApp;
\ No newline at end of file
diff --git a/find_java2/src/utils.cpp b/find_java2/src/utils.cpp
new file mode 100755
index 0000000..7c8c66b
--- /dev/null
+++ b/find_java2/src/utils.cpp
@@ -0,0 +1,282 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+#include "stdafx.h"

+#include "utils.h"

+

+// 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;

+

+// Application name used in error dialog. Defined using initUtils()

+static CString gAppName("Find Java 2");

+

+// Called by the application to initialize the app name used in error dialog boxes.

+void initUtils(const TCHAR *appName) {

+    if (appName != NULL) {

+        gAppName = CString(appName);

+        return;

+    }

+

+    // Try to get the VERSIONINFO.FileDescription and use as app name

+    // Errors are ignored, in which case the default app name is used.

+

+    // First get the module (aka app instance) filename.

+    TCHAR moduleName[MAX_PATH + 1];

+    DWORD sz = ::GetModuleFileName(NULL /*AfxGetInstanceHandle()*/, moduleName, MAX_PATH);

+    if (sz == 0) {

+        // GetModuleFileName failed. Do nothing.

+        return;

+    }

+    moduleName[sz] = '\0';  // make sure string is properly terminated.

+

+    // Get the size of the FileVersionInfo buffer

+    DWORD obsoleteHandle; // see http://blogs.msdn.com/b/oldnewthing/archive/2007/07/31/4138786.aspx

+    DWORD fviSize = ::GetFileVersionInfoSize(moduleName, &obsoleteHandle);

+    if (fviSize == 0) {

+        return; // do nothing on error

+    }

+

+    char *fviBuffer = new char[fviSize];

+    if (::GetFileVersionInfo(moduleName, 0, fviSize, fviBuffer) != 0) {

+        VOID *vBuffer;

+        UINT vLen;

+

+        struct LANGUAGE_CODEPAGE {

+            WORD mLanguage;

+            WORD mCodePage;

+        } *lgcpBuffer;

+

+        UINT lgcpSize;

+

+        // Read the list of languages and code pages (c.f. MSDN for VerQueryValue)

+        if (::VerQueryValue(fviBuffer, _T("\\VarFileInfo\\Translation"), (LPVOID*)&lgcpBuffer, &lgcpSize) != 0 &&

+                lgcpSize >= sizeof(LANGUAGE_CODEPAGE)) {

+            // Use the first available language and code page

+            CString subBlock;

+            subBlock.Format(_T("\\StringFileInfo\\%04x%04x\\FileDescription"),

+                            lgcpBuffer[0].mLanguage,

+                            lgcpBuffer[0].mCodePage);

+            if (::VerQueryValue(fviBuffer, subBlock, &vBuffer, &vLen) != 0) {

+                gAppName.SetString((LPCTSTR)vBuffer, vLen);

+            }

+        }

+    }

+    delete[] fviBuffer;

+}

+

+CString getAppName() {

+    return gAppName;

+}

+

+

+// Displays a message in an ok+info dialog box.

+void msgBox(const TCHAR* text, ...) {

+    CString formatted;

+    va_list ap;

+    va_start(ap, text);

+    formatted.FormatV(text, ap);

+    va_end(ap);

+

+    // TODO global CString to get app name

+    MessageBox(NULL, formatted, gAppName, MB_OK | MB_ICONINFORMATION);

+}

+

+// Sets the string to the message matching Win32 GetLastError.

+// If message is non-null, it is prepended to the last error string.

+CString getLastWin32Error(const TCHAR* message) {

+    DWORD err = GetLastError();

+    CString result;

+    LPTSTR errStr;

+    if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | /* dwFlags */

+                      FORMAT_MESSAGE_FROM_SYSTEM,

+                      NULL,                             /* lpSource */

+                      err,                              /* dwMessageId */

+                      0,                                /* dwLanguageId */

+                      (LPTSTR) &errStr,                 /* out lpBuffer */

+                      0,                                /* nSize */

+                      NULL) != 0) {                     /* va_list args */

+        if (message == NULL) {

+            result.Format(_T("[%d] %s"), err, errStr);

+        } else {

+            result.Format(_T("%s[%d] %s"), message, err, errStr);

+        }

+        LocalFree(errStr);

+    }

+    return result;

+}

+

+// Displays GetLastError prefixed with a description in an error dialog box

+void displayLastError(const TCHAR *description, ...) {

+    CString formatted;

+    va_list ap;

+    va_start(ap, description);

+    formatted.FormatV(description, ap);

+    va_end(ap);

+

+    CString error = getLastWin32Error(NULL);

+    formatted.Append(_T("\r\n"));

+    formatted.Append(error);

+

+    if (gIsConsole) {

+        _ftprintf(stderr, _T("%s\n"), (LPCTSTR) formatted);

+    } else {

+        CString name(gAppName);

+        name.Append(_T(" - Error"));

+        MessageBox(NULL, formatted, name, 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 TCHAR *app, const TCHAR *params, const TCHAR *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 = CreateProcess(

+        app,                                        /* program path */

+        (TCHAR *)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 TCHAR *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 = CreateProcess(

+        NULL,                                       /* program path */

+        (LPTSTR)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) {

+    TCHAR programDir[MAX_PATH];

+    int ret = GetModuleFileName(NULL, programDir, sizeof(programDir) / sizeof(programDir[0]));

+    if (ret != 0) {

+        CPath dir(programDir);

+        dir.RemoveFileSpec();

+        *outDir = dir;

+        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(_T("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(_T("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);

+    }

+}

diff --git a/find_java2/src/utils.h b/find_java2/src/utils.h
new file mode 100755
index 0000000..3557f58
--- /dev/null
+++ b/find_java2/src/utils.h
@@ -0,0 +1,59 @@
+/*

+* Copyright (C) 2014 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.

+*/

+

+#pragma once

+

+#include <atlpath.h>                            // ATL CPath

+

+// Global flag indicating whether this is running in debug mode (more printfs)

+extern bool gIsDebug;

+// Global flag indicating whether this is running in console mode or GUI.

+// In console mode, errors are written on the console; in GUI they use a MsgBox.

+extern bool gIsConsole;

+

+// Must be called by the application to initialize the app name used in error dialog boxes.

+// If NULL is used, fetches VERSIONINFO.FileDescription from resources if available.

+void initUtils(const TCHAR *appName);

+

+// Returns the app name set in initUtils

+CString getAppName();

+

+// Displays a message in an ok+info dialog box. Useful in console mode.

+void msgBox(const TCHAR* text, ...);

+

+// Displays GetLastError prefixed with a description in an error dialog box. Useful in console mode.

+void displayLastError(const TCHAR *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 TCHAR *app, const TCHAR *params, const TCHAR *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 TCHAR *cmd);

+

+bool getModuleDir(CPath *outDir);

+

+// 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.

+PVOID disableWow64FsRedirection();

+

+// Reverts the redirection disabled in disableWow64FsRedirection.

+void revertWow64FsRedirection(PVOID oldWow64Value);