VOID PendAuthorizationDeferredProcedureCall(_In_ KDPC* pDPC,
                                            _In_opt_ PVOID pContext,
                                            _In_opt_ PVOID pArg1,
                                            _In_opt_ PVOID pArg2)
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> PendAuthorizationDeferredProcedureCall()\n");

#endif /// DBG
   
   UNREFERENCED_PARAMETER(pDPC);
   UNREFERENCED_PARAMETER(pContext);
   UNREFERENCED_PARAMETER(pArg2);

   NT_ASSERT(pDPC);
   NT_ASSERT(pArg1);
   NT_ASSERT(((DPC_DATA*)pArg1)->pClassifyData);
   NT_ASSERT(((DPC_DATA*)pArg1)->pInjectionData);

   DPC_DATA* pDPCData = (DPC_DATA*)pArg1;

   if(pDPCData)
   {
      NTSTATUS status = STATUS_SUCCESS;

      status = PerformPendAuthorization(&(pDPCData->pClassifyData),
                                        &(pDPCData->pPendData),
                                        (INJECTION_DATA**)&(pDPCData->pContext));
      if(status != STATUS_SUCCESS)
      {
         if(pDPCData->pClassifyData)
            KrnlHlprClassifyDataDestroyLocalCopy(&(pDPCData->pClassifyData));

         if(pDPCData->pInjectionData)
            KrnlHlprInjectionDataDestroy(&(pDPCData->pInjectionData));

         DbgPrintEx(DPFLTR_IHVNETWORK_ID,
                    DPFLTR_ERROR_LEVEL,
                    " !!!! PendAuthorizationDeferredProcedureCall() [status: %#x]\n",
                    status);
      }

      KrnlHlprDPCDataDestroy(&pDPCData);
   }

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

#endif /// DBG
   
   return;
}
NTSTATUS KrnlHlprThreadedDPCQueue(_In_ KDEFERRED_ROUTINE* pDPCFn,
                                  _In_ NOTIFY_DATA* pNotifyData,
                                  _In_opt_ VOID* pContext)        /* 0 */
{
#if DBG

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

#endif /// DBG

   NT_ASSERT(pDPCFn);
   NT_ASSERT(pNotifyData);

   NTSTATUS  status   = STATUS_SUCCESS;
   DPC_DATA* pDPCData = 0;

#pragma warning(push)
#pragma warning(disable: 6014) /// pDPCData will be freed by caller

   status = KrnlHlprDPCDataCreate(&pDPCData,
                                  pNotifyData,
                                  pContext);
   HLPR_BAIL_ON_FAILURE(status);

#pragma warning(pop)

   KeInitializeThreadedDpc(&(pDPCData->kdpc),
                           pDPCFn,
                           0);

   KeInsertQueueDpc(&(pDPCData->kdpc),
                    pDPCData,
                    0);

   HLPR_BAIL_LABEL:

#pragma warning(push)
#pragma warning(disable: 6001) /// pDPCData initialized with call to KrnlHlprDPCDataCreate

   if(status != STATUS_SUCCESS &&
      pDPCData)
      KrnlHlprDPCDataDestroy(&pDPCData);

#pragma warning(pop)

#if DBG

   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- KrnlHlprThreadedDPCQueue() [status: %#x]\n",
              status);

#endif /// DBG

   return status;
}
NTSTATUS KrnlHlprThreadedDPCQueue(_In_ KDEFERRED_ROUTINE* pDPCFn)
{
#if DBG

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

#endif /// DBG

   NT_ASSERT(pDPCFn);

   NTSTATUS  status   = STATUS_SUCCESS;
   DPC_DATA* pDPCData = 0;

#pragma warning(push)
#pragma warning(disable: 6014) /// pDPCData will be freed by caller

   HLPR_NEW(pDPCData,
            DPC_DATA,
            WFPSAMPLER_SYSLIB_TAG);
   HLPR_BAIL_ON_ALLOC_FAILURE(pDPCData,
                              status);

#pragma warning(pop)

   KeInitializeThreadedDpc(&(pDPCData->kdpc),
                           pDPCFn,
                           0);

   KeInsertQueueDpc(&(pDPCData->kdpc),
                    pDPCData,
                    0);

   HLPR_BAIL_LABEL:

#pragma warning(push)
#pragma warning(disable: 6001) /// pDPCData initialized with call to HLPR_NEW 

   if(status != STATUS_SUCCESS &&
      pDPCData)
      KrnlHlprDPCDataDestroy(&pDPCData);

#pragma warning(pop)

#if DBG

   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- KrnlHlprThreadedDPCQueue() [status: %#x]\n",
              status);

#endif /// DBG

   return status;
}
NTSTATUS KrnlHlprDPCDataCreate(_Outptr_ DPC_DATA** ppDPCData,
                               _In_ CLASSIFY_DATA* pClassifyData,
                               _In_ REDIRECT_DATA* pRedirectData,
                               _In_opt_ VOID* pContext)                 /* 0 */
{
#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " ---> KrnlHlprDPCDataCreate()\n");

#endif /// DBG
   
   NT_ASSERT(ppDPCData);
   NT_ASSERT(pClassifyData);
   NT_ASSERT(pRedirectData);

   NTSTATUS status = STATUS_SUCCESS;

   HLPR_NEW(*ppDPCData,
            DPC_DATA,
            WFPSAMPLER_SYSLIB_TAG);
   HLPR_BAIL_ON_ALLOC_FAILURE(*ppDPCData,
                              status);

   KrnlHlprDPCDataPopulate(*ppDPCData,
                           pClassifyData,
                           pRedirectData,
                           pContext);

   HLPR_BAIL_LABEL:

   if(status != STATUS_SUCCESS)
      KrnlHlprDPCDataDestroy(ppDPCData);

#if DBG
   
   DbgPrintEx(DPFLTR_IHVNETWORK_ID,
              DPFLTR_INFO_LEVEL,
              " <--- KrnlHlprDPCDataCreate() [status: %#x]\n",
              status);

#endif /// DBG
   
   return status;
}