Если вы хотите предотвратить завершение процесса, один из способов — подключиться к TerminateProcess (или NtTerminateProcess). Если процесс завершается (например, из-за того, что вы закрыли его окно), дескриптор, предоставленный этим функциям, равен NULL, поэтому вы можете узнать, какой исполняемый файл завершается, используя GetCurrentProcess() и GetModuleFileNameEx(). Поскольку GetCurrentProcess() возвращает псевдодескриптор, вы можете получить к нему доступ без проблем.
Однако если один процесс завершает другой, предоставленный дескриптор не равен NULL. Он представляет завершение процесса. Проблема в том, что вы не можете получить информацию об этом процессе. Вы можете просто вернуть код с сообщением «отказано в доступе» вместо вызова оригинального [Nt]TerminateProcess(), но это одеяло не позволяет всем процессам завершать другие, что является плохой идеей.
Дескриптор должен представлять что-то действительное, иначе TerminateProcess не сможет сделать с ним ничего полезного, но я даже не могу вызвать для него GetProcessId(), я получаю ERROR_INVALID_HANDLE (или ERROR_ACCESS_DENIED). Я пробовал различные методы, которые я собрал из справки и из Интернета, включая получение привилегии отладки (успех) и DuplicateHandle() (та же ошибка) и ZwQueryInformationProcess() для получения идентификатора (STATUS_ACCESS_DENIED). Я даже не могу перечислить процессы, потому что они возвращают идентификаторы, а я не могу получить идентификатор, а OpenProcess() всегда возвращает новый дескриптор, поэтому я не могу сравнивать дескрипторы.
Я могу только предположить, что дескриптор имеет право PROCESS_TERMINATE и ничего больше. Я знаю, что Vista и более поздние версии имеют защищенные процессы благодаря управлению цифровыми правами, но я использую ProcessExplorer в качестве подопытного кролика, так что это определенно не мультимедийное приложение!
Кто-нибудь знает, как еще я мог бы получить какую-либо информацию о завершении процесса из этого дескриптора?