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