Sample Code

windows driver samples/ Windows Filtering Platform Sample/ C++/ sys/ ClassifyFunctions_FastStreamInjectionCallouts.cpp/

////////////////////////////////////////////////////////////////////////////////////////////////////
//
//   Copyright (c) 2012 Microsoft Corporation.  All Rights Reserved.
//
//   Module Name:
//      ClassifyFunctions_FastStreamInjectionCallouts.cpp
//
//   Abstract:
//      This module contains WFP Classify functions that inject data back into the stream using
//         the clone / block / inject method.  This method is inline only, no modification,
//         and uses as little validation and error checking as possible. These functions are meant
//         for test performance purposes only.
//
//   Naming Convention:
//
//      <Module><Scenario>
//  
//      i.e.
//       ClassifyFastStreamInjection
//
//       <Module>
//          Classify             - Function is an FWPS_CALLOUT_CLASSIFY_FN
//       <Scenario>
//          FastStreamInjection  - Function demonstrates the clone / block / inject model in the 
//                                    fastest form available (inline, no validation, etc.).
//
//   Private Functions:
//
//   Public Functions:
//      ClassifyFastStreamInjection(),
//
//   Author:
//      Dusty Harper      (DHarper)
//
//   Revision History:
//
//      [ Month ][Day] [Year] - [Revision]-[ Comments ]
//      May       01,   2010  -     1.0   -  Creation
//
////////////////////////////////////////////////////////////////////////////////////////////////////

#include "Framework_WFPSamplerCalloutDriver.h"               /// .
#include "ClassifyFunctions_FastStreamInjectionCallouts.tmh" /// $(OBJ_PATH)\$(O)\

#if(NTDDI_VERSION >= NTDDI_WIN7)

/**
 @classify_function="ClassifyFastStreamInjection"
 
   Purpose:  Blocks the current stream data and injects a clone back to the stack without 
             modification.                                                                      <br>
                                                                                                <br>
   Notes:    Applies to the following layers:                                                   <br>
                FWPS_LAYER_STREAM_V{4/6}                                                        <br>
                                                                                                <br>
             Intended for test performance purposes only.                                       <br>
                                                                                                <br>
   MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF544893.aspx             <br>
             HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF551149.aspx             <br>
             HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF551213.aspx             <br>
             HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF551161.aspx             <br>
*/
_IRQL_requires_min_(PASSIVE_LEVEL)
_IRQL_requires_max_(DISPATCH_LEVEL)
_IRQL_requires_same_
VOID ClassifyFastStreamInjection(_In_ const FWPS_INCOMING_VALUES* pClassifyValues,
                                 _In_ const FWPS_INCOMING_METADATA_VALUES* pMetadata,
                                 _Inout_opt_ VOID* pStreamCalloutIOPacket,
                                 _In_opt_ const VOID* pClassifyContext,
                                 _In_ const FWPS_FILTER* pFilter,
                                 _In_ UINT64 flowContext,
                                 _Inout_ FWPS_CLASSIFY_OUT* pClassifyOut)
{
   UNREFERENCED_PARAMETER(pClassifyContext);
   UNREFERENCED_PARAMETER(flowContext);

   if(pStreamCalloutIOPacket &&
      pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE)
   {
      NTSTATUS                       status              = STATUS_SUCCESS;
      FWPS_STREAM_CALLOUT_IO_PACKET* pStreamPacket       = (FWPS_STREAM_CALLOUT_IO_PACKET*)pStreamCalloutIOPacket;
      FWP_DIRECTION                  direction           = (FWP_DIRECTION)pClassifyValues->incomingValue[FWPS_FIELD_STREAM_V4_DIRECTION].value.uint32;
      HANDLE                         injectionHandle     = 0;
      UINT64                         flowID              = 0;
      UINT32                         streamFlags         = pStreamPacket->streamData->flags;
      NET_BUFFER_LIST*               pNetBufferListChain = 0;

      if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
                                        FWPS_METADATA_FIELD_FLOW_HANDLE))
         flowID = pMetadata->flowHandle;

      if(pClassifyValues->layerId == FWPS_LAYER_STREAM_V4)
      {
         if(direction == FWP_DIRECTION_OUTBOUND)
            injectionHandle = g_IPv4OutboundStreamInjectionHandle;
         else
            injectionHandle = g_IPv4InboundStreamInjectionHandle;
      }
      else if(pClassifyValues->layerId == FWPS_LAYER_STREAM_V6)
      {
         if(direction == FWP_DIRECTION_OUTBOUND)
            injectionHandle = g_IPv6OutboundStreamInjectionHandle;
         else
            injectionHandle = g_IPv6InboundStreamInjectionHandle;
      }
      else
         HLPR_BAIL;

      if(!(streamFlags & FWPS_STREAM_FLAG_RECEIVE) &&
         !(streamFlags & FWPS_STREAM_FLAG_SEND))
         streamFlags |= direction ? FWPS_STREAM_FLAG_RECEIVE : FWPS_STREAM_FLAG_SEND;

      pStreamPacket->countBytesRequired = 0;
      pStreamPacket->countBytesEnforced = pStreamPacket->streamData->dataLength;
      pStreamPacket->streamAction       = FWPS_STREAM_ACTION_NONE;

      status = FwpsCloneStreamData(pStreamPacket->streamData,
                                   g_pNDISPoolData->nblPoolHandle,
                                   g_pNDISPoolData->nbPoolHandle,
                                   0,
                                   &pNetBufferListChain);
      if(status != STATUS_SUCCESS)
      {
         DbgPrintEx(DPFLTR_IHVNETWORK_ID,
                    DPFLTR_ERROR_LEVEL,
                    " !!!! PerformBasicStreamInjection : FwpsCloneStreamData() [status: %#x]\n",
                    status);

         HLPR_BAIL;
      }

      pClassifyOut->actionType  = FWP_ACTION_BLOCK;
      pClassifyOut->rights     ^= FWPS_RIGHT_ACTION_WRITE;

      status = FwpsStreamInjectAsync(injectionHandle,
                                     0,
                                     0,
                                     flowID,
                                     pFilter->action.calloutId,
                                     pClassifyValues->layerId,
                                     streamFlags,
                                     pNetBufferListChain,
                                     pStreamPacket->streamData->dataLength,
                                     CompleteFastStreamInjection,
                                     0);

      HLPR_BAIL_LABEL:

      if(status != STATUS_SUCCESS &&
         pNetBufferListChain)
      {
         KIRQL irql = KeGetCurrentIrql();

         FwpsDiscardClonedStreamData(pNetBufferListChain,
                                     0,
                                     irql == DISPATCH_LEVEL ? TRUE : FALSE);
      }
   }

   return;
}

#else

/**
 @classify_function="ClassifyFastStreamInjection"
 
   Purpose:  Blocks the current stream data and injects a clone back to the stack without 
             modification.                                                                      <br>
                                                                                                <br>
   Notes:    Applies to the following layers:                                                   <br>
                FWPS_LAYER_STREAM_V{4/6}                                                        <br>
                                                                                                <br>
             Intended for test performance purposes only.                                       <br>
                                                                                                <br>
   MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF544890.aspx             <br>
             HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF551149.aspx             <br>
             HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF551213.aspx             <br>
             HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/FF551161.aspx             <br>
*/
_IRQL_requires_min_(PASSIVE_LEVEL)
_IRQL_requires_max_(DISPATCH_LEVEL)
_IRQL_requires_same_
VOID ClassifyFastStreamInjection(_In_ const FWPS_INCOMING_VALUES* pClassifyValues,
                                 _In_ const FWPS_INCOMING_METADATA_VALUES0* pMetadata,
                                 _Inout_opt_ VOID* pStreamCalloutIOPacket,
                                 _In_ const FWPS_FILTER* pFilter,
                                 _In_ UINT64 flowContext,
                                 _Inout_ FWPS_CLASSIFY_OUT* pClassifyOut)
{
   UNREFERENCED_PARAMETER(flowContext);

   if(pStreamCalloutIOPacket &&
      pClassifyOut->rights & FWPS_RIGHT_ACTION_WRITE)
   {
      NTSTATUS                       status              = STATUS_SUCCESS;
      FWPS_STREAM_CALLOUT_IO_PACKET* pStreamPacket       = (FWPS_STREAM_CALLOUT_IO_PACKET*)pStreamCalloutIOPacket;
      FWP_DIRECTION                  direction           = (FWP_DIRECTION)pClassifyValues->incomingValue[FWPS_FIELD_STREAM_V4_DIRECTION].value.uint32;
      HANDLE                         injectionHandle     = 0;
      UINT64                         flowID              = 0;
      UINT32                         streamFlags         = pStreamPacket->streamData->flags;
      NET_BUFFER_LIST*               pNetBufferListChain = 0;
   
      if(FWPS_IS_METADATA_FIELD_PRESENT(pMetadata,
                                        FWPS_METADATA_FIELD_FLOW_HANDLE))
         flowID = pMetadata->flowHandle;
   
      if(pClassifyValues->layerId == FWPS_LAYER_STREAM_V4)
      {
         if(direction == FWP_DIRECTION_OUTBOUND)
            injectionHandle = g_IPv4OutboundStreamInjectionHandle;
         else
            injectionHandle = g_IPv4InboundStreamInjectionHandle;
      }
      else if(pClassifyValues->layerId == FWPS_LAYER_STREAM_V6)
      {
         if(direction == FWP_DIRECTION_OUTBOUND)
            injectionHandle = g_IPv6OutboundStreamInjectionHandle;
         else
            injectionHandle = g_IPv6InboundStreamInjectionHandle;
      }
      else
         HLPR_BAIL;
   
      if(!(streamFlags & FWPS_STREAM_FLAG_RECEIVE) &&
         !(streamFlags & FWPS_STREAM_FLAG_SEND))
         streamFlags |= direction ? FWPS_STREAM_FLAG_RECEIVE : FWPS_STREAM_FLAG_SEND;
   
      pStreamPacket->countBytesRequired = 0;
      pStreamPacket->countBytesEnforced = pStreamPacket->streamData->dataLength;
      pStreamPacket->streamAction       = FWPS_STREAM_ACTION_NONE;
   
      status = FwpsCloneStreamData(pStreamPacket->streamData,
                                   g_pNDISPoolData->nblPoolHandle,
                                   g_pNDISPoolData->nbPoolHandle,
                                   0,
                                   &pNetBufferListChain);
      if(status != STATUS_SUCCESS)
      {
         DbgPrintEx(DPFLTR_IHVNETWORK_ID,
                    DPFLTR_ERROR_LEVEL,
                    " !!!! PerformBasicStreamInjection : FwpsCloneStreamData() [status: %#x]\n",
                    status);
   
         HLPR_BAIL;
      }

      pClassifyOut->actionType  = FWP_ACTION_BLOCK;
      pClassifyOut->rights     ^= FWPS_RIGHT_ACTION_WRITE;

      status = FwpsStreamInjectAsync(injectionHandle,
                                     0,
                                     0,
                                     flowID,
                                     pFilter->action.calloutId,
                                     pClassifyValues->layerId,
                                     streamFlags,
                                     pNetBufferListChain,
                                     pStreamPacket->streamData->dataLength,
                                     CompleteFastStreamInjection,
                                     0);
   
      HLPR_BAIL_LABEL:
   
      if(status != STATUS_SUCCESS &&
         pNetBufferListChain)
      {
         KIRQL irql = KeGetCurrentIrql();
   
         FwpsDiscardClonedStreamData(pNetBufferListChain,
                                     0,
                                     irql == DISPATCH_LEVEL ? TRUE : FALSE);
      }
   }
   
   return;
}

#endif // (NTDDI_VERSION >= NTDDI_WIN7)

Our Services

  • What our customers say about us?

© 2011-2025 All Rights Reserved. Joya Systems. 4425 South Mopac Building II Suite 101 Austin, TX 78735 Tel: 800-DEV-KERNEL

Privacy Policy. Terms of use. Valid XHTML & CSS