컨텍스트를 Data Flow 연결
데이터 흐름을 지원하는 필터링 계층에서 데이터를 처리하는 설명선의 경우 설명선 드라이버는 컨텍스트를 각 데이터 흐름과 연결할 수 있습니다. 이러한 컨텍스트는 필터 엔진에 불투명합니다. 설명선의 classifyFn 설명선 함수는 이 컨텍스트를 사용하여 다음에 해당 데이터 흐름에 대한 필터 엔진에서 호출할 때 데이터 흐름과 관련된 상태 정보를 저장할 수 있습니다. 필터 엔진은 flowContext 매개 변수를 통해 이 컨텍스트를 설명선의 classifyFn 설명선 함수에 전달합니다. 데이터 흐름과 연결된 컨텍스트가 없는 경우 flowContext 매개 변수는 0입니다.
컨텍스트를 데이터 흐름과 연결하기 위해 설명선의 classifyFn 설명선 함수는 FwpsFlowAssociateContext0 함수를 호출합니다. 예:
// Context structure to be associated with data flows
typedef struct FLOW_CONTEXT_ {
.
. // Driver-specific content
.
} FLOW_CONTEXT, *PFLOW_CONTEXT;
#define FLOW_CONTEXT_POOL_TAG 'fcpt'
// classifyFn callout function
VOID NTAPI
ClassifyFn(
IN const FWPS_INCOMING_VALUES0 *inFixedValues,
IN const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues,
IN OUT VOID *layerData,
IN const FWPS_FILTER0 *filter,
IN UINT64 flowContext,
IN OUT FWPS_CLASSIFY_OUT *classifyOut
)
{
PFLOW_CONTEXT context;
UINT64 flowHandle;
NTSTATUS status;
...
// Check for the flow handle in the metadata
if (FWPS_IS_METADATA_FIELD_PRESENT(
inMetaValues,
FWPS_METADATA_FIELD_FLOW_HANDLE))
{
// Get the flow handle
flowHandle = inMetaValues->flowHandle;
// Allocate the flow context structure
context =
(PFLOW_CONTEXT)ExAllocatePoolWithTag(
NonPagedPool,
sizeof(FLOW_CONTEXT),
FLOW_CONTEXT_POOL_TAG
);
// Check the result of the memory allocation
if (context == NULL)
{
// Handle memory allocation error
...
}
else
{
// Initialize the flow context structure
...
// Associate the flow context structure with the data flow
status = FwpsFlowAssociateContext0(
flowHandle,
FWPS_LAYER_STREAM_V4,
calloutId,
(UINT64)context
);
// Check the result
if (status != STATUS_SUCCESS)
{
// Handle error
...
}
}
}
...
}
컨텍스트가 이미 데이터 흐름과 연결된 경우 먼저 새 컨텍스트를 데이터 흐름과 연결하기 전에 해당 컨텍스트를 제거해야 합니다. 데이터 흐름에서 컨텍스트를 제거하기 위해 설명선의 classifyFn 설명선 함수는 FwpsFlowRemoveContext0 함수를 호출합니다. 예:
// Context structure to be associated with data flows
typedef struct FLOW_CONTEXT_ {
...
} FLOW_CONTEXT, *PFLOW_CONTEXT;
#define FLOW_CONTEXT_POOL_TAG 'fcpt'
// classifyFn callout function
VOID NTAPI
ClassifyFn(
IN const FWPS_INCOMING_VALUES0 *inFixedValues,
IN const FWPS_INCOMING_METADATA_VALUES0 *inMetaValues,
IN OUT VOID *layerData,
IN const FWPS_FILTER0 *filter,
IN UINT64 flowContext,
OUT FWPS_CLASSIFY_OUT *classifyOut
)
{
PFLOW_CONTEXT context;
UINT64 flowHandle;
NTSTATUS status;
...
// Check for the flow handle in the metadata
if (FWPS_IS_METADATA_FIELD_PRESENT(
inMetaValues,
FWPS_METADATA_FIELD_FLOW_HANDLE))
{
// Get the flow handle
flowHandle = inMetaValues->flowHandle;
// Check whether there is a context associated with the data flow
if (flowHandle != 0)
{
// Get a pointer to the flow context structure
context = (PFLOW_CONTEXT)flowContext;
// Remove the flow context structure from the data flow
status = FwpsFlowRemoveContext0(
flowHandle,
FWPS_LAYER_STREAM_V4,
calloutId
);
// Check the result
if (status != STATUS_SUCCESS)
{
// Handle error
...
}
// Cleanup the flow context structure
...
// Free the memory for the flow context structure
ExFreePoolWithTag(
context,
FLOW_CONTEXT_POOL_TAG
);
}
}
...
}
이전 예제에서 calloutId 변수는 설명선에 대한 런타임 식별자를 포함합니다. 런타임 식별자는 콜아웃 드라이버가 필터 엔진에 콜아웃을 등록할 때 콜아웃 드라이버에 반환된 것과 동일한 식별자입니다.