mirror of
https://github.com/CloudDelphi/Virtual-File-System
synced 2025-12-19 18:03:49 +01:00
Compare commits
No commits in common. "master" and "v1.0.0" have entirely different histories.
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,6 +4,5 @@
|
|||||||
*.ini
|
*.ini
|
||||||
*.identcache
|
*.identcache
|
||||||
*.map
|
*.map
|
||||||
*.res
|
|
||||||
_LOG_.txt
|
_LOG_.txt
|
||||||
__history/
|
__history/
|
||||||
11
README.md
11
README.md
@ -1,9 +1,2 @@
|
|||||||
# VFS (Virtual File System)
|
# vfs
|
||||||
Add Virtual File System support to your project. Implement Mods directory support in 2 lines of code.
|
Add Virtual File System support to your project. Implement Mods directory support in 2 lines of code
|
||||||
Virtually copies contents of any directory into any directory. Copied contents is available in read-only mode.
|
|
||||||
|
|
||||||
## Example:
|
|
||||||
```delphi
|
|
||||||
VfsImport.MapModsFromListA('D:\Game', 'D:\Game\Mods', 'D:\Game\Mods\list.txt');
|
|
||||||
VfsImport.RunVfs(VfsImport.SORT_FIFO);
|
|
||||||
```
|
|
||||||
|
|||||||
10
Vfs.dproj
10
Vfs.dproj
@ -30,7 +30,15 @@
|
|||||||
<Borland.Personality>Delphi.Personality</Borland.Personality>
|
<Borland.Personality>Delphi.Personality</Borland.Personality>
|
||||||
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
|
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
|
||||||
<BorlandProject>
|
<BorlandProject>
|
||||||
<BorlandProject><Delphi.Personality><Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><VersionInfo><VersionInfo Name="IncludeVerInfo">True</VersionInfo><VersionInfo Name="AutoIncBuild">True</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">4</VersionInfo><VersionInfo Name="Build">1</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1049</VersionInfo><VersionInfo Name="CodePage">1251</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName">Alexander Shostak (aka EtherniDee)</VersionInfoKeys><VersionInfoKeys Name="FileDescription">Virtual File System</VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.4.1</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Source><Source Name="MainSource">Vfs.dpr</Source></Source><Excluded_Packages>
|
<BorlandProject><Delphi.Personality><Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><VersionInfo><VersionInfo Name="IncludeVerInfo">True</VersionInfo><VersionInfo Name="AutoIncBuild">True</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1049</VersionInfo><VersionInfo Name="CodePage">1251</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName">Alexander Shostak (aka EtherniDee)</VersionInfoKeys><VersionInfoKeys Name="FileDescription">Virtual File System</VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Source><Source Name="MainSource">Vfs.dpr</Source></Source><Excluded_Packages>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
58
VfsBase.pas
58
VfsBase.pas
@ -48,9 +48,6 @@ type
|
|||||||
(* Name in lower case, used for wildcard mask matching *)
|
(* Name in lower case, used for wildcard mask matching *)
|
||||||
SearchName: WideString;
|
SearchName: WideString;
|
||||||
|
|
||||||
(* Absolute path to virtual file/folder location without trailing slash for non-drives *)
|
|
||||||
VirtPath: WideString;
|
|
||||||
|
|
||||||
(* Absolute path to real file/folder location without trailing slash for non-drives *)
|
(* Absolute path to real file/folder location without trailing slash for non-drives *)
|
||||||
RealPath: WideString;
|
RealPath: WideString;
|
||||||
|
|
||||||
@ -133,10 +130,6 @@ function CallWithoutVfs (Func: TSingleArgExternalFunc; Arg: pointer = nil): inte
|
|||||||
of real and virtual paths is stripped *)
|
of real and virtual paths is stripped *)
|
||||||
function GetMappingsReport: WideString;
|
function GetMappingsReport: WideString;
|
||||||
|
|
||||||
(* Returns text with all applied mappings on per-file level, separated via #13#10. If ShortenPaths is true, common part
|
|
||||||
of real and virtual paths is stripped *)
|
|
||||||
function GetDetailedMappingsReport: WideString;
|
|
||||||
|
|
||||||
|
|
||||||
(***) implementation (***)
|
(***) implementation (***)
|
||||||
|
|
||||||
@ -524,7 +517,6 @@ begin
|
|||||||
CopyFileInfoWithoutNames(FileInfo.Base, VfsItem.Info.Base);
|
CopyFileInfoWithoutNames(FileInfo.Base, VfsItem.Info.Base);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
VfsItem.VirtPath := AbsVirtPath;
|
|
||||||
VfsItem.RealPath := AbsRealPath;
|
VfsItem.RealPath := AbsRealPath;
|
||||||
VfsItem.Priority := Priority;
|
VfsItem.Priority := Priority;
|
||||||
VfsItem.Attrs := 0;
|
VfsItem.Attrs := 0;
|
||||||
@ -577,7 +569,7 @@ begin
|
|||||||
|
|
||||||
with SysScanDir(AbsRealPath, '*') do begin
|
with SysScanDir(AbsRealPath, '*') do begin
|
||||||
while IterNext(FileInfo.FileName, @FileInfo.Base) do begin
|
while IterNext(FileInfo.FileName, @FileInfo.Base) do begin
|
||||||
if Utils.Flags(FileInfo.Base.FileAttributes).Have(Windows.FILE_ATTRIBUTE_DIRECTORY) then begin
|
if Utils.HasFlag(FileInfo.Base.FileAttributes, Windows.FILE_ATTRIBUTE_DIRECTORY) then begin
|
||||||
if (FileInfo.FileName <> '.') and (FileInfo.FileName <> '..') then begin
|
if (FileInfo.FileName <> '.') and (FileInfo.FileName <> '..') then begin
|
||||||
Subdirs.Add(TFileInfo.Create(@FileInfo));
|
Subdirs.Add(TFileInfo.Create(@FileInfo));
|
||||||
end;
|
end;
|
||||||
@ -701,7 +693,7 @@ begin
|
|||||||
end; // .with
|
end; // .with
|
||||||
end; // .function RefreshMappedFile
|
end; // .function RefreshMappedFile
|
||||||
|
|
||||||
function GetMappingsReport_ (Mappings: TList {of TMapping}): WideString;
|
function GetMappingsReport: WideString;
|
||||||
const
|
const
|
||||||
COL_PATHS = 0;
|
COL_PATHS = 0;
|
||||||
COL_META = 1;
|
COL_META = 1;
|
||||||
@ -819,51 +811,7 @@ begin
|
|||||||
// * * * * * //
|
// * * * * * //
|
||||||
SysUtils.FreeAndNil(Buf);
|
SysUtils.FreeAndNil(Buf);
|
||||||
SysUtils.FreeAndNil(Line);
|
SysUtils.FreeAndNil(Line);
|
||||||
end; // .function GetMappingsReport_
|
end; // .function GetMappingsReport
|
||||||
|
|
||||||
function GetMappingsReport: WideString;
|
|
||||||
begin
|
|
||||||
with VfsCritSection do begin
|
|
||||||
Enter;
|
|
||||||
result := GetMappingsReport_(Mappings);
|
|
||||||
Leave;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function CompareMappingsByRealPath (A, B: integer): integer;
|
|
||||||
begin
|
|
||||||
result := StrLib.CompareBinStringsW(TMapping(A).AbsRealPath, TMapping(B).AbsRealPath);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function GetDetailedMappingsReport: WideString;
|
|
||||||
var
|
|
||||||
{O} DetailedMappings: {O} TList {of TMapping};
|
|
||||||
{Un} VfsItem: TVfsItem;
|
|
||||||
|
|
||||||
begin
|
|
||||||
DetailedMappings := DataLib.NewList(Utils.OWNS_ITEMS);
|
|
||||||
VfsItem := nil;
|
|
||||||
// * * * * * //
|
|
||||||
with VfsCritSection do begin
|
|
||||||
Enter;
|
|
||||||
|
|
||||||
with DataLib.IterateDict(VfsItems) do begin
|
|
||||||
while IterNext do begin
|
|
||||||
VfsItem := TVfsItem(IterValue);
|
|
||||||
|
|
||||||
// Note, item Attrs is not the same as directory mapping Flags
|
|
||||||
DetailedMappings.Add(TMapping.Make(true, VfsItem.VirtPath, VfsItem.RealPath, false, VfsItem.Attrs));
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
Leave;
|
|
||||||
end;
|
|
||||||
|
|
||||||
DetailedMappings.CustomSort(CompareMappingsByRealPath);
|
|
||||||
result := GetMappingsReport_(DetailedMappings);
|
|
||||||
// * * * * * //
|
|
||||||
SysUtils.FreeAndNil(DetailedMappings);
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
VfsCritSection.Init;
|
VfsCritSection.Init;
|
||||||
|
|||||||
@ -37,7 +37,6 @@ type
|
|||||||
function RunVfs (DirListingOrder: VfsBase.TDirListingSortType): LONGBOOL; stdcall;
|
function RunVfs (DirListingOrder: VfsBase.TDirListingSortType): LONGBOOL; stdcall;
|
||||||
var
|
var
|
||||||
CurrDir: WideString;
|
CurrDir: WideString;
|
||||||
SysDir: WideString;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
with VfsBase.VfsCritSection do begin
|
with VfsBase.VfsCritSection do begin
|
||||||
@ -48,16 +47,11 @@ begin
|
|||||||
if result then begin
|
if result then begin
|
||||||
VfsHooks.InstallHooks;
|
VfsHooks.InstallHooks;
|
||||||
|
|
||||||
// Hask: Try to ensure, that current directory handle is tracked by VfsOpenFiles
|
// Try to ensure, that current directory handle is tracked by VfsOpenFiles
|
||||||
// Windows SetCurrentDirectoryW is does not reopen directory for the same path, thus
|
|
||||||
// not triggering NtCreateFile
|
|
||||||
// Not thread safe
|
|
||||||
CurrDir := WinUtils.GetCurrentDirW;
|
CurrDir := WinUtils.GetCurrentDirW;
|
||||||
SysDir := WinUtils.GetSysDirW;
|
|
||||||
|
|
||||||
if (CurrDir <> '') and (SysDir <> '') then begin
|
if CurrDir <> '' then begin
|
||||||
WinUtils.SetCurrentDirW(SysDir);
|
WinUtils.SetCurrentDirW(CurrDir);
|
||||||
{!} Assert(WinUtils.SetCurrentDirW(CurrDir), 'Failed to restore current directory from system directory during VFS initialization');
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -149,8 +143,8 @@ begin
|
|||||||
AbsRootDir := VfsUtils.NormalizePath(RootDir);
|
AbsRootDir := VfsUtils.NormalizePath(RootDir);
|
||||||
AbsModsDir := VfsUtils.NormalizePath(ModsDir);
|
AbsModsDir := VfsUtils.NormalizePath(ModsDir);
|
||||||
result := (AbsRootDir <> '') and (AbsModsDir <> '') and
|
result := (AbsRootDir <> '') and (AbsModsDir <> '') and
|
||||||
VfsUtils.GetFileInfo(AbsRootDir, FileInfo) and Utils.Flags(FileInfo.Base.FileAttributes).Have(Windows.FILE_ATTRIBUTE_DIRECTORY) and
|
VfsUtils.GetFileInfo(AbsRootDir, FileInfo) and Utils.HasFlag(Windows.FILE_ATTRIBUTE_DIRECTORY, FileInfo.Base.FileAttributes) and
|
||||||
VfsUtils.GetFileInfo(AbsModsDir, FileInfo) and Utils.Flags(FileInfo.Base.FileAttributes).Have(Windows.FILE_ATTRIBUTE_DIRECTORY);
|
VfsUtils.GetFileInfo(AbsModsDir, FileInfo) and Utils.HasFlag(Windows.FILE_ATTRIBUTE_DIRECTORY, FileInfo.Base.FileAttributes);
|
||||||
|
|
||||||
if result then begin
|
if result then begin
|
||||||
ModPathPrefix := VfsUtils.AddBackslash(AbsModsDir);
|
ModPathPrefix := VfsUtils.AddBackslash(AbsModsDir);
|
||||||
|
|||||||
@ -24,18 +24,6 @@ exports
|
|||||||
(***) implementation (***)
|
(***) implementation (***)
|
||||||
|
|
||||||
|
|
||||||
function Externalize (const Str: AnsiString): {O} pointer; overload;
|
|
||||||
begin
|
|
||||||
GetMem(result, Length(Str) + 1);
|
|
||||||
Utils.CopyMem(Length(Str) + 1, pchar(Str), result);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function Externalize (const Str: WideString): {O} pointer; overload;
|
|
||||||
begin
|
|
||||||
GetMem(result, (Length(Str) + 1) * sizeof(WideChar));
|
|
||||||
Utils.CopyMem((Length(Str) + 1) * sizeof(WideChar), PWideChar(Str), result);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function MapDir (const VirtPath, RealPath: PWideChar; OverwriteExisting: boolean; Flags: integer = 0): LONGBOOL; stdcall;
|
function MapDir (const VirtPath, RealPath: PWideChar; OverwriteExisting: boolean; Flags: integer = 0): LONGBOOL; stdcall;
|
||||||
begin
|
begin
|
||||||
result := VfsBase.MapDir(WideString(VirtPath), WideString(RealPath), OverwriteExisting, Flags);
|
result := VfsBase.MapDir(WideString(VirtPath), WideString(RealPath), OverwriteExisting, Flags);
|
||||||
@ -75,25 +63,25 @@ end;
|
|||||||
(* Returns text with all applied mappings, separated via #13#10. If ShortenPaths is true, common part
|
(* Returns text with all applied mappings, separated via #13#10. If ShortenPaths is true, common part
|
||||||
of real and virtual paths is stripped. Call MemFree to release result buffer *)
|
of real and virtual paths is stripped. Call MemFree to release result buffer *)
|
||||||
function GetMappingsReport: {O} PWideChar; stdcall;
|
function GetMappingsReport: {O} PWideChar; stdcall;
|
||||||
|
var
|
||||||
|
Res: WideString;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
result := Externalize(VfsBase.GetMappingsReport);
|
result := nil;
|
||||||
|
Res := VfsBase.GetMappingsReport;
|
||||||
|
GetMem(result, (Length(Res) + 1) * sizeof(WideChar));
|
||||||
|
Utils.CopyMem((Length(Res) + 1) * sizeof(WideChar), PWideChar(Res), result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetMappingsReportA: {O} pchar; stdcall;
|
function GetMappingsReportA: {O} pchar; stdcall;
|
||||||
begin
|
var
|
||||||
result := Externalize(AnsiString(VfsBase.GetMappingsReport));
|
Res: string;
|
||||||
end;
|
|
||||||
|
|
||||||
(* Returns text with all applied mappings on per-file level, separated via #13#10. If ShortenPaths is true, common part
|
|
||||||
of real and virtual paths is stripped *)
|
|
||||||
function GetDetailedMappingsReport: {O} PWideChar; stdcall;
|
|
||||||
begin
|
begin
|
||||||
result := Externalize(VfsBase.GetDetailedMappingsReport);
|
result := nil;
|
||||||
end;
|
Res := VfsBase.GetMappingsReport;
|
||||||
|
GetMem(result, Length(Res) + 1);
|
||||||
function GetDetailedMappingsReportA: {O} pchar; stdcall;
|
Utils.CopyMem(Length(Res) + 1, pchar(Res), result);
|
||||||
begin
|
|
||||||
result := Externalize(AnsiString(VfsBase.GetDetailedMappingsReport));
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure ConsoleLoggingProc (Operation, Message: pchar); stdcall;
|
procedure ConsoleLoggingProc (Operation, Message: pchar); stdcall;
|
||||||
@ -139,8 +127,6 @@ exports
|
|||||||
RunWatcherA,
|
RunWatcherA,
|
||||||
GetMappingsReport,
|
GetMappingsReport,
|
||||||
GetMappingsReportA,
|
GetMappingsReportA,
|
||||||
GetDetailedMappingsReport,
|
|
||||||
GetDetailedMappingsReportA,
|
|
||||||
MemFree,
|
MemFree,
|
||||||
InstallConsoleLogger;
|
InstallConsoleLogger;
|
||||||
|
|
||||||
|
|||||||
49
VfsHooks.pas
49
VfsHooks.pas
@ -9,7 +9,7 @@ unit VfsHooks;
|
|||||||
uses
|
uses
|
||||||
Windows, SysUtils, Math,
|
Windows, SysUtils, Math,
|
||||||
Utils, WinNative, Concur,
|
Utils, WinNative, Concur,
|
||||||
StrLib, Alg, WinUtils,
|
StrLib, Alg,
|
||||||
VfsBase, VfsUtils, VfsPatching,
|
VfsBase, VfsUtils, VfsPatching,
|
||||||
VfsDebug, VfsApiDigger, VfsOpenFiles;
|
VfsDebug, VfsApiDigger, VfsOpenFiles;
|
||||||
|
|
||||||
@ -31,8 +31,6 @@ var
|
|||||||
NativeNtCreateFile: WinNative.TNtCreateFile;
|
NativeNtCreateFile: WinNative.TNtCreateFile;
|
||||||
NativeNtClose: WinNative.TNtClose;
|
NativeNtClose: WinNative.TNtClose;
|
||||||
NativeNtQueryDirectoryFile: WinNative.TNtQueryDirectoryFile;
|
NativeNtQueryDirectoryFile: WinNative.TNtQueryDirectoryFile;
|
||||||
NativeNtQueryDirectoryFileEx: WinNative.TNtQueryDirectoryFileEx;
|
|
||||||
|
|
||||||
|
|
||||||
NtQueryAttributesFilePatch: VfsPatching.TAppliedPatch;
|
NtQueryAttributesFilePatch: VfsPatching.TAppliedPatch;
|
||||||
NtQueryFullAttributesFilePatch: VfsPatching.TAppliedPatch;
|
NtQueryFullAttributesFilePatch: VfsPatching.TAppliedPatch;
|
||||||
@ -40,7 +38,6 @@ var
|
|||||||
NtCreateFilePatch: VfsPatching.TAppliedPatch;
|
NtCreateFilePatch: VfsPatching.TAppliedPatch;
|
||||||
NtClosePatch: VfsPatching.TAppliedPatch;
|
NtClosePatch: VfsPatching.TAppliedPatch;
|
||||||
NtQueryDirectoryFilePatch: VfsPatching.TAppliedPatch;
|
NtQueryDirectoryFilePatch: VfsPatching.TAppliedPatch;
|
||||||
NtQueryDirectoryFileExPatch: VfsPatching.TAppliedPatch;
|
|
||||||
|
|
||||||
|
|
||||||
(* There is no 100% portable and reliable way to get file path by handle, unless file creation/opening
|
(* There is no 100% portable and reliable way to get file path by handle, unless file creation/opening
|
||||||
@ -51,10 +48,6 @@ var
|
|||||||
function GetFilePathByHandle (hFile: THandle): WideString;
|
function GetFilePathByHandle (hFile: THandle): WideString;
|
||||||
begin
|
begin
|
||||||
result := VfsOpenFiles.GetOpenedFilePath(hFile);
|
result := VfsOpenFiles.GetOpenedFilePath(hFile);
|
||||||
|
|
||||||
if (result = '') and VfsDebug.LoggingEnabled then begin
|
|
||||||
WriteLog('GetFilePathByHandle', Format('Failed to get path for handle %x. Current directory is: %s', [integer(hFile), WinUtils.GetCurrentDirW]));
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
(* Returns single absolute path, not dependant on RootDirectory member. '\??\' prefix is always removed, \\.\ and \\?\ paths remain not touched. *)
|
(* Returns single absolute path, not dependant on RootDirectory member. '\??\' prefix is always removed, \\.\ and \\?\ paths remain not touched. *)
|
||||||
@ -114,7 +107,7 @@ begin
|
|||||||
|
|
||||||
// Return cached VFS file info
|
// Return cached VFS file info
|
||||||
if RedirectedPath <> '' then begin
|
if RedirectedPath <> '' then begin
|
||||||
if not HadTrailingDelim or Utils.Flags(FileInfo.Base.FileAttributes).Have(FILE_ATTRIBUTE_DIRECTORY) then begin
|
if not HadTrailingDelim or Utils.HasFlag(FILE_ATTRIBUTE_DIRECTORY, FileInfo.Base.FileAttributes) then begin
|
||||||
FileInformation.CreationTime := FileInfo.Base.CreationTime;
|
FileInformation.CreationTime := FileInfo.Base.CreationTime;
|
||||||
FileInformation.LastAccessTime := FileInfo.Base.LastAccessTime;
|
FileInformation.LastAccessTime := FileInfo.Base.LastAccessTime;
|
||||||
FileInformation.LastWriteTime := FileInfo.Base.LastWriteTime;
|
FileInformation.LastWriteTime := FileInfo.Base.LastWriteTime;
|
||||||
@ -174,7 +167,7 @@ begin
|
|||||||
|
|
||||||
// Return cached VFS file info
|
// Return cached VFS file info
|
||||||
if RedirectedPath <> '' then begin
|
if RedirectedPath <> '' then begin
|
||||||
if not HadTrailingDelim or Utils.Flags(FileInfo.Base.FileAttributes).Have(FILE_ATTRIBUTE_DIRECTORY) then begin
|
if not HadTrailingDelim or Utils.HasFlag(FILE_ATTRIBUTE_DIRECTORY, FileInfo.Base.FileAttributes) then begin
|
||||||
FileInformation.CreationTime := FileInfo.Base.CreationTime;
|
FileInformation.CreationTime := FileInfo.Base.CreationTime;
|
||||||
FileInformation.LastAccessTime := FileInfo.Base.LastAccessTime;
|
FileInformation.LastAccessTime := FileInfo.Base.LastAccessTime;
|
||||||
FileInformation.LastWriteTime := FileInfo.Base.LastWriteTime;
|
FileInformation.LastWriteTime := FileInfo.Base.LastWriteTime;
|
||||||
@ -546,28 +539,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
end; // .function Hook_NtQueryDirectoryFile
|
end; // .function Hook_NtQueryDirectoryFile
|
||||||
|
|
||||||
function Hook_NtQueryDirectoryFileEx (OrigFunc: WinNative.TNtQueryDirectoryFileEx; FileHandle: HANDLE; Event: HANDLE; ApcRoutine: pointer; ApcContext: PVOID; Io: PIO_STATUS_BLOCK;
|
|
||||||
Buffer: PVOID; BufLength: ULONG; InfoClass: integer (* FILE_INFORMATION_CLASS *); QueryFlags: integer; Mask: PUNICODE_STRING): NTSTATUS; stdcall;
|
|
||||||
var
|
|
||||||
SingleEntry: LONGBOOL;
|
|
||||||
RestartScan: LONGBOOL;
|
|
||||||
|
|
||||||
begin
|
|
||||||
if VfsDebug.LoggingEnabled then begin
|
|
||||||
WriteLog('NtQueryDirectoryFileEx', Format('Handle: %x. QueryFlags: %x', [FileHandle, QueryFlags]));
|
|
||||||
end;
|
|
||||||
|
|
||||||
RestartScan := Utils.Flags(QueryFlags).Have(WinNative.SL_RESTART_SCAN);
|
|
||||||
SingleEntry := Utils.Flags(QueryFlags).Have(WinNative.SL_RETURN_SINGLE_ENTRY);
|
|
||||||
result := WinNative.NtQueryDirectoryFile(FileHandle, Event, ApcRoutine, ApcContext, Io, Buffer, BufLength, InfoClass, SingleEntry, Mask, RestartScan);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure InstallHooks;
|
procedure InstallHooks;
|
||||||
var
|
var
|
||||||
SetProcessDEPPolicy: function (dwFlags: integer): LONGBOOL; stdcall;
|
SetProcessDEPPolicy: function (dwFlags: integer): LONGBOOL; stdcall;
|
||||||
hDll: Windows.THandle;
|
hDll: Windows.THandle;
|
||||||
NtdllHandle: integer;
|
NtdllHandle: integer;
|
||||||
NtQueryDirectoryFileExAddr: WinNative.TNtQueryDirectoryFileEx;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
with HooksCritSection do begin
|
with HooksCritSection do begin
|
||||||
@ -642,18 +618,6 @@ begin
|
|||||||
@Hook_NtQueryDirectoryFile,
|
@Hook_NtQueryDirectoryFile,
|
||||||
@NtQueryDirectoryFilePatch
|
@NtQueryDirectoryFilePatch
|
||||||
);
|
);
|
||||||
|
|
||||||
NtQueryDirectoryFileExAddr := VfsApiDigger.GetRealProcAddress(NtdllHandle, 'NtQueryDirectoryFileEx');
|
|
||||||
|
|
||||||
if @NtQueryDirectoryFileExAddr <> nil then begin
|
|
||||||
WriteLog('InstallHook', 'Installing NtQueryDirectoryFileEx hook');
|
|
||||||
NativeNtQueryDirectoryFileEx := VfsPatching.SpliceWinApi
|
|
||||||
(
|
|
||||||
@NtQueryDirectoryFileExAddr,
|
|
||||||
@Hook_NtQueryDirectoryFileEx,
|
|
||||||
@NtQueryDirectoryFileExPatch
|
|
||||||
);
|
|
||||||
end;
|
|
||||||
end; // .if
|
end; // .if
|
||||||
|
|
||||||
Leave;
|
Leave;
|
||||||
@ -671,7 +635,6 @@ begin
|
|||||||
NtCreateFilePatch.Rollback;
|
NtCreateFilePatch.Rollback;
|
||||||
NtClosePatch.Rollback;
|
NtClosePatch.Rollback;
|
||||||
NtQueryDirectoryFilePatch.Rollback;
|
NtQueryDirectoryFilePatch.Rollback;
|
||||||
NtQueryDirectoryFileExPatch.Rollback;
|
|
||||||
|
|
||||||
Leave;
|
Leave;
|
||||||
end;
|
end;
|
||||||
|
|||||||
@ -51,11 +51,6 @@ procedure MemFree ({O} Buf: pointer); stdcall; external 'vfs.dll';
|
|||||||
function GetMappingsReport: {O} PWideChar; stdcall; external 'vfs.dll';
|
function GetMappingsReport: {O} PWideChar; stdcall; external 'vfs.dll';
|
||||||
function GetMappingsReportA: {O} pchar; stdcall; external 'vfs.dll';
|
function GetMappingsReportA: {O} pchar; stdcall; external 'vfs.dll';
|
||||||
|
|
||||||
(* Returns text with all applied mappings on per-file level, separated via #13#10. If ShortenPaths is true, common part
|
|
||||||
of real and virtual paths is stripped *)
|
|
||||||
function GetDetailedMappingsReport: {O} PWideChar; stdcall; external 'vfs.dll';
|
|
||||||
function GetDetailedMappingsReportA: {O} pchar; stdcall; external 'vfs.dll';
|
|
||||||
|
|
||||||
(* Allocates console and install logger, writing messages to console *)
|
(* Allocates console and install logger, writing messages to console *)
|
||||||
procedure InstallConsoleLogger; stdcall; external 'vfs.dll';
|
procedure InstallConsoleLogger; stdcall; external 'vfs.dll';
|
||||||
|
|
||||||
|
|||||||
@ -159,7 +159,6 @@ begin
|
|||||||
// Create and apply hook at target function start
|
// Create and apply hook at target function start
|
||||||
p.Clear();
|
p.Clear();
|
||||||
p.Jump(PatchForge.JMP, SpliceBridge);
|
p.Jump(PatchForge.JMP, SpliceBridge);
|
||||||
p.Nop(OverwrittenCodeSize - p.Pos);
|
|
||||||
|
|
||||||
if AppliedPatch <> nil then begin
|
if AppliedPatch <> nil then begin
|
||||||
AppliedPatch.Addr := OrigFunc;
|
AppliedPatch.Addr := OrigFunc;
|
||||||
|
|||||||
@ -506,7 +506,7 @@ var
|
|||||||
FileAttrs: integer;
|
FileAttrs: integer;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
result := GetFileAttrs(Path, FileAttrs) and Utils.Flags(FileAttrs).Have(Windows.FILE_ATTRIBUTE_DIRECTORY);
|
result := GetFileAttrs(Path, FileAttrs) and Utils.HasFlag(Windows.FILE_ATTRIBUTE_DIRECTORY, FileAttrs);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function SysOpenFile (const NtAbsPath: WideString; {OUT} var Res: Windows.THandle; const OpenMode: TSysOpenFileMode = OPEN_AS_ANY; const AccessMode: ACCESS_MASK = FILE_GENERIC_READ): boolean;
|
function SysOpenFile (const NtAbsPath: WideString; {OUT} var Res: Windows.THandle; const OpenMode: TSysOpenFileMode = OPEN_AS_ANY; const AccessMode: ACCESS_MASK = FILE_GENERIC_READ): boolean;
|
||||||
|
|||||||
@ -4,7 +4,7 @@ cls
|
|||||||
set h3dir=D:\Heroes 3
|
set h3dir=D:\Heroes 3
|
||||||
copy /Y Vfs.dll "%h3dir%\vfs.dll"
|
copy /Y Vfs.dll "%h3dir%\vfs.dll"
|
||||||
copy /Y Vfs.map "%h3dir%\Vfs.map"
|
copy /Y Vfs.map "%h3dir%\Vfs.map"
|
||||||
php "%h3dir%\Tools\ExeMapCompiler\compile.phc" "vfs.map" "%h3dir%/DebugMaps"
|
php "%h3dir%\Tools\ExeMapCompiler\compile.phc" "vfs.map" "./DebugMaps"
|
||||||
echo.
|
echo.
|
||||||
echo.
|
echo.
|
||||||
echo %date% %time%
|
echo %date% %time%
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user