Does INetFwPolicy2::get_ExcludedInterfaces returning S_OK + VT_EMPTY mean no excluded interfaces?

Lewis 0 Reputation points
2026-11-01T16:55:22.46+00:00

Hello,

Could someone please help clarify the documented contract for INetFwPolicy2::get_ExcludedInterfaces?

The API reference states that an empty list means no excluded interfaces, but I haven’t found a definition of which returned VARIANT encodings represent that empty list.

In a read-only observation using a 64-bit helper in an MTA:

  • COM object creation and the getter both returned S_OK.
  • The requested profile was NET_FW_PROFILE2_DOMAIN.
  • The output VARIANT was initialized before the call and inspected after its confirmed return.
  • The returned tag was VT_EMPTY, rather than an explicit empty SAFEARRAY.

I would appreciate guidance on the following:

  1. Does a successful getter returning VT_EMPTY contractually mean zero excluded interfaces, or can it mean unset or unspecified?
  2. Does this result represent effective policy, including applicable Group Policy, or only local configuration?
  3. How should VT_NULL and an explicit empty SAFEARRAY be interpreted differently?
  4. Are these guarantees version-dependent?

If possible, please point me to the relevant documentation or a clarification from the responsible Microsoft team. I’m trying to establish the supported contract rather than infer a general rule from one observation.

Thank you for taking the time to read this and share your expertise. Any help locating the authoritative guidance would be greatly appreciated.

Windows development | Windows API - Win32
0 comments No comments

2 answers

Sort by: Newest
  1. Nancy Vo (WICLOUD CORPORATION) 8,160 Reputation points Microsoft External Staff Moderator
    2026-11-02T07:16:03.22+00:00

    Hello @Lewis ,

    Thanks for your question.

    S_OK confirms that INetFwPolicy2::get_ExcludedInterfaces completed successfully. However, Microsoft Learn only states that an empty list means no excluded interfaces; it does not define VT_EMPTY as the guaranteed representation of that empty list.

    VT_EMPTY, VT_NULL, and an empty SAFEARRAY are different representations. Microsoft defines VT_EMPTY as "Not specified" and VT_NULL as "Null", while a SAFEARRAY represents an actual array. The firewall API does not state that these are interchangeable.

    The documentation also does not specify whether the result represents local or effective policy including Group Policy, nor does it provide a cross-version guarantee for the empty VARIANT representation.

    Therefore, S_OK + VT_EMPTY is the observed result, but the published Microsoft documentation does not currently provide a supported contract stating that it always means zero excluded interfaces.

    I hope this addresses your question. If this response was helpful, please consider following the guidance to provide feedback. Thank you.

    Was this answer helpful?

    1 person found this answer helpful.

  2. AI answer

    2026-11-01T16:56:46.24+00:00

    A successful get_ExcludedInterfaces call returning VT_EMPTY cannot be treated as a contractually documented encoding of zero excluded interfaces; the supported documentation defines an empty list as no exclusions but does not specify which VARIANT representation constitutes that list.

    What is guaranteed

    The method is per-profile, and NET_FW_PROFILE2_DOMAIN is a valid single profile value. Microsoft states:

    • The property is a list of interfaces on which the firewall does not apply.
    • An empty list means there are no excluded interfaces.
    • Exactly one profile must be supplied; a multi-bit value from CurrentProfileTypes must not be passed directly. ^1^

    Microsoft’s published sample represents a nonempty value as an array of interface names, which confirms the normal populated shape but does not demonstrate the empty case. ^2^

    Interpretation of the returned encodings

    Successful result Supported interpretation
    VT_ARRAY | <element type> with elements The returned interface list, provided the element type and contents are valid for the property.
    Valid SAFEARRAY with zero elements An empty list, therefore no excluded interfaces.
    VT_EMPTY Observed implementation result, but not documented by this API as the empty-list encoding. Generic Automation terminology describes it as “not specified,” not as an empty array.
    VT_NULL A distinct Automation null value. This API does not document any property-specific meaning for it, so it should not be equated with an empty list.
    Any other shape Undocumented for this property; do not infer policy state from it.

    VT_EMPTY and VT_NULL are separate VARENUM values: Microsoft labels them “Not specified” and “Null,” respectively. A SAFEARRAY in a VARIANT uses the VT_ARRAY flag; VT_EMPTY and VT_NULL cannot be combined with VT_ARRAY. ^3^ ^4^

    Consequently, the most defensible contract-level result is:

    S_OK + VT_EMPTY is not documented as either “zero exclusions” or “unset/unspecified” specifically for get_ExcludedInterfaces.

    It may be the current implementation’s representation of the documented empty-list state, but that stronger mapping requires clarification from Microsoft’s Windows Firewall API owner.

    Local policy versus effective policy

    The get_ExcludedInterfaces page does not say whether the value is local-only or the effective result after applicable Group Policy processing. Therefore, VT_EMPTY cannot be used to infer:

    • that local policy contains no configured value;
    • that Group Policy contains no configured value; or
    • that the merged/effective policy contains no exclusions.

    This omission matters because other INetFwPolicy2 properties explicitly document local-versus-effective behavior. For example, get_FirewallEnabled says it reports whether the firewall is enabled locally and that the effective result may differ because of Group Policy. ^5^ No equivalent wording is provided for get_ExcludedInterfaces.

    get_LocalPolicyModifyState can determine whether adding or setting a rule or rule group would take effect, but its documented scope does not establish the source or merge semantics of ExcludedInterfaces. ^6^

    Defensive handling

    Keep the encodings distinct in code rather than silently mapping both VT_EMPTY and VT_NULL to an empty collection:

    VARIANT value;
    VariantInit(&value);
    
    HRESULT hr = policy->get_ExcludedInterfaces(
        NET_FW_PROFILE2_DOMAIN, &value);
    
    if (SUCCEEDED(hr)) {
        if (value.vt & VT_ARRAY) {
            // Enumerate the SAFEARRAY; zero elements means no exclusions.
        } else if (value.vt == VT_EMPTY) {
            // Observed, but API-specific meaning is undocumented.
        } else if (value.vt == VT_NULL) {
            // Undocumented for this property; do not treat as empty.
        } else {
            // Unexpected/undocumented representation.
        }
    }
    VariantClear(&value);
    

    VariantClear releases array contents where applicable and resets the variant to VT_EMPTY; initialized variants should be cleared when no longer needed. ^7^

    Version guarantee

    The method is documented for Windows Vista and Windows Server 2008 onward, but the documentation provides no version-specific encoding rules and no guarantee that VT_EMPTY will remain the empty-list representation across Windows releases. ^1^

    For a supported contractual answer beyond this boundary, request clarification through Microsoft support and ask specifically for:

    1. the allowed VARTYPE values for a successful return;
    2. whether VT_EMPTY means an empty effective list;
    3. the meaning, if any, of VT_NULL;
    4. whether the getter returns local, Group Policy, or merged policy; and
    5. whether those mappings are version-stable.

    References

    1. INetFwPolicy2::get_ExcludedInterfaces method (netfw.h)
    2. Disabling the Firewall per Interface | Microsoft Learn
    3. C28717
    4. VARENUM enumeration (ks.h)
    5. INetFwPolicy2::get_FirewallEnabled method (netfw.h)
    6. INetFwPolicy2::get_LocalPolicyModifyState method (netfw.h)
    7. VariantClear function (oleauto.h)
    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.