upload android base code part9

This commit is contained in:
August 2018-08-08 20:16:11 +08:00
parent 5425409085
commit 071cdf34cd
2679 changed files with 329442 additions and 0 deletions

View file

@ -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

View file

@ -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;
}

View file

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

View file

@ -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

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View file

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

View file

@ -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

View file

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

View file

@ -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);
}

View file

@ -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);
};

View file

@ -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;
}

View file

@ -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;
};

View file

@ -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;
}

View file

@ -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;
};

View file

@ -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;
}

View file

@ -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;

View file

@ -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(TCHAR));
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);
}
}

View file

@ -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);