Added support for NtQueryFullAttributesFile

This commit is contained in:
Berserker 2019-05-04 22:39:26 +03:00
parent 6b5de215d2
commit 360fddaa46
3 changed files with 70 additions and 25 deletions

View File

@ -21,6 +21,7 @@ type
published published
procedure TestGetFileAttributes; procedure TestGetFileAttributes;
procedure TestGetFileAttributesEx;
end; end;
(***) implementation (***) (***) implementation (***)
@ -90,7 +91,31 @@ begin
Check(HasValidAttrs(RootDir + '\503.html', 0, Windows.FILE_ATTRIBUTE_DIRECTORY), '{3}'); Check(HasValidAttrs(RootDir + '\503.html', 0, Windows.FILE_ATTRIBUTE_DIRECTORY), '{3}');
Check(HasValidAttrs(RootDir + '\Hobbots\', Windows.FILE_ATTRIBUTE_DIRECTORY), '{4}'); Check(HasValidAttrs(RootDir + '\Hobbots\', Windows.FILE_ATTRIBUTE_DIRECTORY), '{4}');
Check(HasValidAttrs(RootDir + '\Mods', Windows.FILE_ATTRIBUTE_DIRECTORY), '{5}'); Check(HasValidAttrs(RootDir + '\Mods', Windows.FILE_ATTRIBUTE_DIRECTORY), '{5}');
end; end; // .procedure TestIntegrated.TestGetFileAttributes;
procedure TestIntegrated.TestGetFileAttributesEx;
var
RootDir: string;
function GetFileSize (const Path: string): integer;
var
FileData: Windows.TWin32FileAttributeData;
begin
result := -1;
if Windows.GetFileAttributesExA(pchar(Path), Windows.GetFileExInfoStandard, @FileData) then begin
result := Int(FileData.nFileSizeLow);
end;
end;
begin
RootDir := Self.GetRootDir;
CheckEquals(-1, GetFileSize(RootDir + '\non-existing.non'), '{1}');
CheckEquals(47, GetFileSize(RootDir + '\Hobbots\mms.cfg'), '{2}');
CheckEquals(22, GetFileSize(RootDir + '\503.html'), '{3}');
CheckEquals(318, GetFileSize(RootDir + '\default'), '{4}');
end; // .procedure TestIntegrated.TestGetFileAttributesEx;
begin begin
RegisterTest(TestIntegrated.Suite); RegisterTest(TestIntegrated.Suite);

View File

@ -84,7 +84,7 @@ var
begin begin
if VfsDebug.LoggingEnabled then begin if VfsDebug.LoggingEnabled then begin
WriteLog('NtQueryAttributesFile', Format('Dir: %d. Path: "%s"', [ObjectAttributes.RootDirectory, ObjectAttributes.ObjectName.ToWideStr()])); WriteLog('[ENTER] NtQueryAttributesFile', Format('Dir: %d.'#13#10'Path: "%s"', [ObjectAttributes.RootDirectory, ObjectAttributes.ObjectName.ToWideStr()]));
end; end;
ReplacedObjAttrs := ObjectAttributes^; ReplacedObjAttrs := ObjectAttributes^;
@ -127,7 +127,7 @@ begin
end; // .else end; // .else
if VfsDebug.LoggingEnabled then begin if VfsDebug.LoggingEnabled then begin
WriteLog('NtQueryAttributesFile', Format('Result: %x. Attrs: 0x%x. Path: "%s" => "%s"', [result, FileInformation.FileAttributes, string(ExpandedPath), string(RedirectedPath)])); WriteLog('[LEAVE] NtQueryAttributesFile', Format('Result: %x. Attrs: 0x%x.'#13#10'Expanded: "%s"'#13#10'Redirected: "%s"', [result, FileInformation.FileAttributes, string(ExpandedPath), string(RedirectedPath)]));
end; end;
end; // .function Hook_NtQueryAttributesFile end; // .function Hook_NtQueryAttributesFile
@ -136,11 +136,12 @@ var
ExpandedPath: WideString; ExpandedPath: WideString;
RedirectedPath: WideString; RedirectedPath: WideString;
ReplacedObjAttrs: WinNative.TObjectAttributes; ReplacedObjAttrs: WinNative.TObjectAttributes;
FileInfo: TNativeFileInfo;
HadTrailingDelim: boolean; HadTrailingDelim: boolean;
begin begin
if VfsDebug.LoggingEnabled then begin if VfsDebug.LoggingEnabled then begin
WriteLog('NtQueryFullAttributesFile', Format('Dir: %d. Path: "%s"', [ObjectAttributes.RootDirectory, ObjectAttributes.ObjectName.ToWideStr()])); WriteLog('[ENTER] NtQueryFullAttributesFile', Format('Dir: %d.'#13#10'Path: "%s"', [ObjectAttributes.RootDirectory, ObjectAttributes.ObjectName.ToWideStr()]));
end; end;
ReplacedObjAttrs := ObjectAttributes^; ReplacedObjAttrs := ObjectAttributes^;
@ -149,27 +150,44 @@ begin
RedirectedPath := ''; RedirectedPath := '';
if ExpandedPath <> '' then begin if ExpandedPath <> '' then begin
RedirectedPath := VfsBase.GetVfsItemRealPath(StrLib.ExcludeTrailingDelimW(ExpandedPath, @HadTrailingDelim)); RedirectedPath := VfsBase.GetVfsItemRealPath(StrLib.ExcludeTrailingDelimW(ExpandedPath, @HadTrailingDelim), @FileInfo);
end; end;
if RedirectedPath = '' then begin // Return cached VFS file info
if RedirectedPath <> '' then begin
if not HadTrailingDelim or Utils.HasFlag(FILE_ATTRIBUTE_DIRECTORY, FileInfo.Base.FileAttributes) then begin
FileInformation.CreationTime := FileInfo.Base.CreationTime;
FileInformation.LastAccessTime := FileInfo.Base.LastAccessTime;
FileInformation.LastWriteTime := FileInfo.Base.LastWriteTime;
FileInformation.ChangeTime := FileInfo.Base.ChangeTime;
FileInformation.AllocationSize := FileInfo.Base.AllocationSize;
FileInformation.EndOfFile := FileInfo.Base.EndOfFile;
FileInformation.FileAttributes := FileInfo.Base.FileAttributes;
FileInformation.Reserved := 0;
result := WinNative.STATUS_SUCCESS;
end else begin
result := WinNative.STATUS_NO_SUCH_FILE;
end;
end
// Query file with real path
else begin
RedirectedPath := ExpandedPath; RedirectedPath := ExpandedPath;
end else if HadTrailingDelim then begin
RedirectedPath := RedirectedPath + '\';
end;
if (RedirectedPath <> '') and (RedirectedPath[1] <> '\') then begin if RedirectedPath <> '' then begin
RedirectedPath := '\??\' + RedirectedPath; if RedirectedPath[1] <> '\' then begin
end; RedirectedPath := '\??\' + RedirectedPath;
end;
ReplacedObjAttrs.RootDirectory := 0; ReplacedObjAttrs.RootDirectory := 0;
ReplacedObjAttrs.Attributes := ReplacedObjAttrs.Attributes or WinNative.OBJ_CASE_INSENSITIVE; ReplacedObjAttrs.Attributes := ReplacedObjAttrs.Attributes or WinNative.OBJ_CASE_INSENSITIVE;
ReplacedObjAttrs.ObjectName.AssignExistingStr(RedirectedPath); ReplacedObjAttrs.ObjectName.AssignExistingStr(RedirectedPath);
end;
result := OrigFunc(@ReplacedObjAttrs, FileInformation); result := OrigFunc(@ReplacedObjAttrs, FileInformation);
end; // .else
if VfsDebug.LoggingEnabled then begin if VfsDebug.LoggingEnabled then begin
WriteLog('NtQueryFullAttributesFile', Format('Result: %x. Attrs: 0x%x. Path: "%s" => "%s"', [result, FileInformation.FileAttributes, string(ExpandedPath), string(RedirectedPath)])); WriteLog('[LEAVE] NtQueryFullAttributesFile', Format('Result: %x. Attrs: 0x%x.'#13#10'Expanded: "%s"'#13#10'Redirected: "%s"', [result, FileInformation.FileAttributes, string(ExpandedPath), string(RedirectedPath)]));
end; end;
end; // .Hook_NtQueryFullAttributesFile end; // .Hook_NtQueryFullAttributesFile
@ -511,12 +529,12 @@ begin
@Hook_NtQueryAttributesFile @Hook_NtQueryAttributesFile
); );
// WriteLog('InstallHook', 'Installing NtQueryFullAttributesFile hook'); WriteLog('InstallHook', 'Installing NtQueryFullAttributesFile hook');
// NativeNtQueryFullAttributesFile := VfsPatching.SpliceWinApi NativeNtQueryFullAttributesFile := VfsPatching.SpliceWinApi
// ( (
// VfsApiDigger.GetRealProcAddress(NtdllHandle, 'NtQueryFullAttributesFile'), VfsApiDigger.GetRealProcAddress(NtdllHandle, 'NtQueryFullAttributesFile'),
// @Hook_NtQueryFullAttributesFile @Hook_NtQueryFullAttributesFile
// ); );
// WriteLog('InstallHook', 'Installing NtOpenFile hook'); // WriteLog('InstallHook', 'Installing NtOpenFile hook');
// NativeNtOpenFile := VfsPatching.SpliceWinApi // NativeNtOpenFile := VfsPatching.SpliceWinApi

View File

@ -1,5 +1,7 @@
UTF-8 Logging UTF-8 Logging
Move copyright to single file license?
SetCurrentDirectoryW(GetCurrentDirectoryW) SetCurrentDirectoryW(GetCurrentDirectoryW)
System.IsMultiThread for DLL and exported API System.IsMultiThread for DLL and exported API