From 1ef1aee1204c1d38357880c8139d6498605e8a2d Mon Sep 17 00:00:00 2001 From: Pavel Yosifovich Date: Mon, 30 Sep 2024 21:23:10 -0400 Subject: [PATCH] provider button working in sublayer properties add new sublayer delete sublayer --- WFPCore/WFPEngine.cpp | 10 ++ WFPCore/WFPEngine.h | 2 + WFPExplorer/FiltersView.cpp | 2 +- WFPExplorer/MainFrm.cpp | 16 +++ WFPExplorer/MainFrm.h | 2 + WFPExplorer/NewSubLayerDlg.cpp | 126 ++++++++++++++++++++++++ WFPExplorer/NewSubLayerDlg.h | 40 ++++++++ WFPExplorer/SubLayerDlg.cpp | 9 ++ WFPExplorer/SubLayerDlg.h | 2 + WFPExplorer/SublayersView.cpp | 71 +++++++++++++ WFPExplorer/SublayersView.h | 11 +++ WFPExplorer/WFPExplorer.rc | 47 ++++++++- WFPExplorer/WFPExplorer.vcxproj | 2 + WFPExplorer/WFPExplorer.vcxproj.filters | 6 ++ WFPExplorer/resource.h | 7 +- 15 files changed, 347 insertions(+), 6 deletions(-) create mode 100644 WFPExplorer/NewSubLayerDlg.cpp create mode 100644 WFPExplorer/NewSubLayerDlg.h diff --git a/WFPCore/WFPEngine.cpp b/WFPCore/WFPEngine.cpp index 903f717..3a9619e 100644 --- a/WFPCore/WFPEngine.cpp +++ b/WFPCore/WFPEngine.cpp @@ -111,6 +111,16 @@ WFPObject WFPEngine::GetCalloutById(UINT32 id) const { return WFPObject(co); } +bool WFPEngine::AddSubLayer(FWPM_SUBLAYER const* sl, PSECURITY_DESCRIPTOR sd) { + m_LastError = FwpmSubLayerAdd(m_hEngine, sl, sd); + return m_LastError == ERROR_SUCCESS; +} + +bool WFPEngine::DeleteSubLayer(GUID const& key) { + m_LastError = FwpmSubLayerDeleteByKey(m_hEngine, &key); + return m_LastError == ERROR_SUCCESS; +} + uint32_t WFPEngine::GetFilterCount(GUID const& layer) const { HANDLE hEnum; m_LastError = FwpmFilterCreateEnumHandle(m_hEngine, nullptr, &hEnum); diff --git a/WFPCore/WFPEngine.h b/WFPCore/WFPEngine.h index f84e355..94b5680 100644 --- a/WFPCore/WFPEngine.h +++ b/WFPCore/WFPEngine.h @@ -69,6 +69,8 @@ public: WFPObject GetSublayerByKey(GUID const& key) const; WFPObject GetCalloutByKey(GUID const& key) const; WFPObject GetCalloutById(UINT32 id) const; + bool AddSubLayer(FWPM_SUBLAYER const* sl, PSECURITY_DESCRIPTOR sd = nullptr); + bool DeleteSubLayer(GUID const& key); private: HANDLE m_hEngine{ nullptr }; diff --git a/WFPExplorer/FiltersView.cpp b/WFPExplorer/FiltersView.cpp index c884269..99c9bca 100644 --- a/WFPExplorer/FiltersView.cpp +++ b/WFPExplorer/FiltersView.cpp @@ -187,7 +187,7 @@ LRESULT CFiltersView::OnDeleteFilter(WORD, WORD, HWND, BOOL&) { Refresh(); } if (deleted < selected) - AtlMessageBox(m_hWnd, std::format(L"Deleted {}/{} filters", deleted, selected).c_str(), IDS_TITLE, MB_ICONINFORMATION); + AtlMessageBox(m_hWnd, std::format(L"Deleted {}/{} filters.", deleted, selected).c_str(), IDS_TITLE, MB_ICONWARNING); return 0; } diff --git a/WFPExplorer/MainFrm.cpp b/WFPExplorer/MainFrm.cpp index 206abf6..130ec98 100644 --- a/WFPExplorer/MainFrm.cpp +++ b/WFPExplorer/MainFrm.cpp @@ -19,6 +19,7 @@ #include "NetEventsView.h" #include "ProviderDlg.h" #include "NewFilterDlg.h" +#include "NewSubLayerDlg.h" const int WINDOW_MENU_POSITION = 4; @@ -446,6 +447,21 @@ LRESULT CMainFrame::OnNewFilter(WORD, WORD, HWND, BOOL&) { return 0; } +LRESULT CMainFrame::OnNewSubLayer(WORD, WORD, HWND, BOOL&) { + FWPM_SUBLAYER sl{}; + CNewSubLayerDlg dlg(&sl); + if (IDOK == dlg.DoModal()) { + WFPEngine engine; + auto ok = engine.Open(); + if (ok) { + ok = engine.AddSubLayer(&sl); + } + AtlMessageBox(m_hWnd, ok ? L"Sublayer added successfully." : L"Failed to add sublayer.", + IDS_TITLE, ok ? MB_ICONINFORMATION : MB_ICONERROR); + } + return 0; +} + void CMainFrame::InitDarkTheme() const { s_DarkTheme.BackColor = s_DarkTheme.SysColors[COLOR_WINDOW] = RGB(32, 32, 32); s_DarkTheme.TextColor = s_DarkTheme.SysColors[COLOR_WINDOWTEXT] = RGB(248, 248, 248); diff --git a/WFPExplorer/MainFrm.h b/WFPExplorer/MainFrm.h index 919b3a2..6402939 100644 --- a/WFPExplorer/MainFrm.h +++ b/WFPExplorer/MainFrm.h @@ -49,6 +49,7 @@ public: COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit) COMMAND_ID_HANDLER(ID_NEW_FILTER, OnNewFilter) COMMAND_ID_HANDLER(ID_NEW_PROVIDER, OnNewProvider) + COMMAND_ID_HANDLER(ID_NEW_SUBLAYER, OnNewSubLayer) CHAIN_MSG_MAP(CAutoUpdateUI) CHAIN_MSG_MAP(COwnerDrawnMenu) CHAIN_MSG_MAP(CFrameWindowImpl) @@ -98,6 +99,7 @@ private: LRESULT OnToggleDarkMode(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); LRESULT OnNewProvider(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); LRESULT OnNewFilter(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnNewSubLayer(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); WFPEngine m_Engine; CFont m_MonoFont; diff --git a/WFPExplorer/NewSubLayerDlg.cpp b/WFPExplorer/NewSubLayerDlg.cpp new file mode 100644 index 0000000..2b81a9c --- /dev/null +++ b/WFPExplorer/NewSubLayerDlg.cpp @@ -0,0 +1,126 @@ +#include "pch.h" +#include "resource.h" +#include "NewSubLayerDlg.h" +#include "WFPHelper.h" +#include "StringHelper.h" +#include +#include + +CNewSubLayerDlg::CNewSubLayerDlg(FWPM_SUBLAYER* sublayer) : m_SubLayer(sublayer) { +} + +bool CNewSubLayerDlg::IsNewSubLayer() const { + return m_SubLayer->subLayerKey == GUID_NULL; +} + +bool CNewSubLayerDlg::UpdateSubLayer() { + GetDlgItemText(IDC_NAME, m_Name); + if (m_Name.IsEmpty()) { + AtlMessageBox(m_hWnd, L"Sublayer name cannot be empty.", L"New Sublayer", MB_ICONWARNING); + return false; + } + + CString key; + GetDlgItemText(IDC_KEY, key); + GetDlgItemText(IDC_DESC, m_Desc); + m_SubLayer->displayData.name = m_Name.GetBuffer(); + m_SubLayer->displayData.description = m_Desc.GetBuffer(); + ::CLSIDFromString(key, &m_SubLayer->subLayerKey); + + GetDlgItemText(IDC_WEIGHT, key); + m_SubLayer->weight = (UINT16)wcstol(key, nullptr, 0); + + // + // get provider + // + auto cb = (CComboBox)GetDlgItem(IDC_PROVIDER); + if (cb.GetCurSel()) { + CString text; + cb.GetLBText(cb.GetCurSel(), text); + m_ProviderKey = StringHelper::ExtractGuid(text); + ATLASSERT(m_ProviderKey != GUID_NULL); + m_SubLayer->providerKey = &m_ProviderKey; + } + + return true; +} + +LRESULT CNewSubLayerDlg::OnInitDialog(UINT, WPARAM, LPARAM, BOOL&) { + using namespace std; + using namespace std::views; + using namespace std::ranges; + + SetDialogIcon(IDI_SUBLAYER); + WFPEngine engine; + if (engine.Open()) { + // + // add providers to combo + // + WFPProviderEnumerator en(engine.Handle()); + auto providers = en.Next(256); + struct Data { + CString text; + int type; + }; + int selected = -1, i = 0; + auto data = providers | std::views::transform([&](auto& p) { + if (selected < 0 && m_SubLayer->providerKey && IsNewSubLayer() && p->providerKey == *m_SubLayer->providerKey) + selected = i; + i++; + + return Data{ p->displayData.name + CString(" (") + StringHelper::GuidToString(p->providerKey) + L")", i - 1 }; + }) | to(); + + data.insert(data.begin(), { L"(None)", -1 }); + InitCombo(IDC_PROVIDER, data.data(), (int)data.size(), selected); + } + + if (IsNewSubLayer()) { + SetDlgItemInt(IDC_WEIGHT, 0); + } + else { + SetDlgItemText(IDC_NAME, m_SubLayer->displayData.name); + SetDlgItemText(IDC_DESC, m_SubLayer->displayData.description); + SetDlgItemText(IDC_KEY, StringHelper::GuidToString(m_SubLayer->subLayerKey)); + if (m_SubLayer->flags & FWPM_SUBLAYER_FLAG_PERSISTENT) + CheckDlgButton(IDC_PERSISTENT, BST_CHECKED); + } + + return 0; +} + +LRESULT CNewSubLayerDlg::OnCloseCmd(WORD, WORD wID, HWND, BOOL&) { + if (wID == IDOK) { + if (!UpdateSubLayer()) + return 0; + } + EndDialog(wID); + return 0; +} + +LRESULT CNewSubLayerDlg::OnGenerateKey(WORD, WORD wID, HWND, BOOL&) { + GUID guid; + ::CoCreateGuid(&guid); + WCHAR sguid[64]; + ::StringFromGUID2(guid, sguid, _countof(sguid)); + SetDlgItemText(IDC_KEY, sguid); + + return 0; +} + +LRESULT CNewSubLayerDlg::OnProviderProperties(WORD, WORD wID, HWND, BOOL&) { + auto cb = (CComboBox)GetDlgItem(IDC_PROVIDER); + auto selected = cb.GetCurSel(); + if (selected == 0) + return 0; + + CString text; + cb.GetLBText(selected, text); + auto guid = StringHelper::ExtractGuid(text); + + WFPEngine engine; + engine.Open(); + WFPHelper::ShowProviderProperties(engine, *engine.GetProviderByKey(guid)); + + return 0; +} diff --git a/WFPExplorer/NewSubLayerDlg.h b/WFPExplorer/NewSubLayerDlg.h new file mode 100644 index 0000000..83dd7ed --- /dev/null +++ b/WFPExplorer/NewSubLayerDlg.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +class CNewSubLayerDlg : + public CDialogImpl, + public CDialogHelper { +public: + enum { IDD = IDD_NEWSUBLAYER }; + + explicit CNewSubLayerDlg(FWPM_SUBLAYER* sublayer); + + bool IsNewSubLayer() const; + + BEGIN_MSG_MAP(CNewSubLayerDlg) + MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_ID_HANDLER(IDOK, OnCloseCmd) + COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd) + COMMAND_ID_HANDLER(IDC_GENERATE, OnGenerateKey) + COMMAND_ID_HANDLER(IDC_PROVIDER_PROP, OnProviderProperties) + END_MSG_MAP() + + // Handler prototypes (uncomment arguments if needed): + // LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) + // LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) + // LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) + +private: + bool UpdateSubLayer(); + LRESULT ReportOpenEngineFailure(PCWSTR errorText = nullptr) const; + + LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); + LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnGenerateKey(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnProviderProperties(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + + FWPM_SUBLAYER* m_SubLayer; + CString m_Name, m_Desc; + GUID m_ProviderKey; +}; diff --git a/WFPExplorer/SubLayerDlg.cpp b/WFPExplorer/SubLayerDlg.cpp index c1b6541..fb6923d 100644 --- a/WFPExplorer/SubLayerDlg.cpp +++ b/WFPExplorer/SubLayerDlg.cpp @@ -9,6 +9,8 @@ CSubLayerDlg::CSubLayerDlg(WFPEngine& engine, FWPM_SUBLAYER* sublayer) : m_Engin } LRESULT CSubLayerDlg::OnInitDialog(UINT, WPARAM, LPARAM, BOOL&) { + SetDialogIcon(IDI_SUBLAYER); + SetWindowText(std::format(L"Sublayer ({})", m_Sublayer->displayData.name).c_str()); SetDlgItemText(IDC_KEY, StringHelper::GuidToString(m_Sublayer->subLayerKey)); SetDlgItemText(IDC_NAME, StringHelper::ParseMUIString(m_Sublayer->displayData.name)); SetDlgItemText(IDC_DESC, m_Sublayer->displayData.description); @@ -30,3 +32,10 @@ LRESULT CSubLayerDlg::OnCloseCmd(WORD, WORD wID, HWND, BOOL&) { EndDialog(wID); return 0; } + +LRESULT CSubLayerDlg::OnProviderProperties(WORD, WORD wID, HWND, BOOL&) { + ATLASSERT(m_Sublayer->providerKey); + WFPHelper::ShowProviderProperties(m_Engine, *m_Engine.GetProviderByKey(*m_Sublayer->providerKey)); + + return 0; +} diff --git a/WFPExplorer/SubLayerDlg.h b/WFPExplorer/SubLayerDlg.h index 2eb7b82..a7da9da 100644 --- a/WFPExplorer/SubLayerDlg.h +++ b/WFPExplorer/SubLayerDlg.h @@ -14,6 +14,7 @@ public: BEGIN_MSG_MAP(CSubLayerDlg) MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + COMMAND_ID_HANDLER(IDC_PROVIDER_PROP, OnProviderProperties) COMMAND_ID_HANDLER(IDOK, OnCloseCmd) COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd) END_MSG_MAP() @@ -26,6 +27,7 @@ public: private: LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); LRESULT OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnProviderProperties(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/); WFPEngine& m_Engine; FWPM_SUBLAYER* m_Sublayer; diff --git a/WFPExplorer/SublayersView.cpp b/WFPExplorer/SublayersView.cpp index 31f80f6..1daccea 100644 --- a/WFPExplorer/SublayersView.cpp +++ b/WFPExplorer/SublayersView.cpp @@ -4,6 +4,7 @@ #include #include "resource.h" #include +#include "WFPHelper.h" CSublayersView::CSublayersView(IMainFrame* frame, WFPEngine& engine) : CGenericListViewBase(frame), m_Engine(engine) { } @@ -37,12 +38,52 @@ LRESULT CSublayersView::OnRefresh(WORD, WORD, HWND, BOOL&) { return 0; } +LRESULT CSublayersView::OnDeleteSubLayer(WORD, WORD, HWND, BOOL&) { + int selected = m_List.GetSelectedCount(); + ATLASSERT(selected > 0); + if (AtlMessageBox(m_hWnd, L"Delete selected sublayer(s)?", IDS_TITLE, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2) == IDNO) + return 0; + + int deleted = 0; + for (auto index : SelectedItemsView(m_List)) { + auto const& sl = m_Layers[index]; + if (m_Engine.DeleteSubLayer(sl.Data->subLayerKey)) + deleted++; + } + if (deleted > 0) { + m_List.SelectAllItems(false); + Refresh(); + } + if (deleted < selected) + AtlMessageBox(m_hWnd, std::format(L"Deleted {}/{} sublayers.", deleted, selected).c_str(), IDS_TITLE, MB_ICONWARNING); + + return 0; +} + +LRESULT CSublayersView::OnProperties(WORD, WORD, HWND, BOOL&) { + auto row = m_List.GetNextItem(-1, LVNI_SELECTED); + if (row >= 0) { + auto& sl = m_Layers[row]; + WFPHelper::ShowSublayerProperties(m_Engine, sl.Data); + } + return 0; +} + void CSublayersView::Refresh() { 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()); } +void CSublayersView::UpdateUI() const { + auto& ui = Frame()->UI(); + auto selected = m_List.GetSelectedCount(); + ui.UIEnable(ID_EDIT_PROPERTIES, selected == 1); + ui.UIEnable(ID_EDIT_DELETE, selected > 0); + ui.UIEnable(ID_EDIT_COPY, selected > 0); + ui.UIEnable(ID_EDIT_FINDNEXT, Frame()->GetFindDialog() != nullptr); +} + CString CSublayersView::GetColumnText(HWND, int row, int col) { auto& sl = m_Layers[row]; auto info = sl.Data; @@ -106,6 +147,31 @@ CString CSublayersView::GetDefaultSaveFile() const { return L"sublayers.csv"; } +bool CSublayersView::OnDoubleClickList(HWND, int row, int col, POINT const& pt) { + if (row >= 0) { + auto& sl = m_Layers[row]; + WFPHelper::ShowSublayerProperties(m_Engine, sl.Data); + return true; + } + return false; +} + +bool CSublayersView::OnRightClickList(HWND, int row, int col, POINT const& pt) const { + if (row < 0) + return false; + + CMenu menu; + menu.LoadMenu(IDR_CONTEXT); + + return Frame()->TrackPopupMenu(menu.GetSubMenu(2), 0, pt.x, pt.y); +} + +LRESULT CSublayersView::OnActivate(UINT, WPARAM activate, LPARAM, BOOL&) { + if (activate) + UpdateUI(); + return 0; +} + CString const& CSublayersView::SubLayerInfo::Name() const { if (m_Name.IsEmpty()) m_Name = StringHelper::ParseMUIString(Data->displayData.name); @@ -117,3 +183,8 @@ CString const& CSublayersView::SubLayerInfo::Desc() const { m_Desc = StringHelper::ParseMUIString(Data->displayData.description); return m_Desc; } + +void CSublayersView::OnStateChanged(HWND, int from, int to, UINT oldState, UINT newState) { + if ((newState & LVIS_SELECTED) || (oldState & LVIS_SELECTED)) + UpdateUI(); +} diff --git a/WFPExplorer/SublayersView.h b/WFPExplorer/SublayersView.h index ec9787e..216e523 100644 --- a/WFPExplorer/SublayersView.h +++ b/WFPExplorer/SublayersView.h @@ -18,12 +18,18 @@ public: int GetSaveColumnRange(HWND, int&) const; int GetRowImage(HWND, int row, int col) const; CString GetDefaultSaveFile() const; + bool OnDoubleClickList(HWND, int row, int col, POINT const& pt); + bool OnRightClickList(HWND, int row, int col, POINT const& pt) const; + void OnStateChanged(HWND, int from, int to, UINT oldState, UINT newState); BEGIN_MSG_MAP(CSublayersView) + MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) MESSAGE_HANDLER(WM_CREATE, OnCreate) CHAIN_MSG_MAP(CGenericListViewBase) ALT_MSG_MAP(1) COMMAND_ID_HANDLER(ID_VIEW_REFRESH, OnRefresh) + COMMAND_ID_HANDLER(ID_EDIT_PROPERTIES, OnProperties) + COMMAND_ID_HANDLER(ID_EDIT_DELETE, OnDeleteSubLayer) CHAIN_MSG_MAP_ALT(CGenericListViewBase, 1) END_MSG_MAP() @@ -33,6 +39,8 @@ public: // LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/) private: + void UpdateUI() const; + enum class ColumnType { Key, Name, Desc, Flags, Weight, Provider, ProviderData, }; @@ -49,6 +57,9 @@ private: LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); LRESULT OnRefresh(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnDeleteSubLayer(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnProperties(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnActivate(UINT, WPARAM activate, LPARAM, BOOL&); WFPEngine& m_Engine; diff --git a/WFPExplorer/WFPExplorer.rc b/WFPExplorer/WFPExplorer.rc index 2b52499..1d18cc3 100644 --- a/WFPExplorer/WFPExplorer.rc +++ b/WFPExplorer/WFPExplorer.rc @@ -56,8 +56,8 @@ BEGIN POPUP "&New" BEGIN MENUITEM "&Filter...", ID_NEW_FILTER - MENUITEM "&Simple Filter...", ID_NEW_SIMPLEFILTER MENUITEM "&Provider...", ID_NEW_PROVIDER + MENUITEM "&Sublayer...", ID_NEW_SUBLAYER END MENUITEM SEPARATOR MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN @@ -130,6 +130,12 @@ BEGIN MENUITEM SEPARATOR MENUITEM "Properties...\tAlt+Enter", ID_EDIT_PROPERTIES END + POPUP "sublayer" + BEGIN + MENUITEM "&Delete\tDel", ID_EDIT_DELETE + MENUITEM SEPARATOR + MENUITEM "Properties...\tAlt+Enter", ID_EDIT_PROPERTIES + END END @@ -421,11 +427,35 @@ BEGIN PUSHBUTTON "Provider...",IDC_PROVIDER_PROP,323,66,55,14 CHECKBOX "Persistent",IDC_PERSISTENT,50,88,48,10 LTEXT "Weight:",IDC_STATIC,113,89,26,8 - EDITTEXT IDC_WEIGHT,148,87,40,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER,WS_EX_STATICEDGE + EDITTEXT IDC_WEIGHT,148,88,40,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER,WS_EX_STATICEDGE LTEXT "Provider Data:",IDC_DATASIZE,21,106,48,8 EDITTEXT IDC_PROVIDERDATA,17,118,347,30,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER,WS_EX_STATICEDGE END +IDD_NEWSUBLAYER DIALOGEX 0, 0, 385, 185 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "New Sublayer" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + PUSHBUTTON "Cancel",IDCANCEL,200,164,50,14 + LTEXT "Key:",IDC_STATIC,31,8,16,8 + EDITTEXT IDC_KEY,51,7,248,12,ES_AUTOHSCROLL | NOT WS_BORDER,WS_EX_STATICEDGE + LTEXT "Name:",IDC_STATIC,25,28,22,8 + EDITTEXT IDC_NAME,51,27,327,12,ES_AUTOHSCROLL | NOT WS_BORDER,WS_EX_STATICEDGE + LTEXT "Description:",IDC_STATIC,8,49,39,8 + EDITTEXT IDC_DESC,51,48,327,12,ES_AUTOHSCROLL | NOT WS_BORDER,WS_EX_STATICEDGE + LTEXT "Provider:",IDC_STATIC,16,68,30,8 + PUSHBUTTON "Provider...",IDC_PROVIDER_PROP,323,66,55,14 + CONTROL "Persistent",IDC_PERSISTENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,51,88,48,10 + LTEXT "Weight:",IDC_STATIC,113,89,26,8 + EDITTEXT IDC_WEIGHT,148,88,44,14,ES_AUTOHSCROLL | NOT WS_BORDER,WS_EX_STATICEDGE + LTEXT "Provider Data:",IDC_DATASIZE,21,106,48,8 + EDITTEXT IDC_PROVIDERDATA,17,118,347,30,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER,WS_EX_STATICEDGE + PUSHBUTTON "&Generate",IDC_GENERATE,328,7,50,14 + COMBOBOX IDC_PROVIDER,51,66,263,112,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "OK",IDOK,134,164,50,14 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -514,6 +544,14 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 178 END + + IDD_NEWSUBLAYER, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 378 + TOPMARGIN, 7 + BOTTOMMARGIN, 178 + END END #endif // APSTUDIO_INVOKED @@ -644,6 +682,11 @@ BEGIN 0 END +IDD_NEWSUBLAYER AFX_DIALOG_LAYOUT +BEGIN + 0 +END + ///////////////////////////////////////////////////////////////////////////// // diff --git a/WFPExplorer/WFPExplorer.vcxproj b/WFPExplorer/WFPExplorer.vcxproj index ac48358..41c4752 100644 --- a/WFPExplorer/WFPExplorer.vcxproj +++ b/WFPExplorer/WFPExplorer.vcxproj @@ -372,6 +372,7 @@ + Create Create @@ -408,6 +409,7 @@ + diff --git a/WFPExplorer/WFPExplorer.vcxproj.filters b/WFPExplorer/WFPExplorer.vcxproj.filters index a33e353..199cb9c 100644 --- a/WFPExplorer/WFPExplorer.vcxproj.filters +++ b/WFPExplorer/WFPExplorer.vcxproj.filters @@ -105,6 +105,9 @@ Dialogs + + Dialogs + @@ -188,6 +191,9 @@ Dialogs + + Dialogs + diff --git a/WFPExplorer/resource.h b/WFPExplorer/resource.h index c5235aa..9ccef1a 100644 --- a/WFPExplorer/resource.h +++ b/WFPExplorer/resource.h @@ -49,7 +49,7 @@ #define IDI_CHECK 247 #define IDI_RADIO 248 #define IDD_SUBLAYER 249 -#define IDI_ICON1 251 +#define IDD_NEWSUBLAYER 250 #define IDI_INFO 251 #define IDC_VERSION 1000 #define IDC_COPYRIGHT 1001 @@ -118,14 +118,15 @@ #define ID_NEW_PROVIDER 32796 #define ID_EDIT_FINDNEXT 32797 #define ID_VIEW_STATISTICS 32798 +#define ID_NEW_SUBLAYER 32799 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 252 -#define _APS_NEXT_COMMAND_VALUE 32799 -#define _APS_NEXT_CONTROL_VALUE 1036 +#define _APS_NEXT_COMMAND_VALUE 32800 +#define _APS_NEXT_CONTROL_VALUE 1038 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif