mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-03 19:43:53 +02:00
1173 lines
33 KiB
PHP
1173 lines
33 KiB
PHP
{%MainUnit lazfileutils.pas}
|
|
|
|
|
|
var
|
|
//procedural variables for procedures that are implemented different on Win9x and NT or WinCE platform
|
|
//They are intialized in InitLazFileUtils
|
|
_FileAgeUtf8 : function(const Filename:string):Longint;
|
|
_FileSizeUtf8 : function(const Filename: string): int64;
|
|
_FileSetDateUtf8 : function(const FileName: String; Age: Longint): Longint;
|
|
_FindFirstUtf8 : function(const Path: string; Attr: Longint;
|
|
out Rslt: TSearchRec): Longint;
|
|
_FindNextUtf8 : function(var Rslt: TSearchRec): Longint;
|
|
_FileGetAttrUtf8 : function(const FileName: String): Longint;
|
|
_FileSetAttrUtf8 : function(const Filename: String; Attr: longint): Longint;
|
|
_DeleteFileUtf8 : function(const FileName: String): Boolean;
|
|
_RenameFileUtf8 : function(const OldName, NewName: String): Boolean;
|
|
_GetCurrentDirUtf8 : function: String ;
|
|
_GetDirUtf8 : procedure(DriveNr: Byte; var Dir: String);
|
|
_FileOpenUtf8 : function(Const FileName : string; Mode : Integer) : THandle;
|
|
_FileCreateUtf8 : function(Const FileName : String; ShareMode : Integer; Rights: Integer) : THandle;
|
|
_SetCurrentDirUtf8 : function(const NewDir: String): Boolean;
|
|
_CreateDirUtf8 : function(const NewDir: String): Boolean;
|
|
_RemoveDirUtf8 : function(const Dir: String): Boolean ;
|
|
_GetAppConfigDirUTF8 : function(Global: Boolean; Create: boolean = false): string;
|
|
_GetAppConfigFileUTF8: function(Global: Boolean; SubDir: boolean = false;CreateDir: boolean = false): string;
|
|
_GetShellLinkTarget : function(const FileName: string): string;
|
|
|
|
|
|
|
|
|
|
|
|
// ************* "Stubs" that just call Ansi or WideString routines ***********************
|
|
|
|
|
|
function GetCurrentDirUTF8: String;
|
|
begin
|
|
Result:=_GetCurrentDirUtf8();
|
|
end;
|
|
|
|
procedure GetDirUtf8(DriveNr: Byte; var Dir: String);
|
|
begin
|
|
_GetDirUtf8(DriveNr, Dir);
|
|
end;
|
|
|
|
function FileOpenUTF8(Const FileName : string; Mode : Integer) : THandle;
|
|
begin
|
|
Result := _FileOpenUtf8(FileName, Mode);
|
|
end;
|
|
|
|
function FileCreateUTF8(Const FileName : string) : THandle;
|
|
begin
|
|
Result := _FileCreateUtf8(FileName, fmShareExclusive, 0);
|
|
end;
|
|
|
|
function FileCreateUTF8(Const FileName : string; Rights: Cardinal) : THandle;
|
|
begin
|
|
Result := _FileCreateUtf8(FileName, fmShareExclusive, Rights);
|
|
end;
|
|
|
|
Function FileCreateUtf8(Const FileName : String; ShareMode : Integer; Rights : Cardinal) : THandle;
|
|
begin
|
|
Result := _FileCreateUtf8(FileName, ShareMode, Rights);
|
|
end;
|
|
|
|
function FileGetAttrUTF8(const FileName: String): Longint;
|
|
begin
|
|
Result := _FileGetAttrUtf8(FileName);
|
|
end;
|
|
|
|
function FileSetAttrUTF8(const Filename: String; Attr: longint): Longint;
|
|
begin
|
|
Result := _FileSetAttrUtf8(Filename, Attr);
|
|
InvalidateFileStateCache(Filename);
|
|
end;
|
|
|
|
function FileAgeUTF8(const FileName: String): Longint;
|
|
begin
|
|
Result := _FileAgeUtf8(FileName);
|
|
end;
|
|
|
|
function FileSetDateUTF8(const FileName: String; Age: Longint): Longint;
|
|
begin
|
|
Result := _FileSetDateUtf8(Filename, Age);
|
|
InvalidateFileStateCache(Filename);
|
|
end;
|
|
|
|
function FileSizeUtf8(const Filename: string): int64;
|
|
begin
|
|
Result := _FileSizeUtf8(FileName);
|
|
end;
|
|
|
|
function CreateDirUTF8(const NewDir: String): Boolean;
|
|
begin
|
|
Result := _CreateDirUTF8(NewDir);
|
|
end;
|
|
|
|
function RemoveDirUTF8(const Dir: String): Boolean;
|
|
begin
|
|
Result := _RemoveDirUtf8(Dir);
|
|
end;
|
|
|
|
function DeleteFileUTF8(const FileName: String): Boolean;
|
|
begin
|
|
Result := _DeleteFileUtf8(Filename);
|
|
if Result then
|
|
InvalidateFileStateCache;
|
|
end;
|
|
|
|
function RenameFileUTF8(const OldName, NewName: String): Boolean;
|
|
begin
|
|
Result := _RenameFileUtf8(OldName,NewName);
|
|
if Result then
|
|
InvalidateFileStateCache;
|
|
end;
|
|
|
|
function SetCurrentDirUTF8(const NewDir: String): Boolean;
|
|
begin
|
|
Result := _SetCurrentDirUtf8(NewDir);
|
|
end;
|
|
|
|
function FindFirstUTF8(const Path: string; Attr: Longint; out Rslt: TSearchRec
|
|
): Longint;
|
|
begin
|
|
Result := _FindFirstUtf8(Path, Attr, Rslt);
|
|
end;
|
|
|
|
function FindNextUTF8(var Rslt: TSearchRec): Longint;
|
|
begin
|
|
Result := _FindNextUtf8(Rslt);
|
|
end;
|
|
|
|
|
|
function GetAppConfigDirUTF8(Global: Boolean; Create: boolean = false): string;
|
|
begin
|
|
Result := _GetAppConfigDirUtf8(Global, Create);
|
|
end;
|
|
|
|
function GetAppConfigFileUTF8(Global: Boolean; SubDir: boolean;
|
|
CreateDir: boolean): string;
|
|
begin
|
|
Result := _GetAppConfigFileUTF8(Global, SubDir, CreateDir);
|
|
end;
|
|
|
|
function ReadAllLinks(const Filename: string;
|
|
ExceptionOnError: boolean): string;
|
|
begin
|
|
// not supported under Windows
|
|
Result:=Filename;
|
|
end;
|
|
|
|
function GetPhysicalFilename(const Filename: string;
|
|
OnError: TPhysicalFilenameOnError): string;
|
|
begin
|
|
if OnError=pfeEmpty then ;
|
|
Result:=Filename;
|
|
end;
|
|
|
|
function GetShellLinkTarget(const FileName: string): string;
|
|
begin
|
|
Result := _GetShellLinkTarget(FileName);
|
|
end;
|
|
|
|
// ******** Start of AnsiString specific implementations ************
|
|
|
|
{$ifndef WinCE}
|
|
//No ANSII functions on WinCE
|
|
function GetCurrentDirAnsi: String;
|
|
begin
|
|
Result:=SysToUTF8(SysUtils.GetCurrentDir);
|
|
end;
|
|
|
|
procedure GetDirAnsi(DriveNr: Byte; var Dir: String);
|
|
begin
|
|
GetDir(DriveNr, Dir);
|
|
Dir := SysToUtf8(Dir);
|
|
end;
|
|
|
|
|
|
function FileOpenAnsi(Const FileName : string; Mode : Integer) : THandle;
|
|
begin
|
|
Result := FileOpen(UTF8ToSys(FileName), Mode);
|
|
//if fail api return feInvalidHandle (INVALIDE_HANDLE=feInvalidHandle=-1)
|
|
end;
|
|
|
|
|
|
function FileCreateAnsi(Const FileName : string; ShareMode: Integer; Rights: Integer) : THandle;
|
|
begin
|
|
Result := FileCreate(Utf8ToSys(FileName), Sharemode, Rights);
|
|
end;
|
|
|
|
function FileGetAttrAnsi(const FileName: String): Longint;
|
|
begin
|
|
Result:=SysUtils.FileGetAttr(UTF8ToSys(Filename));
|
|
end;
|
|
|
|
function FileSetAttrAnsi(const Filename: String; Attr: longint): Longint;
|
|
begin
|
|
Result:=SysUtils.FileSetAttr(UTF8ToSys(Filename),Attr);
|
|
end;
|
|
|
|
|
|
function FileAgeAnsi(const FileName: String): Longint;
|
|
begin
|
|
Result := SysUtils.FileAge(UTF8ToSys(Filename));
|
|
end;
|
|
|
|
function FileSetDateAnsi(const FileName: String; Age: Longint): Longint;
|
|
begin
|
|
Result := SysUtils.FileSetDate(UTF8ToSys(Filename), Age);
|
|
end;
|
|
|
|
function FileSizeAnsi(const Filename: string): int64;
|
|
var
|
|
FindData: TWIN32FindDataA;
|
|
FindHandle: THandle;
|
|
Str: AnsiString;
|
|
begin
|
|
Str := Utf8ToAnsi(Filename);
|
|
FindHandle := Windows.FindFirstFileA(PAnsiChar(Str), FindData{%H-});
|
|
if FindHandle = Windows.Invalid_Handle_value then
|
|
begin
|
|
Result := -1;
|
|
exit;
|
|
end;
|
|
Result := (int64(FindData.nFileSizeHigh) shl 32) + FindData.nFileSizeLow;
|
|
Windows.FindClose(FindHandle);
|
|
end;
|
|
|
|
function CreateDirAnsi(const NewDir: String): Boolean;
|
|
begin
|
|
Result:=SysUtils.CreateDir(UTF8ToSys(NewDir));
|
|
end;
|
|
|
|
function RemoveDirAnsi(const Dir: String): Boolean;
|
|
begin
|
|
Result:=SysUtils.RemoveDir(UTF8ToSys(Dir));
|
|
end;
|
|
|
|
function DeleteFileAnsi(const FileName: String): Boolean;
|
|
begin
|
|
Result:=SysUtils.DeleteFile(UTF8ToSys(Filename));
|
|
end;
|
|
|
|
function RenameFileAnsi(const OldName, NewName: String): Boolean;
|
|
begin
|
|
Result:=SysUtils.RenameFile(UTF8ToSys(OldName),UTF8ToSys(NewName));
|
|
end;
|
|
|
|
function SetCurrentDirAnsi(const NewDir: String): Boolean;
|
|
begin
|
|
Result:=SysUtils.SetCurrentDir(UTF8ToSys(NewDir));
|
|
end;
|
|
|
|
function FindFirstAnsi(const Path: string; Attr: Longint; out Rslt: TSearchRec): Longint;
|
|
begin
|
|
Result:=SysUtils.FindFirst(UTF8ToSys(Path),Attr,Rslt);
|
|
Rslt.Name:=SysToUTF8(Rslt.Name);
|
|
end;
|
|
|
|
function FindNextAnsi(var Rslt: TSearchRec): Longint;
|
|
begin
|
|
Rslt.Name:=UTF8ToSys(Rslt.Name);
|
|
Result:=SysUtils.FindNext(Rslt);
|
|
Rslt.Name:=SysToUTF8(Rslt.Name);
|
|
end;
|
|
|
|
function GetAppConfigDirAnsi(Global: Boolean; Create: boolean = false): string;
|
|
begin
|
|
Result := SysToUTF8(SysUtils.GetAppConfigDir(Global));
|
|
if Result = '' then exit;
|
|
if Create and not ForceDirectoriesUTF8(Result) then
|
|
raise EInOutError.Create(Format(lrsUnableToCreateConfigDirectoryS,[Result]));
|
|
end;
|
|
|
|
function GetAppConfigFileAnsi(Global: Boolean; SubDir: boolean;
|
|
CreateDir: boolean): string;
|
|
var
|
|
Dir: string;
|
|
begin
|
|
Result := SysToUTF8(SysUtils.GetAppConfigFile(Global,SubDir));
|
|
if not CreateDir then exit;
|
|
Dir := ExtractFilePath(Result);
|
|
if Dir = '' then exit;
|
|
if not ForceDirectoriesUTF8(Dir) then
|
|
raise EInOutError.Create(Format(lrsUnableToCreateConfigDirectoryS,[Dir]));
|
|
end;
|
|
|
|
function GetShellLinkTargetAnsi(const FileName: string): string;
|
|
{$if (fpc_fullversion >= 20604)}
|
|
var
|
|
ShellLinkA: IShellLinkA;
|
|
PersistFile: IPersistFile;
|
|
WideFileName: WideString;
|
|
AnsiPath: array [0 .. MAX_PATH] of Char;
|
|
WinFindData: WIN32_FIND_DATAA;
|
|
{$endif}
|
|
begin
|
|
Result := FileName;
|
|
{$if fpc_fullversion >= 20604}
|
|
if (LowerCase(ExtractFileExt(FileName)) = '.lnk') then
|
|
begin
|
|
if (CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER,
|
|
IShellLinkA, ShellLinkA) = S_OK) then
|
|
if (ShellLinkA.QueryInterface(IPersistFile, PersistFile) = S_OK) then
|
|
begin
|
|
WideFileName := Utf8ToUtf16(FileName);
|
|
FillChar(WinFindData{%H-}, SizeOf(WinFindData), 0);
|
|
if (PersistFile.Load(POleStr(WideFileName), STGM_READ) = S_OK) then
|
|
begin
|
|
if (ShellLinkA.GetPath(AnsiPath, Length(AnsiPath),
|
|
WinFindData, SLGP_UNCPRIORITY) = S_OK) then
|
|
begin
|
|
Result := SysToUtf8(AnsiPath); // implicit conversion
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
{$endif}
|
|
end;
|
|
|
|
|
|
{$endif WinCE}
|
|
|
|
// ******** End of AnsiString specific implementations ************
|
|
|
|
|
|
// ******** Start of WideString specific implementations ************
|
|
|
|
const
|
|
ShareModes: array[0..4] of Integer = (
|
|
0,
|
|
0,
|
|
FILE_SHARE_READ,
|
|
FILE_SHARE_WRITE,
|
|
FILE_SHARE_READ or FILE_SHARE_WRITE);
|
|
|
|
AccessModes: array[0..2] of Cardinal = (
|
|
GENERIC_READ,
|
|
GENERIC_WRITE,
|
|
GENERIC_READ or GENERIC_WRITE);
|
|
|
|
function WinToDosTime(Var Wtime : TFileTime; var DTime:longint):longbool;
|
|
var
|
|
lft : TFileTime;
|
|
begin
|
|
WinToDosTime:=FileTimeToLocalFileTime(WTime,lft{%H-})
|
|
{$ifndef WinCE}
|
|
and FileTimeToDosDateTime(lft,Longrec(Dtime).Hi,LongRec(DTIME).lo)
|
|
{$endif}
|
|
;
|
|
end;
|
|
|
|
Function DosToWinTime(DosTime:longint; Var Wintime : TFileTime):longbool;
|
|
var
|
|
lft : TFileTime;
|
|
begin
|
|
DosToWinTime:=
|
|
{$ifndef wince}
|
|
DosDateTimeToFileTime(longrec(DosTime).hi,longrec(DosTime).lo,@lft) and
|
|
{$endif}
|
|
LocalFileTimeToFileTime(lft,Wintime); ;
|
|
end;
|
|
|
|
function GetCurrentDirWide: String;
|
|
{$ifndef WinCE}
|
|
var
|
|
w : WideString;
|
|
res : Integer;
|
|
{$endif}
|
|
begin
|
|
{$ifdef WinCE}
|
|
Result := '\';
|
|
// Previously we sent an exception here, which is correct, but this causes
|
|
// trouble with code which isnt tested for WinCE, so lets just send a dummy result instead
|
|
// Exception.Create('[GetCurrentDirWide] The concept of the current directory doesn''t exist in Windows CE');
|
|
{$else}
|
|
res:=GetCurrentDirectoryW(0, nil);
|
|
SetLength(w, res);
|
|
res:=Windows.GetCurrentDirectoryW(res, @w[1]);
|
|
SetLength(w, res);
|
|
Result:=UTF8Encode(w);
|
|
{$endif}
|
|
end;
|
|
|
|
procedure GetDirWide(DriveNr: Byte; var Dir: String);
|
|
{This procedure may not be threadsafe, because SetCurrentDirectory isn't}
|
|
{$ifndef WinCE}
|
|
var
|
|
w, D: WideString;
|
|
SavedDir: WideString;
|
|
res : Integer;
|
|
{$endif}
|
|
begin
|
|
{$ifdef WinCE}
|
|
Dir := '\';
|
|
// Previously we sent an exception here, which is correct, but this causes
|
|
// trouble with code which isnt tested for WinCE, so lets just send a dummy result instead
|
|
// Exception.Create('[GetCurrentDirWide] The concept of the current directory doesn''t exist in Windows CE');
|
|
{$else}
|
|
//writeln('GetDirWide START');
|
|
if not (DriveNr = 0) then
|
|
begin
|
|
res := GetCurrentDirectoryW(0, nil);
|
|
SetLength(SavedDir, res);
|
|
res:=Windows.GetCurrentDirectoryW(res, @SavedDir[1]);
|
|
SetLength(SavedDir,res);
|
|
|
|
D := WideChar(64 + DriveNr) + ':';
|
|
if not SetCurrentDirectoryW(@D[1]) then
|
|
begin
|
|
Dir := Char(64 + DriveNr) + ':\';
|
|
SetCurrentDirectoryW(@SavedDir[1]);
|
|
Exit;
|
|
end;
|
|
end;
|
|
res := GetCurrentDirectoryW(0, nil);
|
|
SetLength(w, res);
|
|
res := GetCurrentDirectoryW(res, @w[1]);
|
|
SetLength(w, res);
|
|
Dir:=UTF8Encode(w);
|
|
if not (DriveNr = 0) then SetCurrentDirectoryW(@SavedDir[1]);
|
|
//writeln('GetDirWide END');
|
|
{$endif}
|
|
end;
|
|
|
|
|
|
function FileOpenWide(Const FileName : string; Mode : Integer) : THandle;
|
|
|
|
begin
|
|
Result := CreateFileW(PWideChar(UTF8Decode(FileName)), dword(AccessModes[Mode and 3]),
|
|
dword(ShareModes[(Mode and $F0) shr 4]), nil, OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL, 0);
|
|
//if fail api return feInvalidHandle (INVALIDE_HANDLE=feInvalidHandle=-1)
|
|
end;
|
|
|
|
|
|
function FileCreateWide(Const FileName : string; ShareMode: Integer; {%H-}Rights: Integer) : THandle;
|
|
begin
|
|
Result := CreateFileW(PWideChar(UTF8Decode(FileName)), GENERIC_READ or GENERIC_WRITE,
|
|
dword(ShareModes[(ShareMode and $F0) shr 4]), nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
|
|
end;
|
|
|
|
|
|
function FileGetAttrWide(const FileName: String): Longint;
|
|
begin
|
|
Result:=Integer(Windows.GetFileAttributesW(PWideChar(UTF8Decode(FileName))));
|
|
end;
|
|
|
|
function FileSetAttrWide(const Filename: String; Attr: longint): Longint;
|
|
begin
|
|
if Windows.SetFileAttributesW(PWideChar(UTF8Decode(FileName)), Attr) then
|
|
Result:=0
|
|
else
|
|
Result := Integer(Windows.GetLastError);
|
|
end;
|
|
|
|
function FileAgeWide(const FileName: String): Longint;
|
|
var
|
|
Hnd: THandle;
|
|
FindData: TWin32FindDataW;
|
|
begin
|
|
Result := -1;
|
|
Hnd := FindFirstFileW(PWideChar(UTF8ToUTF16(FileName)), FindData{%H-});
|
|
if Hnd <> Windows.INVALID_HANDLE_VALUE then
|
|
begin
|
|
Windows.FindClose(Hnd);
|
|
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
|
|
If WinToDosTime(FindData.ftLastWriteTime,Result) then
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
function FileSetDateWide(const FileName: String; Age: Longint): Longint;
|
|
var
|
|
FT:TFileTime;
|
|
fh: HANDLE;
|
|
begin
|
|
try
|
|
fh := CreateFileW(PWideChar(UTF8ToUTF16(FileName)),
|
|
FILE_WRITE_ATTRIBUTES,
|
|
0, nil, OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL, 0);
|
|
if (fh <> feInvalidHandle) and (DosToWinTime(Age,FT{%H-}) and SetFileTime(fh, nil, nil, @FT)) then
|
|
Result := 0
|
|
else
|
|
Result := GetLastError;
|
|
finally
|
|
if (fh <> feInvalidHandle) then FileClose(fh);
|
|
end;
|
|
end;
|
|
|
|
|
|
function FileSizeWide(const Filename: string): int64;
|
|
var
|
|
FindData: TWIN32FindDataW;
|
|
FindHandle: THandle;
|
|
Str: WideString;
|
|
begin
|
|
// Fix for the bug 14360:
|
|
// Don't assign the widestring to TSearchRec.name because it is of type
|
|
// string, which will generate a conversion to the system encoding
|
|
Str := UTF8Decode(Filename);
|
|
FindHandle := Windows.FindFirstFileW(PWideChar(Str), FindData{%H-});
|
|
if FindHandle = Windows.Invalid_Handle_value then
|
|
begin
|
|
Result := -1;
|
|
exit;
|
|
end;
|
|
Result := (int64(FindData.nFileSizeHigh) shl 32) + FindData.nFileSizeLow;
|
|
Windows.FindClose(FindHandle);
|
|
end;
|
|
|
|
function CreateDirWide(const NewDir: String): Boolean;
|
|
begin
|
|
Result:=Windows.CreateDirectoryW(PWideChar(UTF8Decode(NewDir)), nil);
|
|
end;
|
|
|
|
function RemoveDirWide(const Dir: String): Boolean;
|
|
begin
|
|
Result:=Windows.RemoveDirectoryW(PWideChar(UTF8Decode(Dir)));
|
|
end;
|
|
|
|
function DeleteFileWide(const FileName: String): Boolean;
|
|
begin
|
|
Result:=Windows.DeleteFileW(PWideChar(UTF8Decode(FileName)));
|
|
end;
|
|
|
|
function RenameFileWide(const OldName, NewName: String): Boolean;
|
|
begin
|
|
Result:=MoveFileW(PWideChar(UTF8Decode(OldName)), PWideChar(UTF8Decode(NewName)));
|
|
end;
|
|
|
|
function SetCurrentDirWide(const NewDir: String): Boolean;
|
|
begin
|
|
{$ifdef WinCE}
|
|
raise Exception.Create('[SetCurrentDirWide] The concept of the current directory doesn''t exist in Windows CE');
|
|
{$else}
|
|
Result:=Windows.SetCurrentDirectoryW(PWidechar(UTF8Decode(NewDir)));
|
|
{$endif}
|
|
end;
|
|
|
|
{$IF DEFINED(WinCE) OR (FPC_FULLVERSION>=30000)}
|
|
{$define FindData_W}
|
|
{$IFEND}
|
|
|
|
function FindMatch(var f: TSearchRec) : Longint;
|
|
begin
|
|
{ Find file with correct attribute }
|
|
While (F.FindData.dwFileAttributes and cardinal(F.ExcludeAttr))<>0 do
|
|
begin
|
|
if FindNextUTF8(F)<>0 then
|
|
begin
|
|
Result:=GetLastError;
|
|
exit;
|
|
end;
|
|
end;
|
|
{ Convert some attributes back }
|
|
WinToDosTime(F.FindData.ftLastWriteTime,F.Time);
|
|
f.size:=F.FindData.NFileSizeLow+(qword(maxdword)+1)*F.FindData.NFileSizeHigh;
|
|
f.attr:=F.FindData.dwFileAttributes;
|
|
{ The structures are different at this point
|
|
in win32 it is the ansi structure with a utf-8 string
|
|
in wince it is a wide structure }
|
|
{$ifdef FindData_W}
|
|
{$IFDEF ACP_RTL}
|
|
f.Name:=String(UnicodeString(F.FindData.cFileName));
|
|
{$ELSE}
|
|
f.Name:=UTF8Encode(UnicodeString(F.FindData.cFileName));
|
|
{$ENDIF}
|
|
{$else}
|
|
f.Name:=F.FindData.cFileName;
|
|
{$endif}
|
|
Result:=0;
|
|
end;
|
|
|
|
{$IFNDEF FindData_W}
|
|
|
|
{ This function does not really convert from wide to ansi, but from wide to
|
|
a utf-8 encoded ansi version of the data structures in win32 and does
|
|
nothing in wince
|
|
|
|
See FindMatch also }
|
|
procedure FindWideToAnsi(const wide: TWIN32FINDDATAW; var ansi: TWIN32FINDDATA);
|
|
var
|
|
ws: WideString;
|
|
an: AnsiString;
|
|
begin
|
|
SetLength(ws, length(wide.cAlternateFileName));
|
|
Move(wide.cAlternateFileName[0], ws[1], length(ws)*2);
|
|
an := AnsiString(ws); // no need to utf8 for cAlternateFileName (it's always ansi encoded)
|
|
Move(an[1], ansi.cAlternateFileName, sizeof(ansi.cAlternateFileName));
|
|
|
|
ws := PWideChar(@wide.cFileName[0]);
|
|
an := UTF8Encode(ws);
|
|
ansi.cFileName := an;
|
|
if length(an)<length(ansi.cFileName) then ansi.cFileName[ length(an)]:=#0;
|
|
|
|
with ansi do
|
|
begin
|
|
dwFileAttributes := wide.dwFileAttributes;
|
|
ftCreationTime := wide.ftCreationTime;
|
|
ftLastAccessTime := wide.ftLastAccessTime;
|
|
ftLastWriteTime := wide.ftLastWriteTime;
|
|
nFileSizeHigh := wide.nFileSizeHigh;
|
|
nFileSizeLow := wide.nFileSizeLow;
|
|
dwReserved0 := wide.dwReserved0;
|
|
dwReserved1 := wide.dwReserved1;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
function FindFirstWide(const Path: string; Attr: Longint; out Rslt: TSearchRec): Longint;
|
|
var
|
|
find: TWIN32FINDDATAW;
|
|
begin
|
|
Rslt.Name:=Path;
|
|
Rslt.Attr:=attr;
|
|
Rslt.ExcludeAttr:=(not Attr) and ($1e);
|
|
{ $1e = faHidden or faSysFile or faVolumeID or faDirectory }
|
|
{ FindFirstFile is a Win32 Call }
|
|
{$IFDEF ACP_RTL}
|
|
Rslt.FindHandle:=Windows.FindFirstFileW(PWideChar(WideString(Path)),find{%H-});
|
|
{$ELSE}
|
|
Rslt.FindHandle:=Windows.FindFirstFileW(PWideChar(UTF8Decode(Path)),find{%H-});
|
|
{$ENDIF}
|
|
If Rslt.FindHandle=Windows.Invalid_Handle_value then
|
|
begin
|
|
Result:=GetLastError;
|
|
Exit;
|
|
end;
|
|
{ Find file with correct attribute }
|
|
{$IFNDEF FindData_W}
|
|
FindWideToAnsi(find, Rslt.FindData);
|
|
{$ELSE}
|
|
Rslt.FindData := find;
|
|
{$IFEND}
|
|
Result := FindMatch(Rslt);
|
|
end;
|
|
|
|
|
|
function FindNextWide(var Rslt: TSearchRec): Longint;
|
|
var
|
|
wide: TWIN32FINDDATAW;
|
|
begin
|
|
if FindNextFileW(Rslt.FindHandle, wide{%H-}) then
|
|
begin
|
|
{$IFNDEF FindData_W}
|
|
FindWideToAnsi(wide, Rslt.FindData);
|
|
{$ELSE}
|
|
Rslt.FindData := wide;
|
|
{$ENDIF}
|
|
Result := FindMatch(Rslt);
|
|
end
|
|
else
|
|
Result := Integer(GetLastError);
|
|
end;
|
|
|
|
{$IFDEF WINCE}
|
|
// In WinCE these API calls are in Windows unit
|
|
function GetWindowsSpecialDirW(ID : Integer) : String;
|
|
Var
|
|
APath : Array[0..MAX_PATH] of WideChar;
|
|
WS: WideString;
|
|
Len: SizeInt;
|
|
begin
|
|
Result := '';
|
|
if SHGetSpecialFolderPath(0, APath, ID, True) then
|
|
begin
|
|
Len := StrLen(APath);
|
|
SetLength(WS, Len);
|
|
System.Move(APath[0], WS[1], Len * SizeOf(WideChar));
|
|
Result := AppendPathDelim(Utf16ToUtf8(WS));
|
|
end
|
|
else
|
|
Result:='';
|
|
end;
|
|
{$ELSE}
|
|
|
|
Type
|
|
PFNSHGetFolderPathW = Function(Ahwnd: HWND; Csidl: Integer; Token: THandle; Flags: DWord; Path: PWChar): HRESULT; stdcall;
|
|
|
|
var
|
|
SHGetFolderPathW : PFNSHGetFolderPathW = Nil;
|
|
CFGDLLHandle : THandle = 0;
|
|
|
|
Procedure InitDLL;
|
|
Var
|
|
pathBuf: array[0..MAX_PATH-1] of char;
|
|
pathLength: Integer;
|
|
begin
|
|
{ Load shfolder.dll using a full path, in order to prevent spoofing (Mantis #18185)
|
|
Don't bother loading shell32.dll because shfolder.dll itself redirects SHGetFolderPath
|
|
to shell32.dll whenever possible. }
|
|
pathLength:=GetSystemDirectory(pathBuf, MAX_PATH);
|
|
if (pathLength>0) and (pathLength<MAX_PATH-14) then { 14=length('\shfolder.dll'#0) }
|
|
begin
|
|
StrLCopy(@pathBuf[pathLength],'\shfolder.dll',MAX_PATH-pathLength-1);
|
|
CFGDLLHandle:=LoadLibrary(pathBuf);
|
|
|
|
if (CFGDLLHandle<>0) then
|
|
begin
|
|
Pointer(ShGetFolderPathW):=GetProcAddress(CFGDLLHandle,'SHGetFolderPathW');
|
|
If @ShGetFolderPathW=nil then
|
|
begin
|
|
FreeLibrary(CFGDLLHandle);
|
|
CFGDllHandle:=0;
|
|
end;
|
|
end;
|
|
end;
|
|
If (@ShGetFolderPathW=Nil) then
|
|
Raise Exception.Create('Could not determine SHGetFolderPathW Function');
|
|
end;
|
|
|
|
function GetWindowsSpecialDirW(ID : Integer) : String;
|
|
Var
|
|
APath : Array[0..MAX_PATH] of WideChar;
|
|
WS: WideString;
|
|
Len: SizeInt;
|
|
begin
|
|
Result := '';
|
|
if (CFGDLLHandle = 0) then
|
|
InitDLL;
|
|
If (SHGetFolderPathW <> Nil) then
|
|
begin
|
|
FillChar(APath{%H-}, SizeOf(APath), #0);
|
|
if SHGetFolderPathW(0,ID or CSIDL_FLAG_CREATE,0,0,@APATH[0]) = S_OK then
|
|
begin
|
|
Len := StrLen(APath);
|
|
SetLength(WS, Len);
|
|
System.Move(APath[0], WS[1], Len * SizeOf(WideChar));
|
|
Result := AppendPathDelim(Utf16ToUtf8(WS));
|
|
end;
|
|
end
|
|
else
|
|
Result := SysToUtf8(GetWindowsSpecialDir(ID));
|
|
end;
|
|
|
|
{$ENDIF WINCE}
|
|
|
|
function DGetAppConfigDir({%H-}Global : Boolean) : String;
|
|
begin
|
|
Result := ChompPathDelim(ExtractFilePath(ParamStrUtf8(0)));
|
|
end;
|
|
|
|
|
|
function GetAppConfigDirWide(Global: Boolean; Create: boolean = false): string;
|
|
const
|
|
CSIDL_GLOBAL = {$IFDEF WINCE}CSIDL_WINDOWS{$ELSE}CSIDL_COMMON_APPDATA{$ENDIF WINCE};
|
|
CSIDL_LOCAL = {$IFDEF WINCE}CSIDL_APPDATA{$ELSE}CSIDL_LOCAL_APPDATA{$ENDIF};
|
|
begin
|
|
If Global then
|
|
Result := GetWindowsSpecialDirW(CSIDL_GLOBAL)
|
|
else
|
|
Result := GetWindowsSpecialDirW(CSIDL_LOCAL);
|
|
If (Result <> '') then
|
|
begin
|
|
if VendorName <> '' then
|
|
Result := AppendPathDelim(Result + VendorName);
|
|
Result := AppendPathDelim(Result + ApplicationName);
|
|
end
|
|
else
|
|
Result := AppendPathDelim(DGetAppConfigDir(Global));
|
|
if Result = '' then exit;
|
|
if Create and not ForceDirectoriesUtf8(Result) then
|
|
raise EInOutError.Create(Format(lrsUnableToCreateConfigDirectoryS,[Result]));
|
|
end;
|
|
|
|
function GetAppConfigFileWide(Global: Boolean; SubDir: boolean;
|
|
CreateDir: boolean): string;
|
|
var
|
|
Dir: string;
|
|
begin
|
|
Result := GetAppConfigDirWide(Global);
|
|
if SubDir then
|
|
Result := AppendPathDelim(Result + 'Config');
|
|
Result := Result + ApplicationName + ConfigExtension;
|
|
if not CreateDir then exit;
|
|
Dir := ExtractFilePath(Result);
|
|
if Dir = '' then exit;
|
|
if not ForceDirectoriesUTF8(Dir) then
|
|
raise EInOutError.Create(Format(lrsUnableToCreateConfigDirectoryS,[Dir]));
|
|
end;
|
|
|
|
|
|
function GetShellLinkTargetWide(const FileName: string): string;
|
|
{$IFnDEF WINCE}
|
|
var
|
|
ShellLinkW: IShellLinkW;
|
|
PersistFile: IPersistFile;
|
|
WideFileName: WideString;
|
|
WidePath: array [0 .. MAX_PATH] of WideChar;
|
|
WinFindData: WIN32_FIND_DATAW;
|
|
{$ENDIF WINCE}
|
|
begin
|
|
Result := FileName;
|
|
{$IFnDEF WINCE}
|
|
if (LowerCase(ExtractFileExt(FileName)) = '.lnk') then
|
|
begin
|
|
if (CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER,
|
|
IShellLinkW, ShellLinkW) = S_OK) then
|
|
if (ShellLinkW.QueryInterface(IPersistFile, PersistFile) = S_OK) then
|
|
begin
|
|
WideFileName := Utf8ToUtf16(FileName);
|
|
FillChar(WinFindData{%H-}, SizeOf(WinFindData), 0);
|
|
if (PersistFile.Load(POleStr(WideFileName), STGM_READ) = S_OK) then
|
|
begin
|
|
if (ShellLinkW.GetPath(WidePath, Length(WidePath),
|
|
@WinFindData, SLGP_UNCPRIORITY) = S_OK) then
|
|
begin
|
|
Result := Utf16toUtf8(WidePath); // implicit conversion
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
{$ENDIF WINCE}
|
|
end;
|
|
|
|
// ******** End of WideString specific implementations ************
|
|
|
|
|
|
function FilenameIsAbsolute(const TheFilename: string):boolean;
|
|
begin
|
|
Result:=FilenameIsWinAbsolute(TheFilename);
|
|
end;
|
|
|
|
|
|
function ExpandFileNameUtf8(const FileName: string; {const} BaseDir: String = ''): String;
|
|
var
|
|
IsAbs, StartsWithRoot, CanUseBaseDir : Boolean;
|
|
{$ifndef WinCE}
|
|
HasDrive: Boolean;
|
|
FnDrive, CurDrive, BaseDirDrive: Char;
|
|
{$endif}
|
|
CurDir, Fn: String;
|
|
begin
|
|
//writeln('LazFileUtils.ExpandFileNameUtf8');
|
|
//writeln('FileName = "',FileName,'"');
|
|
//writeln('BaseDir = "',BaseDir,'"');
|
|
|
|
//{$ifndef WinCE}
|
|
//if (Win32Platform = VER_PLATFORM_WIN32_WINDOWS) then
|
|
// Result := SysToUtf8(SysUtils.ExpandFileName(Utf8ToSys(FileName)))
|
|
//else
|
|
//{$endif}
|
|
Fn := FileName;
|
|
//if Filename uses ExtendedLengthPath scheme then it cannot be expanded
|
|
//AND it should not be altered by ForcePathDelims or ResolveDots
|
|
//See: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
|
|
if (Length(Fn) > 3) and (Fn[1] = PathDelim) and (Fn[2] = PathDelim) and
|
|
(Fn[3] = '?') and (Fn[4] = PathDelim) //Do NOT use AllowDirectorySeparators here!
|
|
then Exit;
|
|
ForcePathDelims(Fn);
|
|
IsAbs := FileNameIsWinAbsolute(Fn);
|
|
if not IsAbs then
|
|
begin
|
|
StartsWithRoot := (Fn = '\') or
|
|
((Length(Fn) > 1) and
|
|
(Fn[1] = DirectorySeparator) and
|
|
(Fn[2] <> DirectorySeparator));
|
|
{$ifndef WinCE}
|
|
HasDrive := (Length(Fn) > 1) and
|
|
(Fn[2] = ':') and
|
|
(UpCase(Fn[1]) in ['A'..'Z']);
|
|
|
|
if HasDrive then
|
|
begin
|
|
FnDrive := UpCase(Fn[1]);
|
|
_GetDirUtf8(Byte(FnDrive)-64, CurDir{%H-});
|
|
CurDrive := UpCase(GetCurrentDirUtf8[1]);
|
|
end
|
|
else
|
|
begin
|
|
CurDir := GetCurrentDirUtf8;
|
|
FnDrive := UpCase(CurDir[1]);
|
|
CurDrive := FnDrive;
|
|
end;
|
|
|
|
//writeln('HasDrive = ',HasDrive,' Fn = ',Fn);
|
|
//writeln('CurDir = ',CurDir);
|
|
//writeln('CurDrive = ',CurDrive);
|
|
//writeln('FnDrive = ',FnDrive);
|
|
|
|
if (Length(BaseDir) > 1) and (UpCase(BaseDir[1]) in ['A'..'Z']) and (BaseDir[2] = ':') then
|
|
begin
|
|
BaseDirDrive := BaseDir[1]
|
|
end
|
|
else
|
|
begin
|
|
if HasDrive then
|
|
BaseDirDrive := CurDrive
|
|
else
|
|
BaseDirDrive := #0;
|
|
end;
|
|
|
|
//You cannot use BaseDir if both FileName and BaseDir includes a drive and they are not the same
|
|
CanUseBaseDir := ((BaseDirDrive = #0) or
|
|
(not HasDrive) or
|
|
(HasDrive and (FnDrive = BaseDirDrive)))
|
|
and (BaseDir <> '');
|
|
|
|
//writeln('CanUseBaseDir = ',CanUseBaseDir);
|
|
|
|
if not HasDrive and StartsWithRoot and not CanUseBaseDir then
|
|
begin
|
|
//writeln('HasDrive and StartsWithRoot');
|
|
Fn := Copy(CurDir,1,2) + Fn;
|
|
HasDrive := True;
|
|
IsAbs := True;
|
|
end;
|
|
//FileNames like C:foo, strip Driveletter + colon
|
|
if HasDrive and not IsAbs then Delete(Fn,1,2);
|
|
|
|
//writeln('HasDrive = ',Hasdrive,' Fn = ',Fn);
|
|
{$else}
|
|
CanUseBaseDir := True;
|
|
{$endif WinCE}
|
|
end;
|
|
if IsAbs then
|
|
begin
|
|
//writeln('IsAbs = True -> Exit');
|
|
Result := ResolveDots(Fn);
|
|
end
|
|
else
|
|
begin
|
|
if not CanUseBaseDir or (BaseDir = '') then
|
|
Fn := IncludeTrailingPathDelimiter(CurDir) + Fn
|
|
else
|
|
begin
|
|
if (Length(Fn) > 0) and (Fn[1] = DirectorySeparator) then Delete(Fn,1,1);
|
|
Fn := IncludeTrailingPathDelimiter(BaseDir) + Fn;
|
|
end;
|
|
|
|
Fn := ResolveDots(Fn);
|
|
//if BaseDir is something like 'z:foo\' or '\' then this needs to be expanded as well
|
|
if not FileNameIsAbsolute(Fn) then
|
|
Fn := ExpandFileNameUtf8(Fn, '');
|
|
Result := Fn;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
function FileExistsUTF8(const Filename: string): boolean;
|
|
var
|
|
Attr: Longint;
|
|
begin
|
|
Attr := _FileGetAttrUTF8(FileName);
|
|
if Attr <> -1 then
|
|
Result:= (Attr and FILE_ATTRIBUTE_DIRECTORY) = 0
|
|
else
|
|
Result:=False;
|
|
end;
|
|
|
|
function DirectoryExistsUTF8(const Directory: string): boolean;
|
|
var
|
|
Attr: Longint;
|
|
begin
|
|
Attr := _FileGetAttrUTF8(Directory);
|
|
if Attr <> -1 then
|
|
Result := (Attr and FILE_ATTRIBUTE_DIRECTORY) > 0
|
|
else
|
|
Result := False;
|
|
end;
|
|
|
|
function FileIsExecutable(const AFilename: string): boolean;
|
|
begin
|
|
Result:=FileExistsUTF8(AFilename);
|
|
end;
|
|
|
|
procedure CheckIfFileIsExecutable(const AFilename: string);
|
|
begin
|
|
// TProcess does not report, if a program can not be executed
|
|
// to get good error messages consider the OS
|
|
if not FileExistsUTF8(AFilename) then begin
|
|
raise Exception.Create(Format(lrsFileDoesNotExist, [AFilename]));
|
|
end;
|
|
if DirPathExists(AFilename) then begin
|
|
raise Exception.Create(Format(lrsFileIsADirectoryAndNotAnExecutable, [
|
|
AFilename]));
|
|
end;
|
|
end;
|
|
|
|
function FileIsSymlink(const AFilename: string): boolean;
|
|
{$ifndef wince}
|
|
const
|
|
IO_REPARSE_TAG_MOUNT_POINT = $A0000003;
|
|
IO_REPARSE_TAG_SYMLINK = $A000000C;
|
|
var
|
|
Attr: Longint;
|
|
Rec: TSearchRec;
|
|
{$endif}
|
|
begin
|
|
{$ifndef wince}
|
|
Attr := FileGetAttrUTF8(AFilename);
|
|
if (Attr <> -1) and (Attr and FILE_ATTRIBUTE_REPARSE_POINT <> 0) then
|
|
begin
|
|
FindFirstUTF8(AFilename, Attr, Rec);
|
|
if Rec.FindHandle <> feInvalidHandle then
|
|
begin
|
|
Windows.FindClose(Rec.FindHandle);
|
|
Result := (Rec.FindData.dwReserved0 = IO_REPARSE_TAG_SYMLINK) or (Rec.FindData.dwReserved0 = IO_REPARSE_TAG_MOUNT_POINT);
|
|
end
|
|
else
|
|
Result := False;
|
|
end
|
|
else
|
|
{$endif}
|
|
Result := False;
|
|
end;
|
|
|
|
procedure CheckIfFileIsSymlink(const AFilename: string);
|
|
begin
|
|
// to get good error messages consider the OS
|
|
if not FileExistsUTF8(AFilename) then begin
|
|
raise Exception.Create(Format(lrsFileDoesNotExist, [AFilename]));
|
|
end;
|
|
if not FileIsSymLink(AFilename) then
|
|
raise Exception.Create(Format(lrsIsNotASymbolicLink, [AFilename]));
|
|
end;
|
|
|
|
|
|
function FileIsHardLink(const AFilename: string): boolean;
|
|
{$ifndef wince}
|
|
var
|
|
H: THandle;
|
|
FileInfo: BY_HANDLE_FILE_INFORMATION;
|
|
{$endif}
|
|
begin
|
|
Result := false;
|
|
{$ifndef wince}
|
|
//HardLinks are not supported in Win9x platform
|
|
if (Win32Platform = VER_PLATFORM_WIN32_WINDOWS) then Exit;
|
|
H := FileOpenUtf8(aFilename, fmOpenRead);
|
|
if (H <> feInvalidHandle) then
|
|
begin
|
|
FillChar(FileInfo{%H-}, SizeOf(BY_HANDLE_FILE_INFORMATION),0);
|
|
if GetFileInformationByHandle(H, FileInfo) then
|
|
Result := (FileInfo.nNumberOfLinks > 1);
|
|
FileClose(H);
|
|
end;
|
|
{$endif}
|
|
end;
|
|
|
|
function FileIsReadable(const AFilename: string): boolean;
|
|
begin
|
|
Result:=FileExistsUTF8(AFilename);
|
|
end;
|
|
|
|
function FileIsWritable(const AFilename: string): boolean;
|
|
begin
|
|
Result := ((FileGetAttrUTF8(AFilename) and faReadOnly) = 0);
|
|
end;
|
|
|
|
|
|
function IsUNCPath(const Path: String): Boolean;
|
|
begin
|
|
Result := (Length(Path) > 2) and (Path[1] in AllowDirectorySeparators) and (Path[2] in AllowDirectorySeparators);
|
|
end;
|
|
|
|
function ExtractUNCVolume(const Path: String): String;
|
|
var
|
|
I, Len: Integer;
|
|
|
|
// the next function reuses Len variable
|
|
function NextPathDelim(const Start: Integer): Integer;// inline;
|
|
begin
|
|
Result := Start;
|
|
while (Result <= Len) and not (Path[Result] in AllowDirectorySeparators) do
|
|
inc(Result);
|
|
end;
|
|
|
|
begin
|
|
if not IsUNCPath(Path) then
|
|
Exit('');
|
|
I := 3;
|
|
Len := Length(Path);
|
|
if Path[I] = '?' then
|
|
begin
|
|
// Long UNC path form like:
|
|
// \\?\UNC\ComputerName\SharedFolder\Resource or
|
|
// \\?\C:\Directory
|
|
inc(I);
|
|
if not (Path[I] in AllowDirectorySeparators) then
|
|
Exit('');
|
|
if UpperCase(Copy(Path, I + 1, 3)) = 'UNC' then
|
|
begin
|
|
inc(I, 4);
|
|
if I < Len then
|
|
I := NextPathDelim(I + 1);
|
|
if I < Len then
|
|
I := NextPathDelim(I + 1);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
I := NextPathDelim(I);
|
|
if I < Len then
|
|
I := NextPathDelim(I + 1);
|
|
end;
|
|
Result := Copy(Path, 1, I);
|
|
end;
|
|
|
|
function GetFileDescription(const AFilename: string): string;
|
|
begin
|
|
// date + time
|
|
Result:=lrsModified;
|
|
try
|
|
Result:=Result+FormatDateTime('DD/MM/YYYY hh:mm',
|
|
FileDateToDateTime(FileAgeUTF8(AFilename)));
|
|
except
|
|
Result:=Result+'?';
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure InitLazFileUtils;
|
|
begin
|
|
{$ifndef WinCE}
|
|
if Win32MajorVersion <= 4 then
|
|
begin
|
|
_FileAgeUtf8 := @FileAgeAnsi;
|
|
_FileSizeUtf8 := @FileSizeAnsi;
|
|
_FileSetDateUtf8 := @FileSetDateAnsi;
|
|
_FileGetAttrUtf8 := @FileGetAttrAnsi;
|
|
_FileSetAttrUtf8 := @FileSetAttrAnsi;
|
|
_DeleteFileUtf8 := @DeleteFileAnsi;
|
|
_RenameFileUtf8 := @RenameFileAnsi;
|
|
_SetCurrentDirUtf8 := @SetCurrentDirAnsi;
|
|
_GetCurrentDirUtf8 := @GetCurrentDirAnsi;
|
|
_GetDirUtf8 := @GetDirAnsi;
|
|
_FileOpenUtf8 := @FileOpenAnsi;
|
|
_FileCreateUtf8 := @FileCreateAnsi;
|
|
_CreateDirUtf8 := @CreateDirAnsi;
|
|
_RemoveDirUtf8 := @RemoveDirAnsi;
|
|
_FindFirstUtf8 := @FindFirstAnsi;
|
|
_FindNextUtf8 := @FindNextAnsi;
|
|
_GetAppConfigDirUtf8 := @GetAppConfigDirAnsi;
|
|
_GetAppConfigFileUtf8 := @GetAppConfigFileAnsi;
|
|
_GetShellLinkTarget := @GetShellLinkTargetAnsi;
|
|
end
|
|
else
|
|
{$endif}
|
|
begin
|
|
_FileAgeUtf8 := @FileAgeWide;
|
|
_FileSizeUtf8 := @FileSizeWide;
|
|
_FileSetDateUtf8 := @FileSetDateWide;
|
|
_FileGetAttrUtf8 := @FileGetAttrWide;
|
|
_FileSetAttrUtf8 := @FileSetAttrWide;
|
|
_DeleteFileUtf8 := @DeleteFileWide;
|
|
_RenameFileUtf8 := @RenameFileWide;
|
|
_SetCurrentDirUtf8 := @SetCurrentDirWide;
|
|
_GetCurrentDirUtf8 :=@ GetCurrentDirWide;
|
|
_GetDirUtf8 := @GetDirWide;
|
|
_FileOpenUtf8 := @FileOpenWide;
|
|
_FileCreateUtf8 := @FileCreateWide;
|
|
_CreateDirUtf8 := @CreateDirWide;
|
|
_RemoveDirUtf8 := @RemoveDirWide;
|
|
_FindFirstUtf8 := @FindFirstWide;
|
|
_FindNextUtf8 := @FindNextWide;
|
|
_GetAppConfigDirUtf8 := @GetAppConfigDirWide;
|
|
_GetAppConfigFileUtf8 := @GetAppConfigFileWide;
|
|
_GetShellLinkTarget := @GetShellLinkTargetWide;
|
|
end;
|
|
end;
|
|
|
|
procedure FinalizeLazFileUtils;
|
|
begin
|
|
{$IFnDEF WINCE}
|
|
if CFGDLLHandle <> 0 then
|
|
FreeLibrary(CFGDllHandle);
|
|
{$ENDIF WINCE}
|
|
end;
|