Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.07.08;
Скачать: CL | DM;

Вниз

Узнать о закрытии 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 вся ветка

Текущий архив: 2007.07.08;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.023 c
3-1176035051
skichyp
2007-04-08 16:24
2007.07.08
Как заставить БД понимать языки с кракозябрами (армянский и


2-1181923176
denissoft
2007-06-15 19:59
2007.07.08
Вопрос по базам Microsoft Access 2003


1-1178275582
zero
2007-05-04 14:46
2007.07.08
Узнать создана ли форма


6-1165828880
Rentgen
2006-12-11 12:21
2007.07.08
IdHTTP и Content-Transfer


2-1181993469
kotbazilio
2007-06-16 15:31
2007.07.08
Японские символы