_IRQL_requires_same_
inline VOID KrnlHlprClassifyDataReleaseLocalCopy(_Inout_ CLASSIFY_DATA* pClassifyData)
{
#if DBG

   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> KrnlHlprClassifyDataReleaseLocalCopy()\n");

#endif /// DBG
   
   NT_ASSERT(pClassifyData);

   KrnlHlprFwpsClassifyOutDestroyLocalCopy((FWPS_CLASSIFY_OUT**)&(pClassifyData->pClassifyOut));

   pClassifyData->flowContext = 0;

   KrnlHlprFwpsFilterDestroyLocalCopy((FWPS_FILTER**)&(pClassifyData->pFilter));

#if(NTDDI_VERSION >= NTDDI_WIN7)
   
      if(pClassifyData->classifyContextHandle)
         FwpsReleaseClassifyHandle(pClassifyData->classifyContextHandle);
   
#endif /// (NTDDI_VERSION >= NTDDI_WIN7)

   if(pClassifyData->pPacket)
   {
      if(pClassifyData->pClassifyValues)
      {
         if(pClassifyData->pClassifyValues->layerId == FWPS_LAYER_STREAM_V4 ||
            pClassifyData->pClassifyValues->layerId == FWPS_LAYER_STREAM_V4_DISCARD ||
            pClassifyData->pClassifyValues->layerId == FWPS_LAYER_STREAM_V6 ||
            pClassifyData->pClassifyValues->layerId == FWPS_LAYER_STREAM_V6_DISCARD)
            KrnlHlprFwpsStreamCalloutIOPacketDestroyLocalCopy((FWPS_STREAM_CALLOUT_IO_PACKET**)&(pClassifyData->pPacket));
         else if(pClassifyData->chainedNBL)
         {
            BOOLEAN isDispatch	   = (KeGetCurrentIrql() == DISPATCH_LEVEL) ? TRUE : FALSE;
            UINT32  numChainedNBLs  = pClassifyData->numChainedNBLs;

            for(NET_BUFFER_LIST* pCurrentNBL = (NET_BUFFER_LIST*)pClassifyData->pPacket;
                pCurrentNBL &&
                numChainedNBLs;
                numChainedNBLs--)
            {
               NET_BUFFER_LIST* pNextNBL = NET_BUFFER_LIST_NEXT_NBL(pCurrentNBL);

               FwpsDereferenceNetBufferList(pCurrentNBL,
                                            isDispatch);

               pCurrentNBL = pNextNBL;

#if DBG

               InterlockedDecrement64((LONG64*)&(g_OutstandingNBLReferences));

#endif /// DBG

            }
         }
         else
         {
            BOOLEAN isDispatch = (KeGetCurrentIrql() == DISPATCH_LEVEL) ? TRUE : FALSE;

            FwpsDereferenceNetBufferList((NET_BUFFER_LIST*)pClassifyData->pPacket,
                                         isDispatch);

#if DBG

            InterlockedDecrement64((LONG64*)&(g_OutstandingNBLReferences));

#endif /// DBG

         }
      }

      pClassifyData->pPacket = 0;
   }

   KrnlHlprFwpsIncomingMetadataValuesDestroyLocalCopy((FWPS_INCOMING_METADATA_VALUES**)&(pClassifyData->pMetadataValues));

   if(pClassifyData->pClassifyValues)
      KrnlHlprFwpsIncomingValuesDestroyLocalCopy((FWPS_INCOMING_VALUES**)&(pClassifyData->pClassifyValues));

   RtlZeroMemory(pClassifyData,
                 sizeof(CLASSIFY_DATA));

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- KrnlHlprClassifyDataReleaseLocalCopy()\n");

#endif /// DBG
   
   return;
}
_IRQL_requires_same_
inline VOID KrnlHlprRedirectDataPurge(_Inout_ REDIRECT_DATA* pRedirectData)
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> KrnlHlprRedirectDataPurge()\n");

#endif /// DBG
   
   NT_ASSERT(pRedirectData);

   if(pRedirectData->pWritableLayerData)
   {
      FwpsApplyModifiedLayerData(pRedirectData->classifyHandle,
                                 pRedirectData->pWritableLayerData,
                                 FWPS_CLASSIFY_FLAG_REAUTHORIZE_IF_MODIFIED_BY_OTHERS);

      pRedirectData->pWritableLayerData = 0;
   }

   if(pRedirectData->classifyHandle)
   {
      if(pRedirectData->isPended)
      {
         FwpsCompleteClassify(pRedirectData->classifyHandle,
                              0,
                              pRedirectData->pClassifyOut);

         pRedirectData->isPended = FALSE;
      }

#if(NTDDI_VERSION >= NTDDI_WIN8)

      if(pRedirectData->redirectHandle)
      {
         FwpsRedirectHandleDestroy(pRedirectData->redirectHandle);

         pRedirectData->redirectHandle = 0;
      }

#endif

      FwpsReleaseClassifyHandle(pRedirectData->classifyHandle);

      pRedirectData->classifyHandle = 0;
   }

   RtlZeroMemory(pRedirectData,
                 sizeof(REDIRECT_DATA));

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- KrnlHlprRedirectDataPurge()\n");

#endif /// DBG
   
   return;
}
_IRQL_requires_same_
inline VOID KrnlHlprPendDataPurge(_Inout_ PEND_DATA* pPendData)
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> KrnlHlprPendDataPurge()\n");

#endif /// DBG
   
   NT_ASSERT(pPendData);

#if(NTDDI_VERSION >= NTDDI_WIN7)

   if(pPendData->layerID == FWPS_LAYER_ALE_ENDPOINT_CLOSURE_V4 ||
      pPendData->layerID == FWPS_LAYER_ALE_ENDPOINT_CLOSURE_V6)
   {
      if(pPendData->classifyHandle &&
         pPendData->isPended)
      {
         FwpsCompleteClassify(pPendData->classifyHandle,
                              0,
                              &(pPendData->classifyOut));


         FwpsReleaseClassifyHandle(pPendData->classifyHandle);

         pPendData->classifyHandle = 0;
         pPendData->pPCPendData    = 0;
         pPendData->isPended       = FALSE;
      }
   }
   else

#endif /// (NTDDI_VERSION >= NTDDI_WIN7)

   {
      if(pPendData->completionContext &&
         pPendData->isPended)
      {
         FwpsCompleteOperation(pPendData->completionContext,
                               pPendData->pNBL);

         pPendData->completionContext      = 0;
         pPendData->pNBL                   = 0;
         pPendData->pPendAuthorizationData = 0;
         pPendData->isPended               = FALSE;
      }
   }

   RtlZeroMemory(pPendData,
                 sizeof(PEND_DATA));

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- KrnlHlprPendDataPurge()\n");

#endif /// DBG
   
   return;
}