/** * Removes a menu item from its parent. * * \param Parent The parent menu item. If \a Item is NULL, * this parameter must be specified. * \param Item The child menu item. This may be NULL if * \a Index is specified. * \param Index The index of the menu item to remove. If * \a Item is specified, this parameter is ignored. */ BOOLEAN PhRemoveEMenuItem( __inout_opt PPH_EMENU_ITEM Parent, __in_opt PPH_EMENU_ITEM Item, __in_opt ULONG Index ) { if (Item) { if (!Parent) Parent = Item->Parent; if (!Parent->Items) return FALSE; Index = PhFindItemList(Parent->Items, Item); if (Index == -1) return FALSE; } else { if (!Parent) return FALSE; if (!Parent->Items) return FALSE; } Item = Parent->Items->Items[Index]; PhRemoveItemList(Parent->Items, Index); Item->Parent = NULL; return TRUE; }
VOID VirusTotalRemoveCacheResult( _In_ PPROCESS_EXTENSION Extension ) { PhAcquireQueuedLockExclusive(&ProcessListLock); for (ULONG i = 0; i < VirusTotalList->Count; i++) { PVIRUSTOTAL_FILE_HASH_ENTRY extension = VirusTotalList->Items[i]; PhRemoveItemList(VirusTotalList, i); PhClearReference(&extension->FileName); PhClearReference(&extension->FileHash); PhClearReference(&extension->FileNameAnsi); PhClearReference(&extension->FileHashAnsi); PhClearReference(&extension->CreationTime); PhFree(extension); } //PhClearList(VirusTotalList); //PhDereferenceObject(VirusTotalList); PhReleaseQueuedLockExclusive(&ProcessListLock); }
/** * Frees resources used by a work queue. * * \param WorkQueue A work queue object. */ VOID PhDeleteWorkQueue( _Inout_ PPH_WORK_QUEUE WorkQueue ) { PLIST_ENTRY listEntry; PPH_WORK_QUEUE_ITEM workQueueItem; #ifdef DEBUG ULONG index; #endif #ifdef DEBUG PhAcquireQueuedLockExclusive(&PhDbgWorkQueueListLock); if ((index = PhFindItemList(PhDbgWorkQueueList, WorkQueue)) != -1) PhRemoveItemList(PhDbgWorkQueueList, index); PhReleaseQueuedLockExclusive(&PhDbgWorkQueueListLock); #endif // Wait for all worker threads to exit. WorkQueue->Terminating = TRUE; NtReleaseSemaphore(WorkQueue->SemaphoreHandle, WorkQueue->CurrentThreads, NULL); PhWaitForRundownProtection(&WorkQueue->RundownProtect); // Free all un-executed work items. listEntry = WorkQueue->QueueListHead.Flink; while (listEntry != &WorkQueue->QueueListHead) { workQueueItem = CONTAINING_RECORD(listEntry, PH_WORK_QUEUE_ITEM, ListEntry); listEntry = listEntry->Flink; PhFreeToFreeList(&PhWorkQueueItemFreeList, workQueueItem); } NtClose(WorkQueue->SemaphoreHandle); }
VOID AddFilterType( _Inout_ PPH_DBGEVENTS_CONTEXT Context, _In_ FILTER_BY_TYPE Type, _In_ HANDLE ProcessID, _In_ PPH_STRING ProcessName ) { PDBG_FILTER_TYPE newFilterEntry; newFilterEntry = PhAllocate(sizeof(DBG_FILTER_TYPE)); newFilterEntry->Type = Type; newFilterEntry->ProcessId = ProcessID; newFilterEntry->ProcessName = ProcessName; PhAddItemList(Context->ExcludeList, newFilterEntry); // Remove any existing entries... for (ULONG i = 0; i < Context->LogMessageList->Count; i++) { PDEBUG_LOG_ENTRY listEntry = Context->LogMessageList->Items[i]; if (Type == FilterByName) { if (PhEqualString(listEntry->ProcessName, newFilterEntry->ProcessName, TRUE)) { PhRemoveItemList(Context->LogMessageList, i); i--; } } else if (Type == FilterByPid) { if (listEntry->ProcessId == ProcessID) { PhRemoveItemList(Context->LogMessageList, i); i--; } } } }
VOID PhUnregisterDialog( _In_ HWND DialogWindowHandle ) { ULONG indexOfDialog; if (!DialogList) return; indexOfDialog = PhFindItemList(DialogList, (PVOID)DialogWindowHandle); if (indexOfDialog != -1) PhRemoveItemList(DialogList, indexOfDialog); }
static VOID DbgAddLogEntry( _Inout_ PPH_DBGEVENTS_CONTEXT Context, _In_ PDEBUG_LOG_ENTRY Entry ) { if (Context->LogMessageList->Count > PhGetIntegerSetting(SETTING_NAME_MAX_ENTRIES)) { DbgFreeLogEntry(Context->LogMessageList->Items[0]); PhRemoveItemList(Context->LogMessageList, 0); } PhAddItemList(Context->LogMessageList, Entry); PhInvokeCallback(&DbgLoggedCallback, Entry); }
VOID PhUnregisterMessageLoopFilter( _In_ struct _PH_MESSAGE_LOOP_FILTER_ENTRY *FilterEntry ) { ULONG indexOfFilter; if (!FilterList) return; indexOfFilter = PhFindItemList(FilterList, FilterEntry); if (indexOfFilter != -1) PhRemoveItemList(FilterList, indexOfFilter); PhFree(FilterEntry); }
VOID ResetFilters( _Inout_ PPH_DBGEVENTS_CONTEXT Context ) { for (ULONG i = 0; i < Context->ExcludeList->Count; i++) { PDBG_FILTER_TYPE filterEntry = Context->ExcludeList->Items[i]; if (filterEntry->ProcessName) PhDereferenceObject(filterEntry->ProcessName); PhFree(filterEntry); PhRemoveItemList(Context->ExcludeList, i); i--; } }
VOID AdapterEntryDeleteProcedure( _In_ PVOID Object, _In_ ULONG Flags ) { PDV_NETADAPTER_ENTRY entry = Object; PhAcquireQueuedLockExclusive(&NetworkAdaptersListLock); PhRemoveItemList(NetworkAdaptersList, PhFindItemList(NetworkAdaptersList, entry)); PhReleaseQueuedLockExclusive(&NetworkAdaptersListLock); DeleteNetAdapterId(&entry->Id); PhClearReference(&entry->AdapterName); PhDeleteCircularBuffer_ULONG64(&entry->InboundBuffer); PhDeleteCircularBuffer_ULONG64(&entry->OutboundBuffer); }
static VOID DiskEntryDeleteProcedure( _In_ PVOID Object, _In_ ULONG Flags ) { PDV_DISK_ENTRY entry = Object; PhAcquireQueuedLockExclusive(&DiskDrivesListLock); PhRemoveItemList(DiskDrivesList, PhFindItemList(DiskDrivesList, entry)); PhReleaseQueuedLockExclusive(&DiskDrivesListLock); DeleteDiskId(&entry->Id); PhClearReference(&entry->DiskName); PhDeleteCircularBuffer_ULONG64(&entry->ReadBuffer); PhDeleteCircularBuffer_ULONG64(&entry->WriteBuffer); }
VOID PhConvertIgnoredSettings( VOID ) { ULONG i; PhAcquireQueuedLockExclusive(&PhSettingsLock); for (i = 0; i < PhIgnoredSettings->Count; i++) { PPH_SETTING ignoredSetting = PhIgnoredSettings->Items[i]; PPH_SETTING setting; setting = PhpLookupSetting(&ignoredSetting->Name); if (setting) { PhpFreeSettingValue(setting->Type, setting); if (!PhpSettingFromString( setting->Type, &((PPH_STRING)ignoredSetting->u.Pointer)->sr, ignoredSetting->u.Pointer, setting )) { PhpSettingFromString( setting->Type, &setting->DefaultValue, NULL, setting ); } PhpFreeIgnoredSetting(ignoredSetting); PhRemoveItemList(PhIgnoredSettings, i); i--; } } PhReleaseQueuedLockExclusive(&PhSettingsLock); }
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 (GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_LIST: { if (GET_WM_COMMAND_CMD(wParam, lParam) == 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 EspServiceOtherDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PSERVICE_OTHER_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = PhAllocate(sizeof(SERVICE_OTHER_CONTEXT)); memset(context, 0, sizeof(SERVICE_OTHER_CONTEXT)); SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PSERVICE_OTHER_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { NTSTATUS status; LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PPH_SERVICE_ITEM serviceItem = (PPH_SERVICE_ITEM)propSheetPage->lParam; HWND privilegesLv; context->ServiceItem = serviceItem; context->PrivilegesLv = privilegesLv = GetDlgItem(hwndDlg, IDC_PRIVILEGES); PhSetListViewStyle(privilegesLv, FALSE, TRUE); PhSetControlTheme(privilegesLv, L"explorer"); PhAddListViewColumn(privilegesLv, 0, 0, 0, LVCFMT_LEFT, 140, L"Name"); PhAddListViewColumn(privilegesLv, 1, 1, 1, LVCFMT_LEFT, 220, L"Display Name"); PhSetExtendedListView(privilegesLv); context->PrivilegeList = PhCreateList(32); if (context->ServiceItem->Type == SERVICE_KERNEL_DRIVER || context->ServiceItem->Type == SERVICE_FILE_SYSTEM_DRIVER) { // Drivers don't support required privileges. EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); } EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_SIDTYPE), EspServiceSidTypeStrings, sizeof(EspServiceSidTypeStrings) / sizeof(PWSTR)); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_PROTECTION), EspServiceLaunchProtectedStrings, sizeof(EspServiceLaunchProtectedStrings) / sizeof(PWSTR)); if (WindowsVersion < WINDOWS_8_1) EnableWindow(GetDlgItem(hwndDlg, IDC_PROTECTION), FALSE); SetDlgItemText(hwndDlg, IDC_SERVICESID, PhGetStringOrDefault(PH_AUTO(EspGetServiceSidString(&serviceItem->Name->sr)), L"N/A")); status = EspLoadOtherInfo(hwndDlg, context); if (!NT_SUCCESS(status)) { PhShowWarning(hwndDlg, L"Unable to query service information: %s", ((PPH_STRING)PH_AUTO(PhGetNtMessage(status)))->Buffer); } context->Ready = TRUE; } break; case WM_DESTROY: { if (context->PrivilegeList) { PhDereferenceObjects(context->PrivilegeList->Items, context->PrivilegeList->Count); PhDereferenceObject(context->PrivilegeList); } PhFree(context); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_ADD: { NTSTATUS status; LSA_HANDLE policyHandle; LSA_ENUMERATION_HANDLE enumContext; PPOLICY_PRIVILEGE_DEFINITION buffer; ULONG count; ULONG i; PPH_LIST choices; PPH_STRING selectedChoice = NULL; choices = PH_AUTO(PhCreateList(100)); if (!NT_SUCCESS(status = PhOpenLsaPolicy(&policyHandle, POLICY_VIEW_LOCAL_INFORMATION, NULL))) { PhShowStatus(hwndDlg, L"Unable to open LSA policy", status, 0); break; } enumContext = 0; while (TRUE) { status = LsaEnumeratePrivileges( policyHandle, &enumContext, &buffer, 0x100, &count ); if (status == STATUS_NO_MORE_ENTRIES) break; if (!NT_SUCCESS(status)) break; for (i = 0; i < count; i++) { PhAddItemList(choices, PhaCreateStringEx(buffer[i].Name.Buffer, buffer[i].Name.Length)->Buffer); } LsaFreeMemory(buffer); } LsaClose(policyHandle); qsort(choices->Items, choices->Count, sizeof(PWSTR), PrivilegeNameCompareFunction); while (PhaChoiceDialog( hwndDlg, L"Add privilege", L"Select a privilege to add:", (PWSTR *)choices->Items, choices->Count, NULL, PH_CHOICE_DIALOG_CHOICE, &selectedChoice, NULL, NULL )) { BOOLEAN found = FALSE; PPH_STRING privilegeString; INT lvItemIndex; PPH_STRING displayName; // Check for duplicates. for (i = 0; i < context->PrivilegeList->Count; i++) { if (PhEqualString(context->PrivilegeList->Items[i], selectedChoice, FALSE)) { found = TRUE; break; } } if (found) { if (PhShowMessage( hwndDlg, MB_OKCANCEL | MB_ICONERROR, L"The selected privilege has already been added." ) == IDOK) { continue; } else { break; } } PhSetReference(&privilegeString, selectedChoice); PhAddItemList(context->PrivilegeList, privilegeString); lvItemIndex = PhAddListViewItem(context->PrivilegesLv, MAXINT, privilegeString->Buffer, privilegeString); if (PhLookupPrivilegeDisplayName(&privilegeString->sr, &displayName)) { PhSetListViewSubItem(context->PrivilegesLv, lvItemIndex, 1, displayName->Buffer); PhDereferenceObject(displayName); } ExtendedListView_SortItems(context->PrivilegesLv); context->Dirty = TRUE; context->RequiredPrivilegesValid = TRUE; break; } } break; case IDC_REMOVE: { INT lvItemIndex; PPH_STRING privilegeString; ULONG index; lvItemIndex = ListView_GetNextItem(context->PrivilegesLv, -1, LVNI_SELECTED); if (lvItemIndex != -1 && PhGetListViewItemParam(context->PrivilegesLv, lvItemIndex, (PVOID *)&privilegeString)) { index = PhFindItemList(context->PrivilegeList, privilegeString); if (index != -1) { PhDereferenceObject(privilegeString); PhRemoveItemList(context->PrivilegeList, index); PhRemoveListViewItem(context->PrivilegesLv, lvItemIndex); context->Dirty = TRUE; context->RequiredPrivilegesValid = TRUE; } } } break; } switch (HIWORD(wParam)) { case EN_CHANGE: case CBN_SELCHANGE: { if (context->Ready) { context->Dirty = TRUE; switch (LOWORD(wParam)) { case IDC_PRESHUTDOWNTIMEOUT: context->PreshutdownTimeoutValid = TRUE; break; case IDC_SIDTYPE: context->SidTypeValid = TRUE; break; case IDC_PROTECTION: context->LaunchProtectedValid = TRUE; break; } } } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_KILLACTIVE: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); } return TRUE; case PSN_APPLY: { SC_HANDLE serviceHandle = NULL; ULONG win32Result = 0; BOOLEAN connectedToPhSvc = FALSE; PPH_STRING launchProtectedString; ULONG launchProtected; SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); launchProtectedString = PH_AUTO(PhGetWindowText(GetDlgItem(hwndDlg, IDC_PROTECTION))); launchProtected = EspGetServiceLaunchProtectedInteger(launchProtectedString->Buffer); if (context->LaunchProtectedValid && launchProtected != 0 && launchProtected != context->OriginalLaunchProtected) { if (PhShowMessage( hwndDlg, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2, L"Setting service protection will prevent the service from being controlled, modified, or deleted. Do you want to continue?" ) == IDNO) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); return TRUE; } } if (context->Dirty) { SERVICE_PRESHUTDOWN_INFO preshutdownInfo; SERVICE_REQUIRED_PRIVILEGES_INFO requiredPrivilegesInfo; SERVICE_SID_INFO sidInfo; SERVICE_LAUNCH_PROTECTED_INFO launchProtectedInfo; if (!(serviceHandle = PhOpenService(context->ServiceItem->Name->Buffer, SERVICE_CHANGE_CONFIG))) { win32Result = GetLastError(); if (win32Result == ERROR_ACCESS_DENIED && !PhElevated) { // Elevate using phsvc. if (PhUiConnectToPhSvc(hwndDlg, FALSE)) { win32Result = 0; connectedToPhSvc = TRUE; } else { // User cancelled elevation. win32Result = ERROR_CANCELLED; goto Done; } } else { goto Done; } } if (context->PreshutdownTimeoutValid) { preshutdownInfo.dwPreshutdownTimeout = GetDlgItemInt(hwndDlg, IDC_PRESHUTDOWNTIMEOUT, NULL, FALSE); if (!EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_PRESHUTDOWN_INFO, &preshutdownInfo)) { win32Result = GetLastError(); } } if (context->RequiredPrivilegesValid) { PH_STRING_BUILDER sb; ULONG i; PhInitializeStringBuilder(&sb, 100); for (i = 0; i < context->PrivilegeList->Count; i++) { PhAppendStringBuilder(&sb, &((PPH_STRING)context->PrivilegeList->Items[i])->sr); PhAppendCharStringBuilder(&sb, 0); } requiredPrivilegesInfo.pmszRequiredPrivileges = sb.String->Buffer; if (win32Result == 0 && !EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, &requiredPrivilegesInfo)) { win32Result = GetLastError(); } PhDeleteStringBuilder(&sb); } if (context->SidTypeValid) { PPH_STRING sidTypeString; sidTypeString = PH_AUTO(PhGetWindowText(GetDlgItem(hwndDlg, IDC_SIDTYPE))); sidInfo.dwServiceSidType = EspGetServiceSidTypeInteger(sidTypeString->Buffer); if (win32Result == 0 && !EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_SERVICE_SID_INFO, &sidInfo)) { win32Result = GetLastError(); } } if (context->LaunchProtectedValid) { launchProtectedInfo.dwLaunchProtected = launchProtected; if (!EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_LAUNCH_PROTECTED, &launchProtectedInfo)) { // For now, ignore errors here. // win32Result = GetLastError(); } } Done: if (connectedToPhSvc) PhUiDisconnectFromPhSvc(); if (serviceHandle) CloseServiceHandle(serviceHandle); if (win32Result != 0) { if (win32Result == ERROR_CANCELLED || PhShowMessage( hwndDlg, MB_ICONERROR | MB_RETRYCANCEL, L"Unable to change service information: %s", ((PPH_STRING)PH_AUTO(PhGetWin32Message(win32Result)))->Buffer ) == IDRETRY) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } } return TRUE; } break; case LVN_ITEMCHANGED: { if (header->hwndFrom == context->PrivilegesLv) { EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), ListView_GetSelectedCount(context->PrivilegesLv) == 1); } } break; } } break; } return FALSE; }
INT_PTR CALLBACK PhpColumnSetEditorDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PCOLUMNSET_DIALOG_CONTEXT context = NULL; if (uMsg == WM_INITDIALOG) { context = PhAllocate(sizeof(COLUMNSET_DIALOG_CONTEXT)); memset(context, 0, sizeof(COLUMNSET_DIALOG_CONTEXT)); context->SettingName = PhCreateString((PWSTR)lParam); SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context); } else { context = (PCOLUMNSET_DIALOG_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { context->DialogHandle = hwndDlg; context->ListViewHandle = GetDlgItem(hwndDlg, IDC_COLUMNSETLIST); context->RenameButtonHandle = GetDlgItem(hwndDlg, IDC_RENAME); context->MoveUpButtonHandle = GetDlgItem(hwndDlg, IDC_MOVEUP); context->MoveDownButtonHandle = GetDlgItem(hwndDlg, IDC_MOVEDOWN); context->RemoveButtonHandle = GetDlgItem(hwndDlg, IDC_REMOVE); PhCenterWindow(hwndDlg, GetParent(hwndDlg)); PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE); PhSetControlTheme(context->ListViewHandle, L"explorer"); PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 250, L"Name"); PhSetExtendedListView(context->ListViewHandle); context->ColumnSetList = PhInitializeColumnSetList(PhGetString(context->SettingName)); for (ULONG i = 0; i < context->ColumnSetList->Count; i++) { PPH_COLUMN_SET_ENTRY entry = context->ColumnSetList->Items[i]; PhAddListViewItem(context->ListViewHandle, MAXINT, entry->Name->Buffer, entry); } Button_Enable(context->RenameButtonHandle, FALSE); Button_Enable(context->MoveUpButtonHandle, FALSE); Button_Enable(context->MoveDownButtonHandle, FALSE); Button_Enable(context->RemoveButtonHandle, FALSE); } break; case WM_DESTROY: { PhDeleteColumnSetList(context->ColumnSetList); RemoveProp(hwndDlg, PhMakeContextAtom()); PhFree(context); } break; case WM_COMMAND: { switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); break; case IDOK: { if (context->LabelEditActive) break; PhSaveSettingsColumnList(PhGetString(context->SettingName), context->ColumnSetList); EndDialog(hwndDlg, IDOK); } break; case IDC_RENAME: { INT lvItemIndex; lvItemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); if (lvItemIndex != -1) { SetFocus(context->ListViewHandle); ListView_EditLabel(context->ListViewHandle, lvItemIndex); } } break; case IDC_MOVEUP: { INT lvItemIndex; PPH_COLUMN_SET_ENTRY entry; ULONG index; PhpMoveSelectedListViewItemUp(context->ListViewHandle); lvItemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); if (lvItemIndex != -1 && PhGetListViewItemParam(context->ListViewHandle, lvItemIndex, (PVOID *)&entry)) { index = PhFindItemList(context->ColumnSetList, entry); if (index != -1) { PhRemoveItemList(context->ColumnSetList, index); PhInsertItemList(context->ColumnSetList, lvItemIndex, entry); } } } break; case IDC_MOVEDOWN: { INT lvItemIndex; PPH_COLUMN_SET_ENTRY entry; ULONG index; PhpMoveSelectedListViewItemDown(context->ListViewHandle); lvItemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); if (lvItemIndex != -1 && PhGetListViewItemParam(context->ListViewHandle, lvItemIndex, (PVOID *)&entry)) { index = PhFindItemList(context->ColumnSetList, entry); if (index != -1) { PhRemoveItemList(context->ColumnSetList, index); PhInsertItemList(context->ColumnSetList, lvItemIndex, entry); } } } break; case IDC_REMOVE: { INT lvItemIndex; PPH_COLUMN_SET_ENTRY entry; ULONG index; lvItemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); if (lvItemIndex != -1 && PhGetListViewItemParam(context->ListViewHandle, lvItemIndex, (PVOID *)&entry)) { index = PhFindItemList(context->ColumnSetList, entry); if (index != -1) { PhRemoveItemList(context->ColumnSetList, index); PhRemoveListViewItem(context->ListViewHandle, lvItemIndex); PhClearReference(&entry->Name); PhClearReference(&entry->Setting); PhClearReference(&entry->Sorting); PhFree(entry); } SetFocus(context->ListViewHandle); ListView_SetItemState(context->ListViewHandle, 0, LVNI_SELECTED, LVNI_SELECTED); //ListView_EnsureVisible(context->ListViewHandle, 0, FALSE); } } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case NM_DBLCLK: { INT lvItemIndex; lvItemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); if (lvItemIndex != -1) { SetFocus(context->ListViewHandle); ListView_EditLabel(context->ListViewHandle, lvItemIndex); } } break; case LVN_ITEMCHANGED: { LPNMLISTVIEW listview = (LPNMLISTVIEW)lParam; INT index; INT lvItemIndex; INT count; index = listview->iItem; lvItemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); count = ListView_GetItemCount(context->ListViewHandle); if (count == 0 || index == -1 || lvItemIndex == -1) { Button_Enable(context->RenameButtonHandle, FALSE); Button_Enable(context->MoveUpButtonHandle, FALSE); Button_Enable(context->MoveDownButtonHandle, FALSE); Button_Enable(context->RemoveButtonHandle, FALSE); break; } if (index != lvItemIndex) break; if (index == 0 && count == 1) { // First and last item Button_Enable(context->MoveUpButtonHandle, FALSE); Button_Enable(context->MoveDownButtonHandle, FALSE); } else if (index == (count - 1)) { // Last item Button_Enable(context->MoveUpButtonHandle, TRUE); Button_Enable(context->MoveDownButtonHandle, FALSE); } else if (index == 0) { // First item Button_Enable(context->MoveUpButtonHandle, FALSE); Button_Enable(context->MoveDownButtonHandle, TRUE); } else { Button_Enable(context->MoveUpButtonHandle, TRUE); Button_Enable(context->MoveDownButtonHandle, TRUE); } Button_Enable(context->RenameButtonHandle, TRUE); Button_Enable(context->RemoveButtonHandle, TRUE); } break; case LVN_BEGINLABELEDIT: context->LabelEditActive = TRUE; break; case LVN_ENDLABELEDIT: { LV_DISPINFO* lvinfo = (LV_DISPINFO*)lParam; if (lvinfo->item.iItem != -1 && lvinfo->item.pszText) { BOOLEAN found = FALSE; PPH_COLUMN_SET_ENTRY entry; ULONG index; for (ULONG i = 0; i < context->ColumnSetList->Count; i++) { entry = context->ColumnSetList->Items[i]; if (PhEqualStringRef2(&entry->Name->sr, lvinfo->item.pszText, FALSE)) { found = TRUE; break; } } if (!found && PhGetListViewItemParam(context->ListViewHandle, lvinfo->item.iItem, (PVOID *)&entry)) { index = PhFindItemList(context->ColumnSetList, entry); if (index != -1) { PhMoveReference(&entry->Name, PhCreateString(lvinfo->item.pszText)); ListView_SetItemText(context->ListViewHandle, lvinfo->item.iItem, 0, lvinfo->item.pszText); } } } context->LabelEditActive = FALSE; } break; } } break; } return FALSE; }
static INT_PTR CALLBACK OptionsDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PPH_PERFMON_CONTEXT context = NULL; if (uMsg == WM_INITDIALOG) { context = (PPH_PERFMON_CONTEXT)PhAllocate(sizeof(PH_PERFMON_CONTEXT)); memset(context, 0, sizeof(PH_PERFMON_CONTEXT)); SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PPH_PERFMON_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_NCDESTROY) { PPH_STRING string; ClearCounterList(CountersList); CopyCounterList(CountersList, context->CountersListEdited); PhDereferenceObject(context->CountersListEdited); string = SaveCounterList(CountersList); PhSetStringSetting2(SETTING_NAME_PERFMON_LIST, &string->sr); PhDereferenceObject(string); RemoveProp(hwndDlg, L"Context"); PhFree(context); } } if (context == NULL) return FALSE; switch (uMsg) { case WM_INITDIALOG: { context->CountersListEdited = PhCreateList(2); context->ListViewHandle = GetDlgItem(hwndDlg, IDC_PERFCOUNTER_LISTVIEW); PhSetListViewStyle(context->ListViewHandle, FALSE, TRUE); PhSetControlTheme(context->ListViewHandle, L"explorer"); PhAddListViewColumn(context->ListViewHandle, 0, 0, 0, LVCFMT_LEFT, 420, L"Counter"); PhSetExtendedListView(context->ListViewHandle); ClearCounterList(context->CountersListEdited); CopyCounterList(context->CountersListEdited, CountersList); LoadCountersToListView(context, context->CountersListEdited); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_ADD_BUTTON: { PDH_STATUS counterStatus = 0; PPH_STRING counterPathString = NULL; PPH_STRING counterWildCardString = NULL; PDH_BROWSE_DLG_CONFIG browseConfig = { 0 }; WCHAR counterPathBuffer[PDH_MAX_COUNTER_PATH] = L""; browseConfig.bIncludeInstanceIndex = FALSE; browseConfig.bSingleCounterPerAdd = FALSE;// Fix empty CounterPathBuffer browseConfig.bSingleCounterPerDialog = TRUE; browseConfig.bLocalCountersOnly = FALSE; browseConfig.bWildCardInstances = TRUE; // Seems to cause a lot of crashes browseConfig.bHideDetailBox = TRUE; browseConfig.bInitializePath = FALSE; browseConfig.bDisableMachineSelection = FALSE; browseConfig.bIncludeCostlyObjects = FALSE; browseConfig.bShowObjectBrowser = FALSE; browseConfig.hWndOwner = hwndDlg; browseConfig.szReturnPathBuffer = counterPathBuffer; browseConfig.cchReturnPathLength = PDH_MAX_COUNTER_PATH; browseConfig.CallBackStatus = ERROR_SUCCESS; browseConfig.dwDefaultDetailLevel = PERF_DETAIL_WIZARD; browseConfig.szDialogBoxCaption = L"Select a counter to monitor."; __try { // Display the counter browser window. if ((counterStatus = PdhBrowseCounters(&browseConfig)) != ERROR_SUCCESS) { if (counterStatus != PDH_DIALOG_CANCELLED) { PhShowError(hwndDlg, L"PdhBrowseCounters failed with status 0x%x.", counterStatus); } __leave; } else if (wcslen(counterPathBuffer) == 0) { // This gets called when pressing the X on the BrowseCounters dialog. __leave; } counterPathString = PhCreateString(counterPathBuffer); // Check if we need to expand any wildcards... if (PhFindCharInString(counterPathString, 0, '*') != -1) { ULONG counterWildCardLength = 0; // Query WildCard buffer length... PdhExpandWildCardPath( NULL, counterPathString->Buffer, NULL, &counterWildCardLength, 0 ); counterWildCardString = PhCreateStringEx(NULL, counterWildCardLength * sizeof(WCHAR)); if ((counterStatus = PdhExpandWildCardPath( NULL, counterPathString->Buffer, counterWildCardString->Buffer, &counterWildCardLength, 0 )) == ERROR_SUCCESS) { PH_STRINGREF part; PH_STRINGREF remaining = counterWildCardString->sr; while (remaining.Length != 0) { // Split the results if (!PhSplitStringRefAtChar(&remaining, '\0', &part, &remaining)) break; if (remaining.Length == 0) break; if ((counterStatus = PdhValidatePath(part.Buffer)) != ERROR_SUCCESS) { PhShowError(hwndDlg, L"PdhValidatePath failed with status 0x%x.", counterStatus); __leave; } AddCounterToListView(context, part.Buffer); } } else { PhShowError(hwndDlg, L"PdhExpandWildCardPath failed with status 0x%x.", counterStatus); } } else { if ((counterStatus = PdhValidatePath(counterPathString->Buffer)) != ERROR_SUCCESS) { PhShowError(hwndDlg, L"PdhValidatePath failed with status 0x%x.", counterStatus); __leave; } AddCounterToListView(context, counterPathString->Buffer); } } __finally { if (counterWildCardString) PhDereferenceObject(counterWildCardString); if (counterPathString) PhDereferenceObject(counterPathString); } } break; case IDC_REMOVE_BUTTON: { INT itemIndex; // Get the first selected item itemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); while (itemIndex != -1) { PPH_PERFMON_ENTRY entry; if (PhGetListViewItemParam(context->ListViewHandle, itemIndex, (PPVOID)&entry)) { ULONG index = PhFindItemList(context->CountersListEdited, entry); if (index != -1) { PhRemoveItemList(context->CountersListEdited, index); PhRemoveListViewItem(context->ListViewHandle, itemIndex); FreeCounterEntry(entry); } } // Get the next selected item itemIndex = ListView_GetNextItem(context->ListViewHandle, -1, LVNI_SELECTED); } } break; case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); break; case IDOK: EndDialog(hwndDlg, IDOK); break; } } break; } return FALSE; }