sdklauncher.c revision ea66c92f80d9745721cfa28e22f2726b76579158
16508be1224ddec08910c464d2a905c4c2e1f7d80Raphael/* 26508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * Copyright (C) 2009 The Android Open Source Project 36508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * 46508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * Licensed under the Apache License, Version 2.0 (the "License"); 56508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * you may not use this file except in compliance with the License. 66508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * You may obtain a copy of the License at 76508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * 86508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * http://www.apache.org/licenses/LICENSE-2.0 96508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * 106508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * Unless required by applicable law or agreed to in writing, software 116508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * distributed under the License is distributed on an "AS IS" BASIS, 126508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * See the License for the specific language governing permissions and 146508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * limitations under the License. 156508be1224ddec08910c464d2a905c4c2e1f7d80Raphael */ 166508be1224ddec08910c464d2a905c4c2e1f7d80Raphael 176508be1224ddec08910c464d2a905c4c2e1f7d80Raphael/* 186508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * The "SDK Launcher" is for Windows only. 196508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * This simple .exe will sit at the root of the Windows SDK 206508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * and currently simply executes tools\android.bat. 216508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * Eventually it should simply replace the batch file. 226508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * 236508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * TODO: 246508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * - create temp dir, always copy *.jar there, exec android.jar 256508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * - get jars to copy from some file 266508be1224ddec08910c464d2a905c4c2e1f7d80Raphael * - use a version number to copy jars only if needed (tools.revision?) 276508be1224ddec08910c464d2a905c4c2e1f7d80Raphael */ 286508be1224ddec08910c464d2a905c4c2e1f7d80Raphael 296508be1224ddec08910c464d2a905c4c2e1f7d80Raphael#ifdef _WIN32 306508be1224ddec08910c464d2a905c4c2e1f7d80Raphael 316508be1224ddec08910c464d2a905c4c2e1f7d80Raphael#include <stdio.h> 326508be1224ddec08910c464d2a905c4c2e1f7d80Raphael#include <windows.h> 336508be1224ddec08910c464d2a905c4c2e1f7d80Raphael 34ea66c92f80d9745721cfa28e22f2726b76579158Raphael 35ea66c92f80d9745721cfa28e22f2726b76579158Raphaelvoid display_error(LPSTR description) { 36ea66c92f80d9745721cfa28e22f2726b76579158Raphael DWORD err = GetLastError(); 37ea66c92f80d9745721cfa28e22f2726b76579158Raphael LPSTR s, s2; 38ea66c92f80d9745721cfa28e22f2726b76579158Raphael 39ea66c92f80d9745721cfa28e22f2726b76579158Raphael fprintf(stderr, "%s, error %ld\n", description, err); 40ea66c92f80d9745721cfa28e22f2726b76579158Raphael 41ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | /* dwFlags */ 42ea66c92f80d9745721cfa28e22f2726b76579158Raphael FORMAT_MESSAGE_FROM_SYSTEM, 43ea66c92f80d9745721cfa28e22f2726b76579158Raphael NULL, /* lpSource */ 44ea66c92f80d9745721cfa28e22f2726b76579158Raphael err, /* dwMessageId */ 45ea66c92f80d9745721cfa28e22f2726b76579158Raphael 0, /* dwLanguageId */ 46ea66c92f80d9745721cfa28e22f2726b76579158Raphael (LPSTR)&s, /* lpBuffer */ 47ea66c92f80d9745721cfa28e22f2726b76579158Raphael 0, /* nSize */ 48ea66c92f80d9745721cfa28e22f2726b76579158Raphael NULL) != 0) { /* va_list args */ 49ea66c92f80d9745721cfa28e22f2726b76579158Raphael fprintf(stderr, "%s", s); 50ea66c92f80d9745721cfa28e22f2726b76579158Raphael 51ea66c92f80d9745721cfa28e22f2726b76579158Raphael s2 = (LPSTR) malloc(strlen(description) + strlen(s) + 5); 52ea66c92f80d9745721cfa28e22f2726b76579158Raphael sprintf(s2, "%s\r\n%s", description, s); 53ea66c92f80d9745721cfa28e22f2726b76579158Raphael MessageBox(NULL, s2, "Android SDK Setup - Error", MB_OK); 54ea66c92f80d9745721cfa28e22f2726b76579158Raphael free(s2); 55ea66c92f80d9745721cfa28e22f2726b76579158Raphael LocalFree(s); 56ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 57ea66c92f80d9745721cfa28e22f2726b76579158Raphael} 58ea66c92f80d9745721cfa28e22f2726b76579158Raphael 59ea66c92f80d9745721cfa28e22f2726b76579158Raphael 60ea66c92f80d9745721cfa28e22f2726b76579158RaphaelHANDLE create_temp_file(LPSTR temp_filename) { 61ea66c92f80d9745721cfa28e22f2726b76579158Raphael 62ea66c92f80d9745721cfa28e22f2726b76579158Raphael HANDLE file_handle = INVALID_HANDLE_VALUE; 63ea66c92f80d9745721cfa28e22f2726b76579158Raphael LPSTR temp_path = (LPSTR) malloc(MAX_PATH); 64ea66c92f80d9745721cfa28e22f2726b76579158Raphael 65ea66c92f80d9745721cfa28e22f2726b76579158Raphael /* Get the temp directory path using GetTempPath. 66ea66c92f80d9745721cfa28e22f2726b76579158Raphael GetTempFilename indicates that the temp path dir should not be larger than MAX_PATH-14. 67ea66c92f80d9745721cfa28e22f2726b76579158Raphael */ 68ea66c92f80d9745721cfa28e22f2726b76579158Raphael int ret = GetTempPath(MAX_PATH - 14, temp_path); 69ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (ret > MAX_PATH || ret == 0) { 70ea66c92f80d9745721cfa28e22f2726b76579158Raphael display_error("GetTempPath failed"); 71ea66c92f80d9745721cfa28e22f2726b76579158Raphael free(temp_path); 72ea66c92f80d9745721cfa28e22f2726b76579158Raphael return INVALID_HANDLE_VALUE; 73ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 74ea66c92f80d9745721cfa28e22f2726b76579158Raphael 75ea66c92f80d9745721cfa28e22f2726b76579158Raphael /* Now get a temp filename in the temp directory. */ 76ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (!GetTempFileName(temp_path, "txt", 0, temp_filename)) { 77ea66c92f80d9745721cfa28e22f2726b76579158Raphael display_error("GetTempFileName failed"); 78ea66c92f80d9745721cfa28e22f2726b76579158Raphael 79ea66c92f80d9745721cfa28e22f2726b76579158Raphael } else { 80ea66c92f80d9745721cfa28e22f2726b76579158Raphael SECURITY_ATTRIBUTES sattr; 81ea66c92f80d9745721cfa28e22f2726b76579158Raphael ZeroMemory(&sattr, sizeof(sattr)); 82ea66c92f80d9745721cfa28e22f2726b76579158Raphael sattr.nLength = sizeof(SECURITY_ATTRIBUTES); 83ea66c92f80d9745721cfa28e22f2726b76579158Raphael sattr.bInheritHandle = TRUE; 84ea66c92f80d9745721cfa28e22f2726b76579158Raphael 85ea66c92f80d9745721cfa28e22f2726b76579158Raphael file_handle = CreateFile(temp_filename, // filename 86ea66c92f80d9745721cfa28e22f2726b76579158Raphael GENERIC_WRITE, // access: write 87ea66c92f80d9745721cfa28e22f2726b76579158Raphael FILE_SHARE_READ, // share mode: read OK 88ea66c92f80d9745721cfa28e22f2726b76579158Raphael &sattr, // security attributes 89ea66c92f80d9745721cfa28e22f2726b76579158Raphael CREATE_ALWAYS, // create even if exists 90ea66c92f80d9745721cfa28e22f2726b76579158Raphael FILE_ATTRIBUTE_NORMAL, // flags and attributes 91ea66c92f80d9745721cfa28e22f2726b76579158Raphael NULL); // template 92ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (file_handle == INVALID_HANDLE_VALUE) { 93ea66c92f80d9745721cfa28e22f2726b76579158Raphael display_error("Create temp file failed"); 94ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 95ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 96ea66c92f80d9745721cfa28e22f2726b76579158Raphael 97ea66c92f80d9745721cfa28e22f2726b76579158Raphael free(temp_path); 98ea66c92f80d9745721cfa28e22f2726b76579158Raphael return file_handle; 99ea66c92f80d9745721cfa28e22f2726b76579158Raphael} 100ea66c92f80d9745721cfa28e22f2726b76579158Raphael 101ea66c92f80d9745721cfa28e22f2726b76579158Raphael 102ea66c92f80d9745721cfa28e22f2726b76579158Raphaelvoid read_temp_file(LPSTR temp_filename) { 103ea66c92f80d9745721cfa28e22f2726b76579158Raphael HANDLE handle; 104ea66c92f80d9745721cfa28e22f2726b76579158Raphael 105ea66c92f80d9745721cfa28e22f2726b76579158Raphael handle = CreateFile(temp_filename, // filename 106ea66c92f80d9745721cfa28e22f2726b76579158Raphael GENERIC_READ, // access: read 107ea66c92f80d9745721cfa28e22f2726b76579158Raphael FILE_SHARE_READ, // share mode: read OK 108ea66c92f80d9745721cfa28e22f2726b76579158Raphael NULL, // security attributes 109ea66c92f80d9745721cfa28e22f2726b76579158Raphael OPEN_EXISTING, // only open existing file 110ea66c92f80d9745721cfa28e22f2726b76579158Raphael FILE_ATTRIBUTE_NORMAL, // flags and attributes 111ea66c92f80d9745721cfa28e22f2726b76579158Raphael NULL); // template 112ea66c92f80d9745721cfa28e22f2726b76579158Raphael 113ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (handle == INVALID_HANDLE_VALUE) { 114ea66c92f80d9745721cfa28e22f2726b76579158Raphael display_error("Open temp file failed"); 115ea66c92f80d9745721cfa28e22f2726b76579158Raphael return; 116ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 117ea66c92f80d9745721cfa28e22f2726b76579158Raphael 118ea66c92f80d9745721cfa28e22f2726b76579158Raphael /* Cap the size we're reading. 119ea66c92f80d9745721cfa28e22f2726b76579158Raphael 4K is good enough to display in a message box. 120ea66c92f80d9745721cfa28e22f2726b76579158Raphael */ 121ea66c92f80d9745721cfa28e22f2726b76579158Raphael DWORD size = 4096; 122ea66c92f80d9745721cfa28e22f2726b76579158Raphael 123ea66c92f80d9745721cfa28e22f2726b76579158Raphael LPSTR buffer = (LPSTR) malloc(size + 1); 124ea66c92f80d9745721cfa28e22f2726b76579158Raphael 125ea66c92f80d9745721cfa28e22f2726b76579158Raphael LPSTR p = buffer; 126ea66c92f80d9745721cfa28e22f2726b76579158Raphael DWORD num_left = size; 127ea66c92f80d9745721cfa28e22f2726b76579158Raphael DWORD num_read; 128ea66c92f80d9745721cfa28e22f2726b76579158Raphael do { 129ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (!ReadFile(handle, p, num_left, &num_read, NULL)) { 130ea66c92f80d9745721cfa28e22f2726b76579158Raphael display_error("Read Output failed"); 131ea66c92f80d9745721cfa28e22f2726b76579158Raphael break; 132ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 133ea66c92f80d9745721cfa28e22f2726b76579158Raphael 134ea66c92f80d9745721cfa28e22f2726b76579158Raphael num_left -= num_read; 135ea66c92f80d9745721cfa28e22f2726b76579158Raphael p += num_read; 136ea66c92f80d9745721cfa28e22f2726b76579158Raphael } while (num_read > 0); 137ea66c92f80d9745721cfa28e22f2726b76579158Raphael 138ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (p != buffer) { 139ea66c92f80d9745721cfa28e22f2726b76579158Raphael *p = 0; 140ea66c92f80d9745721cfa28e22f2726b76579158Raphael 141ea66c92f80d9745721cfa28e22f2726b76579158Raphael /* Only output the buffer if it contains special keywords WARNING or ERROR. */ 142ea66c92f80d9745721cfa28e22f2726b76579158Raphael char* s1 = strstr(buffer, "WARNING"); 143ea66c92f80d9745721cfa28e22f2726b76579158Raphael char* s2 = strstr(buffer, "ERROR"); 144ea66c92f80d9745721cfa28e22f2726b76579158Raphael 145ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (s2 != NULL && s2 < s1) { 146ea66c92f80d9745721cfa28e22f2726b76579158Raphael s1 = s2; 147ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 148ea66c92f80d9745721cfa28e22f2726b76579158Raphael 149ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (s1 != NULL) { 150ea66c92f80d9745721cfa28e22f2726b76579158Raphael /* We end the message at the first occurence of [INFO]. */ 151ea66c92f80d9745721cfa28e22f2726b76579158Raphael s2 = strstr(s1, "[INFO]"); 152ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (s2 != NULL) { 153ea66c92f80d9745721cfa28e22f2726b76579158Raphael *s2 = 0; 154ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 155ea66c92f80d9745721cfa28e22f2726b76579158Raphael 156ea66c92f80d9745721cfa28e22f2726b76579158Raphael MessageBox(NULL, s1, "Android SDK Setup - Output", MB_OK); 157ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 158ea66c92f80d9745721cfa28e22f2726b76579158Raphael 159ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 160ea66c92f80d9745721cfa28e22f2726b76579158Raphael 161ea66c92f80d9745721cfa28e22f2726b76579158Raphael free(buffer); 162ea66c92f80d9745721cfa28e22f2726b76579158Raphael 163ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (!CloseHandle(handle)) { 164ea66c92f80d9745721cfa28e22f2726b76579158Raphael display_error("CloseHandle read temp file failed"); 165ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 166ea66c92f80d9745721cfa28e22f2726b76579158Raphael} 167ea66c92f80d9745721cfa28e22f2726b76579158Raphael 168ea66c92f80d9745721cfa28e22f2726b76579158Raphael 1696508be1224ddec08910c464d2a905c4c2e1f7d80Raphaelint sdk_launcher() { 170ea66c92f80d9745721cfa28e22f2726b76579158Raphael int result = 0; 1716508be1224ddec08910c464d2a905c4c2e1f7d80Raphael STARTUPINFO startup; 1726508be1224ddec08910c464d2a905c4c2e1f7d80Raphael PROCESS_INFORMATION pinfo; 173ea66c92f80d9745721cfa28e22f2726b76579158Raphael CHAR program_path[MAX_PATH]; 1746508be1224ddec08910c464d2a905c4c2e1f7d80Raphael int ret; 175ea66c92f80d9745721cfa28e22f2726b76579158Raphael CHAR temp_filename[MAX_PATH]; 176ea66c92f80d9745721cfa28e22f2726b76579158Raphael HANDLE temp_handle; 177ea66c92f80d9745721cfa28e22f2726b76579158Raphael 178ea66c92f80d9745721cfa28e22f2726b76579158Raphael ZeroMemory(&pinfo, sizeof(pinfo)); 179ea66c92f80d9745721cfa28e22f2726b76579158Raphael 180ea66c92f80d9745721cfa28e22f2726b76579158Raphael temp_handle = create_temp_file(temp_filename); 181ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (temp_handle == INVALID_HANDLE_VALUE) { 182ea66c92f80d9745721cfa28e22f2726b76579158Raphael return 1; 183ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 1846508be1224ddec08910c464d2a905c4c2e1f7d80Raphael 1856508be1224ddec08910c464d2a905c4c2e1f7d80Raphael ZeroMemory(&startup, sizeof(startup)); 1866508be1224ddec08910c464d2a905c4c2e1f7d80Raphael startup.cb = sizeof(startup); 187ea66c92f80d9745721cfa28e22f2726b76579158Raphael startup.dwFlags = STARTF_USESTDHANDLES; 188ea66c92f80d9745721cfa28e22f2726b76579158Raphael startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE); 189ea66c92f80d9745721cfa28e22f2726b76579158Raphael startup.hStdOutput = temp_handle; 190ea66c92f80d9745721cfa28e22f2726b76579158Raphael startup.hStdError = temp_handle; 1916508be1224ddec08910c464d2a905c4c2e1f7d80Raphael 1926508be1224ddec08910c464d2a905c4c2e1f7d80Raphael /* get path of current program */ 1936508be1224ddec08910c464d2a905c4c2e1f7d80Raphael GetModuleFileName(NULL, program_path, sizeof(program_path)); 1946508be1224ddec08910c464d2a905c4c2e1f7d80Raphael 1956508be1224ddec08910c464d2a905c4c2e1f7d80Raphael ret = CreateProcess( 196ea66c92f80d9745721cfa28e22f2726b76579158Raphael NULL, /* program path */ 197ea66c92f80d9745721cfa28e22f2726b76579158Raphael "tools\\android.bat update sdk", /* command-line */ 1986508be1224ddec08910c464d2a905c4c2e1f7d80Raphael NULL, /* process handle is not inheritable */ 1996508be1224ddec08910c464d2a905c4c2e1f7d80Raphael NULL, /* thread handle is not inheritable */ 2006508be1224ddec08910c464d2a905c4c2e1f7d80Raphael TRUE, /* yes, inherit some handles */ 2016508be1224ddec08910c464d2a905c4c2e1f7d80Raphael CREATE_NO_WINDOW, /* we don't want a console */ 2026508be1224ddec08910c464d2a905c4c2e1f7d80Raphael NULL, /* use parent's environment block */ 2036508be1224ddec08910c464d2a905c4c2e1f7d80Raphael NULL, /* use parent's starting directory */ 2046508be1224ddec08910c464d2a905c4c2e1f7d80Raphael &startup, /* startup info, i.e. std handles */ 2056508be1224ddec08910c464d2a905c4c2e1f7d80Raphael &pinfo); 2066508be1224ddec08910c464d2a905c4c2e1f7d80Raphael 2076508be1224ddec08910c464d2a905c4c2e1f7d80Raphael if (!ret) { 208ea66c92f80d9745721cfa28e22f2726b76579158Raphael display_error("Failed to execute tools\\android.bat:"); 209ea66c92f80d9745721cfa28e22f2726b76579158Raphael result = 1; 210ea66c92f80d9745721cfa28e22f2726b76579158Raphael } else { 211ea66c92f80d9745721cfa28e22f2726b76579158Raphael WaitForSingleObject(pinfo.hProcess, INFINITE); 212ea66c92f80d9745721cfa28e22f2726b76579158Raphael CloseHandle(pinfo.hProcess); 213ea66c92f80d9745721cfa28e22f2726b76579158Raphael CloseHandle(pinfo.hThread); 214ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 215ea66c92f80d9745721cfa28e22f2726b76579158Raphael 216ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (!CloseHandle(temp_handle)) { 217ea66c92f80d9745721cfa28e22f2726b76579158Raphael display_error("CloseHandle temp file failed"); 218ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 219ea66c92f80d9745721cfa28e22f2726b76579158Raphael 220ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (!result) { 221ea66c92f80d9745721cfa28e22f2726b76579158Raphael read_temp_file(temp_filename); 222ea66c92f80d9745721cfa28e22f2726b76579158Raphael } 2236508be1224ddec08910c464d2a905c4c2e1f7d80Raphael 224ea66c92f80d9745721cfa28e22f2726b76579158Raphael if (!DeleteFile(temp_filename)) { 225ea66c92f80d9745721cfa28e22f2726b76579158Raphael display_error("Delete temp file failed"); 2266508be1224ddec08910c464d2a905c4c2e1f7d80Raphael } 2276508be1224ddec08910c464d2a905c4c2e1f7d80Raphael 228ea66c92f80d9745721cfa28e22f2726b76579158Raphael return result; 2296508be1224ddec08910c464d2a905c4c2e1f7d80Raphael} 2306508be1224ddec08910c464d2a905c4c2e1f7d80Raphael 2316508be1224ddec08910c464d2a905c4c2e1f7d80Raphaelint main(int argc, char **argv) { 2326508be1224ddec08910c464d2a905c4c2e1f7d80Raphael return sdk_launcher(); 2336508be1224ddec08910c464d2a905c4c2e1f7d80Raphael} 2346508be1224ddec08910c464d2a905c4c2e1f7d80Raphael 2356508be1224ddec08910c464d2a905c4c2e1f7d80Raphael#endif /* _WIN32 */ 236