How can I inspect packets dropped by another filters?

I create my sublayer and assign zero weight to it. Then I create filters with callouts on following layers: FWPM_LAYER_IPFORWARD_V4_DISCARD, FWPM_LAYER_INBOUND_IPPACKET_V4_DISCARD, FWPM_LAYER_OUTBOUND_IPPACKET_V4_DISCARD, FWPM_LAYER_INBOUND_TRANSPORT_V4_DISCARD, FWPM_LAYER_INBOUND_TRANSPORT_V4_DISCARD, FWPM_LAYER_OUTBOUND_TRANSPORT_V4_DISCARD, FWPM_LAYER_STREAM_V4_DISCARD, FWPM_LAYER_DATAGRAM_DATA_V4_DISCARD and DISCARDS on ALE layers. All these filters assigned at my sublayer. I don’t assign any conditions to filters, because I want to catch all discarded packets.
To test project I use “Program” that blocks all outgoing traffic and works only on following layers: FWPM_LAYER_INBOUND_IPPACKET_V4, FWPM_LAYER_OUTBOUND_IPPACKET_V4, FWPM_LAYER_IPFORWARD_V4 and on corresponding discards.
In my mind it must work so: “Program” blocks packet, packet goes to some other sublayers and finally packet goes to my sublayer with inspection filters. I use DbgPrint() function in classify function to identify if callout is invoked. When I send some packet, “Program” drops it, but my classify functions don’t start.

Also I have some questions:

  1. Is my thought is clear that all dropped packets wil go to discard layers on all sublayers?
  2. If no, how can I inspect if packet was dropped by another filter on another sublayer?
  3. Can I attach my own filter on another’s sublayer?

This my functions for adding and registering callouts:
NTSTATUS AddDefault(
LPCWSTR calloutName,
LPCWSTR calloutDescription,
const GUID calloutKey,
const GUID layerKey,
LPCWSTR filterName,
LPCWSTR filterDescription,
const GUID filterKey
)
{
NTSTATUS status;
FWPM_CALLOUT0 callout = { 0 };
FWPM_FILTER0 filter;

	RtlZeroMemory(&filter, sizeof(FWPM_FILTER0));

	callout.calloutKey = GUIDcallout;
	callout.displayData.name = wstrName;
	callout.displayData.description = wstrDescription;
	callout.applicableLayer = GUIDlayer;
	callout.providerKey = (GUID *)&GUIDprovider;

	status = FwpmCalloutAdd0(g_hEngine, &callout, NULL, NULL);
	if (!NT_SUCCESS(status))
	{
		PRINT_ERR("FwpmCalloutAdd0 failed", status);
		goto Exit;
	}

	filter.providerKey = (GUID *)&GUIDprovider;
	filter.displayData.name = wstrName;
	filter.displayData.description = wstrDescription;
	filter.layerKey = GUIDlayer;
	filter.subLayerKey = GUIDsublayer;
	filter.numFilterConditions = 0;
	filter.filterCondition = NULL;
	filter.action.type = FWP_ACTION_CALLOUT_INSPECTION;\
	filter.action.calloutKey = GUIDcallout;
	filter.filterKey = GUIDfilter;
	filter.weight.type = FWP_EMPTY;
	filter.flags = FWPM_FILTER_FLAG_NONE;

	status = FwpmFilterAdd0(g_hEngine, &filter, NULL, NULL);

	if (!NT_SUCCESS(status))
	{
		PRINT_ERR("FwpmFilterAdd0 failed", status);
		goto Exit;
	}

Exit:
	return status;
}

NTSTATUS RegisterDefault(
	PDEVICE_OBJECT pDevice,
	const GUID calloutKey,
	FWPS_CALLOUT_CLASSIFY_FN0 classifyFn,
	FWPS_CALLOUT_FLOW_DELETE_NOTIFY_FN0 flowDeleteFn,
	FWPS_CALLOUT_NOTIFY_FN0 notifyFn
)
{
	FWPS_CALLOUT0 calloutInitData = { 0 };
	calloutInitData.calloutKey = calloutKey;
	calloutInitData.classifyFn = classifyFn;
	calloutInitData.flowDeleteFn = flowDeleteFn;
	calloutInitData.notifyFn = notifyFn;

	return FwpsCalloutRegister0(pDevice, &calloutInitData, NULL);
}