|
@@ -0,0 +1,941 @@
|
|
|
+#include "CWindowsFireWall.h"
|
|
|
+
|
|
|
+
|
|
|
+#include <crtdbg.h>
|
|
|
+#include <objbase.h>
|
|
|
+#include <oleauto.h>
|
|
|
+#include <stdio.h>
|
|
|
+#include <tlhelp32.h>
|
|
|
+#include <Psapi.h>
|
|
|
+#include <strsafe.h>
|
|
|
+#include <QStringList>
|
|
|
+#include <QDebug>
|
|
|
+#include <QFileInfo>
|
|
|
+#include <QSettings>
|
|
|
+#include <comutil.h>
|
|
|
+#include <atlcomcli.h>
|
|
|
+#include<QDateTime>
|
|
|
+#include "logproc.h"
|
|
|
+
|
|
|
+#pragma comment( lib, "ole32.lib" )
|
|
|
+#pragma comment( lib, "oleaut32.lib" )
|
|
|
+
|
|
|
+std::shared_ptr<CWindowsFireWall> g_windowsFireWallPtr = nullptr;
|
|
|
+
|
|
|
+#define STRING_BUFFER_SIZE 500
|
|
|
+
|
|
|
+
|
|
|
+BOOL EnableDebugPrivilege()
|
|
|
+{
|
|
|
+ HANDLE hToken;
|
|
|
+ BOOL fOk = FALSE;
|
|
|
+ if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
|
|
|
+ {
|
|
|
+ TOKEN_PRIVILEGES tp;
|
|
|
+ tp.PrivilegeCount = 1;
|
|
|
+ LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
|
|
|
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
|
+ AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
|
|
|
+ fOk = (GetLastError() == ERROR_SUCCESS);
|
|
|
+ CloseHandle(hToken);
|
|
|
+ }
|
|
|
+ return fOk;
|
|
|
+}
|
|
|
+
|
|
|
+CWindowsFireWall::CWindowsFireWall(DWORD pid, bool bcheck) : m_pid(pid), m_bcheck(bcheck)
|
|
|
+{
|
|
|
+ EnableDebugPrivilege();
|
|
|
+
|
|
|
+ QFileInfo file("coe.cfgi");
|
|
|
+ QString sFilePath = file.absoluteFilePath();
|
|
|
+ QSettings set(sFilePath, QSettings::IniFormat);
|
|
|
+ m_bModifyFireWall = set.value("wallConfig/ModifyWall", false).toBool();
|
|
|
+ m_fw_profile2_domain_enabled = set.value("wallConfig/profile2_domain_enabled", VARIANT_TRUE).toInt();
|
|
|
+ m_fw_profile2_private_enabled = set.value("wallConfig/profile2_private_enabled", VARIANT_TRUE).toInt();
|
|
|
+ m_fw_profile2_public_enabled = set.value("wallConfig/profile2_public_enabled", VARIANT_TRUE).toInt();
|
|
|
+
|
|
|
+ init();
|
|
|
+
|
|
|
+ if(bcheck)
|
|
|
+ {
|
|
|
+ m_pThrd = new std::thread(std::bind(&CWindowsFireWall::threadProc, this));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+CWindowsFireWall::~CWindowsFireWall()
|
|
|
+{
|
|
|
+ m_bIsRun = false;
|
|
|
+ if(m_bcheck)
|
|
|
+ {
|
|
|
+ m_pThrd->join();
|
|
|
+ cleanup();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CWindowsFireWall::threadProc()
|
|
|
+{
|
|
|
+ setWallOn();
|
|
|
+ removeLastRules();
|
|
|
+ setAllRulesEnabled(VARIANT_FALSE);
|
|
|
+
|
|
|
+ disableAllApp();
|
|
|
+ __int64 nLastTime = QDateTime::currentDateTime().toSecsSinceEpoch();
|
|
|
+
|
|
|
+ while(m_bIsRun)
|
|
|
+ {
|
|
|
+ __int64 nCurrentTime = QDateTime::currentDateTime().toSecsSinceEpoch();
|
|
|
+ if(nCurrentTime - nLastTime > m_inprogressCheckSeconds)
|
|
|
+ {
|
|
|
+ nLastTime = nCurrentTime;
|
|
|
+ checkInprogressFireWall();
|
|
|
+ }
|
|
|
+ Sleep(100);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CWindowsFireWall::checkInprogressFireWall()
|
|
|
+{
|
|
|
+ //检测防火墙是否开启
|
|
|
+ HRESULT hr;
|
|
|
+
|
|
|
+ VARIANT_BOOL fw_profile2_domain_enabled = VARIANT_FALSE;
|
|
|
+ VARIANT_BOOL fw_profile2_private_enabled = VARIANT_FALSE;
|
|
|
+ VARIANT_BOOL fw_profile2_public_enabled = VARIANT_FALSE;
|
|
|
+ hr = m_pNetFwPolicy2->get_FirewallEnabled(NET_FW_PROFILE2_DOMAIN, &fw_profile2_domain_enabled);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("put_FirewallEnabled failed for Domain: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ myServerLog()<<m_sErrMsg;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = m_pNetFwPolicy2->get_FirewallEnabled(NET_FW_PROFILE2_PRIVATE, &fw_profile2_private_enabled);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("put_FirewallEnabled failed for private: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ myServerLog()<<m_sErrMsg;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = m_pNetFwPolicy2->get_FirewallEnabled(NET_FW_PROFILE2_PUBLIC, &fw_profile2_public_enabled);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("put_FirewallEnabled failed for public: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ myServerLog()<<m_sErrMsg;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(fw_profile2_domain_enabled != VARIANT_TRUE ||
|
|
|
+ fw_profile2_private_enabled != VARIANT_TRUE ||
|
|
|
+ fw_profile2_public_enabled != VARIANT_TRUE)
|
|
|
+ {
|
|
|
+ myServerLog()<<QString::fromLocal8Bit("考试中防火墙被关闭 ")<<",fw_profile2_domain_enabled:"<<fw_profile2_domain_enabled
|
|
|
+ <<",fw_profile2_private_enabled:"<<fw_profile2_private_enabled
|
|
|
+ <<",fw_profile2_public_enabled:"<<fw_profile2_public_enabled;
|
|
|
+ setWallOn();
|
|
|
+ }
|
|
|
+
|
|
|
+ //遍历进程
|
|
|
+ checkRulesIsEnabled();
|
|
|
+
|
|
|
+ disableAllApp();
|
|
|
+}
|
|
|
+
|
|
|
+void CWindowsFireWall::checkRulesIsEnabled()
|
|
|
+{
|
|
|
+ HRESULT hr = S_OK;
|
|
|
+ CComVariant var;
|
|
|
+ ULONG cFetched = 0;
|
|
|
+ IUnknown *pEnumerator;
|
|
|
+ IEnumVARIANT* pVariant = NULL;
|
|
|
+ INetFwRules *pFwRules = NULL;
|
|
|
+ INetFwRule *pFwRule = NULL;
|
|
|
+
|
|
|
+ long fwRuleCount;
|
|
|
+
|
|
|
+ // Retrieve INetFwRules
|
|
|
+ hr = m_pNetFwPolicy2->get_Rules(&pFwRules);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ wprintf(L"get_Rules failed: 0x%08lx\n", hr);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Obtain the number of Firewall rules
|
|
|
+ hr = pFwRules->get_Count(&fwRuleCount);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ wprintf(L"get_Count failed: 0x%08lx\n", hr);
|
|
|
+ }
|
|
|
+
|
|
|
+ wprintf(L"The number of rules in the Windows Firewall are %d\n", fwRuleCount);
|
|
|
+
|
|
|
+ // Iterate through all of the rules in pFwRules
|
|
|
+ pFwRules->get__NewEnum(&pEnumerator);
|
|
|
+
|
|
|
+ if(pEnumerator)
|
|
|
+ {
|
|
|
+ hr = pEnumerator->QueryInterface(__uuidof(IEnumVARIANT), (void **) &pVariant);
|
|
|
+ }
|
|
|
+
|
|
|
+ while(SUCCEEDED(hr) && hr != S_FALSE)
|
|
|
+ {
|
|
|
+ var.Clear();
|
|
|
+ hr = pVariant->Next(1, &var, &cFetched);
|
|
|
+
|
|
|
+ if (S_FALSE != hr)
|
|
|
+ {
|
|
|
+ if (SUCCEEDED(hr))
|
|
|
+ {
|
|
|
+ hr = var.ChangeType(VT_DISPATCH);
|
|
|
+ }
|
|
|
+ if (SUCCEEDED(hr))
|
|
|
+ {
|
|
|
+ hr = (V_DISPATCH(&var))->QueryInterface(__uuidof(INetFwRule), reinterpret_cast<void**>(&pFwRule));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (SUCCEEDED(hr))
|
|
|
+ {
|
|
|
+ BSTR szRuleName;
|
|
|
+ pFwRule->get_Name(&szRuleName);
|
|
|
+ QString sRuleName = QString::fromStdWString(szRuleName);
|
|
|
+ VARIANT_BOOL bEnable = VARIANT_FALSE;
|
|
|
+ pFwRule->put_Enabled(bEnable);
|
|
|
+ if(sRuleName.startsWith("disable_coe_"))
|
|
|
+ {
|
|
|
+ if(bEnable == VARIANT_FALSE)
|
|
|
+ {
|
|
|
+ pFwRule->put_Enabled(VARIANT_TRUE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(bEnable == VARIANT_TRUE)
|
|
|
+ {
|
|
|
+ pFwRule->put_Enabled(VARIANT_FALSE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Release pFwRule
|
|
|
+ if (pFwRule != NULL)
|
|
|
+ {
|
|
|
+ pFwRule->Release();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(pFwRules != NULL)
|
|
|
+ {
|
|
|
+ pFwRules->Release();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CWindowsFireWall::uploadAppLog(std::vector<CProcessData> &vAppList)
|
|
|
+{
|
|
|
+ QStringList appList;
|
|
|
+ for(CProcessData data : vAppList)
|
|
|
+ {
|
|
|
+ appList << QString::fromStdWString(data.sExeName);
|
|
|
+ }
|
|
|
+ myServerLog()<<appList.join(",");
|
|
|
+}
|
|
|
+// Instantiate INetFwPolicy2
|
|
|
+HRESULT CWindowsFireWall::WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2)
|
|
|
+{
|
|
|
+ HRESULT hr = S_OK;
|
|
|
+
|
|
|
+ hr = CoCreateInstance(
|
|
|
+ __uuidof(NetFwPolicy2),
|
|
|
+ NULL,
|
|
|
+ CLSCTX_INPROC_SERVER,
|
|
|
+ __uuidof(INetFwPolicy2),
|
|
|
+ (void**)ppNetFwPolicy2);
|
|
|
+
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("CoCreateInstance for INetFwPolicy2 failed: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return hr;
|
|
|
+}
|
|
|
+
|
|
|
+bool CWindowsFireWall::init()
|
|
|
+{
|
|
|
+ HRESULT hr = S_OK;
|
|
|
+
|
|
|
+ // Initialize COM.
|
|
|
+ m_comInit = CoInitializeEx(
|
|
|
+ 0,
|
|
|
+ COINIT_APARTMENTTHREADED
|
|
|
+ );
|
|
|
+
|
|
|
+ // Ignore RPC_E_CHANGED_MODE; this just means that COM has already been
|
|
|
+ // initialized with a different mode. Since we don't care what the mode is,
|
|
|
+ // we'll just use the existing mode.
|
|
|
+ if (m_comInit != RPC_E_CHANGED_MODE)
|
|
|
+ {
|
|
|
+ if (FAILED(m_comInit))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("CoInitializeEx for INetFwPolicy2 failed: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Retrieve INetFwPolicy2
|
|
|
+ hr = WFCOMInitialize(&m_pNetFwPolicy2);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+void CWindowsFireWall::cleanup()
|
|
|
+{
|
|
|
+ if(m_vDisableRuleNames.size() > 0)
|
|
|
+ {
|
|
|
+ INetFwRules *pNetFwRules = NULL;
|
|
|
+ HRESULT hr = m_pNetFwPolicy2->get_Rules(&pNetFwRules);
|
|
|
+ if (SUCCEEDED(hr))
|
|
|
+ {
|
|
|
+ for(std::wstring sRuleName: m_vDisableRuleNames)
|
|
|
+ {
|
|
|
+ pNetFwRules->Remove(const_cast<BSTR>(sRuleName.c_str()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ setAllRulesEnabled(VARIANT_TRUE);
|
|
|
+
|
|
|
+ if(m_bModifyFireWall)
|
|
|
+ {
|
|
|
+ HRESULT hr = m_pNetFwPolicy2->put_FirewallEnabled(NET_FW_PROFILE2_DOMAIN, m_fw_profile2_domain_enabled);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("put_FirewallEnabled failed for Domain: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = m_pNetFwPolicy2->put_FirewallEnabled(NET_FW_PROFILE2_PRIVATE, m_fw_profile2_private_enabled);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("put_FirewallEnabled failed for Private: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = m_pNetFwPolicy2->put_FirewallEnabled(NET_FW_PROFILE2_PUBLIC, m_fw_profile2_public_enabled);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("put_FirewallEnabled failed for Public: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ }
|
|
|
+
|
|
|
+ m_bModifyFireWall = false;
|
|
|
+ m_fw_profile2_domain_enabled = VARIANT_TRUE;
|
|
|
+ m_fw_profile2_private_enabled = VARIANT_TRUE;
|
|
|
+ m_fw_profile2_public_enabled = VARIANT_TRUE;
|
|
|
+ QFileInfo file("coe.cfgi");
|
|
|
+ QString sFilePath = file.absoluteFilePath();
|
|
|
+ QSettings set(sFilePath, QSettings::IniFormat);
|
|
|
+ set.setValue("wallConfig/ModifyWall", m_bModifyFireWall);
|
|
|
+ set.setValue("wallConfig/profile2_domain_enabled", m_fw_profile2_domain_enabled);
|
|
|
+ set.setValue("wallConfig/profile2_private_enabled", m_fw_profile2_private_enabled);
|
|
|
+ set.setValue("wallConfig/profile2_public_enabled", m_fw_profile2_public_enabled);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (m_pNetFwPolicy2 != NULL)
|
|
|
+ {
|
|
|
+ m_pNetFwPolicy2->Release();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (SUCCEEDED(m_comInit))
|
|
|
+ {
|
|
|
+ CoUninitialize();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool CWindowsFireWall::setWallOn()
|
|
|
+{
|
|
|
+ HRESULT hr;
|
|
|
+ if(!m_bModifyFireWall)
|
|
|
+ {
|
|
|
+ hr = m_pNetFwPolicy2->get_FirewallEnabled(NET_FW_PROFILE2_DOMAIN, &m_fw_profile2_domain_enabled);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("put_FirewallEnabled failed for Domain: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = m_pNetFwPolicy2->get_FirewallEnabled(NET_FW_PROFILE2_PRIVATE, &m_fw_profile2_private_enabled);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("put_FirewallEnabled failed for private: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = m_pNetFwPolicy2->get_FirewallEnabled(NET_FW_PROFILE2_PUBLIC, &m_fw_profile2_public_enabled);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("put_FirewallEnabled failed for public: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = m_pNetFwPolicy2->put_FirewallEnabled(NET_FW_PROFILE2_DOMAIN, TRUE);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("put_FirewallEnabled failed for Domain: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = m_pNetFwPolicy2->put_FirewallEnabled(NET_FW_PROFILE2_PRIVATE, TRUE);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("put_FirewallEnabled failed for Private: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = m_pNetFwPolicy2->put_FirewallEnabled(NET_FW_PROFILE2_PUBLIC, TRUE);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("put_FirewallEnabled failed for Public: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(m_fw_profile2_domain_enabled != VARIANT_TRUE ||
|
|
|
+ m_fw_profile2_private_enabled != VARIANT_TRUE ||
|
|
|
+ m_fw_profile2_public_enabled != VARIANT_TRUE )
|
|
|
+ {
|
|
|
+ m_bModifyFireWall = true;
|
|
|
+ QFileInfo file("coe.cfgi");
|
|
|
+ QString sFilePath = file.absoluteFilePath();
|
|
|
+ QSettings set(sFilePath, QSettings::IniFormat);
|
|
|
+ set.setValue("wallConfig/ModifyWall", m_bModifyFireWall);
|
|
|
+ set.setValue("wallConfig/profile2_domain_enabled", m_fw_profile2_domain_enabled);
|
|
|
+ set.setValue("wallConfig/profile2_private_enabled", m_fw_profile2_private_enabled);
|
|
|
+ set.setValue("wallConfig/profile2_public_enabled", m_fw_profile2_public_enabled);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+void CWindowsFireWall::setAllRulesEnabled(VARIANT_BOOL bEnable)
|
|
|
+{
|
|
|
+ HRESULT hr = S_OK;
|
|
|
+ CComVariant var;
|
|
|
+ ULONG cFetched = 0;
|
|
|
+ IUnknown *pEnumerator;
|
|
|
+ IEnumVARIANT* pVariant = NULL;
|
|
|
+ INetFwRules *pFwRules = NULL;
|
|
|
+ INetFwRule *pFwRule = NULL;
|
|
|
+
|
|
|
+ long fwRuleCount;
|
|
|
+
|
|
|
+ // Retrieve INetFwRules
|
|
|
+ hr = m_pNetFwPolicy2->get_Rules(&pFwRules);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ wprintf(L"get_Rules failed: 0x%08lx\n", hr);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Obtain the number of Firewall rules
|
|
|
+ hr = pFwRules->get_Count(&fwRuleCount);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ wprintf(L"get_Count failed: 0x%08lx\n", hr);
|
|
|
+ }
|
|
|
+
|
|
|
+ wprintf(L"The number of rules in the Windows Firewall are %d\n", fwRuleCount);
|
|
|
+
|
|
|
+ // Iterate through all of the rules in pFwRules
|
|
|
+ pFwRules->get__NewEnum(&pEnumerator);
|
|
|
+
|
|
|
+ if(pEnumerator)
|
|
|
+ {
|
|
|
+ hr = pEnumerator->QueryInterface(__uuidof(IEnumVARIANT), (void **) &pVariant);
|
|
|
+ }
|
|
|
+
|
|
|
+ while(SUCCEEDED(hr) && hr != S_FALSE)
|
|
|
+ {
|
|
|
+ var.Clear();
|
|
|
+ hr = pVariant->Next(1, &var, &cFetched);
|
|
|
+
|
|
|
+ if (S_FALSE != hr)
|
|
|
+ {
|
|
|
+ if (SUCCEEDED(hr))
|
|
|
+ {
|
|
|
+ hr = var.ChangeType(VT_DISPATCH);
|
|
|
+ }
|
|
|
+ if (SUCCEEDED(hr))
|
|
|
+ {
|
|
|
+ hr = (V_DISPATCH(&var))->QueryInterface(__uuidof(INetFwRule), reinterpret_cast<void**>(&pFwRule));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (SUCCEEDED(hr))
|
|
|
+ {
|
|
|
+ // Output the properties of this rule
|
|
|
+ // DumpFWRulesInCollection(pFwRule);
|
|
|
+ pFwRule->put_Enabled(bEnable);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Release pFwRule
|
|
|
+ if (pFwRule != NULL)
|
|
|
+ {
|
|
|
+ pFwRule->Release();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(pFwRules != NULL)
|
|
|
+ {
|
|
|
+ pFwRules->Release();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CWindowsFireWall::removeLastRules()
|
|
|
+{
|
|
|
+ HRESULT hr = S_OK;
|
|
|
+ CComVariant var;
|
|
|
+ ULONG cFetched = 0;
|
|
|
+ IUnknown *pEnumerator;
|
|
|
+ IEnumVARIANT* pVariant = NULL;
|
|
|
+ INetFwRules *pFwRules = NULL;
|
|
|
+ INetFwRule *pFwRule = NULL;
|
|
|
+
|
|
|
+ long fwRuleCount;
|
|
|
+
|
|
|
+ // Retrieve INetFwRules
|
|
|
+ hr = m_pNetFwPolicy2->get_Rules(&pFwRules);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ wprintf(L"get_Rules failed: 0x%08lx\n", hr);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Obtain the number of Firewall rules
|
|
|
+ hr = pFwRules->get_Count(&fwRuleCount);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ wprintf(L"get_Count failed: 0x%08lx\n", hr);
|
|
|
+ }
|
|
|
+
|
|
|
+ wprintf(L"The number of rules in the Windows Firewall are %d\n", fwRuleCount);
|
|
|
+
|
|
|
+ // Iterate through all of the rules in pFwRules
|
|
|
+ pFwRules->get__NewEnum(&pEnumerator);
|
|
|
+
|
|
|
+ if(pEnumerator)
|
|
|
+ {
|
|
|
+ hr = pEnumerator->QueryInterface(__uuidof(IEnumVARIANT), (void **) &pVariant);
|
|
|
+ }
|
|
|
+
|
|
|
+ QStringList RuleNamelist;
|
|
|
+
|
|
|
+ while(SUCCEEDED(hr) && hr != S_FALSE)
|
|
|
+ {
|
|
|
+ var.Clear();
|
|
|
+ hr = pVariant->Next(1, &var, &cFetched);
|
|
|
+
|
|
|
+ if (S_FALSE != hr)
|
|
|
+ {
|
|
|
+ if (SUCCEEDED(hr))
|
|
|
+ {
|
|
|
+ hr = var.ChangeType(VT_DISPATCH);
|
|
|
+ }
|
|
|
+ if (SUCCEEDED(hr))
|
|
|
+ {
|
|
|
+ hr = (V_DISPATCH(&var))->QueryInterface(__uuidof(INetFwRule), reinterpret_cast<void**>(&pFwRule));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (SUCCEEDED(hr))
|
|
|
+ {
|
|
|
+ // Output the properties of this rule
|
|
|
+ // DumpFWRulesInCollection(pFwRule);
|
|
|
+ BSTR szRuleName;
|
|
|
+ pFwRule->get_Name(&szRuleName);
|
|
|
+ QString sRuleName = QString::fromStdWString(szRuleName);
|
|
|
+ if(sRuleName.startsWith("disable_coe_"))
|
|
|
+ {
|
|
|
+ RuleNamelist<<sRuleName;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ for(QString &sRuleName : RuleNamelist)
|
|
|
+ {
|
|
|
+ std::wstring sName = sRuleName.toStdWString();
|
|
|
+ pFwRules->Remove(const_cast<BSTR>(sName.c_str()));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Release pFwRule
|
|
|
+ if (pFwRule != NULL)
|
|
|
+ {
|
|
|
+ pFwRule->Release();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(pFwRules != NULL)
|
|
|
+ {
|
|
|
+ pFwRules->Release();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool CWindowsFireWall::disableAllApp()
|
|
|
+{
|
|
|
+ HRESULT hr = S_OK;
|
|
|
+
|
|
|
+ std::vector<CProcessData> vAppList;
|
|
|
+ if(getAllAppNameList(vAppList))
|
|
|
+ {
|
|
|
+ uploadAppLog(vAppList);
|
|
|
+ }
|
|
|
+
|
|
|
+ INetFwRules *pNetFwRules = NULL;
|
|
|
+ hr = m_pNetFwPolicy2->get_Rules(&pNetFwRules);
|
|
|
+
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed to retrieve firewall rules collection : 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ }
|
|
|
+
|
|
|
+ for(CProcessData &data : vAppList)
|
|
|
+ {
|
|
|
+ if(data.bDisabled)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool bSucceed = true;
|
|
|
+
|
|
|
+ INetFwRule *pNetFwRule = NULL;
|
|
|
+ INetFwRule2 *pNetFwRule2 = NULL;
|
|
|
+
|
|
|
+ WCHAR pwszTemp[STRING_BUFFER_SIZE] = L"";
|
|
|
+
|
|
|
+ BSTR RuleName = NULL;
|
|
|
+ BSTR RuleGroupName = NULL;
|
|
|
+ BSTR RuleDescription = NULL;
|
|
|
+ BSTR RuleAppPath = NULL;
|
|
|
+
|
|
|
+ hr = StringCchPrintfW(pwszTemp, STRING_BUFFER_SIZE, (L"disable_coe_" + data.sExeName).c_str());
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed to compose a resource identifier string: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ RuleName = SysAllocString(pwszTemp);
|
|
|
+ if (NULL == RuleName)
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("ERROR: Insufficient memory");
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = StringCchPrintfW(pwszTemp, STRING_BUFFER_SIZE, L"coe");
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed to compose a resource identifier string: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+ RuleGroupName = SysAllocString(pwszTemp); // Used for grouping together multiple rules
|
|
|
+ if (NULL == RuleGroupName)
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("ERROR: Insufficient memory");
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = StringCchPrintfW(pwszTemp, STRING_BUFFER_SIZE, (L"disable " + data.sExeName).c_str());
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed to compose a resource identifier string: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+ RuleDescription = SysAllocString(pwszTemp);
|
|
|
+ if (NULL == RuleDescription)
|
|
|
+ {
|
|
|
+ m_sErrMsg = "ERROR: Insufficient memory";
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ RuleAppPath = SysAllocString(data.sExePath.c_str());
|
|
|
+ if (NULL == RuleAppPath)
|
|
|
+ {
|
|
|
+ m_sErrMsg = "ERROR: Insufficient memory";
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+// hr = m_pNetFwPolicy2->get_Rules(&pNetFwRules);
|
|
|
+
|
|
|
+// if (FAILED(hr))
|
|
|
+// {
|
|
|
+// m_sErrMsg = QString("Failed to retrieve firewall rules collection : 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+// bSucceed = false;
|
|
|
+// }
|
|
|
+
|
|
|
+ hr = CoCreateInstance(
|
|
|
+ __uuidof(NetFwRule), //CLSID of the class whose object is to be created
|
|
|
+ NULL,
|
|
|
+ CLSCTX_INPROC_SERVER,
|
|
|
+ __uuidof(INetFwRule), // Identifier of the Interface used for communicating with the object
|
|
|
+ (void**)&pNetFwRule);
|
|
|
+
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("CoCreateInstance for INetFwRule failed: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ hr = pNetFwRule->put_Name(RuleName);
|
|
|
+ if ( FAILED(hr) )
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed INetFwRule::put_Name failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = pNetFwRule->put_Grouping(RuleGroupName);
|
|
|
+ if ( FAILED(hr) )
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed INetFwRule::put_Grouping failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = pNetFwRule->put_Description(RuleDescription);
|
|
|
+ if ( FAILED(hr) )
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed INetFwRule::put_Description failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = pNetFwRule->put_Direction(NET_FW_RULE_DIR_OUT);
|
|
|
+ if ( FAILED(hr) )
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed INetFwRule::put_Direction failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = pNetFwRule->put_Action(NET_FW_ACTION_BLOCK);
|
|
|
+ if ( FAILED(hr) )
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed INetFwRule::put_Action failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = pNetFwRule->put_ApplicationName(RuleAppPath);
|
|
|
+ if ( FAILED(hr) )
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed INetFwRule::put_ApplicationName failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = pNetFwRule->put_Profiles(NET_FW_PROFILE2_DOMAIN | NET_FW_PROFILE2_PRIVATE | NET_FW_PROFILE2_PUBLIC);
|
|
|
+ if ( FAILED(hr) )
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed INetFwRule::put_Profiles failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = pNetFwRule->put_Enabled(VARIANT_TRUE);
|
|
|
+ if ( FAILED(hr) )
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed INetFwRule::put_Enabled failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // Check if INetFwRule2 interface is available (i.e Windows7+)
|
|
|
+ // If supported, then use EdgeTraversalOptions
|
|
|
+ // Else use the EdgeTraversal boolean flag.
|
|
|
+
|
|
|
+ if (SUCCEEDED(pNetFwRule->QueryInterface(__uuidof(INetFwRule2), (void**)&pNetFwRule2)))
|
|
|
+ {
|
|
|
+ hr = pNetFwRule2->put_EdgeTraversalOptions(NET_FW_EDGE_TRAVERSAL_TYPE_DENY);
|
|
|
+ if ( FAILED(hr) )
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed INetFwRule::put_EdgeTraversalOptions failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ hr = pNetFwRule->put_EdgeTraversal(VARIANT_FALSE);
|
|
|
+ if ( FAILED(hr) )
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed INetFwRule::put_EdgeTraversal failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ hr = pNetFwRules->Add(pNetFwRule);
|
|
|
+ if (FAILED(hr))
|
|
|
+ {
|
|
|
+ m_sErrMsg = QString("Failed to add firewall rule to the firewall rules collection: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
|
|
|
+ bSucceed = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(bSucceed)
|
|
|
+ {
|
|
|
+ data.bDisabled = true;
|
|
|
+ m_vDisableRuleNames.push_back(RuleName);
|
|
|
+ qDebug()<<QString::fromStdWString(RuleName);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ qDebug()<<RuleName<<":"<<m_sErrMsg;
|
|
|
+ }
|
|
|
+
|
|
|
+ SysFreeString(RuleName);
|
|
|
+ SysFreeString(RuleGroupName);
|
|
|
+ SysFreeString(RuleDescription);
|
|
|
+ SysFreeString(RuleAppPath);
|
|
|
+
|
|
|
+ if (pNetFwRule2 != NULL)
|
|
|
+ {
|
|
|
+ pNetFwRule2->Release();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pNetFwRule != NULL)
|
|
|
+ {
|
|
|
+ pNetFwRule->Release();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pNetFwRules != NULL)
|
|
|
+ {
|
|
|
+ pNetFwRules->Release();
|
|
|
+ }
|
|
|
+
|
|
|
+ return hr;
|
|
|
+}
|
|
|
+
|
|
|
+std::wstring GetPathByProcessID(DWORD pid)
|
|
|
+{
|
|
|
+ HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
|
|
|
+ if (!hProcess)
|
|
|
+ {
|
|
|
+ return L"";
|
|
|
+ }
|
|
|
+ WCHAR filePath[MAX_PATH];
|
|
|
+ DWORD ret = GetModuleFileNameEx(hProcess, NULL, filePath, MAX_PATH) ;
|
|
|
+
|
|
|
+ CloseHandle(hProcess);
|
|
|
+ return ret == 0 ? L"" : filePath;
|
|
|
+}
|
|
|
+
|
|
|
+// dos 文件路径转 windows 文件路径
|
|
|
+BOOL DosPathToNtPath(LPTSTR pszDosPath, LPTSTR pszNtPath)
|
|
|
+{
|
|
|
+ TCHAR szDriveStr[500];
|
|
|
+ TCHAR szDrive[3];
|
|
|
+ TCHAR szDevName[100];
|
|
|
+ INT cchDevName;
|
|
|
+ INT i;
|
|
|
+
|
|
|
+ //检查参数
|
|
|
+ if(!pszDosPath || !pszNtPath )
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ //获取本地磁盘字符串
|
|
|
+ if(GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr))
|
|
|
+ {
|
|
|
+ for(i = 0; szDriveStr[i]; i += 4)
|
|
|
+ {
|
|
|
+ if(!lstrcmpi(&(szDriveStr[i]), _T("A:\\")) || !lstrcmpi(&(szDriveStr[i]), _T("B:\\"))){continue;}
|
|
|
+
|
|
|
+ szDrive[0] = szDriveStr[i];
|
|
|
+ szDrive[1] = szDriveStr[i + 1];
|
|
|
+ szDrive[2] = '\0';
|
|
|
+ // 查询 Dos 设备名
|
|
|
+ if(!QueryDosDevice(szDrive, szDevName, 100)){return FALSE;}
|
|
|
+
|
|
|
+ // 命中
|
|
|
+ cchDevName = lstrlen(szDevName);
|
|
|
+ if(_tcsnicmp(pszDosPath, szDevName, cchDevName) == 0){
|
|
|
+ // 复制驱动器
|
|
|
+ lstrcpy(pszNtPath, szDrive);
|
|
|
+
|
|
|
+ // 复制路径
|
|
|
+ lstrcat(pszNtPath, pszDosPath + cchDevName);
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ lstrcpy(pszNtPath, pszDosPath);
|
|
|
+
|
|
|
+ return FALSE;
|
|
|
+}
|
|
|
+
|
|
|
+// 获取进程全路径
|
|
|
+BOOL GetProcessFullPath(DWORD dwPID, std::wstring &fullPath){
|
|
|
+ TCHAR szImagePath[MAX_PATH]={'\0'};
|
|
|
+ TCHAR pszFullPath[MAX_PATH]={'\0'};
|
|
|
+ HANDLE hProcess;
|
|
|
+
|
|
|
+
|
|
|
+ // 获取进程句柄失败
|
|
|
+ hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwPID);
|
|
|
+ if(!hProcess){return FALSE;}
|
|
|
+
|
|
|
+ // 获取进程完整路径失败
|
|
|
+ if(!GetProcessImageFileName(
|
|
|
+ hProcess, // 进程句柄
|
|
|
+ szImagePath, // 接收进程所属文件全路径的指针
|
|
|
+ MAX_PATH // 缓冲区大小
|
|
|
+ )){
|
|
|
+ CloseHandle(hProcess);
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 路径转换失败
|
|
|
+ if(!DosPathToNtPath(szImagePath, pszFullPath)){
|
|
|
+ CloseHandle(hProcess);
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseHandle(hProcess);
|
|
|
+
|
|
|
+ // 导出文件全路径
|
|
|
+ fullPath = pszFullPath;
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+}
|
|
|
+
|
|
|
+bool CWindowsFireWall::getAllAppNameList(std::vector<CProcessData> &vAppList)
|
|
|
+{
|
|
|
+ bool bRet = false;
|
|
|
+ PROCESSENTRY32 pe32;
|
|
|
+ pe32.dwSize = sizeof(pe32);
|
|
|
+ HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
+ if(hProcessSnap == INVALID_HANDLE_VALUE)
|
|
|
+ {
|
|
|
+ return bRet;
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL bMore = Process32First(hProcessSnap,&pe32);
|
|
|
+ QStringList list;
|
|
|
+ while(bMore)
|
|
|
+ {
|
|
|
+ std::wstring sExePath = L"";
|
|
|
+ GetProcessFullPath( pe32.th32ProcessID, sExePath);
|
|
|
+ QString sPath = QString::fromStdWString(sExePath).toLower();
|
|
|
+
|
|
|
+ if(pe32.th32ProcessID != m_pid &&
|
|
|
+ !sExePath.empty() &&
|
|
|
+// sPath.indexOf("c:\\windows\\system32") < 0 &&
|
|
|
+ sPath.toLower().indexOf("svchost.exe") < 0 &&
|
|
|
+// sPath.toLower().indexOf("upgrade") < 0 &&
|
|
|
+ list.indexOf(QString::fromStdWString(pe32.szExeFile).toLower()) < 0)
|
|
|
+ {
|
|
|
+ list<<QString::fromStdWString(pe32.szExeFile).toLower();
|
|
|
+ CProcessData data;
|
|
|
+ data.pid = pe32.th32ProcessID;
|
|
|
+ data.sExeName = pe32.szExeFile;
|
|
|
+ data.sExePath = sExePath;
|
|
|
+
|
|
|
+ vAppList.push_back(data);
|
|
|
+ bRet = true;
|
|
|
+ }
|
|
|
+ bMore = Process32Next(hProcessSnap,&pe32);
|
|
|
+ }
|
|
|
+ CloseHandle(hProcessSnap);
|
|
|
+ return bRet;
|
|
|
+}
|
|
|
+
|