// simplewall // Copyright (c) 2016-2024 Henry++ #include "global.h" _Ret_maybenull_ PEDITOR_CONTEXT _app_editor_createwindow ( _In_ HWND hwnd, _In_ PVOID lparam, _In_ INT page_id, _In_ BOOLEAN is_settorules ) { PEDITOR_CONTEXT context; context = _r_mem_allocate (sizeof (EDITOR_CONTEXT)); context->ptr_app = lparam; context->page_id = page_id; context->is_settorules = is_settorules; if (_r_wnd_createmodalwindow (_r_sys_getimagebase (), MAKEINTRESOURCEW (IDD_EDITOR), hwnd, &EditorProc, context)) return context; _app_editor_deletewindow (context); return NULL; } VOID _app_editor_deletewindow ( _In_ PEDITOR_CONTEXT context ) { _r_mem_free (context); } _Ret_maybenull_ PEDITOR_CONTEXT _app_editor_getcontext ( _In_ HWND hwnd ) { PEDITOR_CONTEXT context; context = _r_wnd_getcontext (hwnd, SHORT_MAX); return context; } VOID _app_editor_setcontext ( _In_ HWND hwnd, _In_ PEDITOR_CONTEXT context ) { _r_wnd_setcontext (hwnd, SHORT_MAX, context); } VOID _app_editor_addtabitem ( _In_ HWND hwnd, _In_ UINT locale_id, _In_ INT dlg_id, _In_ PEDITOR_CONTEXT context, _Inout_ PINT tabs_count ) { HWND htab; htab = _r_wnd_createwindow (_r_sys_getimagebase (), MAKEINTRESOURCEW (dlg_id), hwnd, &EditorPagesProc, context); if (!htab) return; _r_tab_additem (hwnd, IDC_TAB, *tabs_count, _r_locale_getstring (locale_id), I_IMAGENONE, (LPARAM)htab); *tabs_count += 1; _r_tab_adjustchild (hwnd, IDC_TAB, htab); BringWindowToTop (htab); // HACK!!! _r_wnd_sendmessage (htab, 0, RM_INITIALIZE, 0, 0); } VOID _app_editor_settabtitle ( _In_ HWND hwnd, _In_ INT listview_id ) { WCHAR buffer[128]; HWND hparent; UINT locale_id; INT checked_count; INT tab_id; if (listview_id == IDC_RULE_APPS_ID) { locale_id = IDS_TAB_APPS; tab_id = 2; } else if (listview_id == IDC_APP_RULES_ID) { locale_id = IDS_TRAY_RULES; tab_id = 1; } else { return; } hparent = GetParent (hwnd); if (!hparent) return; checked_count = _r_listview_getitemcheckedcount (hwnd, listview_id); _r_str_printf (buffer, RTL_NUMBER_OF (buffer), L"%s (%d)", _r_locale_getstring (locale_id), checked_count); _r_tab_setitem (hparent, IDC_TAB, tab_id, buffer, I_IMAGENONE, 0); } _Ret_maybenull_ PR_STRING _app_editor_getrulesfromlistview ( _In_ HWND hwnd, _In_ INT ctrl_id, _In_ INT exclude_id ) { static R_STRINGREF divider_sr = PR_STRINGREF_INIT (DIVIDER_RULE); R_STRINGBUILDER sb; PR_STRING string; INT item_count; item_count = _r_listview_getitemcount (hwnd, ctrl_id); if (!item_count) return NULL; _r_obj_initializestringbuilder (&sb, 512); for (INT i = 0; i < item_count; i++) { if (i == exclude_id) continue; string = _r_listview_getitemtext (hwnd, ctrl_id, i, 0); if (string) { _r_str_trimstring2 (&string->sr, DIVIDER_RULE DIVIDER_TRIM, 0); if (!_r_obj_isstringempty2 (string)) { // check maximum length of one rule if ((_r_str_getlength2 (&sb.string->sr) + _r_str_getlength2 (&string->sr)) > RULE_RULE_CCH_MAX) { _r_obj_dereference (string); break; } _r_obj_appendstringbuilder2 (&sb, &string->sr); _r_obj_appendstringbuilder2 (&sb, ÷r_sr); } _r_obj_dereference (string); } } string = _r_obj_finalstringbuilder (&sb); _r_str_trimstring (&string->sr, ÷r_sr, PR_TRIM_END_ONLY); if (_r_obj_isstringempty2 (string)) { _r_obj_dereference (string); return NULL; } return string; } VOID _app_editor_setrulestolistview ( _In_ HWND hwnd, _In_ INT ctrl_id, _In_ PR_STRING rule ) { PR_STRING rule_string; R_STRINGREF first_part; R_STRINGREF remaining_part; INT item_id = 0; _r_obj_initializestringref2 (&remaining_part, &rule->sr); while (remaining_part.length != 0) { _r_str_splitatchar (&remaining_part, DIVIDER_RULE[0], &first_part, &remaining_part); rule_string = _r_obj_createstring2 (&first_part); _app_listview_lock (hwnd, ctrl_id, TRUE); _r_listview_additem (hwnd, ctrl_id, item_id, rule_string->buffer); _app_listview_lock (hwnd, ctrl_id, FALSE); item_id += 1; _r_obj_dereference (rule_string); } _r_listview_setcolumn (hwnd, ctrl_id, 0, NULL, -100); } INT_PTR CALLBACK EditorRuleProc ( _In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM wparam, _In_ LPARAM lparam ) { PEDITOR_CONTEXT context; switch (msg) { case WM_INITDIALOG: { PR_STRING string; context = (PEDITOR_CONTEXT)lparam; _app_editor_setcontext (hwnd, context); _r_wnd_center (hwnd, GetParent (hwnd)); // localize window _r_ctrl_setstring (hwnd, 0, _r_locale_getstring (IDS_RULE)); _r_edit_settextlimit ( hwnd, IDC_RULE_ID, _r_calc_clamp (RULE_RULE_CCH_MAX - (LONG)(context->current_length) - 1, 1, RULE_RULE_CCH_MAX) ); _r_edit_setcuebanner (hwnd, IDC_RULE_ID, L"Example: 192.168.0.1;192.168.0.17"); if (context->item_id != -1) { string = _r_listview_getitemtext (context->hwnd, context->listview_id, context->item_id, 0); if (string) { _r_ctrl_setstring (hwnd, IDC_RULE_ID, string->buffer); _r_obj_dereference (string); } } _r_ctrl_setstring ( hwnd, IDC_RULE_HINT, L"eg. 192.168.0.1; 192.168.0.1; [fc00::]\r\neg. 192.168.0.1:80; 192.168.0.1:443; [fc00::]:443;\r\n"\ L"eg. 192.168.0.1-192.168.0.255; 192.168.0.1-192.168.0.255;\r\neg. 192.168.0.1-192.168.0.255:80; 192.168.0.1-192.168.0.255:443;\r\n"\ L"eg. 192.168.0.0/16; 192.168.0.0/24; fe80::/10;\r\n"\ L"eg. 20-21; 49152-65534;\r\neg. 21; 80; 443\r\n" ); _r_ctrl_setstring ( hwnd, IDC_SAVE, _r_locale_getstring (context->item_id != -1 ? IDS_SAVE : IDS_ADD) ); _r_ctrl_setstring (hwnd, IDC_CLOSE, _r_locale_getstring (IDS_CLOSE)); // enable save button _r_ctrl_enable (hwnd, IDC_SAVE, _r_ctrl_getstringlength (hwnd, IDC_RULE_ID) != 0); _r_theme_initialize (hwnd, _r_theme_isenabled ()); SetFocus (NULL); break; } case WM_CLOSE: { EndDialog (hwnd, FALSE); break; } case WM_PAINT: { PAINTSTRUCT ps; HDC hdc; hdc = BeginPaint (hwnd, &ps); if (!hdc) break; _r_dc_drawwindow (hdc, hwnd, TRUE); EndPaint (hwnd, &ps); break; } case WM_DPICHANGED: { _r_wnd_message_dpichanged (hwnd, wparam, lparam); break; } case WM_SETTINGCHANGE: { _r_wnd_message_settingchange (hwnd, wparam, lparam); break; } case WM_COMMAND: { INT ctrl_id = LOWORD (wparam); INT notify_code = HIWORD (wparam); if (notify_code == EN_CHANGE) { // enable save button _r_ctrl_enable (hwnd, IDC_SAVE, _r_ctrl_getstringlength (hwnd, IDC_RULE_ID) != 0); return FALSE; } else if (notify_code == EN_MAXTEXT) { _r_ctrl_showballoontip (hwnd, ctrl_id, 0, NULL, SZ_MAXTEXT); return FALSE; } switch (ctrl_id) { case IDOK: // process Enter key case IDC_SAVE: { ITEM_ADDRESS address; R_STRINGREF remaining_part; R_STRINGREF first_part; WCHAR rule_string[256]; PR_STRING string; INT item_id; if (!_r_ctrl_isenabled (hwnd, IDC_SAVE)) return FALSE; string = _r_ctrl_getstring (hwnd, IDC_RULE_ID); if (!string) return FALSE; _r_str_trimstring2 (&string->sr, DIVIDER_TRIM DIVIDER_RULE, 0); if (_r_obj_isstringempty2 (string)) { _r_ctrl_showballoontip (hwnd, IDC_RULE_ID, 0, NULL, SZ_EMPTY); _r_ctrl_enable (hwnd, IDC_SAVE, FALSE); _r_obj_dereference (string); return FALSE; } context = _app_editor_getcontext (hwnd); if (!context) return FALSE; _r_obj_initializestringref2 (&remaining_part, &string->sr); item_id = _r_listview_getitemcount (context->hwnd, context->listview_id); while (remaining_part.length != 0) { _r_str_splitatchar (&remaining_part, DIVIDER_RULE[0], &first_part, &remaining_part); if (!_app_parserulestring (&first_part, &address)) { _r_ctrl_showballoontip (hwnd, IDC_RULE_ID, 0, NULL, _r_locale_getstring (IDS_STATUS_SYNTAX_ERROR)); _r_ctrl_enable (hwnd, IDC_SAVE, FALSE); return FALSE; } _r_str_copystring (rule_string, RTL_NUMBER_OF (rule_string), &first_part); _r_listview_additem (context->hwnd, context->listview_id, item_id, rule_string); item_id += 1; } if (context->item_id != -1) _r_listview_deleteitem (context->hwnd, context->listview_id, context->item_id); _r_listview_setcolumn (context->hwnd, context->listview_id, 0, NULL, -100); _r_obj_dereference (string); FALLTHROUGH; } case IDCANCEL: // process Esc key case IDC_CLOSE: { EndDialog (hwnd, FALSE); break; } } break; } } return FALSE; } INT_PTR CALLBACK EditorPagesProc ( _In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM wparam, _In_ LPARAM lparam ) { PEDITOR_CONTEXT context; switch (msg) { case WM_INITDIALOG: { WCHAR buffer[256]; PITEM_RULE ptr_rule; PITEM_APP ptr_app = NULL; PR_STRING string; HWND hctrl; INT i; ULONG_PTR enum_key; BOOLEAN is_enabled; context = (PEDITOR_CONTEXT)lparam; _app_editor_setcontext (hwnd, context); EnableThemeDialogTexture (hwnd, ETDT_ENABLETAB); SetWindowPos ( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED ); // name if (GetDlgItem (hwnd, IDC_RULE_NAME_ID)) { _r_ctrl_setstringformat (hwnd, IDC_RULE_NAME, L"%s:", _r_locale_getstring (IDS_NAME)); if (!_r_obj_isstringempty (context->ptr_rule->name)) _r_ctrl_setstring (hwnd, IDC_RULE_NAME_ID, context->ptr_rule->name->buffer); _r_ctrl_setreadonly (hwnd, IDC_RULE_NAME_ID, !!context->ptr_rule->is_readonly); _r_ctrl_settextlimit (hwnd, IDC_RULE_NAME_ID, RULE_NAME_CCH_MAX - 1); } // comment if (GetDlgItem (hwnd, IDC_RULE_COMMENT_ID)) { _r_ctrl_setstringformat (hwnd, IDC_RULE_COMMENT, L"%s:", _r_locale_getstring (IDS_COMMENT)); if (!_r_obj_isstringempty (context->ptr_rule->comment)) _r_ctrl_setstring (hwnd, IDC_RULE_COMMENT_ID, context->ptr_rule->comment->buffer); _r_ctrl_enable (hwnd, IDC_RULE_COMMENT_ID, !context->ptr_rule->is_readonly); _r_ctrl_settextlimit (hwnd, IDC_RULE_COMMENT_ID, RULE_RULE_CCH_MAX - 1); } // direction if (GetDlgItem (hwnd, IDC_RULE_DIRECTION)) { _r_ctrl_setstringformat (hwnd, IDC_RULE_DIRECTION, L"%s:", _r_locale_getstring (IDS_DIRECTION)); _r_combobox_insertitem (hwnd, IDC_RULE_DIRECTION_ID, 0, _r_locale_getstring (IDS_DIRECTION_1), (LPARAM)FWP_DIRECTION_OUTBOUND); _r_combobox_insertitem (hwnd, IDC_RULE_DIRECTION_ID, 1, _r_locale_getstring (IDS_DIRECTION_2), (LPARAM)FWP_DIRECTION_INBOUND); _r_combobox_insertitem (hwnd, IDC_RULE_DIRECTION_ID, 2, _r_locale_getstring (IDS_ANY), (LPARAM)FWP_DIRECTION_MAX); _r_combobox_setcurrentitembylparam (hwnd, IDC_RULE_DIRECTION_ID, (LPARAM)context->ptr_rule->direction); _r_ctrl_enable (hwnd, IDC_RULE_DIRECTION_ID, !context->ptr_rule->is_readonly); } // action if (GetDlgItem (hwnd, IDC_RULE_ACTION)) { _r_ctrl_setstringformat (hwnd, IDC_RULE_ACTION, L"%s:", _r_locale_getstring (IDS_ACTION)); _r_combobox_insertitem (hwnd, IDC_RULE_ACTION_ID, 0, _r_locale_getstring (IDS_ACTION_BLOCK), (LPARAM)FWP_ACTION_BLOCK); _r_combobox_insertitem (hwnd, IDC_RULE_ACTION_ID, 1, _r_locale_getstring (IDS_ACTION_ALLOW), (LPARAM)FWP_ACTION_PERMIT); _r_combobox_setcurrentitembylparam (hwnd, IDC_RULE_ACTION_ID, (LPARAM)context->ptr_rule->action); _r_ctrl_enable (hwnd, IDC_RULE_ACTION_ID, !context->ptr_rule->is_readonly); } // protocols if (GetDlgItem (hwnd, IDC_RULE_PROTOCOL_ID)) { static UINT8 protos[] = { IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_IPV4, IPPROTO_TCP, IPPROTO_UDP, IPPROTO_RDP, IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_L2TP, IPPROTO_SCTP, }; _r_ctrl_setstringformat (hwnd, IDC_RULE_PROTOCOL, L"%s:", _r_locale_getstring (IDS_PROTOCOL)); _r_combobox_insertitem (hwnd, IDC_RULE_PROTOCOL_ID, 0, _r_locale_getstring (IDS_ANY), 0); for (i = 0; i < RTL_NUMBER_OF (protos); i++) { string = _app_db_getprotoname (protos[i], AF_UNSPEC, TRUE); _r_str_printf (buffer, RTL_NUMBER_OF (buffer), L"%s (%" TEXT (PRIu8) L")", string->buffer, protos[i]); _r_combobox_insertitem (hwnd, IDC_RULE_PROTOCOL_ID, i + 1, buffer, (LPARAM)protos[i]); _r_obj_dereference (string); } // unknown protocol if (_r_combobox_getcurrentitem (hwnd, IDC_RULE_PROTOCOL_ID) == CB_ERR) { string = _app_db_getprotoname (context->ptr_rule->protocol, AF_UNSPEC, TRUE); _r_str_printf (buffer, RTL_NUMBER_OF (buffer), L"%s (%" TEXT (PRIu8) L")", string->buffer, context->ptr_rule->protocol); _r_combobox_insertitem (hwnd, IDC_RULE_PROTOCOL_ID, i + 1, buffer, (LPARAM)context->ptr_rule->protocol); _r_obj_dereference (string); } _r_combobox_setcurrentitembylparam (hwnd, IDC_RULE_PROTOCOL_ID, (LPARAM)context->ptr_rule->protocol); _r_ctrl_enable (hwnd, IDC_RULE_PROTOCOL_ID, !context->ptr_rule->is_readonly); } // family (ports-only) if (GetDlgItem (hwnd, IDC_RULE_VERSION_ID)) { _r_ctrl_setstringformat (hwnd, IDC_RULE_VERSION, L"%s:", _r_locale_getstring (IDS_PORTVERSION)); _r_combobox_insertitem (hwnd, IDC_RULE_VERSION_ID, 0, _r_locale_getstring (IDS_ANY), (LPARAM)AF_UNSPEC); _r_combobox_insertitem (hwnd, IDC_RULE_VERSION_ID, 1, L"IPv4", (LPARAM)AF_INET); _r_combobox_insertitem (hwnd, IDC_RULE_VERSION_ID, 2, L"IPv6", (LPARAM)AF_INET6); _r_combobox_setcurrentitembylparam (hwnd, IDC_RULE_VERSION_ID, (LPARAM)context->ptr_rule->af); _r_ctrl_enable (hwnd, IDC_RULE_VERSION_ID, !context->ptr_rule->is_readonly); } // rule (remote) if (GetDlgItem (hwnd, IDC_RULE_REMOTE_ID)) { _r_ctrl_setstringformat (hwnd, IDC_RULE_REMOTE, L"%s (" SZ_DIRECTION_REMOTE L"):", _r_locale_getstring (IDS_RULE)); _r_listview_setstyle ( hwnd, IDC_RULE_REMOTE_ID, LVS_EX_DOUBLEBUFFER | LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP | LVS_EX_LABELTIP, FALSE ); _r_listview_addcolumn (hwnd, IDC_RULE_REMOTE_ID, 0, NULL, -100, 0); if (!_r_obj_isstringempty (context->ptr_rule->rule_remote)) { _app_editor_setrulestolistview (hwnd, IDC_RULE_REMOTE_ID, context->ptr_rule->rule_remote); _r_listview_setcolumn (hwnd, IDC_RULE_REMOTE_ID, 0, NULL, -100); } _r_ctrl_setstringformat (hwnd, IDC_RULE_REMOTE_ADD, L"%s...", _r_locale_getstring (IDS_ADD)); _r_ctrl_setstringformat (hwnd, IDC_RULE_REMOTE_EDIT, L"%s...", _r_locale_getstring (IDS_EDIT2)); _r_ctrl_setstringformat (hwnd, IDC_RULE_REMOTE_DELETE, L"%s...", _r_locale_getstring (IDS_DELETE)); _r_ctrl_enable (hwnd, IDC_RULE_REMOTE_ADD, !context->ptr_rule->is_readonly); _r_ctrl_enable (hwnd, IDC_RULE_REMOTE_EDIT, FALSE); _r_ctrl_enable (hwnd, IDC_RULE_REMOTE_DELETE, FALSE); } // rule (local) if (GetDlgItem (hwnd, IDC_RULE_LOCAL_ID)) { _r_ctrl_setstringformat (hwnd, IDC_RULE_LOCAL, L"%s (" SZ_DIRECTION_LOCAL L"):", _r_locale_getstring (IDS_RULE)); _r_listview_setstyle ( hwnd, IDC_RULE_LOCAL_ID, LVS_EX_DOUBLEBUFFER | LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP | LVS_EX_LABELTIP, FALSE ); _r_listview_addcolumn (hwnd, IDC_RULE_LOCAL_ID, 0, NULL, -100, 0); if (!_r_obj_isstringempty (context->ptr_rule->rule_local)) { _app_editor_setrulestolistview (hwnd, IDC_RULE_LOCAL_ID, context->ptr_rule->rule_local); _r_listview_setcolumn (hwnd, IDC_RULE_LOCAL_ID, 0, NULL, -100); } _r_ctrl_setstringformat (hwnd, IDC_RULE_LOCAL_ADD, L"%s...", _r_locale_getstring (IDS_ADD)); _r_ctrl_setstringformat (hwnd, IDC_RULE_LOCAL_EDIT, L"%s...", _r_locale_getstring (IDS_EDIT2)); _r_ctrl_setstringformat (hwnd, IDC_RULE_LOCAL_DELETE, L"%s...", _r_locale_getstring (IDS_DELETE)); _r_ctrl_enable (hwnd, IDC_RULE_LOCAL_ADD, !context->ptr_rule->is_readonly); _r_ctrl_enable (hwnd, IDC_RULE_LOCAL_EDIT, FALSE); _r_ctrl_enable (hwnd, IDC_RULE_LOCAL_DELETE, FALSE); } // search hctrl = GetDlgItem (hwnd, IDC_SEARCH); if (hctrl) { _app_search_create (hctrl); SetWindowPos (hctrl, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED); // HACK!!! } // apps if (GetDlgItem (hwnd, IDC_RULE_APPS_ID)) { _app_listview_setview (hwnd, IDC_RULE_APPS_ID); _r_listview_setstyle ( hwnd, IDC_RULE_APPS_ID, LVS_EX_DOUBLEBUFFER | LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP | LVS_EX_LABELTIP | LVS_EX_CHECKBOXES, TRUE ); _r_listview_addcolumn (hwnd, IDC_RULE_APPS_ID, 0, _r_locale_getstring (IDS_NAME), 0, LVCFMT_LEFT); _r_listview_addgroup (hwnd, IDC_RULE_APPS_ID, 0, L"", 0, LVGS_COLLAPSIBLE, LVGS_COLLAPSIBLE); _r_listview_addgroup (hwnd, IDC_RULE_APPS_ID, 1, L"", 0, LVGS_COLLAPSIBLE, LVGS_COLLAPSIBLE); _r_listview_addgroup (hwnd, IDC_RULE_APPS_ID, 2, L"", 0, LVGS_COLLAPSIBLE, LVGS_COLLAPSIBLE); _r_listview_addgroup (hwnd, IDC_RULE_APPS_ID, LV_HIDDEN_GROUP_ID, L"", 3, LVGS_HIDDEN, LVGS_HIDDEN); // apps (apply to) enum_key = 0; _r_queuedlock_acquireshared (&lock_apps); while (_r_obj_enumhashtablepointer (apps_table, &ptr_app, NULL, &enum_key)) { // check for services is_enabled = ((_r_obj_findhashtable (context->ptr_rule->apps, ptr_app->app_hash)) || (context->ptr_rule->is_forservices && _app_issystemhash (ptr_app->app_hash))); _app_listview_lock (hwnd, IDC_RULE_APPS_ID, TRUE); _r_listview_additem_ex (hwnd, IDC_RULE_APPS_ID, 0, LPSTR_TEXTCALLBACK, I_IMAGECALLBACK, I_GROUPIDCALLBACK, _app_listview_createcontext (ptr_app->app_hash)); _r_listview_setitemcheck (hwnd, IDC_RULE_APPS_ID, 0, is_enabled); _app_listview_lock (hwnd, IDC_RULE_APPS_ID, FALSE); } _r_queuedlock_releaseshared (&lock_apps); // resize column _r_listview_setcolumn (hwnd, IDC_RULE_APPS_ID, 0, NULL, -100); // localize groups _app_listview_refreshgroups (hwnd, IDC_RULE_APPS_ID); // sort column _app_listview_sort (hwnd, IDC_RULE_APPS_ID, -1, FALSE); } // app group if (GetDlgItem (hwnd, IDC_APP_NAME)) _r_ctrl_setstringformat (hwnd, IDC_APP_NAME, L"%s:", _r_locale_getstring (IDS_SETTINGS_GENERAL)); // app path if (GetDlgItem (hwnd, IDC_APP_PATH)) _r_ctrl_setstringformat (hwnd, IDC_APP_PATH, L"%s:", _r_locale_getstring (IDS_FILEPATH)); // app comment if (GetDlgItem (hwnd, IDC_APP_COMMENT)) _r_ctrl_setstringformat (hwnd, IDC_APP_COMMENT, L"%s:", _r_locale_getstring (IDS_COMMENT)); // app icon if (GetDlgItem (hwnd, IDC_APP_ICON_ID)) { context->hicon = _app_icons_getsafeapp_hicon (context->ptr_app->app_hash); _r_wnd_sendmessage (hwnd, IDC_APP_ICON_ID, STM_SETICON, (WPARAM)context->hicon, 0); } // app display name if (GetDlgItem (hwnd, IDC_APP_NAME_ID)) { string = _app_getappdisplayname (context->ptr_app, TRUE); if (string) { _r_ctrl_setstring (hwnd, IDC_APP_NAME_ID, string->buffer); _r_obj_dereference (string); } _r_ctrl_settextmargin (hwnd, IDC_APP_NAME_ID, 0, 0); } // app comment if (GetDlgItem (hwnd, IDC_APP_COMMENT_ID)) { _r_ctrl_setstring (hwnd, IDC_APP_COMMENT_ID, _r_obj_getstring (context->ptr_app->comment)); _r_ctrl_settextmargin (hwnd, IDC_APP_COMMENT_ID, 0, 0); } // app signature if (GetDlgItem (hwnd, IDC_APP_SIGNATURE_ID)) { string = NULL; _app_getappinfoparam2 (context->ptr_app->app_hash, 0, INFO_SIGNATURE_STRING, &string, sizeof (string)); _r_ctrl_setstringformat ( hwnd, IDC_APP_SIGNATURE_ID, L"%s: %s", _r_locale_getstring (IDS_SIGNATURE), _r_obj_getstringordefault (string, _r_locale_getstring (IDS_SIGN_UNSIGNED)) ); _r_ctrl_settextmargin (hwnd, IDC_APP_NAME_ID, 0, 0); _r_ctrl_settextmargin (hwnd, IDC_APP_SIGNATURE_ID, 0, 0); if (string) _r_obj_dereference (string); } // app path if (GetDlgItem (hwnd, IDC_APP_PATH_ID)) { if (_app_isappvalidpath (context->ptr_app->real_path)) { _r_ctrl_setstring (hwnd, IDC_APP_PATH_ID, context->ptr_app->real_path->buffer); } else { _r_ctrl_enable (hwnd, IDC_APP_EXPLORE_ID, FALSE); } } // app hash if (GetDlgItem (hwnd, IDC_APP_HASH_ID)) _r_ctrl_setstring (hwnd, IDC_APP_HASH_ID, _r_obj_getstringordefault (context->ptr_app->hash, L"")); // app rules if (GetDlgItem (hwnd, IDC_APP_RULES_ID)) { // configure listview _app_listview_setview (hwnd, IDC_APP_RULES_ID); _r_listview_setstyle ( hwnd, IDC_APP_RULES_ID, LVS_EX_DOUBLEBUFFER | LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP | LVS_EX_LABELTIP | LVS_EX_CHECKBOXES, TRUE ); _r_listview_addcolumn (hwnd, IDC_APP_RULES_ID, 0, _r_locale_getstring (IDS_NAME), 0, LVCFMT_LEFT); _r_listview_addgroup (hwnd, IDC_APP_RULES_ID, 0, _r_locale_getstring (IDS_TRAY_SYSTEM_RULES), 0, LVGS_COLLAPSIBLE, LVGS_COLLAPSIBLE); _r_listview_addgroup (hwnd, IDC_APP_RULES_ID, 1, _r_locale_getstring (IDS_TRAY_USER_RULES), 0, LVGS_COLLAPSIBLE, LVGS_COLLAPSIBLE); _r_listview_addgroup (hwnd, IDC_APP_RULES_ID, LV_HIDDEN_GROUP_ID, L"", 2, LVGS_COLLAPSED, LVGS_COLLAPSED); // initialize _r_queuedlock_acquireshared (&lock_rules); for (ULONG_PTR i = 0; i < _r_obj_getlistsize (rules_list); i++) { ptr_rule = _r_obj_getlistitem (rules_list, i); if (!ptr_rule || ptr_rule->type != DATA_RULE_USER) continue; // check for services is_enabled = ((ptr_rule->is_forservices && _app_issystemhash (context->ptr_app->app_hash)) || _r_obj_findhashtable (ptr_rule->apps, context->ptr_app->app_hash)); _app_listview_lock (hwnd, IDC_APP_RULES_ID, TRUE); _r_listview_additem_ex (hwnd, IDC_APP_RULES_ID, 0, LPSTR_TEXTCALLBACK, I_IMAGECALLBACK, I_GROUPIDCALLBACK, _app_listview_createcontext (i)); _r_listview_setitemcheck (hwnd, IDC_APP_RULES_ID, 0, is_enabled); _app_listview_lock (hwnd, IDC_APP_RULES_ID, FALSE); } _r_queuedlock_releaseshared (&lock_rules); // resize column _r_listview_setcolumn (hwnd, IDC_APP_RULES_ID, 0, NULL, -100); // localize groups _app_listview_refreshgroups (hwnd, IDC_APP_RULES_ID); // sort column _app_listview_sort (hwnd, IDC_APP_RULES_ID, -1, FALSE); } // hints if (GetDlgItem (hwnd, IDC_RULE_HINT)) _r_ctrl_setstring (hwnd, IDC_RULE_HINT, _r_locale_getstring (IDS_RULE_HINT)); if (GetDlgItem (hwnd, IDC_RULE_APPS_HINT)) _r_ctrl_setstring (hwnd, IDC_RULE_APPS_HINT, _r_locale_getstring (IDS_RULE_APPS_HINT)); if (GetDlgItem (hwnd, IDC_APP_HINT)) _r_ctrl_setstring (hwnd, IDC_APP_HINT, _r_locale_getstring (IDS_APP_HINT)); break; } case RM_INITIALIZE: { // apps if (GetDlgItem (hwnd, IDC_RULE_APPS_ID)) _app_editor_settabtitle (hwnd, IDC_RULE_APPS_ID); // rules if (GetDlgItem (hwnd, IDC_APP_RULES_ID)) _app_editor_settabtitle (hwnd, IDC_APP_RULES_ID); break; } case WM_DESTROY: { // apps if (GetDlgItem (hwnd, IDC_RULE_APPS_ID)) _r_listview_deleteallitems (hwnd, IDC_RULE_APPS_ID); // app rules if (GetDlgItem (hwnd, IDC_APP_RULES_ID)) _r_listview_deleteallitems (hwnd, IDC_APP_RULES_ID); context = _app_editor_getcontext (hwnd); if (!context) break; if (context->hicon) DestroyIcon (context->hicon); break; } case WM_SIZE: { static INT listview_ids[] = { IDC_RULE_APPS_ID, IDC_APP_RULES_ID, IDC_RULE_REMOTE_ID, IDC_RULE_LOCAL_ID, }; HWND hlistview; for (ULONG_PTR i = 0; i < RTL_NUMBER_OF (listview_ids); i++) { hlistview = GetDlgItem (hwnd, listview_ids[i]); if (hlistview) _r_listview_setcolumn (hwnd, listview_ids[i], 0, NULL, -100); } break; } case WM_NOTIFY: { LPNMHDR nmlp = (LPNMHDR)lparam; switch (nmlp->code) { case NM_CUSTOMDRAW: { LONG_PTR result; result = _app_message_custdraw (hwnd, (LPNMLVCUSTOMDRAW)lparam); SetWindowLongPtrW (hwnd, DWLP_MSGRESULT, result); return result; } case NM_DBLCLK: { LPNMITEMACTIVATE lpnmlv; INT command_id = 0; INT listview_id; lpnmlv = (LPNMITEMACTIVATE)lparam; if (lpnmlv->iItem == -1) break; listview_id = (INT)(INT_PTR)(lpnmlv->hdr.idFrom); if (listview_id == IDC_RULE_REMOTE_ID) { command_id = IDC_RULE_REMOTE_EDIT; } else if (listview_id == IDC_RULE_LOCAL_ID) { command_id = IDC_RULE_LOCAL_EDIT; } else if (listview_id == IDC_RULE_APPS_ID || listview_id == IDC_APP_RULES_ID) { command_id = IDM_PROPERTIES; } if (command_id) _r_wnd_sendmessage (hwnd, 0, WM_COMMAND, MAKEWPARAM (command_id, 0), 0); break; } case NM_RCLICK: { LPNMITEMACTIVATE lpnmlv; HMENU hsubmenu; PR_STRING localized_string; UINT id_add; UINT id_edit; UINT id_delete; INT listview_id; BOOLEAN is_remote; BOOLEAN is_selected; lpnmlv = (LPNMITEMACTIVATE)lparam; listview_id = (INT)(INT_PTR)lpnmlv->hdr.idFrom; if (listview_id != IDC_RULE_REMOTE_ID && listview_id != IDC_RULE_LOCAL_ID && listview_id != IDC_RULE_APPS_ID && listview_id != IDC_APP_RULES_ID) break; context = _app_editor_getcontext (hwnd); if (!context) break; hsubmenu = CreatePopupMenu (); if (!hsubmenu) break; is_selected = _r_listview_getselectedcount (hwnd, listview_id) != 0; if (listview_id == IDC_RULE_REMOTE_ID || listview_id == IDC_RULE_LOCAL_ID) { localized_string = NULL; is_remote = (listview_id == IDC_RULE_REMOTE_ID); id_add = is_remote ? IDC_RULE_REMOTE_ADD : IDC_RULE_LOCAL_ADD; id_edit = is_remote ? IDC_RULE_REMOTE_EDIT : IDC_RULE_LOCAL_EDIT; id_delete = is_remote ? IDC_RULE_REMOTE_DELETE : IDC_RULE_LOCAL_DELETE; _r_obj_movereference (&localized_string, _r_obj_concatstrings (2, _r_locale_getstring (IDS_ADD), L"...")); _r_menu_additem (hsubmenu, id_add, localized_string->buffer); _r_obj_movereference (&localized_string, _r_obj_concatstrings (2, _r_locale_getstring (IDS_EDIT2), L"...")); _r_menu_additem (hsubmenu, id_edit, localized_string->buffer); _r_menu_additem (hsubmenu, id_delete, _r_locale_getstring (IDS_DELETE)); _r_menu_additem (hsubmenu, 0, NULL); _r_menu_additem (hsubmenu, IDM_COPY, _r_locale_getstring (IDS_COPY)); if (context->ptr_rule->is_readonly) { _r_menu_enableitem (hsubmenu, id_add, MF_BYCOMMAND, FALSE); _r_menu_enableitem (hsubmenu, id_edit, MF_BYCOMMAND, FALSE); _r_menu_enableitem (hsubmenu, id_delete, MF_BYCOMMAND, FALSE); } if (!is_selected) { _r_menu_enableitem (hsubmenu, id_edit, MF_BYCOMMAND, FALSE); _r_menu_enableitem (hsubmenu, id_delete, MF_BYCOMMAND, FALSE); _r_menu_enableitem (hsubmenu, IDM_COPY, MF_BYCOMMAND, FALSE); } _r_obj_dereference (localized_string); } else if (listview_id == IDC_RULE_APPS_ID || listview_id == IDC_APP_RULES_ID) { _r_menu_additem (hsubmenu, IDM_CHECK, _r_locale_getstring (IDS_CHECK)); _r_menu_additem (hsubmenu, IDM_UNCHECK, _r_locale_getstring (IDS_UNCHECK)); _r_menu_additem (hsubmenu, 0, NULL); _r_menu_additem (hsubmenu, IDM_COPY, _r_locale_getstring (IDS_COPY)); if (context->is_settorules && context->ptr_rule->type != DATA_RULE_USER) { _r_menu_enableitem (hsubmenu, IDM_CHECK, MF_BYCOMMAND, FALSE); _r_menu_enableitem (hsubmenu, IDM_UNCHECK, MF_BYCOMMAND, FALSE); } if (!is_selected) { _r_menu_enableitem (hsubmenu, IDM_CHECK, MF_BYCOMMAND, FALSE); _r_menu_enableitem (hsubmenu, IDM_UNCHECK, MF_BYCOMMAND, FALSE); _r_menu_enableitem (hsubmenu, IDM_COPY, MF_BYCOMMAND, FALSE); } } _r_menu_popup (hsubmenu, hwnd, NULL, TRUE); DestroyMenu (hsubmenu); break; } case LVN_DELETEITEM: { PITEM_LISTVIEW_CONTEXT listview_context; LPNMLISTVIEW lpnmlv; INT listview_id; lpnmlv = (LPNMLISTVIEW)lparam; listview_id = (INT)(INT_PTR)lpnmlv->hdr.idFrom; if (!(listview_id == IDC_RULE_APPS_ID || listview_id == IDC_APP_RULES_ID)) break; listview_context = (PITEM_LISTVIEW_CONTEXT)lpnmlv->lParam; if (!listview_context) break; _app_listview_destroycontext (listview_context); break; } case LVN_GETDISPINFO: { LPNMLVDISPINFOW lpnmlv; INT listview_id; lpnmlv = (LPNMLVDISPINFOW)lparam; listview_id = (INT)(INT_PTR)lpnmlv->hdr.idFrom; _app_message_displayinfo (hwnd, listview_id, lpnmlv); break; } case LVN_COLUMNCLICK: { LPNMLISTVIEW lpnmlv; INT listview_id; lpnmlv = (LPNMLISTVIEW)lparam; listview_id = (INT)(INT_PTR)lpnmlv->hdr.idFrom; _app_listview_sort (hwnd, listview_id, lpnmlv->iSubItem, TRUE); break; } case LVN_ITEMCHANGING: { LPNMLISTVIEW lpnmlv; INT listview_id; BOOLEAN is_locked; lpnmlv = (LPNMLISTVIEW)lparam; listview_id = (INT)(INT_PTR)lpnmlv->hdr.idFrom; context = _app_editor_getcontext (hwnd); if (!context) break; if ((lpnmlv->uChanged & LVIF_STATE) != 0) { if (listview_id == IDC_RULE_APPS_ID) { if ((lpnmlv->uNewState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK (1) || ((lpnmlv->uNewState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK (2))) { is_locked = _app_listview_islocked (hwnd, (INT)(INT_PTR)lpnmlv->hdr.idFrom); if (!is_locked && context->ptr_rule->type != DATA_RULE_USER) { SetWindowLongPtrW (hwnd, DWLP_MSGRESULT, TRUE); return TRUE; } } } } break; } case LVN_ITEMCHANGED: { LPNMLISTVIEW lpnmlv; INT listview_id; BOOLEAN is_selected; lpnmlv = (LPNMLISTVIEW)lparam; listview_id = (INT)(INT_PTR)lpnmlv->hdr.idFrom; context = _app_editor_getcontext (hwnd); if (!context) break; if ((lpnmlv->uChanged & LVIF_STATE) != 0) { if (listview_id == IDC_RULE_APPS_ID || listview_id == IDC_APP_RULES_ID) { if ((lpnmlv->uNewState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK (1) || ((lpnmlv->uNewState & LVIS_STATEIMAGEMASK) == INDEXTOSTATEIMAGEMASK (2))) { if (_app_listview_islocked (hwnd, (INT)(INT_PTR)lpnmlv->hdr.idFrom)) break; _app_editor_settabtitle (hwnd, listview_id); _app_listview_refreshgroups (hwnd, listview_id); _app_listview_sort (hwnd, listview_id, -1, FALSE); } } else if (listview_id == IDC_RULE_REMOTE_ID || listview_id == IDC_RULE_LOCAL_ID) { if ((lpnmlv->uOldState & LVIS_SELECTED) != 0 || (lpnmlv->uNewState & LVIS_SELECTED) != 0) { if (!context->ptr_rule->is_readonly) { is_selected = (lpnmlv->uNewState & LVIS_SELECTED) != 0; if (listview_id == IDC_RULE_REMOTE_ID) { _r_ctrl_enable (hwnd, IDC_RULE_REMOTE_EDIT, is_selected); _r_ctrl_enable (hwnd, IDC_RULE_REMOTE_DELETE, is_selected); } else if (listview_id == IDC_RULE_LOCAL_ID) { _r_ctrl_enable (hwnd, IDC_RULE_LOCAL_EDIT, is_selected); _r_ctrl_enable (hwnd, IDC_RULE_LOCAL_DELETE, is_selected); } } } } } break; } case LVN_GETINFOTIP: { LPNMLVGETINFOTIPW lpnmlv; PR_STRING string; ULONG_PTR context; INT listview_id; lpnmlv = (LPNMLVGETINFOTIPW)lparam; listview_id = (INT)lpnmlv->hdr.idFrom; if (listview_id != IDC_RULE_APPS_ID && listview_id != IDC_APP_RULES_ID) break; context = _app_listview_getitemcontext (hwnd, listview_id, lpnmlv->iItem); string = _app_gettooltipbylparam (hwnd, listview_id, context); if (!string) break; _r_str_copy (lpnmlv->pszText, lpnmlv->cchTextMax, string->buffer); _r_obj_dereference (string); break; } } break; } case WM_COMMAND: { INT ctrl_id = LOWORD (wparam); INT notify_code = HIWORD (wparam); if (notify_code == EN_MAXTEXT) { _r_ctrl_showballoontip (hwnd, ctrl_id, 0, NULL, SZ_MAXTEXT); return FALSE; } else if (notify_code == EN_CHANGE) { PR_STRING string; INT listview_id; if (ctrl_id == IDC_RULE_NAME_ID) { _r_ctrl_enable (GetParent (hwnd), IDC_SAVE, _r_ctrl_getstringlength (hwnd, ctrl_id) != 0); // // enable apply button break; } if (ctrl_id != IDC_SEARCH) break; if (GetDlgItem (hwnd, IDC_RULE_APPS_ID)) { listview_id = IDC_RULE_APPS_ID; } else if (GetDlgItem (hwnd, IDC_APP_RULES_ID)) { listview_id = IDC_APP_RULES_ID; } else { return FALSE; } string = _r_ctrl_getstring (hwnd, IDC_SEARCH); _app_search_applyfilter (hwnd, listview_id, string); if (string) _r_obj_dereference (string); return FALSE; } switch (ctrl_id) { case IDC_RULE_REMOTE_ADD: case IDC_RULE_LOCAL_ADD: case IDC_RULE_REMOTE_EDIT: case IDC_RULE_LOCAL_EDIT: { PR_STRING string; ULONG_PTR current_length; INT listview_id; INT item_id; if (!_r_ctrl_isenabled (hwnd, ctrl_id)) break; listview_id = (ctrl_id == IDC_RULE_REMOTE_ADD || ctrl_id == IDC_RULE_REMOTE_EDIT) ? IDC_RULE_REMOTE_ID : IDC_RULE_LOCAL_ID; if (ctrl_id == IDC_RULE_REMOTE_EDIT || ctrl_id == IDC_RULE_LOCAL_EDIT) { // edit rule item_id = _r_listview_getnextselected (hwnd, listview_id, -1); if (item_id == -1) break; } else { // create new rule item_id = -1; } string = _app_editor_getrulesfromlistview (hwnd, listview_id, item_id); if (string) { current_length = _r_str_getlength2 (&string->sr); _r_obj_dereference (string); } else { current_length = 0; } if (ctrl_id == IDC_RULE_REMOTE_ADD || ctrl_id == IDC_RULE_LOCAL_ADD) { if (current_length >= RULE_RULE_CCH_MAX) { _r_show_errormessage (hwnd, NULL, STATUS_IMPLEMENTATION_LIMIT, NULL, ET_NATIVE); return FALSE; } } context = _app_editor_getcontext (hwnd); if (!context) break; context->hwnd = hwnd; context->listview_id = listview_id; context->item_id = item_id; context->current_length = current_length; _r_wnd_createmodalwindow (_r_sys_getimagebase (), MAKEINTRESOURCEW (IDD_EDITOR_ADDRULE), hwnd, &EditorRuleProc, context); break; } case IDC_RULE_REMOTE_DELETE: case IDC_RULE_LOCAL_DELETE: { INT listview_id; INT selected_count; INT item_count; listview_id = ((ctrl_id == IDC_RULE_REMOTE_DELETE) ? IDC_RULE_REMOTE_ID : IDC_RULE_LOCAL_ID); selected_count = _r_listview_getselectedcount (hwnd, listview_id); if (!selected_count) break; if (_r_show_message (hwnd, MB_YESNO | MB_ICONEXCLAMATION, NULL, _r_locale_getstring (IDS_QUESTION_DELETE)) != IDYES) break; item_count = _r_listview_getitemcount (hwnd, listview_id) - 1; for (INT i = item_count; i != -1; i--) { if (_r_listview_isitemselected (hwnd, listview_id, i)) _r_listview_deleteitem (hwnd, listview_id, i); } _r_listview_setcolumn (hwnd, listview_id, 0, NULL, -100); break; } case IDM_CHECK: case IDM_UNCHECK: { INT listview_id; INT item_id = -1; BOOLEAN new_val; if (GetDlgItem (hwnd, IDC_RULE_APPS_ID)) { listview_id = IDC_RULE_APPS_ID; } else if (GetDlgItem (hwnd, IDC_APP_RULES_ID)) { listview_id = IDC_APP_RULES_ID; } else { break; } new_val = (ctrl_id == IDM_CHECK); _app_listview_lock (hwnd, listview_id, TRUE); while ((item_id = _r_listview_getnextselected (hwnd, listview_id, item_id)) != -1) { _r_listview_setitemcheck (hwnd, listview_id, item_id, new_val); } _app_listview_lock (hwnd, listview_id, FALSE); _app_listview_refreshgroups (hwnd, listview_id); _app_listview_sort (hwnd, listview_id, -1, FALSE); break; } case IDC_APP_EXPLORE_ID: { context = _app_editor_getcontext (hwnd); if (!context) break; if (_app_isappvalidpath (context->ptr_app->real_path)) _r_shell_showfile (context->ptr_app->real_path->buffer); break; } case IDC_APP_HASH_RECHECK_ID: { PR_STRING string; HANDLE hfile; NTSTATUS status; context = _app_editor_getcontext (hwnd); if (!context) break; if (!_app_isappvalidpath (context->ptr_app->real_path)) break; status = _r_fs_openfile ( context->ptr_app->real_path->buffer, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE, 0, FALSE, &hfile ); if (NT_SUCCESS (status)) { string = _app_getfilehashinfo (hfile, context->ptr_app->app_hash); _r_ctrl_setstring (hwnd, IDC_APP_HASH_ID, _r_obj_getstringordefault (string, L"")); NtClose (hfile); } break; } case IDM_PROPERTIES: { ULONG_PTR index; INT listview_id; INT item_id; if (GetDlgItem (hwnd, IDC_RULE_APPS_ID)) { listview_id = IDC_RULE_APPS_ID; } else if (GetDlgItem (hwnd, IDC_APP_RULES_ID)) { listview_id = IDC_APP_RULES_ID; } else { break; } item_id = _r_listview_getnextselected (hwnd, listview_id, -1); if (item_id != -1) { index = _app_listview_getitemcontext (hwnd, listview_id, item_id); _app_listview_showitemby_param (_r_app_gethwnd (), index, (listview_id == IDC_RULE_APPS_ID)); } break; } case IDM_COPY: { R_STRINGBUILDER sb; PR_STRING string; HWND hlistview; INT listview_id; INT item_id = -1; hlistview = GetFocus (); if (!hlistview) break; listview_id = GetDlgCtrlID (hlistview); if (!listview_id || !_r_listview_getitemcount (hwnd, listview_id)) break; _r_obj_initializestringbuilder (&sb, 512); while ((item_id = _r_listview_getnextselected (hwnd, listview_id, item_id)) != -1) { string = _r_listview_getitemtext (hwnd, listview_id, item_id, 0); if (string) { _r_obj_appendstringbuilder2 (&sb, &string->sr); _r_obj_appendstringbuilder (&sb, SZ_CRLF); _r_obj_dereference (string); } } string = _r_obj_finalstringbuilder (&sb); _r_str_trimstring2 (&string->sr, DIVIDER_TRIM, 0); _r_clipboard_set (hwnd, &string->sr); _r_obj_deletestringbuilder (&sb); break; } } break; } } return FALSE; } INT_PTR CALLBACK EditorProc ( _In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM wparam, _In_ LPARAM lparam ) { PEDITOR_CONTEXT context; switch (msg) { case WM_INITDIALOG: { WCHAR title[128] = {0}; PR_STRING string; INT tabs_count; context = (PEDITOR_CONTEXT)lparam; _app_editor_setcontext (hwnd, context); // configure tabs tabs_count = 0; if (context->is_settorules) { _r_str_copy (title, RTL_NUMBER_OF (title), _r_obj_getstringordefault (context->ptr_rule->name, SZ_RULE_NEW_TITLE)); if (context->ptr_rule->is_readonly) _r_str_appendformat (title, RTL_NUMBER_OF (title), L" (%s)", SZ_RULE_INTERNAL_TITLE); _app_editor_addtabitem (hwnd, IDS_SETTINGS_GENERAL, IDD_EDITOR_GENERAL, context, &tabs_count); _app_editor_addtabitem (hwnd, IDS_RULE, IDD_EDITOR_RULE, context, &tabs_count); _app_editor_addtabitem (hwnd, IDS_TAB_APPS, IDD_EDITOR_APPS, context, &tabs_count); // set state _r_ctrl_setstring (hwnd, IDC_ENABLE_CHK, _r_locale_getstring (IDS_ENABLE_CHK)); _r_ctrl_checkbutton (hwnd, IDC_ENABLE_CHK, !!(context->ptr_rule->is_enabled)); } else { string = _app_getappdisplayname (context->ptr_app, TRUE); if (string) { _r_str_copy (title, RTL_NUMBER_OF (title), string->buffer); _r_obj_dereference (string); } _app_editor_addtabitem (hwnd, IDS_SETTINGS_GENERAL, IDD_EDITOR_APPINFO, context, &tabs_count); _app_editor_addtabitem (hwnd, IDS_TRAY_RULES, IDD_EDITOR_APPRULES, context, &tabs_count); // show state _r_ctrl_setstring (hwnd, IDC_ENABLE_CHK, _r_locale_getstring (IDS_ENABLE_APP_CHK)); _r_ctrl_checkbutton (hwnd, IDC_ENABLE_CHK, !!(context->ptr_app->is_enabled)); } // initialize layout _r_layout_initializemanager (&context->layout_manager, hwnd); _r_wnd_top (hwnd, TRUE); _r_wnd_center (hwnd, GetParent (hwnd)); _r_window_restoreposition (hwnd, L"editor"); // set window title _r_ctrl_setstring (hwnd, 0, title); _r_ctrl_setstring (hwnd, IDC_SAVE, _r_locale_getstring (IDS_SAVE)); _r_ctrl_setstring (hwnd, IDC_CLOSE, _r_locale_getstring (IDS_CLOSE)); _r_tab_selectitem (hwnd, IDC_TAB, _r_calc_clamp (context->page_id, 0, _r_tab_getitemcount (hwnd, IDC_TAB))); _r_theme_initialize (hwnd, _r_theme_isenabled ()); break; } case WM_DESTROY: { _r_window_saveposition (hwnd, L"editor"); context = _app_editor_getcontext (hwnd); if (context) _r_layout_destroymanager (&context->layout_manager); break; } case WM_CLOSE: { EndDialog (hwnd, FALSE); break; } case WM_PAINT: { PAINTSTRUCT ps; HDC hdc; hdc = BeginPaint (hwnd, &ps); if (!hdc) break; _r_dc_drawwindow (hdc, hwnd, FALSE); EndPaint (hwnd, &ps); break; } case WM_DPICHANGED: { _r_wnd_message_dpichanged (hwnd, wparam, lparam); break; } case WM_SETTINGCHANGE: { _r_wnd_message_settingchange (hwnd, wparam, lparam); break; } case WM_SIZE: { HWND hpage; INT item_id; context = _app_editor_getcontext (hwnd); if (!context) break; _r_layout_resize (&context->layout_manager, wparam); item_id = _r_tab_getcurrentitem (hwnd, IDC_TAB); hpage = (HWND)_r_tab_getitemlparam (hwnd, IDC_TAB, item_id); if (hpage) _r_tab_adjustchild (hwnd, IDC_TAB, hpage); break; } case WM_GETMINMAXINFO: { context = _app_editor_getcontext (hwnd); if (!context) break; _r_layout_resizeminimumsize (&context->layout_manager, lparam); break; } case WM_NOTIFY: { LPNMHDR nmlp = (LPNMHDR)lparam; switch (nmlp->code) { case TCN_SELCHANGING: { HWND hpage; INT item_id; item_id = _r_tab_getcurrentitem (hwnd, IDC_TAB); hpage = (HWND)_r_tab_getitemlparam (hwnd, IDC_TAB, item_id); if (hpage) ShowWindow (hpage, SW_HIDE); break; } case TCN_SELCHANGE: { HWND hpage; INT item_id; item_id = _r_tab_getcurrentitem (hwnd, IDC_TAB); hpage = (HWND)_r_tab_getitemlparam (hwnd, IDC_TAB, item_id); if (!hpage) break; _r_tab_adjustchild (hwnd, IDC_TAB, hpage); ShowWindow (hpage, SW_SHOWNA); SetFocus (NULL); break; } } break; } case WM_COMMAND: { INT ctrl_id = LOWORD (wparam); switch (ctrl_id) { case IDOK: // process Enter key case IDC_SAVE: { HWND hpage_general; HWND hpage_rule; HWND hpage_apps; PR_STRING string; PR_LIST rules = NULL; HANDLE hengine; ULONG_PTR app_hash; PITEM_RULE ptr_rule; ULONG_PTR rule_idx; INT listview_id; INT item_id; BOOLEAN is_enable; context = _app_editor_getcontext (hwnd); if (!context) break; hpage_general = (HWND)_r_tab_getitemlparam (hwnd, IDC_TAB, 0); hpage_rule = (HWND)_r_tab_getitemlparam (hwnd, IDC_TAB, 1); if (context->is_settorules) { hpage_apps = (HWND)_r_tab_getitemlparam (hwnd, IDC_TAB, 2); if (!hpage_general || !_r_ctrl_getstringlength (hpage_general, IDC_RULE_NAME_ID)) return FALSE; context->ptr_rule->is_haveerrors = FALSE; // reset errors // do not change read-only rules if (!context->ptr_rule->is_readonly) { // name string = _r_ctrl_getstring (hpage_general, IDC_RULE_NAME_ID); if (!string) return FALSE; _r_str_trimstring2 (&string->sr, DIVIDER_TRIM DIVIDER_RULE, 0); if (_r_obj_isstringempty2 (string)) { _r_ctrl_showballoontip (hpage_general, IDC_RULE_NAME_ID, 0, NULL, SZ_EMPTY); _r_obj_dereference (string); return FALSE; } _r_obj_movereference (&context->ptr_rule->name, string); // comment string = _r_ctrl_getstring (hpage_general, IDC_RULE_COMMENT_ID); if (string) _r_str_trimstring2 (&string->sr, DIVIDER_TRIM DIVIDER_RULE, 0); _r_obj_movereference (&context->ptr_rule->comment, string); if (hpage_rule) { // rule (remote) string = _app_editor_getrulesfromlistview (hpage_rule, IDC_RULE_REMOTE_ID, -1); _r_obj_movereference (&context->ptr_rule->rule_remote, string); // rule (local) string = _app_editor_getrulesfromlistview (hpage_rule, IDC_RULE_LOCAL_ID, -1); _r_obj_movereference (&context->ptr_rule->rule_local, string); } context->ptr_rule->protocol = (UINT8)_r_combobox_getitemlparam ( hpage_general, IDC_RULE_PROTOCOL_ID, _r_combobox_getcurrentitem (hpage_general, IDC_RULE_PROTOCOL_ID) ); context->ptr_rule->af = (ADDRESS_FAMILY)_r_combobox_getitemlparam ( hpage_general, IDC_RULE_VERSION_ID, _r_combobox_getcurrentitem (hpage_general, IDC_RULE_VERSION_ID) ); string = _app_db_getprotoname (context->ptr_rule->protocol, context->ptr_rule->af, FALSE); _r_obj_movereference (&context->ptr_rule->protocol_str, string); context->ptr_rule->direction = (FWP_DIRECTION)_r_combobox_getitemlparam ( hpage_general, IDC_RULE_DIRECTION_ID, _r_combobox_getcurrentitem (hpage_general, IDC_RULE_DIRECTION_ID) ); context->ptr_rule->action = (FWP_ACTION_TYPE)_r_combobox_getitemlparam ( hpage_general, IDC_RULE_ACTION_ID, _r_combobox_getcurrentitem (hpage_general, IDC_RULE_ACTION_ID) ); if (context->ptr_rule->type == DATA_RULE_USER) { if (context->ptr_rule->action == FWP_ACTION_BLOCK) { context->ptr_rule->weight = FW_WEIGHT_RULE_USER_BLOCK; } else { context->ptr_rule->weight = FW_WEIGHT_RULE_USER; } } } // save rule apps if (context->ptr_rule->type == DATA_RULE_USER) { _r_obj_clearhashtable (context->ptr_rule->apps); for (INT i = 0; i < _r_listview_getitemcount (hpage_apps, IDC_RULE_APPS_ID); i++) { if (!_r_listview_isitemchecked (hpage_apps, IDC_RULE_APPS_ID, i)) continue; app_hash = _app_listview_getitemcontext (hpage_apps, IDC_RULE_APPS_ID, i); if (context->ptr_rule->is_forservices && _app_issystemhash (app_hash)) continue; if (_app_isappfound (app_hash)) _r_obj_addhashtableitem (context->ptr_rule->apps, app_hash, NULL); } } // enable rule _app_ruleenable (context->ptr_rule, _r_ctrl_isbuttonchecked (hwnd, IDC_ENABLE_CHK), TRUE); rules = _r_obj_createlist (NULL); _r_obj_addlistitem (rules, context->ptr_rule); } else { context->ptr_app->is_haveerrors = FALSE; // reset errors context->ptr_app->is_enabled = _r_ctrl_isbuttonchecked (hwnd, IDC_ENABLE_CHK); rules = _r_obj_createlist (NULL); _r_obj_addlistitem (rules, context->ptr_app); // comment string = _r_ctrl_getstring (hpage_general, IDC_APP_COMMENT_ID); if (string) _r_str_trimstring2 (&string->sr, DIVIDER_TRIM DIVIDER_RULE, 0); _r_obj_movereference (&context->ptr_app->comment, string); if (hpage_rule) { _r_queuedlock_acquireshared (&lock_rules); for (INT i = 0; i < _r_listview_getitemcount (hpage_rule, IDC_APP_RULES_ID); i++) { rule_idx = _app_listview_getitemcontext (hpage_rule, IDC_APP_RULES_ID, i); ptr_rule = _r_obj_getlistitem (rules_list, rule_idx); if (!ptr_rule) continue; listview_id = _app_listview_getbytype (ptr_rule->type); item_id = _app_listview_finditem (_r_app_gethwnd (), listview_id, rule_idx); if (item_id != -1) { is_enable = _r_listview_isitemchecked (hpage_rule, IDC_APP_RULES_ID, i); _app_setruletoapp (_r_app_gethwnd (), ptr_rule, item_id, context->ptr_app, is_enable); } } _r_queuedlock_releaseshared (&lock_rules); } } // apply filter if (rules) { if (!_r_obj_isempty2 (rules) && _wfp_isfiltersinstalled ()) { hengine = _wfp_getenginehandle (); if (context->is_settorules) { _wfp_create4filters (hengine, rules, DBG_ARG, FALSE); } else { _wfp_create3filters (hengine, rules, DBG_ARG, FALSE); } } _r_obj_dereference (rules); } EndDialog (hwnd, TRUE); break; } case IDCANCEL: // process Esc key { HWND hpage; HWND hsearch; INT item_id; item_id = _r_tab_getcurrentitem (hwnd, IDC_TAB); hpage = (HWND)_r_tab_getitemlparam (hwnd, IDC_TAB, item_id); if (hpage) { hsearch = GetDlgItem (hpage, IDC_SEARCH); if (hsearch) { if (GetFocus () == hsearch) { _r_ctrl_setstring (hsearch, 0, L""); SetFocus (hwnd); break; } } } FALLTHROUGH; } case IDC_CLOSE: { EndDialog (hwnd, FALSE); break; } } break; } } return FALSE; }