aboutsummaryrefslogtreecommitdiff
path: root/find_java2/src/utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'find_java2/src/utils.cpp')
-rwxr-xr-xfind_java2/src/utils.cpp282
1 files changed, 282 insertions, 0 deletions
diff --git a/find_java2/src/utils.cpp b/find_java2/src/utils.cpp
new file mode 100755
index 000000000..7c8c66b67
--- /dev/null
+++ b/find_java2/src/utils.cpp
@@ -0,0 +1,282 @@
+/*
+* Copyright (C) 2014 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "stdafx.h"
+#include "utils.h"
+
+// Set to true to get some extra debug information
+bool gIsDebug = false;
+// Set to true to output errors to stderr (for a Console app)
+// or to false to output using msg box (for a Windows UI app)
+bool gIsConsole = false;
+
+// Application name used in error dialog. Defined using initUtils()
+static CString gAppName("Find Java 2");
+
+// Called by the application to initialize the app name used in error dialog boxes.
+void initUtils(const TCHAR *appName) {
+ if (appName != NULL) {
+ gAppName = CString(appName);
+ return;
+ }
+
+ // Try to get the VERSIONINFO.FileDescription and use as app name
+ // Errors are ignored, in which case the default app name is used.
+
+ // First get the module (aka app instance) filename.
+ TCHAR moduleName[MAX_PATH + 1];
+ DWORD sz = ::GetModuleFileName(NULL /*AfxGetInstanceHandle()*/, moduleName, MAX_PATH);
+ if (sz == 0) {
+ // GetModuleFileName failed. Do nothing.
+ return;
+ }
+ moduleName[sz] = '\0'; // make sure string is properly terminated.
+
+ // Get the size of the FileVersionInfo buffer
+ DWORD obsoleteHandle; // see http://blogs.msdn.com/b/oldnewthing/archive/2007/07/31/4138786.aspx
+ DWORD fviSize = ::GetFileVersionInfoSize(moduleName, &obsoleteHandle);
+ if (fviSize == 0) {
+ return; // do nothing on error
+ }
+
+ char *fviBuffer = new char[fviSize];
+ if (::GetFileVersionInfo(moduleName, 0, fviSize, fviBuffer) != 0) {
+ VOID *vBuffer;
+ UINT vLen;
+
+ struct LANGUAGE_CODEPAGE {
+ WORD mLanguage;
+ WORD mCodePage;
+ } *lgcpBuffer;
+
+ UINT lgcpSize;
+
+ // Read the list of languages and code pages (c.f. MSDN for VerQueryValue)
+ if (::VerQueryValue(fviBuffer, _T("\\VarFileInfo\\Translation"), (LPVOID*)&lgcpBuffer, &lgcpSize) != 0 &&
+ lgcpSize >= sizeof(LANGUAGE_CODEPAGE)) {
+ // Use the first available language and code page
+ CString subBlock;
+ subBlock.Format(_T("\\StringFileInfo\\%04x%04x\\FileDescription"),
+ lgcpBuffer[0].mLanguage,
+ lgcpBuffer[0].mCodePage);
+ if (::VerQueryValue(fviBuffer, subBlock, &vBuffer, &vLen) != 0) {
+ gAppName.SetString((LPCTSTR)vBuffer, vLen);
+ }
+ }
+ }
+ delete[] fviBuffer;
+}
+
+CString getAppName() {
+ return gAppName;
+}
+
+
+// Displays a message in an ok+info dialog box.
+void msgBox(const TCHAR* text, ...) {
+ CString formatted;
+ va_list ap;
+ va_start(ap, text);
+ formatted.FormatV(text, ap);
+ va_end(ap);
+
+ // TODO global CString to get app name
+ MessageBox(NULL, formatted, gAppName, MB_OK | MB_ICONINFORMATION);
+}
+
+// Sets the string to the message matching Win32 GetLastError.
+// If message is non-null, it is prepended to the last error string.
+CString getLastWin32Error(const TCHAR* message) {
+ DWORD err = GetLastError();
+ CString result;
+ LPTSTR errStr;
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | /* dwFlags */
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, /* lpSource */
+ err, /* dwMessageId */
+ 0, /* dwLanguageId */
+ (LPTSTR) &errStr, /* out lpBuffer */
+ 0, /* nSize */
+ NULL) != 0) { /* va_list args */
+ if (message == NULL) {
+ result.Format(_T("[%d] %s"), err, errStr);
+ } else {
+ result.Format(_T("%s[%d] %s"), message, err, errStr);
+ }
+ LocalFree(errStr);
+ }
+ return result;
+}
+
+// Displays GetLastError prefixed with a description in an error dialog box
+void displayLastError(const TCHAR *description, ...) {
+ CString formatted;
+ va_list ap;
+ va_start(ap, description);
+ formatted.FormatV(description, ap);
+ va_end(ap);
+
+ CString error = getLastWin32Error(NULL);
+ formatted.Append(_T("\r\n"));
+ formatted.Append(error);
+
+ if (gIsConsole) {
+ _ftprintf(stderr, _T("%s\n"), (LPCTSTR) formatted);
+ } else {
+ CString name(gAppName);
+ name.Append(_T(" - Error"));
+ MessageBox(NULL, formatted, name, MB_OK | MB_ICONERROR);
+ }
+}
+
+// Executes the command line. Does not wait for the program to finish.
+// The return code is from CreateProcess (0 means failure), not the running app.
+int execNoWait(const TCHAR *app, const TCHAR *params, const TCHAR *workDir) {
+ STARTUPINFO startup;
+ PROCESS_INFORMATION pinfo;
+
+ ZeroMemory(&pinfo, sizeof(pinfo));
+
+ ZeroMemory(&startup, sizeof(startup));
+ startup.cb = sizeof(startup);
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_SHOWDEFAULT;
+
+ int ret = CreateProcess(
+ app, /* program path */
+ (TCHAR *)params, /* command-line */
+ NULL, /* process handle is not inheritable */
+ NULL, /* thread handle is not inheritable */
+ TRUE, /* yes, inherit some handles */
+ 0, /* create flags */
+ NULL, /* use parent's environment block */
+ workDir, /* use parent's starting directory */
+ &startup, /* startup info, i.e. std handles */
+ &pinfo);
+
+ if (ret) {
+ CloseHandle(pinfo.hProcess);
+ CloseHandle(pinfo.hThread);
+ }
+
+ return ret;
+}
+
+// Executes command, waits for completion and returns exit code.
+// As indicated in MSDN for CreateProcess, callers should double-quote the program name
+// e.g. cmd="\"c:\program files\myapp.exe\" arg1 arg2";
+int execWait(const TCHAR *cmd) {
+ STARTUPINFO startup;
+ PROCESS_INFORMATION pinfo;
+
+ ZeroMemory(&pinfo, sizeof(pinfo));
+
+ ZeroMemory(&startup, sizeof(startup));
+ startup.cb = sizeof(startup);
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_HIDE | SW_MINIMIZE;
+
+ int ret = CreateProcess(
+ NULL, /* program path */
+ (LPTSTR)cmd, /* command-line */
+ NULL, /* process handle is not inheritable */
+ NULL, /* thread handle is not inheritable */
+ TRUE, /* yes, inherit some handles */
+ CREATE_NO_WINDOW, /* we don't want a console */
+ NULL, /* use parent's environment block */
+ NULL, /* use parent's starting directory */
+ &startup, /* startup info, i.e. std handles */
+ &pinfo);
+
+ int result = -1;
+ if (ret) {
+ WaitForSingleObject(pinfo.hProcess, INFINITE);
+
+ DWORD exitCode;
+ if (GetExitCodeProcess(pinfo.hProcess, &exitCode)) {
+ // this should not return STILL_ACTIVE (259)
+ result = exitCode;
+ }
+ CloseHandle(pinfo.hProcess);
+ CloseHandle(pinfo.hThread);
+ }
+
+ return result;
+}
+
+bool getModuleDir(CPath *outDir) {
+ TCHAR programDir[MAX_PATH];
+ int ret = GetModuleFileName(NULL, programDir, sizeof(programDir) / sizeof(programDir[0]));
+ if (ret != 0) {
+ CPath dir(programDir);
+ dir.RemoveFileSpec();
+ *outDir = dir;
+ return true;
+ }
+ return false;
+}
+
+// Disables the FS redirection done by WOW64.
+// Because this runs as a 32-bit app, Windows automagically remaps some
+// folder under the hood (e.g. "Programs Files(x86)" is mapped as "Program Files").
+// This prevents the app from correctly searching for java.exe in these folders.
+// The registry is also remapped. This method disables this redirection.
+// Caller should restore the redirection later by using revertWow64FsRedirection().
+PVOID disableWow64FsRedirection() {
+
+ // The call we want to make is the following:
+ // PVOID oldWow64Value;
+ // Wow64DisableWow64FsRedirection(&oldWow64Value);
+ // However that method may not exist (e.g. on XP non-64 systems) so
+ // we must not call it directly.
+
+ PVOID oldWow64Value = 0;
+
+ HMODULE hmod = LoadLibrary(_T("kernel32.dll"));
+ if (hmod != NULL) {
+ FARPROC proc = GetProcAddress(hmod, "Wow64DisableWow64FsRedirection");
+ if (proc != NULL) {
+ typedef BOOL(WINAPI *disableWow64FuncType)(PVOID *);
+ disableWow64FuncType funcPtr = (disableWow64FuncType)proc;
+ funcPtr(&oldWow64Value);
+ }
+
+ FreeLibrary(hmod);
+ }
+
+ return oldWow64Value;
+}
+
+// Reverts the redirection disabled in disableWow64FsRedirection.
+void revertWow64FsRedirection(PVOID oldWow64Value) {
+
+ // The call we want to make is the following:
+ // Wow64RevertWow64FsRedirection(oldWow64Value);
+ // However that method may not exist (e.g. on XP non-64 systems) so
+ // we must not call it directly.
+
+ HMODULE hmod = LoadLibrary(_T("kernel32.dll"));
+ if (hmod != NULL) {
+ FARPROC proc = GetProcAddress(hmod, "Wow64RevertWow64FsRedirection");
+ if (proc != NULL) {
+ typedef BOOL(WINAPI *revertWow64FuncType)(PVOID);
+ revertWow64FuncType funcPtr = (revertWow64FuncType)proc;
+ funcPtr(oldWow64Value);
+ }
+
+ FreeLibrary(hmod);
+ }
+}