Exemple #1
0
UINT32 PrvScenarioProxyAddFwpmObjects(_In_ const FWPM_FILTER* pFilter,
                                      _In_ const PC_PROXY_DATA* pPCProxyData)
{
   ASSERT(pFilter);
   ASSERT(pPCProxyData);

   UINT32                status          = NO_ERROR;
   HANDLE                engineHandle    = 0;
   FWP_BYTE_BLOB         byteBlob        = {0};
   FWPM_PROVIDER_CONTEXT providerContext = {0};
   FWPM_CALLOUT          callout         = {0};
   FWPM_FILTER           filter          = {0};

   RtlCopyMemory(&filter,
                 pFilter,
                 sizeof(FWPM_FILTER));

   status = HlprGUIDPopulate(&(providerContext.providerContextKey));
   HLPR_BAIL_ON_FAILURE(status);

   providerContext.displayData.name        = L"WFPSampler's Proxy ProviderContext";
   providerContext.displayData.description = L"Instructs the driver where to proxy the socket or connection";      
   providerContext.providerKey             = (GUID*)&WFPSAMPLER_PROVIDER;
   providerContext.type                    = FWPM_GENERAL_CONTEXT;
   providerContext.dataBuffer              = &byteBlob;
   providerContext.dataBuffer->size        = sizeof(PC_PROXY_DATA);
   providerContext.dataBuffer->data        = (UINT8*)pPCProxyData;

#if(NTDDI_VERSION >= NTDDI_WIN7)

   if(pFilter->layerKey == FWPM_LAYER_ALE_CONNECT_REDIRECT_V4 ||
      pFilter->layerKey == FWPM_LAYER_ALE_CONNECT_REDIRECT_V6 ||
      pFilter->layerKey == FWPM_LAYER_ALE_BIND_REDIRECT_V4 ||
      pFilter->layerKey == FWPM_LAYER_ALE_BIND_REDIRECT_V6)
      callout.calloutKey = WFPSAMPLER_CALLOUT_PROXY_BY_ALE_REDIRECT;
   else

#endif /// (NTDDI_VERSION >= NTDDI_WIN7)

   callout.calloutKey              = WFPSAMPLER_CALLOUT_PROXY_BY_INJECTION;
   callout.calloutKey.Data4[7]     = HlprFwpmLayerGetIDByKey(&(filter.layerKey));                /// Uniquely identifies the callout used
   callout.displayData.name        = L"WFPSampler's Proxy Callout";
   callout.displayData.description = L"Proxies the socket or connection to the designated destination";
   callout.flags                   = FWPM_CALLOUT_FLAG_USES_PROVIDER_CONTEXT;
   callout.providerKey             = (GUID*)&WFPSAMPLER_PROVIDER;
   callout.applicableLayer         = filter.layerKey;

   status = HlprGUIDPopulate(&(filter.filterKey));
   HLPR_BAIL_ON_FAILURE(status);

   filter.flags             |= FWPM_FILTER_FLAG_HAS_PROVIDER_CONTEXT;
   filter.providerKey        = (GUID*)&WFPSAMPLER_PROVIDER;
   filter.subLayerKey        = WFPSAMPLER_SUBLAYER;
   filter.weight.type        = FWP_UINT8;
   filter.weight.uint8       = 0xF;
   filter.action.type        = FWP_ACTION_CALLOUT_UNKNOWN;
   filter.action.calloutKey  = callout.calloutKey;
   filter.providerContextKey = providerContext.providerContextKey;

   if(filter.flags & FWPM_FILTER_FLAG_BOOTTIME ||
      filter.flags & FWPM_FILTER_FLAG_PERSISTENT)
   {
      providerContext.flags |= FWPM_PROVIDER_CONTEXT_FLAG_PERSISTENT;

      callout.flags |= FWPM_CALLOUT_FLAG_PERSISTENT;
   }

   status = HlprFwpmEngineOpen(&engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmTransactionBegin(engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmProviderContextAdd(engineHandle,
                                       &providerContext);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmCalloutAdd(engineHandle,
                               &callout);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmFilterAdd(engineHandle,
                              &filter);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmTransactionCommit(engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   HLPR_BAIL_LABEL:

   if(engineHandle)
   {
      if(status != NO_ERROR)
         HlprFwpmTransactionAbort(engineHandle);

      HlprFwpmEngineClose(&engineHandle);
   }

   return status;
}
Exemple #2
0
UINT32 PrvScenarioProxyDeleteFwpmObjects(_In_ const FWPM_FILTER* pFilter)
{
   ASSERT(pFilter);

   UINT32                              status                      = NO_ERROR;
   HANDLE                              engineHandle                = 0;
   HANDLE                              enumHandle                  = 0;
   UINT32                              entryCount                  = 0;
   FWPM_FILTER**                       ppFilters                   = 0;
   FWPM_FILTER_ENUM_TEMPLATE           filterEnumTemplate          = {0};
   FWPM_PROVIDER_CONTEXT_ENUM_TEMPLATE providerContextEnumTemplate = {0};
   GUID                                calloutKey                  = {0};

#if(NTDDI_VERSION >= NTDDI_WIN7)

   if(pFilter->layerKey == FWPM_LAYER_ALE_CONNECT_REDIRECT_V4 ||
      pFilter->layerKey == FWPM_LAYER_ALE_CONNECT_REDIRECT_V6 ||
      pFilter->layerKey == FWPM_LAYER_ALE_BIND_REDIRECT_V4 ||
      pFilter->layerKey == FWPM_LAYER_ALE_BIND_REDIRECT_V6)
      calloutKey = WFPSAMPLER_CALLOUT_PROXY_BY_ALE_REDIRECT;
   else

#endif /// (NTDDI_VERSION >= NTDDI_WIN7)

   calloutKey          = WFPSAMPLER_CALLOUT_PROXY_BY_INJECTION;
   calloutKey.Data4[7] = HlprFwpmLayerGetIDByKey(&(pFilter->layerKey));                          /// Uniquely identifies the callout used

   providerContextEnumTemplate.providerContextType = FWPM_GENERAL_CONTEXT;

   filterEnumTemplate.providerKey             = (GUID*)&WFPSAMPLER_PROVIDER;
   filterEnumTemplate.layerKey                = pFilter->layerKey;
   filterEnumTemplate.enumType                = FWP_FILTER_ENUM_FULLY_CONTAINED;
   filterEnumTemplate.flags                   = FWP_FILTER_ENUM_FLAG_INCLUDE_BOOTTIME |
                                                FWP_FILTER_ENUM_FLAG_INCLUDE_DISABLED;
   filterEnumTemplate.numFilterConditions     = pFilter->numFilterConditions;
   filterEnumTemplate.filterCondition         = pFilter->filterCondition;
   filterEnumTemplate.providerContextTemplate = &providerContextEnumTemplate;
   filterEnumTemplate.actionMask              = FWP_ACTION_FLAG_CALLOUT;
   filterEnumTemplate.calloutKey              = &calloutKey;

   status = HlprFwpmEngineOpen(&engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmFilterCreateEnumHandle(engineHandle,
                                           &filterEnumTemplate,
                                           &enumHandle);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmFilterEnum(engineHandle,
                               enumHandle,
                               0xFFFFFFFF,
                               &ppFilters,
                               &entryCount);
   HLPR_BAIL_ON_FAILURE(status);

   if(ppFilters)
   {
      for(UINT32 filterIndex = 0;
          filterIndex < entryCount;
          filterIndex++)
      {
         HlprFwpmFilterDeleteByKey(engineHandle,
                                   &(ppFilters[filterIndex]->filterKey));

         HlprFwpmCalloutDeleteByKey(engineHandle,
                                    &(ppFilters[filterIndex]->action.calloutKey));

         if(ppFilters[filterIndex]->flags & FWPM_FILTER_FLAG_HAS_PROVIDER_CONTEXT)
            HlprFwpmProviderContextDeleteByKey(engineHandle,
                                               &(ppFilters[filterIndex]->providerContextKey));
      }

      FwpmFreeMemory((void**)&ppFilters);
   }

   HLPR_BAIL_LABEL:

   if(engineHandle)
   {
      if(enumHandle)
         HlprFwpmFilterDestroyEnumHandle(engineHandle,
                                         &enumHandle);

      HlprFwpmEngineClose(&engineHandle);
   }

   return status;
}
UINT32 PrvScenarioFastStreamInjectionAddFwpmObjects(_In_ const FWPM_FILTER* pFilter)
{
   ASSERT(pFilter);

   UINT32       status       = NO_ERROR;
   HANDLE       engineHandle = 0;
   FWPM_CALLOUT callout      = {0};
   FWPM_FILTER  filter       = {0};

   RtlCopyMemory(&filter,
                 pFilter,
                 sizeof(FWPM_FILTER));

   callout.calloutKey              = WFPSAMPLER_CALLOUT_FAST_STREAM_INJECTION;
   callout.calloutKey.Data4[7]     = HlprFwpmLayerGetIDByKey(&(filter.layerKey));                /// Uniquely identifies the callout used
   callout.displayData.name        = L"WFPSampler's Fast Stream Injection Callout";
   callout.displayData.description = L"Causes callout invocation which blindly injects data back into the stream";
   callout.providerKey             = (GUID*)&WFPSAMPLER_PROVIDER;
   callout.applicableLayer         = filter.layerKey;

   status = HlprGUIDPopulate(&(filter.filterKey));
   HLPR_BAIL_ON_FAILURE(status);

   filter.providerKey        = (GUID*)&WFPSAMPLER_PROVIDER;
   filter.subLayerKey        = WFPSAMPLER_SUBLAYER;
   filter.weight.type        = FWP_UINT8;
   filter.weight.uint8       = 0xF;
   filter.action.type        = FWP_ACTION_CALLOUT_TERMINATING;
   filter.action.calloutKey  = callout.calloutKey;

   if(filter.flags & FWPM_FILTER_FLAG_BOOTTIME ||
      filter.flags & FWPM_FILTER_FLAG_PERSISTENT)
      callout.flags = FWPM_CALLOUT_FLAG_PERSISTENT;
 
   status = HlprFwpmEngineOpen(&engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmTransactionBegin(engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmCalloutAdd(engineHandle,
                               &callout);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmFilterAdd(engineHandle,
                              &filter);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmTransactionCommit(engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   HLPR_BAIL_LABEL:

   if(engineHandle)
   {
      if(status != NO_ERROR)
         HlprFwpmTransactionAbort(engineHandle);

      HlprFwpmEngineClose(&engineHandle);
   }

   return status;
}
UINT32 PrvScenarioFastStreamInjectionDeleteFwpmObjects(_In_ const FWPM_FILTER* pFilter)
{
   ASSERT(pFilter);

   UINT32                    status             = NO_ERROR;
   HANDLE                    engineHandle       = 0;
   HANDLE                    enumHandle         = 0;
   UINT32                    entryCount         = 0;
   FWPM_FILTER**             ppFilters          = 0;
   FWPM_FILTER_ENUM_TEMPLATE filterEnumTemplate = {0};
   GUID                      calloutKey         = {0};

   calloutKey          = WFPSAMPLER_CALLOUT_FAST_STREAM_INJECTION;
   calloutKey.Data4[7] = HlprFwpmLayerGetIDByKey(&(pFilter->layerKey));                          /// Uniquely identifies the callout used

   filterEnumTemplate.providerKey         = (GUID*)&WFPSAMPLER_PROVIDER;
   filterEnumTemplate.layerKey            = pFilter->layerKey;
   filterEnumTemplate.enumType            = FWP_FILTER_ENUM_FULLY_CONTAINED;
   filterEnumTemplate.flags               = FWP_FILTER_ENUM_FLAG_INCLUDE_BOOTTIME |
                                            FWP_FILTER_ENUM_FLAG_INCLUDE_DISABLED;
   filterEnumTemplate.numFilterConditions = pFilter->numFilterConditions;
   filterEnumTemplate.filterCondition     = pFilter->filterCondition;
   filterEnumTemplate.actionMask          = FWP_ACTION_FLAG_CALLOUT;
   filterEnumTemplate.calloutKey          = &calloutKey;

   status = HlprFwpmEngineOpen(&engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmFilterCreateEnumHandle(engineHandle,
                                           &filterEnumTemplate,
                                           &enumHandle);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmFilterEnum(engineHandle,
                               enumHandle,
                               0xFFFFFFFF,
                               &ppFilters,
                               &entryCount);
   HLPR_BAIL_ON_FAILURE(status);

   if(ppFilters)
   {
      for(UINT32 filterIndex = 0;
          filterIndex < entryCount;
          filterIndex++)
      {
         HlprFwpmFilterDeleteByKey(engineHandle,
                                   &(ppFilters[filterIndex]->filterKey));

         HlprFwpmCalloutDeleteByKey(engineHandle,
                                    &(ppFilters[filterIndex]->action.calloutKey));
      }

      FwpmFreeMemory((void**)&ppFilters);
   }

   HLPR_BAIL_LABEL:

   if(engineHandle)
   {
      if(enumHandle)
         HlprFwpmFilterDestroyEnumHandle(engineHandle,
                                         &enumHandle);

      HlprFwpmEngineClose(&engineHandle);
   }

   return status;
}
UINT32 PrvScenarioAppContainerDeleteFwpmObjects(_In_ const SID* pPackageID,
                                                _In_ const SID* pUserID)
{
   UNREFERENCED_PARAMETER(pUserID);

   ASSERT(pPackageID);
   ASSERT(pUserID);

   UINT32                status                            = NO_ERROR;
///   UINT32                sidSize                           = 0;
   HANDLE                engineHandle                      = 0;
   const GUID            pLayerKeys[]                      = {FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4,
                                                              FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6,
                                                              FWPM_LAYER_ALE_AUTH_CONNECT_V4,
                                                              FWPM_LAYER_ALE_AUTH_CONNECT_V6};
   const UINT8           NUM_CONDITIONS                    = 1; /// 2
   const UINT8           NUM_OBJECTS                       = RTL_NUMBER_OF(pLayerKeys);
   FWPM_FILTER_CONDITION pFilterConditions[NUM_CONDITIONS] = {0};

   pFilterConditions[0].fieldKey            = FWPM_CONDITION_ALE_PACKAGE_ID;
   pFilterConditions[0].matchType           = FWP_MATCH_EQUAL;
   pFilterConditions[0].conditionValue.type = FWP_SID;
   pFilterConditions[0].conditionValue.sid  = (SID*)pPackageID;

///   pFilterConditions[1].fieldKey            = FWPM_CONDITION_ALE_USER_ID;
///   pFilterConditions[1].matchType           = FWP_MATCH_EQUAL;
///   pFilterConditions[1].conditionValue.type = FWP_SECURITY_DESCRIPTOR_TYPE;
///   pFilterConditions[1].conditionValue.sd   = ;

   status = HlprFwpmEngineOpen(&engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   for(UINT32 objectIndex = 0;
       objectIndex < NUM_OBJECTS;
       objectIndex++)
   {
      UINT32                    entryCount         = 0;
      FWPM_FILTER**             ppFilters          = 0;
      HANDLE                    enumHandle         = 0;
      FWPM_FILTER_ENUM_TEMPLATE filterEnumTemplate = {0};

      filterEnumTemplate.providerKey         = (GUID*)&WFPSAMPLER_PROVIDER;
      filterEnumTemplate.layerKey            = pLayerKeys[objectIndex];
      filterEnumTemplate.enumType            = FWP_FILTER_ENUM_FULLY_CONTAINED;
      filterEnumTemplate.flags               = FWP_FILTER_ENUM_FLAG_INCLUDE_BOOTTIME |
                                               FWP_FILTER_ENUM_FLAG_INCLUDE_DISABLED;
      filterEnumTemplate.numFilterConditions = NUM_CONDITIONS;
      filterEnumTemplate.filterCondition     = pFilterConditions;
      filterEnumTemplate.actionMask          = 0xFFFFFFFF;

      status = HlprFwpmFilterCreateEnumHandle(engineHandle,
                                              &filterEnumTemplate,
                                              &enumHandle);
      HLPR_BAIL_ON_FAILURE_WITH_LABEL(status,
                                      HLPR_BAIL_LABEL_2);

      status = HlprFwpmFilterEnum(engineHandle,
                                  enumHandle,
                                  0xFFFFFFFF,
                                  &ppFilters,
                                  &entryCount);
      HLPR_BAIL_ON_FAILURE_WITH_LABEL(status,
                                      HLPR_BAIL_LABEL_2);

      if(ppFilters)
      {
         for(UINT32 filterIndex = 0;
             filterIndex < entryCount;
             filterIndex++)
         {
            HlprFwpmFilterDeleteByKey(engineHandle,
                                      &(ppFilters[filterIndex]->filterKey));
         }

         FwpmFreeMemory((void**)&ppFilters);
      }

      HLPR_BAIL_LABEL_2:

      if(enumHandle)
         HlprFwpmFilterDestroyEnumHandle(engineHandle,
                                         &enumHandle);
   }

   HLPR_BAIL_LABEL:

   HlprFwpmEngineClose(&engineHandle);

   return status;
}
UINT32 PrvScenarioAppContainerAddFwpmObjects(_In_ BOOLEAN persistent = TRUE,
                                             _In_ BOOLEAN bootTime = FALSE)
{
   UINT32                status                = NO_ERROR;
   UINT32                sidSize               = 0;
   HANDLE                engineHandle          = 0;
   const GUID            pLayerKeys[]          = {FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4,
                                                  FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6,
                                                  FWPM_LAYER_ALE_AUTH_CONNECT_V4,
                                                  FWPM_LAYER_ALE_AUTH_CONNECT_V6};
   const UINT32          NUM_OBJECTS           = RTL_NUMBER_OF(pLayerKeys);
   FWPM_FILTER_CONDITION filterCondition       = {0};
   FWPM_FILTER           pFilters[NUM_OBJECTS] = {0};

   /// Only App Containers have a valid (non-NULL) SID for the ALE_PACKAGE_ID
   filterCondition.fieldKey            = FWPM_CONDITION_ALE_PACKAGE_ID;
   filterCondition.matchType           = FWP_MATCH_NOT_EQUAL;
   filterCondition.conditionValue.type = FWP_SID;

#pragma warning(push)
#pragma warning(disable: 6388) /// filterCondition.conditionValue.sid guaranteed to be 0 due to ZeroMemory call

   status = HlprSIDGetWellKnown(WinNullSid,
                                &(filterCondition.conditionValue.sid),
                                &sidSize);
   HLPR_BAIL_ON_FAILURE(status);

#pragma warning(pop)

   for(UINT32 objectIndex = 0;
       objectIndex < NUM_OBJECTS;
       objectIndex++)
   {
      status = HlprGUIDPopulate(&(pFilters[objectIndex].filterKey));
      HLPR_BAIL_ON_FAILURE(status);

      pFilters[objectIndex].displayData.name         = L"WFPSampler's AppContainer Scenario Filter";
      pFilters[objectIndex].displayData.description  = L"Trust Windows Service Hardening to handle all App Containers";
      pFilters[objectIndex].flags                   |= FWPM_FILTER_FLAG_PERSISTENT;
      pFilters[objectIndex].providerKey              = (GUID*)&WFPSAMPLER_PROVIDER;
      pFilters[objectIndex].layerKey                 = pLayerKeys[objectIndex];
      pFilters[objectIndex].subLayerKey              = WFPSAMPLER_SUBLAYER;
      pFilters[objectIndex].weight.type              = FWP_UINT8;
      pFilters[objectIndex].weight.uint8             = 0xF;
      pFilters[objectIndex].numFilterConditions      = 1;
      pFilters[objectIndex].filterCondition          = &filterCondition;
      pFilters[objectIndex].action.type              = FWP_ACTION_PERMIT;

      if(!persistent)
         pFilters[objectIndex].flags ^= FWPM_FILTER_FLAG_PERSISTENT;

      if(bootTime)
      {
         if(pFilters[objectIndex].flags & FWPM_FILTER_FLAG_PERSISTENT)
            pFilters[objectIndex].flags ^= FWPM_FILTER_FLAG_PERSISTENT;

         pFilters[objectIndex].flags |= FWPM_FILTER_FLAG_BOOTTIME;
      }
   }

   status = HlprFwpmEngineOpen(&engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmTransactionBegin(engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   for(UINT32 objectIndex = 0;
       objectIndex < NUM_OBJECTS;
       objectIndex++)
   {
      status = HlprFwpmFilterAdd(engineHandle,
                                 &(pFilters[objectIndex]));
      HLPR_BAIL_ON_FAILURE(status);
   }

   status = HlprFwpmTransactionCommit(engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   HLPR_BAIL_LABEL:

   HlprSIDDestroy(&(filterCondition.conditionValue.sid));

   if(engineHandle)
   {
      if(status != NO_ERROR)
         HlprFwpmTransactionAbort(engineHandle);

      HlprFwpmEngineClose(&engineHandle);
   }

   return status;
}
UINT32 PrvScenarioAppContainerAddFwpmObjects(_In_ const SID* pPackageID,
                                             _In_ const SID* pUserID,
                                             _In_opt_ PCWSTR pDisplayName,
                                             _In_ BOOLEAN persistent = TRUE,
                                             _In_ BOOLEAN bootTime = FALSE)
{
   UNREFERENCED_PARAMETER(pUserID);

   ASSERT(pPackageID);
   ASSERT(pUserID);

   UINT32                status                            = NO_ERROR;
///   UINT32                sidSize                           = 0;
   HANDLE                engineHandle                      = 0;
   const GUID            pLayerKeys[]                      = {FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4,
                                                              FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6,
                                                              FWPM_LAYER_ALE_AUTH_CONNECT_V4,
                                                              FWPM_LAYER_ALE_AUTH_CONNECT_V6};
   const UINT8           NUM_CONDITIONS                    = 1; /// 2
   const UINT8           NUM_OBJECTS                       = RTL_NUMBER_OF(pLayerKeys);
   FWPM_FILTER_CONDITION pFilterConditions[NUM_CONDITIONS] = {0};
   FWPM_FILTER           pFilters[NUM_OBJECTS]             = {0};

///   status = HlprSecurityDescriptorGetSelfRelativeForUser();

   pFilterConditions[0].fieldKey            = FWPM_CONDITION_ALE_PACKAGE_ID;
   pFilterConditions[0].matchType           = FWP_MATCH_EQUAL;
   pFilterConditions[0].conditionValue.type = FWP_SID;
   pFilterConditions[0].conditionValue.sid  = (SID*)pPackageID;

///   pFilterConditions[1].fieldKey            = FWPM_CONDITION_ALE_USER_ID;
///   pFilterConditions[1].matchType           = FWP_MATCH_EQUAL;
///   pFilterConditions[1].conditionValue.type = FWP_SECURITY_DESCRIPTOR_TYPE;
///   pFilterConditions[1].conditionValue.sd   = ;

   for(UINT32 objectIndex = 0;
       objectIndex < NUM_OBJECTS;
       objectIndex++)
   {
      status = HlprGUIDPopulate(&(pFilters[objectIndex].filterKey));
      HLPR_BAIL_ON_FAILURE(status);

      pFilters[objectIndex].displayData.name         = L"WFPSampler's AppContainer Scenario Filter";
      pFilters[objectIndex].displayData.description  = (PWSTR)pDisplayName;
      pFilters[objectIndex].flags                   |= FWPM_FILTER_FLAG_PERSISTENT;
      pFilters[objectIndex].providerKey              = (GUID*)&WFPSAMPLER_PROVIDER;
      pFilters[objectIndex].layerKey                 = pLayerKeys[objectIndex];
      pFilters[objectIndex].subLayerKey              = WFPSAMPLER_SUBLAYER;
      pFilters[objectIndex].weight.type              = FWP_UINT8;
      pFilters[objectIndex].weight.uint8             = 0xF;
      pFilters[objectIndex].numFilterConditions      = NUM_CONDITIONS;
      pFilters[objectIndex].filterCondition          = pFilterConditions;
      pFilters[objectIndex].action.type              = FWP_ACTION_PERMIT;

      if(!persistent)
         pFilters[objectIndex].flags ^= FWPM_FILTER_FLAG_PERSISTENT;

      if(bootTime)
      {
         if(pFilters[objectIndex].flags & FWPM_FILTER_FLAG_PERSISTENT)
            pFilters[objectIndex].flags ^= FWPM_FILTER_FLAG_PERSISTENT;

         pFilters[objectIndex].flags |= FWPM_FILTER_FLAG_BOOTTIME;
      }
   }

   status = HlprFwpmEngineOpen(&engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmTransactionBegin(engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   for(UINT32 objectIndex = 0;
       objectIndex < NUM_OBJECTS;
       objectIndex++)
   {
      status = HlprFwpmFilterAdd(engineHandle,
                                 &(pFilters[objectIndex]));
      HLPR_BAIL_ON_FAILURE(status);
   }

   status = HlprFwpmTransactionCommit(engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   HLPR_BAIL_LABEL:

   if(engineHandle)
   {
      if(status != NO_ERROR)
         HlprFwpmTransactionAbort(engineHandle);

      HlprFwpmEngineClose(&engineHandle);
   }

   return status;
}
UINT32 PrvScenarioAppContainerDeleteFwpmObjects()
{
   UINT32                status          = NO_ERROR;
   UINT32                sidSize         = 0;
   HANDLE                engineHandle    = 0;
   const GUID            pLayerKeys[]    = {FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4,
                                            FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6,
                                            FWPM_LAYER_ALE_AUTH_CONNECT_V4,
                                            FWPM_LAYER_ALE_AUTH_CONNECT_V6};
   const UINT32          NUM_OBJECTS     = RTL_NUMBER_OF(pLayerKeys);
   FWPM_FILTER_CONDITION filterCondition = {0};

   /// Only App Containers have a valid (non-NULL) SID for the ALE_PACKAGE_ID
   filterCondition.fieldKey            = FWPM_CONDITION_ALE_PACKAGE_ID;
   filterCondition.matchType           = FWP_MATCH_NOT_EQUAL;
   filterCondition.conditionValue.type = FWP_SID;

#pragma warning(push)
#pragma warning(disable: 6388) /// filterCondition.conditionValue.sid guaranteed to be 0 due to ZeroMemory call

   status = HlprSIDGetWellKnown(WinNullSid,
                                &(filterCondition.conditionValue.sid),
                                &sidSize);
   HLPR_BAIL_ON_FAILURE(status);

#pragma warning(pop)

   status = HlprFwpmEngineOpen(&engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   for(UINT32 objectIndex = 0;
       objectIndex < NUM_OBJECTS;
       objectIndex++)
   {
      HANDLE                    enumHandle         = 0;
      UINT32                    entryCount         = 0;
      FWPM_FILTER**             ppFilters          = 0;
      FWPM_FILTER_ENUM_TEMPLATE filterEnumTemplate = {0};

      filterEnumTemplate.providerKey         = (GUID*)&WFPSAMPLER_PROVIDER;
      filterEnumTemplate.layerKey            = pLayerKeys[objectIndex];
      filterEnumTemplate.enumType            = FWP_FILTER_ENUM_FULLY_CONTAINED;
      filterEnumTemplate.flags               = FWP_FILTER_ENUM_FLAG_INCLUDE_BOOTTIME |
                                               FWP_FILTER_ENUM_FLAG_INCLUDE_DISABLED;
      filterEnumTemplate.numFilterConditions = 1;
      filterEnumTemplate.filterCondition     = &filterCondition;
      filterEnumTemplate.actionMask          = 0xFFFFFFFF;

      status = HlprFwpmFilterCreateEnumHandle(engineHandle,
                                              &filterEnumTemplate,
                                              &enumHandle);
      HLPR_BAIL_ON_FAILURE_WITH_LABEL(status,
                                      HLPR_BAIL_LABEL_2);

      status = HlprFwpmFilterEnum(engineHandle,
                                  enumHandle,
                                  0xFFFFFFFF,
                                  &ppFilters,
                                  &entryCount);
      HLPR_BAIL_ON_FAILURE_WITH_LABEL(status,
                                      HLPR_BAIL_LABEL_2);

      if(ppFilters)
      {
         for(UINT32 filterIndex = 0;
             filterIndex < entryCount;
             filterIndex++)
         {
            HlprFwpmFilterDeleteByKey(engineHandle,
                                      &(ppFilters[filterIndex]->filterKey));
         }

         FwpmFreeMemory((void**)&ppFilters);
      }

      HLPR_BAIL_LABEL_2:

      if(enumHandle)
         HlprFwpmFilterDestroyEnumHandle(engineHandle,
                                         &enumHandle);
   }

   HLPR_BAIL_LABEL:

   HlprSIDDestroy(&(filterCondition.conditionValue.sid));

   HlprFwpmEngineClose(&engineHandle);

   return status;
}
UINT32 PrvBasicPacketModificationScenarioAddFwpmObjects(_In_ const FWPM_FILTER* pFilter,
                                                        _In_ const PC_BASIC_PACKET_MODIFICATION_DATA* pPCBasicPacketModificationData)
{
   ASSERT(pFilter);
   ASSERT(pPCBasicPacketModificationData);

   UINT32                status          = NO_ERROR;
   HANDLE                engineHandle    = 0;
   FWP_BYTE_BLOB         byteBlob        = {0};
   FWPM_PROVIDER_CONTEXT providerContext = {0};
   FWPM_CALLOUT          callout         = {0};
   FWPM_FILTER           filter          = {0};

   RtlCopyMemory(&filter,
                 pFilter,
                 sizeof(FWPM_FILTER));

   status = HlprGUIDPopulate(&(providerContext.providerContextKey));
   HLPR_BAIL_ON_FAILURE(status);

   providerContext.displayData.name = L"WFPSampler's Basic Packet Modification Provider Context";
   providerContext.providerKey      = (GUID*)&WFPSAMPLER_PROVIDER;
   providerContext.type             = FWPM_GENERAL_CONTEXT;
   providerContext.dataBuffer       = &byteBlob;
   providerContext.dataBuffer->size = sizeof(PC_BASIC_PACKET_MODIFICATION_DATA);
   providerContext.dataBuffer->data = (UINT8*)pPCBasicPacketModificationData;

   callout.calloutKey              = WFPSAMPLER_CALLOUT_BASIC_PACKET_MODIFICATION;
   callout.calloutKey.Data4[7]     = HlprFwpmLayerGetIDByKey(&(filter.layerKey));             /// Uniquely identifies the callout used
   callout.displayData.name        = L"WFPSampler's Basic Packet Modification Callout";
   callout.displayData.description = L"Causes callout invocation which modifies the headers and injects traffic back";
   callout.flags                   = FWPM_CALLOUT_FLAG_USES_PROVIDER_CONTEXT;
   callout.providerKey             = (GUID*)&WFPSAMPLER_PROVIDER;
   callout.applicableLayer         = filter.layerKey;

   status = HlprGUIDPopulate(&(filter.filterKey));
   HLPR_BAIL_ON_FAILURE(status);

   filter.flags               |= FWPM_FILTER_FLAG_HAS_PROVIDER_CONTEXT;
   filter.providerKey          = (GUID*)&WFPSAMPLER_PROVIDER;
   filter.subLayerKey          = WFPSAMPLER_SUBLAYER;
   filter.weight.type          = FWP_UINT8;
   filter.weight.uint8         = 0xF;
   filter.action.type          = FWP_ACTION_CALLOUT_UNKNOWN;
   filter.action.calloutKey    = callout.calloutKey;
   filter.providerContextKey   = providerContext.providerContextKey;

   if(filter.flags & FWPM_FILTER_FLAG_BOOTTIME ||
      filter.flags & FWPM_FILTER_FLAG_PERSISTENT)
   {
      providerContext.flags |= FWPM_PROVIDER_CONTEXT_FLAG_PERSISTENT;

      callout.flags |= FWPM_CALLOUT_FLAG_PERSISTENT;
   }

   status = HlprFwpmEngineOpen(&engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmTransactionBegin(engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmProviderContextAdd(engineHandle,
                                       &providerContext);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmCalloutAdd(engineHandle,
                               &callout);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmFilterAdd(engineHandle,
                              &filter);
   HLPR_BAIL_ON_FAILURE(status);

   status = HlprFwpmTransactionCommit(engineHandle);
   HLPR_BAIL_ON_FAILURE(status);

   HLPR_BAIL_LABEL:

   if(engineHandle)
   {
      if(status != NO_ERROR)
         HlprFwpmTransactionAbort(engineHandle);

      HlprFwpmEngineClose(&engineHandle);
   }

   return status;
}