@joebigelow / wix-1 / commits / e29b4aac

remove windows xp specific code from firewall extension

chris_bednarski committed Aug 21, 2023 at 11:34 UTC e29b4aacf89ce060509b20a5f81df200f7d2fbc1
5 files changed +102 -438
src/ext/Firewall/ca/firewall.cpp
+7 -435
@@ -347,90 +347,6 @@ LExit:
347 return hr;
348 }
349
350 -/******************************************************************
351 - FSupportProfiles - Returns true if we support profiles on this machine.
352 - (Only on Vista or later)
353 -
354 -********************************************************************/
355 -static BOOL FSupportProfiles()
356 -{
357 - BOOL fSupportProfiles = FALSE;
358 - INetFwRules* pNetFwRules = NULL;
359 -
360 - // We only support profiles if we can co-create an instance of NetFwPolicy2.
361 - // This will not work on pre-vista machines.
362 - if (SUCCEEDED(GetFirewallRules(TRUE, &pNetFwRules)) && pNetFwRules != NULL)
363 - {
364 - fSupportProfiles = TRUE;
365 - ReleaseObject(pNetFwRules);
366 - }
367 -
368 - return fSupportProfiles;
369 -}
370 -
371 -/******************************************************************
372 - GetCurrentFirewallProfile - get the active firewall profile as an
373 - INetFwProfile, which owns the lists of exceptions we're
374 - updating.
375 -
376 -********************************************************************/
377 -static HRESULT GetCurrentFirewallProfile(
378 - __in BOOL fIgnoreFailures,
379 - __out INetFwProfile** ppfwProfile
380 - )
381 -{
382 - HRESULT hr = S_OK;
383 - INetFwMgr* pfwMgr = NULL;
384 - INetFwPolicy* pfwPolicy = NULL;
385 - INetFwProfile* pfwProfile = NULL;
386 - *ppfwProfile = NULL;
387 -
388 - do
389 - {
390 - ReleaseNullObject(pfwPolicy);
391 - ReleaseNullObject(pfwMgr);
392 - ReleaseNullObject(pfwProfile);
393 -
394 - if (SUCCEEDED(hr = ::CoCreateInstance(__uuidof(NetFwMgr), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwMgr), (void**)&pfwMgr)) &&
395 - SUCCEEDED(hr = pfwMgr->get_LocalPolicy(&pfwPolicy)) &&
396 - SUCCEEDED(hr = pfwPolicy->get_CurrentProfile(&pfwProfile)))
397 - {
398 - break;
399 - }
400 - else if (fIgnoreFailures)
401 - {
402 - ExitFunction1(hr = S_FALSE);
403 - }
404 - else
405 - {
406 - WcaLog(LOGMSG_STANDARD, "Failed to connect to Windows Firewall");
407 - UINT er = WcaErrorMessage(msierrFirewallCannotConnect, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0);
408 - switch (er)
409 - {
410 - case IDABORT: // exit with the current HRESULT
411 - ExitFunction();
412 - case IDRETRY: // clean up and retry the loop
413 - hr = S_FALSE;
414 - break;
415 - case IDIGNORE: // pass S_FALSE back to the caller, who knows how to ignore the failure
416 - ExitFunction1(hr = S_FALSE);
417 - default: // No UI, so default is to fail.
418 - ExitFunction();
419 - }
420 - }
421 - } while (S_FALSE == hr);
422 -
423 - *ppfwProfile = pfwProfile;
424 - pfwProfile = NULL;
425 -
426 -LExit:
427 - ReleaseObject(pfwPolicy);
428 - ReleaseObject(pfwMgr);
429 - ReleaseObject(pfwProfile);
430 -
431 - return hr;
432 -}
433 -
350 /******************************************************************
351 AddApplicationException
352
@@ -508,92 +424,6 @@ LExit:
424 return fIgnoreFailures ? S_OK : hr;
425 }
426
511 -/******************************************************************
512 - AddApplicationExceptionOnCurrentProfile
513 -
514 -********************************************************************/
515 -static HRESULT AddApplicationExceptionOnCurrentProfile(
516 - __in LPCWSTR wzFile,
517 - __in LPCWSTR wzName,
518 - __in_opt LPCWSTR wzRemoteAddresses,
519 - __in BOOL fIgnoreFailures
520 - )
521 -{
522 - HRESULT hr = S_OK;
523 - BSTR bstrFile = NULL;
524 - BSTR bstrName = NULL;
525 - BSTR bstrRemoteAddresses = NULL;
526 - INetFwProfile* pfwProfile = NULL;
527 - INetFwAuthorizedApplications* pfwApps = NULL;
528 - INetFwAuthorizedApplication* pfwApp = NULL;
529 -
530 - // convert to BSTRs to make COM happy
531 - bstrFile = ::SysAllocString(wzFile);
532 - ExitOnNull(bstrFile, hr, E_OUTOFMEMORY, "failed SysAllocString for path");
533 - bstrName = ::SysAllocString(wzName);
534 - ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for name");
535 - bstrRemoteAddresses = ::SysAllocString(wzRemoteAddresses);
536 - ExitOnNull(bstrRemoteAddresses, hr, E_OUTOFMEMORY, "failed SysAllocString for remote addresses");
537 -
538 - // get the firewall profile, which is our entry point for adding exceptions
539 - hr = GetCurrentFirewallProfile(fIgnoreFailures, &pfwProfile);
540 - ExitOnFailure(hr, "failed to get firewall profile");
541 - if (S_FALSE == hr) // user or package author chose to ignore missing firewall
542 - {
543 - ExitFunction();
544 - }
545 -
546 - // first, let's see if the app is already on the exception list
547 - hr = pfwProfile->get_AuthorizedApplications(&pfwApps);
548 - ExitOnFailure(hr, "failed to get list of authorized apps");
549 -
550 - // try to find it (i.e., support reinstall)
551 - hr = pfwApps->Item(bstrFile, &pfwApp);
552 - if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr)
553 - {
554 - // not found, so we get to add it
555 - hr = ::CoCreateInstance(__uuidof(NetFwAuthorizedApplication), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwAuthorizedApplication), reinterpret_cast<void**>(&pfwApp));
556 - ExitOnFailure(hr, "failed to create authorized app");
557 -
558 - // set the display name
559 - hr = pfwApp->put_Name(bstrName);
560 - ExitOnFailure(hr, "failed to set authorized app name");
561 -
562 - // set path
563 - hr = pfwApp->put_ProcessImageFileName(bstrFile);
564 - ExitOnFailure(hr, "failed to set authorized app path");
565 -
566 - // set the allowed remote addresses
567 - if (bstrRemoteAddresses && *bstrRemoteAddresses)
568 - {
569 - hr = pfwApp->put_RemoteAddresses(bstrRemoteAddresses);
570 - ExitOnFailure(hr, "failed to set authorized app remote addresses");
571 - }
572 -
573 - // add it to the list of authorized apps
574 - hr = pfwApps->Add(pfwApp);
575 - ExitOnFailure(hr, "failed to add app to the authorized apps list");
576 - }
577 - else
578 - {
579 - // we found an existing app exception (if we succeeded, that is)
580 - ExitOnFailure(hr, "failed trying to find existing app");
581 -
582 - // enable it (just in case it was disabled)
583 - pfwApp->put_Enabled(VARIANT_TRUE);
584 - }
585 -
586 -LExit:
587 - ReleaseBSTR(bstrRemoteAddresses);
588 - ReleaseBSTR(bstrName);
589 - ReleaseBSTR(bstrFile);
590 - ReleaseObject(pfwApp);
591 - ReleaseObject(pfwApps);
592 - ReleaseObject(pfwProfile);
593 -
594 - return fIgnoreFailures ? S_OK : hr;
595 -}
596 -
427 /******************************************************************
428 AddPortException
429
@@ -659,79 +489,11 @@ LExit:
489 }
490
491 /******************************************************************
662 - AddPortExceptionOnCurrentProfile
663 -
664 -********************************************************************/
665 -static HRESULT AddPortExceptionOnCurrentProfile(
666 - __in LPCWSTR wzName,
667 - __in_opt LPCWSTR wzRemoteAddresses,
668 - __in BOOL fIgnoreFailures,
669 - __in int iPort,
670 - __in int iProtocol
671 - )
672 -{
673 - HRESULT hr = S_OK;
674 - BSTR bstrName = NULL;
675 - BSTR bstrRemoteAddresses = NULL;
676 - INetFwProfile* pfwProfile = NULL;
677 - INetFwOpenPorts* pfwPorts = NULL;
678 - INetFwOpenPort* pfwPort = NULL;
679 -
680 - // convert to BSTRs to make COM happy
681 - bstrName = ::SysAllocString(wzName);
682 - ExitOnNull(bstrName, hr, E_OUTOFMEMORY, "failed SysAllocString for name");
683 - bstrRemoteAddresses = ::SysAllocString(wzRemoteAddresses);
684 - ExitOnNull(bstrRemoteAddresses, hr, E_OUTOFMEMORY, "failed SysAllocString for remote addresses");
685 -
686 - // create and initialize a new open port object
687 - hr = ::CoCreateInstance(__uuidof(NetFwOpenPort), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwOpenPort), reinterpret_cast<void**>(&pfwPort));
688 - ExitOnFailure(hr, "failed to create new open port");
689 -
690 - hr = pfwPort->put_Port(iPort);
691 - ExitOnFailure(hr, "failed to set exception port");
692 -
693 - hr = pfwPort->put_Protocol(static_cast<NET_FW_IP_PROTOCOL>(iProtocol));
694 - ExitOnFailure(hr, "failed to set exception protocol");
695 -
696 - if (bstrRemoteAddresses && *bstrRemoteAddresses)
697 - {
698 - hr = pfwPort->put_RemoteAddresses(bstrRemoteAddresses);
699 - ExitOnFailure(hr, "failed to set exception remote addresses '%ls'", bstrRemoteAddresses);
700 - }
701 -
702 - hr = pfwPort->put_Name(bstrName);
703 - ExitOnFailure(hr, "failed to set exception name");
704 -
705 - // get the firewall profile, its current list of open ports, and add ours
706 - hr = GetCurrentFirewallProfile(fIgnoreFailures, &pfwProfile);
707 - ExitOnFailure(hr, "failed to get firewall profile");
708 - if (S_FALSE == hr) // user or package author chose to ignore missing firewall
709 - {
710 - ExitFunction();
711 - }
712 -
713 - hr = pfwProfile->get_GloballyOpenPorts(&pfwPorts);
714 - ExitOnFailure(hr, "failed to get open ports");
715 -
716 - hr = pfwPorts->Add(pfwPort);
717 - ExitOnFailure(hr, "failed to add exception to global list");
718 -
719 -LExit:
720 - ReleaseBSTR(bstrRemoteAddresses);
721 - ReleaseBSTR(bstrName);
722 - ReleaseObject(pfwProfile);
723 - ReleaseObject(pfwPorts);
724 - ReleaseObject(pfwPort);
725 -
726 - return fIgnoreFailures ? S_OK : hr;
727 -}
728 -
729 -/******************************************************************
730 - RemoveException - Removes the exception rule with the given name.
492 + RemoveException - Removes all exception rules with the given name.
493
494 ********************************************************************/
495 static HRESULT RemoveException(
734 - __in LPCWSTR wzName,
496 + __in LPCWSTR wzName,
497 __in BOOL fIgnoreFailures
498 )
499 {
@@ -751,7 +513,7 @@ static HRESULT RemoveException(
513 }
514
515 hr = pNetFwRules->Remove(bstrName);
754 - ExitOnFailure(hr, "failed to remove authorized app");
516 + ExitOnFailure(hr, "failed to remove firewall rule");
517
518 LExit:
519 ReleaseBSTR(bstrName);
@@ -760,192 +522,6 @@ LExit:
522 return fIgnoreFailures ? S_OK : hr;
523 }
524
763 -/******************************************************************
764 - RemoveApplicationExceptionFromCurrentProfile
765 -
766 -********************************************************************/
767 -static HRESULT RemoveApplicationExceptionFromCurrentProfile(
768 - __in LPCWSTR wzFile,
769 - __in BOOL fIgnoreFailures
770 - )
771 -{
772 - HRESULT hr = S_OK;
773 - INetFwProfile* pfwProfile = NULL;
774 - INetFwAuthorizedApplications* pfwApps = NULL;
775 -
776 - // convert to BSTRs to make COM happy
777 - BSTR bstrFile = ::SysAllocString(wzFile);
778 - ExitOnNull(bstrFile, hr, E_OUTOFMEMORY, "failed SysAllocString for path");
779 -
780 - // get the firewall profile, which is our entry point for removing exceptions
781 - hr = GetCurrentFirewallProfile(fIgnoreFailures, &pfwProfile);
782 - ExitOnFailure(hr, "failed to get firewall profile");
783 - if (S_FALSE == hr) // user or package author chose to ignore missing firewall
784 - {
785 - ExitFunction();
786 - }
787 -
788 - // now get the list of app exceptions and remove the one
789 - hr = pfwProfile->get_AuthorizedApplications(&pfwApps);
790 - ExitOnFailure(hr, "failed to get list of authorized apps");
791 -
792 - hr = pfwApps->Remove(bstrFile);
793 - ExitOnFailure(hr, "failed to remove authorized app");
794 -
795 -LExit:
796 - ReleaseBSTR(bstrFile);
797 - ReleaseObject(pfwApps);
798 - ReleaseObject(pfwProfile);
799 -
800 - return fIgnoreFailures ? S_OK : hr;
801 -}
802 -
803 -/******************************************************************
804 - RemovePortExceptionFromCurrentProfile
805 -
806 -********************************************************************/
807 -static HRESULT RemovePortExceptionFromCurrentProfile(
808 - __in int iPort,
809 - __in int iProtocol,
810 - __in BOOL fIgnoreFailures
811 - )
812 -{
813 - HRESULT hr = S_OK;
814 - INetFwProfile* pfwProfile = NULL;
815 - INetFwOpenPorts* pfwPorts = NULL;
816 -
817 - // get the firewall profile, which is our entry point for adding exceptions
818 - hr = GetCurrentFirewallProfile(fIgnoreFailures, &pfwProfile);
819 - ExitOnFailure(hr, "failed to get firewall profile");
820 - if (S_FALSE == hr) // user or package author chose to ignore missing firewall
821 - {
822 - ExitFunction();
823 - }
824 -
825 - hr = pfwProfile->get_GloballyOpenPorts(&pfwPorts);
826 - ExitOnFailure(hr, "failed to get open ports");
827 -
828 - hr = pfwPorts->Remove(iPort, static_cast<NET_FW_IP_PROTOCOL>(iProtocol));
829 - ExitOnFailure(hr, "failed to remove open port %d, protocol %d", iPort, iProtocol);
830 -
831 -LExit:
832 - return fIgnoreFailures ? S_OK : hr;
833 -}
834 -
835 -static HRESULT AddApplicationException(
836 - __in BOOL fSupportProfiles,
837 - __in LPCWSTR wzFile,
838 - __in LPCWSTR wzName,
839 - __in int iProfile,
840 - __in_opt LPCWSTR wzRemoteAddresses,
841 - __in BOOL fIgnoreFailures,
842 - __in LPCWSTR wzPort,
843 - __in int iProtocol,
844 - __in LPCWSTR wzDescription,
845 - __in int iDirection
846 -)
847 -{
848 - HRESULT hr = S_OK;
849 -
850 - if (fSupportProfiles)
851 - {
852 - hr = AddApplicationException(wzFile, wzName, iProfile, wzRemoteAddresses, fIgnoreFailures, wzPort, iProtocol, wzDescription, iDirection);
853 - }
854 - else
855 - {
856 - if (0 != *wzPort || MSI_NULL_INTEGER != iProtocol)
857 - {
858 - // NOTE: This is treated as an error rather than either creating a rule based on just the application (no port), or
859 - // just the port because it is unclear what is the proper fall back. For example, suppose that you have code that
860 - // runs in dllhost.exe. Clearly falling back to opening all of dllhost is wrong. Because the firewall is a security
861 - // feature, it seems better to require the MSI author to indicate the behavior that they want.
862 - WcaLog(LOGMSG_STANDARD, "FirewallExtension: Cannot add firewall rule '%ls', which defines both an application and a port or protocol. Such a rule requires Microsoft Windows Vista or later.", wzName);
863 - return fIgnoreFailures ? S_OK : E_NOTIMPL;
864 - }
865 -
866 - hr = AddApplicationExceptionOnCurrentProfile(wzFile, wzName, wzRemoteAddresses, fIgnoreFailures);
867 - }
868 -
869 - return hr;
870 -}
871 -
872 -static HRESULT AddPortException(
873 - __in BOOL fSupportProfiles,
874 - __in LPCWSTR wzName,
875 - __in int iProfile,
876 - __in_opt LPCWSTR wzRemoteAddresses,
877 - __in BOOL fIgnoreFailures,
878 - __in LPCWSTR wzPort,
879 - __in int iProtocol,
880 - __in LPCWSTR wzDescription,
881 - __in int iDirection
882 -)
883 -{
884 - HRESULT hr = S_OK;
885 -
886 - if (fSupportProfiles)
887 - {
888 - hr = AddPortException(wzName, iProfile, wzRemoteAddresses, fIgnoreFailures, wzPort, iProtocol, wzDescription, iDirection);
889 - }
890 - else
891 - {
892 - hr = AddPortExceptionOnCurrentProfile(wzName, wzRemoteAddresses, fIgnoreFailures, wcstol(wzPort, NULL, 10), iProtocol);
893 - }
894 -
895 - return hr;
896 -}
897 -
898 -static HRESULT RemoveApplicationException(
899 - __in BOOL fSupportProfiles,
900 - __in LPCWSTR wzName,
901 - __in LPCWSTR wzFile,
902 - __in BOOL fIgnoreFailures,
903 - __in LPCWSTR wzPort,
904 - __in int iProtocol
905 - )
906 -{
907 - HRESULT hr = S_OK;
908 -
909 - if (fSupportProfiles)
910 - {
911 - hr = RemoveException(wzName, fIgnoreFailures);
912 - }
913 - else
914 - {
915 - if (0 != *wzPort || MSI_NULL_INTEGER != iProtocol)
916 - {
917 - WcaLog(LOGMSG_STANDARD, "FirewallExtension: Cannot remove firewall rule '%ls', which defines both an application and a port or protocol. Such a rule requires Microsoft Windows Vista or later.", wzName);
918 - return S_OK;
919 - }
920 -
921 - hr = RemoveApplicationExceptionFromCurrentProfile(wzFile, fIgnoreFailures);
922 - }
923 -
924 - return hr;
925 -}
926 -
927 -static HRESULT RemovePortException(
928 - __in BOOL fSupportProfiles,
929 - __in LPCWSTR wzName,
930 - __in LPCWSTR wzPort,
931 - __in int iProtocol,
932 - __in BOOL fIgnoreFailures
933 - )
934 -{
935 - HRESULT hr = S_OK;
936 -
937 - if (fSupportProfiles)
938 - {
939 - hr = RemoveException(wzName, fIgnoreFailures);
940 - }
941 - else
942 - {
943 - hr = RemovePortExceptionFromCurrentProfile(wcstol(wzPort, NULL, 10), iProtocol, fIgnoreFailures);
944 - }
945 -
946 - return hr;
947 -}
948 -
525 /******************************************************************
526 ExecFirewallExceptions - deferred custom action entry point to
527 register and remove firewall exceptions.
@@ -956,7 +532,6 @@ extern "C" UINT __stdcall ExecFirewallExceptions(
532 )
533 {
534 HRESULT hr = S_OK;
959 - BOOL fSupportProfiles = FALSE;
535 LPWSTR pwz = NULL;
536 LPWSTR pwzCustomActionData = NULL;
537 int iTodo = WCA_TODO_UNKNOWN;
@@ -982,9 +557,6 @@ extern "C" UINT __stdcall ExecFirewallExceptions(
557 hr = ::CoInitialize(NULL);
558 ExitOnFailure(hr, "failed to initialize COM");
559
985 - // Find out if we support profiles (only on Vista or later)
986 - fSupportProfiles = FSupportProfiles();
987 -
560 // loop through all the passed in data
561 pwz = pwzCustomActionData;
562 while (pwz && *pwz)
@@ -1043,13 +615,13 @@ extern "C" UINT __stdcall ExecFirewallExceptions(
615 case WCA_TODO_INSTALL:
616 case WCA_TODO_REINSTALL:
617 WcaLog(LOGMSG_STANDARD, "Installing firewall exception2 %ls on port %ls, protocol %d", pwzName, pwzPort, iProtocol);
1046 - hr = AddPortException(fSupportProfiles, pwzName, iProfile, pwzRemoteAddresses, fIgnoreFailures, pwzPort, iProtocol, pwzDescription, iDirection);
618 + hr = AddPortException(pwzName, iProfile, pwzRemoteAddresses, fIgnoreFailures, pwzPort, iProtocol, pwzDescription, iDirection);
619 ExitOnFailure(hr, "failed to add/update port exception for name '%ls' on port %ls, protocol %d", pwzName, pwzPort, iProtocol);
620 break;
621
622 case WCA_TODO_UNINSTALL:
623 WcaLog(LOGMSG_STANDARD, "Uninstalling firewall exception2 %ls on port %ls, protocol %d", pwzName, pwzPort, iProtocol);
1052 - hr = RemovePortException(fSupportProfiles, pwzName, pwzPort, iProtocol, fIgnoreFailures);
624 + hr = RemoveException(pwzName, fIgnoreFailures);
625 ExitOnFailure(hr, "failed to remove port exception for name '%ls' on port %ls, protocol %d", pwzName, pwzPort, iProtocol);
626 break;
627 }
@@ -1061,13 +633,13 @@ extern "C" UINT __stdcall ExecFirewallExceptions(
633 case WCA_TODO_INSTALL:
634 case WCA_TODO_REINSTALL:
635 WcaLog(LOGMSG_STANDARD, "Installing firewall exception2 %ls (%ls)", pwzName, pwzFile);
1064 - hr = AddApplicationException(fSupportProfiles, pwzFile, pwzName, iProfile, pwzRemoteAddresses, fIgnoreFailures, pwzPort, iProtocol, pwzDescription, iDirection);
636 + hr = AddApplicationException(pwzFile, pwzName, iProfile, pwzRemoteAddresses, fIgnoreFailures, pwzPort, iProtocol, pwzDescription, iDirection);
637 ExitOnFailure(hr, "failed to add/update application exception for name '%ls', file '%ls'", pwzName, pwzFile);
638 break;
639
640 case WCA_TODO_UNINSTALL:
641 WcaLog(LOGMSG_STANDARD, "Uninstalling firewall exception2 %ls (%ls)", pwzName, pwzFile);
1070 - hr = RemoveApplicationException(fSupportProfiles, pwzName, pwzFile, fIgnoreFailures, pwzPort, iProtocol);
642 + hr = RemoveException(pwzName, fIgnoreFailures);
643 ExitOnFailure(hr, "failed to remove application exception for name '%ls', file '%ls'", pwzName, pwzFile);
644 break;
645 }
src/test/burn/WixTestTools/Firewall/Verifier.cs
+7 -1
@@ -254,7 +254,13 @@ namespace WixTestTools.Firewall
254 rule.Enabled = false;
255 }
256
257 - public static void RemoveFirewallRulesByName(string name)
257 + /// <summary>
258 + /// Removes a firewall rule by name. If multiple rules with the same name exist, only one of them is removed.<br/>
259 + /// This behavior is different from <b>netsh advfirewall firewall delete rule</b> where all matching rules are deleted if multiple matches are found.<br/>
260 + /// The firewall rule name cannot be null or an empty string.
261 + /// </summary>
262 + /// <param name="name">Name of the firewall rule to be removed.</param>
263 + public static void RemoveFirewallRuleByName(string name)
264 {
265 var rules = GetINetFwRules();
266 rules.Remove(name);
src/test/msi/TestData/FirewallExtensionTests/IgnoreFailedFirewallRules/IgnoreFailedFirewallRules.wixproj new
+13
@@ -0,0 +1,13 @@
1 +<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2 +<Project Sdk="WixToolset.Sdk">
3 + <PropertyGroup>
4 + <UpgradeCode>{4D188568-1CCF-4EEE-BC27-17C3DCC83E58}</UpgradeCode>
5 + <ProductComponentsRef>true</ProductComponentsRef>
6 + </PropertyGroup>
7 + <ItemGroup>
8 + <Compile Include="..\..\Templates\Product.wxs" Link="Product.wxs" />
9 + </ItemGroup>
10 + <ItemGroup>
11 + <PackageReference Include="WixToolset.Firewall.wixext" />
12 + </ItemGroup>
13 +</Project>
\ No newline at end of file
src/test/msi/TestData/FirewallExtensionTests/IgnoreFailedFirewallRules/product.wxs new
+35
@@ -0,0 +1,35 @@
1 +<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2 +
3 +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:fw="http://wixtoolset.org/schemas/v4/wxs/firewall">
4 + <Fragment>
5 + <ComponentGroup Id="ProductComponents">
6 + <ComponentRef Id="FirewallComponent3"/>
7 + </ComponentGroup>
8 +
9 + <Property Id="RULENAME" Secure="yes" />
10 + <CustomAction Id="SetRuleNameDefaultValue" Property="RULENAME" Value="WiXToolset401 Test - 0008 removal" Execute="firstSequence" />
11 +
12 + <InstallExecuteSequence>
13 + <Custom Action="SetRuleNameDefaultValue" After="AppSearch" Condition="NOT NORULENAME" />
14 + </InstallExecuteSequence>
15 +
16 + </Fragment>
17 +
18 + <Fragment>
19 + <Component Id="FirewallComponent3" Guid="AA693149-B39C-4012-9DDE-92AB0CEA2386" Directory="INSTALLFOLDER" Transitive="yes">
20 + <File Source="$(sys.SOURCEFILEPATH)" KeyPath="yes" >
21 + <fw:FirewallException Id="FirewallException6"
22 + Description="WiX Toolset firewall exception rule integration test | ignore failed app properties"
23 + Name="WiXToolset401 Test - 0006 pipe" Scope="any" IgnoreFailure="yes" />
24 + </File>
25 + <fw:FirewallException Id="FirewallException7"
26 + Description="WiX Toolset firewall exception rule integration test | ignore failed port properties"
27 + Name="WiXToolset401 Test - 0007 pipe" Scope="any" Port="65123" IgnoreFailure="yes" />
28 +
29 + <fw:FirewallException Id="FirewallException8"
30 + Description="WiX Toolset firewall exception rule integration test - removal test"
31 + Name="[RULENAME]" Scope="any" Port="52390" Program="test.exe"
32 + IgnoreFailure="yes" />
33 + </Component>
34 + </Fragment>
35 +</Wix>
src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs
+40 -2
@@ -144,7 +144,7 @@ namespace WixToolsetTest.MsiE2E
144 var product = this.CreatePackageInstaller("FirewallRules");
145 product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
146
147 - Verifier.RemoveFirewallRulesByName("WiXToolset401 Test - 0002");
147 + Verifier.RemoveFirewallRuleByName("WiXToolset401 Test - 0002");
148 Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0002"));
149
150 product.RepairProduct(MSIExec.MSIExecReturnCode.SUCCESS);
@@ -176,7 +176,7 @@ namespace WixToolsetTest.MsiE2E
176 var product = this.CreatePackageInstaller("FirewallRules");
177 product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
178
179 - Verifier.RemoveFirewallRulesByName("WiXToolset401 Test - 0001");
179 + Verifier.RemoveFirewallRuleByName("WiXToolset401 Test - 0001");
180 Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0001"));
181
182 product.RepairProduct(MSIExec.MSIExecReturnCode.SUCCESS);
@@ -277,5 +277,43 @@ namespace WixToolsetTest.MsiE2E
277 Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0004"));
278 Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0005 - 9999"));
279 }
280 +
281 + [RuntimeFact]
282 + public void SucceedWhenIgnoreOnFailureIsSet()
283 + {
284 + var product = this.CreatePackageInstaller("IgnoreFailedFirewallRules");
285 + var log1 = product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
286 +
287 + Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0006 pipe"));
288 + Assert.True(LogVerifier.MessageInLogFile(log1, "failed to add app to the authorized apps list"));
289 +
290 + Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0007 pipe"));
291 + Assert.True(LogVerifier.MessageInLogFile(log1, "failed to add app to the authorized ports list"));
292 +
293 + var expected = new RuleDetails("WiXToolset401 Test - 0008 removal")
294 + {
295 + Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
296 + ApplicationName = "test.exe",
297 + Description = "WiX Toolset firewall exception rule integration test - removal test",
298 + Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
299 + EdgeTraversal = true,
300 + EdgeTraversalOptions = 1,
301 + Enabled = true,
302 + InterfaceTypes = "All",
303 + LocalPorts = "52390",
304 + LocalAddresses = "*",
305 + Profiles = Int32.MaxValue,
306 + Protocol = 6,
307 + RemoteAddresses = "*",
308 + RemotePorts = "*",
309 + SecureFlags = 0,
310 + };
311 +
312 + Verifier.VerifyFirewallRule("WiXToolset401 Test - 0008 removal", expected);
313 + Verifier.RemoveFirewallRuleByName("WiXToolset401 Test - 0008 removal");
314 +
315 + var log2 = product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS, "NORULENAME=1");
316 + Assert.True(LogVerifier.MessageInLogFile(log2, "failed to remove firewall rule"));
317 + }
318 }
319 }