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
}