liteFirewall.cpp (10673B)
1 /* 2 liteFirewall is based on nsisFirewall. 3 Modified by Liang Sun on 19, July, 2011 4 http://liangsun.info/portfolio/nsis-plugin-litefirewall/ 5 http://nsis.sourceforge.net/LiteFirewall_Plugin 6 http://www.msnlite.org 7 */ 8 9 /* 10 nsisFirewall -- Small NSIS plugin for simple tasks with Windows Firewall 11 Web site: http://wiz0u.free.fr/prog/nsisFirewall 12 13 Copyright (c) 2007-2009 Olivier Marcoux 14 15 This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. 16 17 Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 18 19 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 20 21 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 22 23 3. This notice may not be removed or altered from any source distribution. 24 */ 25 #include <windows.h> 26 #include <tchar.h> 27 #include <shlwapi.h> 28 //#include <stdio.h> 29 30 #ifdef NSIS 31 #include "exdll.h" 32 #endif 33 34 //#import "libid:58FBCF7C-E7A9-467C-80B3-FC65E8FCCA08" 35 #import "netfw.tlb" 36 #include <netfw.h> 37 using namespace NetFwTypeLib; 38 39 40 #pragma comment( lib, "ole32.lib" ) 41 #pragma comment( lib, "oleaut32.lib" ) 42 // Forward declarations 43 44 #ifdef NSIS 45 HINSTANCE g_hInstance; 46 #endif 47 48 HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2); 49 50 HRESULT AddRule(LPCTSTR ExceptionName, LPCTSTR ProcessPath) 51 { 52 HRESULT result = CoInitialize(NULL); 53 if (FAILED(result)) 54 return result; 55 result = REGDB_E_CLASSNOTREG; 56 57 HRESULT hrComInit = S_OK; 58 HRESULT hr = S_OK; 59 60 INetFwPolicy2 *pNetFwPolicy2 = NULL; 61 INetFwRules *pFwRules = NULL; 62 INetFwRule *pFwRule = NULL; 63 /* Start Mozilla modification */ 64 INetFwRule *pFwRuleExisting = NULL; 65 66 // long CurrentProfilesBitMask = 0; 67 /* End Mozilla modification */ 68 69 BSTR bstrRuleName = SysAllocString(ExceptionName); 70 BSTR bstrApplicationName = SysAllocString(ProcessPath); 71 BSTR bstrRuleInterfaceType = SysAllocString(L"All"); 72 73 // Initialize COM. 74 hrComInit = CoInitializeEx( 75 0, 76 COINIT_APARTMENTTHREADED 77 ); 78 79 // Ignore RPC_E_CHANGED_MODE; this just means that COM has already been 80 // initialized with a different mode. Since we don't care what the mode is, 81 // we'll just use the existing mode. 82 if (hrComInit != RPC_E_CHANGED_MODE) 83 { 84 if (FAILED(hrComInit)) 85 { 86 printf("CoInitializeEx failed: 0x%08lx\n", hrComInit); 87 goto Cleanup; 88 } 89 } 90 91 // Retrieve INetFwPolicy2 92 hr = WFCOMInitialize(&pNetFwPolicy2); 93 if (FAILED(hr)) 94 { 95 try 96 { 97 INetFwMgrPtr fwMgr(L"HNetCfg.FwMgr"); 98 if (fwMgr) 99 { 100 INetFwAuthorizedApplicationPtr app(L"HNetCfg.FwAuthorizedApplication"); 101 if (app) 102 { 103 app->ProcessImageFileName = ProcessPath; 104 app->Name = ExceptionName; 105 app->Scope = NetFwTypeLib::NET_FW_SCOPE_ALL; 106 app->IpVersion = NetFwTypeLib::NET_FW_IP_VERSION_ANY; 107 app->Enabled = VARIANT_TRUE; 108 fwMgr->LocalPolicy->CurrentProfile->AuthorizedApplications->Add(app); 109 } 110 } 111 } 112 catch (_com_error& e) 113 { 114 /* Start Mozilla modification */ 115 printf("0x%lx", e.Error()); 116 /* End Mozilla modification */ 117 } 118 goto Cleanup; 119 } 120 121 // Retrieve INetFwRules 122 hr = pNetFwPolicy2->get_Rules(&pFwRules); 123 if (FAILED(hr)) 124 { 125 printf("get_Rules failed: 0x%08lx\n", hr); 126 goto Cleanup; 127 } 128 129 /* Start Mozilla modification */ 130 // Don't add a new rule if there is an existing rule with the same name. 131 hr = pFwRules->Item(bstrRuleName, &pFwRuleExisting); 132 // Release the INetFwRule object 133 if (pFwRuleExisting != NULL) 134 { 135 pFwRuleExisting->Release(); 136 } 137 if (SUCCEEDED(hr)) 138 { 139 printf("Firewall profile already exists\n"); 140 goto Cleanup; 141 } 142 143 // Retrieve Current Profiles bitmask 144 // hr = pNetFwPolicy2->get_CurrentProfileTypes(&CurrentProfilesBitMask); 145 // if (FAILED(hr)) 146 // { 147 // printf("get_CurrentProfileTypes failed: 0x%08lx\n", hr); 148 // goto Cleanup; 149 // } 150 151 // When possible we avoid adding firewall rules to the \ profile. 152 // If Public is currently active and it is not the only active profile, we remove it from the bitmask 153 // if ((CurrentProfilesBitMask & NET_FW_PROFILE2_PUBLIC) && 154 // (CurrentProfilesBitMask != NET_FW_PROFILE2_PUBLIC)) 155 // { 156 // CurrentProfilesBitMask ^= NET_FW_PROFILE2_PUBLIC; 157 // } 158 159 // Create a new Firewall Rule object. 160 hr = CoCreateInstance( 161 __uuidof(NetFwRule), 162 NULL, 163 CLSCTX_INPROC_SERVER, 164 __uuidof(INetFwRule), 165 (void**)&pFwRule); 166 if (FAILED(hr)) 167 { 168 printf("CoCreateInstance for Firewall Rule failed: 0x%08lx\n", hr); 169 goto Cleanup; 170 } 171 172 // Populate the Firewall Rule object 173 pFwRule->put_Name(bstrRuleName); 174 pFwRule->put_Protocol(NetFwTypeLib::NET_FW_IP_PROTOCOL_TCP); 175 pFwRule->put_InterfaceTypes(bstrRuleInterfaceType); 176 pFwRule->put_Profiles(NET_FW_PROFILE2_PRIVATE); 177 pFwRule->put_Action(NET_FW_ACTION_ALLOW); 178 pFwRule->put_Enabled(VARIANT_TRUE); 179 180 pFwRule->put_ApplicationName(bstrApplicationName); 181 // Add the Firewall Rule 182 hr = pFwRules->Add(pFwRule); 183 if (FAILED(hr)) 184 { 185 printf("Firewall Rule Add failed: 0x%08lx\n", hr); 186 goto Cleanup; 187 } 188 189 pFwRule->Release(); 190 /* End Mozilla modification */ 191 192 // Create a new Firewall Rule object. 193 hr = CoCreateInstance( 194 __uuidof(NetFwRule), 195 NULL, 196 CLSCTX_INPROC_SERVER, 197 __uuidof(INetFwRule), 198 (void**)&pFwRule); 199 if (FAILED(hr)) 200 { 201 printf("CoCreateInstance for Firewall Rule failed: 0x%08lx\n", hr); 202 goto Cleanup; 203 } 204 205 // Populate the Firewall Rule object 206 pFwRule->put_Name(bstrRuleName); 207 /* Start Mozilla modification */ 208 // pFwRule->put_Protocol(NET_FW_IP_PROTOCOL_ANY); 209 pFwRule->put_Protocol(NetFwTypeLib::NET_FW_IP_PROTOCOL_UDP); 210 /* End Mozilla modification */ 211 pFwRule->put_InterfaceTypes(bstrRuleInterfaceType); 212 /* Start Mozilla modification */ 213 // pFwRule->put_Profiles(CurrentProfilesBitMask); 214 pFwRule->put_Profiles(NET_FW_PROFILE2_PRIVATE); 215 /* End Mozilla modification */ 216 pFwRule->put_Action(NET_FW_ACTION_ALLOW); 217 pFwRule->put_Enabled(VARIANT_TRUE); 218 219 pFwRule->put_ApplicationName(bstrApplicationName); 220 // Add the Firewall Rule 221 hr = pFwRules->Add(pFwRule); 222 if (FAILED(hr)) 223 { 224 printf("Firewall Rule Add failed: 0x%08lx\n", hr); 225 goto Cleanup; 226 } 227 228 Cleanup: 229 230 // Free BSTR's 231 SysFreeString(bstrRuleName); 232 SysFreeString(bstrApplicationName); 233 SysFreeString(bstrRuleInterfaceType); 234 235 // Release the INetFwRule object 236 if (pFwRule != NULL) 237 { 238 pFwRule->Release(); 239 } 240 241 // Release the INetFwRules object 242 if (pFwRules != NULL) 243 { 244 pFwRules->Release(); 245 } 246 247 // Release the INetFwPolicy2 object 248 if (pNetFwPolicy2 != NULL) 249 { 250 pNetFwPolicy2->Release(); 251 } 252 253 CoUninitialize(); 254 return 0; 255 } 256 257 HRESULT RemoveRule(LPCTSTR ExceptionName, LPCTSTR ProcessPath) 258 { 259 HRESULT result = CoInitialize(NULL); 260 if (FAILED(result)) 261 return result; 262 try 263 { 264 INetFwMgrPtr fwMgr(L"HNetCfg.FwMgr"); 265 if (fwMgr) 266 { 267 fwMgr->LocalPolicy->CurrentProfile->AuthorizedApplications->Remove(ProcessPath); 268 result = S_OK; 269 } 270 } 271 catch (_com_error& e) 272 { 273 e; 274 } 275 HRESULT hrComInit = S_OK; 276 HRESULT hr = S_OK; 277 278 INetFwPolicy2 *pNetFwPolicy2 = NULL; 279 INetFwRules *pFwRules = NULL; 280 281 /* Start Mozilla modification */ 282 // long CurrentProfilesBitMask = 0; 283 /* End Mozilla modification */ 284 285 BSTR bstrRuleName = SysAllocString(ExceptionName); 286 287 // Retrieve INetFwPolicy2 288 hr = WFCOMInitialize(&pNetFwPolicy2); 289 if (FAILED(hr)) 290 { 291 goto Cleanup; 292 } 293 294 // Retrieve INetFwRules 295 hr = pNetFwPolicy2->get_Rules(&pFwRules); 296 if (FAILED(hr)) 297 { 298 printf("get_Rules failed: 0x%08lx\n", hr); 299 goto Cleanup; 300 } 301 302 /* Start Mozilla modification */ 303 // Retrieve Current Profiles bitmask 304 // hr = pNetFwPolicy2->get_CurrentProfileTypes(&CurrentProfilesBitMask); 305 // if (FAILED(hr)) 306 // { 307 // printf("get_CurrentProfileTypes failed: 0x%08lx\n", hr); 308 // goto Cleanup; 309 // } 310 311 // When possible we avoid adding firewall rules to the Public profile. 312 // If Public is currently active and it is not the only active profile, we remove it from the bitmask 313 // if ((CurrentProfilesBitMask & NET_FW_PROFILE2_PUBLIC) && 314 // (CurrentProfilesBitMask != NET_FW_PROFILE2_PUBLIC)) 315 // { 316 // CurrentProfilesBitMask ^= NET_FW_PROFILE2_PUBLIC; 317 // } 318 /* End Mozilla modification */ 319 320 // Remove the Firewall Rule 321 hr = pFwRules->Remove(bstrRuleName); 322 if (FAILED(hr)) 323 { 324 printf("Firewall Rule Remove failed: 0x%08lx\n", hr); 325 goto Cleanup; 326 } 327 328 Cleanup: 329 330 // Free BSTR's 331 SysFreeString(bstrRuleName); 332 333 // Release the INetFwRules object 334 if (pFwRules != NULL) 335 { 336 pFwRules->Release(); 337 } 338 339 // Release the INetFwPolicy2 object 340 if (pNetFwPolicy2 != NULL) 341 { 342 pNetFwPolicy2->Release(); 343 } 344 345 CoUninitialize(); 346 return 0; 347 } 348 349 350 #ifdef NSIS 351 extern "C" void __declspec(dllexport) AddRule(HWND hwndParent, int string_size, 352 TCHAR *variables, stack_t **stacktop) 353 { 354 EXDLL_INIT(); 355 356 TCHAR ExceptionName[256], ProcessPath[MAX_PATH]; 357 popstring(ProcessPath); 358 popstring(ExceptionName); 359 HRESULT result = AddRule(ExceptionName, ProcessPath); 360 // push the result back to NSIS 361 TCHAR intBuffer[16]; 362 wsprintf(intBuffer, _T("%d"), result); 363 pushstring(intBuffer); 364 } 365 366 extern "C" void __declspec(dllexport) RemoveRule(HWND hwndParent, int string_size, 367 TCHAR *variables, stack_t **stacktop) 368 { 369 EXDLL_INIT(); 370 371 TCHAR ExceptionName[256], ProcessPath[MAX_PATH]; 372 popstring(ProcessPath); 373 popstring(ExceptionName); 374 HRESULT result = RemoveRule(ExceptionName, ProcessPath); 375 // push the result back to NSIS 376 TCHAR intBuffer[16]; 377 wsprintf(intBuffer, _T("%d"), result); 378 pushstring(intBuffer); 379 } 380 381 extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD, LPVOID) 382 { 383 g_hInstance = hInstance; 384 return TRUE; 385 } 386 #endif 387 388 389 // Instantiate INetFwPolicy2 390 391 HRESULT WFCOMInitialize(INetFwPolicy2** ppNetFwPolicy2) 392 { 393 HRESULT hr = S_OK; 394 395 hr = CoCreateInstance( 396 __uuidof(NetFwPolicy2), 397 NULL, 398 CLSCTX_INPROC_SERVER, 399 __uuidof(INetFwPolicy2), 400 (void**)ppNetFwPolicy2); 401 402 if (FAILED(hr)) 403 { 404 printf("CoCreateInstance for INetFwPolicy2 failed: 0x%08lx\n", hr); 405 goto Cleanup; 406 } 407 408 Cleanup: 409 return hr; 410 }