@echo off
REM --------------------------------------------------------------------------
REM  "Kill processes" script for port numbers used in SVP Software
REM                 Copy right. 2017  Hitachi. Ltd.
REM
REM Argument :Waiting time[seconds] for services stop
REM
REM History  :DATE        :Coder       : Patch No
REM HM800    :2017.09.11  :Y.Numada    : #34821 new
REM --------------------------------------------------------------------------

setlocal enabledelayedexpansion

REM ==============================================
REM startup

set INSTALL_KEY=HKEY_LOCAL_MACHINE\SOFTWARE\HITACHI\HM_RAID
set INSTALL_KEY64=HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\HITACHI\HM_RAID
set INSTALL_VALUE_NAME=Install_Root

set FIND_SERVICE_BAT=%~dp0find_service.bat

set DEFAULT_SC_STOP_WAIT_TIME=180


set TMP_TXT=%~dp0%~n0.tmp
set SC_TXT=%~dp0%~n0_sc.tmp

set PORT_CNF_FILE_NAME=wk\supervisor\mappiniset\mpprt\cnf\mappsetportset.properties
set PORT_DYN_CNF_FILE_NAME=wk\supervisor\portmanager\cnf\MappPortNoManage.properties

set APPLIST=%~dp0applist.tmp

set DEFAULT_APPLIST=%~dp0applist.txt


set APPLIST2=%~dp0applist2.tmp


REM ----------------
mkdir %~dp0log > NUL 2>&1

REM ----------------
set mydate=%date:/=%
set mydate=%mydate: =%
set mydate=%mydate::=%
set mydate=%mydate:.=%

set mytime=%time:/=%
set mytime=%mytime: =%
set mytime=%mytime::=%
set mytime=%mytime:.=%

set LOG_FILE=%~dp0log\%~n0_%mydate%_%mytime%.log

REM ----------------
call :ClearTmp

REM ==============================================
REM main

call :Println "Start %0"

REM ----------------
call :CechkExecAdmin
if %ERRORLEVEL% neq 0 (
	call :Println "Error: It is not running as administrator."
	goto :AbnormalEnd
)

REM ----------------
set SC_STOP_WAIT_TIME=%1
if "%SC_STOP_WAIT_TIME%"=="" (
 set SC_STOP_WAIT_TIME=%DEFAULT_SC_STOP_WAIT_TIME%
)

if "%2"=="" (
	set TARGET_DIR=Unknown
)
if not "%2"=="" (
	set TARGET_DIR=%2
)

if !TARGET_DIR! ==Unknown (
	reg query %INSTALL_KEY% /v %INSTALL_VALUE_NAME%> %TMP_TXT% 2>&1
	for /f "delims=" %%A in ('type %TMP_TXT%') do (
		for /f "tokens=1,3" %%I in ("%%A") do (
			set value_name=%%I
			set value=%%J
			
			if !value_name! == %INSTALL_VALUE_NAME% (
				set TARGET_DIR=!value!
				goto :escape_loop1
			)
		)
	)
	reg query %INSTALL_KEY64% /v %INSTALL_VALUE_NAME%> %TMP_TXT% 2>&1
	for /f "delims=" %%A in ('type %TMP_TXT%') do (
		for /f "tokens=1,3" %%I in ("%%A") do (
			set value_name=%%I
			set value=%%J
			if !value_name! ==%INSTALL_VALUE_NAME% (
				set TARGET_DIR=!value!
				goto :escape_loop1
			)
		)
	)

:escape_loop1
	if !TARGET_DIR! == Unknown (
		call :Println "Cannot find SVP Software install directory."
		
		set /P TARGET_DIR="Enter SVP Software install directory : "
		call :Println_log "Enter SVP Software install directory : "
		call :Println "Enter: !TARGET_DIR!"
	)
)

REM ----------------
set PKILLFRAG=N
call :Println "This Program will kill processes that using port number for SVP(!TARGET_DIR!)."
set  /P PKILLFRAG="Enter(Y):Kill processes, Enter(N):Display just information : "
call :Println_log "Enter(Y):Kill processes, Enter(N):Display just information : "

call :Println "'%PKILLFRAG%' has been selected."

REM ----------------

REM ----------------

set PORT_CNF=!TARGET_DIR!\%PORT_CNF_FILE_NAME%
set PORT_DYN_CNF=!TARGET_DIR!\%PORT_DYN_CNF_FILE_NAME%

REM ----------------
if exist %PORT_CNF% (

	for /f "delims=" %%A in ('type %PORT_CNF%') do (
		echo %%A | findstr /R port\.setting\..*\.localport >nul 2>&1
		if !errorlevel! ==0 (
			for /f "delims== tokens=1,2" %%I in ("%%A") do (
				set name_tmp=%%I
				set value=%%J
			)
			echo !value!>> %APPLIST%
		)
	)
)
REM ----------------
if exist %PORT_DYN_CNF% (
	for /f "delims=" %%A in ('type %PORT_DYN_CNF%') do (
		call :IsComment %%A
		if !errorlevel! ==1 (
			for /f "delims== tokens=1,2" %%I in ("%%A") do (
				set key=%%I
				set value=%%J
				echo !value!>> %APPLIST%
			)
		)
	)
)


if not exist %PORT_CNF% (
	for /f "tokens=1" %%a in (%DEFAULT_APPLIST%) do (
		set targetPort=%%a
		call :IsComment %%a
		if !errorlevel! ==1 (
			echo !targetPort!>> %APPLIST%
		)
	)
)

REM ----------------
call :Println "Check the following port numbers."
for /f "tokens=1" %%a in (%APPLIST%) do (
	set targetPort=%%a
	call :Println "port=!targetPort!"
)

REM ----------------

type nul > %APPLIST2%

for /f "DELIMS=" %%A in ('netstat -ano') do (
	for /f "tokens=1,2,5" %%I in ("%%A") do (
		set protocol=%%I
		set pid=%%K
		call :GetPort %%J
		set port=!ERRORLEVEL!
		if "!protocol!"=="TCP" (
			for /f "tokens=1" %%a in (%APPLIST%) do (
				set targetPort=%%a
				if !port!==!targetPort! (
					if not !pid! ==0 (
						echo !targetPort!,!pid!>> %APPLIST2%
				)
			)
		)
	)
	)
)


REM ----------------
sc queryex > %SC_TXT%

call :Println "=== Check out result ==="

REM ----------------
call :Println "--- Services ---"

set /a exec_num=0
for /f "delims=" %%A in ('type %APPLIST2%') do (
	for /f "delims=, tokens=1,2" %%I in ("%%A") do (
		set port=%%I
		set pid=%%J
		call %FIND_SERVICE_BAT% !pid! "%SC_TXT%"
		
		if not !service_name! ==Unknown (
			call :DiplayOrStopService !port! !pid! "!service_name!"
			set /a exec_num=!exec_num!+1
		)
	)
)

if /i %PKILLFRAG%==Y (
	if /i not !exec_num!==0 (
		echo Wait for %SC_STOP_WAIT_TIME% seconds to stop services...
		timeout /T %SC_STOP_WAIT_TIME%  /NOBREAK
	)
)

REM ----------------
call :Println "--- Processes ---"

for /f "delims=" %%A in ('type %APPLIST2%') do (
	for /f "delims=, tokens=1,2" %%I in ("%%A") do (
		set port=%%I
		set pid=%%J
		call :DiplayOrKillProcess !port! !pid! 
	)
)

REM ----------------
:NormalEnd
call :GatheringInfo
call :ClearTmp
call :Println "Normal end  %0"
exit /b 0

REM ==============================================
:Println
set msg=%~1
echo %msg%
echo %msg%>> %LOG_FILE%
exit /b 0

REM ==============================================
:Println_log
set msg=%~1
echo %msg%>> %LOG_FILE%
exit /b 0

REM ==============================================
:CechkExecAdmin
for /f "tokens=1 delims=," %%i in ('whoami /groups /FO CSV /NH') do (
    if "%%~i"=="BUILTIN\Administrators" set ADMIN=yes
    if "%%~i"=="Mandatory Label\High Mandatory Level" set ELEVATED=yes
)
if "%ADMIN%" neq "yes" (
    exit /b 1
)
if "%ELEVATED%" neq "yes" (
    exit /b 1
)
exit /b 0

REM ==============================================
:GetPort
set str=%1
set rtn=-1
:LOOP
if "%str%"=="" (
	exit /B %rtn%
)
if "%str:~0,1%"==":" (
	set rtn=%str:~1%
)
set str=%str:~1%
goto :LOOP

REM ==============================================
:DiplayOrStopService

set port=%1
set pid=%2
set s_name=%~3

call :Println "port=%port% has been used by pid=%pid%, service=%s_name%"

if /i %PKILLFRAG%==Y (
	echo sc stop "%s_name%" > %TMP_TXT%
	sc stop "%s_name%" >> %TMP_TXT% 2>&1
	type %TMP_TXT%
	type %TMP_TXT%  >> %LOG_FILE%
)
exit /b 0

REM ==============================================
:DiplayOrKillProcess
set port=%1
set pid=%2

tasklist /fi "PID eq %pid%" /NH | find "%pid%">NUL
if %ERRORLEVEL%==0 (
	for /f "DELIMS=" %%A in ('tasklist /fi "PID eq %pid%" /NH') do set processInfo=%%A
	for /f "tokens=1" %%A in ("!processInfo!") do set pname=%%A
	
	call :Println "port=%port% has been used by pid=%pid%, !pname!"
	
	if /i %PKILLFRAG%==Y (
		echo taskkill /F /FI "PID eq %pid%" > %TMP_TXT%
		taskkill /F /FI "PID eq %pid%" >> %TMP_TXT% 2>&1
		type %TMP_TXT%
		type %TMP_TXT%  >> %LOG_FILE%
	)
)
exit /b 0

REM ==============================================
:IsComment
set str=%1
set top=%str:~0,1%

if %top% ==# (
  exit /b 0
)
exit /b 1


REM ==============================================
:GatheringInfo

call :Println_log "==============="
call :Println "Gathering Enviroment Information after execute..."
call :Println_log "--- Logging 'netstat -ano' ---"
netstat -ano >> %LOG_FILE%  2>&1

call :Println_log "--- Logging 'tasklist' ---"
tasklist  >> %LOG_FILE%  2>&1

exit /b 0


REM ==============================================
:ClearTmp

del /F /Q %TMP_TXT%  > NUL 2>&1
del /F /Q %SC_TXT%   > NUL 2>&1
del /F /Q %APPLIST%  > NUL 2>&1
del /F /Q %APPLIST2% > NUL 2>&1

exit /b 0

REM ==============================================
:AbnormalEnd
call :ClearTmp
call :Println "Abnormal end  %0"
exit /b 1

