mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-21 00:23:18 +02:00

- An attempt to unify the defines for the different scenario's in the use of (not) codepage aware ansistrings and the use of the "Utf8 in RTL" feature. It makes for better separation of code and thus better readability and ease of maintainance (and in a later stadium it makes it easier to remove code that deals with non codepage aware ansistrings (fpc < 3.0)). - Also replace (FPC_FULLVERSION >= xxxx) with FPC_HAS_CPSTRING where appropriate. - Replace the custom HasCP define with built in FPC_HAS_CPSTRING define. git-svn-id: trunk@50498 -
1175 lines
33 KiB
PHP
1175 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;
|
|
{$IFDEF ACP_RTL}
|
|
var
|
|
Dummy: String;
|
|
{$ENDIF}
|
|
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}
|
|
{$IFnDEF ACP_RTL}
|
|
f.Name:=UTF8Encode(UnicodeString(F.FindData.cFileName));
|
|
{$ELSE}
|
|
Dummy := '';
|
|
Insert(UTF8Encode(UnicodeString(F.FindData.cFileName)), Dummy, 1);
|
|
f.Name := Dummy;
|
|
{$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 }
|
|
Rslt.FindHandle:=Windows.FindFirstFileW( PWideChar(UTF8Decode(Path)),find{%H-});
|
|
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 (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;
|