internal FWPM_FILTER0 ToStruct(DisposableList list)
        {
            FWPM_FILTER0 ret = new FWPM_FILTER0();

            ret.filterKey               = FilterKey;
            ret.layerKey                = LayerKey;
            ret.subLayerKey             = SubLayerKey;
            ret.displayData.name        = Name;
            ret.displayData.description = Description;
            ret.flags       = Flags;
            ret.weight      = Weight.ToStruct(list);
            ret.action.type = ActionType;
            if (ActionType.HasFlag(FirewallActionType.Callout))
            {
                ret.action.action.calloutKey = CalloutKey;
            }
            else
            {
                ret.action.action.filterType = FilterType;
            }
            if (ProviderKey != Guid.Empty)
            {
                ret.providerKey = list.AddStructureRef(ProviderKey).DangerousGetHandle();
            }

            if (Conditions.Count > 0)
            {
                ret.numFilterConditions = Conditions.Count;
                ret.filterCondition     = list.AddList(Conditions.Select(c => c.ToStruct(list))).DangerousGetHandle();
            }

            return(ret);
        }
        internal FirewallFilter(FWPM_FILTER0 filter, FirewallEngine engine, Func <SecurityInformation, bool, NtResult <SecurityDescriptor> > get_sd)
            : base(filter.filterKey, filter.displayData, new NamedGuidDictionary(), engine, get_sd)
        {
            ActionType = filter.action.type;
            if (ActionType.HasFlag(FirewallActionType.Callout))
            {
                CalloutKey     = filter.action.action.calloutKey;
                CalloutKeyName = NamedGuidDictionary.CalloutGuids.Value.GetName(CalloutKey);
            }
            else
            {
                FilterType = filter.action.action.filterType;
            }
            LayerKey        = filter.layerKey;
            LayerKeyName    = NamedGuidDictionary.LayerGuids.Value.GetName(LayerKey);
            SubLayerKey     = filter.subLayerKey;
            SubLayerKeyName = NamedGuidDictionary.SubLayerGuids.Value.GetName(SubLayerKey);
            Flags           = filter.flags;

            List <FirewallFilterCondition> conditions = new List <FirewallFilterCondition>();

            if (filter.numFilterConditions > 0)
            {
                var conds = new SafeHGlobalBuffer(filter.filterCondition, 1, false);
                conds.Initialize <FWPM_FILTER_CONDITION0>((uint)filter.numFilterConditions);
                conditions.AddRange(conds.ReadArray <FWPM_FILTER_CONDITION0>(0, filter.numFilterConditions).Select(c => new FirewallFilterCondition(c)));
            }
            Conditions      = conditions.AsReadOnly();
            Weight          = new FirewallValue(filter.weight, Guid.Empty);
            EffectiveWeight = new FirewallValue(filter.effectiveWeight, Guid.Empty);
            if (filter.providerKey != IntPtr.Zero)
            {
                ProviderKey = filter.providerKey.ReadGuid() ?? Guid.Empty;
            }
            ProviderData = filter.providerData.ToArray();
            FilterId     = filter.filterId;
        }