/** * 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; }
static BOOLEAN NTAPI PhpCsrProcessHandlesCallback( _In_ PPH_CSR_HANDLE_INFO Handle, _In_opt_ PVOID Context ) { NTSTATUS status; BOOLEAN cont = TRUE; PCSR_HANDLES_CONTEXT context = Context; HANDLE processHandle; KERNEL_USER_TIMES times; PPH_STRING fileName; PH_HIDDEN_PROCESS_ENTRY entry; entry.ProcessId = Handle->ProcessId; if (NT_SUCCESS(status = PhOpenProcessByCsrHandle( &processHandle, ProcessQueryAccess, Handle ))) { if (NT_SUCCESS(status = PhGetProcessTimes( processHandle, × )) && NT_SUCCESS(status = PhGetProcessImageFileName( processHandle, &fileName ))) { entry.FileName = PhGetFileName(fileName); PhDereferenceObject(fileName); if (times.ExitTime.QuadPart != 0) entry.Type = TerminatedProcess; else if (PhFindItemList(context->Pids, Handle->ProcessId) != -1) entry.Type = NormalProcess; else entry.Type = HiddenProcess; if (!context->Callback(&entry, context->Context)) cont = FALSE; PhDereferenceObject(entry.FileName); } NtClose(processHandle); } if (!NT_SUCCESS(status)) { entry.FileName = NULL; entry.Type = UnknownProcess; if (!context->Callback(&entry, context->Context)) cont = FALSE; } return cont; }
/** * 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); }
/** * Determines the index of a menu item. * * \param Parent The parent menu item. * \param Item The child menu item. * * \return The index of the menu item, or -1 if the menu item * was not found in the parent menu item. */ ULONG PhIndexOfEMenuItem( __in PPH_EMENU_ITEM Parent, __in PPH_EMENU_ITEM Item ) { if (!Parent->Items) return -1; return PhFindItemList(Parent->Items, Item); }
VOID PhUnregisterDialog( _In_ HWND DialogWindowHandle ) { ULONG indexOfDialog; if (!DialogList) return; indexOfDialog = PhFindItemList(DialogList, (PVOID)DialogWindowHandle); if (indexOfDialog != -1) PhRemoveItemList(DialogList, indexOfDialog); }
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 PhCmSetNotifyPlugin( _In_ PPH_CM_MANAGER Manager, _In_ struct _PH_PLUGIN *Plugin ) { if (!Manager->NotifyList) { Manager->NotifyList = PhCreateList(8); } else { if (PhFindItemList(Manager->NotifyList, Plugin) != -1) return; } PhAddItemList(Manager->NotifyList, Plugin); }
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); }
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; }
static VOID PhListTick( __in PPH_EXTLV_CONTEXT Context ) { HWND hwnd = Context->Handle; ULONG tickCount; BOOLEAN redrawDisabled = FALSE; PPH_LIST itemsToRemove = NULL; PH_HASHTABLE_ENUM_CONTEXT enumContext; PPH_TICK_ENTRY entry; if (!Context->TickHashtable) return; tickCount = GetTickCount(); // First pass PhBeginEnumHashtable(Context->TickHashtable, &enumContext); while (entry = PhNextEnumHashtable(&enumContext)) { LVITEM item; PH_ITEM_STATE itemState; if (PhRoundNumber(tickCount - entry->TickCount, PH_DURATION_MULT) < Context->HighlightingDuration) continue; item.mask = LVIF_STATE; item.iItem = ListView_MapIDToIndex(hwnd, entry->Id); item.iSubItem = 0; item.stateMask = LVIS_STATEIMAGEMASK; CallWindowProc(Context->OldWndProc, hwnd, LVM_GETITEM, 0, (LPARAM)&item); itemState = PH_GET_ITEM_STATE(item.state); if (itemState == NewItemState) { item.state = INDEXTOSTATEIMAGEMASK(NormalItemState); CallWindowProc(Context->OldWndProc, hwnd, LVM_SETITEM, 0, (LPARAM)&item); if (!itemsToRemove) itemsToRemove = PhCreateList(2); PhAddItemList(itemsToRemove, (PVOID)entry->Id); entry->TickCount = tickCount; } } // Second pass // This pass is specifically for deleting items. PhBeginEnumHashtable(Context->TickHashtable, &enumContext); while (entry = PhNextEnumHashtable(&enumContext)) { LVITEM item; PH_ITEM_STATE itemState; if (itemsToRemove) { if (PhFindItemList(itemsToRemove, (PVOID)entry->Id) != -1) continue; } if (PhRoundNumber(tickCount - entry->TickCount, PH_DURATION_MULT) < Context->HighlightingDuration) continue; item.mask = LVIF_STATE; item.iItem = ListView_MapIDToIndex(hwnd, entry->Id); item.iSubItem = 0; item.stateMask = LVIS_STATEIMAGEMASK; CallWindowProc(Context->OldWndProc, hwnd, LVM_GETITEM, 0, (LPARAM)&item); itemState = PH_GET_ITEM_STATE(item.state); if (itemState == RemovingItemState) { if (!redrawDisabled) { ExtendedListView_SetRedraw(hwnd, FALSE); redrawDisabled = TRUE; } CallWindowProc(Context->OldWndProc, hwnd, LVM_DELETEITEM, item.iItem, 0); if (!itemsToRemove) itemsToRemove = PhCreateList(2); PhAddItemList(itemsToRemove, (PVOID)entry->Id); entry->TickCount = tickCount; } } if (redrawDisabled) { ExtendedListView_SetRedraw(hwnd, TRUE); } if (itemsToRemove) { ULONG i; for (i = 0; i < itemsToRemove->Count; i++) { PH_TICK_ENTRY removeEntry; removeEntry.Id = (ULONG)itemsToRemove->Items[i]; PhRemoveEntryHashtable(Context->TickHashtable, &removeEntry); } PhDereferenceObject(itemsToRemove); } }
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; }
NTSTATUS PhpEnumHiddenProcessesBruteForce( _In_ PPH_ENUM_HIDDEN_PROCESSES_CALLBACK Callback, _In_opt_ PVOID Context ) { NTSTATUS status; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; PPH_LIST pids; ULONG pid; BOOLEAN stop = FALSE; if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) return status; pids = PhCreateList(40); process = PH_FIRST_PROCESS(processes); do { PhAddItemList(pids, process->UniqueProcessId); } while (process = PH_NEXT_PROCESS(process)); PhFree(processes); for (pid = 8; pid <= 65536; pid += 4) { NTSTATUS status2; HANDLE processHandle; PH_HIDDEN_PROCESS_ENTRY entry; KERNEL_USER_TIMES times; PPH_STRING fileName; status2 = PhOpenProcess( &processHandle, ProcessQueryAccess, UlongToHandle(pid) ); if (NT_SUCCESS(status2)) { entry.ProcessId = UlongToHandle(pid); if (NT_SUCCESS(status2 = PhGetProcessTimes( processHandle, × )) && NT_SUCCESS(status2 = PhGetProcessImageFileName( processHandle, &fileName ))) { entry.FileName = PhGetFileName(fileName); PhDereferenceObject(fileName); if (times.ExitTime.QuadPart != 0) entry.Type = TerminatedProcess; else if (PhFindItemList(pids, UlongToHandle(pid)) != -1) entry.Type = NormalProcess; else entry.Type = HiddenProcess; if (!Callback(&entry, Context)) stop = TRUE; PhDereferenceObject(entry.FileName); } NtClose(processHandle); } // Use an alternative method if we don't have sufficient access. if (status2 == STATUS_ACCESS_DENIED && WindowsVersion >= WINDOWS_VISTA) { if (NT_SUCCESS(status2 = PhGetProcessImageFileNameByProcessId(UlongToHandle(pid), &fileName))) { entry.ProcessId = UlongToHandle(pid); entry.FileName = PhGetFileName(fileName); PhDereferenceObject(fileName); if (PhFindItemList(pids, UlongToHandle(pid)) != -1) entry.Type = NormalProcess; else entry.Type = HiddenProcess; if (!Callback(&entry, Context)) stop = TRUE; PhDereferenceObject(entry.FileName); } } if (status2 == STATUS_INVALID_CID || status2 == STATUS_INVALID_PARAMETER) status2 = STATUS_SUCCESS; if (!NT_SUCCESS(status2)) { entry.ProcessId = UlongToHandle(pid); entry.FileName = NULL; entry.Type = UnknownProcess; if (!Callback(&entry, Context)) stop = TRUE; } if (stop) break; } PhDereferenceObject(pids); return status; }
NTSTATUS PhEnumCsrProcessHandles( _In_ PPH_ENUM_CSR_PROCESS_HANDLES_CALLBACK Callback, _In_opt_ PVOID Context ) { NTSTATUS status; PHANDLE csrProcessHandles; ULONG numberOfCsrProcessHandles; ULONG i; BOOLEAN stop = FALSE; PPH_LIST pids; if (!NT_SUCCESS(status = PhpOpenCsrProcesses( &csrProcessHandles, &numberOfCsrProcessHandles ))) return status; pids = PhCreateList(40); for (i = 0; i < numberOfCsrProcessHandles; i++) { PKPH_PROCESS_HANDLE_INFORMATION handles; ULONG j; if (stop) break; if (NT_SUCCESS(KphEnumerateProcessHandles2(csrProcessHandles[i], &handles))) { for (j = 0; j < handles->HandleCount; j++) { PH_CSR_HANDLE_INFO handle; handle.CsrProcessHandle = csrProcessHandles[i]; handle.Handle = handles->Handles[j].Handle; // Get the process ID associated with the handle. // This call will fail if the handle is not a // process or thread handle. if (!NT_SUCCESS(PhpGetCsrHandleProcessId(&handle))) continue; // Avoid duplicate PIDs. if (PhFindItemList(pids, handle.ProcessId) != -1) continue; PhAddItemList(pids, handle.ProcessId); if (!Callback(&handle, Context)) { stop = TRUE; break; } } PhFree(handles); } } PhDereferenceObject(pids); for (i = 0; i < numberOfCsrProcessHandles; i++) NtClose(csrProcessHandles[i]); PhFree(csrProcessHandles); return status; }
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; }