diff --git a/WFPCore/Enumerators.h b/WFPCore/Enumerators.h index 45e5307..8610d42 100644 --- a/WFPCore/Enumerators.h +++ b/WFPCore/Enumerators.h @@ -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) { + } +}; + diff --git a/WFPExplorer/AppSettings.h b/WFPExplorer/AppSettings.h index c2bb004..9dbb1c7 100644 --- a/WFPExplorer/AppSettings.h +++ b/WFPExplorer/AppSettings.h @@ -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) }; diff --git a/WFPExplorer/LayersView.cpp b/WFPExplorer/LayersView.cpp index 7428376..c19957d 100644 --- a/WFPExplorer/LayersView.cpp +++ b/WFPExplorer/LayersView.cpp @@ -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(si->SortColumn); auto asc = si->SortAscending; diff --git a/WFPExplorer/NetEventsView.cpp b/WFPExplorer/NetEventsView.cpp index 02d8d47..96ba371 100644 --- a/WFPExplorer/NetEventsView.cpp +++ b/WFPExplorer/NetEventsView.cpp @@ -3,6 +3,7 @@ #include #include #include "StringHelper.h" +#include 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(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); diff --git a/WFPExplorer/NetEventsView.h b/WFPExplorer/NetEventsView.h index 7641ce1..c8a4700 100644 --- a/WFPExplorer/NetEventsView.h +++ b/WFPExplorer/NetEventsView.h @@ -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*/); diff --git a/WFPExplorer/ProviderContextView.cpp b/WFPExplorer/ProviderContextView.cpp index e2e62f3..3dcca76 100644 --- a/WFPExplorer/ProviderContextView.cpp +++ b/WFPExplorer/ProviderContextView.cpp @@ -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(); } diff --git a/WFPExplorer/ProvidersView.cpp b/WFPExplorer/ProvidersView.cpp index b2fd698..8e9146f 100644 --- a/WFPExplorer/ProvidersView.cpp +++ b/WFPExplorer/ProvidersView.cpp @@ -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(); diff --git a/WFPExplorer/SessionsView.cpp b/WFPExplorer/SessionsView.cpp index 31ced86..f87a160 100644 --- a/WFPExplorer/SessionsView.cpp +++ b/WFPExplorer/SessionsView.cpp @@ -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); diff --git a/WFPExplorer/WFPExplorer.rc b/WFPExplorer/WFPExplorer.rc index 2b86043..69ce60f 100644 --- a/WFPExplorer/WFPExplorer.rc +++ b/WFPExplorer/WFPExplorer.rc @@ -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 diff --git a/WFPExplorer/pch.h b/WFPExplorer/pch.h index 8003f90..74af661 100644 --- a/WFPExplorer/pch.h +++ b/WFPExplorer/pch.h @@ -31,6 +31,8 @@ extern CAppModule _Module; #include #include #include +#include +#include #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='*'\"") diff --git a/WFPExplorer/resource.h b/WFPExplorer/resource.h index e67d969..27b8599 100644 --- a/WFPExplorer/resource.h +++ b/WFPExplorer/resource.h @@ -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 diff --git a/wfpc/wfpc.cpp b/wfpc/wfpc.cpp index 2a17abb..d843f78 100644 --- a/wfpc/wfpc.cpp +++ b/wfpc/wfpc.cpp @@ -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);