SDK Launcher: capture stdout from batch file.

Change-Id: Iab4e8f54bf2039cd9a17b1e814ffdc3ccd3deb23
diff --git a/files/find_java.bat b/files/find_java.bat
index 6039e89..ac11d06 100755
--- a/files/find_java.bat
+++ b/files/find_java.bat
@@ -36,7 +36,7 @@
 rem Search for an alternative in %ProgramFiles%\Java\*\bin\java.exe

 

 echo.

-echo Java not found in your path.

+echo WARNING: Java not found in your path.

 echo Checking it it's installed in %ProgramFiles%\Java instead.

 echo.

 

@@ -45,9 +45,9 @@
 if defined java_exe goto :EOF

 

 echo.

-echo No suitable Java found. In order to properly use the Android Developer Tools,

-echo you need a suitable version of Java installed on your system. We recommend

-echo that you install the JDK version of JavaSE, available here:

+echo ERROR: No suitable Java found. In order to properly use the Android Developer

+echo Tools, you need a suitable version of Java installed on your system. We

+echo recommend that you install the JDK version of JavaSE, available here:

 echo   http://java.sun.com/javase/downloads/

 echo.

 echo You can find the complete Android SDK requirements here:

@@ -74,7 +74,7 @@
 echo Please consider adding it to your path:

 echo - Under Windows XP, open Control Panel / System / Advanced / Environment Variables

 echo - Under Windows Vista, open Control Panel / System / Advanced System Settings

-echo                                                    / Environment Variables

+echo                             / Environment Variables

 echo At the end of the "Path" entry in "User variables", add the following:

 echo   ;%full_path%

 echo.

diff --git a/sdklauncher/sdklauncher.c b/sdklauncher/sdklauncher.c
index d052284..23b785d 100644
--- a/sdklauncher/sdklauncher.c
+++ b/sdklauncher/sdklauncher.c
@@ -21,7 +21,6 @@
  * Eventually it should simply replace the batch file.
  *
  * TODO:
- * - detect that java is installed; error dialog if not, explaning where to get it.
  * - create temp dir, always copy *.jar there, exec android.jar
  * - get jars to copy from some file
  * - use a version number to copy jars only if needed (tools.revision?)
@@ -32,23 +31,170 @@
 #include <stdio.h>
 #include <windows.h>
 
+
+void display_error(LPSTR description) {
+    DWORD err = GetLastError();
+    LPSTR s, s2;
+
+    fprintf(stderr, "%s, error %ld\n", description, err);
+
+    if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | /* dwFlags */
+                      FORMAT_MESSAGE_FROM_SYSTEM,
+                      NULL,                             /* lpSource */
+                      err,                              /* dwMessageId */
+                      0,                                /* dwLanguageId */
+                      (LPSTR)&s,                        /* lpBuffer */
+                      0,                                /* nSize */
+                      NULL) != 0) {                     /* va_list args */
+        fprintf(stderr, "%s", s);
+
+        s2 = (LPSTR) malloc(strlen(description) + strlen(s) + 5);
+        sprintf(s2, "%s\r\n%s", description, s);
+        MessageBox(NULL, s2, "Android SDK Setup - Error", MB_OK);
+        free(s2);
+        LocalFree(s);
+    }
+}
+
+
+HANDLE create_temp_file(LPSTR temp_filename) {
+
+    HANDLE file_handle = INVALID_HANDLE_VALUE;
+    LPSTR temp_path = (LPSTR) malloc(MAX_PATH);
+
+    /* Get the temp directory path using GetTempPath.
+       GetTempFilename indicates that the temp path dir should not be larger than MAX_PATH-14.
+    */
+    int ret = GetTempPath(MAX_PATH - 14, temp_path);
+    if (ret > MAX_PATH || ret == 0) {
+        display_error("GetTempPath failed");
+        free(temp_path);
+        return INVALID_HANDLE_VALUE;
+    }
+
+    /* Now get a temp filename in the temp directory. */
+    if (!GetTempFileName(temp_path, "txt", 0, temp_filename)) {
+        display_error("GetTempFileName failed");
+
+    } else {
+        SECURITY_ATTRIBUTES sattr;
+        ZeroMemory(&sattr, sizeof(sattr));
+        sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
+        sattr.bInheritHandle = TRUE;
+
+        file_handle = CreateFile(temp_filename,             // filename
+                                 GENERIC_WRITE,             // access: write
+                                 FILE_SHARE_READ,           // share mode: read OK
+                                 &sattr,                    // security attributes
+                                 CREATE_ALWAYS,             // create even if exists
+                                 FILE_ATTRIBUTE_NORMAL,     // flags and attributes
+                                 NULL);                     // template
+        if (file_handle == INVALID_HANDLE_VALUE) {
+            display_error("Create temp file failed");
+        }
+    }
+
+    free(temp_path);
+    return file_handle;
+}
+
+
+void read_temp_file(LPSTR temp_filename) {
+    HANDLE handle;
+
+    handle = CreateFile(temp_filename,             // filename
+                        GENERIC_READ,              // access: read
+                        FILE_SHARE_READ,           // share mode: read OK
+                        NULL,                      // security attributes
+                        OPEN_EXISTING,             // only open existing file
+                        FILE_ATTRIBUTE_NORMAL,     // flags and attributes
+                        NULL);                     // template
+
+    if (handle == INVALID_HANDLE_VALUE) {
+        display_error("Open temp file failed");
+        return;
+    }
+
+    /* Cap the size we're reading.
+       4K is good enough to display in a message box.
+    */
+    DWORD size = 4096;
+
+    LPSTR buffer = (LPSTR) malloc(size + 1);
+
+    LPSTR p = buffer;
+    DWORD num_left = size;
+    DWORD num_read;
+    do {
+        if (!ReadFile(handle, p, num_left, &num_read, NULL)) {
+            display_error("Read Output failed");
+            break;
+        }
+
+        num_left -= num_read;
+        p += num_read;
+    } while (num_read > 0);
+
+    if (p != buffer) {
+        *p = 0;
+
+        /* Only output the buffer if it contains special keywords WARNING or ERROR. */
+        char* s1 = strstr(buffer, "WARNING");
+        char* s2 = strstr(buffer, "ERROR");
+
+        if (s2 != NULL && s2 < s1) {
+            s1 = s2;
+        }
+
+        if (s1 != NULL) {
+            /* We end the message at the first occurence of [INFO]. */
+            s2 = strstr(s1, "[INFO]");
+            if (s2 != NULL) {
+                *s2 = 0;
+            }
+
+            MessageBox(NULL, s1, "Android SDK Setup - Output", MB_OK);
+        }
+
+    }
+
+    free(buffer);
+
+    if (!CloseHandle(handle)) {
+        display_error("CloseHandle read temp file failed");
+    }
+}
+
+
 int sdk_launcher() {
+    int                   result = 0;
     STARTUPINFO           startup;
     PROCESS_INFORMATION   pinfo;
-    char                  program_path[MAX_PATH];
+    CHAR                  program_path[MAX_PATH];
     int                   ret;
+    CHAR                  temp_filename[MAX_PATH];
+    HANDLE                temp_handle;
+
+    ZeroMemory(&pinfo, sizeof(pinfo));
+
+    temp_handle = create_temp_file(temp_filename);
+    if (temp_handle == INVALID_HANDLE_VALUE) {
+        return 1;
+    }
 
     ZeroMemory(&startup, sizeof(startup));
     startup.cb = sizeof(startup);
-
-    ZeroMemory(&pinfo, sizeof(pinfo));
+    startup.dwFlags    = STARTF_USESTDHANDLES;
+    startup.hStdInput  = GetStdHandle(STD_INPUT_HANDLE);
+    startup.hStdOutput = temp_handle;
+    startup.hStdError  = temp_handle;
 
     /* get path of current program */
     GetModuleFileName(NULL, program_path, sizeof(program_path));
 
     ret = CreateProcess(
-            NULL,                                  /* program path */
-            "tools\\android.bat update sdk",         /* command-line */
+            NULL,                                       /* program path */
+            "tools\\android.bat update sdk",            /* command-line */
             NULL,                  /* process handle is not inheritable */
             NULL,                   /* thread handle is not inheritable */
             TRUE,                          /* yes, inherit some handles */
@@ -59,26 +205,27 @@
             &pinfo);
 
     if (!ret) {
-        DWORD err = GetLastError();
-        fprintf(stderr, "CreateProcess failure, error %ld\n", err);
-
-        LPSTR s;
-        if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | /* dwFlags */
-                          FORMAT_MESSAGE_FROM_SYSTEM,
-                          NULL,                             /* lpSource */
-                          err,                              /* dwMessageId */
-                          0,                                /* dwLanguageId */
-                          (LPSTR)&s,                        /* lpBuffer */
-                          0,                                /* nSize */
-                          NULL) != 0) {                     /* va_list args */
-            fprintf(stderr, "%s", s);
-            LocalFree(s);
-        }
-
-        return -1;
+        display_error("Failed to execute tools\\android.bat:");
+        result = 1;
+    } else {
+        WaitForSingleObject(pinfo.hProcess, INFINITE);
+        CloseHandle(pinfo.hProcess);
+        CloseHandle(pinfo.hThread);
     }
 
-    return 0;
+    if (!CloseHandle(temp_handle)) {
+        display_error("CloseHandle temp file failed");
+    }
+
+    if (!result) {
+        read_temp_file(temp_filename);
+    }
+
+    if (!DeleteFile(temp_filename)) {
+        display_error("Delete temp file failed");
+    }
+
+    return result;
 }
 
 int main(int argc, char **argv) {
diff --git a/sdkmanager/app/etc/android.bat b/sdkmanager/app/etc/android.bat
index 3aeebc2..196e684 100755
--- a/sdkmanager/app/etc/android.bat
+++ b/sdkmanager/app/etc/android.bat
@@ -46,7 +46,7 @@
 if "%1 %2"=="update sdk" goto StartUi
 if not "%1"=="" goto EndTempCopy
 :StartUi
-    echo Starting Android SDK and AVD Manager
+    echo [INFO] Starting Android SDK and AVD Manager
 
     rem We're now going to create a temp dir to hold all the Jar files needed
     rem to run the android tool, copy them in the temp dir and finally execute
@@ -71,9 +71,9 @@
 if defined ANDROID_SWT set swt_path=%ANDROID_SWT%
 
 if exist %swt_path% goto SetPath
-    echo SWT folder '%swt_path%' does not exist.
+    echo ERROR: SWT folder '%swt_path%' does not exist.
     echo Please set ANDROID_SWT to point to the folder containing swt.jar for your platform.
-    exit /B
+    goto :EOF
 
 :SetPath
 set java_ext_dirs=%swt_path%;lib\