@echo off

rem ##############################################################################
rem #
rem # Copyright (c) 2013 VMware, Inc. All rights reserved.
rem # -- VMware Confidential
rem #
rem ##############################################################################

set _VUM_RUNDLL32_EXE=%windir%\system32\rundll32.exe
set _VUM_REG_EXE=%windir%\system32\reg.exe
set _VUM_SC_EXE=%windir%\system32\sc.exe
set _VUM_PING_EXE=%windir%\system32\ping.exe
set _VUM_FC_EXE=%windir%\system32\fc.exe
set _VUM_XCOPY_EXE=%windir%\system32\xcopy.exe

set _VUM_VC_REG_PATH="HKLM\SOFTWARE\VMware, Inc.\VMware Update Manager"
set _VUM_VC_REG_WOW_PATH="HKLM\SOFTWARE\Wow6432Node\VMware, Inc.\VMware Update Manager"

call "%~dp0common" Verifying that the required tools exist

if NOT EXIST "%_VUM_REG_EXE%" (
	set last_error=reg.exe is not present in the system32 directory.
	goto endError
)

if NOT EXIST "%_VUM_SC_EXE%" (
	set last_error=sc.exe is not present in the system32 directory.
	goto endError
)

if NOT EXIST "%_VUM_XCOPY_EXE%" (
	set last_error=xcopy.exe is not present in the system32 directory.
	goto endError
)

if NOT EXIST "%_VUM_RUNDLL32_EXE%" (
	set last_error=rundll32.exe is not present in the system32 directory.
	goto endError
)

call "%~dp0common" Validating the input parameters

if "%ROLLBACK_BACKUP_FOLDER%"=="" (
	set last_error=The backup folder was not specified
	goto endError
)

if "%vc_username%"=="" (
	set last_error=vCenter Server user account name was not specified
	goto endError
)

if "%vc_password%"=="" (
	set last_error=vCenter Server user account password was not specified
	goto endError
)

call "%~dp0common" Determining the product installation directory

set _VUM_INSTALL_PATH=
call :GetVUMInstallDir %_VUM_VC_REG_PATH% > nul 2>&1
if "%_VUM_INSTALL_PATH%"=="" call :GetVUMInstallDir %_VUM_VC_REG_WOW_PATH% > nul 2>&1
if "%_VUM_INSTALL_PATH%"=="" (
	call "%~dp0common" Failed to load the path from the registry. vSphere Update Manager might not be installed.
	call :ClearInfo
	exit /B 2
)
rem chop off the last backslash if one is present
if "%_VUM_INSTALL_PATH:~-1%" == "\" set "_VUM_INSTALL_PATH=%_VUM_INSTALL_PATH:~0,-1%"
call "%~dp0common" Detected that vSphere Update Manager is installed at "%_VUM_INSTALL_PATH%"

set _VUM_VC_ADDR=
call :GetVCServerName %_VUM_VC_REG_PATH% > nul 2>&1
if "%_VUM_VC_ADDR%"=="" call :GetVCServerName %_VUM_VC_REG_WOW_PATH% > nul 2>&1
if "%_VUM_VC_ADDR%"=="" (
	set last_error=Failed to load the vCenter Server name from the registry.
	goto endError
)

set _VUM_VC_PORT=
call :GetVCServerPort %_VUM_VC_REG_PATH% > nul 2>&1
if "%_VUM_VC_PORT%"=="" call :GetVCServerPort %_VUM_VC_REG_WOW_PATH% > nul 2>&1
if "%_VUM_VC_PORT%"=="" (
	set last_error=Failed to load the vCenter Server port from the registry.
	goto endError
)
call "%~dp0common" Using the vCenter Server at "%_VUM_VC_ADDR%" on port "%_VUM_VC_PORT%"

rem tool doesn't like trailing slash on config path
set "_VUM_CONFIG_PATH=%_VUM_INSTALL_PATH%"

set "_VUM_ROLLBACK_PATH=%ROLLBACK_BACKUP_FOLDER%"
rem Remove trailing slash
if "%_VUM_ROLLBACK_PATH:~-1%" == "\" set "_VUM_ROLLBACK_PATH=%_VUM_ROLLBACK_PATH:~0,-1%"
call "%~dp0common" Rollback path is "%_VUM_ROLLBACK_PATH%"

if NOT EXIST "%_VUM_ROLLBACK_PATH%" (
	mkdir "%_VUM_ROLLBACK_PATH%"
	if NOT EXIST "%_VUM_ROLLBACK_PATH%" (
		set last_error=The specified rollback directory "%_VUM_ROLLBACK_PATH%" does not exist.
		goto endError
	)
)

set "_VUM_ROLLBACK_PATH=%_VUM_ROLLBACK_PATH%\VUM"
if NOT EXIST "%_VUM_ROLLBACK_PATH%" (
	mkdir "%_VUM_ROLLBACK_PATH%"
)
call "%~dp0common" Rollback path is "%_VUM_ROLLBACK_PATH%"
if NOT EXIST "%_VUM_ROLLBACK_PATH%" (
	set last_error=vSphere Update Manager rollback directory "%_VUM_ROLLBACK_PATH%" does not exist.
	goto endError
)

rem tool doesn't like trailing slash on log path
set "_VUM_LOG_PATH=%LOGS_FOLDER%"
if "%_VUM_LOG_PATH:~-1%" == "\" set "_VUM_LOG_PATH=%_VUM_LOG_PATH:~0,-1%"
call "%~dp0common" Log path is "%_VUM_LOG_PATH%"

set "_VUM_TOOL_PATH=%_VUM_ROLLBACK_PATH%"
set _VUM_TOOL_NAME=vciInstallUtils.exe
set "_VUM_TOOL_FULL_PATH=%_VUM_TOOL_PATH%\%_VUM_TOOL_NAME%"
set _VUM_TOOL_TRUST_ARGS=-v %_VUM_VC_ADDR% -p %_VUM_VC_PORT% -U "%vc_username%" -P "%vc_password%" -C "%_VUM_CONFIG_PATH%" -L "%_VUM_LOG_PATH%"

set "_VUM_PATCH_PATH=%~dp0vumutils"
set _VUM_PATCH_CANARY_NAME=vmwareUpdateManagerUtility.patch.exe
set _VUM_PATCH_INF_NAME=vumtoolupdate.inf

call "%~dp0common" Copying in the needed files to perfrom the patch

for %%i in ("vciInstallUtils.exe" "vmwareUpdateManagerUtility.exe" "libeay32.dll" "log4cpp.dll" "ssleay32.dll" "sysimgbase.dll" "ufa-common.dll" "ufa-types.dll" "vim-types.dll" "vmacore.dll" "vmomi.dll") do (
	"%_VUM_XCOPY_EXE%" /y "%_VUM_INSTALL_PATH%\%%~i" "%_VUM_TOOL_PATH%\"
	if ERRORLEVEL 1 (
		set last_error=Cannot copy "%_VUM_INSTALL_PATH%\%%~i" to "%_VUM_TOOL_PATH%\": %ERRORLEVEL%
		goto endError
	)
)

call "%~dp0common" Copied the product files

rem copy in patched versioned file
"%_VUM_XCOPY_EXE%" /y "%_VUM_PATCH_PATH%\%_VUM_PATCH_CANARY_NAME%" "%_VUM_TOOL_PATH%\"
if ERRORLEVEL 1 (
	set last_error=Cannot copy "%_VUM_PATCH_PATH%\%_VUM_PATCH_CANARY_NAME%" to "%_VUM_TOOL_PATH%\": %ERRORLEVEL%
	goto endError
)

rem copy over inf file to do conditional copy
"%_VUM_XCOPY_EXE%" /y "%_VUM_PATCH_PATH%\%_VUM_PATCH_INF_NAME%" "%_VUM_TOOL_PATH%\"
if ERRORLEVEL 1 (
	set last_error=Cannot copy "%_VUM_PATCH_PATH%\%_VUM_PATCH_INF_NAME%" to "%_VUM_TOOL_PATH%\": %ERRORLEVEL%
	goto endError
)

call "%~dp0common" Copied patched files, running a conditional update

pushd "%_VUM_TOOL_PATH%"

rem let Windows figure out whether source.exe is newer and overwrite
rem need to use a .\ prefix and no quotes, otherwise things fail
"%_VUM_RUNDLL32_EXE%" setupapi.dll,InstallHinfSection DefaultInstall 128 .\%_VUM_PATCH_INF_NAME%
call "%~dp0common" result of rundll32 is %ERRORLEVEL%

popd

rem fc has errorlevel 1 if files are different, otherwise 0
"%_VUM_FC_EXE%" /b "%_VUM_TOOL_PATH%\vmwareUpdateManagerUtility.exe" "%_VUM_TOOL_PATH%\%_VUM_PATCH_CANARY_NAME%" > nul
if ERRORLEVEL 1 (
	call "%~dp0common" The patched and final files are different, using the product files
) else (
	call "%~dp0common" Patched and final files are the same, patching other unversioned files
	"%_VUM_XCOPY_EXE%" /y "%_VUM_PATCH_PATH%\%_VUM_TOOL_NAME%" "%_VUM_TOOL_PATH%\"
	if ERRORLEVEL 1 (
		set last_error=Cannot copy "%_VUM_PATCH_PATH%\%_VUM_TOOL_NAME%" to "%_VUM_TOOL_PATH%\": %ERRORLEVEL%
		goto endError
	)
)

if NOT EXIST "%_VUM_TOOL_FULL_PATH%" (
	set last_error=%_VUM_TOOL_NAME% is not present in the "%_VUM_TOOL_PATH%" directory.
	goto endError
)

call "%~dp0common" Testing vCenter Server credentials...
"%_VUM_TOOL_FULL_PATH%" %_VUM_TOOL_TRUST_ARGS% -O vccred > "%_VUM_LOG_PATH%\vum.trust.vccred.log"
rem returns 0 for success and 102 for bad login
if ERRORLEVEL 1 (
	set last_error=Cannot login to the vCenter using specified credentials: %ERRORLEVEL%. For details, see "%_VUM_LOG_PATH%\vum.trust.vccred.log"
	goto endError
)
call "%~dp0common" Successful login to vCenter using the specified credentials

:stopServices

call "%~dp0common" Stopping services

"%_VUM_SC_EXE%" stop vmware-ufad-vci > nul
"%_VUM_SC_EXE%" stop vmware-ufad-vci > nul
if ERRORLEVEL 1063 (
	call "%~dp0common" Failed to stop vSphere Update Manager: %ERRORLEVEL%
	goto stopUfa
)
if ERRORLEVEL 1062 (
	call "%~dp0common" vSphere Update Manager has not been started
	goto stopUfa
)
if ERRORLEVEL 1061 (
	call "%~dp0common" Need to wait to stop vSphere Update Manager
	"%_VUM_PING_EXE%" localhost > nul
	goto stopServices
)
if ERRORLEVEL 1 (
	call "%~dp0common" Failed to stop vSphere Update Manager: %ERRORLEVEL%
	goto stopUfa
)

:stopUfa
"%_VUM_SC_EXE%" stop vmware-vum-ufa > nul
"%_VUM_SC_EXE%" stop vmware-vum-ufa > nul
if ERRORLEVEL 1063 (
	call "%~dp0common" Failed to stop vSphere Update Manager UFA: %ERRORLEVEL%
	goto updateServices
)
if ERRORLEVEL 1062 (
	call "%~dp0common" vSphere Update Manager UFA has not been started
	goto updateServices
)
if ERRORLEVEL 1061 (
	call "%~dp0common" Need to wait to stop vSphere Update Manager UFA
	"%_VUM_PING_EXE%" localhost > nul
	goto stopUfa
)
if ERRORLEVEL 1 (
	call "%~dp0common" Failed to stop vSphere Update Manager UFA: %ERRORLEVEL%
	goto updateServices
)

:updateServices

call "%~dp0common" Updating vCenter Server trust

"%_VUM_TOOL_FULL_PATH%" %_VUM_TOOL_TRUST_ARGS% -S "%_VUM_CONFIG_PATH%\extension.xml" -I "%_VUM_CONFIG_PATH%" -O extupdate > "%_VUM_LOG_PATH%\vum.trustupdate.log"
rem returns 0 for success
if ERRORLEVEL 1 (
	set last_error=Cannot update the vCenter Server extension: %ERRORLEVEL%. For details, see "%_VUM_LOG_PATH%\vum.trustupdate.log"
	goto endErrorRestart
)

call "%~dp0common" vCenter Server trust was updated, Restarting Update service

"%_VUM_SC_EXE%" start vmware-ufad-vci > nul
if ERRORLEVEL 1 (
	call "%~dp0common" Failed to start vSphere Update Manager: %ERRORLEVEL%
)

call "%~dp0common" vSphere Update Manager start requested, script execution is complete

goto end

:ClearInfo

rem clear username and password info
set _VUM_TOOL_TRUST_ARGS=
exit /B 0

:GetVUMInstallDir
call "%~dp0common" GetVUMInstallDir called with "%1"
set _VUM_INSTALL_PATH=
for /F "tokens=1,2*" %%i in ('%_VUM_REG_EXE% query %1 /v "InstallPath"') DO (
	if "%%i"=="InstallPath" (
		SET "_VUM_INSTALL_PATH=%%k"
	)
)
exit /B 0

:GetVCServerName
call "%~dp0common" GetVCServerName called with "%1"
set _VUM_VC_ADDR=
for /F "tokens=1,2*" %%i in ('%_VUM_REG_EXE% query %1 /v "VCServer"') DO (
	if "%%i"=="VCServer" (
		SET "_VUM_VC_ADDR=%%k"
	)
)
exit /B 0

:GetVCServerPort
call "%~dp0common" GetVCServerPort called with "%1"
set _VUM_VC_PORT=
for /F "tokens=1,2*" %%i in ('%_VUM_REG_EXE% query %1 /v "VCServerPort"') DO (
	if "%%i"=="VCServerPort" (
		SET "_VUM_VC_PORT=%%k"
	)
)
exit /B 0

:end
call :ClearInfo
exit /B 0

:endErrorRestart

call "%~dp0common" Undo is starting the vSphere Update Manager service

"%_VUM_SC_EXE%" start vmware-ufad-vci > nul
if ERRORLEVEL 1 (
	call "%~dp0common" Failed to start vSphere Update Manager: %ERRORLEVEL%
	goto endError
)

:endError

call "%~dp0common" "%last_error%"

call :ClearInfo

exit /B 1

rem ---------------------------------------------

call "%~dp0common" Successfully updated the vSphere Update Manager trust to vCenter Server

call :ClearInfo
