|
Вопрос # 944/ вопрос открыт / |
|
Здравствуйте, эксперты! Подскажите пожалуйста, как можно определить, что началось копирование или перемещение данных в Windows? Можно ли определить что, откуда и куда копируется или перемещается?
 |
Вопрос задал: alone (статус: Посетитель)
Вопрос отправлен: 28 сентября 2007, 23:02
Состояние вопроса: открыт, ответов: 2.
|
Ответ #1. Отвечает эксперт: Грег Леонов
Доброе утро, Олег!
Тут однозначно нужно использовать WinAPI.
А вообще считаю что отследить "все" записи в Windows - ресурсоемкая операция. Т.к. Windows постоянно что-то пишет на диск(правда постоянно новые файлы не создает).
http://download.sysinternals.com/Files/Filemon.zip - прога чтоб отследить все операции с файловой системой в ОС.
Я сам в WinAPI не очень хорошо разбираюсь, но поюзав google, нашел код реализации поиска изменений в файловой системе с помощью WinAPI.
Приложение: Переключить в обычный режим- program file_seeker;
-
- {$APPTYPE CONSOLE}
-
- uses
- SysUtils, windows, tintlist;
-
- type
- NTStatus = cardinal;
- PVOID = pointer;
- USHORT = WORD;
- UCHAR = byte;
- PWSTR = PWideChar;
-
-
- STATUS_SUCCESS = NTStatus($00000000);
- STATUS_ACCESS_DENIED = NTStatus($C0000022);
- STATUS_INFO_LENGTH_MISMATCH = NTStatus($C0000004);
- SEVERITY_ERROR = NTStatus($C0000000);
-
- const SystemHandleInformation = 16;
- OB_TYPE_FILE = 28;
-
- type
- PClientID = ^TClientID;
- TClientID = packed record
- UniqueProcess:cardinal;
- UniqueThread:cardinal;
- end;
-
- PUnicodeString = ^TUnicodeString;
- TUnicodeString = packed record
- Length: Word;
- MaximumLength: Word;
- Buffer: PWideChar;
- end;
-
- PSYSTEM_HANDLE_INFORMATION = ^SYSTEM_HANDLE_INFORMATION;
- SYSTEM_HANDLE_INFORMATION = packed record
- ProcessId: dword;
- ObjectTypeNumber: byte;
- Flags: byte;
- Handle: word;
- pObject: pointer;
- GrantedAccess: dword;
- end;
-
- PSYSTEM_HANDLE_INFORMATION_EX = ^SYSTEM_HANDLE_INFORMATION_EX;
- SYSTEM_HANDLE_INFORMATION_EX = packed record
- NumberOfHandles: dword;
- Information: array [0..0] of SYSTEM_HANDLE_INFORMATION;
- end;
-
- Function ZwQuerySystemInformation(ASystemInformationClass: dword;
- ASystemInformation: Pointer;
- ASystemInformationLength: dword;
- AReturnLength:PCardinal): NTStatus;
- stdcall;external 'ntdll.dll';
-
-
- function EnablePrivilegeEx(Process: dword; lpPrivilegeName: PChar):Boolean;
- var
- hToken: dword;
- NameValue: Int64;
- tkp: TOKEN_PRIVILEGES;
- ReturnLength: dword;
- begin
- Result:=false;
-
- OpenProcessToken(Process, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);
-
- if not LookupPrivilegeValue(nil, lpPrivilegeName, NameValue) then
- begin
- CloseHandle(hToken);
- exit;
- end;
- tkp.PrivilegeCount := 1;
- tkp.Privileges[0].Luid := NameValue;
- tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
-
- AdjustTokenPrivileges(hToken, false, tkp, SizeOf(TOKEN_PRIVILEGES), tkp, ReturnLength);
- if GetLastError() <> ERROR_SUCCESS then
- begin
- CloseHandle(hToken);
- exit;
- end;
- Result:=true;
- CloseHandle(hToken);
- end;
-
-
- function EnablePrivilege(lpPrivilegeName: PChar):Boolean;
- begin
- Result := EnablePrivilegeEx(INVALID_HANDLE_VALUE, lpPrivilegeName);
- end;
-
-
-
- function EnableDebugPrivilegeEx(Process: dword):Boolean;
- begin
- Result := EnablePrivilegeEx(Process, 'SeDebugPrivilege');
- end;
-
-
- function EnableDebugPrivilege():Boolean;
- begin
- Result := EnablePrivilegeEx(INVALID_HANDLE_VALUE, 'SeDebugPrivilege');
- end;
-
-
- Function GetInfoTable(ATableType:dword):Pointer;
- var
- mSize: dword;
- mPtr: pointer;
- St: NTStatus;
- begin
- Result := nil;
-
- repeat
- mPtr := VirtualAlloc(nil, mSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
- if mPtr = nil then Exit;
- St := ZwQuerySystemInformation(ATableType, mPtr, mSize, nil);
- if St = STATUS_INFO_LENGTH_MISMATCH then
-
- VirtualFree(mPtr, 0, MEM_RELEASE);
- mSize := mSize * 2;
- end;
- until St <> STATUS_INFO_LENGTH_MISMATCH;
- if St = STATUS_SUCCESS
- then Result := mPtr
- else VirtualFree(mPtr, 0, MEM_RELEASE);
- end;
-
- var
- HandlesInfo: PSYSTEM_HANDLE_INFORMATION_EX;
- r: integer;
- hProcess, tHandle: dword;
- file_h: tintegerlist;
- begin
-
- file_h := tintegerlist.Create;
-
- EnableDebugPrivilege();
- HandlesInfo := GetInfoTable(SystemHandleInformation);
- for r := 0 to HandlesInfo^.NumberOfHandles do
- if HandlesInfo^.Information[r].ObjectTypeNumber = OB_TYPE_FILE then
- begin
- file_h.Add(HandlesInfo^.Information[r].Handle);
- end;
-
- VirtualFree(HandlesInfo, 0, MEM_RELEASE);
-
-
- while true do
- begin
- Sleep(200);
-
- HandlesInfo := GetInfoTable(SystemHandleInformation);
- for r := 0 to HandlesInfo^.NumberOfHandles do
- if HandlesInfo^.Information[r].ObjectTypeNumber = OB_TYPE_FILE then
- begin
- if file_h.IndexOf(HandlesInfo^.Information[r].Handle)=-1 then
- begin
- file_h.Add(HandlesInfo^.Information[r].Handle);
- writeln(HandlesInfo^.Information[r].Handle, ' - added a file handle');
- end;
- end;
-
- VirtualFree(HandlesInfo, 0, MEM_RELEASE);
- end;
-
- readln;
-
- end.
-
-
 |
Ответ отправил: Грег Леонов (статус: 1-ый класс)
Время отправки: 29 сентября 2007, 00:47
Оценка за ответ: 4
|
Ответ #2. Отвечает эксперт: Feniks
Здравствуйте, Гадлевский Олег Вячеславович!
Сам я не пробовал, но пару примеров нашел. См. в приложении.
Приложение: Переключить в обычный режим-
-
- unit Unit1;
-
- {cDrkb v.3(2007): www.drkb.ru}
-
- interface
-
- uses
-
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls;
-
- type
-
- PFileNotifyInformation = ^TFileNotifyInformation;
- TFileNotifyInformation = record
- NextEntryOffset: DWORD;
- Action: DWORD;
- FileNameLength: DWORD;
- FileName: array [0..MAX_PATH - 1] of WideChar;
- end;
-
- TForm1 = class(TForm)
- Memo1: TMemo;
- procedure FormCreate(Sender: TObject);
- end;
-
- var
-
- Form1: TForm1;
-
- implementation
-
- {$R *.dfm}
-
- procedure TForm1.FormCreate(Sender: TObject);
- const
- Filter = 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;
- var
-
- Dir: THandle;
- Notify: TFileNotifyInformation;
- BytesReturned: DWORD;
-
- begin
- Dir := CreateFile('d:', GENERIC_READ,
- FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
- nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
- if Dir <> INVALID_HANDLE_VALUE then
- try
- if not ReadDirectoryChangesW(Dir, @Notify, SizeOf(TFileNotifyInformation),
- False, Filter, @BytesReturned, nil, nil) then
- raise Exception.Create(SysErrorMessage(GetLastError))
- else
- case Notify.Action of
- FILE_ACTION_ADDED: ShowMessage('New file' + Notify.FileName);
- FILE_ACTION_REMOVED: ShowMessage('Delete file' + Notify.FileName);
- FILE_ACTION_MODIFIED: ShowMessage('Modify file' + Notify.FileName);
- FILE_ACTION_RENAMED_OLD_NAME: ShowMessage('Old Name file' + Notify.FileName);
- FILE_ACTION_RENAMED_NEW_NAME: ShowMessage('New Name file' + Notify.FileName);
- end;
- finally
- CloseHandle(Dir);
- end;
- end;
- end.
-
- ====================================================
-
-
-
- unit wfsU;
-
- interface
-
- type
-
-
-
- PInfoCallback = ^TInfoCallback;
- TInfoCallback = record
-
-
-
-
- end;
-
-
-
- TWatchFileSystemCallback = procedure (pInfo: TInfoCallback);
-
-
-
-
-
-
-
- procedure StartWatch(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallback:
TWatchFileSystemCallback);
-
-
-
- procedure StopWatch;
-
- implementation
-
- uses
-
- Classes, Windows, SysUtils;
-
- const
-
- FILE_LIST_DIRECTORY = $0001;
-
- type
-
- PFileNotifyInformation = ^TFileNotifyInformation;
- TFileNotifyInformation = record
- NextEntryOffset : DWORD;
- Action : DWORD;
- FileNameLength : DWORD;
- FileName : array[0..0] of WideChar;
- end;
-
- WFSError = class(Exception);
-
- TWFS = class(TThread)
- private
- FName : string;
- FFilter : Cardinal;
- FSubTree : boolean;
- FInfoCallback : TWatchFileSystemCallback;
- FWatchHandle : THandle;
- FWatchBuf : array[0..4096] of Byte;
- FOverLapp : TOverlapped;
- FPOverLapp : POverlapped;
- FBytesWritte : DWORD;
- FCompletionPort : THandle;
- FNumBytes : Cardinal;
- FOldFileName : string;
- function CreateDirHandle(aDir: string): THandle;
- procedure WatchEvent;
- procedure HandleEvent;
- protected
- procedure Execute; override;
- public
- constructor Create(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallback:
TWatchFileSystemCallback);
- destructor Destroy; override;
- end;
-
-
- var
-
- WFS : TWFS;
-
- procedure StartWatch(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallback:
TWatchFileSystemCallback);
- begin
- WFS:=TWFS.Create(pName, pFilter, pSubTree, pInfoCallback);
- end;
-
- procedure StopWatch;
- var
- Temp : TWFS;
- begin
- if Assigned(WFS) then
- begin
- PostQueuedCompletionStatus(WFS.FCompletionPort, 0, 0, nil);
- Temp := WFS;
- WFS:=nil;
- Temp.Terminate;
- end;
- end;
-
- constructor TWFS.Create(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallback:
TWatchFileSystemCallback);
- begin
- inherited Create(True);
- FreeOnTerminate:=True;
- FName:=IncludeTrailingBackslash(pName);
- FFilter:=pFilter;
- FSubTree:=pSubTree;
- FOldFileName:=EmptyStr;
- ZeroMemory(@FOverLapp, SizeOf(TOverLapped));
- FPOverLapp:=@FOverLapp;
- ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
- FInfoCallback:=pInfoCallback;
- Resume
- end;
-
- destructor TWFS.Destroy;
- begin
- PostQueuedCompletionStatus(FCompletionPort, 0, 0, nil);
- CloseHandle(FWatchHandle);
- FWatchHandle:=0;
- CloseHandle(FCompletionPort);
- FCompletionPort:=0;
- inherited Destroy;
- end;
-
- function TWFS.CreateDirHandle(aDir: string): THandle;
- begin
- Result:=CreateFile(PChar(aDir), FILE_LIST_DIRECTORY,
FILE_SHARE_READ+FILE_SHARE_DELETE+FILE_SHARE_WRITE,
- nil,OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED, 0);
- end;
-
- procedure TWFS.Execute;
- begin
- FWatchHandle:=CreateDirHandle(FName);
- WatchEvent;
- end;
-
- procedure TWFS.HandleEvent;
- var
- FileNotifyInfo : PFileNotifyInformation;
- InfoCallback : TInfoCallback;
- Offset : Longint;
- begin
- Pointer(FileNotifyInfo) := @FWatchBuf[0];
- repeat
- Offset:=FileNotifyInfo^.NextEntryOffset;
- InfoCallback.FAction:=FileNotifyInfo^.Action;
- InfoCallback.FDrive:=FName;
- SetString(InfoCallback.FNewFileName,FileNotifyInfo^.FileName,FileNotifyInfo^.FileNameLength);
- InfoCallback.FNewFileName:=Trim(InfoCallback.FNewFileName);
- case FileNotifyInfo^.Action of
- FILE_ACTION_RENAMED_OLD_NAME:
FOldFileName:=Trim(WideCharToString(@(FileNotifyInfo^.FileName[0])));
- FILE_ACTION_RENAMED_NEW_NAME: InfoCallback.FOldFileName:=FOldFileName;
- end;
- FInfoCallback(InfoCallback);
- PChar(FileNotifyInfo):=PChar(FileNotifyInfo)+Offset;
- until (Offset=0) or Terminated;
- end;
-
- procedure TWFS.WatchEvent;
- var
- CompletionKey: Cardinal;
- begin
- FCompletionPort:=CreateIoCompletionPort(FWatchHandle, 0, Longint(pointer(self)), 0);
- ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
- if not ReadDirectoryChanges(FWatchHandle, @FWatchBuf, SizeOf(FWatchBuf), FSubTree,
- FFilter, @FBytesWritte, @FOverLapp, nil) then
- begin
- raise WFSError.Create(SysErrorMessage(GetLastError));
- Terminate;
- end else
- begin
- while not Terminated do
- begin
- GetQueuedCompletionStatus(FCompletionPort, FNumBytes, CompletionKey, FPOverLapp, INFINITE);
- if CompletionKey<>0 then
- begin
- Synchronize(HandleEvent);
- ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
- FBytesWritte:=0;
- ReadDirectoryChanges(FWatchHandle, @FWatchBuf, SizeOf(FWatchBuf), FSubTree, FFilter,
- @FBytesWritte, @FOverLapp, nil);
- end else Terminate;
- end
- end
- end;
-
- end.
-
-
-
-
- unit Unit1;
- interface
- uses
-
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-
- Dialogs, StdCtrls;
-
- type
-
- TForm1 = class(TForm)
- Memo1: TMemo;
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
-
- var
-
- Form1: TForm1;
-
- implementation
-
- {$R *.dfm}
-
- uses wfsU;
-
- procedure MyInfoCallback(pInfo: TInfoCallback);
- const
-
- begin
- case pInfo.FAction of
-
- [pInfo.FDrive+pInfo.FOldFileName,pInfo.FDrive+pInfo.FNewFileName]));
- else
- if pInfo.FAction<FILE_ACTION_RENAMED_OLD_NAME then
- Form1.Memo1.Lines.Add(Format(Action[pInfo.Faction], [pInfo.FDrive+pInfo.FNewFileName]));
- end;
- end;
-
- procedure TForm1.FormCreate(Sender: TObject);
- begin
-
- StartWatch('C:', FILE_NOTIFY_CHANGE_DIR_NAME, True, @MyInfoCallback);
- end;
-
- procedure TForm1.FormDestroy(Sender: TObject);
- begin
- StopWatch
- end;
-
- end.
 |
Ответ отправил: Feniks (статус: Бакалавр)
Время отправки: 1 октября 2007, 15:50
|
Мини-форум вопроса
Всего сообщений: 1; последнее сообщение — 29 сентября 2007, 00:49; участников в обсуждении: 1.
|
Грег Леонов (статус: 1-ый класс), 29 сентября 2007, 00:49 [#1]:
Код скопировался неудачно, выдели его и вставь в блокнот, легче прочесть будет. юзай ctrl + a, ctrl + c, ctrl + v
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|