/* * Process Hacker Extra Plugins - * Average CPU Plugin * * Copyright (C) 2012 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 . */ #include #include "resource.h" #define CRITICAL_MENU_ITEM 1 static PPH_PLUGIN PluginInstance; static PH_CALLBACK_REGISTRATION MenuItemCallbackRegistration; static PH_CALLBACK_REGISTRATION ProcessMenuInitializingCallbackRegistration; VOID NTAPI MenuItemCallback( _In_opt_ PVOID Parameter, _In_opt_ PVOID Context ) { PPH_PLUGIN_MENU_ITEM menuItem = Parameter; switch (menuItem->Id) { case CRITICAL_MENU_ITEM: { NTSTATUS status; PPH_PROCESS_ITEM processItem = menuItem->Context; HANDLE processHandle; ULONG breakOnTermination; if (NT_SUCCESS(status = PhOpenProcess(&processHandle, PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION, processItem->ProcessId))) { if (NT_SUCCESS(status = NtQueryInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG), NULL))) { if (!breakOnTermination && PhShowConfirmMessage( menuItem->OwnerWindow, L"enable", L"critical status on the process", L"If the process ends, the operating system will shut down immediately.", TRUE )) { breakOnTermination = TRUE; status = NtSetInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG)); } else if (breakOnTermination && PhShowConfirmMessage( menuItem->OwnerWindow, L"disable", L"critical status on the process", NULL, FALSE )) { breakOnTermination = FALSE; status = NtSetInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG)); } if (!NT_SUCCESS(status)) PhShowStatus(menuItem->OwnerWindow, L"Unable to set critical status", status, 0); } else { PhShowStatus(menuItem->OwnerWindow, L"Unable to query critical status", status, 0); } NtClose(processHandle); } else { PhShowStatus(menuItem->OwnerWindow, L"Unable to open the process", status, 0); } } break; } } VOID NTAPI ProcessMenuInitializingCallback( _In_opt_ PVOID Parameter, _In_opt_ PVOID Context ) { PPH_PLUGIN_MENU_INFORMATION menuInfo = Parameter; PPH_EMENU_ITEM miscMenuItem; PPH_EMENU_ITEM criticalMenuItem; PPH_PROCESS_ITEM processItem; miscMenuItem = PhFindEMenuItem(menuInfo->Menu, 0, L"Miscellaneous", 0); if (!miscMenuItem) return; processItem = menuInfo->u.Process.NumberOfProcesses == 1 ? menuInfo->u.Process.Processes[0] : NULL; criticalMenuItem = PhPluginCreateEMenuItem(PluginInstance, 0, CRITICAL_MENU_ITEM, L"Critical", processItem); PhInsertEMenuItem(miscMenuItem, criticalMenuItem, -1); if (processItem) { HANDLE processHandle; ULONG breakOnTermination; if (NT_SUCCESS(PhOpenProcess(&processHandle, PROCESS_QUERY_INFORMATION, processItem->ProcessId))) { if (NT_SUCCESS(NtQueryInformationProcess(processHandle, ProcessBreakOnTermination, &breakOnTermination, sizeof(ULONG), NULL))) { if (breakOnTermination) criticalMenuItem->Flags |= PH_EMENU_CHECKED; } NtClose(processHandle); } } else { criticalMenuItem->Flags |= PH_EMENU_DISABLED; } } LOGICAL DllMain( _In_ HINSTANCE Instance, _In_ ULONG Reason, _Reserved_ PVOID Reserved ) { if (Reason == DLL_PROCESS_ATTACH) { PPH_PLUGIN_INFORMATION info; PluginInstance = PhRegisterPlugin(L"wj32.SetCriticalPlugin", Instance, &info); if (!PluginInstance) return FALSE; info->DisplayName = L"Set process critical status"; info->Description = L"Adds Miscellaneous > Critical menu item."; info->Author = L"wj32"; PhRegisterCallback( PhGetPluginCallback(PluginInstance, PluginCallbackMenuItem), MenuItemCallback, NULL, &MenuItemCallbackRegistration ); PhRegisterCallback( PhGetGeneralCallback(GeneralCallbackProcessMenuInitializing), ProcessMenuInitializingCallback, NULL, &ProcessMenuInitializingCallbackRegistration ); } return TRUE; }