Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2007.07.08;
Скачать: [xml.tar.bz2];

Вниз

Узнать о закрытии handle   Найти похожие ветки 

 
MetalFan ©   (2006-11-21 14:50) [0]

есть такая программка, Unlocker.
она позволяет, на сколько я понимаю, закрывать окрытые другими процессами файлы...
как мне из своей программы узнать, что сторонняя программа взяла и закрыла хэндл открытого моей программой файла?
кроме периодических попыток обращения на чтение ничего в голову не приходит.
как можно "запретить" ей хозяйничать открытми в моем приложении
файлами?
з.ы. сайт программки http://ccollomb.free.fr/unlocker/index.htm


 
Rouse_ ©   (2006-11-21 14:59) [1]

Она работает через драйвер - с драйвером может поспорить только еще один драйвер, поэтому не запретишь. А по поводу реакции на момент разблокирования, лови изменения через ReadDirectoryChangesW


 
MetalFan ©   (2006-11-21 16:36) [2]

хм... надо поискать примеры...


 
MetalFan ©   (2006-11-21 22:12) [3]

а какое событие возникает в данном случае?


 
Джо ©   (2006-11-21 22:16) [4]

> [3] MetalFan ©   (21.11.06 22:12)
> а какое событие возникает в данном случае?

Никакого.


 
BiN ©   (2006-11-21 22:21) [5]

Для отслеживания закрытия хэндла файла можно пойти немного неуклюжим, но рабочим путем - WaitForSingleObject


 
Rouse_ ©   (2006-11-21 22:24) [6]

>  какое событие возникает в данном случае?
Товарищь, вы находитесь в конференции АПИ, события - это часть модели ООП :) А вот нотификацию в калбеке можно поймать на FILE_NOTIFY_CHANGE_LAST_ACCESS


 
MetalFan ©   (2006-11-22 12:27) [7]


> нотификацию в калбеке

сорри, именно так) не правильно выразился.

вот нашел несколько примеров
unction ReadDirectoryChangesW(
 hDirectory: THandle; // описатель каталога, за которым надо следить
 lpBuffer: Pointer;  // Указатель на буфер, в который будет записана информация
 nBufferLength: DWORD; // Размер буфера
 bWatchSubtree: Bool; // Следить ли за подкаталогами
 dwNotifyFilter: DWORD; // Фильтр действий
 lpBytesReturned: LPDWORD; // Сколько было записано в буфер
 lpOverlapped: POverlapped; // Для асинхронной работы
 lpCompletionRoutine: FARPROC // Функция, которая будет вызвана при окончании операции
 ): BOOL; stdcall;
procedure WorkThread(LV: TListView); stdcall;
procedure WorkThread(LV : TListView);stdcall;
var
hDir : THandle;
lpBuf : Pointer;
Ptr   : Pointer;
cbReturn : Cardinal;
FileName : PWideChar;
Item : TListItem;
sTime : _SYSTEMTIME;
begin
// Сначала нам надо получить описатель каталога, за которым мы будем следить
// В данном примере это будет весь диск C:
hDir := CreateFile ("C:\",GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE
  or FILE_SHARE_DELETE,nil,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
// Если ошиблись...
if hDir = INVALID_HANDLE_VALUE
 then begin ShowMessage(SysErrorMessage(GetLastError)); exit; end;
// Выделяем память под буфер
// const BUF_SIZE = 2048 - думаю вполне достаточно
GetMem(lpBuf,BUF_SIZE);
repeat
 // очищаем память перед записью в нее (на всякий случай)
 ZeroMemory(lpBuf,BUF_SIZE);
 // Теперь мы будем ждать пока чего-нибудь в интересующем нас каталоге
 // изменится или произойдет ошибка (и мы выйдем из цикла)
 // FILE_NOTIFY_CHANGE - это список флагов
 if not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true,
                  FILE_NOTIFY_CHANGE,@cbReturn,nil,nil)
  then Break;
 // Сюда мы попадаем, если функция выполнилась успешно
 // и lpBuf указывает на одну или несколько структур FILE_NOTIFY_INFORMATION
 Ptr:=lpBuf;
repeat
  // Добавляем новый элемент в TListView (ViewStyle = vsReport )
  Item := LV.Items.Add;
  // Выделяем память под имя файла
  GetMem(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
  // Очищаем память - чтобы последним символом после копирования
  // был бы #0 нуль
  ZeroMemory(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
  // WinAPI функция для копирования Unicode строки
  lstrcpynW(FileName,PFileNotifyInformation(Ptr).FileName,
            PFileNotifyInformation(Ptr).FileNameLength div 2+1);
  // Имя файла у нас дается относительно папки
  // т.е.если изменится файл C:\File\test.dat, то FileName
  // будет равно File\test.dat
  Item.Caption:="C:\"+FileName;
  // Имя файла нам больше не нужно - очищаем память
  FreeMem(FileName);
  // Определяем тип произошедшего действия
  case PFileNotifyInformation(Ptr).Action of
   FILE_ACTION_ADDED    : Item.SubItems.Add("Файл был создан");
   FILE_ACTION_REMOVED  : Item.SubItems.Add("Файл был удален");
   FILE_ACTION_MODIFIED : Item.SubItems.Add("Файл был изменен");
   FILE_ACTION_RENAMED_OLD_NAME :
  Item.SubItems.Add("Файл был переименован и в имени файла - предыдущее имя");
   FILE_ACTION_RENAMED_NEW_NAME :
 Item.SubItems.Add("новое имя после переименования");
   else Item.SubItems.Add("Произошло что-то странное");
  end;
  // Время, когда произошло событие
  GetLocalTime(sTime);
  with sTime do
   Item.SubItems.Add(Format("%.2d:%.2d:%.2d",[wHour,wMinute,wSecond])); // 13:54:20
  // Если эта запись не последняя (NextEntryOffset < >  0), то...
  if PFileNotifyInformation(Ptr).NextEntryOffset=0
   then Break
    else begin
  // ... добавляем строку в примечания (если интересно посмотреть смещение)
     Item.SubItems.Add("Offset : "+
      IntToStr(PFileNotifyInformation(Ptr).NextEntryOffset));
  //Передвигаем указатель на NextEntryOffset байт вперед
     Inc(Cardinal(Ptr),PFileNotifyInformation(Ptr).NextEntryOffset);
  // Теперь Ptr указывает на следующую запись
    end;
 // Передвигать надо именно Ptr, а не lpBuf
 until false;
until false;
// Очищаем память
FreeMem(lpBuf);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ThID : Cardinal;
begin
// hThread - THandle - глобальная переменная
// Создаем поток
// LV - TListView, WorkThread - функция выше
hThread:=CreateThread(nil,0,@WorkThread,LV,0,ThID);
// В случае неудачи выводим сообщение
if hThread=0 then ShowMessage(SysErrorMessage(GetLastError));
end


и

var
 Dir : string = "C:\"; \\ имя каталога
 SubDirs : boolean; \\ следить за подкаталогами ?
type
 FILE_NOTIFY_INFORMATION = record
   NextEntryOffset: DWORD;
   Action: DWORD;
   FileNameLength: DWORD;
   FileName: array [0..0] of WCHAR;
 end;
var
 hDir : THandle;
 Buf : pointer;
 Returned, BufSize : dword;
 adr : DWORD;
 fni : ^FILE_NOTIFY_INFORMATION absolute adr;
 s : string;
 ws : WideString;
const
 wcs = SizeOf(WideChar); // = 2
 FILE_LIST_DIRECTORY       = ($0001); // directory
begin
 hDir := CreateFile(PChar(Dir),
                    FILE_LIST_DIRECTORY,
                    FILE_SHARE_READ or FILE_SHARE_DELETE,
                    nil,
                    OPEN_EXISTING,
                    FILE_FLAG_BACKUP_SEMANTICS,
                    0);
 if hDir = INVALID_HANDLE_VALUE then Exit;
 BufSize := 16*1024*1024; // 16 mb
 GetMem(Buf, BufSize);
 repeat
   if ReadDirectoryChangesW(hDir, Buf, BufSize, SubDirs,
      FILE_NOTIFY_CHANGE_FILE_NAME or
      FILE_NOTIFY_CHANGE_DIR_NAME or
      FILE_NOTIFY_CHANGE_ATTRIBUTES or
      FILE_NOTIFY_CHANGE_SIZE or
      FILE_NOTIFY_CHANGE_LAST_WRITE or
      FILE_NOTIFY_CHANGE_LAST_ACCESS or
      FILE_NOTIFY_CHANGE_CREATION or
      FILE_NOTIFY_CHANGE_SECURITY, @Returned, nil, nil) then
   begin
     Adr := Cardinal(Buf);
     while Adr < (Cardinal(Buf) + Returned) do
     begin
       case fni^.Action of
         FILE_ACTION_ADDED            : s := "Added";
         FILE_ACTION_REMOVED          : s := "Removed";
         FILE_ACTION_MODIFIED         : s := "Modified";
         FILE_ACTION_RENAMED_OLD_NAME : s := "Renamed from";
         FILE_ACTION_RENAMED_NEW_NAME : s := "Renamed to";
         else s := "0x" + IntToHex(fni^.Action, 8);
       end;
       SetLength(ws, fni^.FileNameLength div wcs);
       Move(fni^.FileName, ws[1], fni^.FileNameLength);
       ListBox1.Items.Add(s + " "" + ws + """);
       Inc(adr, fni^.FileNameLength - wcs + SizeOf(fni^));
     end;
   end;
 until False;
 CloseHandle(hDir);
 FreeMem(Buf);
end


первый не нравится, что лезут из потока к LV,
а второй вроде как "ловит" только одно "событие"


 
prisoner849 ©   (2007-01-28 00:40) [8]

кстати, фукнция ReadDirectoryChangesW "не работает" с сетевыми папками, если размер буфера > 64 kB
любопытно, что в справке Win32 Programmer"s Reference об этом не упоминается...
пришлось рыть MSDN ;)


 
GrayFace ©   (2007-01-28 16:32) [9]

prisoner849 ©   (28.01.07 0:40) [8]
любопытно, что в справке Win32 Programmer"s Reference об этом не упоминается...

Это далеко не единственное, о чем там не упоминается.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2007.07.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.04 c
15-1181393189
Nucer
2007-06-09 16:46
2007.07.08
Разрешено ли испольовать BlowFish?


2-1181889608
Баян 555
2007-06-15 10:40
2007.07.08
перевод в читабельный вид


2-1181726745
Клара
2007-06-13 13:25
2007.07.08
Excel


2-1181835730
SerMaxx
2007-06-14 19:42
2007.07.08
Работа с Exel из Delphi


15-1181109052
Игорь Шевченко
2007-06-06 09:50
2007.07.08
Компания Codegear Borland проводит семинары





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский