Invalid Enumerator when trying to add a filter using WFP by C #

1

I'm trying to port a c ++ code for C #. My goal is to block a site using WFP. After translating the code, it seems that I made a mistake because when I add a filter I receive the message "An enumerator is not valid" (FWP_E_INVALID_ENUMERATOR).

I've checked the code several times, including debugging along with the original code and I could not find what's wrong. The code is too long because it contains declarations of structures, enumerators, and methods of calling api from windows. Therefore, I leave below only the excerpt that you are throwing. The complete code can be found in the pastebin from this link .

var filterConditions = new List<FWPM_FILTER_CONDITION0_>();
filterConditions.Add(new FWPM_FILTER_CONDITION0_ {
    fieldKey = FWPM_CONDITION_IP_REMOTE_ADDRESS,
    matchType = FWP_MATCH_TYPE_.FWP_MATCH_EQUAL,
    conditionValue = new FWP_CONDITION_VALUE0_
    {
        type = FWP_DATA_TYPE_.FWP_V4_ADDR_MASK,
        v4AddrMask = site.ToIntPtr() // site é um objeto do tipo FWP_V4_ADDR_AND_MASK_
    }
});

var filterIn = new FWPM_FILTER0_ {
    subLayerKey = _subLayerGuid,
    layerKey = FWPM_LAYER_INBOUND_IPPACKET_V4,
    displayData = new FWPM_DISPLAY_DATA0_ { name = "Filter Name" },
    action = new FWPM_ACTION0_ { type = NativeConstants.FWP_ACTION_BLOCK },
    filterCondition = filterConditions.ToIntPtr(),
    numFilterConditions = (uint)filterConditions.Count,
    weight = new FWP_VALUE0_
    {
        type = FWP_DATA_TYPE_.FWP_UINT8,
        uint8 = 0x00
    }
};

var hr = NativeMethods.FwpmEngineOpen0(null, RPC_C_AUTHN_WINNT, IntPtr.Zero, IntPtr.Zero, ref _engineHandle);
Marshal.ThrowExceptionForHR((int)hr);

hr = NativeMethods.FwpmSubLayerAdd0(_engineHandle, ref subLayer, IntPtr.Zero);
Marshal.ThrowExceptionForHR((int)hr);

hr = NativeMethods.FwpmFilterAdd0(_engineHandle, ref filterIn, IntPtr.Zero, ref filterIn.filterId);
Marshal.ThrowExceptionForHR((int)hr); // aqui recebo a exception FWP_E_INVALID_ENUMERATOR

I've been having this problem for days unresolved. I put a question on the stackoverflow in English and I got some downvotes so I know I've done a lot of research to carry this code (do not have the necessary references on pinvoke.net) and if something is not clear, please comment that I add any necessary information. / p>     

asked by anonymous 01.06.2016 / 01:20

1 answer

0

At the end of the day, I discovered what it was. The problem was in the translation of the structs that contain union. An example is the struct below:

typedef struct FWP_VALUE0_ {
  FWP_DATA_TYPE type;
  union {
    ;      // case(FWP_EMPTY)
    UINT8                 uint8;
    UINT16                uint16;
    UINT32                uint32;
    UINT64                *uint64;
    INT8                  int8;
    INT16                 int16;
    INT32                 int32;
    INT64                 *int64;
    float                 float32;
    double                *double64;
    FWP_BYTE_ARRAY16      *byteArray16;
    FWP_BYTE_BLOB         *byteBlob;
    SID                   *sid;
    FWP_BYTE_BLOB         *sd;
    FWP_TOKEN_INFORMATION *tokenInformation;
    FWP_BYTE_BLOB         *tokenAccessInformation;
    LPWSTR                unicodeString;
    FWP_BYTE_ARRAY6       *byteArray6;
  };
} FWP_VALUE0;

In translating it, I simply ignored the union. Getting the code in C # like this:

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct FWP_VALUE0_
{
    public FWP_DATA_TYPE_ type;
    public byte uint8;
    public ushort uint16;
    public uint uint32;
    public System.IntPtr uint64;
    public byte int8;
    public short int16;
    public int int32;
    public System.IntPtr int64;
    public float float32;
    public System.IntPtr double64;
    public System.IntPtr byteArray16;
    public System.IntPtr byteBlob;
    public System.IntPtr sid;
    public System.IntPtr sd;
    public System.IntPtr tokenInformation;
    public System.IntPtr tokenAccessInformation;
    public System.IntPtr unicodeString;
    public System.IntPtr byteArray6;
}

The problem is that, as I understand it, doing so is putting each of the values in sequence in memory. The union allows all values within it to occupy the same position, which consequently allows me to use one of the values. In this way, the correct translation would look like this:

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)]
public struct UnionType
{
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public byte uint8;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public ushort uint16;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public uint uint32;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public System.IntPtr uint64;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public byte int8;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public short int16;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public int int32;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public System.IntPtr int64;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public float float32;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public System.IntPtr double64;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public System.IntPtr byteArray16;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public System.IntPtr byteBlob;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public System.IntPtr sid;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public System.IntPtr sd;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public System.IntPtr tokenInformation;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public System.IntPtr tokenAccessInformation;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public System.IntPtr unicodeString;
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
    public System.IntPtr byteArray6;
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct FWP_VALUE0_
{
    public FWP_DATA_TYPE_ type;
    public UnionType Union1;
}

Note the StructLayout attribute on UnionType as Explicit. Which forces me to speak the offset of each of the values. And then, all values have the same offset (0) which causes everyone to occupy the same position.

    
03.06.2016 / 23:28