Page 1 of 1

Help with Windows Firewall with Advanced Security

Posted: Mon Aug 04, 2008 8:55 pm
by SFSxOI
Hi;

I'm starting to mess around with the Windows Firewall with Advanced Security API in Vista, located at : http://msdn.microsoft.com/en-us/library ... S.85).aspx

I'm adding an application rule by converting the code here : http://msdn.microsoft.com/en-us/library ... S.85).aspx

Here is the code I have so far:

Code: Select all

Enumeration ;NET_FW_PROFILE_TYPE2
#NET_FW_PROFILE2_DOMAIN    = $0001
#NET_FW_PROFILE2_PRIVATE   = $0002
#NET_FW_PROFILE2_PUBLIC    = $0004
#NET_FW_PROFILE2_ALL       = $7FFFFFFF
EndEnumeration

Enumeration ;NET_FW_ACTION
#NET_FW_ACTION_BLOCK
#NET_FW_ACTION_ALLOW
#NET_FW_ACTION_MAX
EndEnumeration

#NET_FW_IP_PROTOCOL_TCP = 6

Interface INetFwPolicy2 Extends IDispatch
  get_BlockAllInboundTraffic(x)
  put_BlockAllInboundTraffic(x)
  get_CurrentProfileTypes(x)
  get_DefaultInboundAction(x)
  put_DefaultInboundAction(x)
  get_DefaultOutboundAction(x, y)
  put_DefaultOutboundAction(x, y)
  get_ExcludedInterfaces(x)
  put_ExcludedInterfaces(x)
  get_FirewallEnabled(x)
  put_FirewallEnabled(x)
  get_IsRuleGroupCurrentlyEnabled(x, y)
  get_IsRuleGroupEnabled(x, y, z)
  get_LocalPolicyModifyState(x)
  get_NotificationsDisabled(x)
  put_NotificationsDisabled(x)
  get_Rules(x)
  get_ServiceRestriction(x)
  get_UnicastResponsesToMulticastBroadcastDisabled(x)
  put_UnicastResponsesToMulticastBroadcastDisabled(x)
EndInterface

Interface INetFwRule Extends IDispatch
  get_Action(x)
  put_Action(x)
  get_Name(x)
  put_Name(x.s)
  get_Description(x)
  put_Description(x.s)
  get_ApplicationName(x)
  put_ApplicationName(x.s)
  get_ServiceName(x)
  put_ServiceName(x)
  get_Protocol(x)
  put_Protocol(x)
  get_LocalPorts(x)
  put_LocalPorts(x.s)
  get_RemotePorts(x)
  put_RemotePorts(x)
  get_LocalAddresses(x)
  put_LocalAddresses(x)
  get_RemoteAddresses(x)
  put_RemoteAddresses(x)
  get_IcmpTypesAndCodes(x)
  put_IcmpTypesAndCodes(x)
  get_Direction(x)
  put_Direction(x)
  get_Interfaces(x)
  put_Interfaces(x)
  get_InterfaceType(x)
  put_InterfaceTypes(x)
  get_Enabled(x)
  put_Enabled(x)
  get_Grouping(x)
  put_Grouping(x.s)
  get_Profiles(x)
  put_Profiles(x)
  get_EdgeTraversal(x)
  put_EdgeTraversal(x)
EndInterface

Interface INetFwRules Extends IDispatch
  get_Count(a) 
  Add(a) 
  Remove(a) 
  Item(a,b) 
  get__NewEnum(a) 
EndInterface

CoInitialize_(0) 
  
If CoCreateInstance_(?CLSID_NetFwPolicy2,0,1,?IID_INetFwPolicy2,@fwPolicy2_obj.INetFwPolicy2) = 0

fwPolicy2_obj\get_Rules(@RulesObject.INetFwRules)

fwPolicy2_obj\get_CurrentProfileTypes(@CurrentProfile.INetFwPolicy2)

If CoCreateInstance_(?CLSID_NetFwRule,0,1,?IID_INetFwRule,@NewRule_obj.INetFwRule)


NewRule_obj\put_Name("My Application Name")
NewRule_obj\put_Description("Allow my application network traffic")
NewRule_obj\put_ApplicationName("%systemDrive%\\Program Files\\MyApplication.exe")
NewRule_obj\put_Protocol(#NET_FW_IP_PROTOCOL_TCP)
NewRule_obj\put_LocalPorts("4000")
NewRule_obj\put_Enabled(#VARIANT_FALSE)
NewRule_obj\put_Grouping("@firewallapi.dll,-23255")
NewRule_obj\put_Profiles(CurrentProfile)
NewRule_obj\put_Action(#NET_FW_ACTION_MAX)
EndIf 

;Add a new rule
RulesObject\add(NewRule_obj)

EndIf 

CoUninitialize_()

DataSection
  CLSID_NetFwPolicy2:
    Data.l $E2B3C97F 
    Data.w $6AE1,$41AC
    Data.b $81,$7A,$F6,$F9,$21,$66,$D7,$DD
  IID_INetFwPolicy2:
    Data.l $98325047 
    Data.w $C671,$4174
    Data.b $8D,$81,$DE,$FC,$D3,$F0,$31,$86
  CLSID_NetFwRule:
    Data.l $2C5BC43E 
    Data.w $3369, $4C33
    Data.b $AB,$0C,$BE,$94,$69,$67,$7A,$F4
  IID_INetFwRule:
    Data.l $AF230D27 
    Data.w $BABA,$4E42
    Data.b $AC,$ED,$F5,$24,$F2,$2C,$FC,$E2
  IID_INetFwRules:
  Data.l $9C4C6277 
  Data.w $5027, $441E
  Data.b $AF,$AE,$CA,$1F,$54,$2D,$A0,$09
EndDataSection
It always fails at this line:

Code: Select all

RulesObject\add(NewRule_obj)
It fails with this error: [ERROR] Invalid memory access. (read error at address 0)

I can't seem to get rid of the error, what am I doing wrong? Any help appreciated.

Thank You.

Posted: Tue Aug 05, 2008 8:45 am
by idle
Sorry I can't help no vista, maybe it just wants the address of the the of the data passed in the function call. @data

Posted: Tue Aug 05, 2008 12:32 pm
by SFSxOI
idle,

thought about that, doesn't seem to work either. This should work as is but doesn't. :(

Maybe I crreated the RulesObject wrong or something, dunno.

Posted: Tue Aug 05, 2008 1:01 pm
by idle
I can't even get it to pass go. CoCreateInstance_ returns false probably to do with different guid's on xp or is there something else I need to do access com

Posted: Tue Aug 05, 2008 1:18 pm
by srod
Well, the interface string arguments need to be in BSTR form. Try adding the p-bstr pseudotype to all relevant interface method parameters etc.

Posted: Tue Aug 05, 2008 1:34 pm
by SFSxOI
@ idle, its Vista only.

@srod, yep I tried that also, still no go. It should work with just strings tho as the VB Script for it works with strings also...the C++ implementation takes the BSTR , but i'll try the BSTR again. But everything else seems to work fine as it is, just not the 'RulesObject\add(NewRule_obj)'

Hey, I just realized something... The VB Script...at the:

Code: Select all

RulesObject\add(NewRule_obj)
The interface is INetFwRules and the method is Add. In looking at the definition for that method it says:
(http://msdn.microsoft.com/en-us/library ... S.85).aspx)

Code: Select all

 VBScript 
Syntax

Sub Add( _
  ByVal rule _
)Parameters
rule 
Rule to be add to the collection via an INetFwRule object.

Return Value
This method does not return a value. 
The INetFwRule object is NewRule_obj.

But what is the 'collection'? I mean I know what a colletion is, but how do you implement a collection in code in PB? I see the MSDN makes reference to it in relation to .Net code.

I see the Dim statements too. I wonder if something has to be deminsioned first?

Kinda strange this won't work tho. I can do the same thing in the normal windows firewall API (with the only difference really being is that it only adds to the inbound side and you dont have control over the outbound with the normal windows firewall API). I can use the same basic method with the normal windows firewall API and it works fine, of course the interfaces are different but have the same basic function/methods in them just named differently and there are fewer of them.

I found a collection object thing in the MSDN, its for .Net but its as close to what i can find for what I need I think, its at: http://msdn.microsoft.com/en-us/library ... S.80).aspx - its uses the VB Dim statement to dimension the collection.

It has a VB implementation that says this:

"Once you have created a collection, you can do any of the following:

Add an element with the Add Method."

So does a collection need to be created first? And is that what is cause my problems at the 'RulesObject\add(NewRule_obj)' in that 'NewRule_obj' is not a collection ? How would I dim it as a collection?

Posted: Tue Aug 05, 2008 1:50 pm
by srod
fwPolicy2_obj\get_Rules() is failing. Also you need an '=#S_OK' at the end of the second CoCreateInstance_() etc.

Posted: Tue Aug 05, 2008 3:06 pm
by srod
Right, I'm getting somewhere - slowly!!! Your interfaces are all topsy-turvy!!!

I'm using COMLIB and I can, with what appear to be the correct interfaces, run the program without a crash. The final RulesObject\Add(NewRule) is reporting an error (no crash), but this could be my setup in which I have disabled the Win firewall etc.

I'll test some more.


**EDIT : okay I have it running with the aid of COMLIB. I'll try and get your code working now. Beings as you had the interface definitions a bit mixed up, I wonder about the GUID's though?

Posted: Tue Aug 05, 2008 3:12 pm
by srod
Okay, the following runs and reports no errors here. Whether it does what you intend is another matter though? :)

**EDIT : yep, seems to work. It certainly added an 'exception' to the Window's firewall control panel dialog etc.

Code: Select all

Enumeration ;NET_FW_PROFILE_TYPE2 
#NET_FW_PROFILE2_DOMAIN    = $0001 
#NET_FW_PROFILE2_PRIVATE   = $0002 
#NET_FW_PROFILE2_PUBLIC    = $0004 
#NET_FW_PROFILE2_ALL       = $7FFFFFFF 
EndEnumeration 

Enumeration ;NET_FW_ACTION 
#NET_FW_ACTION_BLOCK 
#NET_FW_ACTION_ALLOW 
#NET_FW_ACTION_MAX 
EndEnumeration 

#NET_FW_IP_PROTOCOL_TCP = 6 

Interface INetFwPolicy2 Extends IDispatch 
  get_CurrentProfileTypes(a)
  get_FirewallEnabled(a,b)
  put_FirewallEnabled(a,b)
  get_ExcludedInterfaces(a,b)
  put_ExcludedInterfaces(a,b,c,d,e)
  get_BlockAllInboundTraffic(a,b)
  put_BlockAllInboundTraffic(a,b)
  get_NotificationsDisabled(a,b)
  put_NotificationsDisabled(a,b)
  get_UnicastResponsesToMulticastBroadcastDisabled(a,b)
  put_UnicastResponsesToMulticastBroadcastDisabled(a,b)
  get_Rules(a)
  get_ServiceRestriction(a)
  EnableRuleGroup(a,b,c)
  IsRuleGroupEnabled(a,b,c)
  RestoreLocalFirewallDefaults()
  get_DefaultInboundAction(a,b)
  put_DefaultInboundAction(a,b)
  get_DefaultOutboundAction(a,b)
  put_DefaultOutboundAction(a,b)
  get_IsRuleGroupCurrentlyEnabled(a,b)
  get_LocalPolicyModifyState(a)
EndInterface 

Interface INetFwRule Extends IDispatch 
  get_Name(x) 
  put_Name(x.p-bstr) 
  get_Description(x) 
  put_Description(x.p-bstr) 
  get_ApplicationName(x) 
  put_ApplicationName(x.p-bstr) 
  get_ServiceName(x) 
  put_ServiceName(x) 
  get_Protocol(x) 
  put_Protocol(x) 
  get_LocalPorts(x) 
  put_LocalPorts(x.p-bstr) 
  get_RemotePorts(x) 
  put_RemotePorts(x) 
  get_LocalAddresses(x) 
  put_LocalAddresses(x) 
  get_RemoteAddresses(x) 
  put_RemoteAddresses(x) 
  get_IcmpTypesAndCodes(x) 
  put_IcmpTypesAndCodes(x) 
  get_Direction(x) 
  put_Direction(x) 
  get_Interfaces(x) 
  put_Interfaces(x) 
  get_InterfaceType(x) 
  put_InterfaceTypes(x) 
  get_Enabled(x) 
  put_Enabled(x) 
  get_Grouping(x) 
  put_Grouping(x.p-bstr) 
  get_Profiles(x) 
  put_Profiles(x) 
  get_EdgeTraversal(x) 
  put_EdgeTraversal(x) 
  get_Action(x) 
  put_Action(x) 
EndInterface 

Interface INetFwRules Extends IDispatch 
  get_Count(a) 
  Add(a) 
  Remove(a) 
  Item(a,b) 
  get__NewEnum(a) 
EndInterface 

CoInitialize_(0) 
  
If CoCreateInstance_(?CLSID_NetFwPolicy2,0,1,?IID_INetFwPolicy2,@fwPolicy2_obj.INetFwPolicy2) = #S_OK

  fwPolicy2_obj\get_Rules(@RulesObject.INetFwRules) 

  fwPolicy2_obj\get_CurrentProfileTypes(@CurrentProfile) 

  If CoCreateInstance_(?CLSID_NetFwRule,0,1,?IID_INetFwRule,@NewRule_obj.INetFwRule) = #S_OK
    NewRule_obj\put_Name("My Application Name") 
    NewRule_obj\put_Description("Allow my application network traffic") 
    NewRule_obj\put_ApplicationName("%systemDrive%\\Program Files\\MyApplication.exe")
    NewRule_obj\put_Protocol(#NET_FW_IP_PROTOCOL_TCP) 
    NewRule_obj\put_LocalPorts("4000") 
    NewRule_obj\put_Enabled(#VARIANT_FALSE) 
    NewRule_obj\put_Grouping("@firewallapi.dll,-23255") 
    NewRule_obj\put_Profiles(CurrentProfile) 
    NewRule_obj\put_Action(#NET_FW_ACTION_MAX) 

    ;Add a new rule 
      RulesObject\add(NewRule_obj)

    NewRule_obj\Release()
  EndIf 
  fwPolicy2_obj\Release()
EndIf 

CoUninitialize_() 

DataSection 
  CLSID_NetFwPolicy2: 
    Data.l $E2B3C97F 
    Data.w $6AE1,$41AC 
    Data.b $81,$7A,$F6,$F9,$21,$66,$D7,$DD 
  IID_INetFwPolicy2: 
    Data.l $98325047 
    Data.w $C671,$4174 
    Data.b $8D,$81,$DE,$FC,$D3,$F0,$31,$86 
  CLSID_NetFwRule: 
    Data.l $2C5BC43E 
    Data.w $3369, $4C33 
    Data.b $AB,$0C,$BE,$94,$69,$67,$7A,$F4 
  IID_INetFwRule: 
    Data.l $AF230D27 
    Data.w $BABA,$4E42 
    Data.b $AC,$ED,$F5,$24,$F2,$2C,$FC,$E2 
  IID_INetFwRules: 
  Data.l $9C4C6277 
  Data.w $5027, $441E 
  Data.b $AF,$AE,$CA,$1F,$54,$2D,$A0,$09 
EndDataSection 

Posted: Tue Aug 05, 2008 6:11 pm
by SFSxOI
Thanks srod,

So you had to use the comlib? on XP or Vista?

and thats all it was, straighten out the interfaces a little and a p-bstr and #S_OK ? I did the interfaces by hand, wish i had an interface generator, saw one in the forums but the links dead.

I see you added the releases also, i forgot those.

I'm gonna give it a whirl now and see what happens.

Thank You very much. :)

Posted: Tue Aug 05, 2008 6:16 pm
by srod
I also changed 'CurrentProfile' to a simple 'long' type variable.

I used comlib first, my next step would have been to use PureDispHelper as this avoids explicit use of interfaces through automation etc. Comlib didn't actually give any advantage as I still needed the interfaces, but yes, an interface generator came to my assistance when I concluded that at least one of your interface definitions must be wrong.

I think I missed one ...\Release() in my code above.

Posted: Tue Aug 05, 2008 6:41 pm
by SFSxOI
In regards to puredisphelper; i came across it when i was searching around the forum. Maybe this would be a good time to check it out for use with this project too.

EDIT: OK, going to use puredisphelper in the final version for personal use version. But....Found the S.M. interface generator in the forum so going to use the interfaces from interface generator for the posted version as it might help someone to see the whole thing

Posted: Tue Aug 05, 2008 9:36 pm
by srod
It's good; offering simple access to those COM objects which offer automation through an iDispatch interface etc. Not as direct as using QueryInterface() etc. (and thus not as fast), but it is very useful when you're not sure about individual interface definitions! :wink: