Jack
Jack

Reputation: 43

How to Open Port in Windows Firewall using C++ Builder?

I get an error when I compile my project in Borland C++Builder:

'Add' is not a member of 'Variant'

I tried to do this using the Automation API, but it gives me the error above:

const NET_FW_PROFILE2_DOMAIN  = 1;
const NET_FW_PROFILE2_PRIVATE = 2;
const NET_FW_PROFILE2_PUBLIC  = 4;

const NET_FW_IP_PROTOCOL_TCP = 6;
const NET_FW_IP_PROTOCOL_UDP = 17;
const NET_FW_ACTION_ALLOW    = 1;
const NET_FW_RULE_DIR_IN  = 1;
const NET_FW_RULE_DIR_OUT = 2;

Variant fwPolicy2, RulesObject, NewRule;
DWORD Profile;

Profile   = NET_FW_PROFILE2_PRIVATE | NET_FW_PROFILE2_PUBLIC;
fwPolicy2 = CreateOleObject("HNetCfg.FwPolicy2");
RulesObject = fwPolicy2.OlePropertyGet("Rules");
NewRule   = CreateOleObject("HNetCfg.FWRule");
NewRule.OlePropertyGet("Name") = "Text Firewall";
NewRule.OlePropertyGet("Description") = "Text Firewall";
NewRule.OlePropertyGet("Applicationname") = "System_RCC.exe";
NewRule.OlePropertyGet("Protocol")   = NET_FW_IP_PROTOCOL_TCP;
NewRule.OlePropertyGet("LocalPorts") = Edit1->Text;
NewRule.OlePropertyGet("Direction")  = NET_FW_RULE_DIR_OUT;
NewRule.OlePropertyGet("Enabled")   = true;
NewRule.OlePropertyGet("Grouping")  = "";
NewRule.OlePropertyGet("Profiles")  = Profile;
NewRule.OlePropertyGet("Action")  = NET_FW_ACTION_ALLOW;
RulesObject.Add(NewRule);

Note: this code is taken from here:

How to open port in Win7 Firewall using Delphi

Upvotes: 1

Views: 446

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 596713

RulesObject is a System::Variant wrapping a COM object.

In Delphi, (Ole)Variant handles access to a COM object's properties and methods transparently for you (the compiler translates the calls into invocations of the IDispatch::GetIDsOfNames() and IDispatch::Invoke() interface methods). That is why the Delphi code you link to is very straight forward.

In C++, however, you have to use the Variant::OleProcedure() or Variant::OleFunction() method to invoke a COM object's methods, just like you have to use the Variant::OleProperty(Get|Set)() methods to access a COM object's properties. The Variant::Ole...() methods perform similar IDispatch invocations that Delphi performs.

In addition, when populating NewRule, you need to use OlePropertySet() instead of OlePropertyGet().

Try this:

const NET_FW_PROFILE2_DOMAIN = 1;
const NET_FW_PROFILE2_PRIVATE = 2;
const NET_FW_PROFILE2_PUBLIC = 4;

const NET_FW_IP_PROTOCOL_TCP = 6;
const NET_FW_IP_PROTOCOL_UDP = 17;
const NET_FW_ACTION_ALLOW = 1;
const NET_FW_RULE_DIR_IN = 1;
const NET_FW_RULE_DIR_OUT = 2;

Variant fwPolicy2, RulesObject, NewRule;
DWORD Profile;

Profile = NET_FW_PROFILE2_PRIVATE | NET_FW_PROFILE2_PUBLIC;
fwPolicy2 = CreateOleObject("HNetCfg.FwPolicy2"); RulesObject = fwPolicy2.OlePropertyGet("Rules");
NewRule = CreateOleObject("HNetCfg.FWRule");
NewRule.OlePropertySet("Name", WideString("Text Firewall"));
NewRule.OlePropertySet("Description", WideString("Text Firewall"));
NewRule.OlePropertySet("Applicationname", WideString("System_RCC.exe"));
NewRule.OlePropertySet("Protocol", NET_FW_IP_PROTOCOL_TCP);
NewRule.OlePropertySet("LocalPorts", Edit1->Text);
NewRule.OlePropertySet("Direction", NET_FW_RULE_DIR_OUT);
NewRule.OlePropertySet("Enabled", true);
NewRule.OlePropertySet("Grouping", WideString(""));
NewRule.OlePropertySet("Profiles", Profile);
NewRule.OlePropertySet("Action", NET_FW_ACTION_ALLOW);
RulesObject.OleProcedure("Add", NewRule);

Upvotes: 1

Related Questions