다음을 통해 공유


필터 드라이버에서 데이터 보내기

필터 드라이버는 전송 요청을 시작하거나 지나치게 많은 드라이버가 시작하는 송신 요청을 필터링할 수 있습니다. 프로토콜 드라이버가 NdisSendNetBufferLists 함수를 호출하면 NDIS는 지정된 NET_BUFFER_LIST 구조를 드라이버 스택의 최상위 필터 모듈에 제출합니다.

필터 드라이버에서 시작한 요청 보내기

다음 그림에서는 필터 드라이버에서 시작하는 보내기 작업을 보여 줍니다.

NdisFSendNetBufferLists 함수를 사용하여 필터 드라이버에서 시작한 보내기 작업을 보여 주는 다이어그램

필터 드라이버는 NdisFSendNetBufferLists 함수를 호출하여 NET_BUFFER_LIST 구조 목록에 정의된 네트워크 데이터를 보냅니다.

필터 드라이버는 만든 각 NET_BUFFER_LIST 구조체의 SourceHandle 멤버를 NdisFSendNetBufferListsNdisFilterHandle 매개 변수에 전달하는 것과 동일한 값으로 설정해야 합니다. NDIS 드라이버는 드라이버가 시작되지 않은 NET_BUFFER_LIST 구조체에 대해 SourceHandle 멤버를 수정해서는 안 됩니다.

NdisFSendNetBufferLists를 호출하기 전에 필터 드라이버는 NET_BUFFER_LIST_INFO 매크로와 함께 보내기 요청과 함께 정보를 설정할 수 있습니다. 기본 드라이버는 NET_BUFFER_LIST_INFO 매크로를 사용하여 이 정보를 검색할 수 있습니다.

필터 드라이버가 NdisFSendNetBufferLists를 호출하는 즉시 NET_BUFFER_LIST 구조체 및 모든 연결된 리소스의 소유권을 포기합니다. NDIS는 보내기 요청을 처리하거나 기본 드라이버에 요청을 전달할 수 있습니다.

NDIS는 FilterSendNetBufferListsComplete 함수를 호출하여 구조체와 데이터를 필터 드라이버에 반환합니다. NDIS는 목록을 FilterSendNetBufferListsComplete에 전달하기 전에 여러 송신 요청의 구조와 데이터를 NET_BUFFER_LIST 구조의 연결된 단일 목록으로 수집할 수 있습니다.

NDIS가 FilterSendNetBufferListsComplete를 호출할 때까지 전송 요청의 현재 상태 알 수 없습니다. 필터 드라이버는 NDIS가 FilterSendNetBufferListsComplete에 구조를 반환하기 전에 NET_BUFFER_LIST 구조체 또는 연결된 데이터를 검사하지 않아야 합니다.

FilterSendNetBufferListsComplete 는 보내기 작업을 완료하는 데 필요한 후처리를 수행합니다.

NDIS가 FilterSendNetBufferListsComplete를 호출하면 필터 드라이버는 NetBufferLists 매개 변수로 지정된 NET_BUFFER_LIST 구조와 연결된 모든 리소스의 소유권을 되찾습니다. FilterSendNetBufferListsComplete 는 이러한 리소스를 해제하거나(예: NdisFreeNetBufferNdisFreeNetBufferList 함수를 호출하여) NdisFSendNetBufferLists에 대한 후속 호출에서 다시 사용할 수 있도록 준비할 수 있습니다.

NDIS는 항상 NdisFSendNetBufferLists에 전달된 필터 드라이버 결정 순서로 기본 드라이버에 필터 제공 네트워크 데이터를 제출합니다. 그러나 지정된 순서로 데이터를 보낸 후 기본 드라이버는 모든 순서로 버퍼를 반환할 수 있습니다.

필터 드라이버는 시작된 보내기 요청에 대한 루프백을 요청할 수 있습니다. 루프백을 요청하기 위해 드라이버는 NdisFSendNetBufferListsSendFlags 매개 변수에서 NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK 플래그를 설정합니다. NDIS는 전송 데이터가 포함된 수신된 패킷을 나타냅니다.

참고 필터 드라이버는 시작된 송신 요청을 추적하고 이러한 요청이 완료되면 NdisFSendNetBufferListsComplete 함수를 호출하지 않는지 확인해야 합니다.

송신 요청 필터링

다음 그림에서는 오버리싱 드라이버에서 시작하는 송신 요청을 필터링하는 것을 보여 줍니다.

FilterSendNetBufferLists 함수를 사용하여 지나치게 드라이버가 시작한 송신 요청을 필터링하는 프로세스를 보여 주는 다이어그램

NDIS는 필터 드라이버의 FilterSendNetBufferLists 함수를 호출하여 지나치게 많은 드라이버의 보내기 요청을 필터링합니다.

필터 드라이버는 다른 드라이버에서 수신하는 NET_BUFFER_LIST 구조체에서 SourceHandle 멤버를 수정해서는 안 됩니다.

필터 드라이버는 데이터를 필터링하고 필터링된 데이터를 기본 드라이버로 보낼 수 있습니다. FilterSendNetBufferLists에 제출된 각 NET_BUFFER 구조체에 대해 필터 드라이버는 다음을 수행할 수 있습니다.

  • NdisFSendNetBufferLists 함수를 호출하여 버퍼를 다음 기본 드라이버에 전달합니다. NDIS는 필터 드라이버에 대한 컨텍스트 공간( NET_BUFFER_LIST_CONTEXT 구조 참조)의 가용성을 보장합니다. 필터 드라이버는 NdisFSendNetBufferLists를 호출하기 전에 버퍼 콘텐츠를 수정할 수 있습니다. 필터링된 데이터의 처리는 필터 드라이버에서 시작한 보내기 작업과 마찬가지로 진행됩니다.

  • NdisFSendNetBufferListsComplete 함수를 호출하여 버퍼를 삭제합니다.

  • 이후 처리를 위해 로컬 데이터 구조에서 버퍼를 큐에 대기합니다. 필터 드라이버의 디자인은 드라이버가 큐에 대기 중인 버퍼를 처리하게 하는 원인을 지정합니다. 일부 예로는 제한 시간 후 처리 또는 특정 버퍼가 수신된 후의 처리가 포함됩니다.

    참고 드라이버 큐가 나중에 처리하기 위해 요청을 보내는 경우 전송 취소 요청을 지원해야 합니다. 송신 취소 요청에 대한 자세한 내용은 필터 드라이버에서 보내기 요청 취소를 참조하세요.

  • 버퍼를 복사하고 복사본을 사용하여 보내기 요청을 시작합니다. 보내기 작업은 필터 드라이버가 시작한 보내기 요청과 유사합니다. 이 경우 드라이버는 NdisFSendNetBufferListsComplete 함수를 호출하여 원래 버퍼를 오버리딩 드라이버로 반환해야 합니다.

보내기 요청이 완료되면 드라이버 스택이 진행됩니다. 미니포트 드라이버가 NdisMSendNetBufferListsComplete 함수를 호출하면 NDIS는 가장 낮은 오버리싱 필터 모듈에 대해 FilterSendNetBufferListsComplete 함수를 호출합니다.

보내기 작업이 완료되면 필터 드라이버는 필터 드라이버가 FilterSendNetBufferLists에서 만든 오버리싱 드라이버의 버퍼 설명자로 수정된 내용을 반전합니다. 드라이버는 NdisFSendNetBufferListsComplete 함수를 호출하여 NET_BUFFER_LIST 구조의 연결된 목록을 지나치게 많은 드라이버에 반환하고 보내기 요청의 최종 상태 반환합니다.

최상위 필터 모듈이 NdisFSendNetBufferListsComplete를 호출하면 NDIS는 원래 프로토콜 드라이버의 ProtocolSendNetBufferListsComplete 함수를 호출합니다.

FilterSendNetBufferLists 함수를 제공하지 않는 필터 드라이버는 여전히 보내기 요청을 시작할 수 있습니다. 이러한 드라이버가 보내기 요청을 시작하는 경우 FilterSendNetBufferListsComplete 함수를 제공해야 하며 드라이버 스택에 전체 이벤트를 전달해서는 안 됩니다.

필터 드라이버는 오버리딩 드라이버의 루프백 요청을 전달하거나 필터링할 수 있습니다. 루프백 요청을 전달하려면 NDIS가 FilterSendNetBufferLists의 SendFlags 매개 변수에서 NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK 설정하는 경우 필터 드라이버는 NdisFSendNetBufferLists를 호출할 때 SendFlags 매개 변수의 NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK 설정합니다. NDIS는 전송 데이터가 포함된 수신된 패킷을 나타냅니다.

일반적으로 필터 드라이버가 NDIS가 표준 서비스(예: 루프백)를 제공할 수 없는 방식으로 동작을 수정하는 경우 필터 드라이버는 NDIS에 해당 서비스를 제공해야 합니다. 예를 들어 하드웨어 주소에 대한 요청을 수정하는 필터 드라이버( OID_802_3_CURRENT_ADDRESS 참조)는 새 하드웨어 주소로 전달되는 버퍼의 루프백을 처리해야 합니다. 이 경우 필터가 주소를 변경했기 때문에 NDIS는 일반적으로 제공하는 루프백 서비스를 제공할 수 없습니다. 또한 필터 드라이버가 무차별 모드를 설정하는 경우( OID_GEN_CURRENT_PACKET_FILTER 참조) 지나치게 많은 드라이버에 수신하는 추가 데이터를 전달해서는 안 됩니다.