PDA

Показать полную графическую версию : [решено] Получение списка хендлов к файлу


Raistlin
24-05-2005, 18:40
Как через Win32 узнать, есть ли открытые хендлы у файла? Хочется узнать, получится ли удалить файл, не производя собственно попытки его стереть.

hasherfrog
26-05-2005, 12:15
Обязательно самому писать? Если нет, советую:
http://www.sysinternals.com/ntw2k/freeware/handle.shtml
Ну и это можно посмотреть:
http://www.sysinternals.com/ntw2k/source/filemon.shtml

Raistlin
06-09-2005, 14:02
Handle выдаёт неполные данные. Возьмём, к примеру, nnCron (http://www.nncron.ru/). У него в составе библиотека есть, которая, очевидно, отвечает за отображение контекстного меню, — nnhook.dll. Если в сеансе работы вызвать контекстное меню, то до перезагрузки этот файл удалить невозможно. Но Handle никаких данных о хендлах к нему не выдаёт. Или я что-то недопонимаю здесь просто?

DillerInc
06-09-2005, 15:21
Raistlin
Или я что-то недопонимаю здесь просто?
...вот я тоже сейчас возможно чего-то недопонимаю,но почему бы не воспользоваться API-функцией EnumProcessModules (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/enumprocessmodules.asp) ?
Ведь насколько я понял,под "открытым файлом" ты подразумеваешь некоторый запущенный исполняемый файл (.exe)... :huh:

Raistlin
06-09-2005, 17:07
подразумеваешь некоторый запущенный исполняемый файл (.exe)
Нет, как раз не exe, "запущенность" exe проверить-то легко. А меня интересует "залоченность" файла, а именно dll. Такую информацию возможно получить с помощью этой функции? Если да, не мог бы ты объяснить на примере — как должна вызываться функция и как проинтерпретировать результат? А то сер я совсем в этом, тыкаюсь, как слепой котёнок… Заранее спасибо!

SergeCpp
07-09-2005, 07:03
А попробуй его открыть — Exclusive... (for r/w and w/o sharing flags)

Я так проверяю в аналогичной ситуации.

DillerInc
07-09-2005, 15:48
Raistlin
Теперь я вроде понял,что ты имеешь в виду (невозможность удаления библиотеки пока не перезагрузишь систему).
Значит,функция EnumProcessModules лишь перечисляет все модули,загруженные в адресное пространство конкретного процесса.
В твоём же случае необходимо,на мой взгляд,смотреть атрибуты файла, т.е. возможно,что у этой библиотеки выставлен атрибут FILE_ATTRIBUTE_READONLY ,который означает,что приложения не могут ни писать в этот файл,ни удалять его.
К примеру:

var
fAttrs : DWORD;
fName : LPCTSTR;
begin
fAttrs := GetFileAttributes('nnhook.dll');
if fAttrs = FILE_ATTRIBUTE_READONLY then
begin
SetFileAttributes('nnhook.dll', FILE_ATTRIBUTE_NORMAL);
end;
end;

...попробуй,может это поможет.

P.S. Если тебе всё-таки понадобится пример кода функции EnumProcessModules,напиши - приведём :) .

Raistlin
07-09-2005, 17:18
Я воспользовался советом SergeCpp, вроде получилось:
CreateFile(filename, GENERIC_WRITE, 1, 0, OPEN_EXISTING, 0, 0)
Возвращает -1, если файл заблокирован или с ним что-то не так, или хендл к нему, если можно открыть эксклюзивно на запись. Само собой, в последнем случае вызываем CloseHandle.

SergeCpp
07-09-2005, 17:59
А спасибо...

Ладно уж, я так, к слову...

Raistlin
08-09-2005, 15:57
Прощу прощения! Конечно, большое спасибо. Я долго раздумывал, писать такое неинформативное сообщение или нет :), решил — не буду, так как в предыдущем посте я поблагодарил заранее. Надеюсь, ты меня простишь :sorry:.
А вот и кое-что по теме. Похоже, проверить каталог на залоченность таким образом нельзя:
CreateFile(dirname, GENERIC_WRITE, 1, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
возвращает хендл к каталогу, который открыт, скажем, в Far и удалён быть не может. Есть идеи?

Raistlin
08-09-2005, 16:24
Ага, здесь как раз может помочь Handle. Правда, есть одна проблема: он рассматривает хендлы только к реальным каталогам — символических связей не понимает. Есть ли способ узнать реальный путь, на который указывает символическая связь?

SergeCpp
08-09-2005, 18:21
Там надо поколдовать с SHARING'ами при открытии каталога,
так как это не обычный файл (ну да, обычный, но не совсем)

Посмотри в MSDN... И о Symbolic Link & Hard Link...

P.S. Насчёт "заранее спасибо"

мягко говоря, это не совсем...

про это есть даже статья в "Elements of Style"

Raistlin
08-09-2005, 19:03
Точно! Не тот флаг выставлял. Вот итоговые варианты:
CreateFile(filename, GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)
CreateFile(dirname, GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
Ещё раз спасибо!

Raistlin
21-10-2005, 16:59
Важная ремарка: если файл имеет атрибут read-only, открыть его эксклюзивно на запись тоже не получится. Надо снимать атрибут, открывать файл, потом снова устанавливать атрибут.




© OSzone.net 2001-2012