1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "stdafx.h" 18 #include "FindJava2.h" 19 #include "utils.h" 20 #include "JavaFinder.h" 21 #include "FindJava2Dlg.h" 22 23 #ifdef _DEBUG 24 #define new DEBUG_NEW 25 #endif 26 27 // The one and only MFC application object 28 class CFindJava2App : public CWinApp { 29 public: 30 CFindJava2App() { 31 } 32 33 // Set CWinApp default registry key. Must be consistent with all apps using findjava2. 34 void initRegistryKey() { 35 SetRegistryKey(_T("Android-FindJava2")); 36 } 37 }; 38 39 CFindJava2App theApp; 40 41 using namespace std; 42 43 int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { 44 45 // Init utils; use default app name based on VERSIONINFO.FileDescription 46 initUtils(NULL); 47 48 // initialize MFC and print and error on failure 49 HMODULE hModule = ::GetModuleHandle(NULL); 50 if (hModule == NULL) { 51 displayLastError(_T("Fatal Error: ")); 52 return -2; 53 } 54 if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0)) { 55 displayLastError(_T("Fatal Error: ")); 56 return -3; 57 } 58 59 theApp.initRegistryKey(); 60 61 gIsConsole = true; // tell utils to to print errors to stderr 62 gIsDebug = (getenv("ANDROID_SDKMAN_DEBUG") != NULL); 63 64 // Parse command line 65 bool doTests = false; 66 bool doShortPath = false; 67 bool doVersion = false; 68 bool doJavaW = false; 69 bool doForceUi = false; 70 bool doJava1_7 = false; 71 72 for (int i = 1; i < argc; i++) { 73 if (_tcsnccmp(argv[i], _T("-t"), 2) == 0) { 74 doTests = true; 75 76 } else if (_tcsnccmp(argv[i], _T("-d"), 2) == 0) { 77 gIsDebug = true; 78 79 } else if (_tcsnccmp(argv[i], _T("-s"), 2) == 0) { 80 doShortPath = true; 81 82 } else if (_tcsnccmp(argv[i], _T("-v"), 2) == 0) { 83 doVersion = true; 84 85 } else if (_tcsnccmp(argv[i], _T("-f"), 2) == 0) { 86 doForceUi = true; 87 88 } else if (_tcsnccmp(argv[i], _T("-7"), 2) == 0) { 89 doJava1_7 = true; 90 91 } else if (_tcscmp(argv[i], _T("-w")) == 0 || _tcscmp(argv[i], _T("-javaw")) == 0) { 92 doJavaW = true; 93 94 } else { 95 printf( 96 "Outputs the path of the first Java.exe found on the local system.\n" 97 "Returns code 0 when found, 1 when not found.\n" 98 "Options:\n" 99 "-h / -help : This help.\n" 100 "-t / -test : Internal test.\n" 101 "-f / -force : Force UI selection.\n" 102 "-7 : Java 1.7 minimum instead of 1.6.\n" 103 "-s / -short : Print path in short DOS form.\n" 104 "-w / -javaw : Search a matching javaw.exe; defaults to java.exe if not found.\n" 105 "-v / -version: Only prints the Java version found.\n" 106 ); 107 return 2; 108 } 109 } 110 111 112 CJavaFinder javaFinder(JAVA_VERS_TO_INT(1, doJava1_7 ? 7 : 6)); 113 CJavaPath javaPath = javaFinder.getRegistryPath(); 114 115 if (doTests) { 116 std::set<CJavaPath> paths; 117 javaFinder.findJavaPaths(&paths); 118 bool regPrinted = false; 119 for (const CJavaPath &p : paths) { 120 bool isReg = (p == javaPath); 121 if (isReg) { 122 regPrinted = true; 123 } 124 _tprintf(_T("%c [%s] %s\n"), isReg ? '*' : ' ', p.getVersion(), p.mPath); 125 } 126 127 if (!regPrinted && !javaPath.isEmpty()) { 128 const CJavaPath &p = javaPath; 129 _tprintf(_T("* [%s] %s\n"), p.getVersion(), p.mPath); 130 } 131 return 0; 132 } 133 134 if (doForceUi || javaPath.isEmpty()) { 135 CFindJava2Dlg dlg; 136 dlg.setJavaFinder(&javaFinder); 137 INT_PTR nResponse = dlg.DoModal(); 138 139 if (nResponse == IDOK) { 140 // Get java path selected by user and save into registry for later re-use 141 javaPath = dlg.getSelectedPath(); 142 javaFinder.setRegistryPath(javaPath); 143 } else if (nResponse == -1) { // MFC boilerplate 144 TRACE(traceAppMsg, 0, "Warning: dialog creation failed, so application is terminating unexpectedly.\n"); 145 return 1; 146 } 147 } 148 149 if (javaPath.isEmpty()) { 150 fprintf(stderr, "No java.exe path found"); 151 return 1; 152 } 153 154 if (doShortPath) { 155 PVOID oldWow64Value = disableWow64FsRedirection(); 156 if (!javaPath.toShortPath()) { 157 revertWow64FsRedirection(&oldWow64Value); 158 _ftprintf(stderr, 159 _T("Failed to convert path to a short DOS path: %s\n"), 160 javaPath.mPath); 161 return 1; 162 } 163 revertWow64FsRedirection(&oldWow64Value); 164 } 165 166 if (doVersion) { 167 // Print version found. We already have the version as an integer 168 // so we don't need to run java -version a second time. 169 _tprintf(_T("%s"), javaPath.getVersion()); 170 return 0; 171 } 172 173 if (doJavaW) { 174 // Try to find a javaw.exe instead of java.exe at the same location. 175 CPath javawPath = javaPath.mPath; 176 javawPath.RemoveFileSpec(); 177 javawPath.Append(_T("javaw.exe")); 178 javawPath.Canonicalize(); 179 180 // Only accept it if we can actually find the exec 181 PVOID oldWow64Value = disableWow64FsRedirection(); 182 bool exists = javawPath.FileExists() == TRUE; // skip BOOL-to-bool warning 183 revertWow64FsRedirection(&oldWow64Value); 184 185 if (!exists) { 186 _ftprintf(stderr, 187 _T("Failed to find javaw at: %s\n"), 188 javawPath); 189 return 1; 190 } 191 192 javaPath.mPath = javawPath; 193 } 194 195 // Print java.exe path found 196 _tprintf(_T("%s"), javaPath.mPath); 197 return 0; 198 199 } 200