суббота, 12 марта 2011 г.

Приостановка и возобновление процессов

   Механизм приостановки и возобновления потоков в Windows есть. А как насчет процессов?


   Вообще говоря, понятия "приостановка" и "возобновление" к процессам неприменимы. Процессы не принимают участия в планировании и распределении времени процессора. Поэтому корректнее говорить "приостановка и возобновление всех потоков процесса".

   Это можно сделать из другого процесса, причем этот второй процесс должен быть отладчиком первого. А может можно как-то попроще? Ведь, например, в утилите Process Explorer есть возможность сделать Suspend/Resume процессу.

   Можно конечно, с помощью ToolHelp API перечислить все потоки требуемого процесса и каждому из них сделать Suspend/Resume. Но такая реализация не будет идеальной - ведь во время перечисления некоторые потоки могут завершиться, или наоборот - могут быть созданы новые. Или вообще процесс может быть завершен.

   Начиная с Windows XP в ядре появились функции NtSuspendProcess и NtResumeProcess, которые, как не трудно догадаться по их названию, могут приостанавливать и возобновлять все потоки процесса (и именно их использует Process Explorer). Функции внутренние и недокументированные, аналогов в Win32 API не имеют. Но если сильно нужно, то ими вполне можно воспользоваться :)

   Вот как выглядят объявления для переходников из ntdll.dll
  function NtSuspendProcess(ProcessHandle: THandle): NTSTATUS; stdcall; 
  function NtResumeProcess(ProcessHandle: THandle): NTSTATUS; stdcall;

   Эти функции лишены недостатков реализации через ToolHelp API - перед тем, как обойти все потоки процесса и сделать им Suspend/Resume, захватывается блокировка Process->RundownProtect. Она не позволяет ни уничтожиться процессу, ни создать в нем новый поток, ни завершиться существующему, пока эта блокировка не будет освобождена.

Ссылки
[1] Suspending processes in Windows, part 1

Комментариев нет:

Отправить комментарий