mirror of
https://github.com/zodiacon/WFPExplorer
synced 2026-06-08 18:39:31 +00:00
allow sorting in network event view
This commit is contained in:
@@ -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) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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*/);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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='*'\"")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user