CWindowsFireWall.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. #include "CWindowsFireWall.h"
  2. #include <crtdbg.h>
  3. #include <objbase.h>
  4. #include <oleauto.h>
  5. #include <stdio.h>
  6. #include <tlhelp32.h>
  7. #include <Psapi.h>
  8. #include <strsafe.h>
  9. #include <QStringList>
  10. #include <QDebug>
  11. #include <QFileInfo>
  12. #include <QSettings>
  13. #include <comutil.h>
  14. #include <atlcomcli.h>
  15. #include<QDateTime>
  16. #include "logproc.h"
  17. #pragma comment( lib, "ole32.lib" )
  18. #pragma comment( lib, "oleaut32.lib" )
  19. std::shared_ptr<CWindowsFireWall> g_windowsFireWallPtr = nullptr;
  20. #define STRING_BUFFER_SIZE 500
  21. BOOL EnableDebugPrivilege()
  22. {
  23. HANDLE hToken;
  24. BOOL fOk = FALSE;
  25. if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
  26. {
  27. TOKEN_PRIVILEGES tp;
  28. tp.PrivilegeCount = 1;
  29. LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
  30. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  31. AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
  32. fOk = (GetLastError() == ERROR_SUCCESS);
  33. CloseHandle(hToken);
  34. }
  35. return fOk;
  36. }
  37. CWindowsFireWall::CWindowsFireWall(DWORD pid, bool bcheck) : m_pid(pid), m_bcheck(bcheck)
  38. {
  39. EnableDebugPrivilege();
  40. QFileInfo file("coe.cfgi");
  41. QString sFilePath = file.absoluteFilePath();
  42. QSettings set(sFilePath, QSettings::IniFormat);
  43. m_bModifyFireWall = set.value("wallConfig/ModifyWall", false).toBool();
  44. m_fw_profile2_domain_enabled = set.value("wallConfig/profile2_domain_enabled", VARIANT_TRUE).toInt();
  45. m_fw_profile2_private_enabled = set.value("wallConfig/profile2_private_enabled", VARIANT_TRUE).toInt();
  46. m_fw_profile2_public_enabled = set.value("wallConfig/profile2_public_enabled", VARIANT_TRUE).toInt();
  47. init();
  48. if(bcheck)
  49. {
  50. m_pThrd = new std::thread(std::bind(&CWindowsFireWall::threadProc, this));
  51. }
  52. }
  53. CWindowsFireWall::~CWindowsFireWall()
  54. {
  55. m_bIsRun = false;
  56. if(m_bcheck)
  57. {
  58. m_pThrd->join();
  59. cleanup();
  60. }
  61. }
  62. void CWindowsFireWall::threadProc()
  63. {
  64. setWallOn();
  65. removeLastRules();
  66. setAllRulesEnabled(VARIANT_FALSE);
  67. disableAllApp();
  68. __int64 nLastTime = QDateTime::currentDateTime().toSecsSinceEpoch();
  69. while(m_bIsRun)
  70. {
  71. __int64 nCurrentTime = QDateTime::currentDateTime().toSecsSinceEpoch();
  72. if(nCurrentTime - nLastTime > m_inprogressCheckSeconds)
  73. {
  74. nLastTime = nCurrentTime;
  75. checkInprogressFireWall();
  76. }
  77. Sleep(100);
  78. }
  79. }
  80. void CWindowsFireWall::checkInprogressFireWall()
  81. {
  82. //检测防火墙是否开启
  83. HRESULT hr;
  84. VARIANT_BOOL fw_profile2_domain_enabled = VARIANT_FALSE;
  85. VARIANT_BOOL fw_profile2_private_enabled = VARIANT_FALSE;
  86. VARIANT_BOOL fw_profile2_public_enabled = VARIANT_FALSE;
  87. hr = m_pNetFwPolicy2->get_FirewallEnabled(NET_FW_PROFILE2_DOMAIN, &fw_profile2_domain_enabled);
  88. if (FAILED(hr))
  89. {
  90. m_sErrMsg = QString("put_FirewallEnabled failed for Domain: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  91. myServerLog()<<m_sErrMsg;
  92. }
  93. hr = m_pNetFwPolicy2->get_FirewallEnabled(NET_FW_PROFILE2_PRIVATE, &fw_profile2_private_enabled);
  94. if (FAILED(hr))
  95. {
  96. m_sErrMsg = QString("put_FirewallEnabled failed for private: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  97. myServerLog()<<m_sErrMsg;
  98. }
  99. hr = m_pNetFwPolicy2->get_FirewallEnabled(NET_FW_PROFILE2_PUBLIC, &fw_profile2_public_enabled);
  100. if (FAILED(hr))
  101. {
  102. m_sErrMsg = QString("put_FirewallEnabled failed for public: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  103. myServerLog()<<m_sErrMsg;
  104. }
  105. if(fw_profile2_domain_enabled != VARIANT_TRUE ||
  106. fw_profile2_private_enabled != VARIANT_TRUE ||
  107. fw_profile2_public_enabled != VARIANT_TRUE)
  108. {
  109. myServerLog()<<QString::fromLocal8Bit("考试中防火墙被关闭 ")<<",fw_profile2_domain_enabled:"<<fw_profile2_domain_enabled
  110. <<",fw_profile2_private_enabled:"<<fw_profile2_private_enabled
  111. <<",fw_profile2_public_enabled:"<<fw_profile2_public_enabled;
  112. setWallOn();
  113. }
  114. //遍历进程
  115. checkRulesIsEnabled();
  116. disableAllApp();
  117. }
  118. void CWindowsFireWall::checkRulesIsEnabled()
  119. {
  120. HRESULT hr = S_OK;
  121. CComVariant var;
  122. ULONG cFetched = 0;
  123. IUnknown *pEnumerator;
  124. IEnumVARIANT* pVariant = NULL;
  125. INetFwRules *pFwRules = NULL;
  126. INetFwRule *pFwRule = NULL;
  127. long fwRuleCount;
  128. // Retrieve INetFwRules
  129. hr = m_pNetFwPolicy2->get_Rules(&pFwRules);
  130. if (FAILED(hr))
  131. {
  132. wprintf(L"get_Rules failed: 0x%08lx\n", hr);
  133. }
  134. // Obtain the number of Firewall rules
  135. hr = pFwRules->get_Count(&fwRuleCount);
  136. if (FAILED(hr))
  137. {
  138. wprintf(L"get_Count failed: 0x%08lx\n", hr);
  139. }
  140. wprintf(L"The number of rules in the Windows Firewall are %d\n", fwRuleCount);
  141. // Iterate through all of the rules in pFwRules
  142. pFwRules->get__NewEnum(&pEnumerator);
  143. if(pEnumerator)
  144. {
  145. hr = pEnumerator->QueryInterface(__uuidof(IEnumVARIANT), (void **) &pVariant);
  146. }
  147. while(SUCCEEDED(hr) && hr != S_FALSE)
  148. {
  149. var.Clear();
  150. hr = pVariant->Next(1, &var, &cFetched);
  151. if (S_FALSE != hr)
  152. {
  153. if (SUCCEEDED(hr))
  154. {
  155. hr = var.ChangeType(VT_DISPATCH);
  156. }
  157. if (SUCCEEDED(hr))
  158. {
  159. hr = (V_DISPATCH(&var))->QueryInterface(__uuidof(INetFwRule), reinterpret_cast<void**>(&pFwRule));
  160. }
  161. if (SUCCEEDED(hr))
  162. {
  163. BSTR szRuleName;
  164. pFwRule->get_Name(&szRuleName);
  165. QString sRuleName = QString::fromStdWString(szRuleName);
  166. VARIANT_BOOL bEnable = VARIANT_FALSE;
  167. pFwRule->put_Enabled(bEnable);
  168. if(sRuleName.startsWith("disable_coe_"))
  169. {
  170. if(bEnable == VARIANT_FALSE)
  171. {
  172. pFwRule->put_Enabled(VARIANT_TRUE);
  173. }
  174. }
  175. else
  176. {
  177. if(bEnable == VARIANT_TRUE)
  178. {
  179. pFwRule->put_Enabled(VARIANT_FALSE);
  180. }
  181. }
  182. }
  183. }
  184. }
  185. // Release pFwRule
  186. if (pFwRule != NULL)
  187. {
  188. pFwRule->Release();
  189. }
  190. if(pFwRules != NULL)
  191. {
  192. pFwRules->Release();
  193. }
  194. }
  195. void CWindowsFireWall::uploadAppLog(std::vector<CProcessData> &vAppList)
  196. {
  197. QStringList appList;
  198. for(CProcessData data : vAppList)
  199. {
  200. appList << QString::fromStdWString(data.sExeName);
  201. }
  202. myServerLog()<<appList.join(",");
  203. }
  204. // Instantiate INetFwPolicy2
  205. HRESULT CWindowsFireWall::WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2)
  206. {
  207. HRESULT hr = S_OK;
  208. hr = CoCreateInstance(
  209. __uuidof(NetFwPolicy2),
  210. NULL,
  211. CLSCTX_INPROC_SERVER,
  212. __uuidof(INetFwPolicy2),
  213. (void**)ppNetFwPolicy2);
  214. if (FAILED(hr))
  215. {
  216. m_sErrMsg = QString("CoCreateInstance for INetFwPolicy2 failed: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  217. }
  218. return hr;
  219. }
  220. bool CWindowsFireWall::init()
  221. {
  222. HRESULT hr = S_OK;
  223. // Initialize COM.
  224. m_comInit = CoInitializeEx(
  225. 0,
  226. COINIT_APARTMENTTHREADED
  227. );
  228. // Ignore RPC_E_CHANGED_MODE; this just means that COM has already been
  229. // initialized with a different mode. Since we don't care what the mode is,
  230. // we'll just use the existing mode.
  231. if (m_comInit != RPC_E_CHANGED_MODE)
  232. {
  233. if (FAILED(m_comInit))
  234. {
  235. m_sErrMsg = QString("CoInitializeEx for INetFwPolicy2 failed: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  236. return false;
  237. }
  238. }
  239. // Retrieve INetFwPolicy2
  240. hr = WFCOMInitialize(&m_pNetFwPolicy2);
  241. if (FAILED(hr))
  242. {
  243. return false;
  244. }
  245. return true;
  246. }
  247. void CWindowsFireWall::cleanup()
  248. {
  249. if(m_vDisableRuleNames.size() > 0)
  250. {
  251. INetFwRules *pNetFwRules = NULL;
  252. HRESULT hr = m_pNetFwPolicy2->get_Rules(&pNetFwRules);
  253. if (SUCCEEDED(hr))
  254. {
  255. for(std::wstring sRuleName: m_vDisableRuleNames)
  256. {
  257. pNetFwRules->Remove(const_cast<BSTR>(sRuleName.c_str()));
  258. }
  259. }
  260. }
  261. setAllRulesEnabled(VARIANT_TRUE);
  262. if(m_bModifyFireWall)
  263. {
  264. HRESULT hr = m_pNetFwPolicy2->put_FirewallEnabled(NET_FW_PROFILE2_DOMAIN, m_fw_profile2_domain_enabled);
  265. if (FAILED(hr))
  266. {
  267. m_sErrMsg = QString("put_FirewallEnabled failed for Domain: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  268. }
  269. hr = m_pNetFwPolicy2->put_FirewallEnabled(NET_FW_PROFILE2_PRIVATE, m_fw_profile2_private_enabled);
  270. if (FAILED(hr))
  271. {
  272. m_sErrMsg = QString("put_FirewallEnabled failed for Private: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  273. }
  274. hr = m_pNetFwPolicy2->put_FirewallEnabled(NET_FW_PROFILE2_PUBLIC, m_fw_profile2_public_enabled);
  275. if (FAILED(hr))
  276. {
  277. m_sErrMsg = QString("put_FirewallEnabled failed for Public: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  278. }
  279. m_bModifyFireWall = false;
  280. m_fw_profile2_domain_enabled = VARIANT_TRUE;
  281. m_fw_profile2_private_enabled = VARIANT_TRUE;
  282. m_fw_profile2_public_enabled = VARIANT_TRUE;
  283. QFileInfo file("coe.cfgi");
  284. QString sFilePath = file.absoluteFilePath();
  285. QSettings set(sFilePath, QSettings::IniFormat);
  286. set.setValue("wallConfig/ModifyWall", m_bModifyFireWall);
  287. set.setValue("wallConfig/profile2_domain_enabled", m_fw_profile2_domain_enabled);
  288. set.setValue("wallConfig/profile2_private_enabled", m_fw_profile2_private_enabled);
  289. set.setValue("wallConfig/profile2_public_enabled", m_fw_profile2_public_enabled);
  290. }
  291. if (m_pNetFwPolicy2 != NULL)
  292. {
  293. m_pNetFwPolicy2->Release();
  294. }
  295. if (SUCCEEDED(m_comInit))
  296. {
  297. CoUninitialize();
  298. }
  299. }
  300. bool CWindowsFireWall::setWallOn()
  301. {
  302. HRESULT hr;
  303. if(!m_bModifyFireWall)
  304. {
  305. hr = m_pNetFwPolicy2->get_FirewallEnabled(NET_FW_PROFILE2_DOMAIN, &m_fw_profile2_domain_enabled);
  306. if (FAILED(hr))
  307. {
  308. m_sErrMsg = QString("put_FirewallEnabled failed for Domain: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  309. return false;
  310. }
  311. hr = m_pNetFwPolicy2->get_FirewallEnabled(NET_FW_PROFILE2_PRIVATE, &m_fw_profile2_private_enabled);
  312. if (FAILED(hr))
  313. {
  314. m_sErrMsg = QString("put_FirewallEnabled failed for private: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  315. return false;
  316. }
  317. hr = m_pNetFwPolicy2->get_FirewallEnabled(NET_FW_PROFILE2_PUBLIC, &m_fw_profile2_public_enabled);
  318. if (FAILED(hr))
  319. {
  320. m_sErrMsg = QString("put_FirewallEnabled failed for public: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  321. return false;
  322. }
  323. }
  324. hr = m_pNetFwPolicy2->put_FirewallEnabled(NET_FW_PROFILE2_DOMAIN, TRUE);
  325. if (FAILED(hr))
  326. {
  327. m_sErrMsg = QString("put_FirewallEnabled failed for Domain: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  328. return false;
  329. }
  330. hr = m_pNetFwPolicy2->put_FirewallEnabled(NET_FW_PROFILE2_PRIVATE, TRUE);
  331. if (FAILED(hr))
  332. {
  333. m_sErrMsg = QString("put_FirewallEnabled failed for Private: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  334. return false;
  335. }
  336. hr = m_pNetFwPolicy2->put_FirewallEnabled(NET_FW_PROFILE2_PUBLIC, TRUE);
  337. if (FAILED(hr))
  338. {
  339. m_sErrMsg = QString("put_FirewallEnabled failed for Public: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  340. return false;
  341. }
  342. if(m_fw_profile2_domain_enabled != VARIANT_TRUE ||
  343. m_fw_profile2_private_enabled != VARIANT_TRUE ||
  344. m_fw_profile2_public_enabled != VARIANT_TRUE )
  345. {
  346. m_bModifyFireWall = true;
  347. QFileInfo file("coe.cfgi");
  348. QString sFilePath = file.absoluteFilePath();
  349. QSettings set(sFilePath, QSettings::IniFormat);
  350. set.setValue("wallConfig/ModifyWall", m_bModifyFireWall);
  351. set.setValue("wallConfig/profile2_domain_enabled", m_fw_profile2_domain_enabled);
  352. set.setValue("wallConfig/profile2_private_enabled", m_fw_profile2_private_enabled);
  353. set.setValue("wallConfig/profile2_public_enabled", m_fw_profile2_public_enabled);
  354. }
  355. return true;
  356. }
  357. void CWindowsFireWall::setAllRulesEnabled(VARIANT_BOOL bEnable)
  358. {
  359. HRESULT hr = S_OK;
  360. CComVariant var;
  361. ULONG cFetched = 0;
  362. IUnknown *pEnumerator;
  363. IEnumVARIANT* pVariant = NULL;
  364. INetFwRules *pFwRules = NULL;
  365. INetFwRule *pFwRule = NULL;
  366. long fwRuleCount;
  367. // Retrieve INetFwRules
  368. hr = m_pNetFwPolicy2->get_Rules(&pFwRules);
  369. if (FAILED(hr))
  370. {
  371. wprintf(L"get_Rules failed: 0x%08lx\n", hr);
  372. }
  373. // Obtain the number of Firewall rules
  374. hr = pFwRules->get_Count(&fwRuleCount);
  375. if (FAILED(hr))
  376. {
  377. wprintf(L"get_Count failed: 0x%08lx\n", hr);
  378. }
  379. wprintf(L"The number of rules in the Windows Firewall are %d\n", fwRuleCount);
  380. // Iterate through all of the rules in pFwRules
  381. pFwRules->get__NewEnum(&pEnumerator);
  382. if(pEnumerator)
  383. {
  384. hr = pEnumerator->QueryInterface(__uuidof(IEnumVARIANT), (void **) &pVariant);
  385. }
  386. while(SUCCEEDED(hr) && hr != S_FALSE)
  387. {
  388. var.Clear();
  389. hr = pVariant->Next(1, &var, &cFetched);
  390. if (S_FALSE != hr)
  391. {
  392. if (SUCCEEDED(hr))
  393. {
  394. hr = var.ChangeType(VT_DISPATCH);
  395. }
  396. if (SUCCEEDED(hr))
  397. {
  398. hr = (V_DISPATCH(&var))->QueryInterface(__uuidof(INetFwRule), reinterpret_cast<void**>(&pFwRule));
  399. }
  400. if (SUCCEEDED(hr))
  401. {
  402. // Output the properties of this rule
  403. // DumpFWRulesInCollection(pFwRule);
  404. pFwRule->put_Enabled(bEnable);
  405. }
  406. }
  407. }
  408. // Release pFwRule
  409. if (pFwRule != NULL)
  410. {
  411. pFwRule->Release();
  412. }
  413. if(pFwRules != NULL)
  414. {
  415. pFwRules->Release();
  416. }
  417. }
  418. void CWindowsFireWall::removeLastRules()
  419. {
  420. HRESULT hr = S_OK;
  421. CComVariant var;
  422. ULONG cFetched = 0;
  423. IUnknown *pEnumerator;
  424. IEnumVARIANT* pVariant = NULL;
  425. INetFwRules *pFwRules = NULL;
  426. INetFwRule *pFwRule = NULL;
  427. long fwRuleCount;
  428. // Retrieve INetFwRules
  429. hr = m_pNetFwPolicy2->get_Rules(&pFwRules);
  430. if (FAILED(hr))
  431. {
  432. wprintf(L"get_Rules failed: 0x%08lx\n", hr);
  433. }
  434. // Obtain the number of Firewall rules
  435. hr = pFwRules->get_Count(&fwRuleCount);
  436. if (FAILED(hr))
  437. {
  438. wprintf(L"get_Count failed: 0x%08lx\n", hr);
  439. }
  440. wprintf(L"The number of rules in the Windows Firewall are %d\n", fwRuleCount);
  441. // Iterate through all of the rules in pFwRules
  442. pFwRules->get__NewEnum(&pEnumerator);
  443. if(pEnumerator)
  444. {
  445. hr = pEnumerator->QueryInterface(__uuidof(IEnumVARIANT), (void **) &pVariant);
  446. }
  447. QStringList RuleNamelist;
  448. while(SUCCEEDED(hr) && hr != S_FALSE)
  449. {
  450. var.Clear();
  451. hr = pVariant->Next(1, &var, &cFetched);
  452. if (S_FALSE != hr)
  453. {
  454. if (SUCCEEDED(hr))
  455. {
  456. hr = var.ChangeType(VT_DISPATCH);
  457. }
  458. if (SUCCEEDED(hr))
  459. {
  460. hr = (V_DISPATCH(&var))->QueryInterface(__uuidof(INetFwRule), reinterpret_cast<void**>(&pFwRule));
  461. }
  462. if (SUCCEEDED(hr))
  463. {
  464. // Output the properties of this rule
  465. // DumpFWRulesInCollection(pFwRule);
  466. BSTR szRuleName;
  467. pFwRule->get_Name(&szRuleName);
  468. QString sRuleName = QString::fromStdWString(szRuleName);
  469. if(sRuleName.startsWith("disable_coe_"))
  470. {
  471. RuleNamelist<<sRuleName;
  472. }
  473. }
  474. }
  475. }
  476. for(QString &sRuleName : RuleNamelist)
  477. {
  478. std::wstring sName = sRuleName.toStdWString();
  479. pFwRules->Remove(const_cast<BSTR>(sName.c_str()));
  480. }
  481. // Release pFwRule
  482. if (pFwRule != NULL)
  483. {
  484. pFwRule->Release();
  485. }
  486. if(pFwRules != NULL)
  487. {
  488. pFwRules->Release();
  489. }
  490. }
  491. bool CWindowsFireWall::disableAllApp()
  492. {
  493. HRESULT hr = S_OK;
  494. std::vector<CProcessData> vAppList;
  495. if(getAllAppNameList(vAppList))
  496. {
  497. uploadAppLog(vAppList);
  498. }
  499. INetFwRules *pNetFwRules = NULL;
  500. hr = m_pNetFwPolicy2->get_Rules(&pNetFwRules);
  501. if (FAILED(hr))
  502. {
  503. m_sErrMsg = QString("Failed to retrieve firewall rules collection : 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  504. }
  505. for(CProcessData &data : vAppList)
  506. {
  507. if(data.bDisabled)
  508. {
  509. continue;
  510. }
  511. bool bSucceed = true;
  512. INetFwRule *pNetFwRule = NULL;
  513. INetFwRule2 *pNetFwRule2 = NULL;
  514. WCHAR pwszTemp[STRING_BUFFER_SIZE] = L"";
  515. BSTR RuleName = NULL;
  516. BSTR RuleGroupName = NULL;
  517. BSTR RuleDescription = NULL;
  518. BSTR RuleAppPath = NULL;
  519. hr = StringCchPrintfW(pwszTemp, STRING_BUFFER_SIZE, (L"disable_coe_" + data.sExeName).c_str());
  520. if (FAILED(hr))
  521. {
  522. m_sErrMsg = QString("Failed to compose a resource identifier string: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  523. bSucceed = false;
  524. }
  525. RuleName = SysAllocString(pwszTemp);
  526. if (NULL == RuleName)
  527. {
  528. m_sErrMsg = QString("ERROR: Insufficient memory");
  529. bSucceed = false;
  530. }
  531. hr = StringCchPrintfW(pwszTemp, STRING_BUFFER_SIZE, L"coe");
  532. if (FAILED(hr))
  533. {
  534. m_sErrMsg = QString("Failed to compose a resource identifier string: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  535. bSucceed = false;
  536. }
  537. RuleGroupName = SysAllocString(pwszTemp); // Used for grouping together multiple rules
  538. if (NULL == RuleGroupName)
  539. {
  540. m_sErrMsg = QString("ERROR: Insufficient memory");
  541. bSucceed = false;
  542. }
  543. hr = StringCchPrintfW(pwszTemp, STRING_BUFFER_SIZE, (L"disable " + data.sExeName).c_str());
  544. if (FAILED(hr))
  545. {
  546. m_sErrMsg = QString("Failed to compose a resource identifier string: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  547. bSucceed = false;
  548. }
  549. RuleDescription = SysAllocString(pwszTemp);
  550. if (NULL == RuleDescription)
  551. {
  552. m_sErrMsg = "ERROR: Insufficient memory";
  553. bSucceed = false;
  554. }
  555. RuleAppPath = SysAllocString(data.sExePath.c_str());
  556. if (NULL == RuleAppPath)
  557. {
  558. m_sErrMsg = "ERROR: Insufficient memory";
  559. bSucceed = false;
  560. }
  561. // hr = m_pNetFwPolicy2->get_Rules(&pNetFwRules);
  562. // if (FAILED(hr))
  563. // {
  564. // m_sErrMsg = QString("Failed to retrieve firewall rules collection : 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  565. // bSucceed = false;
  566. // }
  567. hr = CoCreateInstance(
  568. __uuidof(NetFwRule), //CLSID of the class whose object is to be created
  569. NULL,
  570. CLSCTX_INPROC_SERVER,
  571. __uuidof(INetFwRule), // Identifier of the Interface used for communicating with the object
  572. (void**)&pNetFwRule);
  573. if (FAILED(hr))
  574. {
  575. m_sErrMsg = QString("CoCreateInstance for INetFwRule failed: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  576. bSucceed = false;
  577. }
  578. hr = pNetFwRule->put_Name(RuleName);
  579. if ( FAILED(hr) )
  580. {
  581. m_sErrMsg = QString("Failed INetFwRule::put_Name failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  582. bSucceed = false;
  583. }
  584. hr = pNetFwRule->put_Grouping(RuleGroupName);
  585. if ( FAILED(hr) )
  586. {
  587. m_sErrMsg = QString("Failed INetFwRule::put_Grouping failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  588. bSucceed = false;
  589. }
  590. hr = pNetFwRule->put_Description(RuleDescription);
  591. if ( FAILED(hr) )
  592. {
  593. m_sErrMsg = QString("Failed INetFwRule::put_Description failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  594. bSucceed = false;
  595. }
  596. hr = pNetFwRule->put_Direction(NET_FW_RULE_DIR_OUT);
  597. if ( FAILED(hr) )
  598. {
  599. m_sErrMsg = QString("Failed INetFwRule::put_Direction failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  600. bSucceed = false;
  601. }
  602. hr = pNetFwRule->put_Action(NET_FW_ACTION_BLOCK);
  603. if ( FAILED(hr) )
  604. {
  605. m_sErrMsg = QString("Failed INetFwRule::put_Action failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  606. bSucceed = false;
  607. }
  608. hr = pNetFwRule->put_ApplicationName(RuleAppPath);
  609. if ( FAILED(hr) )
  610. {
  611. m_sErrMsg = QString("Failed INetFwRule::put_ApplicationName failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  612. bSucceed = false;
  613. }
  614. hr = pNetFwRule->put_Profiles(NET_FW_PROFILE2_DOMAIN | NET_FW_PROFILE2_PRIVATE | NET_FW_PROFILE2_PUBLIC);
  615. if ( FAILED(hr) )
  616. {
  617. m_sErrMsg = QString("Failed INetFwRule::put_Profiles failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  618. bSucceed = false;
  619. }
  620. hr = pNetFwRule->put_Enabled(VARIANT_TRUE);
  621. if ( FAILED(hr) )
  622. {
  623. m_sErrMsg = QString("Failed INetFwRule::put_Enabled failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  624. bSucceed = false;
  625. }
  626. // Check if INetFwRule2 interface is available (i.e Windows7+)
  627. // If supported, then use EdgeTraversalOptions
  628. // Else use the EdgeTraversal boolean flag.
  629. if (SUCCEEDED(pNetFwRule->QueryInterface(__uuidof(INetFwRule2), (void**)&pNetFwRule2)))
  630. {
  631. hr = pNetFwRule2->put_EdgeTraversalOptions(NET_FW_EDGE_TRAVERSAL_TYPE_DENY);
  632. if ( FAILED(hr) )
  633. {
  634. m_sErrMsg = QString("Failed INetFwRule::put_EdgeTraversalOptions failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  635. }
  636. }
  637. else
  638. {
  639. hr = pNetFwRule->put_EdgeTraversal(VARIANT_FALSE);
  640. if ( FAILED(hr) )
  641. {
  642. m_sErrMsg = QString("Failed INetFwRule::put_EdgeTraversal failed with error: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  643. bSucceed = false;
  644. }
  645. }
  646. hr = pNetFwRules->Add(pNetFwRule);
  647. if (FAILED(hr))
  648. {
  649. m_sErrMsg = QString("Failed to add firewall rule to the firewall rules collection: 0x%1").arg(hr, 8, 16, QLatin1Char('0'));
  650. bSucceed = false;
  651. }
  652. if(bSucceed)
  653. {
  654. data.bDisabled = true;
  655. m_vDisableRuleNames.push_back(RuleName);
  656. qDebug()<<QString::fromStdWString(RuleName);
  657. }
  658. else
  659. {
  660. qDebug()<<RuleName<<":"<<m_sErrMsg;
  661. }
  662. SysFreeString(RuleName);
  663. SysFreeString(RuleGroupName);
  664. SysFreeString(RuleDescription);
  665. SysFreeString(RuleAppPath);
  666. if (pNetFwRule2 != NULL)
  667. {
  668. pNetFwRule2->Release();
  669. }
  670. if (pNetFwRule != NULL)
  671. {
  672. pNetFwRule->Release();
  673. }
  674. }
  675. if (pNetFwRules != NULL)
  676. {
  677. pNetFwRules->Release();
  678. }
  679. return hr;
  680. }
  681. std::wstring GetPathByProcessID(DWORD pid)
  682. {
  683. HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
  684. if (!hProcess)
  685. {
  686. return L"";
  687. }
  688. WCHAR filePath[MAX_PATH];
  689. DWORD ret = GetModuleFileNameEx(hProcess, NULL, filePath, MAX_PATH) ;
  690. CloseHandle(hProcess);
  691. return ret == 0 ? L"" : filePath;
  692. }
  693. // dos 文件路径转 windows 文件路径
  694. BOOL DosPathToNtPath(LPTSTR pszDosPath, LPTSTR pszNtPath)
  695. {
  696. TCHAR szDriveStr[500];
  697. TCHAR szDrive[3];
  698. TCHAR szDevName[100];
  699. INT cchDevName;
  700. INT i;
  701. //检查参数
  702. if(!pszDosPath || !pszNtPath )
  703. return FALSE;
  704. //获取本地磁盘字符串
  705. if(GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr))
  706. {
  707. for(i = 0; szDriveStr[i]; i += 4)
  708. {
  709. if(!lstrcmpi(&(szDriveStr[i]), _T("A:\\")) || !lstrcmpi(&(szDriveStr[i]), _T("B:\\"))){continue;}
  710. szDrive[0] = szDriveStr[i];
  711. szDrive[1] = szDriveStr[i + 1];
  712. szDrive[2] = '\0';
  713. // 查询 Dos 设备名
  714. if(!QueryDosDevice(szDrive, szDevName, 100)){return FALSE;}
  715. // 命中
  716. cchDevName = lstrlen(szDevName);
  717. if(_tcsnicmp(pszDosPath, szDevName, cchDevName) == 0){
  718. // 复制驱动器
  719. lstrcpy(pszNtPath, szDrive);
  720. // 复制路径
  721. lstrcat(pszNtPath, pszDosPath + cchDevName);
  722. return TRUE;
  723. }
  724. }
  725. }
  726. lstrcpy(pszNtPath, pszDosPath);
  727. return FALSE;
  728. }
  729. // 获取进程全路径
  730. BOOL GetProcessFullPath(DWORD dwPID, std::wstring &fullPath){
  731. TCHAR szImagePath[MAX_PATH]={'\0'};
  732. TCHAR pszFullPath[MAX_PATH]={'\0'};
  733. HANDLE hProcess;
  734. // 获取进程句柄失败
  735. hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwPID);
  736. if(!hProcess){return FALSE;}
  737. // 获取进程完整路径失败
  738. if(!GetProcessImageFileName(
  739. hProcess, // 进程句柄
  740. szImagePath, // 接收进程所属文件全路径的指针
  741. MAX_PATH // 缓冲区大小
  742. )){
  743. CloseHandle(hProcess);
  744. return FALSE;
  745. }
  746. // 路径转换失败
  747. if(!DosPathToNtPath(szImagePath, pszFullPath)){
  748. CloseHandle(hProcess);
  749. return FALSE;
  750. }
  751. CloseHandle(hProcess);
  752. // 导出文件全路径
  753. fullPath = pszFullPath;
  754. return TRUE;
  755. }
  756. bool CWindowsFireWall::getAllAppNameList(std::vector<CProcessData> &vAppList)
  757. {
  758. bool bRet = false;
  759. PROCESSENTRY32 pe32;
  760. pe32.dwSize = sizeof(pe32);
  761. HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  762. if(hProcessSnap == INVALID_HANDLE_VALUE)
  763. {
  764. return bRet;
  765. }
  766. BOOL bMore = Process32First(hProcessSnap,&pe32);
  767. QStringList list;
  768. while(bMore)
  769. {
  770. std::wstring sExePath = L"";
  771. GetProcessFullPath( pe32.th32ProcessID, sExePath);
  772. QString sPath = QString::fromStdWString(sExePath).toLower();
  773. if(pe32.th32ProcessID != m_pid &&
  774. !sExePath.empty() &&
  775. // sPath.indexOf("c:\\windows\\system32") < 0 &&
  776. sPath.toLower().indexOf("svchost.exe") < 0 &&
  777. // sPath.toLower().indexOf("upgrade") < 0 &&
  778. list.indexOf(QString::fromStdWString(pe32.szExeFile).toLower()) < 0)
  779. {
  780. list<<QString::fromStdWString(pe32.szExeFile).toLower();
  781. CProcessData data;
  782. data.pid = pe32.th32ProcessID;
  783. data.sExeName = pe32.szExeFile;
  784. data.sExePath = sExePath;
  785. vAppList.push_back(data);
  786. bRet = true;
  787. }
  788. bMore = Process32Next(hProcessSnap,&pe32);
  789. }
  790. CloseHandle(hProcessSnap);
  791. return bRet;
  792. }