2025-11-28 00:35:46 +09:00

290 lines
7.5 KiB
C

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
/*++
Module Name:
Diagevents.c
Abstract:
This file contains sample code for a command line utility which dumps the
diagnostic events using the Windows Filtering Platform(WFP) API NDF
Helper Class Functions.
--*/
#ifndef UNICODE
#define UNICODE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <fwpmtypes.h>
#include <fwpmu.h>
#include "wfpeventutil.h"
#ifdef __cplusplus
}
#endif
#define NUM_FILTER_CONDITIONS 4
#define MIN_FACTOR 600000000
#define CHECK_RESULT(result) {\
if (ERROR_SUCCESS != result) \
goto cleanup;\
}
DWORD
GetMatchingEvents(
__in UINT32 mins,
__in ADDRESS_FAMILY version,
__in_opt SOCKADDR_STORAGE* remoteAddr,
__out FWPM_NET_EVENT0*** matchedEvents,
__out UINT32* numMatchedEvents
)
/*++
Routine Description:
This routine creates and fills an event enumeration template, and
retrieve events matching the template using WFP API. The diagnostic
events API is used only in this function
Arguments:
mins - period in minutes for which events should be retrieved going
back from current time.
version - IP version
remoteAddr - pointer to IP address which should match the remote
address in events.
matchedEvents - pointer to an array of pointers to events that have
period and/or remote address matching those specified.
numMatchedEvents - pointer to the number of events matching the
criterion.
Return Value:
DWORD - If the function succeeds, the return value is ERROR_SUCCESS.
--*/
{
DWORD result = ERROR_SUCCESS;
UINT32 filterCondCount = 0;
FWPM_NET_EVENT_ENUM_TEMPLATE0 eventTemplate;
FWPM_FILTER_CONDITION0 filterConditions[NUM_FILTER_CONDITIONS] = {0};
HANDLE fwpEngineHandle = NULL;
HANDLE enumHandle = NULL;
BOOLEAN engineOpen = FALSE;
SYSTEMTIME curTimeSys;
//-----------------------------------------
// The period in which the event happened is set to current sytem time.
GetSystemTime(&curTimeSys);
if (!(SystemTimeToFileTime(&curTimeSys, &(eventTemplate.endTime))))
{
wprintf(L"Error in converting system time to file time.\n");
result = GetLastError();
CHECK_RESULT(result);
}
//-----------------------------------------
// Set the lower end of the period in which events are of interest
if (0 == mins)
{
eventTemplate.startTime.dwLowDateTime = 0;
eventTemplate.startTime.dwHighDateTime = 0;
}
else
{
ULARGE_INTEGER filetime;
ULONGLONG period;
filetime.LowPart = eventTemplate.endTime.dwLowDateTime;
filetime.HighPart = eventTemplate.endTime.dwHighDateTime;
period = ((ULONGLONG)mins)*MIN_FACTOR;
if (filetime.QuadPart > period)
{
filetime.QuadPart -= period;
}
else
{
filetime.QuadPart = 0;
}
eventTemplate.startTime.dwLowDateTime = filetime.LowPart;
eventTemplate.startTime.dwHighDateTime = filetime.HighPart;
}
//-----------------------------------------
// Set the filter condition to look for events matching the remote address
if (remoteAddr)
{
if (AF_INET == version)
{
SOCKADDR_IN* ipV4Addr = (SOCKADDR_IN*)remoteAddr;
filterConditions[filterCondCount].fieldKey =
FWPM_CONDITION_IP_REMOTE_ADDRESS;
filterConditions[filterCondCount].matchType = FWP_MATCH_EQUAL;
filterConditions[filterCondCount].conditionValue.type = FWP_UINT32;
filterConditions[filterCondCount].conditionValue.uint32 =
ntohl(ipV4Addr->sin_addr.s_addr);
filterCondCount++;
}
else if (AF_INET6 == version)
{
SOCKADDR_IN6* ipV6Addr = (SOCKADDR_IN6*)remoteAddr;
filterConditions[filterCondCount].fieldKey =
FWPM_CONDITION_IP_REMOTE_ADDRESS;
filterConditions[filterCondCount].matchType = FWP_MATCH_EQUAL;
filterConditions[filterCondCount].conditionValue.type =
FWP_BYTE_ARRAY16_TYPE;
filterConditions[filterCondCount].conditionValue.byteArray16 =
(FWP_BYTE_ARRAY16 *)(ipV6Addr->sin6_addr.s6_bytes);
filterCondCount++;
}
}
//-----------------------------------------
// Fill the event enumeration template
eventTemplate.numFilterConditions = filterCondCount;
eventTemplate.filterCondition = filterConditions;
//-----------------------------------------
// Open a session to the filter engine
result = FwpmEngineOpen0(
NULL,
RPC_C_AUTHN_WINNT,
NULL,
NULL,
&fwpEngineHandle
);
CHECK_RESULT(result);
//-----------------------------------------
// Create an enumeration handle based on event template
result = FwpmNetEventCreateEnumHandle0(
fwpEngineHandle,
&eventTemplate,
&enumHandle
);
CHECK_RESULT(result);
//-----------------------------------------
// Get the events from enumeration
result = FwpmNetEventEnum0(
fwpEngineHandle,
enumHandle,
INFINITE,
matchedEvents,
numMatchedEvents
);
CHECK_RESULT(result);
//
// fallthrough
//
cleanup:
//-----------------------------------------
// Destroy enumeration handle
if (enumHandle)
{
FwpmNetEventDestroyEnumHandle0(fwpEngineHandle, enumHandle);
}
//-----------------------------------------
// Close session after destroying enumeration handle
if (fwpEngineHandle)
{
FwpmEngineClose0(fwpEngineHandle);
}
return result;
}
int __cdecl wmain(int argc, const wchar_t* const argv[])
{
DWORD result = ERROR_SUCCESS;
UINT32 mins = 0;
UINT32 num = 0;
ADDRESS_FAMILY version;
SOCKADDR_STORAGE remoteAddr = {0};
FWPM_NET_EVENT0** matchedEvents;
BOOL stop = FALSE;
WSADATA wsaData;
//-----------------------------------------
// Initialize Winsock
if (WSAStartup(MAKEWORD(2,2), &wsaData))
{
wprintf(L"Winsock library initialization failed\n");
result = E_UNEXPECTED;
CHECK_RESULT(result);
}
//-----------------------------------------
// Parse and Validate the command line arguments
result = ParseArguments(
argc,
argv,
&mins,
&version,
&remoteAddr,
&stop
);
CHECK_RESULT(result);
if (stop)
{
goto cleanup;
}
//-----------------------------------------
// Get events matching the arguments
result = GetMatchingEvents(
mins,
version,
&remoteAddr,
&matchedEvents,
&num);
CHECK_RESULT(result);
if (num == 0)
{
wprintf(L"No events matching criterion\n");
goto cleanup;
}
if (matchedEvents == NULL)
{
wprintf(L"Number of events is not zero. But event pointer NULL\n");
result = ERROR_INVALID_DATA;
goto cleanup;
}
//-----------------------------------------
// Print event details of all events matching criterion
PrintEvents(matchedEvents, num);
//-----------------------------------------
// Free memory allocated by engine for enumerated events
FwpmFreeMemory0((VOID**)&matchedEvents);
cleanup:
WSACleanup();
return result;
}