#include "StdAfx.h"
#include "AddAuthorizedApp2.h"


/*!
	INetFwPolicy2が使えるかチェック
*/
bool CAddAuthorizedApp2::CanUse()
{
	CComPtr<INetFwPolicy2>	fwPolicy2;

	HRESULT hResult = ::CoCreateInstance((REFCLSID)CLSID_NetFwPolicy2, 0, CLSCTX_INPROC_SERVER, (REFIID)IID_INetFwPolicy2, (LPVOID*)&fwPolicy2);
	if(!SUCCEEDED(hResult))
	{
		TRACE("Can not use INetFwPolicy2\n");
		return FALSE;
	}

	TRACE("Can use INetFwPolicy2\n");
	return TRUE;
}


/*!
	Vista以降向け追加
*/
void CAddAuthorizedApp2::AddAppToFW(CString appName, CString appPath, CString description, bool setPublic)
{
	//	最初に削除
	DelAppFromFW(appName);

	//	INetFwPolicy2を取得
	CComPtr<INetFwPolicy2>	fwPolicy2;
	HRESULT hResult = ::CoCreateInstance((REFCLSID)CLSID_NetFwPolicy2, 0, CLSCTX_INPROC_SERVER, (REFIID)IID_INetFwPolicy2, (LPVOID*)&fwPolicy2);
	if(!SUCCEEDED(hResult))
		ThrowException(_T("INetFwPolicy2が取得できません"));

	//	ルールリスト取得
	CComPtr<INetFwRules>	existRules;
	hResult = fwPolicy2->get_Rules(&existRules);
	if(!SUCCEEDED(hResult))
		ThrowException(_T("INetFwRulesが取得できません"));

	//	ルール生成
	CComPtr<INetFwRule>	newRule;
	hResult = ::CoCreateInstance((REFCLSID)CLSID_NetFwRule, 0, CLSCTX_INPROC_SERVER, (REFIID)IID_INetFwRule, (LPVOID*)&newRule);
	if(!SUCCEEDED(hResult))
		ThrowException(_T("INetFwRuleが取得できません"));

	//	適応先
	long	profileBitmap = NET_FW_PROFILE2_DOMAIN | NET_FW_PROFILE2_PRIVATE;
	if(setPublic)
		profileBitmap = NET_FW_PROFILE2_ALL;

	//	ルールのプロパティを設定
	newRule->put_Name(_bstr_t(appName));
	newRule->put_Description(_bstr_t(description));
	newRule->put_ApplicationName(_bstr_t(appPath));
	newRule->put_Protocol(NET_FW_IP_PROTOCOL_TCP);
	newRule->put_Enabled(VARIANT_TRUE);
	newRule->put_Profiles(profileBitmap);
	newRule->put_Action(NET_FW_ACTION_ALLOW);

	//	登録
	hResult = existRules->Add(newRule);
	if(!SUCCEEDED(hResult))
		ThrowException(_T("ルールの登録に失敗しました"));
	TRACE("ルールを登録しました\n");
}

/*!
	Vista以降向け削除
*/
void CAddAuthorizedApp2::DelAppFromFW(CString appName)
{
	//	あるの？
	if(!RuleIsExist(appName))
		return;

	//	INetFwPolicy2を取得
	CComPtr<INetFwPolicy2>	fwPolicy2;
	HRESULT hResult = ::CoCreateInstance((REFCLSID)CLSID_NetFwPolicy2, 0, CLSCTX_INPROC_SERVER, (REFIID)IID_INetFwPolicy2, (LPVOID*)&fwPolicy2);
	if(!SUCCEEDED(hResult))
		ThrowException(_T("INetFwPolicy2が取得できません"));

	//	ルールリスト取得
	CComPtr<INetFwRules>	existRules;
	hResult = fwPolicy2->get_Rules(&existRules);
	if(!SUCCEEDED(hResult))
		ThrowException(_T("INetFwRulesが取得できません"));

	//	削除
	hResult = existRules->Remove(_bstr_t(appName));
	if(!SUCCEEDED(hResult))
		ThrowException(_T("ルールの削除に失敗しました"));
	TRACE("ルールを削除しました\n");
}


/*!
	Vista以降向け、存在チェック
*/
bool CAddAuthorizedApp2::RuleIsExist(CString appName)
{
	//	INetFwPolicy2を取得
	CComPtr<INetFwPolicy2>	fwPolicy2;
	HRESULT hResult = ::CoCreateInstance((REFCLSID)CLSID_NetFwPolicy2, 0, CLSCTX_INPROC_SERVER, (REFIID)IID_INetFwPolicy2, (LPVOID*)&fwPolicy2);
	if(!SUCCEEDED(hResult))
		ThrowException(_T("INetFwPolicy2が取得できません"));

	//	ルールリスト取得
	CComPtr<INetFwRules>	existRules;
	hResult = fwPolicy2->get_Rules(&existRules);
	if(!SUCCEEDED(hResult))
		ThrowException(_T("INetFwRulesが取得できません"));

	//	アプリのルール取得
	CComPtr<INetFwRule>		appRule;
    hResult = existRules->Item(_bstr_t(appName), &appRule);
	if(!SUCCEEDED(hResult))
		return FALSE;
	return TRUE;
}


/*!
	エラーを投げる
*/
void CAddAuthorizedApp2::ThrowException(CString errorInfo)
{
	TRACE(_T("Error : %s\n"), errorInfo);
	throw CAddAuthorizedAppException(errorInfo);
}
