allow sorting in network event view

This commit is contained in:
Pavel Yosifovich
2022-12-13 21:01:09 -05:00
parent 63d5158ba5
commit 76d78646b8
12 changed files with 152 additions and 41 deletions
+11
View File
@@ -88,3 +88,14 @@ struct WFPProviderContextEnumerator : WFPEnumerator<
}
};
struct WFPConnectionEnumerator : WFPEnumerator<
decltype(&::FwpmConnectionCreateEnumHandle),
decltype(&::FwpmConnectionDestroyEnumHandle),
decltype(&::FwpmConnectionEnum),
FWPM_CONNECTION> {
explicit WFPConnectionEnumerator(HANDLE hEngine) :
WFPEnumerator(hEngine, ::FwpmConnectionCreateEnumHandle, ::FwpmConnectionDestroyEnumHandle, ::FwpmConnectionEnum) {
}
};
+9 -5
View File
@@ -13,14 +13,18 @@ public:
SETTING(DarkMode, 0, SettingType::Bool);
SETTING(SingleInstance, 0, SettingType::Bool);
SETTING(HideEmptyLayers, 1, SettingType::Bool);
SETTING(AppendNetworkEvents, 0, SettingType::Bool);
SETTING(ResolveNetworkAddresses, 0, SettingType::Bool);
END_SETTINGS
DEF_SETTING(DarkMode, int)
DEF_SETTING(AlwaysOnTop, int)
DEF_SETTING(ViewToolBar, int)
DEF_SETTING(ViewStatusBar, int)
DEF_SETTING(SingleInstance, int)
DEF_SETTING(DarkMode, bool)
DEF_SETTING(AlwaysOnTop, bool)
DEF_SETTING(ViewToolBar, bool)
DEF_SETTING(ViewStatusBar, bool)
DEF_SETTING(SingleInstance, bool)
DEF_SETTING(MainWindowPlacement, WINDOWPLACEMENT)
DEF_SETTING(HideEmptyLayers, bool)
DEF_SETTING(AppendNetworkEvents, bool)
DEF_SETTING(ResolveNetworkAddresses, bool)
};
-2
View File
@@ -97,8 +97,6 @@ CString CLayersView::GetColumnText(HWND, int row, int col) {
}
void CLayersView::DoSort(SortInfo const* si) {
if (si == nullptr)
return;
auto col = GetColumnManager(m_List)->GetColumnTag<ColumnType>(si->SortColumn);
auto asc = si->SortAscending;
+97 -22
View File
@@ -3,6 +3,7 @@
#include <Enumerators.h>
#include <atltime.h>
#include "StringHelper.h"
#include <SortHelper.h>
CNetEventsView::CNetEventsView(IMainFrame* frame, WFPEngine& engine) : CFrameView(frame), m_Engine(engine) {
}
@@ -24,32 +25,52 @@ CString CNetEventsView::GetColumnText(HWND, int row, int col) {
case ColumnType::AddressFamily: return StringHelper::AddressFamilyToString(e->header.addressFamily);
case ColumnType::Protocol: return StringHelper::IpProtocolToString(e->header.ipProtocol);
case ColumnType::ScopeId: return (flags & FWPM_NET_EVENT_FLAG_SCOPE_ID_SET) ? std::to_wstring(e->header.scopeId).c_str() : L"";
case ColumnType::LocalPort: return (flags & FWPM_NET_EVENT_FLAG_LOCAL_PORT_SET) ? std::to_wstring(e->header.localPort).c_str() : L"";
case ColumnType::RemotePort: return (flags & FWPM_NET_EVENT_FLAG_REMOTE_PORT_SET) ? std::to_wstring(e->header.remotePort).c_str() : L"";
case ColumnType::LocalAddress:
if (e->header.ipVersion == FWP_IP_VERSION_NONE || (flags & FWPM_NET_EVENT_FLAG_LOCAL_ADDR_SET) == 0)
return L"";
return e->header.ipVersion == FWP_IP_VERSION_V4
? StringHelper::FormatIpv4Address(e->header.localAddrV4)
: StringHelper::FormatIpv6Address(e->header.localAddrV6.byteArray16);
case ColumnType::RemoteAddress:
if (e->header.ipVersion == FWP_IP_VERSION_NONE || (flags & FWPM_NET_EVENT_FLAG_REMOTE_ADDR_SET) == 0)
return L"";
return e->header.ipVersion == FWP_IP_VERSION_V4
? StringHelper::FormatIpv4Address(e->header.remoteAddrV4)
: StringHelper::FormatIpv6Address(e->header.remoteAddrV6.byteArray16);
case ColumnType::LocalPort:
{
auto port = GetLocalPort(info);
return port ? std::to_wstring(port).c_str() : L"";
}
case ColumnType::UserId: return (flags & FWPM_NET_EVENT_FLAG_USER_ID_SET) ? StringHelper::FormatSID(e->header.userId) : CString(L"");
case ColumnType::PackageId: return (flags & FWPM_NET_EVENT_FLAG_PACKAGE_ID_SET) ? StringHelper::FormatSID(e->header.packageSid) : CString(L"");
case ColumnType::AppId:
return (e->header.flags & FWPM_NET_EVENT_FLAG_APP_ID_SET) ?
StringHelper::FormatBinary(e->header.appId.data, min(16, e->header.appId.size)) : CString(L"");
case ColumnType::RemotePort:
{
auto port = GetRemotePort(info);
return port ? std::to_wstring(port).c_str() : L"";
}
case ColumnType::LocalAddress: return GetLocalAddress(info);
case ColumnType::RemoteAddress: return GetRemoteAddress(info);
case ColumnType::UserId: return GetUserId(info);
case ColumnType::PackageId: return GetPackageId(info);
case ColumnType::AppId: return GetAppId(info);
}
return CString();
}
void CNetEventsView::DoSort(SortInfo const* si) {
auto col = GetColumnManager(si->hWnd)->GetColumnTag<ColumnType>(si->SortColumn);
auto asc = si->SortAscending;
auto compare = [&](auto& ev1, auto& ev2) {
auto e1 = ev1.Data, e2 = ev2.Data;
switch (col) {
case ColumnType::LocalAddress: return SortHelper::Sort(GetLocalAddress(ev1), GetLocalAddress(ev2), asc);
case ColumnType::RemoteAddress: return SortHelper::Sort(GetRemoteAddress(ev1), GetRemoteAddress(ev2), asc);
case ColumnType::LocalPort: return SortHelper::Sort(GetLocalPort(ev1), GetLocalPort(ev2), asc);
case ColumnType::RemotePort: return SortHelper::Sort(GetRemotePort(ev1), GetRemotePort(ev2), asc);
case ColumnType::Time: return SortHelper::Sort(*(LONGLONG*)&e1->header.timeStamp, *(LONGLONG*)&e2->header.timeStamp, asc);
case ColumnType::Type: return SortHelper::Sort(StringHelper::NetEventTypeToString(e1->type), StringHelper::NetEventTypeToString(e2->type), asc);
case ColumnType::AddressFamily: return SortHelper::Sort(
StringHelper::AddressFamilyToString(e1->header.addressFamily),
StringHelper::AddressFamilyToString(e2->header.addressFamily), asc);
case ColumnType::Protocol: return SortHelper::Sort(
StringHelper::IpProtocolToString(e1->header.ipProtocol),
StringHelper::IpProtocolToString(e2->header.ipProtocol), asc);
case ColumnType::ScopeId: return SortHelper::Sort(e1->header.scopeId, e2->header.scopeId, asc);
case ColumnType::AppId: return SortHelper::Sort(GetAppId(ev1), GetAppId(ev2), asc);
}
return false;
};
std::ranges::sort(m_Events, compare);
}
int CNetEventsView::GetRowImage(HWND, int row, int col) const {
@@ -59,6 +80,60 @@ int CNetEventsView::GetRowImage(HWND, int row, int col) const {
void CNetEventsView::UpdateUI() {
}
CString const& CNetEventsView::GetLocalAddress(NetEventInfo& info) {
if (info.LocalAddress.IsEmpty()) {
auto const& header = info.Data->header;
auto flags = header.flags;
if (flags & FWPM_NET_EVENT_FLAG_LOCAL_ADDR_SET)
info.LocalAddress = header.ipVersion == FWP_IP_VERSION_V4
? StringHelper::FormatIpv4Address(header.localAddrV4)
: StringHelper::FormatIpv6Address(header.localAddrV6.byteArray16);
}
return info.LocalAddress;
}
CString const& CNetEventsView::GetRemoteAddress(NetEventInfo& info) {
if (info.RemoteAddress.IsEmpty()) {
auto const& header = info.Data->header;
auto flags = header.flags;
if (flags & FWPM_NET_EVENT_FLAG_REMOTE_ADDR_SET)
info.RemoteAddress = header.ipVersion == FWP_IP_VERSION_V4
? StringHelper::FormatIpv4Address(header.remoteAddrV4)
: StringHelper::FormatIpv6Address(header.remoteAddrV6.byteArray16);
}
return info.RemoteAddress;
}
UINT16 CNetEventsView::GetLocalPort(NetEventInfo& info) const {
return (info.Data->header.flags & FWPM_NET_EVENT_FLAG_LOCAL_PORT_SET) ? info.Data->header.localPort : 0;
}
UINT16 CNetEventsView::GetRemotePort(NetEventInfo& info) const {
return (info.Data->header.flags & FWPM_NET_EVENT_FLAG_REMOTE_PORT_SET) ? info.Data->header.localPort : 0;
}
CString const& CNetEventsView::GetAppId(NetEventInfo& info) {
if (info.AppId.IsEmpty()) {
info.AppId = (info.Data->header.flags & FWPM_NET_EVENT_FLAG_APP_ID_SET) ?
StringHelper::FormatBinary(info.Data->header.appId.data, min(16, info.Data->header.appId.size)) : CString(L"");
}
return info.AppId;
}
CString const& CNetEventsView::GetUserId(NetEventInfo& info) {
if (info.UserId.IsEmpty()) {
info.UserId = (info.Data->header.flags & FWPM_NET_EVENT_FLAG_USER_ID_SET) ? StringHelper::FormatSID(info.Data->header.userId) : CString(L"");
}
return info.UserId;
}
CString const& CNetEventsView::GetPackageId(NetEventInfo& info) {
if (info.PackageId.IsEmpty()) {
info.PackageId = (info.Data->header.flags & FWPM_NET_EVENT_FLAG_PACKAGE_ID_SET) ? StringHelper::FormatSID(info.Data->header.packageSid) : CString(L"");
}
return info.PackageId;
}
LRESULT CNetEventsView::OnCreate(UINT, WPARAM, LPARAM, BOOL&) {
m_hWndClient = m_List.Create(m_hWnd, rcDefault, nullptr,
WS_CHILD | WS_VISIBLE | LVS_OWNERDATA | LVS_REPORT);
@@ -73,9 +148,9 @@ LRESULT CNetEventsView::OnCreate(UINT, WPARAM, LPARAM, BOOL&) {
cm->AddColumn(L"Time", 0, 130, ColumnType::Time);
cm->AddColumn(L"Protocol", 0, 90, ColumnType::Protocol);
cm->AddColumn(L"Address Family", 0, 70, ColumnType::AddressFamily);
cm->AddColumn(L"Local Address", LVCFMT_RIGHT, 170, ColumnType::LocalAddress);
cm->AddColumn(L"Local Address", LVCFMT_RIGHT, 220, ColumnType::LocalAddress);
cm->AddColumn(L"Local Port", LVCFMT_RIGHT, 80, ColumnType::LocalPort);
cm->AddColumn(L"Remote Address", LVCFMT_RIGHT, 170, ColumnType::RemoteAddress);
cm->AddColumn(L"Remote Address", LVCFMT_RIGHT, 220, ColumnType::RemoteAddress);
cm->AddColumn(L"Remote Port", LVCFMT_RIGHT, 80, ColumnType::RemotePort);
cm->AddColumn(L"Scope ID", LVCFMT_RIGHT, 80, ColumnType::ScopeId);
cm->AddColumn(L"User ID", 0, 180, ColumnType::UserId);
+13 -4
View File
@@ -40,7 +40,20 @@ public:
// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
private:
struct NetEventInfo {
FWPM_NET_EVENT* Data;
CString LocalAddress, RemoteAddress;
CString AppId, UserId, PackageId;
};
void UpdateUI();
CString const& GetLocalAddress(NetEventInfo& info);
CString const& GetRemoteAddress(NetEventInfo& info);
UINT16 GetLocalPort(NetEventInfo& info) const;
UINT16 GetRemotePort(NetEventInfo& info) const;
CString const& GetAppId(NetEventInfo& info);
CString const& GetUserId(NetEventInfo& info);
CString const& GetPackageId(NetEventInfo& info);
enum class ColumnType {
Time, Type, LocalPort, RemotePort, LocalAddress, RemoteAddress, Flags, EnterpriseId,
@@ -49,10 +62,6 @@ private:
};
struct NetEventInfo {
FWPM_NET_EVENT* Data;
};
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnRefresh(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
LRESULT OnProperties(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
+1 -1
View File
@@ -68,7 +68,7 @@ CString CProviderContextView::GetColumnText(HWND, int row, int col) {
case ColumnType::Flags:
if (info->flags == 0)
return L"0";
return std::format(L"0x{:X} ({})", info->flags, StringHelper::WFPProviderContextFlagsToString(info->flags)).c_str();
return std::format(L"0x{:X} ({})", info->flags, (PCWSTR)StringHelper::WFPProviderContextFlagsToString(info->flags)).c_str();
}
return CString();
}
+1 -1
View File
@@ -55,7 +55,7 @@ CString CProvidersView::GetColumnText(HWND, int row, int col) {
case ColumnType::Flags:
if (info->flags == 0)
return L"0";
return std::format(L"0x{:X} ({})", info->flags, StringHelper::WFPProviderFlagsToString(info->flags)).c_str();
return std::format(L"0x{:X} ({})", info->flags, (PCWSTR)StringHelper::WFPProviderFlagsToString(info->flags)).c_str();
case ColumnType::ServiceName: return info->serviceName;
}
return CString();
+1 -1
View File
@@ -40,7 +40,7 @@ CString CSessionsView::GetColumnText(HWND, int row, int col) {
case ColumnType::Flags:
if (data->flags == 0)
return L"0";
return std::format(L"0x{:X} ({})", data->flags, StringHelper::WFPSessionFlagsToString(data->flags)).c_str();
return std::format(L"0x{:X} ({})", data->flags, (PCWSTR)StringHelper::WFPSessionFlagsToString(data->flags)).c_str();
case ColumnType::ProcessName:
if (session.ProcessName.IsEmpty())
session.ProcessName = ProcessHelper::GetProcessName(data->processId);
+11 -4
View File
@@ -53,6 +53,11 @@ IDR_MAINFRAME MENU
BEGIN
POPUP "&File"
BEGIN
POPUP "&New"
BEGIN
MENUITEM "&Filter...", ID_NEW_FILTER
END
MENUITEM SEPARATOR
MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
MENUITEM "&Save...\tCtrl+S", ID_FILE_SAVE
MENUITEM SEPARATOR
@@ -369,8 +374,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,3,0,0
PRODUCTVERSION 0,3,0,0
FILEVERSION 0,4,0,0
PRODUCTVERSION 0,4,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -387,12 +392,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Scorpio Software"
VALUE "FileDescription", "Windows Filtering Platform Explorer"
VALUE "FileVersion", "0.3"
VALUE "FileVersion", "0.4.0.0"
VALUE "InternalName", "WFPExplorer"
VALUE "LegalCopyright", "©2022 Pavel Yosifovich"
VALUE "OriginalFilename", "WFPExplorer.exe"
VALUE "ProductName", "WFP Explorer"
VALUE "ProductVersion", "0.3"
VALUE "ProductVersion", "0.4.0.0"
END
END
BLOCK "VarFileInfo"
@@ -551,6 +556,8 @@ STRINGTABLE
BEGIN
ID_VIEW_PROVIDERS "\nProviders"
ID_VIEW_PROVIDERCONTEXTS "\nProvider Contexts"
ID_VIEW_NETWORKEVENTS "\nNetwork Events"
ID_NEW_FILTER "\nNew Filter"
END
#endif // English (United States) resources
+2
View File
@@ -31,6 +31,8 @@ extern CAppModule _Module;
#include <strsafe.h>
#include <dontuse.h>
#include <TlHelp32.h>
#include <ranges>
#include <algorithm>
#if defined _M_IX86
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
+3 -1
View File
@@ -78,13 +78,15 @@
#define ID_VIEW_NETWORKEVENTS 32787
#define ID_OPTIONS_APPENDNETWORKEVENTS 32788
#define ID_OPTIONS_RESOLVENETWORKADDRESSES 32789
#define ID_FILE_NEW32790 32790
#define ID_NEW_FILTER 32791
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 236
#define _APS_NEXT_COMMAND_VALUE 32790
#define _APS_NEXT_COMMAND_VALUE 32792
#define _APS_NEXT_CONTROL_VALUE 1019
#define _APS_NEXT_SYMED_VALUE 101
#endif
+3
View File
@@ -105,6 +105,9 @@ int main(int argc, const char* argv[]) {
return 1;
}
WFPConnectionEnumerator enumerator(engine.Handle());
auto conns = enumerator.Next(256);
switch (argv[1][0]) {
case 's': case 'S':
DisplaySessions(engine);