Surveillance des modifications de filtre
L’exemple de code suivant montre comment surveiller l’ajout et la suppression de filtres susceptibles d’affecter une application serveur.
Notes
Les conditions de filtre sont les mêmes que celles prises en charge par l’API IsPortAllowed de niveau inférieur.
#include <windows.h>
#include <fwpmu.h>
#include <stdio.h>
#pragma comment(lib, "fwpuclnt.lib")
#define EXIT_ON_ERROR(fnName) \
if (result != ERROR_SUCCESS) \
{ \
printf(#fnName " = 0x%08X\n", result); \
goto CLEANUP; \
}
void FilterChangeCallback(IN void* context,
IN const FWPM_FILTER_CHANGE0* change)
{
PCSTR changeType;
wchar_t guidString[sizeof("{eaea82e6-6747-4321-ab51-44ba5509b812}")];
switch (change->changeType)
{
case FWPM_CHANGE_ADD:
{
changeType = "FWPM_CHANGE_ADD";
break;
}
case FWPM_CHANGE_DELETE:
{
changeType = "FWPM_CHANGE_DELETE";
break;
}
default:
{
changeType = "<unknown>";
break;
}
}
printf(
" changeType = %s\n"
" filterId = %I64u\n"
"\n",
changeType,
change->filterId
);
}
DWORD InitFilterConditions(
__in_opt PCWSTR appPath,
__in_opt const SOCKADDR* localAddr,
__in_opt UINT8 ipProtocol,
__in UINT32 numCondsIn,
__out_ecount_part(numCondsIn, *numCondsOut)
FWPM_FILTER_CONDITION0* conds,
__out UINT32* numCondsOut,
__deref_out FWP_BYTE_BLOB** appId
)
{
*numCondsOut = 0;
return 0;
}
DWORD MonitorMatchingFilters(
__in HANDLE engine,
__in const GUID* layerKey,
__in_opt PCWSTR appPath,
__in_opt const SOCKADDR* localAddr,
__in_opt UINT8 ipProtocol,
__in FWPM_FILTER_CHANGE_CALLBACK0 callback,
__in_opt void* context,
__out HANDLE* changeHandle
)
{
DWORD result = ERROR_SUCCESS;
FWPM_FILTER_CONDITION0 conds[4];
UINT32 numConds;
FWP_BYTE_BLOB* appBlob = NULL;
FWPM_FILTER_ENUM_TEMPLATE0 enumTempl;
FWPM_FILTER_SUBSCRIPTION0 sub;
// InitFilterConditions is presented in the
// Populating Filter Conditions example code
result = InitFilterConditions(
appPath,
localAddr,
ipProtocol,
ARRAYSIZE(conds),
conds,
&numConds,
&appBlob
);
EXIT_ON_ERROR(InitFilterConditions);
memset(&enumTempl, 0, sizeof(enumTempl));
enumTempl.layerKey = *layerKey;
enumTempl.numFilterConditions = numConds;
if (numConds > 0)
{
enumTempl.filterCondition = conds;
}
// We want to see all filters regardless of action.
enumTempl.actionMask = 0xFFFFFFFF;
memset(&sub, 0, sizeof(sub));
sub.enumTemplate = &enumTempl;
// We want to see both adds and deletes.
sub.flags = ( FWPM_SUBSCRIPTION_FLAG_NOTIFY_ON_ADD |
FWPM_SUBSCRIPTION_FLAG_NOTIFY_ON_DELETE );
// Once we have successfully subscribed, our callback will be invoked for
// every matching add and delete until we call FwpmFilterUnsubscribeChanges0.
result = FwpmFilterSubscribeChanges0(
engine,
&sub,
callback,
context,
changeHandle
);
EXIT_ON_ERROR(result);
CLEANUP:
FwpmFreeMemory0((void**)&appBlob);
return result;
}
DWORD wmain(int argc,
wchar_t* argv[])
{
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
// Open a session to the filter engine
HANDLE engineHandle = 0;
// Use dynamic sessions for efficiency and safety:
// - All objects associated with the dynamic session are deleted with one call.
// - Filtering policy objects are deleted even when the application crashes.
FWPM_SESSION0 session;
memset(&session, 0, sizeof(session));
session.flags = FWPM_SESSION_FLAG_DYNAMIC;
DWORD result = FwpmEngineOpen0(NULL, RPC_C_AUTHN_WINNT, NULL, &session, &engineHandle);
EXIT_ON_ERROR(FwpmEngineOpen0);
HANDLE changeHandle = 0;
FWPM_FILTER_CHANGE_CALLBACK0 callback = (FWPM_FILTER_CHANGE_CALLBACK0)FilterChangeCallback;
result = MonitorMatchingFilters(
engineHandle,
&FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4,
0,
0,
0,
callback,
0,
&changeHandle
);
CLEANUP:
if (result != ERROR_SUCCESS)
{
printf("Error: %x\n", result);
}
else
{
printf("Success");
}
return result;
}