【HSP3】MPEG2RepairProxy(仮Ver0.01)

MPEG2Repair.exeをバッジ処理するためのプロキシソフト 不具合多し

MPEG2Repair.exeをバッジ処理するためのプロキシソフト 不具合多し

#include "kernel32.as"
#include "user32.as"
#uselib "shlwapi"
#cfunc global PathFileExists "PathFileExistsA" str
#packopt name "MPEG2RepairProxy"
// コンソールにしない場合はCONSOLEMODEをコメントアウトしてください
#define CONSOLEMODE
#ifdef CONSOLEMODE
#runtime "hsp3cl"
#define ERRORMSG mes
#define LOGMSG mes
#else
#packopt hide 1
#define ERRORMSG dialog
#define LOGMSG logmes
#endif

#module
#deffunc GetWindowList var list, int _max
	if _max == 0 : max = 4096 : else : max = _max
	VirtualAlloc 0, 12*4, 0x2000/*MEM_RESERVE*/, 0x40/*PAGE_EXECUTE_READWRITE*/
	VirtualAlloc stat, 12*4, 0x1000/*MEM_COMMIT*/, 0x40/*PAGE_EXECUTE_READWRITE*/
	pbm = stat
	dupptr bm, pbm, 12*4, 4
	bm.0 = $0824448b, $8b08488b, $ca3b0450, $c033057c, $8b0008c2, $748b5610
	bm.6 = $34890824, $08488b8a, $48895e41, $0001b808, $08c20000, $00000000
	dim list, max
	ENUMWND_DATA = varptr(list), max, 0
	EnumWindows pbm, varptr(ENUMWND_DATA)
	dim bm
	VirtualFree pbm, 12*4, 0x4000 /*MEM_DECOMMIT*/
	VirtualFree pbm, 0, 0x8000 /*MEM_RELEASE*/
return
#global
#module
#defcfunc exec2 str _cmd, var pid, int showmode
	pid = -1
	cmd = _cmd
	; STARTUPINFO構造体を設定
	dim stinfo, 17
	stinfo.0 = 68         ; 構造体サイズ(cbメンバ)
	stinfo.11 = 1//STARTF_USESHOWWINDOW
	
	stinfo.12 = showmode & 0xFFFF
	; PROCESS_INFOMATION構造体を設定
	dim prinfo, 4
	
	; 新しいプロセスを起動
	CreateProcess 0,varptr(cmd),0,0,0,0,0,0,varptr(stinfo),varptr(prinfo)
	if (stat == 0) : return 0
	hProcess = prinfo.0       ; プロセスのハンドル
	hThread = prinfo.1        ; プライマリスレッドのハンドル
	pid = prinfo.2
	; プライマリスレッドのハンドルは直ちにクローズ
	CloseHandle hThread
	hThread = 0
	
return hProcess
#global

*main
	// コマンドライン保存
	cl = dir_cmdline + " "
	// test
	;cl = "-input \"D:\\DummyTs\\ -output -hide -errorlog ☆ Duumy01あれれれれ.ts\" -output -errorlog -hide -minimize"
	;cl = "-input \"D:\\DummyTs\\Duumy01.ts\" -output -overwrite -minimize"
	
	m_hide = 0
	m_minimize = 0
	m_overwrite = 0
	sdim m_input : m_input_f = 0
	sdim m_output : m_output_f = 0
	sdim m_errorlog : m_errorlog_f = 0

	mode = 0
	p = 0
	repeat strlen(cl)
		sdim m
		// 現在位置の1文字取得
		tmp = strmid(cl, p, 1)
		if tmp == "-"{
			mode = 1
		}else : if tmp == "\""{
			mode = 2
		}else{
			mode = 0
		}
	
		if mode == 0{
			
		}
		if mode == 1{
			i = p
			repeat strlen(cl)-p
				tmp2 = strmid(cl, i, 1)
				// コレの場合は文字列取得し抜ける
				if tmp2 == " " | tmp2 == "\"" : m = strmid(cl, p, i-p) : p = i : break
				// 最終桁到達の場合とりあえずとってみる
				if cnt == (strlen(cl) - p) - 1 : m = strmid(cl, p, i-p+1) : p = i : break
				i++
			loop
			// -input,-output,-errorlogは続きを取らないといけない(強制はinputのみ)のでモード変更し続行する
			if m == "-input"{
				m_input_f = 1
				mode = 2
			}else : if m == "-output"{
				m_output_f = 1
				mode = 2
			}else : if m == "-errorlog"{
				m_errorlog_f = 1
				mode = 2
			}else : if m == ""{
				// 該当しない場合
			}else : if m == "-hide"{
				m_hide = 1
			}else : if m == "-minimize"{
				m_minimize = 1
			}else : if m == "-overwrite"{
				m_overwrite = 1
			}
		}
		
		if mode == 2{
			i = p
			sp = -1 : ep = -1
			repeat strlen(cl)-p
				tmp2 = strmid(cl, i, 1)
				// コレの場合は文字列取得し抜ける
				if tmp2 == "\"" {
					mode_dq = 1
					if sp == -1 : sp = i : i++ : continue
					if ep == -1 : ep = i : i++ : break
				}
				i++
			loop
			// 取得できた場合
			if sp != -1 && ep != -1 {
				p = i	// 読み進める
				tmp2 = strmid(cl, sp + 1, ep - sp - 1)
				if m == "-input"{
					m_input = tmp2
				}else : if m == "-output"{
					m_output = tmp2
				}else : if m == "-errorlog"{
					m_errorlog = tmp2
				}
				
			}
			
		}
		
		p++
	loop
	
	// チェック
	if m_input == "" {
		ERRORMSG "ERROR:引数が不正です。-input がありません。" : end
	}
	if m_output_f == 0{
		ERRORMSG "ERROR:引数が不正です。-output がありません。" : end
	}
	
	// 2GB以上のファイルに対応するため、existは使わない
	if PathFileExists(m_input) == 0{
		ERRORMSG "ERROR:入力ファイルが存在しません。\n"+m_input : end
	}
	
	// MPEG2Repair.exeを探す
	if PathFileExists("./MPEG2Repair/MPEG2Repair.exe") == 0{
		ERRORMSG "ERROR:MPEG2Repair.exeが存在しません。 ./MPEG2Repair/MPEG2Repair.exe" : end
	}
	
	// 起動する
	hProcess = exec2("./MPEG2Repair/MPEG2Repair.exe", pID, 0)
	if hProcess == 0{
		ERRORMSG "ERROR:MPEG2Repair.exe の起動に失敗しました。" : end
	}
	
	// 起動を待つ
	WaitForInputIdle hProcess, 0xFFFFFFFF/*INFINITE*/
	
	// 60回ほど検索を繰り返す(約1分)
	repeat 60
		wait 100
		// ウィンドウを列挙する
		GetWindowList list, 4096 : hMain = 0 : c_pID = 0
		repeat length(list)
			GetWindowThreadProcessId list(cnt), varptr(c_pID)
			if c_pID == pID : hMain = list(cnt) : break
		loop
		if hMain != 0 : break
		LOGMSG "WAIT:ウィンドウの検索中... 試行回数("+(cnt+1)+"/60)"
	loop
	
	if hMain == 0 {
		ERRORMSG "ERROR:ウィンドウの検索に失敗しました。" 
		TerminateProcess hProcess, 0
		end
	}
	
	// 最小化が有効の場合
	if m_minimize == 1{
		ShowWindow hMain, 6
	}else : if m_hide == 1{
		// 隠すモード(動作しない様子)
	}else{
		// ノーマルモード
		ShowWindow hMain, 4
	}
	
	sleep 500
	
	// ウィンドウがMPEG2Repairかどうか?
	sdim name, 256 : sdim class, 256
	GetClassNameA hMain, varptr(class), 256
	GetWindowTextA hMain, varptr(name), 256
	
	if class != "#32770" || name != "MPEG2Repair"{
		ERRORMSG "ERROR:MPEG2Repairではないようです。操作に失敗しました。"
		TerminateProcess hProcess, 0
		end
	}
	
	// 1番目のエディトボックスを取得
	FindWindowEx hMain, 0, "Edit", 0
	hEdit = stat
	hStatic = stat
	if hEdit == 0 {
		ERRORMSG "ERROR:MPEG2Repairの操作に失敗しました。(Editが見つかりません)" 
		TerminateProcess hProcess, 0
		end
	}
	// 反映させる
	;SetWindowTextA hEdit, varptr(m_input)	// 別プロセスだと使えないので↓
	SendMessageA hEdit, 0x000C, 0, varptr(m_input)

	// スタティックを取得
	FindWindowEx hMain, 0, "Static", "0 % Complete"
	hStatic = stat
	if hStatic == 0 {
		ERRORMSG "ERROR:MPEG2Repairの操作に失敗しました。(Staticが見つかりません)" 
		TerminateProcess hProcess, 0
		end
	}

	// Find PID's を取得(ボタン)
	hButton = 0
	repeat 60
		wait 100
		FindWindowEx hMain, 0, "Button", "Find PID's"
		hButton = stat
		if hButton != 0 : break
		LOGMSG "WAIT:ボタンの検索中... 試行回数("+(cnt+1)+"/60)"
	loop
	if hButton == 0 {
		ERRORMSG "ERROR:MPEG2Repairの操作に失敗しました。(Buttonが見つかりません)" 
		TerminateProcess hProcess, 0
		end
	}
	// ボタンを押す
	SendMessageA hButton, 0x00F5, 0, 0
	
	// パーセントを調査する
	repeat 60
		wait 100
		sdim string, 256
		GetWindowTextA hStatic, varptr(string), 256
		if instr(string, 0, "100 % Completed.") != -1 : break
		LOGMSG "WAIT:PID解析待機中... 試行回数("+(cnt+1)+"/60)"
	loop
	if instr(string, 0, "100 % Completed.") == -1 {
		ERRORMSG "ERROR:MPEG2Repairの操作に失敗しました。PID解析に失敗しました。" 
		TerminateProcess hProcess, 0
		end
	}
	
	// Repair Errosを取得
	FindWindowEx hMain, 0, "Button", "Repair Errors"
	hButton2 = stat
	if hButton2 == 0 {
		ERRORMSG "ERROR:MPEG2Repairの操作に失敗しました。(Buttonが見つかりません)" 
		TerminateProcess hProcess, 0
		end
	}
	// ボタンを押す
	SendMessageA hButton2, 0x00F5, 0, 0
	
	sleep 500
	
	if m_output != ""{
		//2番目のエディトボックスを取得
		FindWindowEx hMain, hEdit, "Edit", 0
		hEdit2 = stat
		if hEdit2 == 0 {
			ERRORMSG "ERROR:MPEG2Repairの操作に失敗しました。(Editが見つかりません)" 
			TerminateProcess hProcess, 0
			end
		}
		// 反映
		SendMessageA hEdit2, 0x000C, 0, varptr(m_output)
		
	}
	
	
	// エラーログ機能が有効な場合
	if m_errorlog_f == 1{
		// Log Errosを取得
		FindWindowEx hMain, 0, "Button", "Log Errors"
		hButton3 = stat
		if hButton3 == 0 {
			ERRORMSG "ERROR:MPEG2Repairの操作に失敗しました。(Buttonが見つかりません)" 
			TerminateProcess hProcess, 0
			end
		}
		// ボタンを押す
		SendMessageA hButton3, 0x00F5, 0, 0
	
		sleep 500
		
		//3番目のエディトボックスを取得
		FindWindowEx hMain, hEdit2, "Edit", 0
		hEdit3 = stat
		if hEdit3 == 0 {
			ERRORMSG "ERROR:MPEG2Repairの操作に失敗しました。(Editが見つかりません)" 
			TerminateProcess hProcess, 0
			end
		}
		// 反映
		SendMessageA hEdit3, 0x000C, 0, varptr(m_errorlog)
		
	}
	
	// ボタンを押して処理を開始する
	SendMessageA hButton, 0x00F5, 0, 0
	f = 0
	repeat
		// 状態表示
		sdim string, 256
		GetWindowTextA hStatic, varptr(string), 256
		LOGMSG string
		
		// ウィンドウの検索
		GetWindowList list, 4096
		repeat length(list)
			sdim class, 256 : sdim name, 256 : c_pid = 0
			GetClassNameA list.cnt, varptr(class), 256
			GetWindowTextA list.cnt, varptr(name), 256
			GetWindowThreadProcessId list.cnt, varptr(c_pid)
	
			// 上書き確認のダイアログ検出
			if m_overwrite == 1{
				if class == "#32770" && name == "Warning:" && c_pid == pID{
					// 本当にOverWriteかチェックする
					hDialog = list.cnt
					hDialog2 = list.cnt
					repeat
						FindWindowEx hDialog, 0, "Static", 0
						hDialog = stat
						if hDialog == 0 : break
						sdim static_string, 256
						GetWindowTextA hDialog, varptr(static_string), 256
						// オーバーライト画面を確認できた場合
						if instr(static_string, 0, "Overwrite it?") != -1 {
							FindWindowEx hDialog2, 0, "Button", 0
							SendMessageA stat, 0x00F5, 0, 0
							break
						}
					loop
					
				}
			}
			// 完了ダイアログの検出
			if class == "#32770" && name == "Status:" && c_pid == pID{
				// 完了ボタンを押す
				FindWindowEx list.cnt, 0, "Button", 0
				SendMessageA stat, 0x00F5, 0, 0
				f = 1
				break
			}
		loop
		if f == 1 : break
		//
		wait 100
	loop
	TerminateProcess hProcess, 0
	LOGMSG "SUCCEED:処理が完了しました。"
end