diff --git a/2.x/trunk/plugins/ExtendedTools/ExtendedTools.vcproj b/2.x/trunk/plugins/ExtendedTools/ExtendedTools.vcproj index 95e5c27a6..18e70126c 100644 --- a/2.x/trunk/plugins/ExtendedTools/ExtendedTools.vcproj +++ b/2.x/trunk/plugins/ExtendedTools/ExtendedTools.vcproj @@ -348,6 +348,10 @@ RelativePath=".\objprp.c" > + + diff --git a/2.x/trunk/plugins/ExtendedTools/extendedtools.h b/2.x/trunk/plugins/ExtendedTools/extendedtools.h index 61927e9a5..2a4b20b8e 100644 --- a/2.x/trunk/plugins/ExtendedTools/extendedtools.h +++ b/2.x/trunk/plugins/ExtendedTools/extendedtools.h @@ -12,6 +12,13 @@ VOID EtHandlePropertiesInitializing( __in PVOID Parameter ); +// thrdact + +BOOLEAN EtUiCancelIoThread( + __in HWND hWnd, + __in PPH_THREAD_ITEM Thread + ); + // unldll VOID EtShowUnloadedDllsDialog( diff --git a/2.x/trunk/plugins/ExtendedTools/main.c b/2.x/trunk/plugins/ExtendedTools/main.c index ae555703b..073f09889 100644 --- a/2.x/trunk/plugins/ExtendedTools/main.c +++ b/2.x/trunk/plugins/ExtendedTools/main.c @@ -53,6 +53,11 @@ VOID NTAPI ProcessMenuInitializingCallback( __in_opt PVOID Context ); +VOID NTAPI ThreadMenuInitializingCallback( + __in_opt PVOID Parameter, + __in_opt PVOID Context + ); + PPH_PLUGIN PluginInstance; PH_CALLBACK_REGISTRATION PluginLoadCallbackRegistration; PH_CALLBACK_REGISTRATION PluginShowOptionsCallbackRegistration; @@ -60,6 +65,7 @@ PH_CALLBACK_REGISTRATION PluginMenuItemCallbackRegistration; PH_CALLBACK_REGISTRATION MainWindowShowingCallbackRegistration; PH_CALLBACK_REGISTRATION HandlePropertiesInitializingCallbackRegistration; PH_CALLBACK_REGISTRATION ProcessMenuInitializingCallbackRegistration; +PH_CALLBACK_REGISTRATION ThreadMenuInitializingCallbackRegistration; LOGICAL DllMain( __in HINSTANCE Instance, @@ -120,6 +126,12 @@ LOGICAL DllMain( NULL, &ProcessMenuInitializingCallbackRegistration ); + PhRegisterCallback( + PhGetGeneralCallback(GeneralCallbackThreadMenuInitializing), + ThreadMenuInitializingCallback, + NULL, + &ThreadMenuInitializingCallbackRegistration + ); } break; } @@ -157,6 +169,11 @@ VOID NTAPI MenuItemCallback( EtShowUnloadedDllsDialog(PhMainWndHandle, menuItem->Context); } break; + case ID_THREAD_CANCELIO: + { + EtUiCancelIoThread(menuItem->OwnerWindow, menuItem->Context); + } + break; } } @@ -197,3 +214,29 @@ VOID NTAPI ProcessMenuInitializingCallback( PhInsertEMenuItem(miscMenu, PhPluginCreateEMenuItem(PluginInstance, 0, ID_PROCESS_UNLOADEDMODULES, L"Unloaded Modules", processItem), -1); } } + +VOID NTAPI ThreadMenuInitializingCallback( + __in_opt PVOID Parameter, + __in_opt PVOID Context + ) +{ + PPH_PLUGIN_MENU_INFORMATION menuInfo = Parameter; + PPH_THREAD_ITEM threadItem; + ULONG insertIndex; + PPH_EMENU_ITEM menuItem; + + if (menuInfo->u.Thread.NumberOfThreads == 1) + threadItem = menuInfo->u.Thread.Threads[0]; + else + threadItem = NULL; + + if (menuItem = PhFindEMenuItem(menuInfo->Menu, 0, L"Resume", 0)) + insertIndex = PhIndexOfEMenuItem(menuInfo->Menu, menuItem) + 1; + else + insertIndex = 0; + + PhInsertEMenuItem(menuInfo->Menu, menuItem = PhPluginCreateEMenuItem(PluginInstance, 0, ID_THREAD_CANCELIO, + L"Cancel I/O", threadItem), insertIndex); + + if (!threadItem) menuItem->Flags |= PH_EMENU_DISABLED; +} diff --git a/2.x/trunk/plugins/ExtendedTools/resource.h b/2.x/trunk/plugins/ExtendedTools/resource.h index bd97d0700..a1a0aae11 100644 --- a/2.x/trunk/plugins/ExtendedTools/resource.h +++ b/2.x/trunk/plugins/ExtendedTools/resource.h @@ -5,13 +5,13 @@ #define ID_PROCESS_UNLOADEDMODULES 101 #define IDD_UNLOADEDDLLS 101 #define IDD_OBJALPCPORT 102 +#define ID_THREAD_CANCELIO 102 #define IDD_OBJTPWORKERFACTORY 103 #define IDC_LIST 1001 #define IDC_REFRESH 1002 #define IDC_SEQUENCENUMBER 1003 #define IDC_PORTCONTEXT 1004 #define IDC_WORKERTHREADSTART 1005 -#define IDC_WORKERTHREADSTART2 1006 #define IDC_WORKERTHREADCONTEXT 1006 // Next default values for new objects @@ -21,6 +21,6 @@ #define _APS_NEXT_RESOURCE_VALUE 103 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1006 -#define _APS_NEXT_SYMED_VALUE 102 +#define _APS_NEXT_SYMED_VALUE 103 #endif #endif diff --git a/2.x/trunk/plugins/ExtendedTools/thrdact.c b/2.x/trunk/plugins/ExtendedTools/thrdact.c new file mode 100644 index 000000000..33b116974 --- /dev/null +++ b/2.x/trunk/plugins/ExtendedTools/thrdact.c @@ -0,0 +1,65 @@ +/* + * Process Hacker Extended Tools - + * thread actions extensions + * + * Copyright (C) 2010 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 "extendedtools.h" +#include "resource.h" + +BOOLEAN EtUiCancelIoThread( + __in HWND hWnd, + __in PPH_THREAD_ITEM Thread + ) +{ + NTSTATUS status; + BOOLEAN cont = FALSE; + HANDLE threadHandle; + IO_STATUS_BLOCK isb; + + if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage( + hWnd, + L"end", + L"I/O for the selected thread", + NULL, + FALSE + )) + cont = TRUE; + + if (!cont) + return FALSE; + + if (NT_SUCCESS(status = PhOpenThread(&threadHandle, THREAD_TERMINATE, Thread->ThreadId))) + { + status = NtCancelSynchronousIoFile(threadHandle, NULL, &isb); + } + + if (status == STATUS_NOT_FOUND) + { + PhShowInformation(hWnd, L"There is no synchronous I/O to cancel."); + return FALSE; + } + else if (!NT_SUCCESS(status)) + { + PhShowStatus(hWnd, L"Unable to cancel synchronous I/O", status, 0); + return FALSE; + } + + return TRUE; +}