1 /* 2 * Copyright (C) 2011 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 #ifdef _WIN32 18 19 #include "utils.h" 20 21 #define _CRT_SECURE_NO_WARNINGS 1 22 23 // Set to true to get some extra debug information 24 bool gIsDebug = false; 25 // Set to true to output errors to stderr (for a Console app) 26 // or to false to output using msg box (for a Windows UI app) 27 bool gIsConsole = false; 28 29 // Displays a message in an ok+info dialog box. 30 void msgBox(const char* text, ...) { 31 CString formatted; 32 va_list ap; 33 va_start(ap, text); 34 formatted.setv(text, ap); 35 va_end(ap); 36 37 MessageBoxA(NULL, formatted.cstr(), "Android SDK Manager", MB_OK | MB_ICONINFORMATION); 38 } 39 40 // Displays GetLastError prefixed with a description in an error dialog box 41 void displayLastError(const char *description, ...) { 42 CString formatted; 43 va_list ap; 44 va_start(ap, description); 45 formatted.setv(description, ap); 46 va_end(ap); 47 48 CString error; 49 error.setLastWin32Error(NULL); 50 formatted.add("\r\n"); 51 formatted.add(error.cstr()); 52 53 if (gIsConsole) { 54 fprintf(stderr, "%s\n", formatted.cstr()); 55 } else { 56 MessageBox(NULL, formatted.cstr(), "Android SDK Manager - Error", MB_OK | MB_ICONERROR); 57 } 58 } 59 60 // Executes the command line. Does not wait for the program to finish. 61 // The return code is from CreateProcess (0 means failure), not the running app. 62 int execNoWait(const char *app, const char *params, const char *workDir) { 63 STARTUPINFO startup; 64 PROCESS_INFORMATION pinfo; 65 66 ZeroMemory(&pinfo, sizeof(pinfo)); 67 68 ZeroMemory(&startup, sizeof(startup)); 69 startup.cb = sizeof(startup); 70 startup.dwFlags = STARTF_USESHOWWINDOW; 71 startup.wShowWindow = SW_SHOWDEFAULT; 72 73 int ret = CreateProcessA( 74 (LPSTR) app, /* program path */ 75 (LPSTR) params, /* command-line */ 76 NULL, /* process handle is not inheritable */ 77 NULL, /* thread handle is not inheritable */ 78 TRUE, /* yes, inherit some handles */ 79 0, /* create flags */ 80 NULL, /* use parent's environment block */ 81 workDir, /* use parent's starting directory */ 82 &startup, /* startup info, i.e. std handles */ 83 &pinfo); 84 85 if (ret) { 86 CloseHandle(pinfo.hProcess); 87 CloseHandle(pinfo.hThread); 88 } 89 90 return ret; 91 } 92 93 // Executes command, waits for completion and returns exit code. 94 // As indicated in MSDN for CreateProcess, callers should double-quote the program name 95 // e.g. cmd="\"c:\program files\myapp.exe\" arg1 arg2"; 96 int execWait(const char *cmd) { 97 STARTUPINFO startup; 98 PROCESS_INFORMATION pinfo; 99 100 ZeroMemory(&pinfo, sizeof(pinfo)); 101 102 ZeroMemory(&startup, sizeof(startup)); 103 startup.cb = sizeof(startup); 104 startup.dwFlags = STARTF_USESHOWWINDOW; 105 startup.wShowWindow = SW_HIDE|SW_MINIMIZE; 106 107 int ret = CreateProcessA( 108 NULL, /* program path */ 109 (LPSTR) cmd, /* command-line */ 110 NULL, /* process handle is not inheritable */ 111 NULL, /* thread handle is not inheritable */ 112 TRUE, /* yes, inherit some handles */ 113 CREATE_NO_WINDOW, /* we don't want a console */ 114 NULL, /* use parent's environment block */ 115 NULL, /* use parent's starting directory */ 116 &startup, /* startup info, i.e. std handles */ 117 &pinfo); 118 119 int result = -1; 120 if (ret) { 121 WaitForSingleObject(pinfo.hProcess, INFINITE); 122 123 DWORD exitCode; 124 if (GetExitCodeProcess(pinfo.hProcess, &exitCode)) { 125 // this should not return STILL_ACTIVE (259) 126 result = exitCode; 127 } 128 CloseHandle(pinfo.hProcess); 129 CloseHandle(pinfo.hThread); 130 } 131 132 return result; 133 } 134 135 bool getModuleDir(CPath *outDir) { 136 CHAR programDir[MAX_PATH]; 137 int ret = GetModuleFileName(NULL, programDir, sizeof(programDir)); 138 if (ret != 0) { 139 // Remove the last segment to keep only the directory. 140 int pos = ret - 1; 141 while (pos > 0 && programDir[pos] != '\\') { 142 --pos; 143 } 144 outDir->set(programDir, pos); 145 return true; 146 } 147 return false; 148 } 149 150 // Disables the FS redirection done by WOW64. 151 // Because this runs as a 32-bit app, Windows automagically remaps some 152 // folder under the hood (e.g. "Programs Files(x86)" is mapped as "Program Files"). 153 // This prevents the app from correctly searching for java.exe in these folders. 154 // The registry is also remapped. This method disables this redirection. 155 // Caller should restore the redirection later by using revertWow64FsRedirection(). 156 PVOID disableWow64FsRedirection() { 157 158 // The call we want to make is the following: 159 // PVOID oldWow64Value; 160 // Wow64DisableWow64FsRedirection(&oldWow64Value); 161 // However that method may not exist (e.g. on XP non-64 systems) so 162 // we must not call it directly. 163 164 PVOID oldWow64Value = 0; 165 166 HMODULE hmod = LoadLibrary("kernel32.dll"); 167 if (hmod != NULL) { 168 FARPROC proc = GetProcAddress(hmod, "Wow64DisableWow64FsRedirection"); 169 if (proc != NULL) { 170 typedef BOOL (WINAPI *disableWow64FuncType)(PVOID *); 171 disableWow64FuncType funcPtr = (disableWow64FuncType)proc; 172 funcPtr(&oldWow64Value); 173 } 174 175 FreeLibrary(hmod); 176 } 177 178 return oldWow64Value; 179 } 180 181 // Reverts the redirection disabled in disableWow64FsRedirection. 182 void revertWow64FsRedirection(PVOID oldWow64Value) { 183 184 // The call we want to make is the following: 185 // Wow64RevertWow64FsRedirection(oldWow64Value); 186 // However that method may not exist (e.g. on XP non-64 systems) so 187 // we must not call it directly. 188 189 HMODULE hmod = LoadLibrary("kernel32.dll"); 190 if (hmod != NULL) { 191 FARPROC proc = GetProcAddress(hmod, "Wow64RevertWow64FsRedirection"); 192 if (proc != NULL) { 193 typedef BOOL (WINAPI *revertWow64FuncType)(PVOID); 194 revertWow64FuncType funcPtr = (revertWow64FuncType)proc; 195 funcPtr(oldWow64Value); 196 } 197 198 FreeLibrary(hmod); 199 } 200 } 201 202 #endif /* _WIN32 */ 203