Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 1 971

/ вопрос открыт /

Здравствуйте, эксперты!
Помогите пожалуйста!!! Как можно узнать о том, что начался процесс копирования файлов с жёсткого диска на какой-либо носитель информации? Если возможно, подскажите как запретить этот процесс копирования перед тем как он начался?

Малыш Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Малыш (статус: Посетитель)
Вопрос отправлен: 6 октября 2008, 02:24
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Feniks

Здравствуйте, Малыш!
Можно, но очень сложно. Вам надо копать в сторону FindFirstChangeNotification, FindNextChangeNotification, FindCloseChangeNotification вместе с WaitForSingleObject. А так же смотрите пример в приложении. В нем отслеживается создание/изменение/удаление файлов.

P.S. Желаю удачи.

Приложение:
  1. unit wfsU;
  2.  
  3. interface
  4.  
  5. type
  6.  
  7.  
  8. PInfoCallback = ^TInfoCallback;
  9. TInfoCallback = record
  10.  
  11.  
  12.  
  13.  
  14. end;
  15.  
  16.  
  17. TWatchFileSystemCallback = procedure (pInfo: TInfoCallback);
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25. procedure StartWatch(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallback: TWatchFileSystemCallback);
  26.  
  27. procedure StopWatch;
  28.  
  29. implementation
  30.  
  31. uses
  32. Classes, Windows, SysUtils;
  33.  
  34. const
  35. FILE_LIST_DIRECTORY = $0001;
  36.  
  37. type
  38. PFileNotifyInformation = ^TFileNotifyInformation;
  39. TFileNotifyInformation = record
  40. NextEntryOffset : DWORD;
  41. Action : DWORD;
  42. FileNameLength : DWORD;
  43. FileName : array[0..0] of WideChar;
  44. end;
  45.  
  46. WFSError = class(Exception);
  47.  
  48. TWFS = class(TThread)
  49. private
  50. FName : string;
  51. FFilter : Cardinal;
  52. FSubTree : boolean;
  53. FInfoCallback : TWatchFileSystemCallback;
  54. FWatchHandle : THandle;
  55. FWatchBuf : array[0..4096] of Byte;
  56. FOverLapp : TOverlapped;
  57. FPOverLapp : POverlapped;
  58. FBytesWritte : DWORD;
  59. FCompletionPort : THandle;
  60. FNumBytes : Cardinal;
  61. FOldFileName : string;
  62. function CreateDirHandle(aDir: string): THandle;
  63. procedure WatchEvent;
  64. procedure HandleEvent;
  65. protected
  66. procedure Execute; override;
  67. public
  68. constructor Create(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallback: TWatchFileSystemCallback);
  69. destructor Destroy; override;
  70. end;
  71.  
  72.  
  73. var
  74. WFS : TWFS;
  75.  
  76. procedure StartWatch(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallback: TWatchFileSystemCallback);
  77. begin
  78. WFS:=TWFS.Create(pName, pFilter, pSubTree, pInfoCallback);
  79. end;
  80.  
  81. procedure StopWatch;
  82. var
  83. Temp : TWFS;
  84. begin
  85. if Assigned(WFS) then
  86. begin
  87. PostQueuedCompletionStatus(WFS.FCompletionPort, 0, 0, nil);
  88. Temp := WFS;
  89. WFS:=nil;
  90. Temp.Terminate;
  91. end;
  92. end;
  93.  
  94. constructor TWFS.Create(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallback: TWatchFileSystemCallback);
  95. begin
  96. inherited Create(True);
  97. FreeOnTerminate:=True;
  98. FName:=IncludeTrailingBackslash(pName);
  99. FFilter:=pFilter;
  100. FSubTree:=pSubTree;
  101. FOldFileName:=EmptyStr;
  102. ZeroMemory(@FOverLapp, SizeOf(TOverLapped));
  103. FPOverLapp:=@FOverLapp;
  104. ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
  105. FInfoCallback:=pInfoCallback;
  106. Resume
  107. end;
  108.  
  109. destructor TWFS.Destroy;
  110. begin
  111. PostQueuedCompletionStatus(FCompletionPort, 0, 0, nil);
  112. CloseHandle(FWatchHandle);
  113. FWatchHandle:=0;
  114. CloseHandle(FCompletionPort);
  115. FCompletionPort:=0;
  116. inherited Destroy;
  117. end;
  118.  
  119. function TWFS.CreateDirHandle(aDir: string): THandle;
  120. begin
  121. Result:=CreateFile(PChar(aDir), FILE_LIST_DIRECTORY, FILE_SHARE_READ+FILE_SHARE_DELETE+FILE_SHARE_WRITE,
  122. nil,OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED, 0);
  123. end;
  124.  
  125. procedure TWFS.Execute;
  126. begin
  127. FWatchHandle:=CreateDirHandle(FName);
  128. WatchEvent;
  129. end;
  130.  
  131. procedure TWFS.HandleEvent;
  132. var
  133. FileNotifyInfo : PFileNotifyInformation;
  134. InfoCallback : TInfoCallback;
  135. Offset : Longint;
  136. begin
  137. Pointer(FileNotifyInfo) := @FWatchBuf[0];
  138. repeat
  139. Offset:=FileNotifyInfo^.NextEntryOffset;
  140. InfoCallback.FAction:=FileNotifyInfo^.Action;
  141. InfoCallback.FDrive:=FName;
  142. SetString(InfoCallback.FNewFileName,FileNotifyInfo^.FileName,FileNotifyInfo^.FileNameLength);
  143. InfoCallback.FNewFileName:=Trim(InfoCallback.FNewFileName);
  144. case FileNotifyInfo^.Action of
  145. FILE_ACTION_RENAMED_OLD_NAME: FOldFileName:=Trim(WideCharToString(@(FileNotifyInfo^.FileName[0])));
  146. FILE_ACTION_RENAMED_NEW_NAME: InfoCallback.FOldFileName:=FOldFileName;
  147. end;
  148. FInfoCallback(InfoCallback);
  149. PChar(FileNotifyInfo):=PChar(FileNotifyInfo)+Offset;
  150. until (Offset=0) or Terminated;
  151. end;
  152.  
  153. procedure TWFS.WatchEvent;
  154. var
  155. CompletionKey: Cardinal;
  156. begin
  157. FCompletionPort:=CreateIoCompletionPort(FWatchHandle, 0, Longint(pointer(self)), 0);
  158. ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
  159. if not ReadDirectoryChanges(FWatchHandle, @FWatchBuf, SizeOf(FWatchBuf), FSubTree,
  160. FFilter, @FBytesWritte, @FOverLapp, nil) then
  161. begin
  162. raise WFSError.Create(SysErrorMessage(GetLastError));
  163. Terminate;
  164. end else
  165. begin
  166. while not Terminated do
  167. begin
  168. GetQueuedCompletionStatus(FCompletionPort, FNumBytes, CompletionKey, FPOverLapp, INFINITE);
  169. if CompletionKey<>0 then
  170. begin
  171. Synchronize(HandleEvent);
  172. ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
  173. FBytesWritte:=0;
  174. ReadDirectoryChanges(FWatchHandle, @FWatchBuf, SizeOf(FWatchBuf), FSubTree, FFilter,
  175. @FBytesWritte, @FOverLapp, nil);
  176. end else Terminate;
  177. end
  178. end
  179. end;
  180.  
  181. end.
  182.  
  183.  
  184.  
  185.  
  186. procedure MyInfoCallback(pInfo: TInfoCallback);
  187. const
  188.  
  189. begin
  190. case pInfo.FAction of
  191.  
  192. [pInfo.FDrive+pInfo.FOldFileName,pInfo.FDrive+pInfo.FNewFileName]));
  193. else
  194. if pInfo.FAction<FILE_ACTION_RENAMED_OLD_NAME then
  195. Form1.Memo1.Lines.Add(Format(Action[pInfo.Faction], [pInfo.FDrive+pInfo.FNewFileName]));
  196. end;
  197. end;
  198.  
  199.  
  200. procedure TForm1.FormCreate(Sender: TObject);
  201. begin
  202.  
  203. StartWatch('C:', FILE_NOTIFY_CHANGE_DIR_NAME, True, @MyInfoCallback);
  204. end;
  205.  
  206. procedure TForm1.FormDestroy(Sender: TObject);
  207. begin
  208. StopWatch
  209. end;


Ответ отправил: Feniks (статус: Бакалавр)
Время отправки: 6 октября 2008, 12:11


Мини-форум вопроса

Всего сообщений: 6; последнее сообщение — 7 октября 2008, 20:58; участников в обсуждении: 3.
Вадим К

Вадим К (статус: Академик), 6 октября 2008, 11:00 [#1]:

Можно.
Зачечь сам процес - можно. А вот "не дать комироваться" - это уже лучше писать драйвера. А это уже не делфи...
Галочка "подтверждения прочтения" - вселенское зло.
Ученый

Ученый (статус: 8-ой класс), 6 октября 2008, 12:08 [#2]:

to Вадим К. А можно поподробнее, если это вас не затрудит, please...
Вадим К

Вадим К (статус: Академик), 6 октября 2008, 12:32 [#3]:

to Ученый
Как драйвер писать?
Галочка "подтверждения прочтения" - вселенское зло.
Ученый

Ученый (статус: 8-ой класс), 6 октября 2008, 20:06 [#4]:

to Вадим К. Как можно отследить процесс копирования файлов с жёсткого диска на какой-либо носитель информации?
Вадим К

Вадим К (статус: Академик), 6 октября 2008, 20:26 [#5]:

наиболее надёжно - написав драйвер. Но это не делфовская парафия.
Галочка "подтверждения прочтения" - вселенское зло.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 7 октября 2008, 20:58 [#6]:

Наиболее надежно - отключить в BIOS устройства со сменными носителями, порты USB и поставить суперпароль на BIOS. Но остается еще локальная сеть, WiFi, IrDA и т.д.
Если серьезно, то довольно проблематичная задача, например, рассмотрим след. ситуацию : пользователь запустил Word загрузил документ, делает сохранить как... на сменный носитель - это рассматривать как копирование файла с винчестера?А если он внес в документ какие-то изменения, то как быть, ведь это уже другой файл?

to Малыш - поищите лучше программку, управляющую доступом к локальным папкам. Либо не пускайте чужих за свой комп, чтобы не инфу не копировали.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 16:15
Выполнено за 0.01 сек.