mirror of
https://github.com/CloudDelphi/Virtual-File-System
synced 2025-12-19 09:53:54 +01:00
Added more high-level exported API. VFS.dll is built
This commit is contained in:
parent
745737abdf
commit
081194c185
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
*.dcu
|
||||
*.exe
|
||||
*.dll
|
||||
*.ini
|
||||
*.identcache
|
||||
*.map
|
||||
|
||||
@ -1,156 +0,0 @@
|
||||
unit VfsControl;
|
||||
(*
|
||||
Facade unit for high-level VFS API.
|
||||
*)
|
||||
|
||||
|
||||
(***) interface (***)
|
||||
|
||||
uses
|
||||
Windows, SysUtils,
|
||||
Utils, WinUtils, TypeWrappers, DataLib,
|
||||
Files, StrLib,
|
||||
VfsBase, VfsUtils, VfsHooks, DlgMes {FIXME DELETEME};
|
||||
|
||||
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} var {out} ModList: DataLib.TList {of (O) TWideString}): boolean;
|
||||
// var
|
||||
// AbsFilePath: WideString;
|
||||
// FileHandle: integer;
|
||||
// FileContents: string;
|
||||
// Lines: Utils.TArrayOfStr;
|
||||
// ModNameUtf8: string;
|
||||
// ModName: WideString;
|
||||
// i: integer;
|
||||
|
||||
// // FIXME ModList is not result
|
||||
|
||||
// begin
|
||||
// result := DataLib.NewList(Utils.OWNS_ITEMS);
|
||||
// // * * * * * //
|
||||
// AbsFilePath := VfsUtils.NormalizePath(ModListFilePath);
|
||||
// FileHandle := Windows.CreateFileW(PWideChar(AbsFilePath), Windows.GENERIC_READ, Windows.FILE_SHARE_READ, nil, Windows.OPEN_EXISTING, 0, nil);
|
||||
// // Make available UNICODE path
|
||||
// // Make UTF8 BOM support EF BB BF
|
||||
|
||||
// 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.TrimW(StrLib.Utf8ToWide(ModNameUtf8, StrLib.FAIL_ON_ERROR));
|
||||
|
||||
// if ValidateModName(ModName) then begin
|
||||
// result.Add(TWideString.Create(ModName));
|
||||
// end;
|
||||
// end;
|
||||
// end;
|
||||
// end; // .function LoadModList
|
||||
|
||||
function MapModsFromList_ (const RootDir, ModsDir: WideString; ModList: TList {of (O) TWideString}; Flags: integer = 0): boolean;
|
||||
var
|
||||
AbsRootDir: WideString;
|
||||
AbsModsDir: WideString;
|
||||
FileInfo: VfsUtils.TNativeFileInfo;
|
||||
ModName: WideString;
|
||||
ModPathPrefix: WideString;
|
||||
NumFailedMappings: integer;
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
{!} Assert(ModList <> nil);
|
||||
// * * * * * //
|
||||
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
|
||||
ModPathPrefix := VfsUtils.AddBackslash(AbsModsDir);
|
||||
NumFailedMappings := 0;
|
||||
|
||||
for i := ModList.Count - 1 downto 0 do begin
|
||||
ModName := TWideString(ModList[i]).Value;
|
||||
|
||||
if not VfsBase.MapDir(AbsRootDir, ModPathPrefix + ModName, not VfsBase.OVERWRITE_EXISTING, Flags) then begin
|
||||
Inc(NumFailedMappings);
|
||||
end;
|
||||
end;
|
||||
|
||||
result := (NumFailedMappings = 0) or (NumFailedMappings < ModList.Count);
|
||||
end; // .if
|
||||
end; // .function MapModsFromList
|
||||
|
||||
function MapModsFromList (const RootDir, ModsDir, ModListFile: WideString; Flags: integer = 0): boolean;
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
L: TList;
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
|
||||
end.
|
||||
2
Vfs.dpr
2
Vfs.dpr
@ -3,7 +3,7 @@ library Vfs;
|
||||
Author: Alexander Shostak aka Berserker aka EtherniDee.
|
||||
*)
|
||||
|
||||
uses Windows;
|
||||
uses VfsExport;
|
||||
|
||||
begin
|
||||
System.IsMultiThread := true;
|
||||
|
||||
14
Vfs.dproj
14
Vfs.dproj
@ -16,14 +16,12 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<Version>7.0</Version>
|
||||
<DCC_Define>DEBUG</DCC_Define>
|
||||
<DCC_IOChecking>False</DCC_IOChecking>
|
||||
<DCC_WriteableConstants>True</DCC_WriteableConstants>
|
||||
<DCC_Optimize>False</DCC_Optimize>
|
||||
<DCC_UnitSearchPath>..\Lib\B2;.\Png</DCC_UnitSearchPath>
|
||||
<DCC_ResourcePath>..\Lib\B2;.\Png</DCC_ResourcePath>
|
||||
<DCC_ObjPath>..\Lib\B2;.\Png</DCC_ObjPath>
|
||||
<DCC_IncludePath>..\Lib\B2;.\Png</DCC_IncludePath>
|
||||
<DCC_UnitSearchPath>..\Lib\B2</DCC_UnitSearchPath>
|
||||
<DCC_ResourcePath>..\Lib\B2</DCC_ResourcePath>
|
||||
<DCC_ObjPath>..\Lib\B2</DCC_ObjPath>
|
||||
<DCC_IncludePath>..\Lib\B2</DCC_IncludePath>
|
||||
<DCC_MapFile>3</DCC_MapFile>
|
||||
</PropertyGroup>
|
||||
<ProjectExtensions>
|
||||
@ -33,6 +31,10 @@
|
||||
<BorlandProject><Delphi.Personality><Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</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"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<Excluded_Packages Name="$(BDS)\bin\dcloffice2k100.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
|
||||
<Excluded_Packages Name="$(BDS)\bin\dclofficexp100.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
|
||||
</Excluded_Packages></Delphi.Personality></BorlandProject></BorlandProject>
|
||||
|
||||
213
Vfs.drc
213
Vfs.drc
@ -8,3 +8,216 @@
|
||||
resources were bound to the produced executable.
|
||||
*/
|
||||
|
||||
#define RTLConsts_SInvalidPropertyValue 65424
|
||||
#define RTLConsts_SListCapacityError 65425
|
||||
#define RTLConsts_SListCountError 65426
|
||||
#define RTLConsts_SListIndexError 65427
|
||||
#define RTLConsts_SReadError 65428
|
||||
#define RTLConsts_SSeekNotImplemented 65429
|
||||
#define RTLConsts_SSortedListError 65430
|
||||
#define RTLConsts_SWriteError 65431
|
||||
#define SysConst_SShortDayNameTue 65440
|
||||
#define SysConst_SShortDayNameWed 65441
|
||||
#define SysConst_SShortDayNameThu 65442
|
||||
#define SysConst_SShortDayNameFri 65443
|
||||
#define SysConst_SShortDayNameSat 65444
|
||||
#define SysConst_SLongDayNameSun 65445
|
||||
#define SysConst_SLongDayNameMon 65446
|
||||
#define SysConst_SLongDayNameTue 65447
|
||||
#define SysConst_SLongDayNameWed 65448
|
||||
#define SysConst_SLongDayNameThu 65449
|
||||
#define SysConst_SLongDayNameFri 65450
|
||||
#define SysConst_SLongDayNameSat 65451
|
||||
#define RTLConsts_SAssignError 65452
|
||||
#define RTLConsts_SDuplicateString 65453
|
||||
#define RTLConsts_SFCreateErrorEx 65454
|
||||
#define RTLConsts_SFOpenErrorEx 65455
|
||||
#define SysConst_SShortMonthNameNov 65456
|
||||
#define SysConst_SShortMonthNameDec 65457
|
||||
#define SysConst_SLongMonthNameJan 65458
|
||||
#define SysConst_SLongMonthNameFeb 65459
|
||||
#define SysConst_SLongMonthNameMar 65460
|
||||
#define SysConst_SLongMonthNameApr 65461
|
||||
#define SysConst_SLongMonthNameMay 65462
|
||||
#define SysConst_SLongMonthNameJun 65463
|
||||
#define SysConst_SLongMonthNameJul 65464
|
||||
#define SysConst_SLongMonthNameAug 65465
|
||||
#define SysConst_SLongMonthNameSep 65466
|
||||
#define SysConst_SLongMonthNameOct 65467
|
||||
#define SysConst_SLongMonthNameNov 65468
|
||||
#define SysConst_SLongMonthNameDec 65469
|
||||
#define SysConst_SShortDayNameSun 65470
|
||||
#define SysConst_SShortDayNameMon 65471
|
||||
#define SysConst_SSafecallException 65472
|
||||
#define SysConst_SAssertError 65473
|
||||
#define SysConst_SAbstractError 65474
|
||||
#define SysConst_SModuleAccessViolation 65475
|
||||
#define SysConst_SOSError 65476
|
||||
#define SysConst_SUnkOSError 65477
|
||||
#define SysConst_SShortMonthNameJan 65478
|
||||
#define SysConst_SShortMonthNameFeb 65479
|
||||
#define SysConst_SShortMonthNameMar 65480
|
||||
#define SysConst_SShortMonthNameApr 65481
|
||||
#define SysConst_SShortMonthNameMay 65482
|
||||
#define SysConst_SShortMonthNameJun 65483
|
||||
#define SysConst_SShortMonthNameJul 65484
|
||||
#define SysConst_SShortMonthNameAug 65485
|
||||
#define SysConst_SShortMonthNameSep 65486
|
||||
#define SysConst_SShortMonthNameOct 65487
|
||||
#define SysConst_SVarArrayCreate 65488
|
||||
#define SysConst_SVarArrayBounds 65489
|
||||
#define SysConst_SVarArrayLocked 65490
|
||||
#define SysConst_SInvalidVarCast 65491
|
||||
#define SysConst_SInvalidVarOp 65492
|
||||
#define SysConst_SInvalidVarOpWithHResultWithPrefix 65493
|
||||
#define SysConst_SVarTypeCouldNotConvert 65494
|
||||
#define SysConst_SVarTypeConvertOverflow 65495
|
||||
#define SysConst_SVarOverflow 65496
|
||||
#define SysConst_SVarInvalid 65497
|
||||
#define SysConst_SVarBadType 65498
|
||||
#define SysConst_SVarNotImplemented 65499
|
||||
#define SysConst_SVarUnexpected 65500
|
||||
#define SysConst_SExternalException 65501
|
||||
#define SysConst_SAssertionFailed 65502
|
||||
#define SysConst_SIntfCastError 65503
|
||||
#define SysConst_SOverflow 65504
|
||||
#define SysConst_SUnderflow 65505
|
||||
#define SysConst_SInvalidPointer 65506
|
||||
#define SysConst_SInvalidCast 65507
|
||||
#define SysConst_SAccessViolationArg3 65508
|
||||
#define SysConst_SAccessViolationNoArg 65509
|
||||
#define SysConst_SStackOverflow 65510
|
||||
#define SysConst_SControlC 65511
|
||||
#define SysConst_SPrivilege 65512
|
||||
#define SysConst_SException 65513
|
||||
#define SysConst_SExceptTitle 65514
|
||||
#define SysConst_SInvalidFormat 65515
|
||||
#define SysConst_SArgumentMissing 65516
|
||||
#define SysConst_SDispatchError 65517
|
||||
#define SysConst_SReadAccess 65518
|
||||
#define SysConst_SWriteAccess 65519
|
||||
#define SysConst_STimeEncodeError 65520
|
||||
#define SysConst_SDateEncodeError 65521
|
||||
#define SysConst_SOutOfMemory 65522
|
||||
#define SysConst_SInOutError 65523
|
||||
#define SysConst_SFileNotFound 65524
|
||||
#define SysConst_SInvalidFilename 65525
|
||||
#define SysConst_STooManyOpenFiles 65526
|
||||
#define SysConst_SAccessDenied 65527
|
||||
#define SysConst_SEndOfFile 65528
|
||||
#define SysConst_SDiskFull 65529
|
||||
#define SysConst_SInvalidInput 65530
|
||||
#define SysConst_SDivByZero 65531
|
||||
#define SysConst_SRangeError 65532
|
||||
#define SysConst_SIntOverflow 65533
|
||||
#define SysConst_SInvalidOp 65534
|
||||
#define SysConst_SZeroDivide 65535
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
RTLConsts_SInvalidPropertyValue, "Invalid property value"
|
||||
RTLConsts_SListCapacityError, "List capacity out of bounds (%d)"
|
||||
RTLConsts_SListCountError, "List count out of bounds (%d)"
|
||||
RTLConsts_SListIndexError, "List index out of bounds (%d)"
|
||||
RTLConsts_SReadError, "Stream read error"
|
||||
RTLConsts_SSeekNotImplemented, "%s.Seek not implemented"
|
||||
RTLConsts_SSortedListError, "Operation not allowed on sorted list"
|
||||
RTLConsts_SWriteError, "Stream write error"
|
||||
SysConst_SShortDayNameTue, "Tue"
|
||||
SysConst_SShortDayNameWed, "Wed"
|
||||
SysConst_SShortDayNameThu, "Thu"
|
||||
SysConst_SShortDayNameFri, "Fri"
|
||||
SysConst_SShortDayNameSat, "Sat"
|
||||
SysConst_SLongDayNameSun, "Sunday"
|
||||
SysConst_SLongDayNameMon, "Monday"
|
||||
SysConst_SLongDayNameTue, "Tuesday"
|
||||
SysConst_SLongDayNameWed, "Wednesday"
|
||||
SysConst_SLongDayNameThu, "Thursday"
|
||||
SysConst_SLongDayNameFri, "Friday"
|
||||
SysConst_SLongDayNameSat, "Saturday"
|
||||
RTLConsts_SAssignError, "Cannot assign a %s to a %s"
|
||||
RTLConsts_SDuplicateString, "String list does not allow duplicates"
|
||||
RTLConsts_SFCreateErrorEx, "Cannot create file \"%s\". %s"
|
||||
RTLConsts_SFOpenErrorEx, "Cannot open file \"%s\". %s"
|
||||
SysConst_SShortMonthNameNov, "Nov"
|
||||
SysConst_SShortMonthNameDec, "Dec"
|
||||
SysConst_SLongMonthNameJan, "January"
|
||||
SysConst_SLongMonthNameFeb, "February"
|
||||
SysConst_SLongMonthNameMar, "March"
|
||||
SysConst_SLongMonthNameApr, "April"
|
||||
SysConst_SLongMonthNameMay, "May"
|
||||
SysConst_SLongMonthNameJun, "June"
|
||||
SysConst_SLongMonthNameJul, "July"
|
||||
SysConst_SLongMonthNameAug, "August"
|
||||
SysConst_SLongMonthNameSep, "September"
|
||||
SysConst_SLongMonthNameOct, "October"
|
||||
SysConst_SLongMonthNameNov, "November"
|
||||
SysConst_SLongMonthNameDec, "December"
|
||||
SysConst_SShortDayNameSun, "Sun"
|
||||
SysConst_SShortDayNameMon, "Mon"
|
||||
SysConst_SSafecallException, "Exception in safecall method"
|
||||
SysConst_SAssertError, "%s (%s, line %d)"
|
||||
SysConst_SAbstractError, "Abstract Error"
|
||||
SysConst_SModuleAccessViolation, "Access violation at address %p in module '%s'. %s of address %p"
|
||||
SysConst_SOSError, "System Error. Code: %d.\r\n%s"
|
||||
SysConst_SUnkOSError, "A call to an OS function failed"
|
||||
SysConst_SShortMonthNameJan, "Jan"
|
||||
SysConst_SShortMonthNameFeb, "Feb"
|
||||
SysConst_SShortMonthNameMar, "Mar"
|
||||
SysConst_SShortMonthNameApr, "Apr"
|
||||
SysConst_SShortMonthNameMay, "May"
|
||||
SysConst_SShortMonthNameJun, "Jun"
|
||||
SysConst_SShortMonthNameJul, "Jul"
|
||||
SysConst_SShortMonthNameAug, "Aug"
|
||||
SysConst_SShortMonthNameSep, "Sep"
|
||||
SysConst_SShortMonthNameOct, "Oct"
|
||||
SysConst_SVarArrayCreate, "Error creating variant or safe array"
|
||||
SysConst_SVarArrayBounds, "Variant or safe array index out of bounds"
|
||||
SysConst_SVarArrayLocked, "Variant or safe array is locked"
|
||||
SysConst_SInvalidVarCast, "Invalid variant type conversion"
|
||||
SysConst_SInvalidVarOp, "Invalid variant operation"
|
||||
SysConst_SInvalidVarOpWithHResultWithPrefix, "Invalid variant operation (%s%.8x)\n%s"
|
||||
SysConst_SVarTypeCouldNotConvert, "Could not convert variant of type (%s) into type (%s)"
|
||||
SysConst_SVarTypeConvertOverflow, "Overflow while converting variant of type (%s) into type (%s)"
|
||||
SysConst_SVarOverflow, "Variant overflow"
|
||||
SysConst_SVarInvalid, "Invalid argument"
|
||||
SysConst_SVarBadType, "Invalid variant type"
|
||||
SysConst_SVarNotImplemented, "Operation not supported"
|
||||
SysConst_SVarUnexpected, "Unexpected variant error"
|
||||
SysConst_SExternalException, "External exception %x"
|
||||
SysConst_SAssertionFailed, "Assertion failed"
|
||||
SysConst_SIntfCastError, "Interface not supported"
|
||||
SysConst_SOverflow, "Floating point overflow"
|
||||
SysConst_SUnderflow, "Floating point underflow"
|
||||
SysConst_SInvalidPointer, "Invalid pointer operation"
|
||||
SysConst_SInvalidCast, "Invalid class typecast"
|
||||
SysConst_SAccessViolationArg3, "Access violation at address %p. %s of address %p"
|
||||
SysConst_SAccessViolationNoArg, "Access violation"
|
||||
SysConst_SStackOverflow, "Stack overflow"
|
||||
SysConst_SControlC, "Control-C hit"
|
||||
SysConst_SPrivilege, "Privileged instruction"
|
||||
SysConst_SException, "Exception %s in module %s at %p.\r\n%s%s\r\n"
|
||||
SysConst_SExceptTitle, "Application Error"
|
||||
SysConst_SInvalidFormat, "Format '%s' invalid or incompatible with argument"
|
||||
SysConst_SArgumentMissing, "No argument for format '%s'"
|
||||
SysConst_SDispatchError, "Variant method calls not supported"
|
||||
SysConst_SReadAccess, "Read"
|
||||
SysConst_SWriteAccess, "Write"
|
||||
SysConst_STimeEncodeError, "Invalid argument to time encode"
|
||||
SysConst_SDateEncodeError, "Invalid argument to date encode"
|
||||
SysConst_SOutOfMemory, "Out of memory"
|
||||
SysConst_SInOutError, "I/O error %d"
|
||||
SysConst_SFileNotFound, "File not found"
|
||||
SysConst_SInvalidFilename, "Invalid filename"
|
||||
SysConst_STooManyOpenFiles, "Too many open files"
|
||||
SysConst_SAccessDenied, "File access denied"
|
||||
SysConst_SEndOfFile, "Read beyond end of file"
|
||||
SysConst_SDiskFull, "Disk full"
|
||||
SysConst_SInvalidInput, "Invalid numeric input"
|
||||
SysConst_SDivByZero, "Division by zero"
|
||||
SysConst_SRangeError, "Range check error"
|
||||
SysConst_SIntOverflow, "Integer overflow"
|
||||
SysConst_SInvalidOp, "Invalid floating point operation"
|
||||
SysConst_SZeroDivide, "Floating point division by zero"
|
||||
END
|
||||
|
||||
/* D:\Soft\Programming\Delphi\source\SRC\Vfs\Vfs.drf */
|
||||
|
||||
13
VfsBase.pas
13
VfsBase.pas
@ -93,14 +93,19 @@ function GetThreadVfsDisabler: TThreadVfsDisabler;
|
||||
function RunVfs (DirListingOrder: TDirListingSortType): boolean;
|
||||
|
||||
(* Temporarily pauses VFS, but does not reset existing mappings *)
|
||||
function PauseVfs: boolean; stdcall;
|
||||
function PauseVfs: LONGBOOL; stdcall;
|
||||
|
||||
(* Stops VFS and clears all mappings *)
|
||||
function ResetVfs: boolean; stdcall;
|
||||
function ResetVfs: LONGBOOL; stdcall;
|
||||
|
||||
(* Returns true if VFS is active globally and for current thread *)
|
||||
function IsVfsActive: boolean;
|
||||
|
||||
function EnterVfs: boolean;
|
||||
procedure LeaveVfs;
|
||||
function EnterVfsConfig: boolean;
|
||||
procedure LeaveVfsConfig;
|
||||
|
||||
(* Returns real path for VFS item by its absolute virtual path or empty string. Optionally returns file info structure *)
|
||||
function GetVfsItemRealPath (const AbsVirtPath: WideString; {n} FileInfo: PNativeFileInfo = nil): WideString;
|
||||
|
||||
@ -315,7 +320,7 @@ begin
|
||||
end; // .if
|
||||
end; // .function RunVfs
|
||||
|
||||
function PauseVfs: boolean; stdcall;
|
||||
function PauseVfs: LONGBOOL; stdcall;
|
||||
begin
|
||||
result := not DisableVfsForThisThread;
|
||||
|
||||
@ -328,7 +333,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function ResetVfs: boolean; stdcall;
|
||||
function ResetVfs: LONGBOOL; stdcall;
|
||||
begin
|
||||
result := not DisableVfsForThisThread;
|
||||
|
||||
|
||||
184
VfsControl.pas
Normal file
184
VfsControl.pas
Normal file
@ -0,0 +1,184 @@
|
||||
unit VfsControl;
|
||||
(*
|
||||
Facade unit for high-level VFS API.
|
||||
*)
|
||||
|
||||
|
||||
(***) interface (***)
|
||||
|
||||
uses
|
||||
Windows, SysUtils,
|
||||
Utils, WinUtils, TypeWrappers, DataLib,
|
||||
Files, StrLib,
|
||||
VfsBase, VfsUtils, VfsHooks, DlgMes {FIXME DELETEME};
|
||||
|
||||
type
|
||||
(* Import *)
|
||||
TWideString = TypeWrappers.TWideString;
|
||||
|
||||
|
||||
(* Runs all VFS subsystems, unless VFS is already running *)
|
||||
function RunVfs (DirListingOrder: VfsBase.TDirListingSortType): LONGBOOL; stdcall;
|
||||
|
||||
(* Loads mod list from file and maps each mod directory to specified root directory.
|
||||
File with mod list is treated as (BOM or BOM-less) UTF-8 plain text file, where each mod name is separated
|
||||
from another one via Line Feed (#10) character. Each mod named is trimmed, converted to UCS16 and validated before
|
||||
adding to list. Invalid or empty mods will be skipped.
|
||||
Returns true if root and mods directory existed and file with mod list was loaded successfully *)
|
||||
function MapModsFromList (const RootDir, ModsDir, ModListFile: WideString; Flags: integer = 0): boolean;
|
||||
|
||||
(***) implementation (***)
|
||||
|
||||
|
||||
type
|
||||
TModList = DataLib.TList {of (O) TWideString};
|
||||
|
||||
|
||||
function RunVfs (DirListingOrder: VfsBase.TDirListingSortType): LONGBOOL; 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} var {out} ModList: TModList): boolean;
|
||||
const
|
||||
UTF8_BOM = #$EF#$BB#$BF;
|
||||
|
||||
var
|
||||
{O} OpenedFile: Files.TFile;
|
||||
AbsFilePath: WideString;
|
||||
FileHandle: integer;
|
||||
FileContents: string;
|
||||
Lines: Utils.TArrayOfStr;
|
||||
ModNameUtf8: string;
|
||||
ModName: WideString;
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
OpenedFile := Files.TFile.Create;
|
||||
// * * * * * //
|
||||
AbsFilePath := VfsUtils.NormalizePath(ModListFilePath);
|
||||
FileHandle := integer(Windows.INVALID_HANDLE_VALUE);
|
||||
result := AbsFilePath <> '';
|
||||
|
||||
if result then begin
|
||||
FileHandle := Windows.CreateFileW(PWideChar(AbsFilePath), Windows.GENERIC_READ, Windows.FILE_SHARE_READ, nil, Windows.OPEN_EXISTING, 0, 0);
|
||||
result := FileHandle <> integer(Windows.INVALID_HANDLE_VALUE);
|
||||
end;
|
||||
|
||||
if result then begin
|
||||
result := Files.ReadFileContents(FileHandle, FileContents);
|
||||
|
||||
if result then begin
|
||||
SysUtils.FreeAndNil(ModList);
|
||||
ModList := DataLib.NewList(Utils.OWNS_ITEMS);
|
||||
|
||||
if (Length(FileContents) >= 3) and (FileContents[1] = UTF8_BOM[1]) and (FileContents[2] = UTF8_BOM[2]) and (FileContents[3] = UTF8_BOM[3]) then begin
|
||||
FileContents := Copy(FileContents, Length(UTF8_BOM) + 1);
|
||||
end;
|
||||
|
||||
Lines := StrLib.Explode(FileContents, #10);
|
||||
|
||||
for i := 0 to High(Lines) do begin
|
||||
ModNameUtf8 := Lines[i];
|
||||
ModName := StrLib.TrimW(StrLib.Utf8ToWide(ModNameUtf8, StrLib.FAIL_ON_ERROR));
|
||||
|
||||
if ValidateModName(ModName) then begin
|
||||
ModList.Add(TWideString.Create(ModName));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
Windows.CloseHandle(FileHandle);
|
||||
end; // .if
|
||||
// * * * * * //
|
||||
SysUtils.FreeAndNil(OpenedFile);
|
||||
end; // .function LoadModList
|
||||
|
||||
function MapModsFromList_ (const RootDir, ModsDir: WideString; ModList: TModList; Flags: integer = 0): boolean;
|
||||
var
|
||||
AbsRootDir: WideString;
|
||||
AbsModsDir: WideString;
|
||||
FileInfo: VfsUtils.TNativeFileInfo;
|
||||
ModName: WideString;
|
||||
ModPathPrefix: WideString;
|
||||
i: integer;
|
||||
|
||||
begin
|
||||
{!} Assert(ModList <> nil);
|
||||
// * * * * * //
|
||||
AbsRootDir := VfsUtils.NormalizePath(RootDir);
|
||||
AbsModsDir := VfsUtils.NormalizePath(ModsDir);
|
||||
result := (AbsRootDir <> '') and (AbsModsDir <> '') and
|
||||
VfsUtils.GetFileInfo(AbsRootDir, FileInfo) and Utils.HasFlag(Windows.FILE_ATTRIBUTE_DIRECTORY, FileInfo.Base.FileAttributes) and
|
||||
VfsUtils.GetFileInfo(AbsModsDir, FileInfo) and Utils.HasFlag(Windows.FILE_ATTRIBUTE_DIRECTORY, FileInfo.Base.FileAttributes);
|
||||
|
||||
if result then begin
|
||||
ModPathPrefix := VfsUtils.AddBackslash(AbsModsDir);
|
||||
|
||||
for i := ModList.Count - 1 downto 0 do begin
|
||||
ModName := TWideString(ModList[i]).Value;
|
||||
VfsBase.MapDir(AbsRootDir, ModPathPrefix + ModName, not VfsBase.OVERWRITE_EXISTING, Flags);
|
||||
end;
|
||||
end; // .if
|
||||
end; // .function MapModsFromList
|
||||
|
||||
function MapModsFromList (const RootDir, ModsDir, ModListFile: WideString; Flags: integer = 0): boolean;
|
||||
var
|
||||
{O} ModList: TModList;
|
||||
|
||||
begin
|
||||
ModList := nil;
|
||||
// * * * * * //
|
||||
result := VfsBase.EnterVfsConfig;
|
||||
|
||||
if result then begin
|
||||
try
|
||||
result := LoadModList(ModListFile, ModList) and MapModsFromList_(RootDir, ModsDir, ModList, Flags);
|
||||
finally
|
||||
VfsBase.LeaveVfsConfig;
|
||||
end;
|
||||
end;
|
||||
// * * * * * //
|
||||
SysUtils.FreeAndNil(ModList);
|
||||
end; // .function MapModsFromList
|
||||
|
||||
end.
|
||||
@ -7,7 +7,8 @@ unit VfsExport;
|
||||
(***) interface (***)
|
||||
|
||||
uses
|
||||
VfsDebug, VfsBase, VfsControl;
|
||||
Windows,
|
||||
VfsDebug, VfsBase, VfsControl, DlgMes, Files, FilesEx;
|
||||
|
||||
exports
|
||||
VfsDebug.SetLoggingProc,
|
||||
@ -21,12 +22,36 @@ exports
|
||||
(***) implementation (***)
|
||||
|
||||
|
||||
function MapDir (const VirtPath, RealPath: PWideChar; OverwriteExisting: boolean; Flags: integer = 0): boolean; stdcall;
|
||||
function MapDir (const VirtPath, RealPath: PWideChar; OverwriteExisting: boolean; Flags: integer = 0): LONGBOOL; stdcall;
|
||||
begin
|
||||
result := VfsBase.MapDir(WideString(VirtPath), WideString(RealPath), OverwriteExisting, Flags);
|
||||
end;
|
||||
|
||||
exports
|
||||
MapDir;
|
||||
function MapDirA (const VirtPath, RealPath: PAnsiChar; OverwriteExisting: boolean; Flags: integer = 0): LONGBOOL; stdcall;
|
||||
begin
|
||||
result := VfsBase.MapDir(WideString(VirtPath), WideString(RealPath), OverwriteExisting, Flags);
|
||||
end;
|
||||
|
||||
function MapModsFromList (const RootDir, ModsDir, ModListFile: PWideChar; Flags: integer = 0): LONGBOOL; stdcall;
|
||||
begin
|
||||
result := VfsControl.MapModsFromList(WideString(RootDir), WideString(ModsDir), WideString(ModListFile), Flags);
|
||||
end;
|
||||
|
||||
function MapModsFromListA (const RootDir, ModsDir, ModListFile: PAnsiChar; Flags: integer = 0): LONGBOOL; stdcall;
|
||||
begin
|
||||
result := VfsControl.MapModsFromList(WideString(RootDir), WideString(ModsDir), WideString(ModListFile), Flags);
|
||||
end;
|
||||
|
||||
exports
|
||||
MapDir,
|
||||
MapDirA,
|
||||
MapModsFromList,
|
||||
MapModsFromListA;
|
||||
|
||||
// var s: string;
|
||||
// begin
|
||||
// assert(MapModsFromListA('D:\Heroes 3', 'D:\Heroes 3\Mods', 'D:\Heroes 3\Mods\list.txt'));
|
||||
// VfsControl.RunVfs(SORT_FIFO);
|
||||
// ReadFileContents('D:\Heroes 3\Data\s\pHoenix.erm', s);
|
||||
// VarDump([GetFileList('D:\Heroes 3\Data\s\*', FILES_AND_DIRS).ToText(#13#10)]);
|
||||
end.
|
||||
|
||||
@ -633,6 +633,7 @@ begin
|
||||
end;
|
||||
|
||||
initialization
|
||||
System.IsMultiThread := true;
|
||||
HooksCritSection.Init;
|
||||
finalization
|
||||
with VfsBase.VfsCritSection do begin
|
||||
|
||||
Loading…
Reference in New Issue
Block a user