Home | History | Annotate | Download | only in FindJava2
      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