Commit:    b1704f17dd71abd5d4b8064019f5ecd9fcd9e9d5
Author:    Holly Li (WIPRO LIMITED) <v-hu...@microsoft.com>         Mon, 15 Apr 
2019 17:22:44 -0700
Committer: Anatol Belski <a...@php.net>      Tue, 30 Apr 2019 12:18:19 +0200
Parents:   b423a5d0587eb4f97f67f2fc1434d4b99f37ba05
Branches:  master

Link:       
http://git.php.net/?p=pftt2.git;a=commitdiff;h=b1704f17dd71abd5d4b8064019f5ecd9fcd9e9d5

Log:
Issue #3, Implement pftt setup, step 1

use zip non-install package for MySQL installation

support download/install VC16

remove code for sql installer which will never be used

rename from VC16 to VS16

Bugs:
https://bugs.php.net/3

Changed paths:
  M  .gitignore
  M  src/com/mostc/pftt/host/Host.java
  M  src/com/mostc/pftt/main/PfttMain.java
  M  src/com/mostc/pftt/model/core/EBuildBranch.java
  M  src/com/mostc/pftt/model/core/PhpBuild.java
  M  src/com/mostc/pftt/util/DownloadUtil.java
  M  src/com/mostc/pftt/util/HostEnvUtil.java

diff --git a/.gitignore b/.gitignore
index 638851d..80b9c7c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,5 +5,8 @@ src/com/sshtools/*
 hostkeys.txt
 ssh_server.jar
 cache/working/*
+cache/dep/*
 jre/*
-/build/
+job_work/*
+.metadata/*
+pftt_release.zip
\ No newline at end of file
diff --git a/src/com/mostc/pftt/host/Host.java 
b/src/com/mostc/pftt/host/Host.java
index edecc47..93657ed 100644
--- a/src/com/mostc/pftt/host/Host.java
+++ b/src/com/mostc/pftt/host/Host.java
@@ -25,6 +25,8 @@ public abstract class Host {
        /** should always have a timeout... should NOT let something run 
forever */
        public static final int FOUR_HOURS = ONE_HOUR * 4;
        public static final int ONE_MINUTE = 60;
+       public static final int TEN_MINUTES = ONE_MINUTE * 10;
+       public static final int TWENTY_MINUTES = TEN_MINUTES * 2;
        protected static final int NO_TIMEOUT = 0;
        /** put PATH in the ENV vars you pass to #exec and it will 
automatically add that
         * value to the system's PATH (takes care of merging it for you, so it 
won't be completely overridden)
diff --git a/src/com/mostc/pftt/main/PfttMain.java 
b/src/com/mostc/pftt/main/PfttMain.java
index 941163e..c28e7db 100644
--- a/src/com/mostc/pftt/main/PfttMain.java
+++ b/src/com/mostc/pftt/main/PfttMain.java
@@ -501,6 +501,14 @@ public class PfttMain {
                return 
config==null?ScenarioSet.getDefaultScenarioSets():config.getScenarioSets(layer);
        }
        
+       private PhpBuild setupBuild;
+       protected void ensureLocalhostSetup(PhpBuild build) throws Exception {
+               if (setupBuild==build)
+                       return;
+               HostEnvUtil.setupHostEnv(fs, host, cm, build);
+               setupBuild = build;
+       }
+       
        private PhpBuild prepared;
        protected void ensureLocalhostPrepared(PhpBuild build) throws Exception 
{
                if (prepared==build)
@@ -1978,6 +1986,9 @@ public class PfttMain {
                                        
                                        checkUAC(is_uac, true, config, cm, 
EScenarioSetPermutationLayer.PRODUCTION_OR_ALL_UP_TEST);
                                        
+                                       // setup host environment
+                                       p.ensureLocalhostSetup(build);
+                                       
                                        // setup all scenarios
                                        PhpIni ini;
                                        ScenarioSetSetup setup = null;
diff --git a/src/com/mostc/pftt/model/core/EBuildBranch.java 
b/src/com/mostc/pftt/model/core/EBuildBranch.java
index 7edd966..f6ccf64 100644
--- a/src/com/mostc/pftt/model/core/EBuildBranch.java
+++ b/src/com/mostc/pftt/model/core/EBuildBranch.java
@@ -69,6 +69,18 @@ public enum EBuildBranch {
                        return null; // could be X86 or X64
                }
        },
+       PHP_7_4 {
+               @Override
+               public ECPUArch getCPUArch() {
+                       return null; // could be X86 or X64
+               }
+       },
+       PHP_8_0 {
+               @Override
+               public ECPUArch getCPUArch() {
+                       return null; // could be X86 or X64
+               }
+       },
        STR_SIZE_AND_INT64 {
                @Override
                public ECPUArch getCPUArch() {
diff --git a/src/com/mostc/pftt/model/core/PhpBuild.java 
b/src/com/mostc/pftt/model/core/PhpBuild.java
index f0161b5..036999c 100644
--- a/src/com/mostc/pftt/model/core/PhpBuild.java
+++ b/src/com/mostc/pftt/model/core/PhpBuild.java
@@ -517,6 +517,15 @@ public class PhpBuild extends SAPIManager {
                                                case 3:
                                                        branch  = 
EBuildBranch.PHP_7_3;
                                                        break;
+                                               case 4:
+                                                       branch  = 
EBuildBranch.PHP_7_4;
+                                                       break;
+                                               }
+                                       } else if (major == 8) {
+                                               switch(minor) {
+                                               case 0:
+                                                       branch  = 
EBuildBranch.PHP_8_0;
+                                                       break;
                                                }
                                        }
                                        
diff --git a/src/com/mostc/pftt/util/DownloadUtil.java 
b/src/com/mostc/pftt/util/DownloadUtil.java
index 880648d..0e7a545 100644
--- a/src/com/mostc/pftt/util/DownloadUtil.java
+++ b/src/com/mostc/pftt/util/DownloadUtil.java
@@ -1,14 +1,17 @@
 package com.mostc.pftt.util;
 
+import java.io.File;
 import java.io.FileOutputStream;
 import java.net.Socket;
 import java.net.URL;
 
 import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.Header;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpVersion;
+import org.apache.http.StatusLine;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.DefaultHttpClientConnection;
 import org.apache.http.message.BasicHttpRequest;
@@ -46,6 +49,52 @@ public class DownloadUtil {
        public static boolean downloadAndUnzip(ConsoleManager cm, Host host, 
URL remote_url, String local_dir) {
                String local_file_zip = host.mCreateTempName("Download", 
".zip");
                
+               if(!downloadFile(cm, remote_url, local_file_zip))
+               {
+                       return false;
+               }
+               
+               // decompress local_file_zip
+               try {
+                       host.mCreateDirs(local_dir);
+                       
+                       System.out.println("PFTT: release_get: decompressing 
"+local_file_zip+"...");
+                       
+                       return host.unzip(cm, local_file_zip, local_dir);
+               } catch ( Exception ex ) {
+                       cm.addGlobalException(EPrintType.CANT_CONTINUE, 
DownloadUtil.class, "downloadAndUnzip", ex, "");
+                       return false;
+               }
+       } // end public static boolean downloadAndUnzip
+
+       public static boolean downloadFile(ConsoleManager cm, String 
remote_url, String local_file_name) {
+               try {
+                       cm.println(EPrintType.CLUE, DownloadUtil.class, 
"Downloading from ["+remote_url.toString()+"] as ["+local_file_name+"]");
+                       return downloadFile(cm, new URL(remote_url), 
local_file_name);
+               } catch ( Exception ex ) {
+                       cm.addGlobalException(EPrintType.CANT_CONTINUE, 
DownloadUtil.class, "downloadFile", ex, "");
+                       return false;
+               }
+       }
+       
+       private static final int MAX_REDIRECT = 5;
+       /**
+        * @param cm
+        * @param remote_url
+        * @param local_file_name
+        */
+       public static boolean downloadFile(ConsoleManager cm, URL remote_url, 
String local_file_name)
+       {
+               return downloadFile(cm, remote_url, local_file_name, 0);
+       }
+       
+       private static boolean downloadFile(ConsoleManager cm, URL remote_url, 
String local_file_name, int redirect) {
+               if(redirect > MAX_REDIRECT)
+               {
+                       cm.println(EPrintType.CANT_CONTINUE, 
DownloadUtil.class, "Exceeding maximal redirects" + MAX_REDIRECT + " for 
downloading [" + remote_url + "]");
+                       return false;
+               }
+               
                HttpParams params = new SyncBasicHttpParams();
                HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
                HttpProtocolParams.setContentCharset(params, "UTF-8");
@@ -84,35 +133,57 @@ public class DownloadUtil {
                        response.setParams(params);
                        httpexecutor.postProcess(response, httpproc, context);
                        
-                       FileOutputStream out_file = new 
FileOutputStream(local_file_zip);
+                       StatusLine statusLine = response.getStatusLine();
+                       int statusCode = statusLine.getStatusCode();
+                       if( statusCode != 200)
+                       {
+                               switch(statusCode)
+                               {
+                               // Handling redirects
+                               case 301: // 301 Moved Permanently
+                               case 302: // 302 Found or originally temporary 
redirect
+                               case 303: // 303 see other 
+                               case 307: // 307 temporary redirect
+                               case 308: // 308 permanent redirect
+                                       Header[] locations = 
response.getHeaders("Location");
+                                       for(int i = 0; i < locations.length; 
i++)
+                                       {
+                                               String redirectedUrl = 
locations[i].getValue();
+                                               cm.println(EPrintType.CLUE, 
DownloadUtil.class, "Redirecting from ["+remote_url.toString()+"] to 
["+redirectedUrl+"], redirect count =" + redirect++);
+                                               if(downloadFile(cm, new 
URL(redirectedUrl), local_file_name, redirect))
+                                               {
+                                                       return true;
+                                               }
+                                       }
+                                       break;                                  
+                               }
+                               
+                               throw new Exception("Error downloading file 
from [" + remote_url + "] with status " + statusLine.toString());
+       
+                       }
+                       
+                       File local_file = new File(local_file_name);
+                       // create parent directories if not exists
+                       local_file.getParentFile().mkdirs();
+                       
+                       FileOutputStream out_file = new 
FileOutputStream(local_file_name);
                        
                        IOUtil.copy(response.getEntity().getContent(), 
out_file, IOUtil.UNLIMITED);
                        
                        out_file.close();
+                       return true;
                } catch ( Exception ex ) {
-                       cm.addGlobalException(EPrintType.CANT_CONTINUE, 
DownloadUtil.class, "downloadAndUnzip", ex, "error downloading file: 
"+remote_url);
+                       cm.addGlobalException(EPrintType.CANT_CONTINUE, 
DownloadUtil.class, "downloadFile", ex, "error downloading file: "+remote_url);
                        return false;
                } finally {
                        if ( response == null || 
!connStrategy.keepAlive(response, context)) {
                                try {
                                        conn.close();
                                } catch ( Exception ex ) {
-                                       
cm.addGlobalException(EPrintType.CANT_CONTINUE, DownloadUtil.class, 
"downloadAndUnzip", ex, "");
+                                       
cm.addGlobalException(EPrintType.CANT_CONTINUE, DownloadUtil.class, 
"downloadFile", ex, "");
                                }
                        }
                }
-               
-               // decompress local_file_zip
-               try {
-                       host.mCreateDirs(local_dir);
-                       
-                       System.out.println("PFTT: release_get: decompressing 
"+local_file_zip+"...");
-                       
-                       return host.unzip(cm, local_file_zip, local_dir);
-               } catch ( Exception ex ) {
-                       cm.addGlobalException(EPrintType.CANT_CONTINUE, 
DownloadUtil.class, "downloadAndUnzip", ex, "");
-                       return false;
-               }
-       } // end public static boolean downloadAndUnzip
+       }
 
 } // end public class DownloadUtil
diff --git a/src/com/mostc/pftt/util/HostEnvUtil.java 
b/src/com/mostc/pftt/util/HostEnvUtil.java
index 98d0e52..6410b7e 100644
--- a/src/com/mostc/pftt/util/HostEnvUtil.java
+++ b/src/com/mostc/pftt/util/HostEnvUtil.java
@@ -1,6 +1,10 @@
 package com.mostc.pftt.util;
 
+import java.io.File;
 import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.nio.file.*;
 
 import com.github.mattficken.io.StringUtil;
 import com.mostc.pftt.host.ExecOutput;
@@ -9,7 +13,17 @@ import com.mostc.pftt.host.LocalHost;
 import com.mostc.pftt.model.core.PhpBuild;
 import com.mostc.pftt.results.ConsoleManager;
 import com.mostc.pftt.results.EPrintType;
+import com.mostc.pftt.results.LocalConsoleManager;
 import com.mostc.pftt.scenario.FileSystemScenario;
+import com.mostc.pftt.scenario.LocalFileSystemScenario;
+import com.sun.corba.se.impl.orbutil.closure.Future;
+import com.sun.jna.Memory;
+import com.sun.jna.Pointer;
+import com.sun.jna.platform.win32.VerRsrc.VS_FIXEDFILEINFO;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.PointerByReference;
+
+import groovy.lang.Tuple;
 
 /** Utilities for setting up the test environment and convenience settings on 
Hosts
  * 
@@ -18,6 +32,70 @@ import com.mostc.pftt.scenario.FileSystemScenario;
  */
 
 public final class HostEnvUtil {
+
+       static final String Link_VC9_Redist_X86
+               = 
"https://download.microsoft.com/download/1/1/1/1116b75a-9ec3-481a-a3c8-1777b5381140/vcredist_x86.exe";;
+       static final String Link_VC10_Redist_X86
+               = 
"https://download.microsoft.com/download/5/B/C/5BC5DBB3-652D-4DCE-B14A-475AB85EEF6E/vcredist_x86.exe";;
+       static final String Link_VC10_Redist_X64
+               = 
"https://download.microsoft.com/download/3/2/2/3224B87F-CFA0-4E70-BDA3-3DE650EFEBA5/vcredist_x64.exe";;
+       static final String Link_VC11_Redist_X86
+               = 
"https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x86.exe";;
+       static final String Link_VC11_Redist_X64
+               = 
"https://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe";;
          
+       static final String Link_VC14_Redist_X86
+               = 
"https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x86.exe";;
+       static final String Link_VC14_Redist_X64
+               = 
"https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe";;
+       static final String Link_VC15_Redist_X86
+               = "https://aka.ms/vs/15/release/VC_redist.x86.exe";;
+       static final String Link_VC15_Redist_X64
+               = "https://aka.ms/vs/15/release/VC_redist.x64.exe";;
+       static final String Link_VS16_Redist_X86
+               = "https://aka.ms/vs/16/release/VC_redist.x86.exe";;
+       static final String Link_VS16_Redist_X64
+               = "https://aka.ms/vs/16/release/VC_redist.x64.exe";;
+       static final String Link_Mysql_Win32_5_7_25
+               = 
"https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.25-win32.zip";;
+       
+       
+       static final String Dir_Cache_Dep = LocalHost.getLocalPfttDir() + 
"\\cache\\dep";
+       static final String Dir_Cache_Dep_VCRedist = Dir_Cache_Dep + 
"\\VCRedist";
+       static final String Dir_Cache_Dep_Mysql = Dir_Cache_Dep + "\\MySql";
+       static final String File_VC9_Redist_X86 = Dir_Cache_Dep_VCRedist + 
"\\vc9_redist_x86.exe";
+       static final String File_VC10_Redist_X86 = Dir_Cache_Dep_VCRedist + 
"\\vc10_redist_x86.exe";
+       static final String File_VC10_Redist_X64 = Dir_Cache_Dep_VCRedist + 
"\\vc10_redist_x64.exe";
+       static final String File_VC11_Redist_X86 = Dir_Cache_Dep_VCRedist + 
"\\vc11_redist_x86.exe";
+       static final String File_VC11_Redist_X64 = Dir_Cache_Dep_VCRedist + 
"\\vc11_redist_x64.exe";
+       static final String File_VC12_Redist_X86 = Dir_Cache_Dep_VCRedist + 
"\\vc12_redist_x86.exe";
+       static final String File_VC12_Redist_X64 = Dir_Cache_Dep_VCRedist + 
"\\vc12_redist_x64.exe";
+       static final String File_VC14_Redist_X86 = Dir_Cache_Dep_VCRedist + 
"\\vc14_redist_x86.exe";
+       static final String File_VC14_Redist_X64 = Dir_Cache_Dep_VCRedist + 
"\\vc14_redist_x64.exe";
+       static final String File_VC15_Redist_X86 = Dir_Cache_Dep_VCRedist + 
"\\vc15_redist_x86.exe";
+       static final String File_VC15_Redist_X64 = Dir_Cache_Dep_VCRedist + 
"\\vc15_redist_x64.exe";
+       static final String File_VS16_Redist_X86 = Dir_Cache_Dep_VCRedist + 
"\\vc_vs16_redist_x86.exe";
+       static final String File_VS16_Redist_X64 = Dir_Cache_Dep_VCRedist + 
"\\vc_vs16_redist_x64.exe";
+       
+       static final String Dir_Mysql = "C:\\MySQL";
+       static final String Dir_Mysql_5_7 = Dir_Mysql + "\\mysql-5.7.25-win32";
+       static final String Dir_Mysql_5_7_bin = Dir_Mysql_5_7 + "\\bin";
+       static final String Exe_Mysql_5_7_mysqld = Dir_Mysql_5_7_bin + 
"\\mysqld.exe";
+       static final String Exe_Mysql_5_7_mysql = Dir_Mysql_5_7_bin + 
"\\mysql.exe";
+       
+       static final String Dir_WinSxS = "\\WinSxS";
+       static final String WinSxS_VC9_Fragment = "VC9";
+       
+       static final String Dir_System32 = "\\system32";
+       static final String Dir_SysWOW64 = "\\SysWOW64";
+       static final String Sys_Dll_VC10_Redist_X86 = Dir_System32 + 
"\\msvcr100.dll";
+       static final String Sys_Dll_VC10_Redist_X64 = Dir_SysWOW64 + 
"\\msvcr100.dll";
+       static final String Sys_Dll_VC11_Redist_X86 = Dir_System32 + 
"\\msvcr110.dll";
+       static final String Sys_Dll_VC11_Redist_X64 = Dir_SysWOW64 + 
"\\msvcr110.dll";
+       static final String Sys_Dll_VC12_Redist_X86 = Dir_System32 + 
"\\msvcr120.dll";
+       static final String Sys_Dll_VC12_Redist_X64 = Dir_SysWOW64 + 
"\\msvcr120.dll";
+       // Note: VC15 and VC16 will have the same dll name with VC14, but 
different version to be backward compatible
+       static final String Sys_Dll_VC14Plus_Redist_X86 = Dir_System32 + 
"\\vcruntime140.dll";
+       static final String Sys_Dll_VC14Plus_Redist_X64 = Dir_SysWOW64 + 
"\\vcruntime140.dll";
        
        public static void prepareHostEnv(FileSystemScenario fs, AHost host, 
ConsoleManager cm, PhpBuild build, boolean enable_debug_prompt) throws 
Exception {
                if (host.isWindows()) {
@@ -120,15 +198,85 @@ public final class HostEnvUtil {
                        // share PHP-SDK over network. this also will share C$, 
G$, etc...
                        //host.execElevated(cm, HostEnvUtil.class, "NET SHARE 
PHP_SDK="+host.getJobWorkDir()+" /Grant:"+host.getUsername()+",Full", 
AHost.ONE_MINUTE);
                }
-                       
+               
                installVCRuntime(fs, host, cm, build);
+               
+               installAndConfigureMySql(fs, host, cm);
+               
                cm.println(EPrintType.COMPLETED_OPERATION, HostEnvUtil.class, 
"Windows host prepared to run PHP.");
        } // end public static void prepareWindows
        
+       private static void installAndConfigureMySql(FileSystemScenario fs, 
AHost host, ConsoleManager cm) throws IllegalStateException, IOException, 
Exception {
+               
+               if(!fs.exists(Exe_Mysql_5_7_mysqld))
+               {
+                       cm.println(EPrintType.WARNING, HostEnvUtil.class, 
"MySql 5.7.25.0 is not downloaded, should run setup command first...");
+                       return;
+               }
+
+               ExecOutput op = host.execOut("sc.exe query MySQL", 
AHost.TEN_MINUTES);
+               
+               if(op.output.contains("RUNNING"))
+               {
+                       cm.println(EPrintType.WARNING, HostEnvUtil.class, 
"MySql service is already running.");
+                       return;
+               }
+
+               if(op.output.contains("EnumQueryServicesStatus:OpenService 
FAILED"))
+               {
+                       // creating data directly for MySQL service
+                       cm.println(EPrintType.IN_PROGRESS, HostEnvUtil.class, 
"Creating data folder for MySql Server 5.7.25.0");                
+                       String data_dir = Dir_Mysql_5_7 + "\\data";
+                       createDirectoryIfNotExists(fs, cm, data_dir);
+                       
+                       // Install the MySQL service
+                       cm.println(EPrintType.IN_PROGRESS, HostEnvUtil.class, 
"Installing MySQL as a windows service");
+                       // mysqld.exe --install
+                       host.execOut("\"" + Exe_Mysql_5_7_mysqld + "\" 
--install", AHost.TEN_MINUTES);
+                       
+                       // initialize the MySQL service
+                       cm.println(EPrintType.IN_PROGRESS, HostEnvUtil.class, 
"Initializing MySQL service");
+                       // mysqld.exe --initialize-insecure
+                       ExecOutput output = host.execOut("\"" + 
Exe_Mysql_5_7_mysqld + "\" --initialize-insecure", AHost.TEN_MINUTES);
+                       cm.println(EPrintType.CLUE, HostEnvUtil.class, 
output.output);
+               }
+               
+               // Start the MySQL service
+               cm.println(EPrintType.IN_PROGRESS, HostEnvUtil.class, "Starting 
MySQL service");
+               // start MySQL service using sc.exe
+               // sc start MySQL
+               host.execOut("sc.exe start MySQL", AHost.TEN_MINUTES);
+               
+               // Create database "test" if not exist
+               // mysql -u root -e "create database if not exists test"
+               cm.println(EPrintType.IN_PROGRESS, HostEnvUtil.class, "Creating 
test database on MySQL server");
+               host.execOut("\"" + Exe_Mysql_5_7_mysql + "\" -u root -e 
\"create database if not exists test\"", AHost.TEN_MINUTES);
+       }
+
+       /**
+        * @param fs
+        * @param cm
+        * @param dir_path
+        */
+       private static void createDirectoryIfNotExists(FileSystemScenario fs, 
ConsoleManager cm, String dir_path) {
+               if(!fs.exists(dir_path))
+               {
+                       File data_dir_file = new File(dir_path);
+                   // attempt to create the directory here
+                   boolean successful = data_dir_file.mkdirs();
+                   if (!successful)
+                   {
+                               cm.println(EPrintType.WARNING, 
HostEnvUtil.class, "Failed create directory " + dir_path);
+                               return;
+                   }
+               }
+       }
+
        /** PHP on Windows requires Microsoft's VC Runtime to be installed. 
This method ensures that the correct version is installed.
         * 
         * PHP 5.3 and 5.4 require the VC9 x86 Runtime
         * PHP 5.5+ require the VC11 x86 Runtime
+        * PHP 7.0+ require the VC14 x86 Runtime
         * 
         * Windows 8+ already has the VC9 x86 Runtime
         * 
@@ -143,49 +291,204 @@ public final class HostEnvUtil {
                if (!host.isWindows()) {
                        return;
                }
-               
+
                switch (build.getVersionBranch(cm, host)) {
                case PHP_5_3:
                case PHP_5_4:
                        installVCRT9(cm, fs, host);
                        break;
-               case PHP_7_0:
-               case PHP_Master:
-                       // TODO install VC14 CRT
                case PHP_5_5:
                case PHP_5_6:
-               default: 
-                       installVCRT9(cm, fs, host); // just in case
-                       installVCRT(cm, fs, host, "VC10 x86", "msvcr100.dll", 
"vc10_redist_x86.exe");
-                       installVCRT(cm, fs, host, "VC11 x86", "msvcr110.dll", 
"vc11_redist_x86.exe");
+                       installVCRT(cm, fs, host, "VC10 x86", 
File_VC10_Redist_X86, Sys_Dll_VC10_Redist_X86);
+                       installVCRT(cm, fs, host, "VC11 x86", 
File_VC11_Redist_X86, Sys_Dll_VC11_Redist_X86);
+                       if (build.isX64()) {
+                               installVCRT(cm, fs, host, "VC10 x64", 
File_VC10_Redist_X64, Sys_Dll_VC10_Redist_X64);
+                               installVCRT(cm, fs, host, "VC11 x64", 
File_VC11_Redist_X64, Sys_Dll_VC11_Redist_X64);
+                       }
+                       break;
+               case PHP_7_0:
+               case PHP_7_1:
+                       installVCRT14(cm, fs, host, "VC14 x86", 
File_VC14_Redist_X86, Sys_Dll_VC14Plus_Redist_X86);
+                       if (build.isX64()) {
+                               installVCRT14(cm, fs, host, "VC14 x64", 
File_VC14_Redist_X64, Sys_Dll_VC14Plus_Redist_X64);
+                       }
+                       break;
+               case PHP_7_2:
+               case PHP_7_3:
+                       installVCRT15(cm, fs, host, "VC15 x86", 
File_VC15_Redist_X86, Sys_Dll_VC14Plus_Redist_X86);
+                       if (build.isX64()) {
+                               installVCRT15(cm, fs, host, "VC15 x64", 
File_VC15_Redist_X64, Sys_Dll_VC14Plus_Redist_X64);
+                       }
+                       break;
+               case PHP_7_4:
+               case PHP_8_0:
+               case PHP_Master:
+               default:
+                       installVCRT16(cm, fs, host, "VS16 x86", 
File_VS16_Redist_X86, Sys_Dll_VC14Plus_Redist_X86);
                        if (build.isX64()) {
-                               installVCRT(cm, fs, host, "VC10 x64", 
"msvcr100.dll", "vc10_redist_x64.exe");
-                               installVCRT(cm, fs, host, "VC11 x64", 
"msvcr110.dll", "vc11_redist_x64.exe");
+                               installVCRT16(cm, fs, host, "VS16 x64", 
File_VS16_Redist_X64, Sys_Dll_VC14Plus_Redist_X64);
                        }
                        break;
                } // end switch
        } // end public static void installVCRuntime
        
-       protected static void installVCRT9(ConsoleManager cm, 
FileSystemScenario fs, AHost host) throws IllegalStateException, IOException, 
Exception {
+       
+       protected static boolean installedVCRT9(AHost host)
+       {
                // with VC9 (and before), checking WinSXS directory is the only 
way to tell
-               if (host.mDirContainsFragment(host.getSystemRoot()+"\\WinSxS", 
"VC9")) {
+               return host.mDirContainsFragment(host.getSystemRoot() + 
Dir_WinSxS, WinSxS_VC9_Fragment);
+       }
+       
+       
+       protected static void installVCRT9(ConsoleManager cm, 
FileSystemScenario fs, AHost host) throws IllegalStateException, IOException, 
Exception {
+               
+               if (installedVCRT9(host)) {
                        cm.println(EPrintType.CLUE, HostEnvUtil.class, "VC9 
Runtime already installed");
                } else {
                        doInstallVCRT(cm, fs, host, "VC9", 
"vc9_redist_x86.exe");
                }
        }
-       
-       protected static void installVCRT(ConsoleManager cm, FileSystemScenario 
fs, AHost host, String name, String dll_name, String filename) throws 
IllegalStateException, IOException, Exception {
+               
+       protected static void installVCRT(ConsoleManager cm, FileSystemScenario 
fs, AHost host, String name, String installerFile, String sysDllFile)
+                       throws IllegalStateException, IOException, Exception {
                // starting with VCRT10, checking the registry is the only way 
to tell
-               if (fs.exists(host.getSystemRoot()+"\\system32\\"+dll_name)) {
+               if (fs.exists(host.getSystemRoot() +  sysDllFile)) {
+                       cm.println(EPrintType.CLUE, HostEnvUtil.class, name+" 
Runtime already installed");
+               } else {
+                       doInstallVCRT(cm, fs, host, name, installerFile);
+               }
+       }
+       
+       protected static void installVCRT14(ConsoleManager cm, 
FileSystemScenario fs, AHost host, String name, String installerFile, String 
sysDllFile)
+                       throws IllegalStateException, IOException, Exception {
+
+               String dllFullName = host.getSystemRoot() + sysDllFile;
+               if(installedVCRT14(fs, dllFullName)) {
+                       cm.println(EPrintType.CLUE, HostEnvUtil.class, name+" 
Runtime already installed");
+               }
+               else {          
+                       doInstallVCRT(cm, fs, host, name, installerFile);
+               }
+       }
+
+       protected static void installVCRT15(ConsoleManager cm, 
FileSystemScenario fs, AHost host, String name, String installerFile, String 
sysDllFile)
+                       throws IllegalStateException, IOException, Exception {
+
+               String dllFullName = host.getSystemRoot() + sysDllFile;
+               if(installedVCRT15(fs, dllFullName)) {
+                       cm.println(EPrintType.CLUE, HostEnvUtil.class, name+" 
Runtime already installed");
+               }
+               else {
+                       doInstallVCRT(cm, fs, host, name, installerFile);
+               }
+       }
+
+       protected static void installVCRT16(ConsoleManager cm, 
FileSystemScenario fs, AHost host, String name, String installerFile, String 
sysDllFile)
+                       throws IllegalStateException, IOException, Exception {
+
+               if(installedVCRT16(fs, host.getSystemRoot() + sysDllFile)) {
                        cm.println(EPrintType.CLUE, HostEnvUtil.class, name+" 
Runtime already installed");
                } else {
-                       doInstallVCRT(cm, fs, host, name, filename);
+                       doInstallVCRT(cm, fs, host, name, installerFile);
+               }
+       }
+
+       // checking if VCRT15 is installed by existing of the vcruntime140.dll 
and the file version
+       private static boolean installedVCRT14(FileSystemScenario fs, String 
dllFile)
+       {
+               if(!fs.exists(dllFile))
+               {
+                       return false;
+               }
+               
+               int[] fileVersion = getVC14Version(fs, dllFile);
+               if(fileVersion.length != 4)
+               {
+                       return false;
                }
+
+        // VC14 Runtime dll file version: 14.0.23026.0
+               return fileVersion[0] == 14 && fileVersion[1] > 0;
        }
        
-       protected static void doInstallVCRT(ConsoleManager cm, 
FileSystemScenario fs, AHost host, String name, String filename) throws 
IllegalStateException, IOException, Exception {
-               String local_file = 
LocalHost.getLocalPfttDir()+"/cache/dep/VCRedist/"+filename;
+       // checking if VCRT15 is installed by existing of the vcruntime140.dll 
and the file version
+       private static boolean installedVCRT15(FileSystemScenario fs, String 
dllFile)
+       {
+               if(!fs.exists(dllFile))
+               {
+                       return false;
+               }
+               
+               int[] fileVersion = getVC14Version(fs, dllFile);
+               if(fileVersion.length != 4)
+               {
+                       return false;
+               }
+
+        // VC15 Runtime dll file version: 14.16.27027.1
+               return fileVersion[0] == 14 && fileVersion[1] >= 16;
+       }
+       
+       // checking if VCRT15 is installed by existing of the vcruntime140.dll 
and the file version
+       private static boolean installedVCRT16(FileSystemScenario fs, String 
dllFile)
+       {
+               if(!fs.exists(dllFile))
+               {
+                       return false;
+               }
+               
+               int[] fileVersion = getVC14Version(fs, dllFile);
+               if(fileVersion.length != 4)
+               {
+                       return false;
+               }
+
+        // VC16 Runtime dll file version: 14.20.27508.1
+               return fileVersion[0] == 14 && fileVersion[1] >= 20;
+       }
+
+       // checking if VCRT15 is installed by existing of the vcruntime140.dll 
and the file version
+       private static int[] getVC14Version(FileSystemScenario fs, String 
dllFile)
+       {
+               if(!fs.exists(dllFile))
+               {
+                       return new int[0];
+               }
+               
+        IntByReference dwDummy = new IntByReference();
+        dwDummy.setValue(0);
+
+        int versionlength =
+                
com.sun.jna.platform.win32.Version.INSTANCE.GetFileVersionInfoSize(
+                               dllFile, dwDummy);
+
+        byte[] bufferarray = new byte[versionlength];
+        Pointer lpData = new Memory(bufferarray.length);
+        PointerByReference lplpBuffer = new PointerByReference();
+        IntByReference puLen = new IntByReference();
+
+        boolean fileInfoResult =
+                com.sun.jna.platform.win32.Version.INSTANCE.GetFileVersionInfo(
+                               dllFile, 0, versionlength, lpData);
+
+        boolean verQueryVal =
+                com.sun.jna.platform.win32.Version.INSTANCE.VerQueryValue(
+                        lpData, "\\", lplpBuffer, puLen);
+
+        VS_FIXEDFILEINFO lplpBufStructure = new 
VS_FIXEDFILEINFO(lplpBuffer.getValue());
+        lplpBufStructure.read();
+        
+        int v1 = (lplpBufStructure.dwFileVersionMS).intValue() >> 16;
+        int v2 = (lplpBufStructure.dwFileVersionMS).intValue() & 0xffff;
+        int v3 = (lplpBufStructure.dwFileVersionLS).intValue() >> 16;
+        int v4 = (lplpBufStructure.dwFileVersionLS).intValue() & 0xffff;
+
+        return new int[] {v1, v2, v3, v4};
+       }
+       
+       
+       protected static void doInstallVCRT(ConsoleManager cm, 
FileSystemScenario fs, AHost host, String name, String installerFile) throws 
IllegalStateException, IOException, Exception {
+               String local_file = LocalHost.getLocalPfttDir() + installerFile;
                String remote_file = local_file;
                if (host.isRemote()) {
                        remote_file = fs.mktempname(HostEnvUtil.class, ".exe");
@@ -194,7 +497,7 @@ public final class HostEnvUtil {
                        host.upload(local_file, remote_file);
                }
                cm.println(EPrintType.IN_PROGRESS, HostEnvUtil.class, 
"Installing "+name+" Runtime");
-               host.execElevated(cm, HostEnvUtil.class, remote_file+" /Q 
/NORESTART", AHost.FOUR_HOURS);
+               host.execElevated(cm, HostEnvUtil.class, remote_file+" /Q 
/NORESTART", AHost.TEN_MINUTES);
                if (remote_file!=null)
                        fs.delete(remote_file);
        }
@@ -250,7 +553,165 @@ public final class HostEnvUtil {
        public static boolean regDel(ConsoleManager cm, AHost host, String key, 
String value_name) throws Exception {
                return host.execElevated(cm, HostEnvUtil.class, "REG DELETE 
\""+key+"\" /v "+value_name + " /f", AHost.ONE_MINUTE);
        }
+       
+       public static void setupHostEnv(FileSystemScenario fs, LocalHost host, 
LocalConsoleManager cm, PhpBuild build)
+               throws IllegalStateException, IOException, Exception {
+               if (host.isWindows()) {
+                       setupWindows(fs, host, cm, build);
+               } else {
+                       // TODO: setup none windows environment
+               }
+       }
+       
+       private static void setupWindows(FileSystemScenario fs, LocalHost host, 
LocalConsoleManager cm, PhpBuild build)
+               throws IllegalStateException, IOException, Exception {
+
+               downloadVCRuntimeByBuild(fs, host, cm, build);
+               
+               downloadMySQL5(fs, host, cm);
+               
+               cm.println(EPrintType.COMPLETED_OPERATION, HostEnvUtil.class, 
"Windows host setup to run PHP.");
+       }
+       
+       private static void downloadMySQL5(FileSystemScenario fs, LocalHost 
host, LocalConsoleManager cm) {
+
+               if(!fs.exists(Exe_Mysql_5_7_mysqld))
+               {
+                       // download MySQL and unzip 
+                       createDirectoryIfNotExists(fs, cm, Dir_Mysql);
+                       DownloadUtil.downloadAndUnzip(cm, host, 
Link_Mysql_Win32_5_7_25, Dir_Mysql);
+               }
+               else
+               {
+                       cm.println(EPrintType.CLUE, HostEnvUtil.class, "MySQL 
5.7.25 is already downloaded.");
+               }
+       }
+       
+       private static void downloadVCRuntimeByBuild(FileSystemScenario fs, 
LocalHost host, LocalConsoleManager cm,
+                       PhpBuild build)
+               throws IllegalStateException, IOException, Exception {
+               if (!host.isWindows()) {
+                       return;
+               }
+
+               String system_dir = host.getSystemRoot();
+               switch (build.getVersionBranch(cm, host)) {
+               case PHP_5_3:
+               case PHP_5_4:
+                       downloadVCRuntime9(fs, host, cm);
+                       break;
+               case PHP_5_5:
+               case PHP_5_6:
+                       downloadVCRuntime(fs, cm, "VC10 x86", 
Link_VC10_Redist_X86, File_VC10_Redist_X86, system_dir + 
Sys_Dll_VC10_Redist_X86);
+                       downloadVCRuntime(fs, cm, "VC11 x86", 
Link_VC11_Redist_X86, File_VC11_Redist_X86, system_dir + 
Sys_Dll_VC11_Redist_X86);
+                       if (build.isX64()) {
+                               downloadVCRuntime(fs, cm, "VC10 x64", 
Link_VC10_Redist_X64, File_VC10_Redist_X64, system_dir + 
Sys_Dll_VC10_Redist_X64);
+                               downloadVCRuntime(fs, cm, "VC11 x64", 
Link_VC11_Redist_X64, File_VC11_Redist_X64, system_dir + 
Sys_Dll_VC11_Redist_X64);
+                       }
+                       break;
+               case PHP_7_0:
+               case PHP_7_1:
+                       downloadVC14Runtime(fs, cm, "VC14 x86", 
Link_VC14_Redist_X86, File_VC14_Redist_X86, system_dir + 
Sys_Dll_VC14Plus_Redist_X86);
+                       if (build.isX64()) {
+                               downloadVC14Runtime(fs, cm, "VC14 x64", 
Link_VC14_Redist_X64, File_VC14_Redist_X64, system_dir + 
Sys_Dll_VC14Plus_Redist_X64);
+                       }
+                       break;
+               case PHP_7_2:
+               case PHP_7_3:
+                       downloadVC15Runtime(fs, cm, "VC15 x86", 
Link_VC15_Redist_X86, File_VC15_Redist_X86, system_dir + 
Sys_Dll_VC14Plus_Redist_X86);
+                       if (build.isX64()) {
+                               downloadVC15Runtime(fs, cm, "VC15 x64", 
Link_VC15_Redist_X64, File_VC15_Redist_X64, system_dir + 
Sys_Dll_VC14Plus_Redist_X64);
+                       }
+                       break;
+               case PHP_7_4:
+               case PHP_8_0:
+               case PHP_Master:
+               default:
+                       downloadVC16Runtime(fs, cm, "VS16 x86", 
Link_VS16_Redist_X86, File_VS16_Redist_X86, system_dir + 
Sys_Dll_VC14Plus_Redist_X86);
+                       if (build.isX64()) {
+                               downloadVC16Runtime(fs, cm, "VS16 x64", 
Link_VS16_Redist_X64, File_VS16_Redist_X64, system_dir + 
Sys_Dll_VC14Plus_Redist_X64);
+                       }
+                       break;
+               } // end switch
+       }
                        
+       private static void downloadVCRuntime9(FileSystemScenario fs, LocalHost 
host, LocalConsoleManager cm)
+       {
+               if (installedVCRT9(host)) {
+                       cm.println(EPrintType.CLUE, HostEnvUtil.class, "VC9 
Runtime already installed, skip downloading.");
+               }
+               else
+               {
+                       String pftt_dir = LocalHost.getLocalPfttDir();
+                       downloadFile(fs, cm, "VC9 Runtime", 
Link_VC9_Redist_X86, pftt_dir + File_VC9_Redist_X86);
+               }
+       }
+               
+       private static void downloadVC14Runtime(FileSystemScenario fs, 
LocalConsoleManager cm,
+                       String name, String remote_url, String installer_file, 
String dll_file)
+       {
+               if(installedVCRT14(fs, dll_file))
+               {
+                       cm.println(EPrintType.CLUE, HostEnvUtil.class, name + " 
Runtime already installed, skip downloading.");
+               }
+               else
+               {
+                       downloadFile(fs, cm, name, remote_url, installer_file);
+               }
+       }
+       
+       private static void downloadVC15Runtime(FileSystemScenario fs, 
LocalConsoleManager cm,
+                       String name, String remote_url, String installer_file, 
String dll_file)
+       {
+               if(installedVCRT15(fs, dll_file))
+               {
+                       cm.println(EPrintType.CLUE, HostEnvUtil.class, name + " 
Runtime already installed, skip downloading.");
+               }
+               else
+               {
+                       downloadFile(fs, cm, name, remote_url, installer_file);
+               }
+       }
+
+       
+       private static void downloadVC16Runtime(FileSystemScenario fs, 
LocalConsoleManager cm,
+                       String name, String remote_url, String installer_file, 
String dll_file)
+       {
+               if(installedVCRT16(fs, dll_file))
+               {
+                       cm.println(EPrintType.CLUE, HostEnvUtil.class, name + " 
Runtime already installed, skip downloading.");
+               }
+               else
+               {
+                       downloadFile(fs, cm, name, remote_url, installer_file);
+               }
+       }
+       
+       private static void downloadVCRuntime(FileSystemScenario fs, 
LocalConsoleManager cm,
+                       String name, String remote_url, String installer_file, 
String dll_file)
+       {
+               if(fs.exists(dll_file))
+               {
+                       cm.println(EPrintType.CLUE, HostEnvUtil.class, name + " 
Runtime already installed, skip downloading.");
+               }
+               else
+               {
+                       downloadFile(fs, cm, name, remote_url, installer_file);
+               }
+       }
+
+       private static void downloadFile(FileSystemScenario fs, 
LocalConsoleManager cm,
+                       String name, String remote_url, String local_file)
+       {
+               if(fs.exists(local_file))
+               {
+                       cm.println(EPrintType.CLUE, HostEnvUtil.class, name + " 
Installer [" + local_file + "] already downloaded.");
+               }
+               else
+               {
+                       DownloadUtil.downloadFile(cm, remote_url, local_file);
+               }
+       }
 
        private HostEnvUtil() {}

Reply via email to