Merge pull request #4 from pedro-w/issue-5060

Make installer also look for Java on the PATH
diff --git a/src/main/cpp/cleaner/windows/Makefile.mingw b/src/main/cpp/cleaner/windows/Makefile.mingw
index 8ae362b..9b31802 100644
--- a/src/main/cpp/cleaner/windows/Makefile.mingw
+++ b/src/main/cpp/cleaner/windows/Makefile.mingw
@@ -15,17 +15,26 @@
 # specific language governing permissions and limitations
 # under the License.
 
-TMPFLD = ../../../../../target/tmp/
 OFLD = ../../../../../target/cleaner/
 
+CC=i686-w64-mingw32-gcc
+CFLAGS=-Os -s -DARCHITECTURE=32 -W -Wall -Wl,--nxcompat -Wl,--dynamicbase \
+	   -Wl,--no-seh -Wl,--no-insert-timestamp -mwindows
+LDFLAGS=-static -static-libstdc++ -static-libgcc
+LDLIBS=-lstdc++ -lcomctl32 -luserenv
+
+SRCS=src/main.c
+INCS=
 all: prepfolder cleaner.exe
 
 prepfolder:
-	mkdir -p $(TMPFLD)
 	mkdir -p $(OFLD)
 
 clean:
-	rm -f *.res *.exe *.dll
+	-rm -f $(OFLD)cleaner.exe
 
-cleaner.exe: src/main.c
-	i686-w64-mingw32-gcc -s -DARCHITECTURE=32 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -Wl,--no-insert-timestamp -mwindows src/main.c -o$(OFLD)cleaner.exe -static -lstdc++ -static-libstdc++ -static-libgcc
+cleaner.exe: $(OFLD)cleaner.exe
+
+$(OFLD)cleaner.exe: $(SRCS) $(INCS)
+	$(LINK.c) $(SRCS) -o$@ $(LDLIBS)
+
diff --git a/src/main/cpp/cleaner/windows/src/main.c b/src/main/cpp/cleaner/windows/src/main.c
index 43271ff..ac7fd65 100644
--- a/src/main/cpp/cleaner/windows/src/main.c
+++ b/src/main/cpp/cleaner/windows/src/main.c
@@ -426,7 +426,10 @@
 #define MAXIMUM_THREADS MAXIMUM_WAIT_OBJECTS
 
 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hi, PSTR pszCmdLine, int nCmdShow) {
-//int main(void) {
+    UNREFERENCED_PARAMETER(hInstance);
+    UNREFERENCED_PARAMETER(hi);
+    UNREFERENCED_PARAMETER(pszCmdLine);
+    UNREFERENCED_PARAMETER(nCmdShow);
     int argumentsNumber = 0;
     DWORD i=0;
     DWORD  threadCounter = 0;
diff --git a/src/main/cpp/launcher/windows/Makefile.mingw b/src/main/cpp/launcher/windows/Makefile.mingw
index 7085105..30170d4 100644
--- a/src/main/cpp/launcher/windows/Makefile.mingw
+++ b/src/main/cpp/launcher/windows/Makefile.mingw
@@ -18,6 +18,21 @@
 TMPFLD = ../../../../../target/tmp/
 OFLD = ../../../../../target/launcher/
 
+CC=i686-w64-mingw32-gcc
+RC=i686-w64-mingw32-windres
+CFLAGS=-Os -s -DARCHITECTURE=32 -W -Wall -Wl,--nxcompat -Wl,--dynamicbase \
+	   -Wl,--no-seh -Wl,--no-insert-timestamp -mwindows
+LDFLAGS=-static -static-libstdc++ -static-libgcc
+LDLIBS=-lstdc++ -lcomctl32 -luserenv
+
+SRCS=src/Main.c src/Launcher.c src/ExtractUtils.c src/FileUtils.c \
+     src/SystemUtils.c src/RegistryUtils.c src/ProcessUtils.c \
+     src/JavaUtils.c src/StringUtils.c
+
+INCS=src/Errors.h src/JavaUtils.h src/ProcessUtils.h src/SystemUtils.h \
+     src/ExtractUtils.h src/Launcher.h src/RegistryUtils.h src/Types.h \
+     src/FileUtils.h src/Main.h src/StringUtils.h
+
 all: prepfolder nlw.exe
 
 prepfolder:
@@ -25,11 +40,12 @@
 	mkdir -p $(OFLD)
 
 clean:
-	rm -f *.res *.exe *.dll
+	-rm -f $(TMPFLD)nlw.res $(OFLD)nlw.exe
 
-nlw.res: resources/res.rc
-	i686-w64-mingw32-windres -o$(TMPFLD)nlw.res -Ocoff resources/res.rc
+$(TMPFLD)nlw.res: resources/res.rc
+	$(RC) -o$@ -Ocoff $<
 
+nlw.exe: $(OFLD)nlw.exe
 
-nlw.exe: nlw.res
-	i686-w64-mingw32-gcc -s -DARCHITECTURE=32 -Wl,--nxcompat -Wl,--dynamicbase -Wl,--no-seh -Wl,--no-insert-timestamp -mwindows src/Main.c src/Launcher.c src/ExtractUtils.c src/FileUtils.c src/SystemUtils.c src/RegistryUtils.c src/ProcessUtils.c src/JavaUtils.c src/StringUtils.c -o$(OFLD)nlw.exe -static -lstdc++ -lcomctl32 -luserenv -static-libstdc++ -static-libgcc
+$(OFLD)nlw.exe: $(TMPFLD)nlw.res $(SRCS) $(INCS)
+	$(LINK.c) $(SRCS) -o$@ $(LDLIBS)
diff --git a/src/main/cpp/launcher/windows/src/JavaUtils.c b/src/main/cpp/launcher/windows/src/JavaUtils.c
index 9e4245e..0f01ca4 100644
--- a/src/main/cpp/launcher/windows/src/JavaUtils.c
+++ b/src/main/cpp/launcher/windows/src/JavaUtils.c
@@ -36,6 +36,7 @@
 const WCHAR * JAVA_LIB_SUFFIX = L"\\lib";
 const WCHAR * PACK_GZ_SUFFIX  = L".pack.gz";
 const WCHAR * JAR_PACK_GZ_SUFFIX = L".jar.pack.gz";
+const WCHAR * PATH_ENV = L"PATH";
 
 const DWORD JVM_EXTRACTION_TIMEOUT = 180000;  //180sec
 
@@ -395,7 +396,6 @@
     HKEY rootKeys [2] = {HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER};
     DWORD rootKeysNumber = sizeof(rootKeys)/sizeof(HKEY);
     DWORD keysNumber = sizeof(JAVA_REGISTRY_KEYS)/sizeof(WCHAR*);
-    DWORD status = ERROR_OK;
     
     writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in CurrentVersion values...", 1);
     
@@ -455,7 +455,6 @@
                         err = RegEnumKeyExW(hkey, index, buffer, &size, NULL, NULL, NULL, NULL);
                         if (err == ERROR_SUCCESS) {
                             WCHAR  * javaHome = getJavaHomeValue(keys[i], buffer, access64key);
-                            status = ERROR_OK;
                             
                             writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, (rootKeys[k]==HKEY_LOCAL_MACHINE) ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER", 0);
                             writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0);
@@ -531,7 +530,6 @@
 void unpackJars(LauncherProperties * props, WCHAR * jvmDir, WCHAR * startDir, WCHAR * unpack200exe) {
     DWORD attrs;
     DWORD dwError;
-    DWORD count = 0 ;
     
     if(!isOK(props)) return;
     attrs = GetFileAttributesW(startDir);
@@ -686,10 +684,10 @@
     GetModuleFileName(0, executablePath, MAX_PATH);
     char * pch = strrchr(executablePath, '\\');    
     char installationFolder [MAX_PATH]= "";
-    int i = 0;
+    int i;
     int end = (int) (pch - executablePath);
     printf("%i", end);
-    for(i; i < end; i++) {
+    for(i = 0; i < end; i++) {
         installationFolder[i] = executablePath[i];
     }
     strcat(installationFolder, "\\bin\\jre");
@@ -737,6 +735,34 @@
         }        
     }
 }
+static void searchJavaOnPath(LauncherProperties * props) {
+  // Find the correct size first, then allocate
+  DWORD size = GetEnvironmentVariableW(PATH_ENV, NULL, 0);
+  WCHAR * str = newpWCHAR(size);
+  GetEnvironmentVariableW(PATH_ENV, str, size);
+  StringListEntry * list = splitStringToList(NULL, str, L';');
+  StringListEntry * iter = list;
+  while (iter) {
+    // Quickly check for java.exe ...
+    WCHAR * javaExecutable = appendStringW(NULL, iter->string);
+    javaExecutable = appendStringW(javaExecutable, L"\\java.exe");
+    if (fileExists(javaExecutable)) {
+      // ... then check properly with trySetCompatibleJava
+      WCHAR* msg = appendStringW(NULL, L"A potential path is ");
+      msg = appendStringW(msg, iter->string);
+      writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, msg, 1);
+      WCHAR * javaHome = getParentDirectory(iter->string);
+      trySetCompatibleJava(javaHome, props);
+      FREE(javaHome);
+      FREE(msg);
+    }
+    FREE(javaExecutable);
+    iter = iter->next;
+  }
+  freeStringList(&list);
+  FREE(str);
+}
+
 void findSystemJava(LauncherProperties *props) {
     // install bundled JVMs if any
     if(isTerminated(props)) return;
@@ -759,7 +785,12 @@
         writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in environment variables", 1);
         searchJavaFromEnvVariables(props);
     }
-    
+
+    if (isTerminated(props)) return;
+    if (props->java == NULL) {
+      writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in executable paths", 1);
+      searchJavaOnPath(props);
+    }
     // search JVM in the registry
     if(isTerminated(props)) return;
     if(props->java==NULL) {        
diff --git a/src/main/cpp/launcher/windows/src/Launcher.c b/src/main/cpp/launcher/windows/src/Launcher.c
index 95bdcbd..fee1f22 100644
--- a/src/main/cpp/launcher/windows/src/Launcher.c
+++ b/src/main/cpp/launcher/windows/src/Launcher.c
@@ -479,8 +479,7 @@
 }
 
 void resolvePath(LauncherProperties * props, LauncherResource * file) {
-    WCHAR * result = NULL;
-    DWORD i=0;
+    DWORD i;
     
     if(file==NULL) return;
     if(file->resolved!=NULL) return;
diff --git a/src/main/cpp/launcher/windows/src/Main.c b/src/main/cpp/launcher/windows/src/Main.c
index 5a819ee..4dbb8c6 100644
--- a/src/main/cpp/launcher/windows/src/Main.c
+++ b/src/main/cpp/launcher/windows/src/Main.c
@@ -103,8 +103,6 @@
 void initErrorTitleWindow(LauncherProperties *props, HINSTANCE hInstance) {
     if(!isSilent(props)) {
         RECT rcClient;
-        int cyVScroll;
-        cyVScroll = GetSystemMetrics(SM_CYVSCROLL);
         GetClientRect(hwndMain, &rcClient);
         hwndErrorTitle = CreateWindowExW(0,  WC_STATICW,  WC_STATICW, WS_CHILD,
                 rcClient.left + 10,  15, rcClient.right - 20, 20, hwndMain, NULL, hInstance, NULL);
@@ -128,8 +126,6 @@
 void initErrorDetailWindow(LauncherProperties *props, HINSTANCE hInstance) {
     if(!isSilent(props)) {
         RECT rcClient;
-        int cyVScroll;
-        cyVScroll = GetSystemMetrics(SM_CYVSCROLL);
         GetClientRect(hwndMain, &rcClient);
         hwndErrorDetail = CreateWindowExW(0,  WC_STATICW,  WC_STATICW, WS_CHILD  ,
                 rcClient.left + 10,  40, rcClient.right - 20, 80,
@@ -587,6 +583,7 @@
 }
 
 DWORD createGui(LauncherProperties* props, HINSTANCE hInstance, HINSTANCE hi, int nCmdShow) {
+    (void) hi;
     if (!InitApplication(props, hInstance)) {
         SetEvent(initializationFailed);
         return 0;
diff --git a/src/main/cpp/launcher/windows/src/ProcessUtils.c b/src/main/cpp/launcher/windows/src/ProcessUtils.c
index 0fcd9dd..46f156d 100644
--- a/src/main/cpp/launcher/windows/src/ProcessUtils.c
+++ b/src/main/cpp/launcher/windows/src/ProcessUtils.c
@@ -28,21 +28,20 @@
     ReadFile(hRead, buf, STREAM_BUF_LENGTH - 1, bytesRead, NULL);
     
     if((*bytesRead)>0 && hWrite!=INVALID_HANDLE_VALUE) {
-        DWORD bytesWritten = 0;
-        WriteFile(hWrite, buf, (*bytesRead), &bytesWritten, 0);
+        WriteFile(hWrite, buf, (*bytesRead), NULL, 0);
     }
-    ZERO(buf, sizeof(buf));
+    ZERO(buf, STREAM_BUF_LENGTH);
     return 0;
 }
 
 DWORD readNextData(HANDLE hRead, WCHAR * buf, HANDLE hWrite) {
     DWORD bytesRead;
     DWORD bytesAvailable;
-    ZERO(buf, sizeof(buf));
+    ZERO(buf, STREAM_BUF_LENGTH);
     
     PeekNamedPipe(hRead, buf, STREAM_BUF_LENGTH - 1, &bytesRead, &bytesAvailable, NULL);
     if (bytesRead != 0) {
-        ZERO(buf, sizeof(buf));
+        ZERO(buf, STREAM_BUF_LENGTH);
         if (bytesAvailable >= STREAM_BUF_LENGTH) {
             while (bytesRead >= STREAM_BUF_LENGTH-1) {
                 readBuf(hRead, buf, &bytesRead, hWrite);
diff --git a/src/main/cpp/launcher/windows/src/StringUtils.c b/src/main/cpp/launcher/windows/src/StringUtils.c
index cf0423b..5c501cb 100644
--- a/src/main/cpp/launcher/windows/src/StringUtils.c
+++ b/src/main/cpp/launcher/windows/src/StringUtils.c
@@ -320,6 +320,7 @@
                     result[r++] = '\\';
                     bsCounter--;
                 } while(bsCounter>0);
+		break;
             default:
                 bsCounter = 0;                
                 break;
@@ -538,6 +539,21 @@
 }
 
 
+StringListEntry * splitStringToList(StringListEntry * top, WCHAR * strlist, WCHAR sep) {
+  if (strlist != NULL) {
+    WCHAR * start = strlist;
+    while (*strlist != 0) {
+      if (*strlist == 0 || *strlist == sep) {
+	top = addStringToList(top, appendStringNW(NULL, 0, start, strlist - start));
+	start = ++strlist;
+      } else {
+	++strlist;
+      }
+    }
+  }
+  return top;
+}
+
 DWORD getLineSeparatorNumber(char *str) {
     DWORD result = 0;
     char *ptr = str;
diff --git a/src/main/cpp/launcher/windows/src/StringUtils.h b/src/main/cpp/launcher/windows/src/StringUtils.h
index 9cf775c..ae50d7a 100644
--- a/src/main/cpp/launcher/windows/src/StringUtils.h
+++ b/src/main/cpp/launcher/windows/src/StringUtils.h
@@ -94,6 +94,7 @@
     
     void freeStringList(StringListEntry **s);
     StringListEntry * addStringToList(StringListEntry * top, WCHAR * str);
+    StringListEntry * splitStringToList(StringListEntry * top, WCHAR * str, WCHAR sep);
     DWORD inList(StringListEntry * top, WCHAR * str);
     
     char *toChar(const WCHAR * string);
diff --git a/src/main/cpp/launcher/windows/src/SystemUtils.c b/src/main/cpp/launcher/windows/src/SystemUtils.c
index c8b423e..feabb49 100644
--- a/src/main/cpp/launcher/windows/src/SystemUtils.c
+++ b/src/main/cpp/launcher/windows/src/SystemUtils.c
@@ -81,15 +81,15 @@
     return (id == VER_PLATFORM_WIN32_NT && major == 6 && minor == 1 && type == VER_NT_WORKSTATION) ? 1 : 0;
 }
 
-typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
-LPFN_ISWOW64PROCESS fnIsWow64Process;
-
 void initWow64()
 {
-    IsWow64 = FALSE;
+    typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
 
-    fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
-  
+    IsWow64 = FALSE;
+    // Have to ignore the warning here:
+#pragma GCC diagnostic ignored "-Wcast-function-type"
+    LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process");
+#pragma GCC diagnostic pop
     if (NULL != fnIsWow64Process)
     {
         if (!fnIsWow64Process(GetCurrentProcess(),&IsWow64))