Virtual-File-System/Tests/VfsControl.pas

139 lines
3.6 KiB
ObjectPascal

unit VfsControl;
(*
Facade unit for high-level VFS API.
*)
(***) interface (***)
uses
Windows, SysUtils,
Utils, WinUtils, TypeWrappers, DataLib,
Files, StrLib,
VfsBase, VfsUtils, VfsHooks, DlgMes;
type
(* Import *)
TWideString = TypeWrappers.TWideString;
const
(* Flag forces to skip directory names, starting with '#' *)
SKIP_HASHTAGGED_MODS = 1;
(* Runs all VFS subsystems, unless VFS is already running *)
function RunVfs (DirListingOrder: VfsBase.TDirListingSortType): boolean; stdcall;
(***) implementation (***)
function RunVfs (DirListingOrder: VfsBase.TDirListingSortType): boolean; stdcall;
var
CurrDir: WideString;
begin
with VfsBase.VfsCritSection do begin
Enter;
result := VfsBase.RunVfs(DirListingOrder);
if result then begin
VfsHooks.InstallHooks;
// Try to ensure, that current directory handle is tracked by VfsOpenFiles
CurrDir := WinUtils.GetCurrentDirW;
if CurrDir <> '' then begin
WinUtils.SetCurrentDirW(CurrDir);
end;
end;
Leave;
end; // .with
end; // function RunVfs
function ValidateModName (const ModName: WideString): boolean;
const
DISALLOWED_CHARS = ['<', '>', '"', '?', '*', '\', '/', '|', ':', #0];
var
StrLen: integer;
i: integer;
begin
StrLen := Length(ModName);
i := 1;
while (i <= StrLen) and ((ord(ModName[i]) > 255) or not (AnsiChar(ModName[i]) in DISALLOWED_CHARS)) do begin
Inc(i);
end;
result := (i > StrLen) and (ModName <> '') and (ModName <> '.') and (ModName <> '..');
end;
function LoadModList (const ModListFilePath: WideString): {O} DataLib.TList {of (O) TWideString};
var
AbsFilePath: WideString;
FileContents: string;
Lines: Utils.TArrayOfStr;
ModNameUtf8: string;
ModName: WideString;
i: integer;
begin
result := DataLib.NewList(Utils.OWNS_ITEMS);
// * * * * * //
AbsFilePath := VfsUtils.NormalizePath(ModListFilePath);
if (AbsFilePath <> '') and (Files.ReadFileContents(AbsFilePath, FileContents)) then begin
Lines := StrLib.Explode(FileContents, #10);
for i := 0 to High(Lines) do begin
ModNameUtf8 := Lines[i];
ModName := StrLib.Utf8ToWide(ModNameUtf8);
if ValidateModName(ModName) then begin
result.Add(TWideString.Create(ModName));
end;
end;
end;
end; // .function LoadModList
// function MapModsDir (const RootDir, ModsDir: WideString; Flags: integer = 0);
// var
// AbsRootDir: WideString;
// AbsModsDir: WideString;
// FileInfo: VfsUtils.TNativeFileInfo;
// ModName: WideString;
// begin
// AbsRootDir := VfsUtils.NormalizePath(RootDir);
// AbsModsDir := VfsUtils.NormalizePath(ModsDir);
// result := (AbsRootDir <> '') and (AbsModsDir <> '') and VfsUtils.GetFileInfo(AbsRootDir, FileInfo);
// result := result and Utils.HasFlag(Windows.FILE_ATTRIBUTE_DIRECTORY, FileInfo.Base.FileAttributes);
// result := result and VfsUtils.GetFileInfo(AbsModsDir, FileInfo);
// result := result and Utils.HasFlag(Windows.FILE_ATTRIBUTE_DIRECTORY, FileInfo.Base.FileAttributes);
// if result then begin
// with VfsUtils.SysScanDir(AbsModsDir, '*') do begin
// while IterNext(ModName, @FileInfo.Base) do begin
// if (ModName <> '.') and (ModName <> '..') and Utils.HasFlag(Windows.FILE_ATTRIBUTE_DIRECTORY, FileInfo.Base.FileAttributes) then begin
// end;
// end;
// end;
// end;
// end;
var
L: TList;
i: integer;
begin
// L := LoadModList('D:\Heroes 3\Mods\list.txt');
// for i := 0 to L.Count- 1 do begin
// VarDump([TWideString(L[i]).Value]);
// end;
end.