Skip to content

Commit 3ff1189

Browse files
committed
added the possibility of connecting to the remote COM+ server regarding #42
1 parent 97265cf commit 3ff1189

File tree

15 files changed

+533
-214
lines changed

15 files changed

+533
-214
lines changed

WindowsFirewallHelper.Tests/FirewallLegacyTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public void CreateIndirectBadPortRule()
224224
);
225225

226226
// `Any` protocol is not supported with Windows Firewall Legacy in compatibility mode
227-
if (FirewallWAS.IsSupported)
227+
if (FirewallWAS.IsLocallySupported)
228228
{
229229
Assert.Throws<FirewallLegacyNotSupportedException>(() =>
230230
{
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using WindowsFirewallHelper.InternalHelpers;
4+
5+
namespace WindowsFirewallHelper
6+
{
7+
/// <summary>
8+
/// Contains methods facilitating access to local and remove COM+ types
9+
/// </summary>
10+
public class COMTypeResolver
11+
{
12+
/// <summary>
13+
/// Gets the machine name assigned to this instance or <see langword="null"/>
14+
/// </summary>
15+
public string MachineName { get; }
16+
17+
public COMTypeResolver(string machineName)
18+
{
19+
MachineName = machineName;
20+
}
21+
22+
public COMTypeResolver() : this(null)
23+
{
24+
25+
}
26+
27+
internal T CreateInstance<T>()
28+
{
29+
if (!typeof(T).IsInterface)
30+
{
31+
throw new ArgumentException("Invalid generic type passed.", nameof(T));
32+
}
33+
34+
try
35+
{
36+
var progId = ComClassProgIdAttribute.GetClassProgId<T>();
37+
38+
if (!string.IsNullOrWhiteSpace(progId))
39+
{
40+
var typeByProgId = Type.GetTypeFromProgID(progId, MachineName, false);
41+
42+
if (typeByProgId != null)
43+
{
44+
try
45+
{
46+
return (T)Activator.CreateInstance(typeByProgId);
47+
}
48+
catch (COMException)
49+
{
50+
if (MachineName == null)
51+
{
52+
throw;
53+
}
54+
}
55+
}
56+
}
57+
58+
var typeByClassId = Type.GetTypeFromCLSID(typeof(T).GUID, MachineName, false);
59+
60+
if (typeByClassId != null)
61+
{
62+
try
63+
{
64+
return (T)Activator.CreateInstance(typeByClassId);
65+
}
66+
catch (COMException)
67+
{
68+
if (MachineName == null)
69+
{
70+
throw;
71+
}
72+
}
73+
}
74+
}
75+
catch (COMException e)
76+
{
77+
throw new NotSupportedException("Can not create a new instance of this interface in current environment.", e);
78+
}
79+
80+
throw new NotSupportedException("Can not create a new instance of this interface in current environment.");
81+
}
82+
83+
internal bool IsSupported<T>()
84+
{
85+
if (!typeof(T).IsInterface)
86+
{
87+
throw new ArgumentException("Invalid generic type passed.", nameof(T));
88+
}
89+
90+
try
91+
{
92+
return CreateInstance<T>() != null;
93+
}
94+
catch
95+
{
96+
return false;
97+
}
98+
}
99+
}
100+
}

WindowsFirewallHelper/Collections/FirewallLegacyRulesCollection.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@ namespace WindowsFirewallHelper.Collections
99
{
1010
internal class FirewallLegacyRulesCollection : IFirewallLegacyRulesCollection
1111
{
12+
private readonly FirewallLegacy _firewall;
13+
1214
private readonly Dictionary<FirewallProfiles, FirewallLegacyApplicationCollection>
1315
_firewallApplicationCollections;
1416

1517
private readonly Dictionary<FirewallProfiles, FirewallLegacyPortCollection> _firewallPortCollections;
1618
private readonly Dictionary<FirewallProfiles, FirewallLegacyServiceCollection> _firewallServiceCollections;
1719

18-
public FirewallLegacyRulesCollection(FirewallLegacyProfile[] profiles)
20+
public FirewallLegacyRulesCollection(FirewallLegacyProfile[] profiles, FirewallLegacy firewall)
1921
{
22+
_firewall = firewall;
2023
_firewallPortCollections = profiles.ToDictionary(
2124
profile => profile.Type,
2225
profile => new FirewallLegacyPortCollection(profile.UnderlyingObject.GloballyOpenPorts)
@@ -204,7 +207,7 @@ public IEnumerator<IFirewallRule> GetEnumerator()
204207
.Select(group => group.GroupBy(arg => arg.Profile))
205208
.Select(
206209
group => new FirewallLegacyPortRule(
207-
group.ToDictionary(t => t.Key, t => t.Select(arg => arg.Rule).ToArray())
210+
group.ToDictionary(t => t.Key, t => t.Select(arg => arg.Rule).ToArray()), _firewall.TypeResolver
208211
)
209212
)
210213
.OfType<IFirewallRule>();
@@ -247,7 +250,7 @@ public FirewallLegacyApplicationRule this[string applicationPath]
247250
return null;
248251
}
249252

250-
return new FirewallLegacyPortRule(rules);
253+
return new FirewallLegacyPortRule(rules, _firewall.TypeResolver);
251254
}
252255
}
253256

WindowsFirewallHelper/FirewallLegacy.cs

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,26 @@ namespace WindowsFirewallHelper
1616
public class FirewallLegacy : IFirewall
1717
{
1818
/// <summary>
19-
/// Creates a new instance of this class on the current thread and leaves the cross thread control to the user of the
19+
/// Creates a new instance of this class on the current thread for the local machine and leaves the cross thread control to the user of the
2020
/// class.
2121
/// </summary>
22-
public FirewallLegacy()
22+
public FirewallLegacy() : this(new COMTypeResolver())
2323
{
24-
if (!IsSupported)
24+
}
25+
26+
/// <summary>
27+
/// Creates a new instance of this class on the current thread for a remote machine and leaves the cross thread control to the user of the
28+
/// class.
29+
/// </summary>
30+
public FirewallLegacy(COMTypeResolver typeResolver)
31+
{
32+
if (!IsSupported(typeResolver))
2533
{
2634
throw new NotSupportedException("This type is not supported in this environment.");
2735
}
2836

29-
UnderlyingObject = ComHelper.CreateInstance<INetFwMgr>();
30-
37+
TypeResolver = typeResolver;
38+
UnderlyingObject = TypeResolver.CreateInstance<INetFwMgr>();
3139
Profiles = new ReadOnlyCollection<FirewallLegacyProfile>(
3240
new[]
3341
{
@@ -40,10 +48,13 @@ public FirewallLegacy()
4048
/// <inheritdoc />
4149
public IFirewall Reload()
4250
{
43-
UnderlyingObject = ComHelper.CreateInstance<INetFwMgr>();
51+
UnderlyingObject = TypeResolver.CreateInstance<INetFwMgr>();
4452
return this;
4553
}
4654

55+
/// <inheritdoc />
56+
public COMTypeResolver TypeResolver { get; }
57+
4758
/// <summary>
4859
/// Gets the current singleton instance of this class
4960
/// </summary>
@@ -53,11 +64,19 @@ public static FirewallLegacy Instance
5364
}
5465

5566
/// <summary>
56-
/// Gets a Boolean value showing if the firewall is supported in this environment.
67+
/// Gets a Boolean value showing if the firewall is supported locally
68+
/// </summary>
69+
public static bool IsLocallySupported
70+
{
71+
get => IsSupported(new COMTypeResolver());
72+
}
73+
74+
/// <summary>
75+
/// Gets a Boolean value showing if the firewall is supported remotely
5776
/// </summary>
58-
public static bool IsSupported
77+
public static bool IsSupported(COMTypeResolver typeResolver)
5978
{
60-
get => ComHelper.IsSupported<INetFwMgr>();
79+
return typeResolver.IsSupported<INetFwMgr>();
6180
}
6281

6382
/// <summary>
@@ -70,7 +89,7 @@ public static bool IsSupported
7089
/// </summary>
7190
public IFirewallLegacyRulesCollection Rules
7291
{
73-
get => new FirewallLegacyRulesCollection(Profiles.ToArray());
92+
get => new FirewallLegacyRulesCollection(Profiles.ToArray(), this);
7493
}
7594

7695
internal INetFwMgr UnderlyingObject { get; private set; }
@@ -85,11 +104,6 @@ IFirewallRule IFirewall.CreateApplicationRule(
85104
string filename,
86105
FirewallProtocol protocol)
87106
{
88-
if (!IsSupported)
89-
{
90-
throw new NotSupportedException();
91-
}
92-
93107
if (!protocol.Equals(FirewallProtocol.Any))
94108
{
95109
throw new FirewallLegacyNotSupportedException(
@@ -170,18 +184,13 @@ IFirewallRule IFirewall.CreatePortRule(
170184
FirewallProtocol protocol
171185
)
172186
{
173-
if (!IsSupported)
174-
{
175-
throw new NotSupportedException();
176-
}
177-
178187
if (action != FirewallAction.Allow)
179188
{
180189
throw new FirewallLegacyNotSupportedException(
181190
"Windows Firewall Legacy only accepts allow exception rules.");
182191
}
183192

184-
return new FirewallLegacyPortRule(name, portNumber, profiles) {Protocol = protocol};
193+
return new FirewallLegacyPortRule(name, portNumber, profiles, TypeResolver) {Protocol = protocol};
185194
}
186195

187196
/// <inheritdoc />
@@ -282,12 +291,7 @@ public FirewallLegacyApplicationRule CreateApplicationRule(
282291
string filename
283292
)
284293
{
285-
if (!IsSupported)
286-
{
287-
throw new NotSupportedException();
288-
}
289-
290-
return new FirewallLegacyApplicationRule(name, filename, profiles);
294+
return new FirewallLegacyApplicationRule(name, filename, profiles, TypeResolver);
291295
}
292296

293297
/// <summary>
@@ -301,19 +305,14 @@ public FirewallLegacyApplicationRule CreateApplicationRule(
301305
string filename
302306
)
303307
{
304-
if (!IsSupported)
305-
{
306-
throw new NotSupportedException();
307-
}
308-
309308
var activeProfile = GetActiveProfile();
310309

311310
if (activeProfile == null)
312311
{
313312
throw new InvalidOperationException("No firewall profile is currently active.");
314313
}
315314

316-
return new FirewallLegacyApplicationRule(name, filename, activeProfile.Type);
315+
return new FirewallLegacyApplicationRule(name, filename, activeProfile.Type, TypeResolver);
317316
}
318317

319318
/// <summary>
@@ -325,12 +324,7 @@ string filename
325324
/// <returns>Returns the newly created <see cref="FirewallLegacyPortRule" /> instance</returns>
326325
public FirewallLegacyPortRule CreatePortRule(FirewallProfiles profiles, string name, ushort portNumber)
327326
{
328-
if (!IsSupported)
329-
{
330-
throw new NotSupportedException();
331-
}
332-
333-
return new FirewallLegacyPortRule(name, portNumber, profiles) {Protocol = FirewallProtocol.TCP};
327+
return new FirewallLegacyPortRule(name, portNumber, profiles, TypeResolver) {Protocol = FirewallProtocol.TCP};
334328
}
335329

336330
/// <summary>
@@ -342,19 +336,14 @@ public FirewallLegacyPortRule CreatePortRule(FirewallProfiles profiles, string n
342336
/// <returns>Returns the newly created <see cref="FirewallLegacyPortRule" /> instance</returns>
343337
public FirewallLegacyPortRule CreatePortRule(string name, ushort portNumber)
344338
{
345-
if (!IsSupported)
346-
{
347-
throw new NotSupportedException();
348-
}
349-
350339
var activeProfile = GetActiveProfile();
351340

352341
if (activeProfile == null)
353342
{
354343
throw new InvalidOperationException("No firewall profile is currently active.");
355344
}
356345

357-
return new FirewallLegacyPortRule(name, portNumber, activeProfile.Type) {Protocol = FirewallProtocol.TCP};
346+
return new FirewallLegacyPortRule(name, portNumber, activeProfile.Type, TypeResolver) {Protocol = FirewallProtocol.TCP};
358347
}
359348

360349
/// <summary>

WindowsFirewallHelper/FirewallLegacyProfile.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ internal FirewallLegacyProfile(FirewallLegacy firewall, FirewallProfiles profile
2424
/// </summary>
2525
public IFirewallLegacyRulesCollection Rules
2626
{
27-
get => new FirewallLegacyRulesCollection(new[] {this});
27+
get => new FirewallLegacyRulesCollection(new[] { this }, _firewall);
2828
}
2929

3030
internal INetFwProfile UnderlyingObject { get; }

0 commit comments

Comments
 (0)