2025-05-13 19:45:22 +03:00

1111 lines
31 KiB
C

/*
* Process Hacker Extended Notifications -
* main program
*
* Copyright (C) 2010-2011 wj32
*
* This file is part of Process Hacker.
*
* Process Hacker is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Process Hacker is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
*/
#include <phdk.h>
#include <workqueue.h>
#include <windowsx.h>
#include "extnoti.h"
#include "resource.h"
#include "gntp-send/growl.h"
VOID NTAPI LoadCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
);
VOID NTAPI ShowOptionsCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
);
VOID NTAPI NotifyEventCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
);
VOID RegisterGrowl(
_In_ BOOLEAN Force
);
VOID NotifyGrowl(
_In_ PPH_PLUGIN_NOTIFY_EVENT NotifyEvent
);
NTSTATUS NTAPI RegisterGrowlCallback(
_In_ PVOID Parameter
);
INT_PTR CALLBACK ProcessesDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
INT_PTR CALLBACK ServicesDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
INT_PTR CALLBACK LoggingDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
INT_PTR CALLBACK GrowlDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
PPH_PLUGIN PluginInstance;
PH_CALLBACK_REGISTRATION PluginLoadCallbackRegistration;
PH_CALLBACK_REGISTRATION PluginShowOptionsCallbackRegistration;
PH_CALLBACK_REGISTRATION NotifyEventCallbackRegistration;
PPH_LIST ProcessFilterList;
PPH_LIST ServiceFilterList;
PSTR GrowlNotifications[] =
{
"Process Created",
"Process Terminated",
"Service Created",
"Service Deleted",
"Service Started",
"Service Stopped"
};
LOGICAL DllMain(
_In_ HINSTANCE Instance,
_In_ ULONG Reason,
_Reserved_ PVOID Reserved
)
{
switch (Reason)
{
case DLL_PROCESS_ATTACH:
{
PPH_PLUGIN_INFORMATION info;
PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info);
if (!PluginInstance)
return FALSE;
info->DisplayName = L"Extended Notifications";
info->Author = L"wj32";
info->Description = L"Filters notifications.";
info->Url = L"https://wj32.org/processhacker/forums/viewtopic.php?t=1112";
info->HasOptions = TRUE;
PhRegisterCallback(
PhGetPluginCallback(PluginInstance, PluginCallbackLoad),
LoadCallback,
NULL,
&PluginLoadCallbackRegistration
);
PhRegisterCallback(
PhGetPluginCallback(PluginInstance, PluginCallbackShowOptions),
ShowOptionsCallback,
NULL,
&PluginShowOptionsCallbackRegistration
);
PhRegisterCallback(
PhGetGeneralCallback(GeneralCallbackNotifyEvent),
NotifyEventCallback,
NULL,
&NotifyEventCallbackRegistration
);
{
static PH_SETTING_CREATE settings[] =
{
{ IntegerSettingType, SETTING_NAME_ENABLE_GROWL, L"0" },
{ StringSettingType, SETTING_NAME_LOG_FILENAME, L"" },
{ StringSettingType, SETTING_NAME_PROCESS_LIST, L"\\i*" },
{ StringSettingType, SETTING_NAME_SERVICE_LIST, L"\\i*" }
};
PhAddSettings(settings, sizeof(settings) / sizeof(PH_SETTING_CREATE));
}
ProcessFilterList = PhCreateList(10);
ServiceFilterList = PhCreateList(10);
}
break;
}
return TRUE;
}
VOID FreeFilterEntry(
_In_ PFILTER_ENTRY Entry
)
{
PhDereferenceObject(Entry->Filter);
PhFree(Entry);
}
VOID ClearFilterList(
_Inout_ PPH_LIST FilterList
)
{
ULONG i;
for (i = 0; i < FilterList->Count; i++)
FreeFilterEntry(FilterList->Items[i]);
PhClearList(FilterList);
}
VOID CopyFilterList(
_Inout_ PPH_LIST Destination,
_In_ PPH_LIST Source
)
{
ULONG i;
for (i = 0; i < Source->Count; i++)
{
PFILTER_ENTRY entry = Source->Items[i];
PFILTER_ENTRY newEntry;
newEntry = PhAllocate(sizeof(FILTER_ENTRY));
newEntry->Type = entry->Type;
newEntry->Filter = entry->Filter;
PhReferenceObject(newEntry->Filter);
PhAddItemList(Destination, newEntry);
}
}
VOID LoadFilterList(
_Inout_ PPH_LIST FilterList,
_In_ PPH_STRING String
)
{
PH_STRING_BUILDER stringBuilder;
SIZE_T length;
SIZE_T i;
PFILTER_ENTRY entry;
length = String->Length / 2;
PhInitializeStringBuilder(&stringBuilder, 20);
entry = NULL;
for (i = 0; i < length; i++)
{
if (String->Buffer[i] == '\\')
{
if (i != length - 1)
{
i++;
switch (String->Buffer[i])
{
case 'i':
case 'e':
if (entry)
{
entry->Filter = PhFinalStringBuilderString(&stringBuilder);
PhAddItemList(FilterList, entry);
PhInitializeStringBuilder(&stringBuilder, 20);
}
entry = PhAllocate(sizeof(FILTER_ENTRY));
entry->Type = String->Buffer[i] == 'i' ? FilterInclude : FilterExclude;
break;
default:
PhAppendCharStringBuilder(&stringBuilder, String->Buffer[i]);
break;
}
}
else
{
// Trailing backslash. Just ignore it.
break;
}
}
else
{
PhAppendCharStringBuilder(&stringBuilder, String->Buffer[i]);
}
}
if (entry)
{
entry->Filter = PhFinalStringBuilderString(&stringBuilder);
PhAddItemList(FilterList, entry);
}
else
{
PhDeleteStringBuilder(&stringBuilder);
}
}
PPH_STRING SaveFilterList(
_Inout_ PPH_LIST FilterList
)
{
PH_STRING_BUILDER stringBuilder;
SIZE_T i;
SIZE_T j;
WCHAR temp[2];
PhInitializeStringBuilder(&stringBuilder, 100);
temp[0] = '\\';
for (i = 0; i < FilterList->Count; i++)
{
PFILTER_ENTRY entry = FilterList->Items[i];
SIZE_T length;
// Write the entry type.
temp[1] = entry->Type == FilterInclude ? 'i' : 'e';
PhAppendStringBuilderEx(&stringBuilder, temp, 4);
// Write the filter string.
length = entry->Filter->Length / 2;
for (j = 0; j < length; j++)
{
if (entry->Filter->Buffer[j] == '\\') // escape backslashes
{
temp[1] = entry->Filter->Buffer[j];
PhAppendStringBuilderEx(&stringBuilder, temp, 4);
}
else
{
PhAppendCharStringBuilder(&stringBuilder, entry->Filter->Buffer[j]);
}
}
}
return PhFinalStringBuilderString(&stringBuilder);
}
VOID NTAPI LoadCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
LoadFilterList(ProcessFilterList, PhaGetStringSetting(SETTING_NAME_PROCESS_LIST));
LoadFilterList(ServiceFilterList, PhaGetStringSetting(SETTING_NAME_SERVICE_LIST));
FileLogInitialization();
if (PhGetIntegerSetting(SETTING_NAME_ENABLE_GROWL))
{
PhQueueItemWorkQueue(PhGetGlobalWorkQueue(), RegisterGrowlCallback, NULL);
}
}
VOID NTAPI ShowOptionsCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
PROPSHEETHEADER propSheetHeader = { sizeof(propSheetHeader) };
PROPSHEETPAGE propSheetPage;
HPROPSHEETPAGE pages[4];
propSheetHeader.dwFlags =
PSH_NOAPPLYNOW |
PSH_NOCONTEXTHELP |
PSH_PROPTITLE;
propSheetHeader.hwndParent = (HWND)Parameter;
propSheetHeader.pszCaption = L"Extended Notifications";
propSheetHeader.nPages = 0;
propSheetHeader.nStartPage = 0;
propSheetHeader.phpage = pages;
// Processes
memset(&propSheetPage, 0, sizeof(PROPSHEETPAGE));
propSheetPage.dwSize = sizeof(PROPSHEETPAGE);
propSheetPage.hInstance = PluginInstance->DllBase;
propSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_PROCESSES);
propSheetPage.pfnDlgProc = ProcessesDlgProc;
pages[propSheetHeader.nPages++] = CreatePropertySheetPage(&propSheetPage);
// Services
memset(&propSheetPage, 0, sizeof(PROPSHEETPAGE));
propSheetPage.dwSize = sizeof(PROPSHEETPAGE);
propSheetPage.hInstance = PluginInstance->DllBase;
propSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_SERVICES);
propSheetPage.pfnDlgProc = ServicesDlgProc;
pages[propSheetHeader.nPages++] = CreatePropertySheetPage(&propSheetPage);
// Logging
memset(&propSheetPage, 0, sizeof(PROPSHEETPAGE));
propSheetPage.dwSize = sizeof(PROPSHEETPAGE);
propSheetPage.hInstance = PluginInstance->DllBase;
propSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_LOGGING);
propSheetPage.pfnDlgProc = LoggingDlgProc;
pages[propSheetHeader.nPages++] = CreatePropertySheetPage(&propSheetPage);
// Growl
memset(&propSheetPage, 0, sizeof(PROPSHEETPAGE));
propSheetPage.dwSize = sizeof(PROPSHEETPAGE);
propSheetPage.hInstance = PluginInstance->DllBase;
propSheetPage.pszTemplate = MAKEINTRESOURCE(IDD_GROWL);
propSheetPage.pfnDlgProc = GrowlDlgProc;
pages[propSheetHeader.nPages++] = CreatePropertySheetPage(&propSheetPage);
PhModalPropertySheet(&propSheetHeader);
}
BOOLEAN MatchFilterList(
_In_ PPH_LIST FilterList,
_In_ PPH_STRING String,
_Out_ FILTER_TYPE *FilterType
)
{
ULONG i;
BOOLEAN isFileName;
isFileName = PhFindCharInString(String, 0, '\\') != -1;
for (i = 0; i < FilterList->Count; i++)
{
PFILTER_ENTRY entry = FilterList->Items[i];
if (isFileName && PhFindCharInString(entry->Filter, 0, '\\') == -1)
continue; // ignore filters without backslashes if we're matching a file name
if (entry->Filter->Length == 2 && entry->Filter->Buffer[0] == '*') // shortcut
{
*FilterType = entry->Type;
return TRUE;
}
if (PhMatchWildcards(entry->Filter->Buffer, String->Buffer, TRUE))
{
*FilterType = entry->Type;
return TRUE;
}
}
return FALSE;
}
VOID NTAPI NotifyEventCallback(
_In_opt_ PVOID Parameter,
_In_opt_ PVOID Context
)
{
PPH_PLUGIN_NOTIFY_EVENT notifyEvent = Parameter;
PPH_PROCESS_ITEM processItem;
PPH_SERVICE_ITEM serviceItem;
FILTER_TYPE filterType;
BOOLEAN found = FALSE;
filterType = FilterExclude;
switch (notifyEvent->Type)
{
case PH_NOTIFY_PROCESS_CREATE:
case PH_NOTIFY_PROCESS_DELETE:
processItem = notifyEvent->Parameter;
if (processItem->FileName)
found = MatchFilterList(ProcessFilterList, processItem->FileName, &filterType);
if (!found)
MatchFilterList(ProcessFilterList, processItem->ProcessName, &filterType);
break;
case PH_NOTIFY_SERVICE_CREATE:
case PH_NOTIFY_SERVICE_DELETE:
case PH_NOTIFY_SERVICE_START:
case PH_NOTIFY_SERVICE_STOP:
serviceItem = notifyEvent->Parameter;
MatchFilterList(ServiceFilterList, serviceItem->Name, &filterType);
break;
}
if (filterType == FilterExclude)
notifyEvent->Handled = TRUE; // pretend we handled the notification to prevent it from displaying
if (PhGetIntegerSetting(SETTING_NAME_ENABLE_GROWL))
NotifyGrowl(notifyEvent);
}
VOID RegisterGrowl(
_In_ BOOLEAN Force
)
{
static BOOLEAN registered = FALSE;
if (!Force && registered)
return;
growl_tcp_register("127.0.0.1", "Process Hacker", GrowlNotifications, sizeof(GrowlNotifications) / sizeof(PSTR), NULL, NULL);
registered = TRUE;
}
VOID NotifyGrowl(
_In_ PPH_PLUGIN_NOTIFY_EVENT NotifyEvent
)
{
PSTR notification;
PPH_STRING title;
PPH_BYTES titleUtf8;
PPH_STRING message;
PPH_BYTES messageUtf8;
PPH_PROCESS_ITEM processItem;
PPH_SERVICE_ITEM serviceItem;
PPH_PROCESS_ITEM parentProcessItem;
if (NotifyEvent->Handled)
return;
switch (NotifyEvent->Type)
{
case PH_NOTIFY_PROCESS_CREATE:
processItem = NotifyEvent->Parameter;
notification = GrowlNotifications[0];
title = processItem->ProcessName;
parentProcessItem = PhReferenceProcessItemForParent(
processItem->ParentProcessId,
processItem->ProcessId,
&processItem->CreateTime
);
message = PhaFormatString(
L"The process %s (%lu) was started by %s.",
processItem->ProcessName->Buffer,
HandleToUlong(processItem->ProcessId),
parentProcessItem ? parentProcessItem->ProcessName->Buffer : L"an unknown process"
);
if (parentProcessItem)
PhDereferenceObject(parentProcessItem);
break;
case PH_NOTIFY_PROCESS_DELETE:
processItem = NotifyEvent->Parameter;
notification = GrowlNotifications[1];
title = processItem->ProcessName;
message = PhaFormatString(L"The process %s (%lu) was terminated.",
processItem->ProcessName->Buffer,
HandleToUlong(processItem->ProcessId)
);
break;
case PH_NOTIFY_SERVICE_CREATE:
serviceItem = NotifyEvent->Parameter;
notification = GrowlNotifications[2];
title = serviceItem->DisplayName;
message = PhaFormatString(L"The service %s (%s) has been created.",
serviceItem->Name->Buffer,
serviceItem->DisplayName->Buffer
);
break;
case PH_NOTIFY_SERVICE_DELETE:
serviceItem = NotifyEvent->Parameter;
notification = GrowlNotifications[3];
title = serviceItem->DisplayName;
message = PhaFormatString(L"The service %s (%s) has been deleted.",
serviceItem->Name->Buffer,
serviceItem->DisplayName->Buffer
);
break;
case PH_NOTIFY_SERVICE_START:
serviceItem = NotifyEvent->Parameter;
notification = GrowlNotifications[4];
title = serviceItem->DisplayName;
message = PhaFormatString(L"The service %s (%s) has been started.",
serviceItem->Name->Buffer,
serviceItem->DisplayName->Buffer
);
break;
case PH_NOTIFY_SERVICE_STOP:
serviceItem = NotifyEvent->Parameter;
notification = GrowlNotifications[5];
title = serviceItem->DisplayName;
message = PhaFormatString(L"The service %s (%s) has been stopped.",
serviceItem->Name->Buffer,
serviceItem->DisplayName->Buffer
);
break;
default:
return;
}
titleUtf8 = PH_AUTO(PhConvertUtf16ToUtf8Ex(title->Buffer, title->Length));
messageUtf8 = PH_AUTO(PhConvertUtf16ToUtf8Ex(message->Buffer, message->Length));
RegisterGrowl(TRUE);
if (growl_tcp_notify("127.0.0.1", "Process Hacker", notification, titleUtf8->Buffer, messageUtf8->Buffer, NULL, NULL, NULL) == 0)
NotifyEvent->Handled = TRUE;
}
NTSTATUS NTAPI RegisterGrowlCallback(
_In_ PVOID Parameter
)
{
RegisterGrowl(FALSE);
return STATUS_SUCCESS;
}
PPH_STRING FormatFilterEntry(
_In_ PFILTER_ENTRY Entry
)
{
return PhConcatStrings2(Entry->Type == FilterInclude ? L"[Include] " : L"[Exclude] ", Entry->Filter->Buffer);
}
VOID AddEntriesToListBox(
_In_ HWND ListBox,
_In_ PPH_LIST FilterList
)
{
ULONG i;
for (i = 0; i < FilterList->Count; i++)
{
PFILTER_ENTRY entry = FilterList->Items[i];
ListBox_AddString(ListBox, PH_AUTO_T(PH_STRING, FormatFilterEntry(entry))->Buffer);
}
}
PPH_LIST EditingProcessFilterList;
PPH_LIST EditingServiceFilterList;
LRESULT CALLBACK TextBoxSubclassProc(
_In_ HWND hWnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam,
_In_ UINT_PTR uIdSubclass,
_In_ ULONG_PTR dwRefData
)
{
switch (uMsg)
{
case WM_NCDESTROY:
RemoveWindowSubclass(hWnd, TextBoxSubclassProc, uIdSubclass);
break;
case WM_GETDLGCODE:
{
if (wParam == VK_RETURN)
return DLGC_WANTALLKEYS;
}
break;
case WM_CHAR:
{
if (wParam == VK_RETURN)
{
SendMessage(GetParent(hWnd), WM_COMMAND, IDC_TEXT_RETURN, 0);
return 0;
}
}
break;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
VOID FixControlStates(
_In_ HWND hwndDlg,
_In_ HWND ListBox
)
{
ULONG i;
ULONG count;
i = ListBox_GetCurSel(ListBox);
count = ListBox_GetCount(ListBox);
EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), i != LB_ERR);
EnableWindow(GetDlgItem(hwndDlg, IDC_MOVEUP), i != LB_ERR && i != 0);
EnableWindow(GetDlgItem(hwndDlg, IDC_MOVEDOWN), i != LB_ERR && i != count - 1);
}
INT_PTR HandleCommonMessages(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam,
_In_ HWND ListBox,
_In_ PPH_LIST FilterList
)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
SetWindowSubclass(GetDlgItem(hwndDlg, IDC_TEXT), TextBoxSubclassProc, 0, 0);
Button_SetCheck(GetDlgItem(hwndDlg, IDC_INCLUDE), BST_CHECKED);
FixControlStates(hwndDlg, ListBox);
}
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_LIST:
{
if (HIWORD(wParam) == LBN_SELCHANGE)
{
ULONG i;
i = ListBox_GetCurSel(ListBox);
if (i != LB_ERR)
{
PFILTER_ENTRY entry;
entry = FilterList->Items[i];
SetDlgItemText(hwndDlg, IDC_TEXT, entry->Filter->Buffer);
Button_SetCheck(GetDlgItem(hwndDlg, IDC_INCLUDE),
entry->Type == FilterInclude ? BST_CHECKED : BST_UNCHECKED);
Button_SetCheck(GetDlgItem(hwndDlg, IDC_EXCLUDE),
entry->Type == FilterExclude ? BST_CHECKED : BST_UNCHECKED);
}
FixControlStates(hwndDlg, ListBox);
}
}
break;
case IDC_ADD:
case IDC_TEXT_RETURN:
{
ULONG i;
PPH_STRING string;
PFILTER_ENTRY entry = NULL;
FILTER_TYPE type;
PPH_STRING entryString;
string = PhGetWindowText(GetDlgItem(hwndDlg, IDC_TEXT));
if (string->Length == 0)
{
PhDereferenceObject(string);
return FALSE;
}
for (i = 0; i < FilterList->Count; i++)
{
entry = FilterList->Items[i];
if (PhEqualString(entry->Filter, string, TRUE))
break;
}
type = Button_GetCheck(GetDlgItem(hwndDlg, IDC_INCLUDE)) == BST_CHECKED ? FilterInclude : FilterExclude;
if (i == FilterList->Count)
{
// No existing entry, so add a new one.
entry = PhAllocate(sizeof(FILTER_ENTRY));
entry->Type = type;
entry->Filter = string;
PhInsertItemList(FilterList, 0, entry);
entryString = FormatFilterEntry(entry);
ListBox_InsertString(ListBox, 0, entryString->Buffer);
PhDereferenceObject(entryString);
ListBox_SetCurSel(ListBox, 0);
}
else
{
entry->Type = type;
PhDereferenceObject(entry->Filter);
entry->Filter = string;
ListBox_DeleteString(ListBox, i);
entryString = FormatFilterEntry(entry);
ListBox_InsertString(ListBox, i, entryString->Buffer);
PhDereferenceObject(entryString);
ListBox_SetCurSel(ListBox, i);
}
SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_TEXT), TRUE);
Edit_SetSel(GetDlgItem(hwndDlg, IDC_TEXT), 0, -1);
FixControlStates(hwndDlg, ListBox);
}
break;
case IDC_REMOVE:
{
ULONG i;
PFILTER_ENTRY entry;
i = ListBox_GetCurSel(ListBox);
if (i != LB_ERR)
{
entry = FilterList->Items[i];
FreeFilterEntry(entry);
PhRemoveItemList(FilterList, i);
ListBox_DeleteString(ListBox, i);
if (i >= FilterList->Count)
i = FilterList->Count - 1;
ListBox_SetCurSel(ListBox, i);
FixControlStates(hwndDlg, ListBox);
}
}
break;
case IDC_MOVEUP:
{
ULONG i;
PFILTER_ENTRY entry;
PPH_STRING entryString;
i = ListBox_GetCurSel(ListBox);
if (i != LB_ERR && i != 0)
{
entry = FilterList->Items[i];
PhRemoveItemList(FilterList, i);
PhInsertItemList(FilterList, i - 1, entry);
ListBox_DeleteString(ListBox, i);
entryString = FormatFilterEntry(entry);
ListBox_InsertString(ListBox, i - 1, entryString->Buffer);
PhDereferenceObject(entryString);
i--;
ListBox_SetCurSel(ListBox, i);
FixControlStates(hwndDlg, ListBox);
}
}
break;
case IDC_MOVEDOWN:
{
ULONG i;
PFILTER_ENTRY entry;
PPH_STRING entryString;
i = ListBox_GetCurSel(ListBox);
if (i != LB_ERR && i != FilterList->Count - 1)
{
entry = FilterList->Items[i];
PhRemoveItemList(FilterList, i);
PhInsertItemList(FilterList, i + 1, entry);
ListBox_DeleteString(ListBox, i);
entryString = FormatFilterEntry(entry);
ListBox_InsertString(ListBox, i + 1, entryString->Buffer);
PhDereferenceObject(entryString);
i++;
ListBox_SetCurSel(ListBox, i);
FixControlStates(hwndDlg, ListBox);
}
}
break;
}
}
break;
}
return FALSE;
}
INT_PTR CALLBACK ProcessesDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
INT_PTR result;
if (result = HandleCommonMessages(hwndDlg, uMsg, wParam, lParam,
GetDlgItem(hwndDlg, IDC_LIST), EditingProcessFilterList))
return result;
switch (uMsg)
{
case WM_INITDIALOG:
{
EditingProcessFilterList = PhCreateList(ProcessFilterList->Count + 10);
CopyFilterList(EditingProcessFilterList, ProcessFilterList);
AddEntriesToListBox(GetDlgItem(hwndDlg, IDC_LIST), EditingProcessFilterList);
}
break;
case WM_DESTROY:
{
ClearFilterList(EditingProcessFilterList);
PhDereferenceObject(EditingProcessFilterList);
EditingProcessFilterList = NULL;
}
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
NOTHING;
}
}
break;
case WM_NOTIFY:
{
LPNMHDR header = (LPNMHDR)lParam;
switch (header->code)
{
case PSN_APPLY:
{
PPH_STRING string;
ClearFilterList(ProcessFilterList);
CopyFilterList(ProcessFilterList, EditingProcessFilterList);
string = SaveFilterList(ProcessFilterList);
PhSetStringSetting2(SETTING_NAME_PROCESS_LIST, &string->sr);
PhDereferenceObject(string);
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
}
return TRUE;
}
}
break;
}
return FALSE;
}
INT_PTR CALLBACK ServicesDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
if (HandleCommonMessages(hwndDlg, uMsg, wParam, lParam,
GetDlgItem(hwndDlg, IDC_LIST), EditingServiceFilterList))
return FALSE;
switch (uMsg)
{
case WM_INITDIALOG:
{
EditingServiceFilterList = PhCreateList(ServiceFilterList->Count + 10);
CopyFilterList(EditingServiceFilterList, ServiceFilterList);
AddEntriesToListBox(GetDlgItem(hwndDlg, IDC_LIST), EditingServiceFilterList);
}
break;
case WM_DESTROY:
{
ClearFilterList(EditingServiceFilterList);
PhDereferenceObject(EditingServiceFilterList);
EditingServiceFilterList = NULL;
}
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
NOTHING;
}
}
break;
case WM_NOTIFY:
{
LPNMHDR header = (LPNMHDR)lParam;
switch (header->code)
{
case PSN_APPLY:
{
PPH_STRING string;
ClearFilterList(ServiceFilterList);
CopyFilterList(ServiceFilterList, EditingServiceFilterList);
string = SaveFilterList(ServiceFilterList);
PhSetStringSetting2(SETTING_NAME_SERVICE_LIST, &string->sr);
PhDereferenceObject(string);
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
}
return TRUE;
}
}
break;
}
return FALSE;
}
INT_PTR CALLBACK LoggingDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
SetDlgItemText(hwndDlg, IDC_LOGFILENAME, ((PPH_STRING)PH_AUTO(PhGetStringSetting(SETTING_NAME_LOG_FILENAME)))->Buffer);
}
break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_BROWSE:
{
static PH_FILETYPE_FILTER filters[] =
{
{ L"Log files (*.txt;*.log)", L"*.txt;*.log" },
{ L"All files (*.*)", L"*.*" }
};
PVOID fileDialog;
PPH_STRING fileName;
fileDialog = PhCreateSaveFileDialog();
PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER));
fileName = PH_AUTO(PhGetFileName(PhaGetDlgItemText(hwndDlg, IDC_LOGFILENAME)));
PhSetFileDialogFileName(fileDialog, fileName->Buffer);
if (PhShowFileDialog(hwndDlg, fileDialog))
{
fileName = PH_AUTO(PhGetFileDialogFileName(fileDialog));
SetDlgItemText(hwndDlg, IDC_LOGFILENAME, fileName->Buffer);
}
PhFreeFileDialog(fileDialog);
}
break;
}
}
break;
case WM_NOTIFY:
{
LPNMHDR header = (LPNMHDR)lParam;
switch (header->code)
{
case PSN_APPLY:
{
PhSetStringSetting2(SETTING_NAME_LOG_FILENAME, &PhaGetDlgItemText(hwndDlg, IDC_LOGFILENAME)->sr);
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
}
return TRUE;
}
}
break;
}
return FALSE;
}
INT_PTR CALLBACK GrowlDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
SetDlgItemText(hwndDlg, IDC_LICENSE, PH_AUTO_T(PH_STRING, PhConvertUtf8ToUtf16(gntp_send_license_text))->Buffer);
Button_SetCheck(GetDlgItem(hwndDlg, IDC_ENABLEGROWL), PhGetIntegerSetting(SETTING_NAME_ENABLE_GROWL) ? BST_CHECKED : BST_UNCHECKED);
}
break;
case WM_NOTIFY:
{
LPNMHDR header = (LPNMHDR)lParam;
switch (header->code)
{
case PSN_QUERYINITIALFOCUS:
{
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LONG_PTR)GetDlgItem(hwndDlg, IDC_ENABLEGROWL));
}
return TRUE;
case PSN_APPLY:
{
PhSetIntegerSetting(SETTING_NAME_ENABLE_GROWL, Button_GetCheck(GetDlgItem(hwndDlg, IDC_ENABLEGROWL)) == BST_CHECKED);
if (PhGetIntegerSetting(SETTING_NAME_ENABLE_GROWL))
RegisterGrowl(FALSE);
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
}
return TRUE;
}
}
break;
}
return FALSE;
}