为啥要关注防火墙
今天项目中的p2p直连遇到了问题。经过排查,发现充当服务器的一端进入listen状态后,另外的客户端一端connect失败。
错误码10060(超时)。
开始时怀疑客户端connect的时候,服务器还没准备好,或者哪里的代码有问题。然后下载了一个tcp测试工具。启动后发现
测试工具也无法正常直连。
然后发现原因是网络管理(防火墙)的问题。
即机器上的入站规则没有添加,导致连接的时候被防火墙屏蔽了。把“阻止”改成“允许”就ok了。
看了下已有的入站规则
如微信是已经写入防火墙的。看来应该有程序写入防火墙的方法。
搜索了下:
防火墙相关API目录:
https://docs.microsoft.com/en-us/windows/win32/api/netfw/
网上找到的示例代码(2010年前的代码,我电脑的win10无效)
#include "stdafx.h" #include <windows.h> #include <crtdbg.h> #include <netfw.h> #include <objbase.h> #include <oleauto.h> #include <stdio.h> #pragma comment( lib, "ole32.lib" ) #pragma comment( lib, "oleaut32.lib" ) HRESULT WindowsFirewallInitialize(OUT INetFwProfile** fwProfile) { HRESULT hr = S_OK; INetFwMgr* fwMgr = NULL; INetFwPolicy* fwPolicy = NULL; _ASSERT(fwProfile != NULL); *fwProfile = NULL; // Create an instance of the firewall settings manager. hr = CoCreateInstance( __uuidof(NetFwMgr), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwMgr), (void**)&fwMgr ); if (FAILED(hr)) { printf("CoCreateInstance failed: 0x%08lx ", hr); goto error; } // Retrieve the local firewall policy. hr = fwMgr->get_LocalPolicy(&fwPolicy); if (FAILED(hr)) { printf("get_LocalPolicy failed: 0x%08lx ", hr); goto error; } // Retrieve the firewall profile currently in effect. hr = fwPolicy->get_CurrentProfile(fwProfile); if (FAILED(hr)) { printf("get_CurrentProfile failed: 0x%08lx ", hr); goto error; } error: // Release the local firewall policy. if (fwPolicy != NULL) { fwPolicy->Release(); } // Release the firewall settings manager. if (fwMgr != NULL) { fwMgr->Release(); } return hr; } void WindowsFirewallCleanup(IN INetFwProfile* fwProfile) { // Release the firewall profile. if (fwProfile != NULL) { fwProfile->Release(); } } HRESULT WindowsFirewallIsOn(IN INetFwProfile* fwProfile, OUT BOOL* fwOn) { HRESULT hr = S_OK; VARIANT_BOOL fwEnabled; _ASSERT(fwProfile != NULL); _ASSERT(fwOn != NULL); *fwOn = FALSE; // Get the current state of the firewall. hr = fwProfile->get_FirewallEnabled(&fwEnabled); if (FAILED(hr)) { printf("get_FirewallEnabled failed: 0x%08lx ", hr); goto error; } // Check to see if the firewall is on. if (fwEnabled != VARIANT_FALSE) { *fwOn = TRUE; printf("The firewall is on. "); } else { printf("The firewall is off. "); } error: return hr; } HRESULT WindowsFirewallTurnOn(IN INetFwProfile* fwProfile) { HRESULT hr = S_OK; BOOL fwOn; _ASSERT(fwProfile != NULL); // Check to see if the firewall is off. hr = WindowsFirewallIsOn(fwProfile, &fwOn); if (FAILED(hr)) { printf("WindowsFirewallIsOn failed: 0x%08lx ", hr); goto error; } // If it is, turn it on. if (!fwOn) { // Turn the firewall on. hr = fwProfile->put_FirewallEnabled(VARIANT_TRUE); if (FAILED(hr)) { printf("put_FirewallEnabled failed: 0x%08lx ", hr); goto error; } printf("The firewall is now on. "); } error: return hr; } HRESULT WindowsFirewallTurnOff(IN INetFwProfile* fwProfile) { HRESULT hr = S_OK; BOOL fwOn; _ASSERT(fwProfile != NULL); // Check to see if the firewall is on. hr = WindowsFirewallIsOn(fwProfile, &fwOn); if (FAILED(hr)) { printf("WindowsFirewallIsOn failed: 0x%08lx ", hr); goto error; } // If it is, turn it off. if (fwOn) { // Turn the firewall off. hr = fwProfile->put_FirewallEnabled(VARIANT_FALSE); if (FAILED(hr)) { printf("put_FirewallEnabled failed: 0x%08lx ", hr); goto error; } printf("The firewall is now off. "); } error: return hr; } HRESULT WindowsFirewallAppIsEnabled( IN INetFwProfile* fwProfile, IN const wchar_t* fwProcessImageFileName, OUT BOOL* fwAppEnabled ) { HRESULT hr = S_OK; BSTR fwBstrProcessImageFileName = NULL; VARIANT_BOOL fwEnabled; INetFwAuthorizedApplication* fwApp = NULL; INetFwAuthorizedApplications* fwApps = NULL; _ASSERT(fwProfile != NULL); _ASSERT(fwProcessImageFileName != NULL); _ASSERT(fwAppEnabled != NULL); *fwAppEnabled = FALSE; // Retrieve the authorized application collection. hr = fwProfile->get_AuthorizedApplications(&fwApps); if (FAILED(hr)) { printf("get_AuthorizedApplications failed: 0x%08lx ", hr); goto error; } // Allocate a BSTR for the process image file name. fwBstrProcessImageFileName = SysAllocString(fwProcessImageFileName); if (SysStringLen(fwBstrProcessImageFileName) == 0) { hr = E_OUTOFMEMORY; printf("SysAllocString failed: 0x%08lx ", hr); goto error; } // Attempt to retrieve the authorized application. hr = fwApps->Item(fwBstrProcessImageFileName, &fwApp); if (SUCCEEDED(hr)) { // Find out if the authorized application is enabled. hr = fwApp->get_Enabled(&fwEnabled); if (FAILED(hr)) { printf("get_Enabled failed: 0x%08lx ", hr); goto error; } if (fwEnabled != VARIANT_FALSE) { // The authorized application is enabled. *fwAppEnabled = TRUE; printf( "Authorized application %lS is enabled in the firewall. ", fwProcessImageFileName ); } else { printf( "Authorized application %lS is disabled in the firewall. ", fwProcessImageFileName ); } } else { // The authorized application was not in the collection. hr = S_OK; printf( "Authorized application %lS is disabled in the firewall. ", fwProcessImageFileName ); } error: // Free the BSTR. SysFreeString(fwBstrProcessImageFileName); // Release the authorized application instance. if (fwApp != NULL) { fwApp->Release(); } // Release the authorized application collection. if (fwApps != NULL) { fwApps->Release(); } return hr; } HRESULT WindowsFirewallAddApp( IN INetFwProfile* fwProfile, IN const wchar_t* fwProcessImageFileName, IN const wchar_t* fwName ) { HRESULT hr = S_OK; BOOL fwAppEnabled; BSTR fwBstrName = NULL; BSTR fwBstrProcessImageFileName = NULL; INetFwAuthorizedApplication* fwApp = NULL; INetFwAuthorizedApplications* fwApps = NULL; _ASSERT(fwProfile != NULL); _ASSERT(fwProcessImageFileName != NULL); _ASSERT(fwName != NULL); // First check to see if the application is already authorized. hr = WindowsFirewallAppIsEnabled( fwProfile, fwProcessImageFileName, &fwAppEnabled ); if (FAILED(hr)) { printf("WindowsFirewallAppIsEnabled failed: 0x%08lx ", hr); goto error; } // Only add the application if it isn't already authorized. if (!fwAppEnabled) { // Retrieve the authorized application collection. hr = fwProfile->get_AuthorizedApplications(&fwApps); if (FAILED(hr)) { printf("get_AuthorizedApplications failed: 0x%08lx ", hr); goto error; } // Create an instance of an authorized application. hr = CoCreateInstance( __uuidof(NetFwAuthorizedApplication), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwAuthorizedApplication), (void**)&fwApp ); if (FAILED(hr)) { printf("CoCreateInstance failed: 0x%08lx ", hr); goto error; } // Allocate a BSTR for the process image file name. fwBstrProcessImageFileName = SysAllocString(fwProcessImageFileName); if (SysStringLen(fwBstrProcessImageFileName) == 0) { hr = E_OUTOFMEMORY; printf("SysAllocString failed: 0x%08lx ", hr); goto error; } // Set the process image file name. hr = fwApp->put_ProcessImageFileName(fwBstrProcessImageFileName); if (FAILED(hr)) { printf("put_ProcessImageFileName failed: 0x%08lx ", hr); goto error; } // Allocate a BSTR for the application friendly name. fwBstrName = SysAllocString(fwName); if (SysStringLen(fwBstrName) == 0) { hr = E_OUTOFMEMORY; printf("SysAllocString failed: 0x%08lx ", hr); goto error; } // Set the application friendly name. hr = fwApp->put_Name(fwBstrName); if (FAILED(hr)) { printf("put_Name failed: 0x%08lx ", hr); goto error; } // Add the application to the collection. hr = fwApps->Add(fwApp); if (FAILED(hr)) { printf("Add failed: 0x%08lx ", hr); goto error; } printf( "Authorized application %lS is now enabled in the firewall. ", fwProcessImageFileName ); } error: // Free the BSTRs. SysFreeString(fwBstrName); SysFreeString(fwBstrProcessImageFileName); // Release the authorized application instance. if (fwApp != NULL) { fwApp->Release(); } // Release the authorized application collection. if (fwApps != NULL) { fwApps->Release(); } return hr; } HRESULT WindowsFirewallPortIsEnabled( IN INetFwProfile* fwProfile, IN LONG portNumber, IN NET_FW_IP_PROTOCOL ipProtocol, OUT BOOL* fwPortEnabled ) { HRESULT hr = S_OK; VARIANT_BOOL fwEnabled; INetFwOpenPort* fwOpenPort = NULL; INetFwOpenPorts* fwOpenPorts = NULL; _ASSERT(fwProfile != NULL); _ASSERT(fwPortEnabled != NULL); *fwPortEnabled = FALSE; // Retrieve the globally open ports collection. hr = fwProfile->get_GloballyOpenPorts(&fwOpenPorts); if (FAILED(hr)) { printf("get_GloballyOpenPorts failed: 0x%08lx ", hr); goto error; } // Attempt to retrieve the globally open port. hr = fwOpenPorts->Item(portNumber, ipProtocol, &fwOpenPort); if (SUCCEEDED(hr)) { // Find out if the globally open port is enabled. hr = fwOpenPort->get_Enabled(&fwEnabled); if (FAILED(hr)) { printf("get_Enabled failed: 0x%08lx ", hr); goto error; } if (fwEnabled != VARIANT_FALSE) { // The globally open port is enabled. *fwPortEnabled = TRUE; printf("Port %ld is open in the firewall. ", portNumber); } else { printf("Port %ld is not open in the firewall. ", portNumber); } } else { // The globally open port was not in the collection. hr = S_OK; printf("Port %ld is not open in the firewall. ", portNumber); } error: // Release the globally open port. if (fwOpenPort != NULL) { fwOpenPort->Release(); } // Release the globally open ports collection. if (fwOpenPorts != NULL) { fwOpenPorts->Release(); } return hr; } HRESULT WindowsFirewallPortAdd( IN INetFwProfile* fwProfile, IN LONG portNumber, IN NET_FW_IP_PROTOCOL ipProtocol, IN const wchar_t* name ) { HRESULT hr = S_OK; BOOL fwPortEnabled; BSTR fwBstrName = NULL; INetFwOpenPort* fwOpenPort = NULL; INetFwOpenPorts* fwOpenPorts = NULL; _ASSERT(fwProfile != NULL); _ASSERT(name != NULL); // First check to see if the port is already added. hr = WindowsFirewallPortIsEnabled( fwProfile, portNumber, ipProtocol, &fwPortEnabled ); if (FAILED(hr)) { printf("WindowsFirewallPortIsEnabled failed: 0x%08lx ", hr); goto error; } // Only add the port if it isn't already added. if (!fwPortEnabled) { // Retrieve the collection of globally open ports. hr = fwProfile->get_GloballyOpenPorts(&fwOpenPorts); if (FAILED(hr)) { printf("get_GloballyOpenPorts failed: 0x%08lx ", hr); goto error; } // Create an instance of an open port. hr = CoCreateInstance( __uuidof(NetFwOpenPort), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwOpenPort), (void**)&fwOpenPort ); if (FAILED(hr)) { printf("CoCreateInstance failed: 0x%08lx ", hr); goto error; } // Set the port number. hr = fwOpenPort->put_Port(portNumber); if (FAILED(hr)) { printf("put_Port failed: 0x%08lx ", hr); goto error; } // Set the IP protocol. hr = fwOpenPort->put_Protocol(ipProtocol); if (FAILED(hr)) { printf("put_Protocol failed: 0x%08lx ", hr); goto error; } // Allocate a BSTR for the friendly name of the port. fwBstrName = SysAllocString(name); if (SysStringLen(fwBstrName) == 0) { hr = E_OUTOFMEMORY; printf("SysAllocString failed: 0x%08lx ", hr); goto error; } // Set the friendly name of the port. hr = fwOpenPort->put_Name(fwBstrName); if (FAILED(hr)) { printf("put_Name failed: 0x%08lx ", hr); goto error; } // Opens the port and adds it to the collection. hr = fwOpenPorts->Add(fwOpenPort); if (FAILED(hr)) { printf("Add failed: 0x%08lx ", hr); goto error; } printf("Port %ld is now open in the firewall. ", portNumber); } error: // Free the BSTR. SysFreeString(fwBstrName); // Release the open port instance. if (fwOpenPort != NULL) { fwOpenPort->Release(); } // Release the globally open ports collection. if (fwOpenPorts != NULL) { fwOpenPorts->Release(); } return hr; } int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr = S_OK; HRESULT comInit = E_FAIL; INetFwProfile* fwProfile = NULL; // Initialize COM. comInit = CoInitializeEx( 0, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE ); // 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 (comInit != RPC_E_CHANGED_MODE) { hr = comInit; if (FAILED(hr)) { printf("CoInitializeEx failed: 0x%08lx ", hr); goto error; } } // Retrieve the firewall profile currently in effect. hr = WindowsFirewallInitialize(&fwProfile); if (FAILED(hr)) { printf("WindowsFirewallInitialize failed: 0x%08lx ", hr); goto error; } // Add Windows Messenger to the authorized application collection. hr = WindowsFirewallAddApp( fwProfile, L"E:\代码\个人测试代码\My\Debug\FW.exe", L"FW.EXE" ); if (FAILED(hr)) { printf("WindowsFirewallAddApp failed: 0x%08lx ", hr); goto error; } // Add TCP::80 to list of globally open ports. // hr = WindowsFirewallPortAdd(fwProfile, 80, NET_FW_IP_PROTOCOL_TCP, L"WWW"); // if (FAILED(hr)) // { // printf("WindowsFirewallPortAdd failed: 0x%08lx ", hr); // goto error; // } error: // Release the firewall profile. WindowsFirewallCleanup(fwProfile); // Uninitialize COM. if (SUCCEEDED(comInit)) { CoUninitialize(); } return 0; }
官网的适用于Win10的方法(得有管理员权限,否则add返回E_ACCESSDENIED The operation was aborted due to permissions issues)
#include <windows.h> #include <stdio.h> #include <netfw.h> #pragma comment( lib, "ole32.lib" ) #pragma comment( lib, "oleaut32.lib" ) // Forward declarations HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2); // Instantiate INetFwPolicy2 HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2) { HRESULT hr = S_OK; hr = CoCreateInstance( __uuidof(NetFwPolicy2), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwPolicy2), (void**)ppNetFwPolicy2); if (FAILED(hr)) { printf("CoCreateInstance for INetFwPolicy2 failed: 0x%08lx ", hr); goto Cleanup; } Cleanup: return hr; } int _tmain(int argc, _TCHAR* argv[]) { HRESULT hrComInit = S_OK; HRESULT hr = S_OK; INetFwPolicy2 *pNetFwPolicy2 = NULL; INetFwRules *pFwRules = NULL; INetFwRule *pFwRule = NULL; long CurrentProfilesBitMask = 0; BSTR bstrRuleName = SysAllocString(L"PER_INTERFACETYPE_RULE_TWO"); BSTR bstrRuleDescription = SysAllocString(L"Allow incoming network traffic over port 2400 coming from LAN interface type"); BSTR bstrRuleGroup = SysAllocString(L"Sample Rule Group"); BSTR bstrRuleLPorts = SysAllocString(L"2400-2450"); BSTR bstrRuleInterfaceType = SysAllocString(L"LAN"); // Initialize COM. hrComInit = 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 (hrComInit != RPC_E_CHANGED_MODE) { if (FAILED(hrComInit)) { printf("CoInitializeEx failed: 0x%08lx ", hrComInit); goto Cleanup; } } // Retrieve INetFwPolicy2 hr = WFCOMInitialize(&pNetFwPolicy2); if (FAILED(hr)) { goto Cleanup; } // Retrieve INetFwRules hr = pNetFwPolicy2->get_Rules(&pFwRules); if (FAILED(hr)) { printf("get_Rules failed: 0x%08lx ", hr); goto Cleanup; } // Retrieve Current Profiles bitmask hr = pNetFwPolicy2->get_CurrentProfileTypes(&CurrentProfilesBitMask); if (FAILED(hr)) { printf("get_CurrentProfileTypes failed: 0x%08lx ", hr); goto Cleanup; } // When possible we avoid adding firewall rules to the Public profile. // If Public is currently active and it is not the only active profile, we remove it from the bitmask if ((CurrentProfilesBitMask & NET_FW_PROFILE2_PUBLIC) && (CurrentProfilesBitMask != NET_FW_PROFILE2_PUBLIC)) { CurrentProfilesBitMask ^= NET_FW_PROFILE2_PUBLIC; } // Create a new Firewall Rule object. hr = CoCreateInstance( __uuidof(NetFwRule), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwRule), (void**)&pFwRule); if (FAILED(hr)) { printf("CoCreateInstance for Firewall Rule failed: 0x%08lx ", hr); goto Cleanup; } // Populate the Firewall Rule object pFwRule->put_Name(bstrRuleName); pFwRule->put_Description(bstrRuleDescription); pFwRule->put_Protocol(NET_FW_IP_PROTOCOL_TCP); pFwRule->put_LocalPorts(bstrRuleLPorts); pFwRule->put_Grouping(bstrRuleGroup); pFwRule->put_InterfaceTypes(bstrRuleInterfaceType); pFwRule->put_Profiles(CurrentProfilesBitMask); pFwRule->put_Action(NET_FW_ACTION_ALLOW); pFwRule->put_Enabled(VARIANT_TRUE); // Add the Firewall Rule hr = pFwRules->Add(pFwRule); if (FAILED(hr)) { printf("Firewall Rule Add failed: 0x%08lx ", hr); goto Cleanup; } Cleanup: // Free BSTR's SysFreeString(bstrRuleName); SysFreeString(bstrRuleDescription); SysFreeString(bstrRuleGroup); SysFreeString(bstrRuleLPorts); SysFreeString(bstrRuleInterfaceType); // Release the INetFwRule object if (pFwRule != NULL) { pFwRule->Release(); } // Release the INetFwRules object if (pFwRules != NULL) { pFwRules->Release(); } // Release the INetFwPolicy2 object if (pNetFwPolicy2 != NULL) { pNetFwPolicy2->Release(); } // Uninitialize COM. if (SUCCEEDED(hrComInit)) { CoUninitialize(); } getchar(); return 0; }
自己写了一个函数WriteFireWall支持各类操作系统、(麻烦帮我测试下xp,没找到机器。。)
update 2019-11-14 增加一个参数,如果存在是否不添加。true 不添加 false 添加
#include "stdafx.h" #include <windows.h> #include <stdio.h> #include <netfw.h> #pragma warning(disable: 4996) //解决GetVersionEx 过期问题 void WriteFireWallXP(LPCTSTR ruleName, LPCTSTR appPath,bool NoopIfExist) { HRESULT hr = S_OK; HRESULT comInit = E_FAIL; INetFwProfile* fwProfile = NULL; INetFwMgr* fwMgr = NULL; INetFwPolicy* fwPolicy = NULL; INetFwAuthorizedApplication* fwApp = NULL; INetFwAuthorizedApplications* fwApps = NULL; BSTR bstrRuleName = SysAllocString(ruleName); BSTR bstrAppName = SysAllocString(appPath); // Initialize COM. comInit = CoInitializeEx( 0, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE ); // 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 (comInit != RPC_E_CHANGED_MODE) { hr = comInit; if (FAILED(hr)) { printf("CoInitializeEx failed: 0x%08lx ", hr); goto error; } } // Create an instance of the firewall settings manager. hr = CoCreateInstance( __uuidof(NetFwMgr), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwMgr), (void**)&fwMgr ); if (FAILED(hr)) { printf("CoCreateInstance failed: 0x%08lx ", hr); goto error; } // Retrieve the local firewall policy. hr = fwMgr->get_LocalPolicy(&fwPolicy); if (FAILED(hr)) { printf("get_LocalPolicy failed: 0x%08lx ", hr); goto error; } // Retrieve the firewall profile currently in effect. hr = fwPolicy->get_CurrentProfile(&fwProfile); if (FAILED(hr)) { printf("get_CurrentProfile failed: 0x%08lx ", hr); goto error; } // Retrieve the authorized application collection. hr = fwProfile->get_AuthorizedApplications(&fwApps); if (FAILED(hr)) { printf("get_AuthorizedApplications failed: 0x%08lx ", hr); goto error; } //check if exist if (NoopIfExist) { hr = fwApps->Item(bstrRuleName, &fwApp); if (hr == S_OK) { printf("item is exist"); goto error; } } // Create an instance of an authorized application. hr = CoCreateInstance( __uuidof(NetFwAuthorizedApplication), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwAuthorizedApplication), (void**)&fwApp ); if (FAILED(hr)) { printf("CoCreateInstance failed: 0x%08lx ", hr); goto error; } // Set the process image file name. hr = fwApp->put_ProcessImageFileName(bstrAppName); if (FAILED(hr)) { printf("put_ProcessImageFileName failed: 0x%08lx ", hr); goto error; } // Set the application friendly name. hr = fwApp->put_Name(bstrRuleName); if (FAILED(hr)) { printf("put_Name failed: 0x%08lx ", hr); goto error; } // Add the application to the collection. hr = fwApps->Add(fwApp); if (FAILED(hr)) { printf("Add failed: 0x%08lx ", hr); goto error; } error: // Release the local firewall policy. if (fwPolicy != NULL) { fwPolicy->Release(); } // Release the firewall settings manager. if (fwMgr != NULL) { fwMgr->Release(); } SysFreeString(bstrRuleName); SysFreeString(bstrAppName); if (fwApp != NULL) { fwApp->Release(); } // Release the authorized application collection. if (fwApps != NULL) { fwApps->Release(); } if (fwProfile != NULL) { fwProfile->Release(); } // Uninitialize COM. if (SUCCEEDED(comInit)) { CoUninitialize(); } } //写入防火墙,最低支持版本Windows Vista void WriteFireWallOverXP(LPCTSTR ruleName, LPCTSTR appPath, bool NoopIfExist) { HRESULT hrComInit = S_OK; HRESULT hr = S_OK; INetFwPolicy2 *pNetFwPolicy2 = NULL; INetFwRules *pFwRules = NULL; INetFwRule *pFwRule = NULL; BSTR bstrRuleName = SysAllocString(ruleName); BSTR bstrAppName = SysAllocString(appPath); // Initialize COM. hrComInit = 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 (hrComInit != RPC_E_CHANGED_MODE) { if (FAILED(hrComInit)) { printf("CoInitializeEx failed: 0x%08lx ", hrComInit); goto Cleanup; } } // Retrieve INetFwPolicy2 hr = CoCreateInstance( __uuidof(NetFwPolicy2), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwPolicy2), (void**)&pNetFwPolicy2); if (FAILED(hr)) { printf("CoCreateInstance for INetFwPolicy2 failed: 0x%08lx ", hr); goto Cleanup; } // Retrieve INetFwRules hr = pNetFwPolicy2->get_Rules(&pFwRules); if (FAILED(hr)) { printf("get_Rules failed: 0x%08lx ", hr); goto Cleanup; } //see if existed if (NoopIfExist) { hr = pFwRules->Item(bstrRuleName, &pFwRule); if (hr == S_OK) { printf("Item existed", hr); goto Cleanup; } } // Create a new Firewall Rule object. hr = CoCreateInstance( __uuidof(NetFwRule), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwRule), (void**)&pFwRule); if (FAILED(hr)) { printf("CoCreateInstance for Firewall Rule failed: 0x%08lx ", hr); goto Cleanup; } // Populate the Firewall Rule object pFwRule->put_Name(bstrRuleName); pFwRule->put_ApplicationName(bstrAppName); pFwRule->put_Action(NET_FW_ACTION_ALLOW); pFwRule->put_Enabled(VARIANT_TRUE); // Add the Firewall Rule hr = pFwRules->Add(pFwRule); if (FAILED(hr)) { printf("Firewall Rule Add failed: 0x%08lx ", hr); goto Cleanup; } Cleanup: // Free BSTR's SysFreeString(bstrRuleName); SysFreeString(bstrAppName); // Release the INetFwRule object if (pFwRule != NULL) { pFwRule->Release(); } // Release the INetFwRules object if (pFwRules != NULL) { pFwRules->Release(); } // Release the INetFwPolicy2 object if (pNetFwPolicy2 != NULL) { pNetFwPolicy2->Release(); } // Uninitialize COM. if (SUCCEEDED(hrComInit)) { CoUninitialize(); } } void WriteFireWall(LPCTSTR ruleName, LPCTSTR appPath,bool NoopIfExist) { //check windows version OSVERSIONINFO ovi = { sizeof(OSVERSIONINFO) }; if (!::GetVersionEx(&ovi)) return; int version = ovi.dwMajorVersion * 100 + ovi.dwMinorVersion; if (version < 600) //600为vista { WriteFireWallXP(ruleName, appPath, NoopIfExist); } else { WriteFireWallOverXP(ruleName, appPath, NoopIfExist); } } int _tmain(int argc, _TCHAR* argv[]) { WriteFireWall(L"testfirewall", L"d:\test.text",true); getchar(); return 0; }