Доброго времени суток. Возникла необходимось убивать хендл, принадлежащий чужому процессу. Что-то подобное делается в ProcessExplorer: есть процес и список хендлов принадлежащих ему, можна выбрать, скажем, file — \Device\Floppy0 и закрыть. Может кто подскажет, как это можно реализовать в своем коде. Известно, какой процес искать и известно как называется файл, хендл которого надо закрыть.
Здравствуйте, <Аноним>, Вы писали:
А>Доброго времени суток. Возникла необходимось убивать хендл, принадлежащий чужому процессу. Что-то подобное делается в ProcessExplorer: есть процес и список хендлов принадлежащих ему, можна выбрать, скажем, file — \Device\Floppy0 и закрыть. Может кто подскажет, как это можно реализовать в своем коде. Известно, какой процес искать и известно как называется файл, хендл которого надо закрыть.
А>Заранее спасибо.
Общая схема:
1) Внедряете dll в адресное пространство процесса, у которого нужно закрыть хэндл. Это можно сделать с помощью hooks(подробнее см. у Рихтера).
2) Каким-то образом получаете хэндл того файла
3) Закрываете его вызовом CloseHandle.
Как Вы будете искать хэндл в процессе я не знаю. Но наверное есть способы. Причём нужно обратить внимание на тот факт, что ХЭНДЛ и ОБЪЕКТ ядра ФАЙЛ это НЕ одно и тоже. У одного процесса может быть несколько хэндлов на один объект ядра файл. И у другого процесса может быть хэндл на этот же объект.
Здравствуйте, Zhukov, Вы писали:
Z>1) Внедряете dll в адресное пространство процесса, у которого нужно закрыть хэндл. Это можно сделать с помощью hooks(подробнее см. у Рихтера).
А никак нельзя без внедрениия в адресное пространство процесса, у которого нужно закрыть хэндл? например каким нибудь перечислением всех процесов и их хендлов? (ну, может это и не возможно, спрашиваю, как вариант ) Чтобы без внедрения dll обойтись.
Z> Причём нужно обратить внимание на тот факт, что ХЭНДЛ и ОБЪЕКТ ядра ФАЙЛ это НЕ одно и тоже. У одного процесса может быть несколько хэндлов на один объект ядра файл. И у другого процесса может быть хэндл на этот же объект.
Дело вот в чем, спулер печати держит хендл \Device\Parallel0. Другими словами держит открытым LPT1 порт. Понятно, объект ядра — драйвер устройства параллельного порта \Device\Parallel0 может иметь и другие хендлы и в этом и в других процессах. Верее если б мог, небыло б и проблемы. Этот файл открывается OPEN_EXISTING только один раз и пока не закроется, больше никто на него хендлов не получит. А мне надо этот хендл, вот и пытаюсь отобрать у спулера.
Кстати, если есть возможность более цивилизовано его отобрать (ну послать спулеру какое нибудь сообщение на эту тему), то если знаете, подскажите. Вариант остановки службы спулера конечно срабатывает, но в моем случае неприемлем по условию из-за побочных еффектов (долго срабатывает, нарушает работу печати и др.).
Здравствуйте, <Аноним>, Вы писали:
А>А никак нельзя без внедрениия в адресное пространство процесса, у которого нужно закрыть хэндл? например каким нибудь перечислением всех процесов и их хендлов? (ну, может это и не возможно, спрашиваю, как вариант ) Чтобы без внедрения dll обойтись.
Никак. Хэндлы объектов ядра ядра принадлежат только процессу. У процесса есть таблица хэндлов и функция CloseHandle закрывает хэндл именно в этой таблице процесса, из которого она вызывается. Поэтому, чтобы закрыть что-нибудь "ядерное" нужно вызвать функцию от имени процесса, которому принадлежит хэндл.
А>Дело вот в чем, спулер печати держит хендл \Device\Parallel0. Другими словами держит открытым LPT1 порт. Понятно, объект ядра — драйвер устройства параллельного порта \Device\Parallel0 может иметь и другие хендлы и в этом и в других процессах. Верее если б мог, небыло б и проблемы. Этот файл открывается OPEN_EXISTING только один раз и пока не закроется, больше никто на него хендлов не получит. А мне надо этот хендл, вот и пытаюсь отобрать у спулера.
А>Кстати, если есть возможность более цивилизовано его отобрать (ну послать спулеру какое нибудь сообщение на эту тему), то если знаете, подскажите. Вариант остановки службы спулера конечно срабатывает, но в моем случае неприемлем по условию из-за побочных еффектов (долго срабатывает, нарушает работу печати и др.).
Не знаю к сожалению. А если вы закроете хэндл, побочные эффекты не возникнут?
Здравствуйте, Zhukov, Вы писали:
Z>Хэндлы объектов ядра ядра принадлежат только процессу. У процесса есть таблица хэндлов и функция CloseHandle закрывает хэндл именно в этой таблице процесса, из которого она вызывается. Поэтому, чтобы закрыть что-нибудь "ядерное" нужно вызвать функцию от имени процесса, которому принадлежит хэндл.
Понятно. Наверное М.Руссинович тоже использует Hooks в handleEx (насколько я понимаю входит в ProcessExplorer от него же) чтобы получать хендлы всех процесов и закрывать их?
Z>А если вы закроете хэндл, побочные эффекты не возникнут?
Я экспериментировал — не возникают, кроме, конечно, случая, когда спулер печатает на принтер в данный порт. Тогда печать прерывается. А если остановить службу, то нарушается не только печать в данный порт, а все задания печати на все принтеры и даже сетевые. И не работают апишные функции связаные со спулером, а их в приложениях немало, даже таких, которые непостредственно ничего не печатают.