From afd79f789bc355edcfc5511668194686a4549644 Mon Sep 17 00:00:00 2001 From: Pavel Yosifovich Date: Sun, 11 Dec 2022 14:10:24 -0500 Subject: [PATCH] sublayers refactored --- WFPCore/WFPEngine.cpp | 12 +++--- WFPCore/WFPEngine.h | 73 +---------------------------------- WFPExplorer/FiltersView.cpp | 4 +- WFPExplorer/LayersView.cpp | 4 +- WFPExplorer/SessionsView.cpp | 2 +- WFPExplorer/StringHelper.cpp | 6 +-- WFPExplorer/StringHelper.h | 5 +-- WFPExplorer/SublayersView.cpp | 65 +++++++++++++++++++------------ WFPExplorer/SublayersView.h | 11 +++++- WFPExplorer/WFPHelper.cpp | 4 +- 10 files changed, 67 insertions(+), 119 deletions(-) diff --git a/WFPCore/WFPEngine.cpp b/WFPCore/WFPEngine.cpp index 5375617..8788cdc 100644 --- a/WFPCore/WFPEngine.cpp +++ b/WFPCore/WFPEngine.cpp @@ -62,18 +62,16 @@ WFPObject WFPEngine::GetLayerByKey(GUID const& key) const { return WFPObject(layer); } -WFPObject WFPEngine::GetLayerById(UINT16 id) const { +WFPObject WFPEngine::GetLayerById(UINT16 id) const { FWPM_LAYER* layer; m_LastError = FwpmLayerGetById(m_hEngine, id, &layer); return WFPObject(layer); } -std::optional WFPEngine::GetSublayerByKey(GUID const& key) const { - FWPM_SUBLAYER* sublayer; - FwpmSubLayerGetByKey(m_hEngine, &key, &sublayer); - auto info = InitSubLayer(sublayer); - FwpmFreeMemory((void**)&sublayer); - return info; +WFPObject WFPEngine::GetSublayerByKey(GUID const& key) const { + FWPM_SUBLAYER* sublayer = nullptr; + m_LastError = FwpmSubLayerGetByKey(m_hEngine, &key, &sublayer); + return WFPObject(sublayer); } WFPProviderContextInfo WFPEngine::InitProviderContext(FWPM_PROVIDER_CONTEXT* p, bool includeData) { diff --git a/WFPCore/WFPEngine.h b/WFPCore/WFPEngine.h index 9238525..ee36a87 100644 --- a/WFPCore/WFPEngine.h +++ b/WFPCore/WFPEngine.h @@ -6,19 +6,6 @@ #include #include -enum class WFPSessionFlags { - None, - Dynamic = FWPM_SESSION_FLAG_DYNAMIC, - Reserved = FWPM_SESSION_FLAG_RESERVED, -}; -DEFINE_ENUM_FLAG_OPERATORS(WFPSessionFlags); - -enum class WFPIPVersion { - V4 = 0, - V6, - NONE, -}; - enum class WFPProviderContextFlags { None, Persistent = FWPM_PROVIDER_CONTEXT_FLAG_PERSISTENT, @@ -26,17 +13,6 @@ enum class WFPProviderContextFlags { }; DEFINE_ENUM_FLAG_OPERATORS(WFPProviderContextFlags); -struct WFPSubLayerInfo { - GUID SubLayerKey; - std::wstring Name; - std::wstring Desc; - UINT32 Flags; - GUID ProviderKey; - std::vector ProviderData; - uint32_t ProviderDataSize; - UINT16 Weight; -}; - enum class WFPProviderContextType { IPSecKeying = FWPM_IPSEC_KEYING_CONTEXT, IPSecIkeQuickModeTransport = FWPM_IPSEC_IKE_QM_TRANSPORT_CONTEXT, @@ -105,31 +81,6 @@ public: uint32_t GetFilterCount(GUID const& layer = GUID_NULL) const; uint32_t GetCalloutCount(GUID const& layer = GUID_NULL) const; - - template requires std::is_base_of_v - std::vector EnumSubLayers() const { - HANDLE hEnum; - std::vector info; - m_LastError = FwpmSubLayerCreateEnumHandle(m_hEngine, nullptr, &hEnum); - if (m_LastError) - return info; - FWPM_SUBLAYER** layers; - UINT32 count; - m_LastError = FwpmSubLayerEnum(m_hEngine, hEnum, 256, &layers, &count); - if (m_LastError == ERROR_SUCCESS) { - info.reserve(count); - for (UINT32 i = 0; i < count; i++) { - auto layer = layers[i]; - auto li = InitSubLayer(layer); - info.emplace_back(std::move(li)); - } - FwpmFreeMemory((void**)&layers); - } - m_LastError = FwpmSubLayerDestroyEnumHandle(m_hEngine, hEnum); - return info; - - } - std::vector EnumProviderContexts(bool includeData = false) const; // @@ -154,8 +105,8 @@ public: // // sublayer API // - std::optional GetSublayerByKey(GUID const& key) const; - std::optional GetSublayerById(UINT16 id) const; + WFPObject GetSublayerByKey(GUID const& key) const; + WFPObject GetSublayerById(UINT16 id) const; WFPObject GetCalloutByKey(GUID const& key) const; @@ -167,26 +118,6 @@ private: static std::wstring ParseMUIString(PCWSTR input); static WFPProviderContextInfo InitProviderContext(FWPM_PROVIDER_CONTEXT* p, bool full = false); - - template requires std::is_base_of_v - static TLayer InitSubLayer(FWPM_SUBLAYER* layer, bool full = false) { - TLayer li; - li.Name = ParseMUIString(layer->displayData.name); - li.Desc = ParseMUIString(layer->displayData.description); - li.SubLayerKey = layer->subLayerKey; - li.Flags = layer->flags; - li.Weight = layer->weight; - li.ProviderKey = layer->providerKey ? *layer->providerKey : GUID_NULL; - li.ProviderDataSize = layer->providerData.size; - if (full && li.ProviderDataSize) { - li.ProviderData.resize(li.ProviderDataSize); - memcpy(li.ProviderData.data(), layer->providerData.data, layer->providerData.size); - } - return li; - } - - static std::wstring PoorParseMUIString(std::wstring const& path); - HANDLE m_hEngine{ nullptr }; mutable DWORD m_LastError{ 0 }; }; diff --git a/WFPExplorer/FiltersView.cpp b/WFPExplorer/FiltersView.cpp index 878eb3e..b1e4aad 100644 --- a/WFPExplorer/FiltersView.cpp +++ b/WFPExplorer/FiltersView.cpp @@ -101,8 +101,8 @@ CString const& CFiltersView::GetLayerName(FilterInfo& info) const { CString const& CFiltersView::GetSublayerName(FilterInfo& info) const { if (info.SubLayer.IsEmpty()) { auto layer = m_Engine.GetSublayerByKey(info.Data->subLayerKey); - if (layer && !layer.value().Name.empty() && layer.value().Name[0] != L'@') - info.SubLayer = layer.value().Name.c_str(); + if (layer) + info.SubLayer = StringHelper::ParseMUIString(layer->displayData.name); else info.SubLayer = StringHelper::GuidToString(info.Data->layerKey); } diff --git a/WFPExplorer/LayersView.cpp b/WFPExplorer/LayersView.cpp index 71637cb..7428376 100644 --- a/WFPExplorer/LayersView.cpp +++ b/WFPExplorer/LayersView.cpp @@ -71,8 +71,8 @@ CString CLayersView::GetColumnText(HWND, int row, int col) { if (layer.DefaultSublayer.IsEmpty()) { if (info->defaultSubLayerKey != GUID_NULL) { auto sl = m_Engine.GetSublayerByKey(info->defaultSubLayerKey); - if (sl && !sl.value().Name.empty()) - layer.DefaultSublayer = sl.value().Name.c_str(); + if (sl) + layer.DefaultSublayer = StringHelper::ParseMUIString(sl->displayData.name); else layer.DefaultSublayer = StringHelper::GuidToString(info->defaultSubLayerKey); } diff --git a/WFPExplorer/SessionsView.cpp b/WFPExplorer/SessionsView.cpp index d15fae7..31ced86 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((WFPSessionFlags)data->flags)).c_str(); + return std::format(L"0x{:X} ({})", data->flags, StringHelper::WFPSessionFlagsToString(data->flags)).c_str(); case ColumnType::ProcessName: if (session.ProcessName.IsEmpty()) session.ProcessName = ProcessHelper::GetProcessName(data->processId); diff --git a/WFPExplorer/StringHelper.cpp b/WFPExplorer/StringHelper.cpp index 7f3d98d..0a6168b 100644 --- a/WFPExplorer/StringHelper.cpp +++ b/WFPExplorer/StringHelper.cpp @@ -123,12 +123,12 @@ CString StringHelper::WFPLayerFlagsToString(UINT32 flags) { return FlagsToString(flags, data); } -CString StringHelper::WFPSessionFlagsToString(WFPSessionFlags flags) { +CString StringHelper::WFPSessionFlagsToString(UINT32 flags) { static const struct { - WFPSessionFlags flag; + UINT32 flag; PCWSTR text; } data[] = { - { WFPSessionFlags::Dynamic, L"Dynamic" }, + { FWPM_SESSION_FLAG_DYNAMIC, L"Dynamic" }, }; return FlagsToString(flags, data); diff --git a/WFPExplorer/StringHelper.h b/WFPExplorer/StringHelper.h index edec6c0..a95e81c 100644 --- a/WFPExplorer/StringHelper.h +++ b/WFPExplorer/StringHelper.h @@ -1,8 +1,5 @@ #pragma once -enum class WFPSessionFlags; -enum class WFPProviderFlags; -enum class WFPSubLayerFlags; enum class WFPProviderContextFlags; enum class WFPProviderContextType; @@ -13,7 +10,7 @@ struct StringHelper abstract final { static CString WFPConditionValueToString(FWP_CONDITION_VALUE const& value, bool hex = false, bool full = false); static CString WFPFilterFlagsToString(UINT32 flags); static CString WFPLayerFlagsToString(UINT32 flags); - static CString WFPSessionFlagsToString(WFPSessionFlags flags); + static CString WFPSessionFlagsToString(UINT32 flags); static CString WFPProviderFlagsToString(DWORD flags); static CString WFPSubLayerFlagsToString(UINT32 flags); static CString WFPCalloutFlagsToString(DWORD flags); diff --git a/WFPExplorer/SublayersView.cpp b/WFPExplorer/SublayersView.cpp index 5fc0ab5..28e2e29 100644 --- a/WFPExplorer/SublayersView.cpp +++ b/WFPExplorer/SublayersView.cpp @@ -3,6 +3,7 @@ #include "StringHelper.h" #include #include "resource.h" +#include CSublayersView::CSublayersView(IMainFrame* frame, WFPEngine& engine) : CFrameView(frame), m_Engine(engine) { } @@ -37,36 +38,37 @@ LRESULT CSublayersView::OnRefresh(WORD, WORD, HWND, BOOL&) { } void CSublayersView::Refresh() { - m_Layers = m_Engine.EnumSubLayers(); + m_Layers = WFPSubLayerEnumerator(m_Engine.Handle()).Next(512); m_List.SetItemCountEx((int)m_Layers.size(), LVSICF_NOSCROLL); Frame()->SetStatusText(6, std::format(L"{} Sublayers", m_Layers.size()).c_str()); } CString CSublayersView::GetColumnText(HWND, int row, int col) { - auto& info = m_Layers[row]; + auto& sl = m_Layers[row]; + auto info = sl.Data; switch (GetColumnManager(m_List)->GetColumnTag(col)) { - case ColumnType::Key: return StringHelper::GuidToString(info.SubLayerKey); - case ColumnType::Name: return info.Name.c_str(); - case ColumnType::Desc: return info.Desc.c_str(); - case ColumnType::ProviderData: return info.ProviderDataSize == 0 ? L"" : std::format(L"{} Bytes", info.ProviderDataSize).c_str(); + case ColumnType::Key: return StringHelper::GuidToString(info->subLayerKey); + case ColumnType::Name: return sl.Name(); + case ColumnType::Desc: return sl.Desc(); + case ColumnType::ProviderData: return info->providerData.size == 0 ? L"" : std::format(L"{} Bytes", info->providerData.size).c_str(); case ColumnType::Flags: - if (info.Flags == 0) + if (info->flags == 0) return L"0"; - return std::format(L"0x{:X} ({})", info.Flags, - (PCWSTR)StringHelper::WFPSubLayerFlagsToString(info.Flags)).c_str(); + return std::format(L"0x{:X} ({})", info->flags, + (PCWSTR)StringHelper::WFPSubLayerFlagsToString(info->flags)).c_str(); - case ColumnType::Weight: return std::to_wstring(info.Weight).c_str(); + case ColumnType::Weight: return std::to_wstring(info->weight).c_str(); case ColumnType::Provider: - if (info.ProviderName.IsEmpty()) { - if (info.ProviderKey != GUID_NULL) { - auto provider = m_Engine.GetProviderByKey(info.ProviderKey); - if (provider && provider->displayData.name && provider->displayData.name[0] != L'@') - info.ProviderName = provider->displayData.name; + if (sl.ProviderName.IsEmpty()) { + if (info->providerKey) { + auto provider = m_Engine.GetProviderByKey(*info->providerKey); + if (provider) + sl.ProviderName = StringHelper::ParseMUIString(provider->displayData.name); else - info.ProviderName = StringHelper::GuidToString(info.ProviderKey); + sl.ProviderName = StringHelper::GuidToString(*info->providerKey); } } - return info.ProviderName; + return sl.ProviderName; } return CString(); @@ -76,15 +78,16 @@ void CSublayersView::DoSort(SortInfo const* si) { auto col = GetColumnManager(m_List)->GetColumnTag(si->SortColumn); auto asc = si->SortAscending; - auto compare = [&](auto& l1, auto& l2) { + auto compare = [&](auto& sl1, auto& sl2) { + auto l1 = sl1.Data, l2 = sl2.Data; switch (col) { - case ColumnType::Key: return SortHelper::Sort(StringHelper::GuidToString(l1.SubLayerKey), StringHelper::GuidToString(l2.SubLayerKey), asc); - case ColumnType::Name: return SortHelper::Sort(l1.Name, l2.Name, asc); - case ColumnType::Desc: return SortHelper::Sort(l1.Desc, l2.Desc, asc); - case ColumnType::Flags: return SortHelper::Sort(l1.Flags, l2.Flags, asc); - case ColumnType::Provider: return SortHelper::Sort(l1.ProviderName, l2.ProviderName, asc); - case ColumnType::Weight: return SortHelper::Sort(l1.Weight, l2.Weight, asc); - case ColumnType::ProviderData: return SortHelper::Sort(l1.ProviderDataSize, l2.ProviderDataSize, asc); + case ColumnType::Key: return SortHelper::Sort(StringHelper::GuidToString(l1->subLayerKey), StringHelper::GuidToString(l2->subLayerKey), asc); + case ColumnType::Name: return SortHelper::Sort(sl1.Name(), sl2.Name(), asc); + case ColumnType::Desc: return SortHelper::Sort(sl1.Desc(), sl2.Desc(), asc); + case ColumnType::Flags: return SortHelper::Sort(l1->flags, l2->flags, asc); + case ColumnType::Provider: return SortHelper::Sort(sl1.ProviderName, sl2.ProviderName, asc); + case ColumnType::Weight: return SortHelper::Sort(l1->weight, l2->weight, asc); + case ColumnType::ProviderData: return SortHelper::Sort(l1->providerData.size, l2->providerData.size, asc); } return false; }; @@ -98,3 +101,15 @@ int CSublayersView::GetSaveColumnRange(HWND, int&) const { int CSublayersView::GetRowImage(HWND, int row, int col) const { return 0; } + +CString const& CSublayersView::SubLayerInfo::Name() const { + if (m_Name.IsEmpty()) + m_Name = StringHelper::ParseMUIString(Data->displayData.name); + return m_Name; +} + +CString const& CSublayersView::SubLayerInfo::Desc() const { + if (m_Desc.IsEmpty()) + m_Desc = StringHelper::ParseMUIString(Data->displayData.description); + return m_Desc; +} diff --git a/WFPExplorer/SublayersView.h b/WFPExplorer/SublayersView.h index 790979b..a529de4 100644 --- a/WFPExplorer/SublayersView.h +++ b/WFPExplorer/SublayersView.h @@ -4,6 +4,7 @@ #include #include "Interfaces.h" #include +#include class WFPEngine; @@ -38,8 +39,14 @@ private: Key, Name, Desc, Flags, Weight, Provider, ProviderData, }; - struct SubLayerInfo : WFPSubLayerInfo { + struct SubLayerInfo { + FWPM_SUBLAYER* Data; CString ProviderName; + CString const& Name() const; + CString const& Desc() const; + + private: + mutable CString m_Name, m_Desc; }; LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); @@ -48,5 +55,5 @@ private: WFPEngine& m_Engine; CListViewCtrl m_List; - std::vector m_Layers; + WFPObjectVector m_Layers; }; diff --git a/WFPExplorer/WFPHelper.cpp b/WFPExplorer/WFPHelper.cpp index ec880a3..e08e133 100644 --- a/WFPExplorer/WFPHelper.cpp +++ b/WFPExplorer/WFPHelper.cpp @@ -41,8 +41,8 @@ CString WFPHelper::GetLayerName(WFPEngine const& engine, GUID const& key) { CString WFPHelper::GetSublayerName(WFPEngine const& engine, GUID const& key) { if (key != GUID_NULL) { auto layer = engine.GetSublayerByKey(key); - if (layer && !layer->Name.empty() && layer->Name[0] != L'@') - return layer->Name.c_str(); + if (layer) + return StringHelper::ParseMUIString(layer->displayData.name); return StringHelper::GuidToString(key); } return L"";