@echo off

rem =====================================================================
rem  PERSISTENT CONSOLE WRAPPER
rem  The first process starts a child CMD with /K. The child window remains
rem  open even if the wizard terminates unexpectedly or hits a syntax error.
rem =====================================================================
if not defined KASPERSKY_WIZARD_KEEP_OPEN (
    set "KASPERSKY_WIZARD_KEEP_OPEN=1"
    "%ComSpec%" /d /k call "%~f0"
    exit /b
)

setlocal EnableExtensions EnableDelayedExpansion
title Baltika OT - Kaspersky Installation Wizard v3.9

rem =====================================================================
rem  BALTIKA OT - KASPERSKY INSTALLATION WIZARD v3.9
rem
rem  Put this BAT file in the root of the "Kasper" folder on the USB drive.
rem  The wizard builds and launches the approved interactive installation.
rem  It does NOT perform a fully silent installation.
rem
rem  Compatibility goal: Windows XP / Server 2003 and newer.
rem  The script intentionally uses SET /P instead of CHOICE.EXE because
rem  CHOICE.EXE may be absent on old Windows installations.
rem =====================================================================

set "ROOT=%~dp0"
set "LOGDIR=%ROOT%Logs"

rem All input files are discovered recursively below ROOT.
rem Folder names and nesting do not matter.
set "PF86=%ProgramFiles(x86)%"
if not exist "%LOGDIR%" md "%LOGDIR%" >nul 2>&1
set "LOG=%LOGDIR%\%COMPUTERNAME%_Kaspersky_plan.txt"
set "DEBUGLOG=%LOGDIR%\%COMPUTERNAME%_Kaspersky_debug.log"
>>"%DEBUGLOG%" echo ============================================================
>>"%DEBUGLOG%" echo Wizard version: 3.9
>>"%DEBUGLOG%" echo Wizard started: %DATE% %TIME%
>>"%DEBUGLOG%" echo Script: %~f0
>>"%DEBUGLOG%" echo Computer: %COMPUTERNAME%
>>"%DEBUGLOG%" echo Root: %ROOT%
>>"%DEBUGLOG%" echo Discovery mode: recursive; folder names and nesting are ignored.

call :SelectLanguage
call :SetMessages
call :Header
call :AskRunMode
if errorlevel 1 goto :CloseWizard
if /I "%RUN_MODE%"=="SELFTEST" goto :SelfTestMain

call :CheckAdmin
if errorlevel 1 goto :EndError

call :DetectOS
if errorlevel 1 goto :EndError

call :ShowOS
call :AskTarget
if errorlevel 1 goto :EndError

:SelectKSCMain
call :AskKSC
if errorlevel 1 goto :EndError

:CheckKSCMain
>>"%DEBUGLOG%" echo [%DATE% %TIME%] Starting KSC check: %KSC%
call :CheckConnectivity
set "CONNECTION_RC=%ERRORLEVEL%"
>>"%DEBUGLOG%" echo [%DATE% %TIME%] KSC check return code: %CONNECTION_RC%
if "%CONNECTION_RC%"=="0" goto :KSCConnectionAutoOK

call :ConnectionFailureMenu
>>"%DEBUGLOG%" echo [%DATE% %TIME%] Connection menu action: %CONN_ACTION%
if /I "%CONN_ACTION%"=="RETRY" goto :CheckKSCMain
if /I "%CONN_ACTION%"=="CHANGE" goto :SelectKSCMain
if /I "%CONN_ACTION%"=="CONTINUE" goto :KSCConnectionManualOK
goto :EndError

:KSCConnectionAutoOK
set "KSC_CONNECTION=OK"
goto :KSCConnectionOk

:KSCConnectionManualOK
set "KSC_CONNECTION=MANUAL_CONFIRMATION"
goto :KSCConnectionOk

:KSCConnectionOk
call :BuildOSPlan
if /I "%PLAN%"=="STOP" goto :StopPlan

call :ResolveFiles
if errorlevel 1 goto :EndError

call :WritePlan
call :ShowPlan
call :AskAction

if "%ACTION%"=="1" goto :Execute
if "%ACTION%"=="2" goto :PlanOnly
goto :End

:Execute
call :ConfirmAntivirus
if errorlevel 1 goto :EndError

call :InstallRequiredKB
if errorlevel 1 goto :EndError
if "%REBOOT_REQUIRED%"=="1" goto :NeedReboot

call :LaunchInstallers
if errorlevel 1 goto :EndError

call :PostCheck
goto :EndSuccess

:PlanOnly
echo.
echo %M_PLAN_SAVED%
echo %LOG%
echo.
echo %M_PLAN_ONLY_TEXT%
>>"%DEBUGLOG%" echo [%DATE% %TIME%] Wizard finished: PLAN_ONLY
goto :CloseWizard

:StopPlan
if defined STOP_REASON goto :StopPlanReasonReady
if /I "%LANG%"=="RU" (
    set "STOP_REASON=Комбинация ОС, версии, Service Pack, редакции или разрядности не разрешена для выбранного комплекта."
) else (
    set "STOP_REASON=The detected OS version, Service Pack, edition or architecture is not approved for the selected package."
)
:StopPlanReasonReady
call :WritePlan
echo.
echo ============================================================
echo %M_INSTALL_STOPPED%
echo ============================================================
echo %STOP_REASON%
echo.
echo KSC: %KSC%
echo KSC connection: %KSC_CONNECTION%
echo.
echo %M_PLAN_SAVED%
echo %LOG%
echo.
echo ============================================================
echo %M_SAFE_STOP_TITLE%
echo ============================================================
echo %M_SAFE_STOP_TEXT%
>>"%DEBUGLOG%" echo [%DATE% %TIME%] Wizard finished: SAFE_STOP. Reason: %STOP_REASON%
goto :CloseWizard



rem =====================================================================
rem READINESS SELF-TEST / DRY-RUN MODE
rem
rem Purpose:
rem   Verify that this removable kit contains every component required by
rem   every OS group that the normal wizard can install.
rem
rem The audit does NOT test unsupported operating systems. It checks:
rem   - complete Network Agent distributions;
rem   - complete KICS distribution;
rem   - prerequisite Windows updates for x86 and x64;
rem   - autonomous packages for the two standard KSC servers;
rem   - coverage of every supported OS group.
rem =====================================================================

:SelfTestMain
set "SELFTEST_LOG=%LOGDIR%\%COMPUTERNAME%_Kaspersky_readiness.txt"
set "SELFTEST_DEBUGLOG=%LOGDIR%\%COMPUTERNAME%_Kaspersky_readiness_debug.log"
set "LAUNCHTEST_LOG=%LOGDIR%\%COMPUTERNAME%_Kaspersky_launch_test.txt"

> "%SELFTEST_LOG%" echo BALTIKA OT - KASPERSKY KIT READINESS AUDIT v3.9
>>"%SELFTEST_LOG%" echo ============================================================
>>"%SELFTEST_LOG%" echo Computer: %COMPUTERNAME%
>>"%SELFTEST_LOG%" echo Date: %DATE% %TIME%
>>"%SELFTEST_LOG%" echo Root: %ROOT%
>>"%SELFTEST_LOG%" echo Scope: supported OS groups only; no installers or network checks.
>>"%SELFTEST_LOG%" echo.

> "%SELFTEST_DEBUGLOG%" echo BALTIKA OT - KASPERSKY KIT DETAILED READINESS LOG v3.9
>>"%SELFTEST_DEBUGLOG%" echo ============================================================
>>"%SELFTEST_DEBUGLOG%" echo Computer: %COMPUTERNAME%
>>"%SELFTEST_DEBUGLOG%" echo Date: %DATE% %TIME%
>>"%SELFTEST_DEBUGLOG%" echo Script: %~f0
>>"%SELFTEST_DEBUGLOG%" echo Root: %ROOT%
>>"%SELFTEST_DEBUGLOG%" echo Discovery: recursive below ROOT
>>"%SELFTEST_DEBUGLOG%" echo.

if not exist "%LAUNCHTEST_LOG%" (
    > "%LAUNCHTEST_LOG%" echo BALTIKA OT - KASPERSKY INSTALLER LAUNCH TEST v3.9
    >>"%LAUNCHTEST_LOG%" echo ============================================================
    >>"%LAUNCHTEST_LOG%" echo Computer: %COMPUTERNAME%
    >>"%LAUNCHTEST_LOG%" echo Date: %DATE% %TIME%
    >>"%LAUNCHTEST_LOG%" echo Root: %ROOT%
    >>"%LAUNCHTEST_LOG%" echo Scope: interactive smoke test on the current OS only.
    >>"%LAUNCHTEST_LOG%" echo.
)

:SelfTestMenu
cls
echo ============================================================
echo %M_RT_TITLE%
echo ============================================================
echo %M_RT_WARNING%
echo.
echo [1] %M_RT_FULL%
echo [2] %M_RT_ONE_PROFILE%
echo [3] %M_RT_ASSETS%
echo [4] %M_LT_MENU_ITEM%
echo [0] %M_EXIT%
echo.
set "ANSWER="
set /p "ANSWER=%M_ENTER_CHOICE% [0/1/2/3/4]: "
if "%ANSWER%"=="1" goto :RT_FullAudit
if "%ANSWER%"=="2" goto :RT_SelectProfile
if "%ANSWER%"=="3" goto :RT_AssetsOnly
if "%ANSWER%"=="4" goto :LT_Menu
if "%ANSWER%"=="0" goto :CloseWizard
echo %M_INVALID%
goto :SelfTestMenu


:RT_Reset
set "RT_CRITICAL_TOTAL=0"
set "RT_CRITICAL_OK=0"
set "RT_CRITICAL_MISSING=0"
set "RT_ROUTE_TOTAL=0"
set "RT_ROUTE_OK=0"
set "RT_ROUTE_MISSING=0"
set "RT_OPTIONAL_TOTAL=0"
set "RT_OPTIONAL_OK=0"
set "RT_OPTIONAL_MISSING=0"
set "RT_PROFILE_TOTAL=0"
set "RT_PROFILE_READY=0"
set "RT_PROFILE_NOT_READY=0"

set "C_AGENT105=0"
set "C_AGENT14=0"
set "C_AGENT15=0"
set "C_KICS=0"
set "C_KB_XP2868626_X86=0"

set "C_KB60_4493730_X86=0"
set "C_KB60_4493730_X64=0"
set "C_KB60_4474419_X86=0"
set "C_KB60_4474419_X64=0"
set "C_KB60_3063858_X86=0"
set "C_KB60_3063858_X64=0"

set "C_KB61_4490628_X86=0"
set "C_KB61_4490628_X64=0"
set "C_KB61_4474419_X86=0"
set "C_KB61_4474419_X64=0"
set "C_KB61_3063858_X86=0"
set "C_KB61_3063858_X64=0"

set "C_AUTO_KICS_207=0"
set "C_AUTO_KICS_105=0"
set "C_AUTO_AGENT_207=0"
set "C_AUTO_AGENT_105=0"
set "C_PORTQRY=0"
exit /b 0


:RT_FullAudit
call :RT_Reset
cls
echo ============================================================
echo %M_RT_FULL%
echo ============================================================
echo %M_RT_WARNING%
echo.
>>"%SELFTEST_LOG%" echo FULL READINESS AUDIT
>>"%SELFTEST_LOG%" echo ------------------------------------------------------------
>>"%SELFTEST_DEBUGLOG%" echo FULL READINESS AUDIT STARTED %DATE% %TIME%

call :RT_AuditComponents
if errorlevel 1 goto :RT_AuditInternalError
call :RT_EvaluateAllProfiles
if errorlevel 1 goto :RT_AuditInternalError
call :RT_ShowSummary
goto :RT_Close

:RT_AuditInternalError
echo.
echo ============================================================
echo INTERNAL READINESS AUDIT ERROR
echo ============================================================
echo The audit stopped unexpectedly. Review:
echo %SELFTEST_DEBUGLOG%
>>"%SELFTEST_DEBUGLOG%" echo INTERNAL READINESS AUDIT ERROR. ErrorLevel=%ERRORLEVEL%
goto :RT_Close


:RT_SelectProfile
call :RT_Reset
cls
echo ============================================================
echo %M_RT_SELECT_PROFILE%
echo ============================================================
echo [1]  Windows XP SP2 x86/x64; Windows Server 2003 SP1/SP2/R2 SP2
echo [2]  Windows XP SP3 / XP Embedded SP3 x86
echo [3]  Windows Server 2008 SP2 x86
echo [4]  Windows Server 2008 SP2 x64
echo [5]  Windows 7 SP1 / Embedded 7 SP1 x86
echo [6]  Windows 7 SP1 / Server 2008 R2 SP1 / Embedded 7 SP1 x64
echo [7]  Windows 8 / 8.1 / Embedded 8 / 8.1 x86/x64
echo [8]  Windows 10 / Windows 10 IoT supported versions x86/x64
echo [9]  Windows 11 / Windows 11 IoT 21H2-23H2 x64 with KICS
echo [10] Windows 11 24H2 x64 - Network Agent only
echo [11] Windows Server 2012-2022 x64
echo [0]  %M_EXIT%
echo.
set "ANSWER="
set "RT_SELECTED_PROFILE="
set /p "ANSWER=%M_ENTER_CHOICE% [0-11]: "
if "%ANSWER%"=="0" goto :SelfTestMenu
if "%ANSWER%"=="1" set "RT_SELECTED_PROFILE=1"
if "%ANSWER%"=="2" set "RT_SELECTED_PROFILE=2"
if "%ANSWER%"=="3" set "RT_SELECTED_PROFILE=3"
if "%ANSWER%"=="4" set "RT_SELECTED_PROFILE=4"
if "%ANSWER%"=="5" set "RT_SELECTED_PROFILE=5"
if "%ANSWER%"=="6" set "RT_SELECTED_PROFILE=6"
if "%ANSWER%"=="7" set "RT_SELECTED_PROFILE=7"
if "%ANSWER%"=="8" set "RT_SELECTED_PROFILE=8"
if "%ANSWER%"=="9" set "RT_SELECTED_PROFILE=9"
if "%ANSWER%"=="10" set "RT_SELECTED_PROFILE=10"
if "%ANSWER%"=="11" set "RT_SELECTED_PROFILE=11"

if not defined RT_SELECTED_PROFILE (
    echo %M_INVALID%
    goto :RT_SelectProfile
)

call :RT_AuditComponents
if "%RT_SELECTED_PROFILE%"=="1" call :RT_Profile1
if "%RT_SELECTED_PROFILE%"=="2" call :RT_Profile2
if "%RT_SELECTED_PROFILE%"=="3" call :RT_Profile3
if "%RT_SELECTED_PROFILE%"=="4" call :RT_Profile4
if "%RT_SELECTED_PROFILE%"=="5" call :RT_Profile5
if "%RT_SELECTED_PROFILE%"=="6" call :RT_Profile6
if "%RT_SELECTED_PROFILE%"=="7" call :RT_Profile7
if "%RT_SELECTED_PROFILE%"=="8" call :RT_Profile8
if "%RT_SELECTED_PROFILE%"=="9" call :RT_Profile9
if "%RT_SELECTED_PROFILE%"=="10" call :RT_Profile10
if "%RT_SELECTED_PROFILE%"=="11" call :RT_Profile11

:RT_ProfileSelectedDone
call :RT_ShowSummary
goto :RT_Close


:RT_AuditComponents
echo ============================================================
echo %M_RT_CRITICAL%
echo ============================================================
>>"%SELFTEST_LOG%" echo.
>>"%SELFTEST_LOG%" echo CRITICAL COMPONENTS
>>"%SELFTEST_LOG%" echo ------------------------------------------------------------

call :RT_CheckAgentBundle "Network Agent 10.5.1781 complete distribution" "10.5.1781" "C_AGENT105" "0"
call :RT_CheckAgentBundle "Network Agent 14.0.0.20023 complete distribution" "14.0.0.20023" "C_AGENT14" "1"
call :RT_CheckAgentBundle "Network Agent 15.1.0.20748 complete distribution" "15.1.0.20748" "C_AGENT15" "1"
call :RT_CheckKicsBundle "KICS for Nodes 4.0.0.236 complete distribution" "C_KICS"

call :RT_CheckUpdate "Windows XP KB2868626 x86" "WindowsXP" "KB2868626" "x86" "C_KB_XP2868626_X86"

call :RT_CheckUpdate "Windows Server 2008 KB4493730 x86" "Windows6.0" "KB4493730" "x86" "C_KB60_4493730_X86"
call :RT_CheckUpdate "Windows Server 2008 KB4493730 x64" "Windows6.0" "KB4493730" "x64" "C_KB60_4493730_X64"
call :RT_CheckUpdate "Windows Server 2008 KB4474419 x86" "Windows6.0" "KB4474419" "x86" "C_KB60_4474419_X86"
call :RT_CheckUpdate "Windows Server 2008 KB4474419 x64" "Windows6.0" "KB4474419" "x64" "C_KB60_4474419_X64"
call :RT_CheckUpdate "Windows Server 2008 KB3063858 x86" "Windows6.0" "KB3063858" "x86" "C_KB60_3063858_X86"
call :RT_CheckUpdate "Windows Server 2008 KB3063858 x64" "Windows6.0" "KB3063858" "x64" "C_KB60_3063858_X64"

call :RT_CheckUpdate "Windows 7 / Server 2008 R2 KB4490628 x86" "Windows6.1" "KB4490628" "x86" "C_KB61_4490628_X86"
call :RT_CheckUpdate "Windows 7 / Server 2008 R2 KB4490628 x64" "Windows6.1" "KB4490628" "x64" "C_KB61_4490628_X64"
call :RT_CheckUpdate "Windows 7 / Server 2008 R2 KB4474419 x86" "Windows6.1" "KB4474419" "x86" "C_KB61_4474419_X86"
call :RT_CheckUpdate "Windows 7 / Server 2008 R2 KB4474419 x64" "Windows6.1" "KB4474419" "x64" "C_KB61_4474419_X64"
call :RT_CheckUpdate "Windows 7 / Server 2008 R2 KB3063858 x86" "Windows6.1" "KB3063858" "x86" "C_KB61_3063858_X86"
call :RT_CheckUpdate "Windows 7 / Server 2008 R2 KB3063858 x64" "Windows6.1" "KB3063858" "x64" "C_KB61_3063858_X64"

echo.
echo ============================================================
echo %M_RT_ROUTES%
echo ============================================================
>>"%SELFTEST_LOG%" echo.
>>"%SELFTEST_LOG%" echo STANDARD KSC AUTONOMOUS PACKAGES
>>"%SELFTEST_LOG%" echo ------------------------------------------------------------

call :RT_CheckAutonomous "Agent + KICS package for KSC 10.255.40.207" "KICS" "10.255.40.207" "C_AUTO_KICS_207"
call :RT_CheckAutonomous "Agent + KICS package for KSC 172.16.66.105" "KICS" "172.16.66.105" "C_AUTO_KICS_105"
call :RT_CheckAutonomous "Agent-only package for KSC 10.255.40.207" "AGENT" "10.255.40.207" "C_AUTO_AGENT_207"
call :RT_CheckAutonomous "Agent-only package for KSC 172.16.66.105" "AGENT" "172.16.66.105" "C_AUTO_AGENT_105"

echo.
echo ============================================================
echo %M_RT_OPTIONAL%
echo ============================================================
>>"%SELFTEST_LOG%" echo.
>>"%SELFTEST_LOG%" echo OPTIONAL DIAGNOSTIC COMPONENTS
>>"%SELFTEST_LOG%" echo ------------------------------------------------------------

call :RT_CheckPortQry "PortQry.exe" "C_PORTQRY"
exit /b 0


:RT_CheckAgentBundle
set "RT_LABEL=%~1"
set "RT_VERSION=%~2"
set "RT_FLAG=%~3"
set "RT_REQUIRE_PRIVACY=%~4"
set "RT_OK=1"
set "RT_DETAILS="
set "RT_SELECTED="

call :FindAgentSetupByVersion "%RT_VERSION%"
set "RT_SELECTED=!FOUND_AGENT_SETUP!"

if not defined FOUND_AGENT_SETUP (
    set "RT_OK=0"
    set "RT_DETAILS=setup.exe not found"
    goto :RT_CheckAgentBundleDone
)

for %%D in ("!FOUND_AGENT_SETUP!") do set "RT_HOME=%%~dpD"

if not exist "!RT_HOME!exec\" (
    set "RT_OK=0"
    set "RT_DETAILS=!RT_DETAILS! missing exec directory;"
) else (
    set "RT_EXEC_FILE="
    for /f "delims=" %%F in ('dir /b /s /a-d "!RT_HOME!exec\*" 2^>nul') do if not defined RT_EXEC_FILE set "RT_EXEC_FILE=%%F"
    if not defined RT_EXEC_FILE (
        set "RT_OK=0"
        set "RT_DETAILS=!RT_DETAILS! empty exec directory;"
    )
)

set "RT_KUD_FILE="
for /f "delims=" %%F in ('dir /b /a-d "!RT_HOME!*.kud" 2^>nul') do if not defined RT_KUD_FILE set "RT_KUD_FILE=%%F"
if not defined RT_KUD_FILE (
    set "RT_OK=0"
    set "RT_DETAILS=!RT_DETAILS! *.kud not found;"
)

if not exist "!RT_HOME!license.txt" (
    set "RT_OK=0"
    set "RT_DETAILS=!RT_DETAILS! license.txt not found;"
)

if "%RT_REQUIRE_PRIVACY%"=="1" if not exist "!RT_HOME!privacy_policy.txt" (
    set "RT_OK=0"
    set "RT_DETAILS=!RT_DETAILS! privacy_policy.txt not found;"
)

:RT_CheckAgentBundleDone
set "%RT_FLAG%=%RT_OK%"
call :RT_RegisterCriticalCurrent
exit /b 0


:RT_CheckKicsBundle
set "RT_LABEL=%~1"
set "RT_FLAG=%~2"
set "RT_OK=1"
set "RT_DETAILS="
set "RT_SELECTED="

call :FindKicsSetup
set "RT_SELECTED=!FOUND_KICS_SETUP!"

if not defined FOUND_KICS_SETUP (
    set "RT_OK=0"
    set "RT_DETAILS=setupui.exe not found"
    goto :RT_CheckKicsBundleDone
)

for %%D in ("!FOUND_KICS_SETUP!") do set "RT_HOME=%%~dpD"

if not exist "!RT_HOME!kics.kud" (
    set "RT_OK=0"
    set "RT_DETAILS=!RT_DETAILS! kics.kud not found;"
)

for %%D in (client endpoint_agent exec gateway kvrt setup) do (
    if not exist "!RT_HOME!%%D\" (
        set "RT_OK=0"
        set "RT_DETAILS=!RT_DETAILS! %%D directory not found;"
    ) else (
        set "RT_DIR_FILE="
        for /f "delims=" %%F in ('dir /b /s /a-d "!RT_HOME!%%D\*" 2^>nul') do if not defined RT_DIR_FILE set "RT_DIR_FILE=%%F"
        if not defined RT_DIR_FILE (
            set "RT_OK=0"
            set "RT_DETAILS=!RT_DETAILS! %%D directory is empty;"
        )
    )
)

:RT_CheckKicsBundleDone
set "%RT_FLAG%=%RT_OK%"
call :RT_RegisterCriticalCurrent
exit /b 0


:RT_CheckUpdate
set "RT_LABEL=%~1"
set "RT_PREFIX=%~2"
set "RT_KB=%~3"
set "RT_ARCH=%~4"
set "RT_FLAG=%~5"
set "RT_OK=0"
set "RT_DETAILS="
set "RT_SELECTED="

call :FindUpdateByCriteria "%RT_PREFIX%" "%RT_KB%" "%RT_ARCH%"
set "RT_SELECTED=!FOUND_UPDATE_FILE!"

if defined FOUND_UPDATE_FILE set "RT_OK=1"
if %FOUND_UPDATE_UNIQUE_COUNT% GTR 1 (
    set "RT_OK=0"
    set "RT_DETAILS=multiple different update files found"
)
if not defined FOUND_UPDATE_FILE set "RT_DETAILS=update file not found"

set "%RT_FLAG%=%RT_OK%"
call :RT_RegisterCriticalCurrent
exit /b 0


:RT_CheckAutonomous
set "RT_LABEL=%~1"
set "RT_TYPE=%~2"
set "RT_KSC=%~3"
set "RT_FLAG=%~4"
set "RT_OK=0"
set "RT_DETAILS="
set "RT_SELECTED="

call :FindAutonomousPackage "%RT_TYPE%" "%RT_KSC%"
set "RT_SELECTED=!FOUND_PACKAGE!"

if defined FOUND_PACKAGE set "RT_OK=1"
if %FOUND_PACKAGE_UNIQUE_COUNT% GTR 1 (
    set "RT_OK=0"
    set "RT_DETAILS=multiple different packages found"
)
if not defined FOUND_PACKAGE set "RT_DETAILS=package not found"

set "%RT_FLAG%=%RT_OK%"
call :RT_RegisterRouteCurrent
exit /b 0


:RT_CheckPortQry
set "RT_LABEL=%~1"
set "RT_FLAG=%~2"
set "RT_OK=0"
set "RT_DETAILS="
set "RT_SELECTED="

call :FindPortQry
set "RT_SELECTED=!FOUND_PORTQRY!"

if defined FOUND_PORTQRY set "RT_OK=1"
if %FOUND_PORTQRY_UNIQUE_COUNT% GTR 1 (
    set "RT_OK=0"
    set "RT_DETAILS=multiple different PortQry.exe files found"
)
if not defined FOUND_PORTQRY set "RT_DETAILS=PortQry.exe not found"

set "%RT_FLAG%=%RT_OK%"
call :RT_RegisterOptionalCurrent
exit /b 0


:RT_RegisterCriticalCurrent
set /a RT_CRITICAL_TOTAL+=1
if "!RT_OK!"=="1" (
    set /a RT_CRITICAL_OK+=1
    echo [!M_RT_OK_STATUS!] !RT_LABEL!
    >>"!SELFTEST_LOG!" echo [OK] !RT_LABEL! -- !RT_SELECTED!
    >>"!SELFTEST_DEBUGLOG!" echo CRITICAL OK: !RT_LABEL!
    >>"!SELFTEST_DEBUGLOG!" echo     Selected=!RT_SELECTED!
) else (
    set /a RT_CRITICAL_MISSING+=1
    echo [!M_RT_MISSING_STATUS!] !RT_LABEL!
    if defined RT_DETAILS echo     !RT_DETAILS!
    >>"!SELFTEST_LOG!" echo [MISSING] !RT_LABEL! -- !RT_DETAILS!
    >>"!SELFTEST_DEBUGLOG!" echo CRITICAL MISSING: !RT_LABEL!
    >>"!SELFTEST_DEBUGLOG!" echo     Details=!RT_DETAILS!
)
exit /b 0

:RT_RegisterRouteCurrent
set /a RT_ROUTE_TOTAL+=1
if "!RT_OK!"=="1" (
    set /a RT_ROUTE_OK+=1
    echo [!M_RT_OK_STATUS!] !RT_LABEL!
    >>"!SELFTEST_LOG!" echo [OK] !RT_LABEL! -- !RT_SELECTED!
    >>"!SELFTEST_DEBUGLOG!" echo ROUTE OK: !RT_LABEL!
    >>"!SELFTEST_DEBUGLOG!" echo     Selected=!RT_SELECTED!
) else (
    set /a RT_ROUTE_MISSING+=1
    echo [!M_RT_MISSING_STATUS!] !RT_LABEL!
    if defined RT_DETAILS echo     !RT_DETAILS!
    >>"!SELFTEST_LOG!" echo [MISSING] !RT_LABEL! -- !RT_DETAILS!
    >>"!SELFTEST_DEBUGLOG!" echo ROUTE MISSING: !RT_LABEL!
    >>"!SELFTEST_DEBUGLOG!" echo     Details=!RT_DETAILS!
)
exit /b 0

:RT_RegisterOptionalCurrent
set /a RT_OPTIONAL_TOTAL+=1
if "!RT_OK!"=="1" (
    set /a RT_OPTIONAL_OK+=1
    echo [!M_RT_OK_STATUS!] !RT_LABEL!
    >>"!SELFTEST_LOG!" echo [OK] !RT_LABEL! -- !RT_SELECTED!
    >>"!SELFTEST_DEBUGLOG!" echo OPTIONAL OK: !RT_LABEL!
    >>"!SELFTEST_DEBUGLOG!" echo     Selected=!RT_SELECTED!
) else (
    set /a RT_OPTIONAL_MISSING+=1
    echo [!M_RT_OPTIONAL_STATUS!] !RT_LABEL!
    >>"!SELFTEST_LOG!" echo [OPTIONAL MISSING] !RT_LABEL! -- !RT_DETAILS!
    >>"!SELFTEST_DEBUGLOG!" echo OPTIONAL MISSING: !RT_LABEL!
    >>"!SELFTEST_DEBUGLOG!" echo     Details=!RT_DETAILS!
)
exit /b 0

:RT_EvaluateAllProfiles
echo.
echo ============================================================
echo %M_RT_COVERAGE%
echo ============================================================
>>"%SELFTEST_LOG%" echo.
>>"%SELFTEST_LOG%" echo SUPPORTED OS COVERAGE
>>"%SELFTEST_LOG%" echo ------------------------------------------------------------

call :RT_Profile1
call :RT_Profile2
call :RT_Profile3
call :RT_Profile4
call :RT_Profile5
call :RT_Profile6
call :RT_Profile7
call :RT_Profile8
call :RT_Profile9
call :RT_Profile10
call :RT_Profile11
exit /b 0


:RT_ProfileBegin
set /a RT_PROFILE_TOTAL+=1
set "RT_PROFILE_NAME=%~1"
set "RT_PROFILE_LOG_NAME=%~2"
set "RT_PROFILE_MISSING="
exit /b 0

:RT_ProfileNeed
call set "RT_NEED_VALUE=%%%~1%%"
if "%RT_NEED_VALUE%"=="1" exit /b 0
if defined RT_PROFILE_MISSING (
    set "RT_PROFILE_MISSING=!RT_PROFILE_MISSING!, %~2"
) else (
    set "RT_PROFILE_MISSING=%~2"
)
exit /b 0

:RT_ProfileEnd
if not defined RT_PROFILE_MISSING (
    set /a RT_PROFILE_READY+=1
    echo [%M_RT_READY_STATUS%] %RT_PROFILE_NAME%
    >>"%SELFTEST_LOG%" echo [READY] %RT_PROFILE_LOG_NAME%
    >>"%SELFTEST_DEBUGLOG%" echo PROFILE READY: %RT_PROFILE_LOG_NAME%
) else (
    set /a RT_PROFILE_NOT_READY+=1
    echo [%M_RT_NOT_READY_STATUS%] %RT_PROFILE_NAME%
    echo     %RT_PROFILE_MISSING%
    >>"%SELFTEST_LOG%" echo [NOT READY] %RT_PROFILE_LOG_NAME% -- missing: %RT_PROFILE_MISSING%
    >>"%SELFTEST_DEBUGLOG%" echo PROFILE NOT READY: %RT_PROFILE_LOG_NAME% Missing=%RT_PROFILE_MISSING%
)
exit /b 0


:RT_Profile1
call :RT_ProfileBegin "Windows XP SP2 x86/x64; Windows Server 2003 SP1/SP2/R2 SP2" "XP SP2 x86/x64 and Server 2003 SP1/SP2/R2 SP2"
call :RT_ProfileNeed C_AGENT105 "Network Agent 10.5.1781"
call :RT_ProfileNeed C_KICS "KICS 4.0.0.236"
call :RT_ProfileEnd
exit /b 0

:RT_Profile2
call :RT_ProfileBegin "Windows XP SP3 / XP Embedded SP3 x86" "XP SP3 and XP Embedded SP3 x86"
call :RT_ProfileNeed C_AGENT14 "Network Agent 14.0.0.20023"
call :RT_ProfileNeed C_KICS "KICS 4.0.0.236"
call :RT_ProfileNeed C_KB_XP2868626_X86 "KB2868626 x86"
call :RT_ProfileEnd
exit /b 0

:RT_Profile3
call :RT_ProfileBegin "Windows Server 2008 SP2 x86" "Windows Server 2008 SP2 x86"
call :RT_ProfileNeed C_AGENT15 "Network Agent 15.1.0.20748"
call :RT_ProfileNeed C_KICS "KICS 4.0.0.236"
call :RT_ProfileNeed C_KB60_4493730_X86 "KB4493730 x86"
call :RT_ProfileNeed C_KB60_4474419_X86 "KB4474419 x86"
call :RT_ProfileNeed C_KB60_3063858_X86 "KB3063858 x86"
call :RT_ProfileEnd
exit /b 0

:RT_Profile4
call :RT_ProfileBegin "Windows Server 2008 SP2 x64" "Windows Server 2008 SP2 x64"
call :RT_ProfileNeed C_AGENT15 "Network Agent 15.1.0.20748"
call :RT_ProfileNeed C_KICS "KICS 4.0.0.236"
call :RT_ProfileNeed C_KB60_4493730_X64 "KB4493730 x64"
call :RT_ProfileNeed C_KB60_4474419_X64 "KB4474419 x64"
call :RT_ProfileNeed C_KB60_3063858_X64 "KB3063858 x64"
call :RT_ProfileEnd
exit /b 0

:RT_Profile5
call :RT_ProfileBegin "Windows 7 SP1 / Embedded 7 SP1 x86" "Windows 7 SP1 and Embedded 7 SP1 x86"
call :RT_ProfileNeed C_AGENT15 "Network Agent 15.1.0.20748"
call :RT_ProfileNeed C_KICS "KICS 4.0.0.236"
call :RT_ProfileNeed C_KB61_4490628_X86 "KB4490628 x86"
call :RT_ProfileNeed C_KB61_4474419_X86 "KB4474419 x86"
call :RT_ProfileNeed C_KB61_3063858_X86 "KB3063858 x86"
call :RT_ProfileEnd
exit /b 0

:RT_Profile6
call :RT_ProfileBegin "Windows 7 SP1 / Server 2008 R2 SP1 / Embedded 7 SP1 x64" "Windows 7 SP1, Server 2008 R2 SP1 and Embedded 7 SP1 x64"
call :RT_ProfileNeed C_AGENT15 "Network Agent 15.1.0.20748"
call :RT_ProfileNeed C_KICS "KICS 4.0.0.236"
call :RT_ProfileNeed C_KB61_4490628_X64 "KB4490628 x64"
call :RT_ProfileNeed C_KB61_4474419_X64 "KB4474419 x64"
call :RT_ProfileNeed C_KB61_3063858_X64 "KB3063858 x64"
call :RT_ProfileEnd
exit /b 0

:RT_Profile7
call :RT_ProfileBegin "Windows 8 / 8.1 / Embedded 8 / 8.1 x86/x64" "Windows 8, 8.1 and Embedded 8/8.1 x86/x64"
call :RT_ProfileNeed C_AGENT15 "Network Agent 15.1.0.20748"
call :RT_ProfileNeed C_KICS "KICS 4.0.0.236"
call :RT_ProfileEnd
exit /b 0

:RT_Profile8
call :RT_ProfileBegin "Windows 10 / Windows 10 IoT supported versions x86/x64" "Windows 10 and Windows 10 IoT supported versions x86/x64"
call :RT_ProfileNeed C_AGENT15 "Network Agent 15.1.0.20748"
call :RT_ProfileNeed C_KICS "KICS 4.0.0.236"
call :RT_ProfileEnd
exit /b 0

:RT_Profile9
call :RT_ProfileBegin "Windows 11 / Windows 11 IoT 21H2-23H2 x64 with KICS" "Windows 11 and Windows 11 IoT 21H2-23H2 x64 with KICS"
call :RT_ProfileNeed C_AGENT15 "Network Agent 15.1.0.20748"
call :RT_ProfileNeed C_KICS "KICS 4.0.0.236"
call :RT_ProfileEnd
exit /b 0

:RT_Profile10
call :RT_ProfileBegin "Windows 11 24H2 x64 - Network Agent only" "Windows 11 24H2 x64 Agent only"
call :RT_ProfileNeed C_AGENT15 "Network Agent 15.1.0.20748"
call :RT_ProfileEnd
exit /b 0

:RT_Profile11
call :RT_ProfileBegin "Windows Server 2012 / 2012 R2 / 2016 / 2019 / 2022 x64" "Windows Server 2012-2022 x64"
call :RT_ProfileNeed C_AGENT15 "Network Agent 15.1.0.20748"
call :RT_ProfileNeed C_KICS "KICS 4.0.0.236"
call :RT_ProfileEnd
exit /b 0


:RT_ShowSummary
echo.
echo ============================================================
echo %M_RT_SUMMARY%
echo ============================================================
echo %M_RT_CRITICAL%: %RT_CRITICAL_OK% / %RT_CRITICAL_TOTAL%
echo %M_RT_CRITICAL_MISSING%: %RT_CRITICAL_MISSING%
echo %M_RT_ROUTES%: %RT_ROUTE_OK% / %RT_ROUTE_TOTAL%
echo %M_RT_ROUTE_MISSING%: %RT_ROUTE_MISSING%
echo %M_RT_COVERAGE%: %RT_PROFILE_READY% / %RT_PROFILE_TOTAL%
echo %M_RT_PROFILE_NOT_READY%: %RT_PROFILE_NOT_READY%
echo %M_RT_OPTIONAL%: %RT_OPTIONAL_OK% / %RT_OPTIONAL_TOTAL%

>>"%SELFTEST_LOG%" echo.
>>"%SELFTEST_LOG%" echo SUMMARY
>>"%SELFTEST_LOG%" echo Critical components: %RT_CRITICAL_OK%/%RT_CRITICAL_TOTAL%
>>"%SELFTEST_LOG%" echo Critical missing: %RT_CRITICAL_MISSING%
>>"%SELFTEST_LOG%" echo Standard KSC packages: %RT_ROUTE_OK%/%RT_ROUTE_TOTAL%
>>"%SELFTEST_LOG%" echo Standard KSC packages missing: %RT_ROUTE_MISSING%
>>"%SELFTEST_LOG%" echo Supported OS groups ready: %RT_PROFILE_READY%/%RT_PROFILE_TOTAL%
>>"%SELFTEST_LOG%" echo Supported OS groups not ready: %RT_PROFILE_NOT_READY%
>>"%SELFTEST_LOG%" echo Optional diagnostics: %RT_OPTIONAL_OK%/%RT_OPTIONAL_TOTAL%
>>"%SELFTEST_LOG%" echo Detailed log: %SELFTEST_DEBUGLOG%

if "%RT_CRITICAL_MISSING%"=="0" if "%RT_ROUTE_MISSING%"=="0" if "%RT_PROFILE_NOT_READY%"=="0" goto :RT_SummaryReady

echo.
echo ============================================================
echo %M_RT_NOT_READY%
echo ============================================================
echo %M_RT_FIX_MISSING%
>>"%SELFTEST_LOG%" echo RESULT: NOT READY
goto :RT_SummaryDone

:RT_SummaryReady
echo.
echo ============================================================
echo %M_RT_READY%
echo ============================================================
>>"%SELFTEST_LOG%" echo RESULT: READY

:RT_SummaryDone
echo %M_ST_REPORT%: %SELFTEST_LOG%
echo %M_ST_DEBUG_REPORT%: %SELFTEST_DEBUGLOG%
echo %M_ST_NO_CHANGES%
exit /b 0


:RT_AssetsOnly
cls
echo ============================================================
echo %M_RT_ASSETS%
echo ============================================================
echo Root: %ROOT%
echo.
>>"%SELFTEST_LOG%" echo.
>>"%SELFTEST_LOG%" echo FULL DISCOVERED ASSET LIST
>>"%SELFTEST_LOG%" echo ------------------------------------------------------------
>>"%SELFTEST_DEBUGLOG%" echo.
>>"%SELFTEST_DEBUGLOG%" echo ASSET INVENTORY STARTED

set "RT_ASSET_COUNT=0"
for /f "delims=" %%F in ('dir /b /s /a-d "%ROOT%*" 2^>nul') do (
    set "RT_ASSET=%%F"
    set "RT_ASSET_EXT=%%~xF"
    set "RT_ASSET_ALLOWED=0"
    for %%E in (.exe .msi .msu .kud .7z .zip .reg .txt .doc .docx .pdf .inf .bat .cmd) do (
        if /I "!RT_ASSET_EXT!"=="%%E" set "RT_ASSET_ALLOWED=1"
    )
    if "!RT_ASSET_ALLOWED!"=="1" (
        set "RT_ASSET_NOT_LOG=!RT_ASSET:\Logs\=!"
        if /I "!RT_ASSET_NOT_LOG!"=="!RT_ASSET!" (
            set /a RT_ASSET_COUNT+=1
            echo [!RT_ASSET_COUNT!] %%F
            >>"!SELFTEST_LOG!" echo [!RT_ASSET_COUNT!] %%F
            >>"!SELFTEST_DEBUGLOG!" echo ASSET [!RT_ASSET_COUNT!] %%F
        )
    )
)
echo.
echo Assets discovered: !RT_ASSET_COUNT!
echo %M_ST_REPORT%: %SELFTEST_LOG%
>>"%SELFTEST_DEBUGLOG%" echo ASSET INVENTORY FINISHED. Count=!RT_ASSET_COUNT!
goto :RT_Close

:LT_Menu
cls
echo ============================================================
echo %M_LT_TITLE%
echo ============================================================
echo %M_LT_WARNING1%
echo %M_LT_WARNING2%
echo %M_LT_WARNING3%
echo %M_LT_WARNING4%
echo.
echo Unpacked interactive installers:
echo [1] %M_LT_AGENT105%
echo [2] %M_LT_AGENT14%
echo [3] %M_LT_AGENT15%
echo [4] %M_LT_KICS%
echo.
echo Autonomous KSC packages - higher risk:
echo [5] %M_LT_AUTO_KICS_ROZLIV%
echo [6] %M_LT_AUTO_KICS_BREWING%
echo [7] %M_LT_AUTO_AGENT_ROZLIV%
echo [8] %M_LT_AUTO_AGENT_BREWING%
echo [0] %M_EXIT%
echo.
set "ANSWER="
set /p "ANSWER=%M_ENTER_CHOICE% [0-8]: "
if "%ANSWER%"=="1" goto :LT_SelectAgent105
if "%ANSWER%"=="2" goto :LT_SelectAgent14
if "%ANSWER%"=="3" goto :LT_SelectAgent15
if "%ANSWER%"=="4" goto :LT_SelectKics
if "%ANSWER%"=="5" goto :LT_SelectAutoKicsRozliv
if "%ANSWER%"=="6" goto :LT_SelectAutoKicsBrewing
if "%ANSWER%"=="7" goto :LT_SelectAutoAgentRozliv
if "%ANSWER%"=="8" goto :LT_SelectAutoAgentBrewing
if "%ANSWER%"=="0" goto :SelfTestMenu
echo %M_INVALID%
goto :LT_Menu


:LT_SelectAgent105
set "LT_LABEL=%M_LT_AGENT105%"
set "LT_RISK=0"
call :FindAgentSetupByVersion "10.5.1781"
if not "%FOUND_AGENT_UNIQUE_COUNT%"=="1" goto :LT_NotFound
set "LT_FILE=!FOUND_AGENT_SETUP!"
goto :LT_Review


:LT_SelectAgent14
set "LT_LABEL=%M_LT_AGENT14%"
set "LT_RISK=0"
call :FindAgentSetupByVersion "14.0.0.20023"
if not "%FOUND_AGENT_UNIQUE_COUNT%"=="1" goto :LT_NotFound
set "LT_FILE=!FOUND_AGENT_SETUP!"
goto :LT_Review


:LT_SelectAgent15
set "LT_LABEL=%M_LT_AGENT15%"
set "LT_RISK=0"
call :FindAgentSetupByVersion "15.1.0.20748"
if not "%FOUND_AGENT_UNIQUE_COUNT%"=="1" goto :LT_NotFound
set "LT_FILE=!FOUND_AGENT_SETUP!"
goto :LT_Review


:LT_SelectKics
set "LT_LABEL=%M_LT_KICS%"
set "LT_RISK=0"
call :FindKicsSetup
if not "%FOUND_KICS_UNIQUE_COUNT%"=="1" goto :LT_NotFound
set "LT_FILE=!FOUND_KICS_SETUP!"
goto :LT_Review


:LT_SelectAutoKicsRozliv
set "LT_LABEL=%M_LT_AUTO_KICS_ROZLIV%"
set "LT_RISK=1"
call :FindAutonomousPackage "KICS" "10.255.40.207"
if not "%FOUND_PACKAGE_UNIQUE_COUNT%"=="1" goto :LT_NotFound
set "LT_FILE=!FOUND_PACKAGE!"
goto :LT_Review


:LT_SelectAutoKicsBrewing
set "LT_LABEL=%M_LT_AUTO_KICS_BREWING%"
set "LT_RISK=1"
call :FindAutonomousPackage "KICS" "172.16.66.105"
if not "%FOUND_PACKAGE_UNIQUE_COUNT%"=="1" goto :LT_NotFound
set "LT_FILE=!FOUND_PACKAGE!"
goto :LT_Review


:LT_SelectAutoAgentRozliv
set "LT_LABEL=%M_LT_AUTO_AGENT_ROZLIV%"
set "LT_RISK=1"
call :FindAutonomousPackage "AGENT" "10.255.40.207"
if not "%FOUND_PACKAGE_UNIQUE_COUNT%"=="1" goto :LT_NotFound
set "LT_FILE=!FOUND_PACKAGE!"
goto :LT_Review


:LT_SelectAutoAgentBrewing
set "LT_LABEL=%M_LT_AUTO_AGENT_BREWING%"
set "LT_RISK=1"
call :FindAutonomousPackage "AGENT" "172.16.66.105"
if not "%FOUND_PACKAGE_UNIQUE_COUNT%"=="1" goto :LT_NotFound
set "LT_FILE=!FOUND_PACKAGE!"
goto :LT_Review


:LT_NotFound
echo.
echo ============================================================
echo %M_LT_NOT_FOUND%
echo ============================================================
echo %LT_LABEL%
echo.
>>"%LAUNCHTEST_LOG%" echo [%DATE% %TIME%] NOT FOUND OR AMBIGUOUS: %LT_LABEL%
goto :LT_AfterTest


:LT_Review
cls
echo ============================================================
echo %M_LT_TITLE%
echo ============================================================
echo %M_LT_WARNING1%
echo %M_LT_WARNING2%
echo %M_LT_WARNING3%
echo.
echo %M_LT_FILE%:
echo !LT_FILE!
echo.
set "ANSWER="
set /p "ANSWER=%M_LT_LAUNCH_Q% "
if /I "%ANSWER%"=="Y" goto :LT_PreStart
if /I "%ANSWER%"=="YES" goto :LT_PreStart
if /I "%ANSWER%"=="Д" goto :LT_PreStart
if /I "%ANSWER%"=="ДА" goto :LT_PreStart
if /I "%ANSWER%"=="N" goto :LT_Cancelled
if /I "%ANSWER%"=="NO" goto :LT_Cancelled
if /I "%ANSWER%"=="Н" goto :LT_Cancelled
if /I "%ANSWER%"=="НЕТ" goto :LT_Cancelled
echo %M_INVALID%
goto :LT_Review


:LT_PreStart
if not "!LT_RISK!"=="1" goto :LT_Start
echo.
echo ============================================================
echo %M_LT_DANGER%
echo ============================================================
echo !LT_FILE!
echo.
set "ANSWER="
set /p "ANSWER=%M_LT_DANGER_Q%: "
if /I "!ANSWER!"=="RUN" goto :LT_Start
>>"%LAUNCHTEST_LOG%" echo [%DATE% %TIME%] AUTONOMOUS PACKAGE CANCELLED BEFORE LAUNCH: !LT_LABEL!
goto :LT_AfterTest


:LT_Start
for %%D in ("!LT_FILE!") do (
    set "LT_WORKDIR=%%~dpD"
    set "LT_FILENAME=%%~nxD"
)

>>"%LAUNCHTEST_LOG%" echo.
>>"%LAUNCHTEST_LOG%" echo [%DATE% %TIME%] START REQUESTED: !LT_LABEL!
>>"%LAUNCHTEST_LOG%" echo     File=!LT_FILE!
>>"%LAUNCHTEST_LOG%" echo     Working directory=!LT_WORKDIR!
>>"%LAUNCHTEST_LOG%" echo     Current computer=%COMPUTERNAME%

if not exist "!LT_FILE!" (
    echo.
    echo %M_LT_NOT_FOUND%
    >>"%LAUNCHTEST_LOG%" echo     Result=FILE DISAPPEARED BEFORE LAUNCH
    goto :LT_AfterTest
)

pushd "!LT_WORKDIR!" >nul 2>&1
if errorlevel 1 (
    echo.
    echo Unable to enter installer working directory:
    echo !LT_WORKDIR!
    >>"%LAUNCHTEST_LOG%" echo     Result=WORKING DIRECTORY ERROR
    goto :LT_AfterTest
)

rem Do not use START /WAIT here. Many setup bootstrapper processes create a
rem child process and exit immediately. The visual result is confirmed by user.
start "" "!LT_FILENAME!"
set "LT_RETURN_CODE=!ERRORLEVEL!"
popd >nul 2>&1

rem Give Windows, UAC and the installer bootstrapper time to show a window.
ping 127.0.0.1 -n 4 >nul 2>&1

echo.
echo Launch command return code: !LT_RETURN_CODE!
>>"%LAUNCHTEST_LOG%" echo     START command return code=!LT_RETURN_CODE!
goto :LT_AskResult


:LT_AskResult
echo.
set "ANSWER="
set /p "ANSWER=%M_LT_RESULT_Q% "
if "%ANSWER%"=="1" goto :LT_ResultStarted
if "%ANSWER%"=="2" goto :LT_ResultCompatibility
if "%ANSWER%"=="3" goto :LT_ResultFailed
if "%ANSWER%"=="4" goto :LT_ResultUncertain
echo %M_INVALID%
goto :LT_AskResult


:LT_ResultStarted
echo [%M_LT_STARTED%] %LT_LABEL%
>>"%LAUNCHTEST_LOG%" echo     Result=INSTALLER WINDOW OPENED
goto :LT_AfterTest


:LT_ResultCompatibility
echo [%M_LT_COMPAT%] %LT_LABEL%
>>"%LAUNCHTEST_LOG%" echo     Result=EXECUTABLE STARTED; COMPATIBILITY OR ERROR MESSAGE SHOWN
goto :LT_AfterTest


:LT_ResultFailed
echo [%M_LT_FAILED%] %LT_LABEL%
>>"%LAUNCHTEST_LOG%" echo     Result=NO VISIBLE REACTION
goto :LT_AfterTest


:LT_ResultUncertain
echo [%M_LT_UNCERTAIN%] %LT_LABEL%
>>"%LAUNCHTEST_LOG%" echo     Result=INCONCLUSIVE
goto :LT_AfterTest


:LT_Cancelled
>>"%LAUNCHTEST_LOG%" echo [%DATE% %TIME%] CANCELLED BEFORE LAUNCH: %LT_LABEL%
goto :LT_AfterTest


:LT_AfterTest
echo.
echo %M_LT_LOG%:
echo %LAUNCHTEST_LOG%
echo.
echo [1] %M_LT_TITLE%
echo [0] %M_RT_TITLE%
set "ANSWER="
set /p "ANSWER=%M_ENTER_CHOICE% [0/1]: "
if "%ANSWER%"=="1" goto :LT_Menu
goto :SelfTestMenu


:RT_Close
echo.
echo [1] %M_RT_TITLE%
echo [0] %M_EXIT%
set "ANSWER="
set /p "ANSWER=%M_ENTER_CHOICE% [0/1]: "
if "%ANSWER%"=="1" goto :SelfTestMenu
goto :CloseWizard

rem =====================================================================
rem LANGUAGE
rem =====================================================================

:SelectLanguage
cls
echo ============================================================
echo BALTIKA OT - KASPERSKY INSTALLATION WIZARD
echo ============================================================
echo.
echo Select interface language.
echo Press ENTER to use English.
echo.
echo [1] English  - default; use this on systems without Russian locale
echo [2] Russian  - Russian prompts and explanations
echo.
set "LANG_CHOICE="
set /p "LANG_CHOICE=Language [1/2, ENTER=1]: "
if "%LANG_CHOICE%"=="2" (
    set "LANG=RU"
    chcp 1251 >nul 2>&1
) else (
    set "LANG=EN"
)
exit /b 0

:SetMessages
if /I "%LANG%"=="RU" goto :SetMessagesRU

set "M_HEADER=BALTIKA OT - KASPERSKY INSTALLATION WIZARD"
set "M_ROOT=Source folder"
set "M_ADMIN_ERROR=ERROR: Run this BAT file as Administrator."
set "M_DETECT_ERROR=ERROR: Windows version could not be detected."
set "M_DETECTED=DETECTED OPERATING SYSTEM"
set "M_COMPUTER=Computer"
set "M_OS=Operating system"
set "M_VERSION=Version"
set "M_BUILD=Build"
set "M_SP=Service Pack"
set "M_DISPLAY=DisplayVersion"
set "M_EDITION=Edition"
set "M_ARCH=Architecture"
set "M_TARGET_TITLE=WHAT MUST BE INSTALLED"
set "M_TARGET_HINT1=Choose [1] only for a production workstation or server."
set "M_TARGET_HINT2=Examples: SCADA, HMI, WinCC, STEP 7, OPC, MES client or equipment software."
set "M_TARGET_HINT3=Choose [2] for a Windows virtualization host, service server or PC without production software."
set "M_TARGET_1=Network Agent and KICS for Nodes"
set "M_TARGET_2=Network Agent only"
set "M_EXIT=Exit"
set "M_ENTER_CHOICE=Select option"
set "M_INVALID=Invalid choice. Try again."
set "M_KSC_TITLE=SELECT KSC SERVER"
set "M_KSC_HINT1=Choose the server by the production area, not only by the local IP address."
set "M_KSC_HINT2=Use manual entry only when Information Security has provided another KSC address."
set "M_KSC_1=Filling / Rozliv"
set "M_KSC_2=Brewing / Pivoproizvodstvo"
set "M_KSC_3=Enter KSC address manually"
set "M_ENTER_KSC=Enter KSC IP address or DNS name"
set "M_MANUAL_KSC_NO_PACKAGE=No autonomous package is bound to this manually entered KSC. Separate installers will be used."
set "M_MANUAL_KSC_HINT=During Network Agent setup, enter the KSC address shown in the installation plan."
set "M_CONNECT_TITLE=CHECK CONNECTION TO KSC"
set "M_ICMP_OK=ICMP: reply received."
set "M_ICMP_FAIL=ICMP: no reply. This does not always mean that TCP is unavailable."
set "M_TCP_OK=TCP/13000: available."
set "M_TCP_FAIL=TCP/13000 could not be confirmed automatically."
set "M_PORTQRY_HINT=For a manual check, place PortQry.exe in the Tools folder and choose option 4."
set "M_MANUAL_PORT_HINT=Continue only if TCP/13000 was checked manually with PortQry or Telnet and is open."
set "M_MANUAL_PORT_Q=Was TCP/13000 checked manually and found open? [Y/N]"
set "M_PORT_STOP=Installation stopped: TCP/13000 is unavailable or was not verified."
set "M_CONN_FAIL_TITLE=KSC CONNECTION CHECK FAILED"
set "M_CONN_FAIL_HINT1=The wizard will remain open. Select the next action."
set "M_CONN_FAIL_HINT2=Do not continue unless TCP/13000 was checked manually and is open."
set "M_DEBUG_HINT=Diagnostic log:"
set "M_CONN_FAIL_1=Retry the connection check"
set "M_CONN_FAIL_2=Select another KSC server"
set "M_CONN_FAIL_3=Continue after successful manual TCP/13000 verification"
set "M_CONN_FAIL_4=Open PortQry in a separate window"
set "M_CONN_FAIL_0=Stop installation and keep the window open"
set "M_CONN_CONFIRM=Confirm that TCP/13000 was manually verified as open [Y/N]"
set "M_PORTQRY_MANUAL_HINT=Close the separate PortQry window after reviewing the result, then return here."
set "M_PORTQRY_MISSING=PortQry.exe was not found. Expected location:"
set "M_PLAN_TITLE=INSTALLATION PLAN"
set "M_TARGET=Target"
set "M_ZONE=Area"
set "M_KSC=KSC server"
set "M_METHOD=Method"
set "M_AGENT=Network Agent"
set "M_REQUIRED_KB=Required updates"
set "M_PACKAGE=Package"
set "M_KICS=KICS installer"
set "M_PLAN_SAVED=Plan saved to:"
set "M_ACTION_HINT1=Choose [1] to install now using the selected approved files."
set "M_ACTION_HINT2=Choose [2] to save the plan without changing the computer."
set "M_ACTION_1=Run installation"
set "M_ACTION_2=Save plan only"
set "M_AV_HINT1=Select YES only if another antivirus is absent or was removed and the PC was rebooted."
set "M_AV_HINT2=Do not install two antivirus products at the same time."
set "M_AV_Q=Is another antivirus absent or already removed? [Y/N]"
set "M_AV_STOP=Remove the conflicting antivirus, reboot the computer and run the wizard again."
set "M_KB_TITLE=REQUIRED WINDOWS UPDATES"
set "M_KB_INSTALLED=already installed"
set "M_KB_NOT_FOUND=ERROR: required update file was not found"
set "M_KB_FOLDER=Check the KB folder and file architecture."
set "M_KB_HINT1=The update is required for Network Agent/KICS signature and TLS compatibility."
set "M_KB_HINT2=The wizard never installs an update silently. It launches the Microsoft package only after your confirmation."
set "M_KB_Q=The required update is missing. Launch its interactive installer now? [Y/N]"
set "M_KB_VERIFY_FAIL=WARNING: the update was not detected after the installer closed."
set "M_KB_VERIFY_HINT=Check the Windows Update Standalone Installer result and error code."
set "M_REBOOT_REQUIRED=Updates were installed. Restart Windows before installing Kaspersky."
set "M_INSTALL_TITLE=START INSTALLATION"
set "M_AUTO_HINT=The autonomous package installs the Network Agent and, when selected, KICS."
set "M_AUTO_SUCCESS_Q=Did the installer finish with a successful installation message? [Y/N]"
set "M_AGENT_STEP=STEP 1. Install Network Agent"
set "M_AGENT_HINT1=Use the KSC address and ports shown below."
set "M_AGENT_HINT2=Do not enable proxy, connection gateway or agent tags unless Information Security instructed otherwise."
set "M_AGENT_SUCCESS_Q=Was Network Agent installed successfully? [Y/N]"
set "M_KICS_STEP=STEP 2. Install KICS for Nodes 4.0.0.236"
set "M_KICS_HINT1=Install only the components listed below."
set "M_KICS_HINT2=Do not install Network Threat Protection / Protection from network devices."
set "M_KICS_HINT3=Select Report only mode and the Microsoft/Kaspersky recommended exclusions."
set "M_KICS_SUCCESS_Q=Was KICS installed successfully? [Y/N]"
set "M_POST_TITLE=POST-INSTALLATION CHECK"
set "M_AGENT_SERVICE_OK=Network Agent service was found."
set "M_AGENT_SERVICE_FAIL=Network Agent service was not found."
set "M_KLN_START=Starting Network Agent connection check:"
set "M_KLN_NOT_FOUND=klnagchk.exe was not found automatically."
set "M_POST_HINT=Confirm the following items manually:"
set "M_POST_1=The computer is visible in KSC."
set "M_POST_2=License and policy are assigned."
set "M_POST_3=KICS is running without critical errors."
set "M_POST_4=SCADA/HMI/OPC/MES and PLC communication work normally."
set "M_POST_5=USB/COM/LPT devices and hardware license keys work normally."
set "M_INSTALL_DONE=INSTALLATION WORKFLOW COMPLETED"
set "M_INSTALL_STOPPED=INSTALLATION STOPPED"
set "M_SAFE_STOP_TITLE=CHECK COMPLETED - INSTALLATION NOT STARTED"
set "M_SAFE_STOP_TEXT=The selected package is not compatible with this computer. No Kaspersky installer was started."
set "M_PLAN_ONLY_TEXT=The installation plan was saved. No software was installed."
set "M_OPERATION_FAILED=The wizard ended with an error. Review the message above and the diagnostic log."
set "M_CLOSE_WINDOW=Press any key to close this window..."
set "M_REBOOT_TITLE=RESTART REQUIRED"
set "M_REBOOT_HINT=After Windows starts, run this BAT file again. It will recheck updates and continue."
set "M_REBOOT_Q=Restart the computer now? [Y/N]"
set "M_PRESS_ENTER=Press ENTER to continue..."
set "M_ONLY_AGENT=Network Agent only"
set "M_AGENT_KICS=Network Agent and KICS"
set "M_SEPARATE=Separate installers"
set "M_AUTONOMOUS=Autonomous package"
set "M_MODE_TITLE=SELECT WIZARD MODE"
set "M_MODE_HINT1=Normal mode checks the real computer and may launch approved installers."
set "M_MODE_HINT2=Readiness audit checks whether the kit can install on every supported OS group. It does not run installers, updates or network tests."
set "M_MODE_NORMAL=Normal installation mode"
set "M_MODE_SELFTEST=Kit readiness audit / dry run"
set "M_ST_REPORT=Readiness report"
set "M_ST_DEBUG_REPORT=Detailed readiness log"
set "M_ST_NO_CHANGES=Audit completed. No software was installed and no network connection was attempted."
set "M_RT_TITLE=KIT READINESS AUDIT"
set "M_RT_WARNING=Only supported OS groups are checked. No software is installed and no network request is made."
set "M_RT_FULL=Check readiness for every supported OS group"
set "M_RT_ONE_PROFILE=Check one supported OS group"
set "M_RT_ASSETS=List all files discovered in the kit"
set "M_RT_SELECT_PROFILE=SELECT SUPPORTED OS GROUP"
set "M_RT_CRITICAL=CRITICAL INSTALLATION COMPONENTS"
set "M_RT_ROUTES=STANDARD KSC AUTONOMOUS PACKAGES"
set "M_RT_OPTIONAL=OPTIONAL DIAGNOSTIC COMPONENTS"
set "M_RT_COVERAGE=SUPPORTED OS COVERAGE"
set "M_RT_SUMMARY=KIT READINESS SUMMARY"
set "M_RT_READY=READY: THE KIT COVERS ALL SUPPORTED OS GROUPS"
set "M_RT_NOT_READY=NOT READY: REQUIRED COMPONENTS ARE MISSING"
set "M_RT_FIX_MISSING=Add the components marked MISSING and run the audit again."
set "M_RT_CRITICAL_MISSING=Critical components missing"
set "M_RT_ROUTE_MISSING=Standard KSC packages missing"
set "M_RT_PROFILE_NOT_READY=Supported OS groups not ready"
set "M_RT_OK_STATUS=OK"
set "M_RT_MISSING_STATUS=MISSING"
set "M_RT_OPTIONAL_STATUS=OPTIONAL MISSING"
set "M_RT_READY_STATUS=READY"
set "M_RT_NOT_READY_STATUS=NOT READY"
set "M_LT_MENU_ITEM=Interactively test installer startup on this computer"
set "M_LT_TITLE=INSTALLER STARTUP SMOKE TEST"
set "M_LT_WARNING1=This test starts a real installer executable on the CURRENT operating system."
set "M_LT_WARNING2=It does not prove compatibility with Windows XP, Server 2008 or any other target OS."
set "M_LT_WARNING3=Do not continue installation. Close or cancel the installer at the first screen or compatibility message."
set "M_LT_WARNING4=Windows update packages and autonomous KSC packages are deliberately not started by this test."
set "M_LT_AGENT105=Network Agent 10.5.1781 setup.exe"
set "M_LT_AGENT14=Network Agent 14.0.0.20023 setup.exe"
set "M_LT_AGENT15=Network Agent 15.1.0.20748 setup.exe"
set "M_LT_KICS=KICS for Nodes 4.0.0.236 setupui.exe"
set "M_LT_AUTO_KICS_ROZLIV=Autonomous Agent + KICS package for KSC 10.255.40.207"
set "M_LT_AUTO_KICS_BREWING=Autonomous Agent + KICS package for KSC 172.16.66.105"
set "M_LT_AUTO_AGENT_ROZLIV=Autonomous Agent-only package for KSC 10.255.40.207"
set "M_LT_AUTO_AGENT_BREWING=Autonomous Agent-only package for KSC 172.16.66.105"
set "M_LT_DANGER=WARNING: an autonomous package can start a real unattended or semi-unattended installation immediately."
set "M_LT_DANGER_Q=Type RUN to confirm that you are ready to cancel the installer immediately"
set "M_LT_FILE=Executable"
set "M_LT_LAUNCH_Q=Launch this executable now? [Y/N]"
set "M_LT_RESULT_Q=What happened? [1=installer window opened, 2=compatibility/error message opened, 3=no visible reaction, 4=uncertain]"
set "M_LT_STARTED=INSTALLER WINDOW OPENED"
set "M_LT_COMPAT=EXECUTABLE STARTED - COMPATIBILITY OR ERROR MESSAGE SHOWN"
set "M_LT_FAILED=NO VISIBLE REACTION"
set "M_LT_UNCERTAIN=INCONCLUSIVE"
set "M_LT_NOT_FOUND=Executable was not found or the distribution is ambiguous."
set "M_LT_RETURNED=The executable closed. Process return code"
set "M_LT_LOG=Launch-test log"
exit /b 0

:SetMessagesRU
set "M_HEADER=БАЛТИКА ОТ - МАСТЕР УСТАНОВКИ KASPERSKY"
set "M_ROOT=Папка с установочными файлами"
set "M_ADMIN_ERROR=ОШИБКА: запустите BAT-файл от имени администратора."
set "M_DETECT_ERROR=ОШИБКА: не удалось определить версию Windows."
set "M_DETECTED=ОБНАРУЖЕННАЯ ОПЕРАЦИОННАЯ СИСТЕМА"
set "M_COMPUTER=Компьютер"
set "M_OS=Операционная система"
set "M_VERSION=Версия"
set "M_BUILD=Сборка"
set "M_SP=Service Pack"
set "M_DISPLAY=DisplayVersion"
set "M_EDITION=Редакция"
set "M_ARCH=Разрядность"
set "M_TARGET_TITLE=ЧТО НУЖНО УСТАНОВИТЬ"
set "M_TARGET_HINT1=Выбирайте [1] только для производственного АРМ или сервера."
set "M_TARGET_HINT2=Примеры: SCADA, HMI, WinCC, STEP 7, OPC, MES-клиент или ПО оборудования."
set "M_TARGET_HINT3=Выбирайте [2] для Windows-хоста виртуализации, служебного сервера или ПК без производственного ПО."
set "M_TARGET_1=Network Agent и KICS for Nodes"
set "M_TARGET_2=Только Network Agent"
set "M_EXIT=Выход"
set "M_ENTER_CHOICE=Выберите вариант"
set "M_INVALID=Некорректный выбор. Повторите ввод."
set "M_KSC_TITLE=ВЫБОР СЕРВЕРА KSC"
set "M_KSC_HINT1=Выбирайте сервер по производственному участку, а не только по IP-адресу компьютера."
set "M_KSC_HINT2=Ручной ввод используйте только если служба ИБ выдала другой адрес KSC."
set "M_KSC_1=Розлив"
set "M_KSC_2=Пивопроизводство"
set "M_KSC_3=Ввести адрес KSC вручную"
set "M_ENTER_KSC=Введите IP-адрес или DNS-имя KSC"
set "M_MANUAL_KSC_NO_PACKAGE=Для введенного вручную KSC автономный пакет не найден. Будут использованы раздельные установщики."
set "M_MANUAL_KSC_HINT=В мастере Network Agent укажите адрес KSC, показанный в плане установки."
set "M_CONNECT_TITLE=ПРОВЕРКА СВЯЗИ С KSC"
set "M_ICMP_OK=ICMP: ответ получен."
set "M_ICMP_FAIL=ICMP: ответа нет. Это не всегда означает отсутствие TCP-связи."
set "M_TCP_OK=TCP/13000: доступен."
set "M_TCP_FAIL=TCP/13000 автоматически не подтвержден."
set "M_PORTQRY_HINT=Для ручной проверки положите PortQry.exe в папку Tools и выберите пункт 4."
set "M_MANUAL_PORT_HINT=Продолжайте только если TCP/13000 проверен вручную через PortQry или Telnet и открыт."
set "M_MANUAL_PORT_Q=TCP/13000 проверен вручную и доступен? [Y/N]"
set "M_PORT_STOP=Установка остановлена: TCP/13000 недоступен или не проверен."
set "M_CONN_FAIL_TITLE=НЕ УДАЛОСЬ ПРОВЕРИТЬ СВЯЗЬ С KSC"
set "M_CONN_FAIL_HINT1=Мастер не будет закрыт автоматически. Выберите дальнейшее действие."
set "M_CONN_FAIL_HINT2=Не продолжайте, пока TCP/13000 не проверен вручную и не подтвержден как открытый."
set "M_DEBUG_HINT=Диагностический журнал:"
set "M_CONN_FAIL_1=Повторить проверку связи"
set "M_CONN_FAIL_2=Выбрать другой сервер KSC"
set "M_CONN_FAIL_3=Продолжить после успешной ручной проверки TCP/13000"
set "M_CONN_FAIL_4=Открыть PortQry в отдельном окне"
set "M_CONN_FAIL_0=Остановить установку и оставить окно открытым"
set "M_CONN_CONFIRM=Подтвердите, что TCP/13000 проверен вручную и открыт [Y/N]"
set "M_PORTQRY_MANUAL_HINT=После просмотра результата закройте отдельное окно PortQry и вернитесь в мастер."
set "M_PORTQRY_MISSING=PortQry.exe не найден. Ожидаемый путь:"
set "M_PLAN_TITLE=ПЛАН УСТАНОВКИ"
set "M_TARGET=Что устанавливаем"
set "M_ZONE=Участок"
set "M_KSC=Сервер KSC"
set "M_METHOD=Способ"
set "M_AGENT=Network Agent"
set "M_REQUIRED_KB=Обязательные обновления"
set "M_PACKAGE=Пакет"
set "M_KICS=Установщик KICS"
set "M_PLAN_SAVED=План сохранен:"
set "M_ACTION_HINT1=Выбирайте [1], чтобы установить ПО сейчас из выбранных утвержденных файлов."
set "M_ACTION_HINT2=Выбирайте [2], чтобы только сохранить план без изменения компьютера."
set "M_ACTION_1=Выполнить установку"
set "M_ACTION_2=Только сохранить план"
set "M_AV_HINT1=Выбирайте ДА только если другой антивирус отсутствует либо удален и компьютер перезагружен."
set "M_AV_HINT2=Не устанавливайте одновременно два антивирусных продукта."
set "M_AV_Q=Другой антивирус отсутствует или уже удален? [Y/N]"
set "M_AV_STOP=Удалите конфликтующий антивирус, перезагрузите компьютер и повторно запустите мастер."
set "M_KB_TITLE=ОБЯЗАТЕЛЬНЫЕ ОБНОВЛЕНИЯ WINDOWS"
set "M_KB_INSTALLED=уже установлено"
set "M_KB_NOT_FOUND=ОШИБКА: файл обязательного обновления не найден"
set "M_KB_FOLDER=Проверьте папку KB и разрядность файла."
set "M_KB_HINT1=Обновление требуется для совместимости подписей и TLS Network Agent/KICS."
set "M_KB_HINT2=Мастер не устанавливает обновление скрытно. Пакет Microsoft запускается только после вашего подтверждения."
set "M_KB_Q=Обязательное обновление отсутствует. Запустить его интерактивный установщик сейчас? [Y/N]"
set "M_KB_VERIFY_FAIL=ВНИМАНИЕ: после закрытия установщика обновление не обнаружено."
set "M_KB_VERIFY_HINT=Проверьте результат автономного установщика обновлений Windows и код ошибки."
set "M_REBOOT_REQUIRED=Обновления установлены. Перед установкой Kaspersky требуется перезагрузка."
set "M_INSTALL_TITLE=ЗАПУСК УСТАНОВКИ"
set "M_AUTO_HINT=Автономный пакет устанавливает Network Agent и, если выбрано, KICS."
set "M_AUTO_SUCCESS_Q=Установщик завершился сообщением об успешной установке? [Y/N]"
set "M_AGENT_STEP=ШАГ 1. Установка Network Agent"
set "M_AGENT_HINT1=Используйте указанные ниже адрес KSC и порты."
set "M_AGENT_HINT2=Не включайте прокси, шлюз соединения и теги агента без указания ИБ."
set "M_AGENT_SUCCESS_Q=Network Agent установлен успешно? [Y/N]"
set "M_KICS_STEP=ШАГ 2. Установка KICS for Nodes 4.0.0.236"
set "M_KICS_HINT1=Установите только перечисленные ниже компоненты."
set "M_KICS_HINT2=Не устанавливайте «Защиту от сетевых устройств»."
set "M_KICS_HINT3=Выберите режим «Только сообщать» и рекомендованные исключения Microsoft/Kaspersky."
set "M_KICS_SUCCESS_Q=KICS установлен успешно? [Y/N]"
set "M_POST_TITLE=ПРОВЕРКА ПОСЛЕ УСТАНОВКИ"
set "M_AGENT_SERVICE_OK=Служба Network Agent найдена."
set "M_AGENT_SERVICE_FAIL=Служба Network Agent не найдена."
set "M_KLN_START=Запуск проверки соединения Network Agent:"
set "M_KLN_NOT_FOUND=klnagchk.exe автоматически не найден."
set "M_POST_HINT=Проверьте вручную:"
set "M_POST_1=Компьютер появился в KSC."
set "M_POST_2=Назначены лицензия и политика."
set "M_POST_3=KICS запущен, критических ошибок нет."
set "M_POST_4=SCADA/HMI/OPC/MES и связь с PLC работают штатно."
set "M_POST_5=USB/COM/LPT и аппаратные ключи лицензирования работают штатно."
set "M_INSTALL_DONE=СЦЕНАРИЙ УСТАНОВКИ ЗАВЕРШЕН"
set "M_INSTALL_STOPPED=УСТАНОВКА ОСТАНОВЛЕНА"
set "M_SAFE_STOP_TITLE=ПРОВЕРКА ЗАВЕРШЕНА - УСТАНОВКА НЕ ЗАПУСКАЛАСЬ"
set "M_SAFE_STOP_TEXT=Выбранный комплект несовместим с этим компьютером. Установщики Kaspersky не запускались."
set "M_PLAN_ONLY_TEXT=План установки сохранен. Программное обеспечение не устанавливалось."
set "M_OPERATION_FAILED=Работа мастера завершена с ошибкой. Проверьте сообщение выше и диагностический журнал."
set "M_CLOSE_WINDOW=Нажмите любую клавишу, чтобы закрыть это окно..."
set "M_REBOOT_TITLE=ТРЕБУЕТСЯ ПЕРЕЗАГРУЗКА"
set "M_REBOOT_HINT=После запуска Windows снова запустите этот BAT-файл. Он повторно проверит обновления и продолжит."
set "M_REBOOT_Q=Перезагрузить компьютер сейчас? [Y/N]"
set "M_PRESS_ENTER=Нажмите ENTER для продолжения..."
set "M_ONLY_AGENT=Только Network Agent"
set "M_AGENT_KICS=Network Agent и KICS"
set "M_SEPARATE=Раздельные установщики"
set "M_AUTONOMOUS=Автономный пакет"
set "M_MODE_TITLE=ВЫБОР РЕЖИМА МАСТЕРА"
set "M_MODE_HINT1=Обычный режим проверяет реальный компьютер и может запускать утвержденные установщики."
set "M_MODE_HINT2=Проверка готовности определяет, хватает ли комплектующих для установки на всех поддерживаемых группах ОС. Установщики, обновления и сеть не запускаются."
set "M_MODE_NORMAL=Обычный режим установки"
set "M_MODE_SELFTEST=Проверка готовности комплекта / сухой прогон"
set "M_ST_REPORT=Отчет готовности"
set "M_ST_DEBUG_REPORT=Подробный журнал готовности"
set "M_ST_NO_CHANGES=Проверка завершена. ПО не устанавливалось, сетевые подключения не выполнялись."
set "M_RT_TITLE=ПРОВЕРКА ГОТОВНОСТИ КОМПЛЕКТА"
set "M_RT_WARNING=Проверяются только поддерживаемые группы ОС. ПО не устанавливается, сетевые запросы не выполняются."
set "M_RT_FULL=Проверить готовность для всех поддерживаемых групп ОС"
set "M_RT_ONE_PROFILE=Проверить одну поддерживаемую группу ОС"
set "M_RT_ASSETS=Показать все найденные файлы комплекта"
set "M_RT_SELECT_PROFILE=ВЫБОР ПОДДЕРЖИВАЕМОЙ ГРУППЫ ОС"
set "M_RT_CRITICAL=ОБЯЗАТЕЛЬНЫЕ КОМПОНЕНТЫ УСТАНОВКИ"
set "M_RT_ROUTES=АВТОНОМНЫЕ ПАКЕТЫ ДЛЯ ШТАТНЫХ KSC"
set "M_RT_OPTIONAL=НЕОБЯЗАТЕЛЬНЫЕ ДИАГНОСТИЧЕСКИЕ КОМПОНЕНТЫ"
set "M_RT_COVERAGE=ПОКРЫТИЕ ПОДДЕРЖИВАЕМЫХ ОС"
set "M_RT_SUMMARY=ИТОГ ГОТОВНОСТИ КОМПЛЕКТА"
set "M_RT_READY=ГОТОВО: КОМПЛЕКТ ПОКРЫВАЕТ ВСЕ ПОДДЕРЖИВАЕМЫЕ ГРУППЫ ОС"
set "M_RT_NOT_READY=НЕ ГОТОВО: НЕ ХВАТАЕТ ОБЯЗАТЕЛЬНЫХ КОМПОНЕНТОВ"
set "M_RT_FIX_MISSING=Добавьте компоненты с отметкой MISSING и повторите проверку."
set "M_RT_CRITICAL_MISSING=Не хватает обязательных компонентов"
set "M_RT_ROUTE_MISSING=Не хватает автономных пакетов KSC"
set "M_RT_PROFILE_NOT_READY=Неготовых поддерживаемых групп ОС"
set "M_RT_OK_STATUS=ЕСТЬ"
set "M_RT_MISSING_STATUS=НЕ НАЙДЕНО"
set "M_RT_OPTIONAL_STATUS=НЕОБЯЗАТЕЛЬНО: НЕ НАЙДЕНО"
set "M_RT_READY_STATUS=ГОТОВО"
set "M_RT_NOT_READY_STATUS=НЕ ГОТОВО"
set "M_LT_MENU_ITEM=Интерактивно проверить запуск установщиков на этом компьютере"
set "M_LT_TITLE=ПРОБНАЯ ПРОВЕРКА ЗАПУСКА УСТАНОВЩИКОВ"
set "M_LT_WARNING1=Проверка запускает реальный установочный файл на ТЕКУЩЕЙ операционной системе."
set "M_LT_WARNING2=Она не подтверждает совместимость с Windows XP, Server 2008 или другой целевой ОС."
set "M_LT_WARNING3=Не продолжайте установку. Закройте или отмените мастер на первом экране либо сообщении о совместимости."
set "M_LT_WARNING4=Пакеты обновлений Windows и автономные пакеты KSC намеренно не запускаются."
set "M_LT_AGENT105=Network Agent 10.5.1781 setup.exe"
set "M_LT_AGENT14=Network Agent 14.0.0.20023 setup.exe"
set "M_LT_AGENT15=Network Agent 15.1.0.20748 setup.exe"
set "M_LT_KICS=KICS for Nodes 4.0.0.236 setupui.exe"
set "M_LT_AUTO_KICS_ROZLIV=Автономный пакет Agent + KICS для KSC 10.255.40.207"
set "M_LT_AUTO_KICS_BREWING=Автономный пакет Agent + KICS для KSC 172.16.66.105"
set "M_LT_AUTO_AGENT_ROZLIV=Автономный пакет только Agent для KSC 10.255.40.207"
set "M_LT_AUTO_AGENT_BREWING=Автономный пакет только Agent для KSC 172.16.66.105"
set "M_LT_DANGER=ВНИМАНИЕ: автономный пакет может сразу начать реальную автоматическую или полуавтоматическую установку."
set "M_LT_DANGER_Q=Введите RUN, подтверждая готовность немедленно отменить установку"
set "M_LT_FILE=Исполняемый файл"
set "M_LT_LAUNCH_Q=Запустить этот файл сейчас? [Y/N]"
set "M_LT_RESULT_Q=Что произошло? [1=открылось окно установщика, 2=появилось сообщение совместимости/ошибки, 3=нет видимой реакции, 4=не уверен]"
set "M_LT_STARTED=ОКНО УСТАНОВЩИКА ОТКРЫЛОСЬ"
set "M_LT_COMPAT=ФАЙЛ ЗАПУСТИЛСЯ - ПОКАЗАНО СООБЩЕНИЕ СОВМЕСТИМОСТИ ИЛИ ОШИБКИ"
set "M_LT_FAILED=НЕТ ВИДИМОЙ РЕАКЦИИ"
set "M_LT_UNCERTAIN=РЕЗУЛЬТАТ НЕ ОПРЕДЕЛЕН"
set "M_LT_NOT_FOUND=Исполняемый файл не найден либо найдено несколько различающихся дистрибутивов."
set "M_LT_RETURNED=Исполняемый файл закрыт. Код возврата процесса"
set "M_LT_LOG=Журнал проверки запуска"
exit /b 0


rem =====================================================================
rem MAIN DISPLAY AND DETECTION
rem =====================================================================

:AskRunMode
:AskRunModeLoop
echo ============================================================
echo %M_MODE_TITLE%
echo ============================================================
echo %M_MODE_HINT1%
echo %M_MODE_HINT2%
echo.
echo [1] %M_MODE_NORMAL%
echo [2] %M_MODE_SELFTEST%
echo [0] %M_EXIT%
echo.
set "ANSWER="
set /p "ANSWER=%M_ENTER_CHOICE% [0/1/2, ENTER=1]: "
if not defined ANSWER set "ANSWER=1"
if "%ANSWER%"=="1" (
    set "RUN_MODE=NORMAL"
    exit /b 0
)
if "%ANSWER%"=="2" (
    set "RUN_MODE=SELFTEST"
    exit /b 0
)
if "%ANSWER%"=="0" exit /b 1
echo %M_INVALID%
goto :AskRunModeLoop

:Header
cls
echo ============================================================
echo %M_HEADER%
echo ============================================================
echo.
echo %M_ROOT%: %ROOT%
echo.
exit /b 0

:CheckAdmin
reg add "HKLM\SOFTWARE\BaltikaKasperskyInstallTest" /v AdminTest /t REG_SZ /d 1 /f >nul 2>&1
if errorlevel 1 (
    echo %M_ADMIN_ERROR%
    exit /b 1
)
reg delete "HKLM\SOFTWARE\BaltikaKasperskyInstallTest" /f >nul 2>&1
exit /b 0

:DetectOS
set "PRODUCT="
set "CURRENT_VERSION="
set "BUILD="
set "SPTEXT="
set "DISPLAY_VERSION="
set "RELEASE_ID="
set "EDITION_ID="
set "INSTALLATION_TYPE="
set "PRODUCT_TYPE="

for /f "tokens=2,*" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v ProductName 2^>nul ^| find /I "ProductName"') do set "PRODUCT=%%B"
for /f "tokens=2,*" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentVersion 2^>nul ^| find /I "CurrentVersion"') do set "CURRENT_VERSION=%%B"
for /f "tokens=2,*" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuildNumber 2^>nul ^| find /I "CurrentBuildNumber"') do set "BUILD=%%B"
for /f "tokens=2,*" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CSDVersion 2^>nul ^| find /I "CSDVersion"') do set "SPTEXT=%%B"
for /f "tokens=2,*" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v DisplayVersion 2^>nul ^| find /I "DisplayVersion"') do set "DISPLAY_VERSION=%%B"
for /f "tokens=2,*" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v ReleaseId 2^>nul ^| find /I "ReleaseId"') do set "RELEASE_ID=%%B"
for /f "tokens=2,*" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v EditionID 2^>nul ^| find /I "EditionID"') do set "EDITION_ID=%%B"
for /f "tokens=2,*" %%A in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v InstallationType 2^>nul ^| find /I "InstallationType"') do set "INSTALLATION_TYPE=%%B"
for /f "tokens=2,*" %%A in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\ProductOptions" /v ProductType 2^>nul ^| find /I "ProductType"') do set "PRODUCT_TYPE=%%B"

if not defined PRODUCT (
    echo %M_DETECT_ERROR%
    exit /b 1
)

if not defined BUILD set "BUILD=0"
set /a BUILDNUM=%BUILD% >nul 2>&1

set "ARCH=x86"
if /I "%PROCESSOR_ARCHITECTURE%"=="AMD64" set "ARCH=x64"
if /I "%PROCESSOR_ARCHITEW6432%"=="AMD64" set "ARCH=x64"
if /I "%PROCESSOR_ARCHITECTURE%"=="IA64" set "ARCH=ia64"
if /I "%PROCESSOR_ARCHITEW6432%"=="IA64" set "ARCH=ia64"

set "SPNUM=0"
echo %SPTEXT% | findstr /I /C:"Service Pack 1" >nul && set "SPNUM=1"
echo %SPTEXT% | findstr /I /C:"Service Pack 2" >nul && set "SPNUM=2"
echo %SPTEXT% | findstr /I /C:"Service Pack 3" >nul && set "SPNUM=3"
echo %SPTEXT% | findstr /I /C:"Пакет обновления 1" >nul && set "SPNUM=1"
echo %SPTEXT% | findstr /I /C:"Пакет обновления 2" >nul && set "SPNUM=2"
echo %SPTEXT% | findstr /I /C:"Пакет обновления 3" >nul && set "SPNUM=3"

set "IS_SERVER=0"
if /I not "%PRODUCT_TYPE%"=="WinNT" set "IS_SERVER=1"
echo %PRODUCT% | findstr /I /C:"Server" >nul && set "IS_SERVER=1"

set "IS_EMBEDDED=0"
echo %PRODUCT% | findstr /I /C:"Embedded" /C:"POSReady" /C:"Point of Service" /C:"IoT" >nul && set "IS_EMBEDDED=1"

if not defined DISPLAY_VERSION set "DISPLAY_VERSION=%RELEASE_ID%"
if not defined DISPLAY_VERSION set "DISPLAY_VERSION=unknown"
if not defined SPTEXT set "SPTEXT=none"
if not defined EDITION_ID set "EDITION_ID=unknown"

set "PRODUCT_DISPLAY=%PRODUCT%"
if %BUILDNUM% GEQ 22000 if "%IS_SERVER%"=="0" set "PRODUCT_DISPLAY=Windows 11 %EDITION_ID%"

exit /b 0

:ShowOS
echo ============================================================
echo %M_DETECTED%
echo ============================================================
echo %M_COMPUTER%:      %COMPUTERNAME%
echo %M_OS%:            %PRODUCT_DISPLAY%
echo %M_VERSION%:       %CURRENT_VERSION%
echo %M_BUILD%:         %BUILD%
echo %M_SP%:            %SPTEXT%
echo %M_DISPLAY%:       %DISPLAY_VERSION%
echo %M_EDITION%:       %EDITION_ID%
echo %M_ARCH%:          %ARCH%
echo.
exit /b 0


rem =====================================================================
rem USER CHOICES WITH EXPLANATIONS
rem =====================================================================

:AskTarget
:AskTargetLoop
echo ============================================================
echo %M_TARGET_TITLE%
echo ============================================================
echo %M_TARGET_HINT1%
echo %M_TARGET_HINT2%
echo %M_TARGET_HINT3%
echo.
echo [1] %M_TARGET_1%
echo [2] %M_TARGET_2%
echo [0] %M_EXIT%
echo.
set "ANSWER="
set /p "ANSWER=%M_ENTER_CHOICE% [0/1/2]: "
if "%ANSWER%"=="1" (
    set "INSTALL_KICS=1"
    set "TARGET_TEXT=%M_AGENT_KICS%"
    exit /b 0
)
if "%ANSWER%"=="2" (
    set "INSTALL_KICS=0"
    set "TARGET_TEXT=%M_ONLY_AGENT%"
    exit /b 0
)
if "%ANSWER%"=="0" exit /b 1
echo %M_INVALID%
echo.
goto :AskTargetLoop

:AskKSC
set "KSC_MANUAL=0"
set "KSC_CONNECTION=NOT_CHECKED"
:AskKSCLoop
echo.
echo ============================================================
echo %M_KSC_TITLE%
echo ============================================================
echo %M_KSC_HINT1%
echo %M_KSC_HINT2%
echo.
echo [1] %M_KSC_1%           - 10.255.40.207
echo [2] %M_KSC_2% - 172.16.66.105
echo [3] %M_KSC_3%
echo [0] %M_EXIT%
echo.
set "ANSWER="
set /p "ANSWER=%M_ENTER_CHOICE% [0/1/2/3]: "
if "%ANSWER%"=="1" (
    set "KSC=10.255.40.207"
    set "ZONE=%M_KSC_1%"
    set "KSC_MANUAL=0"
    exit /b 0
)
if "%ANSWER%"=="2" (
    set "KSC=172.16.66.105"
    set "ZONE=%M_KSC_2%"
    set "KSC_MANUAL=0"
    exit /b 0
)
if "%ANSWER%"=="3" (
    set "KSC="
    set /p "KSC=%M_ENTER_KSC%: "
    if not defined KSC (
        echo %M_INVALID%
        goto :AskKSCLoop
    )
    set "ZONE=Manual"
    set "KSC_MANUAL=1"
    exit /b 0
)
if "%ANSWER%"=="0" exit /b 1
echo %M_INVALID%
goto :AskKSCLoop

:AskAction
:AskActionLoop
echo %M_ACTION_HINT1%
echo %M_ACTION_HINT2%
echo.
echo [1] %M_ACTION_1%
echo [2] %M_ACTION_2%
echo [0] %M_EXIT%
echo.
set "ANSWER="
set /p "ANSWER=%M_ENTER_CHOICE% [0/1/2]: "
if "%ANSWER%"=="1" set "ACTION=1"&exit /b 0
if "%ANSWER%"=="2" set "ACTION=2"&exit /b 0
if "%ANSWER%"=="0" set "ACTION=0"&exit /b 0
echo %M_INVALID%
goto :AskActionLoop

:ConfirmAntivirus
:ConfirmAntivirusLoop
echo.
echo %M_AV_HINT1%
echo %M_AV_HINT2%
echo.
set "ANSWER="
set /p "ANSWER=%M_AV_Q% "
if /I "%ANSWER%"=="Y" exit /b 0
if /I "%ANSWER%"=="YES" exit /b 0
if /I "%ANSWER%"=="Д" exit /b 0
if /I "%ANSWER%"=="ДА" exit /b 0
if /I "%ANSWER%"=="N" (
    echo %M_AV_STOP%
    exit /b 1
)
if /I "%ANSWER%"=="NO" (
    echo %M_AV_STOP%
    exit /b 1
)
if /I "%ANSWER%"=="Н" (
    echo %M_AV_STOP%
    exit /b 1
)
if /I "%ANSWER%"=="НЕТ" (
    echo %M_AV_STOP%
    exit /b 1
)
echo %M_INVALID%
goto :ConfirmAntivirusLoop


rem =====================================================================
rem OS INSTALLATION MATRIX
rem =====================================================================

:BuildOSPlan
set "PLAN=STOP"
set "STOP_REASON="
set "AGENT_VERSION="
set "KB_LIST="
set "OS_FAMILY="
set "INSTALL_METHOD=AUTO"

if /I "%ARCH%"=="ia64" (
    if /I "%LANG%"=="RU" (
        set "STOP_REASON=Скрипт не устанавливает Kaspersky на Itanium. Пакеты ia64 требуют отдельного согласования."
    ) else (
        set "STOP_REASON=The wizard does not install Kaspersky on Itanium. IA64 packages require separate approval."
    )
    exit /b 0
)

if %BUILDNUM% LSS 2600 (
    if /I "%LANG%"=="RU" (
        set "STOP_REASON=Windows 95/98/ME/NT/2000: штатные Network Agent и KICS из комплекта не устанавливаются."
    ) else (
        set "STOP_REASON=Windows 95/98/ME/NT/2000: do not install the supplied Network Agent or KICS packages."
    )
    exit /b 0
)

if "%BUILD%"=="2600" goto :PlanXP
if "%BUILD%"=="3790" goto :Plan3790
if "%BUILD%"=="6000" goto :PlanVista2008
if "%BUILD%"=="6001" goto :PlanVista2008
if "%BUILD%"=="6002" goto :PlanVista2008
if "%BUILD%"=="7600" goto :PlanWin7
if "%BUILD%"=="7601" goto :PlanWin7
if "%BUILD%"=="9200" goto :PlanWin8
if "%BUILD%"=="9600" goto :PlanWin81
if %BUILDNUM% GEQ 10240 goto :PlanModern

if /I "%LANG%"=="RU" (
    set "STOP_REASON=Неизвестная сборка Windows: %BUILD%."
) else (
    set "STOP_REASON=Unknown Windows build: %BUILD%."
)
exit /b 0

:PlanXP
set "OS_FAMILY=Windows XP"
set "INSTALL_METHOD=SEPARATE"
if "%SPNUM%"=="2" (
    if "%IS_EMBEDDED%"=="1" (
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=Windows XP Embedded SP2 не включена в утвержденную матрицу KICS 4.0."
        ) else (
            set "STOP_REASON=Windows XP Embedded SP2 is not included in the approved KICS 4.0 matrix."
        )
        exit /b 0
    )
    set "AGENT_VERSION=10.5.1781"
    set "PLAN=OK"
    exit /b 0
)
if "%SPNUM%"=="3" (
    if /I "%ARCH%"=="x64" (
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=Windows XP SP3 x64 не является поддерживаемой комбинацией."
        ) else (
            set "STOP_REASON=Windows XP SP3 x64 is not a supported combination."
        )
        exit /b 0
    )
    set "AGENT_VERSION=14.0.0.20023"
    set "KB_LIST=KB2868626"
    set "PLAN=OK"
    exit /b 0
)
if /I "%LANG%"=="RU" (
    set "STOP_REASON=Для Windows XP поддерживаются XP Professional SP2 и XP Professional/XP Embedded SP3."
) else (
    set "STOP_REASON=For Windows XP, use XP Professional SP2 or XP Professional/XP Embedded SP3."
)
exit /b 0

:Plan3790
set "INSTALL_METHOD=SEPARATE"
if "%IS_SERVER%"=="0" (
    set "OS_FAMILY=Windows XP Professional x64"
    if not "%SPNUM%"=="2" (
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=Windows XP Professional x64 поддерживается только с SP2."
        ) else (
            set "STOP_REASON=Windows XP Professional x64 is supported only with SP2."
        )
        exit /b 0
    )
    set "AGENT_VERSION=10.5.1781"
    set "PLAN=OK"
    exit /b 0
)

set "OS_FAMILY=Windows Server 2003"
if "%SPNUM%"=="1" (
    echo %PRODUCT% | findstr /I /C:"R2" >nul
    if not errorlevel 1 (
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=Windows Server 2003 R2 поддерживается только с SP2."
        ) else (
            set "STOP_REASON=Windows Server 2003 R2 is supported only with SP2."
        )
        exit /b 0
    )
    set "AGENT_VERSION=10.5.1781"
    set "PLAN=OK"
    exit /b 0
)
if "%SPNUM%"=="2" (
    set "AGENT_VERSION=10.5.1781"
    set "PLAN=OK"
    exit /b 0
)
if /I "%LANG%"=="RU" (
    set "STOP_REASON=Windows Server 2003: требуется SP1/SP2, для R2 требуется SP2."
) else (
    set "STOP_REASON=Windows Server 2003 requires SP1/SP2; Server 2003 R2 requires SP2."
)
exit /b 0

:PlanVista2008
if "%IS_SERVER%"=="0" (
    set "OS_FAMILY=Windows Vista"
    if not "%SPNUM%"=="2" (
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=Windows Vista поддерживается KICS 4.0 только с SP2."
        ) else (
            set "STOP_REASON=KICS 4.0 supports Windows Vista only with SP2."
        )
        exit /b 0
    )
    if /I "%LANG%"=="RU" (
        set "STOP_REASON=KICS 4.0 поддерживает Vista SP2, но версия Network Agent из комплекта для Vista не подтверждена. Обратитесь в ИБ."
    ) else (
        set "STOP_REASON=KICS 4.0 supports Vista SP2, but the supplied Network Agent version is not approved for Vista. Contact Information Security."
    )
    exit /b 0
)

set "OS_FAMILY=Windows Server 2008"
if not "%SPNUM%"=="2" (
    if /I "%LANG%"=="RU" (
        set "STOP_REASON=Windows Server 2008 поддерживается только с SP2."
    ) else (
        set "STOP_REASON=Windows Server 2008 is supported only with SP2."
    )
    exit /b 0
)
set "AGENT_VERSION=15.1.0.20748"
set "KB_LIST=KB4493730 KB4474419 KB3063858"
set "PLAN=OK"
exit /b 0

:PlanWin7
if not "%SPNUM%"=="1" (
    if "%IS_SERVER%"=="1" (
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=Windows Server 2008 R2: требуется SP1."
        ) else (
            set "STOP_REASON=Windows Server 2008 R2 requires SP1."
        )
    ) else (
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=Windows 7: требуется SP1."
        ) else (
            set "STOP_REASON=Windows 7 requires SP1."
        )
    )
    exit /b 0
)

set "AGENT_VERSION=15.1.0.20748"
set "KB_LIST=KB4490628 KB4474419 KB3063858"
set "PLAN=OK"

if "%IS_SERVER%"=="1" (
    set "OS_FAMILY=Windows Server 2008 R2"
    if /I "%ARCH%"=="x86" (
        set "PLAN=STOP"
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=KICS 4.0 поддерживает Windows Server 2008 R2 x86, но Network Agent 15.1.0.20748 из комплекта поддерживает эту ОС только x64. Установка из текущего комплекта запрещена."
        ) else (
            set "STOP_REASON=KICS 4.0 supports Windows Server 2008 R2 x86, but the supplied Network Agent 15.1.0.20748 supports this OS only on x64. Installation from this kit is blocked."
        )
        exit /b 0
    )
    if "%INSTALL_KICS%"=="1" (
        echo %PRODUCT% | findstr /I /C:"Standard" /C:"Enterprise" >nul
        if errorlevel 1 (
            set "PLAN=STOP"
            if /I "%LANG%"=="RU" (
                set "STOP_REASON=KICS 4.0 на Server 2008 R2 предусмотрен для Standard/Enterprise. Для этой редакции требуется согласование."
            ) else (
                set "STOP_REASON=KICS 4.0 is approved for Server 2008 R2 Standard/Enterprise. This edition requires separate approval."
            )
        )
    )
    exit /b 0
)

set "OS_FAMILY=Windows 7"
if "%INSTALL_KICS%"=="1" (
    echo %PRODUCT% | findstr /I /C:"Professional" /C:"Enterprise" /C:"Ultimate" /C:"Embedded" /C:"POSReady" >nul
    if errorlevel 1 (
        set "PLAN=STOP"
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=KICS 4.0 не предусмотрен для обнаруженной редакции Windows 7."
        ) else (
            set "STOP_REASON=KICS 4.0 is not approved for the detected Windows 7 edition."
        )
    )
)
exit /b 0

:PlanWin8
set "AGENT_VERSION=15.1.0.20748"
set "PLAN=OK"
if "%IS_SERVER%"=="1" (
    set "OS_FAMILY=Windows Server 2012"
    if /I "%ARCH%"=="x86" (
        set "PLAN=STOP"
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=Windows Server 2012 поддерживается только в 64-разрядной редакции."
        ) else (
            set "STOP_REASON=Windows Server 2012 is supported only in 64-bit editions."
        )
    )
    exit /b 0
)

set "OS_FAMILY=Windows 8"
if "%INSTALL_KICS%"=="1" (
    echo %PRODUCT% | findstr /I /C:"Pro" /C:"Professional" /C:"Enterprise" /C:"Industry" >nul
    if errorlevel 1 (
        set "PLAN=STOP"
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=KICS 4.0 поддерживает Windows 8 Pro/Enterprise и Embedded 8 Industry Pro."
        ) else (
            set "STOP_REASON=KICS 4.0 supports Windows 8 Pro/Enterprise and Embedded 8 Industry Pro."
        )
    )
)
exit /b 0

:PlanWin81
set "AGENT_VERSION=15.1.0.20748"
set "PLAN=OK"
if "%IS_SERVER%"=="1" (
    set "OS_FAMILY=Windows Server 2012 R2"
    if /I "%ARCH%"=="x86" (
        set "PLAN=STOP"
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=Windows Server 2012 R2 поддерживается только в 64-разрядной редакции."
        ) else (
            set "STOP_REASON=Windows Server 2012 R2 is supported only in 64-bit editions."
        )
    )
    exit /b 0
)

set "OS_FAMILY=Windows 8.1"
if "%INSTALL_KICS%"=="1" (
    echo %PRODUCT% | findstr /I /C:"Pro" /C:"Professional" /C:"Enterprise" /C:"Industry" >nul
    if errorlevel 1 (
        set "PLAN=STOP"
        if /I "%LANG%"=="RU" (
            set "STOP_REASON=KICS 4.0 поддерживает Windows 8.1 Pro/Enterprise и Embedded 8.1 Industry Pro."
        ) else (
            set "STOP_REASON=KICS 4.0 supports Windows 8.1 Pro/Enterprise and Embedded 8.1 Industry Pro."
        )
    )
)
exit /b 0

:PlanModern
set "AGENT_VERSION=15.1.0.20748"
if "%IS_SERVER%"=="1" goto :PlanModernServer
if %BUILDNUM% GEQ 22000 goto :PlanWindows11
goto :PlanWindows10

rem ---------------------------------------------------------------------
rem Windows 11
rem Network Agent 15.1.0.20748: allow only 21H2 through 24H2.
rem KICS for Nodes 4.0.0.236: allow only 21H2 through 23H2.
rem All decisions use direct labels; no variable is set and read in one block.
rem ---------------------------------------------------------------------

:PlanWindows11
set "OS_FAMILY=Windows 11"

if /I "%ARCH%"=="x86" goto :StopWindows11X86

if /I "%DISPLAY_VERSION%"=="21H2" goto :Windows11AgentAndKicsSupported
if /I "%DISPLAY_VERSION%"=="22H2" goto :Windows11AgentAndKicsSupported
if /I "%DISPLAY_VERSION%"=="23H2" goto :Windows11AgentAndKicsSupported
if /I "%DISPLAY_VERSION%"=="24H2" goto :Windows11AgentOnlySupported
goto :StopWindows11AgentUnsupported

:Windows11AgentAndKicsSupported
set "PLAN=OK"
set "STOP_REASON="
exit /b 0

:Windows11AgentOnlySupported
if "%INSTALL_KICS%"=="0" goto :Windows11AgentOnlyOK
goto :StopWindows11KicsUnsupported

:Windows11AgentOnlyOK
set "PLAN=OK"
set "STOP_REASON="
exit /b 0

:StopWindows11X86
set "PLAN=STOP"
if /I "%LANG%"=="RU" goto :StopWindows11X86RU
set "STOP_REASON=Windows 11 x86 is not supported. This package requires Windows 11 x64."
exit /b 0

:StopWindows11X86RU
set "STOP_REASON=Windows 11 x86 не поддерживается. Для этого комплекта требуется Windows 11 x64."
exit /b 0

:StopWindows11KicsUnsupported
set "PLAN=STOP"
if /I "%LANG%"=="RU" goto :StopWindows11KicsUnsupportedRU
set "STOP_REASON=KICS for Nodes 4.0.0.236 is not listed for Windows 11 %DISPLAY_VERSION%. Do not run the autonomous NetAgent+KICS package. For Windows 11 24H2 select Network Agent only."
exit /b 0

:StopWindows11KicsUnsupportedRU
set "STOP_REASON=KICS for Nodes 4.0.0.236 не заявлен для Windows 11 %DISPLAY_VERSION%. Не запускайте автономный пакет NetAgent+KICS. Для Windows 11 24H2 выберите установку только Network Agent."
exit /b 0

:StopWindows11AgentUnsupported
set "PLAN=STOP"
if /I "%LANG%"=="RU" goto :StopWindows11AgentUnsupportedRU
set "STOP_REASON=Network Agent 15.1.0.20748 is not listed for Windows 11 %DISPLAY_VERSION% (build %BUILD%). Do not run any supplied Agent or NetAgent+KICS package. Request a compatible package from Information Security."
exit /b 0

:StopWindows11AgentUnsupportedRU
set "STOP_REASON=Network Agent 15.1.0.20748 не заявлен для Windows 11 %DISPLAY_VERSION% (сборка %BUILD%). Не запускайте имеющийся Agent или пакет NetAgent+KICS. Запросите у ИБ совместимый пакет."
exit /b 0

rem ---------------------------------------------------------------------
rem Windows 10 / Windows 10 IoT
rem ---------------------------------------------------------------------

:PlanWindows10
set "OS_FAMILY=Windows 10"

if "%INSTALL_KICS%"=="0" goto :ModernPlanOK
if "%IS_EMBEDDED%"=="1" goto :PlanWindows10Embedded

if "%BUILD%"=="10240" goto :ModernPlanOK
if "%BUILD%"=="14393" goto :ModernPlanOK
if "%BUILD%"=="17134" goto :ModernPlanOK
if "%BUILD%"=="17763" goto :ModernPlanOK
if "%BUILD%"=="18362" goto :ModernPlanOK
if "%BUILD%"=="19041" goto :ModernPlanOK
if "%BUILD%"=="19042" goto :ModernPlanOK
if "%BUILD%"=="19043" goto :ModernPlanOK
if "%BUILD%"=="19044" goto :ModernPlanOK
if "%BUILD%"=="19045" goto :ModernPlanOK
goto :StopWindows10KicsUnsupported

:PlanWindows10Embedded
if /I "%DISPLAY_VERSION%"=="1803" goto :ModernPlanOK
if /I "%DISPLAY_VERSION%"=="1809" goto :ModernPlanOK
if /I "%DISPLAY_VERSION%"=="1903" goto :ModernPlanOK
if /I "%DISPLAY_VERSION%"=="2004" goto :ModernPlanOK
if /I "%DISPLAY_VERSION%"=="2009" goto :ModernPlanOK
if /I "%DISPLAY_VERSION%"=="21H1" goto :ModernPlanOK
if /I "%DISPLAY_VERSION%"=="21H2" goto :ModernPlanOK
if /I "%DISPLAY_VERSION%"=="22H2" goto :ModernPlanOK
goto :StopWindows10KicsUnsupported

:StopWindows10KicsUnsupported
set "PLAN=STOP"
if /I "%LANG%"=="RU" goto :StopWindows10KicsUnsupportedRU
set "STOP_REASON=This Windows 10 or Windows 10 IoT version is not included in the approved KICS for Nodes 4.0 list."
exit /b 0

:StopWindows10KicsUnsupportedRU
set "STOP_REASON=Эта версия Windows 10 или Windows 10 IoT не включена в утвержденный перечень KICS for Nodes 4.0."
exit /b 0

rem ---------------------------------------------------------------------
rem Windows Server 2016 and newer
rem ---------------------------------------------------------------------

:PlanModernServer
set "OS_FAMILY=%PRODUCT%"

if "%INSTALL_KICS%"=="0" goto :ModernPlanOK
if "%BUILD%"=="16299" goto :ModernPlanOK
if "%BUILD%"=="17134" goto :ModernPlanOK
if "%BUILD%"=="17763" goto :ModernPlanOK
if "%BUILD%"=="18362" goto :ModernPlanOK
if "%BUILD%"=="18363" goto :ModernPlanOK
if "%BUILD%"=="19041" goto :ModernPlanOK
if "%BUILD%"=="19042" goto :ModernPlanOK
if "%BUILD%"=="20348" goto :ModernPlanOK
goto :StopModernServerKicsUnsupported

:StopModernServerKicsUnsupported
set "PLAN=STOP"
if /I "%LANG%"=="RU" goto :StopModernServerKicsUnsupportedRU
set "STOP_REASON=This Windows Server build is not included in the KICS for Nodes 4.0 list. For a non-production server restart the wizard and select Network Agent only."
exit /b 0

:StopModernServerKicsUnsupportedRU
set "STOP_REASON=Эта сборка Windows Server не включена в перечень KICS for Nodes 4.0. Для сервера без производственного ПО перезапустите мастер и выберите установку только Network Agent."
exit /b 0

:ModernPlanOK
set "PLAN=OK"
set "STOP_REASON="
exit /b 0


rem CONNECTION, FILE RESOLUTION AND PLAN
rem =====================================================================

:CheckConnectivity
>>"%DEBUGLOG%" echo [%DATE% %TIME%] CheckConnectivity entered. KSC=%KSC%
echo.
echo ============================================================
echo %M_CONNECT_TITLE%: %KSC%
echo ============================================================

ping -n 1 -w 2000 %KSC% >nul 2>&1
set "PING_RC=%ERRORLEVEL%"
>>"%DEBUGLOG%" echo [%DATE% %TIME%] Ping return code: %PING_RC%
if "%PING_RC%"=="0" (
    echo %M_ICMP_OK%
) else (
    echo %M_ICMP_FAIL%
)

set "TCP_OK=0"
set "POWERSHELL_EXE=%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe"
if exist "%POWERSHELL_EXE%" (
    >>"%DEBUGLOG%" echo [%DATE% %TIME%] PowerShell TCP check started.
    "%POWERSHELL_EXE%" -NoProfile -ExecutionPolicy Bypass -Command "$c=New-Object Net.Sockets.TcpClient;try{$r=$c.BeginConnect('%KSC%',13000,$null,$null);if(-not $r.AsyncWaitHandle.WaitOne(3000,$false)){exit 1};$c.EndConnect($r);exit 0}catch{exit 1}finally{$c.Close()}" >nul 2>&1
    set "PS_TCP_RC=!ERRORLEVEL!"
    >>"%DEBUGLOG%" echo [%DATE% %TIME%] PowerShell TCP return code: !PS_TCP_RC!
    if "!PS_TCP_RC!"=="0" set "TCP_OK=1"
) else (
    >>"%DEBUGLOG%" echo [%DATE% %TIME%] PowerShell executable not found.
)

if "%TCP_OK%"=="1" (
    >>"%DEBUGLOG%" echo [%DATE% %TIME%] TCP/13000 check successful.
    echo %M_TCP_OK%
    exit /b 0
)

>>"%DEBUGLOG%" echo [%DATE% %TIME%] TCP/13000 check failed.
echo %M_TCP_FAIL%
echo %M_PORTQRY_HINT%
>>"%DEBUGLOG%" echo [%DATE% %TIME%] Automatic connection check ended. Waiting for user action.
exit /b 1

:ConnectionFailureMenu
:ConnectionFailureMenuLoop
echo.
echo ============================================================
echo %M_CONN_FAIL_TITLE%
echo ============================================================
echo %M_CONN_FAIL_HINT1%
echo %M_CONN_FAIL_HINT2%
echo %M_DEBUG_HINT% %DEBUGLOG%
echo.
echo [1] %M_CONN_FAIL_1%
echo [2] %M_CONN_FAIL_2%
echo [3] %M_CONN_FAIL_3%
echo [4] %M_CONN_FAIL_4%
echo [0] %M_CONN_FAIL_0%
echo.
set "ANSWER="
set /p "ANSWER=%M_ENTER_CHOICE% [0/1/2/3/4]: "

if "%ANSWER%"=="1" (
    set "CONN_ACTION=RETRY"
    exit /b 0
)

if "%ANSWER%"=="2" (
    set "CONN_ACTION=CHANGE"
    exit /b 0
)

if "%ANSWER%"=="3" goto :ManualConnectionConfirm

if "%ANSWER%"=="4" (
    call :OpenPortQryWindow
    goto :ConnectionFailureMenuLoop
)

if "%ANSWER%"=="0" (
    set "CONN_ACTION=STOP"
    exit /b 0
)

echo %M_INVALID%
goto :ConnectionFailureMenuLoop

:OpenPortQryWindow
call :FindPortQry
if %FOUND_PORTQRY_UNIQUE_COUNT% GTR 1 (
    echo.
    if /I "%LANG%"=="RU" (
        echo Найдено несколько разных PortQry.exe. Оставьте одну утвержденную версию.
    ) else (
        echo Multiple different PortQry.exe files were found. Keep one approved version.
    )
    echo.
    exit /b 0
)
set "PORTQRY=%FOUND_PORTQRY%"
if not defined PORTQRY (
    echo.
    echo %M_PORTQRY_MISSING%
    echo Recursive search root: %ROOT%
    echo.
    exit /b 0
)
echo.
echo %M_PORTQRY_MANUAL_HINT%
echo.
>>"%DEBUGLOG%" echo [%DATE% %TIME%] Manual PortQry window opened: %PORTQRY% -n %KSC% -p tcp -e 13000
start "PortQry TCP 13000" "%ComSpec%" /d /k ""%PORTQRY%" -n %KSC% -p tcp -e 13000"
exit /b 0

:ManualConnectionConfirm
set "ANSWER="
set /p "ANSWER=%M_CONN_CONFIRM% "
if /I "%ANSWER%"=="Y" (
    set "CONN_ACTION=CONTINUE"
    exit /b 0
)
if /I "%ANSWER%"=="YES" (
    set "CONN_ACTION=CONTINUE"
    exit /b 0
)
if /I "%ANSWER%"=="Д" (
    set "CONN_ACTION=CONTINUE"
    exit /b 0
)
if /I "%ANSWER%"=="ДА" (
    set "CONN_ACTION=CONTINUE"
    exit /b 0
)
if /I "%ANSWER%"=="N" goto :ConnectionFailureMenuLoop
if /I "%ANSWER%"=="NO" goto :ConnectionFailureMenuLoop
if /I "%ANSWER%"=="Н" goto :ConnectionFailureMenuLoop
if /I "%ANSWER%"=="НЕТ" goto :ConnectionFailureMenuLoop
echo %M_INVALID%
goto :ManualConnectionConfirm

:ResolveFiles
set "PACKAGE_FILE="
set "AGENT_FILE="
set "KICS_FILE="

if /I "%INSTALL_METHOD%"=="SEPARATE" goto :ResolveSeparate

if "%INSTALL_KICS%"=="1" (
    call :FindAutonomousPackage "KICS" "%KSC%"
) else (
    call :FindAutonomousPackage "AGENT" "%KSC%"
)

if %FOUND_PACKAGE_UNIQUE_COUNT% GTR 1 (
    if /I "%LANG%"=="RU" (
        echo ОШИБКА: найдено несколько разных автономных пакетов для KSC %KSC%.
    ) else (
        echo ERROR: multiple different autonomous packages were found for KSC %KSC%.
    )
    exit /b 1
)
set "PACKAGE_FILE=%FOUND_PACKAGE%"

if not defined PACKAGE_FILE (
    if "%KSC_MANUAL%"=="1" (
        echo.
        echo %M_MANUAL_KSC_NO_PACKAGE%
        echo %M_MANUAL_KSC_HINT%
        set "INSTALL_METHOD=SEPARATE"
        goto :ResolveSeparate
    )
    if /I "%LANG%"=="RU" (
        echo ОШИБКА: автономный пакет для KSC %KSC% не найден.
    ) else (
        echo ERROR: autonomous package for KSC %KSC% was not found.
    )
    exit /b 1
)
set "INSTALL_METHOD_TEXT=%M_AUTONOMOUS%"
exit /b 0

:FindAutonomousPackage
set "FOUND_PACKAGE="
set "FOUND_PACKAGE_COPY_COUNT=0"
set "FOUND_PACKAGE_UNIQUE_COUNT=0"
set "SEARCH_PACKAGE_TYPE=%~1"
set "SEARCH_PACKAGE_KSC=%~2"

for /f "delims=" %%F in ('dir /b /s /a-d "%ROOT%*%SEARCH_PACKAGE_KSC%*.exe" 2^>nul') do (
    set "PACKAGE_NAME=%%~nxF"
    set "PACKAGE_MATCH=0"
    if /I "!SEARCH_PACKAGE_TYPE!"=="KICS" (
        set "TMP_NAME=!PACKAGE_NAME:KICS=!"
        if /I not "!TMP_NAME!"=="!PACKAGE_NAME!" set "PACKAGE_MATCH=1"
    )
    if /I "!SEARCH_PACKAGE_TYPE!"=="AGENT" (
        set "TMP_AGENT=!PACKAGE_NAME:Agent=!"
        set "TMP_KICS=!PACKAGE_NAME:KICS=!"
        if /I not "!TMP_AGENT!"=="!PACKAGE_NAME!" if /I "!TMP_KICS!"=="!PACKAGE_NAME!" set "PACKAGE_MATCH=1"
    )
    if "!PACKAGE_MATCH!"=="1" (
        set /a FOUND_PACKAGE_COPY_COUNT+=1
        if not defined FOUND_PACKAGE (
            set "FOUND_PACKAGE=%%F"
            set "FOUND_PACKAGE_UNIQUE_COUNT=1"
        ) else (
            fc /b "!FOUND_PACKAGE!" "%%F" >nul 2>&1
            if errorlevel 1 set /a FOUND_PACKAGE_UNIQUE_COUNT+=1
        )
        if defined DEBUGLOG >>"%DEBUGLOG%" echo Package candidate: %%F
        if defined SELFTEST_DEBUGLOG >>"%SELFTEST_DEBUGLOG%" echo Package candidate: %%F
    )
)
exit /b 0

:FindAgentSetupByVersion
set "FOUND_AGENT_SETUP="
set "FOUND_AGENT_COPY_COUNT=0"
set "FOUND_AGENT_UNIQUE_COUNT=0"
set "SEARCH_AGENT_VERSION=%~1"

rem A valid Agent setup must have an exec directory, a KUD file and license.txt
rem in the same distribution root. Multiple complete roots of the same version
rem are accepted; the first deterministic DIR result is selected.
for /f "delims=" %%F in ('dir /b /s /a-d "%ROOT%setup.exe" 2^>nul') do (
    set "CANDIDATE=%%F"
    set "WITHOUT_VERSION=!CANDIDATE:%SEARCH_AGENT_VERSION%=!"
    if /I not "!WITHOUT_VERSION!"=="!CANDIDATE!" (
        for %%D in ("%%F") do set "CANDIDATE_HOME=%%~dpD"
        set "CANDIDATE_VALID=1"
        if not exist "!CANDIDATE_HOME!exec\" set "CANDIDATE_VALID=0"
        if not exist "!CANDIDATE_HOME!license.txt" set "CANDIDATE_VALID=0"
        set "CANDIDATE_KUD="
        for /f "delims=" %%K in ('dir /b /a-d "!CANDIDATE_HOME!*.kud" 2^>nul') do if not defined CANDIDATE_KUD set "CANDIDATE_KUD=%%K"
        if not defined CANDIDATE_KUD set "CANDIDATE_VALID=0"

        if "!CANDIDATE_VALID!"=="1" (
            set /a FOUND_AGENT_COPY_COUNT+=1
            if not defined FOUND_AGENT_SETUP set "FOUND_AGENT_SETUP=%%F"
            if defined DEBUGLOG >>"%DEBUGLOG%" echo Valid Agent %SEARCH_AGENT_VERSION% candidate: %%F
            if defined SELFTEST_DEBUGLOG >>"%SELFTEST_DEBUGLOG%" echo Valid Agent %SEARCH_AGENT_VERSION% candidate: %%F
        ) else (
            if defined DEBUGLOG >>"%DEBUGLOG%" echo Ignored incomplete Agent candidate: %%F
            if defined SELFTEST_DEBUGLOG >>"%SELFTEST_DEBUGLOG%" echo Ignored incomplete Agent candidate: %%F
        )
    )
)

if defined FOUND_AGENT_SETUP set "FOUND_AGENT_UNIQUE_COUNT=1"
exit /b 0

:FindKicsSetup
set "FOUND_KICS_SETUP="
set "FOUND_KICS_COPY_COUNT=0"
set "FOUND_KICS_UNIQUE_COUNT=0"
for /f "delims=" %%F in ('dir /b /s /a-d "%ROOT%setupui.exe" 2^>nul') do (
    set "CANDIDATE=%%F"
    set "WITHOUT_VERSION=!CANDIDATE:4.0.0.236=!"
    if /I not "!WITHOUT_VERSION!"=="!CANDIDATE!" (
        set /a FOUND_KICS_COPY_COUNT+=1
        if not defined FOUND_KICS_SETUP (
            set "FOUND_KICS_SETUP=%%F"
            set "FOUND_KICS_UNIQUE_COUNT=1"
        ) else (
            fc /b "!FOUND_KICS_SETUP!" "%%F" >nul 2>&1
            if errorlevel 1 set /a FOUND_KICS_UNIQUE_COUNT+=1
        )
        if defined SELFTEST_DEBUGLOG >>"%SELFTEST_DEBUGLOG%" echo KICS candidate: %%F
    )
)
exit /b 0

:FindPortQry
set "FOUND_PORTQRY="
set "FOUND_PORTQRY_COPY_COUNT=0"
set "FOUND_PORTQRY_UNIQUE_COUNT=0"
for /f "delims=" %%F in ('dir /b /s /a-d "%ROOT%PortQry.exe" 2^>nul') do (
    set /a FOUND_PORTQRY_COPY_COUNT+=1
    if not defined FOUND_PORTQRY (
        set "FOUND_PORTQRY=%%F"
        set "FOUND_PORTQRY_UNIQUE_COUNT=1"
    ) else (
        fc /b "!FOUND_PORTQRY!" "%%F" >nul 2>&1
        if errorlevel 1 set /a FOUND_PORTQRY_UNIQUE_COUNT+=1
    )
)
exit /b 0

:ResolveSeparate
call :FindAgentSetupByVersion "%AGENT_VERSION%"
if %FOUND_AGENT_UNIQUE_COUNT% GTR 1 (
    if /I "%LANG%"=="RU" (
        echo ОШИБКА: найдено несколько разных setup.exe для Network Agent %AGENT_VERSION%.
    ) else (
        echo ERROR: multiple different setup.exe files were found for Network Agent %AGENT_VERSION%.
    )
    exit /b 1
)
set "AGENT_FILE=%FOUND_AGENT_SETUP%"
if not defined AGENT_FILE (
    if /I "%LANG%"=="RU" (
        echo ОШИБКА: setup.exe агента %AGENT_VERSION% не найден.
    ) else (
        echo ERROR: setup.exe for Network Agent %AGENT_VERSION% was not found.
    )
    exit /b 1
)

if "%INSTALL_KICS%"=="1" (
    call :FindKicsSetup
    if !FOUND_KICS_UNIQUE_COUNT! GTR 1 (
        if /I "%LANG%"=="RU" (
            echo ОШИБКА: найдено несколько разных setupui.exe KICS 4.0.0.236.
        ) else (
            echo ERROR: multiple different KICS setupui.exe files were found.
        )
        exit /b 1
    )
    set "KICS_FILE=!FOUND_KICS_SETUP!"
    if not defined KICS_FILE (
        if /I "%LANG%"=="RU" (
            echo ОШИБКА: setupui.exe KICS 4.0.0.236 не найден.
        ) else (
            echo ERROR: KICS 4.0.0.236 setupui.exe was not found.
        )
        exit /b 1
    )
)
set "INSTALL_METHOD_TEXT=%M_SEPARATE%"
exit /b 0

:WritePlan
> "%LOG%" echo BALTIKA OT - KASPERSKY INSTALLATION PLAN
>>"%LOG%" echo ============================================================
>>"%LOG%" echo Computer: %COMPUTERNAME%
>>"%LOG%" echo OS detected: %PRODUCT_DISPLAY%
>>"%LOG%" echo OS family selected: %OS_FAMILY%
>>"%LOG%" echo Build: %BUILD%
>>"%LOG%" echo Service Pack: %SPTEXT%
>>"%LOG%" echo DisplayVersion: %DISPLAY_VERSION%
>>"%LOG%" echo Architecture: %ARCH%
>>"%LOG%" echo Area: %ZONE%
>>"%LOG%" echo KSC: %KSC%
>>"%LOG%" echo KSC entered manually: %KSC_MANUAL%
>>"%LOG%" echo KSC connection: %KSC_CONNECTION%
>>"%LOG%" echo Target: %TARGET_TEXT%
>>"%LOG%" echo Method: %INSTALL_METHOD_TEXT%
>>"%LOG%" echo Network Agent: %AGENT_VERSION%
>>"%LOG%" echo Required KB: %KB_LIST%
>>"%LOG%" echo Plan: %PLAN%
if /I "%PLAN%"=="STOP" >>"%LOG%" echo Stop reason: %STOP_REASON%
if defined PACKAGE_FILE >>"%LOG%" echo Autonomous package: %PACKAGE_FILE%
if defined AGENT_FILE >>"%LOG%" echo Network Agent installer: %AGENT_FILE%
if defined KICS_FILE >>"%LOG%" echo KICS installer: %KICS_FILE%
exit /b 0

:ShowPlan
echo.
echo ============================================================
echo %M_PLAN_TITLE%
echo ============================================================
echo %M_OS%:             %OS_FAMILY%
echo %M_TARGET%:         %TARGET_TEXT%
echo %M_ZONE%:           %ZONE%
echo %M_KSC%:            %KSC%
echo KSC connection:     %KSC_CONNECTION%
echo %M_METHOD%:         %INSTALL_METHOD_TEXT%
echo %M_AGENT%:          %AGENT_VERSION%
if defined KB_LIST echo %M_REQUIRED_KB%: %KB_LIST%
if defined PACKAGE_FILE echo %M_PACKAGE%: %PACKAGE_FILE%
if defined AGENT_FILE echo %M_AGENT%: %AGENT_FILE%
if defined KICS_FILE echo %M_KICS%: %KICS_FILE%
echo.
echo %M_PLAN_SAVED%
echo %LOG%
echo.
exit /b 0


rem =====================================================================
rem WINDOWS UPDATES
rem =====================================================================

:InstallRequiredKB
set "REBOOT_REQUIRED=0"
if not defined KB_LIST exit /b 0

echo.
echo ============================================================
echo %M_KB_TITLE%
echo ============================================================

for %%K in (%KB_LIST%) do (
    call :ProcessKB %%K
    if errorlevel 1 exit /b 1
)
exit /b 0

:ProcessKB
set "KB=%~1"
call :IsKBInstalled %KB%
if "%KB_INSTALLED%"=="1" (
    echo %KB%: %M_KB_INSTALLED%.
    exit /b 0
)

call :FindKBFile %KB%
if %KB_MATCH_COUNT% GTR 1 (
    if /I "%LANG%"=="RU" (
        echo ОШИБКА: найдено несколько разных файлов обновления %KB% для %ARCH%.
    ) else (
        echo ERROR: multiple different %KB% update files were found for %ARCH%.
    )
    exit /b 1
)
if not defined KB_FILE (
    echo %M_KB_NOT_FOUND%: %KB%
    echo %M_KB_FOLDER%
    exit /b 1
)

echo.
echo %M_KB_HINT1%
echo %M_KB_HINT2%
echo %M_PACKAGE%: %KB_FILE%
echo.
:KBChoiceLoop
set "ANSWER="
set /p "ANSWER=%M_KB_Q% "
if /I "%ANSWER%"=="Y" goto :InstallOneKB
if /I "%ANSWER%"=="YES" goto :InstallOneKB
if /I "%ANSWER%"=="Д" goto :InstallOneKB
if /I "%ANSWER%"=="ДА" goto :InstallOneKB
if /I "%ANSWER%"=="N" exit /b 1
if /I "%ANSWER%"=="NO" exit /b 1
if /I "%ANSWER%"=="Н" exit /b 1
if /I "%ANSWER%"=="НЕТ" exit /b 1
echo %M_INVALID%
goto :KBChoiceLoop

:InstallOneKB
set "RUN_FILE=%KB_FILE%"
call :RunFileWait
set "KB_LAUNCH_RC=%ERRORLEVEL%"
call :IsKBInstalled %KB%
if "%KB_INSTALLED%"=="0" (
    echo %M_KB_VERIFY_FAIL%
    echo %M_KB_VERIFY_HINT%
    exit /b 1
)
set "REBOOT_REQUIRED=1"
exit /b 0

:IsKBInstalled
set "KB_INSTALLED=0"
if exist "%SystemRoot%\System32\wbem\wmic.exe" (
    "%SystemRoot%\System32\wbem\wmic.exe" qfe get HotFixID 2>nul | findstr /I /C:"%~1" >nul
    if not errorlevel 1 set "KB_INSTALLED=1"
)
if "%KB_INSTALLED%"=="1" exit /b 0

if exist "%SystemRoot%\System32\dism.exe" (
    "%SystemRoot%\System32\dism.exe" /online /get-packages 2>nul | findstr /I /C:"%~1" >nul
    if not errorlevel 1 set "KB_INSTALLED=1"
)
exit /b 0

:FindKBFile
set "KB_FILE="
set "KB_MATCH_COUNT=0"
set "KB_PREFIX="
if "%BUILD%"=="2600" set "KB_PREFIX=WindowsXP"
if "%BUILD%"=="6002" set "KB_PREFIX=Windows6.0"
if "%BUILD%"=="7601" set "KB_PREFIX=Windows6.1"
if not defined KB_PREFIX exit /b 0

call :FindUpdateByCriteria "%KB_PREFIX%" "%~1" "%ARCH%"
set "KB_FILE=%FOUND_UPDATE_FILE%"
set "KB_MATCH_COUNT=%FOUND_UPDATE_UNIQUE_COUNT%"
exit /b 0

:FindUpdateByCriteria
set "FOUND_UPDATE_FILE="
set "FOUND_UPDATE_COPY_COUNT=0"
set "FOUND_UPDATE_UNIQUE_COUNT=0"
set "SEARCH_UPDATE_PREFIX=%~1"
set "SEARCH_UPDATE_ID=%~2"
set "SEARCH_UPDATE_ARCH=%~3"

for %%E in (msu exe) do (
    for /f "delims=" %%F in ('dir /b /s /a-d "%ROOT%*%SEARCH_UPDATE_PREFIX%*%SEARCH_UPDATE_ID%*%SEARCH_UPDATE_ARCH%*.%%E" 2^>nul') do (
        set /a FOUND_UPDATE_COPY_COUNT+=1
        if not defined FOUND_UPDATE_FILE (
            set "FOUND_UPDATE_FILE=%%F"
            set "FOUND_UPDATE_UNIQUE_COUNT=1"
        ) else (
            fc /b "!FOUND_UPDATE_FILE!" "%%F" >nul 2>&1
            if errorlevel 1 set /a FOUND_UPDATE_UNIQUE_COUNT+=1
        )
        if defined SELFTEST_DEBUGLOG >>"%SELFTEST_DEBUGLOG%" echo Update candidate: %%F
    )
)
exit /b 0

rem =====================================================================
rem INSTALLATION
rem =====================================================================

:RunFileWait
set "RUN_RETURN_CODE=1"
set "RUN_WORKDIR="
set "RUN_FILENAME="

if not defined RUN_FILE exit /b 1
if not exist "!RUN_FILE!" (
    >>"%DEBUGLOG%" echo [%DATE% %TIME%] Launch failed: file does not exist: !RUN_FILE!
    exit /b 1
)

for %%D in ("!RUN_FILE!") do (
    set "RUN_WORKDIR=%%~dpD"
    set "RUN_FILENAME=%%~nxD"
)

>>"%DEBUGLOG%" echo [%DATE% %TIME%] Launching installer:
>>"%DEBUGLOG%" echo     File=!RUN_FILE!
>>"%DEBUGLOG%" echo     WorkingDirectory=!RUN_WORKDIR!

pushd "!RUN_WORKDIR!" >nul 2>&1
if errorlevel 1 (
    >>"%DEBUGLOG%" echo [%DATE% %TIME%] Launch failed: cannot enter working directory.
    exit /b 1
)

start "" /wait "!RUN_FILENAME!"
set "RUN_RETURN_CODE=!ERRORLEVEL!"
popd >nul 2>&1

>>"%DEBUGLOG%" echo [%DATE% %TIME%] Installer process return code: !RUN_RETURN_CODE!
exit /b !RUN_RETURN_CODE!



:LaunchInstallers
echo.
echo ============================================================
echo %M_INSTALL_TITLE%
echo ============================================================

if /I "%INSTALL_METHOD%"=="SEPARATE" goto :LaunchSeparate

echo %M_AUTO_HINT%
echo.
echo %M_PACKAGE%:
echo %PACKAGE_FILE%
echo.
set /p "DUMMY=%M_PRESS_ENTER%"
set "RUN_FILE=%PACKAGE_FILE%"
call :RunFileWait
set "PACKAGE_LAUNCH_RC=%ERRORLEVEL%"

:AutoSuccessLoop
echo.
set "ANSWER="
set /p "ANSWER=%M_AUTO_SUCCESS_Q% "
if /I "%ANSWER%"=="Y" exit /b 0
if /I "%ANSWER%"=="YES" exit /b 0
if /I "%ANSWER%"=="Д" exit /b 0
if /I "%ANSWER%"=="ДА" exit /b 0
if /I "%ANSWER%"=="N" exit /b 1
if /I "%ANSWER%"=="NO" exit /b 1
if /I "%ANSWER%"=="Н" exit /b 1
if /I "%ANSWER%"=="НЕТ" exit /b 1
echo %M_INVALID%
goto :AutoSuccessLoop

:LaunchSeparate
echo %M_AGENT_STEP% %AGENT_VERSION%
echo %M_AGENT_HINT1%
echo %M_AGENT_HINT2%
echo.
echo KSC:       %KSC%
echo Port:      14000
echo SSL port:  13000
echo SSL:       enabled
echo UDP port:  15000
echo Proxy:     do not use
echo Gateway:   do not use
echo Certificate: receive from Administration Server
echo.
echo %M_AGENT%:
echo %AGENT_FILE%
echo.
set /p "DUMMY=%M_PRESS_ENTER%"
set "RUN_FILE=%AGENT_FILE%"
call :RunFileWait
set "AGENT_LAUNCH_RC=%ERRORLEVEL%"

:AgentSuccessLoop
set "ANSWER="
set /p "ANSWER=%M_AGENT_SUCCESS_Q% "
if /I "%ANSWER%"=="Y" goto :AgentInstalled
if /I "%ANSWER%"=="YES" goto :AgentInstalled
if /I "%ANSWER%"=="Д" goto :AgentInstalled
if /I "%ANSWER%"=="ДА" goto :AgentInstalled
if /I "%ANSWER%"=="N" exit /b 1
if /I "%ANSWER%"=="NO" exit /b 1
if /I "%ANSWER%"=="Н" exit /b 1
if /I "%ANSWER%"=="НЕТ" exit /b 1
echo %M_INVALID%
goto :AgentSuccessLoop

:AgentInstalled
if "%INSTALL_KICS%"=="0" exit /b 0

echo.
echo %M_KICS_STEP%
echo %M_KICS_HINT1%
echo %M_KICS_HINT2%
echo %M_KICS_HINT3%
echo.
echo Components to install / Компоненты:
echo   - Core functionality
echo   - Log inspection
echo   - Anti-malware protection
echo   - File operation monitoring
echo   - Exploit prevention
echo   - Tray icon
echo   - Registry access monitor
echo   - Device Control
echo   - Application Launch Control
echo   - Kaspersky Security Center integration
echo.
echo Do not install / Не устанавливать:
echo   - Protection from network devices / Network Threat Protection
echo.
echo %M_KICS%:
echo %KICS_FILE%
echo.
set /p "DUMMY=%M_PRESS_ENTER%"
set "RUN_FILE=%KICS_FILE%"
call :RunFileWait
set "KICS_LAUNCH_RC=%ERRORLEVEL%"

:KICSSuccessLoop
set "ANSWER="
set /p "ANSWER=%M_KICS_SUCCESS_Q% "
if /I "%ANSWER%"=="Y" exit /b 0
if /I "%ANSWER%"=="YES" exit /b 0
if /I "%ANSWER%"=="Д" exit /b 0
if /I "%ANSWER%"=="ДА" exit /b 0
if /I "%ANSWER%"=="N" exit /b 1
if /I "%ANSWER%"=="NO" exit /b 1
if /I "%ANSWER%"=="Н" exit /b 1
if /I "%ANSWER%"=="НЕТ" exit /b 1
echo %M_INVALID%
goto :KICSSuccessLoop


rem =====================================================================
rem POST CHECK AND EXIT
rem =====================================================================

:PostCheck
echo.
echo ============================================================
echo %M_POST_TITLE%
echo ============================================================

sc query klnagent >nul 2>&1
if errorlevel 1 (
    echo %M_AGENT_SERVICE_FAIL%
) else (
    echo %M_AGENT_SERVICE_OK%
)

set "KLNAGCHK="
if exist "%ProgramFiles%\Kaspersky Lab\NetworkAgent\klnagchk.exe" set "KLNAGCHK=%ProgramFiles%\Kaspersky Lab\NetworkAgent\klnagchk.exe"
if defined PF86 if exist "%PF86%\Kaspersky Lab\NetworkAgent\klnagchk.exe" set "KLNAGCHK=%PF86%\Kaspersky Lab\NetworkAgent\klnagchk.exe"

if defined KLNAGCHK (
    echo.
    echo %M_KLN_START%
    echo %KLNAGCHK%
    "%KLNAGCHK%"
) else (
    echo %M_KLN_NOT_FOUND%
)

echo.
echo %M_POST_HINT%
echo [ ] %M_POST_1%
echo [ ] %M_POST_2%
if "%INSTALL_KICS%"=="1" echo [ ] %M_POST_3%
echo [ ] %M_POST_4%
echo [ ] %M_POST_5%
echo.
set /p "DUMMY=%M_PRESS_ENTER%"
exit /b 0

:NeedReboot
echo.
echo ============================================================
echo %M_REBOOT_TITLE%
echo ============================================================
echo %M_REBOOT_REQUIRED%
echo %M_REBOOT_HINT%
echo.
:RebootLoop
set "ANSWER="
set /p "ANSWER=%M_REBOOT_Q% "
if /I "%ANSWER%"=="Y" goto :DoReboot
if /I "%ANSWER%"=="YES" goto :DoReboot
if /I "%ANSWER%"=="Д" goto :DoReboot
if /I "%ANSWER%"=="ДА" goto :DoReboot
if /I "%ANSWER%"=="N" goto :End
if /I "%ANSWER%"=="NO" goto :End
if /I "%ANSWER%"=="Н" goto :End
if /I "%ANSWER%"=="НЕТ" goto :End
echo %M_INVALID%
goto :RebootLoop

:DoReboot
shutdown /r /t 30 /c "Restart after required Kaspersky prerequisites"
goto :End

:EndSuccess
echo.
echo ============================================================
echo %M_INSTALL_DONE%
echo ============================================================
echo %M_PLAN_SAVED%
echo %LOG%
>>"%DEBUGLOG%" echo [%DATE% %TIME%] Wizard finished: SUCCESS
goto :CloseWizard

:EndError
echo.
echo ============================================================
echo %M_INSTALL_STOPPED%
echo ============================================================
echo %M_OPERATION_FAILED%
echo %M_DEBUG_HINT% %DEBUGLOG%
>>"%DEBUGLOG%" echo [%DATE% %TIME%] Wizard finished: ERROR
goto :CloseWizard

:End
>>"%DEBUGLOG%" echo [%DATE% %TIME%] Wizard finished: USER_EXIT
goto :CloseWizard

:CloseWizard
echo.
echo %M_CLOSE_WINDOW%
pause >nul
endlocal
exit
