1
0
mirror of https://bitbucket.org/Dennis07/lina-components.git synced 2025-02-02 10:25:22 +02:00
lina-components/Source/uFileTools.pas
Dennis07 62559dcad1 Version 1.0 DEV 1.11e
Signed-off-by: Dennis07 <den.goehlert@t-online.de>
2014-11-16 12:10:44 +01:00

870 lines
23 KiB
ObjectPascal

unit uFileTools;
//////////////////////////////////////
/// Lina File Tools Unit ///
/// **************************** ///
/// (c) 2014 Dennis Göhlert a.o. ///
//////////////////////////////////////
{$IFNDEF MSWINDOWS}
{$MESSAGE ERROR 'The "uFileTools" unit is only available under MS-Windows OS'}
{$ENDIF}
interface
uses
{ Standard-Units }
Classes, SysUtils, ShellAPI, Forms, Windows, Math,
{$IFNDEF NO_GENERIC}
Generics.Collections,
{$ENDIF}
{ Andere Package-Units }
uBase, uSysTools;
type
{ Fehlermeldungen }
EDriveNoExist = class(Exception);
EFileNoExist = class(Exception);
EMissingTypeDesc = class(Exception);
EMissingExts = class(Exception);
EInvalidStyle = class(Exception);
ENoGetFileOwner = class(Exception);
type
{ Hilfsklassen }
TFileExecuteMode = (feOpen,feEdit,feExplore,feFind,fePrint);
TFileNameStyles = set of (fnDirectory,fnExtension);
TFileAttributes = set of (faReadOnly,faHidden,faSystem,faArchive,faTemporary);
TInvalidFileName = String[4];
TInvalidFileNames = array[1..22] of TInvalidFileName;
type
{ Hauptklassen }
TWinFileInfo = class
private
{ Private-Deklarationen }
FFileName: String;
public
{ Public-Deklarationen }
constructor Create(AFileName: String);
destructor Destroy; override;
property FileName: String read FFileName;
{ function GetSignature: String;
function GetVersionStructure: Integer;
function GetVersionFileMS: Integer;
function GetVersionFileLS: Integer;
function GetVersionProductMS: Integer;
function GetVersionProductLS: Integer; }
end;
TWinDrive = class
private
{ Private-Deklarationen }
FDriveChar: Char;
public
{ Public-Deklarationen }
constructor Create(ADriveChar: Char);
destructor Destroy; override;
property DriveChar: Char read FDriveChar;
function GetSpaceTotal: Int64;
function GetSpaceFree: Int64;
end;
TWinFile = class
private
{ Private-Deklarationen }
FFileName: String;
FExecuteMode: TFileExecuteMode;
FDrive: TWinDrive;
FInfo: TWinFileInfo;
public
{ Public-Deklarationen }
constructor Create(AFileName: String);
destructor Destroy; override;
property FileName: String read FFileName;
property ExecuteMode: TFileExecuteMode read FExecuteMode write FExecuteMode;
property Drive: TWinDrive read FDrive write FDrive;
property Info: TWinFileInfo read FInfo write FInfo;
function GetExtension(WithDot: Boolean = True): String; //ExtractFileExt()
function GetPath: String; //ExtractFilePath()
function GetDir: String; //ExtractFileDir()
function GetFileName(WithExt: Boolean = True): String; //ExtractFileName()
function GetFolderName: String; //ExtractFileFolder()
function GetSize: Int64; //GetFileSize()
//function GetVersion: Extended;
function GetAttributes: TFileAttributes; //GetFileAttributes();
function GetOwner: String;
function GetModified: TDateTime; //GetFileModified()
function GetCreated: TDateTime; //GetFileCreated()
function GetAccessed: TDateTime; //GetFileAccessed()
function Execute: Boolean; //ExecuteFile()
function SafeExecute: Boolean; //.............
end;
TWinFileArray = array of TWinFile;
{$IFNDEF NOGENERIC}
TWinFileList = TList<TWinFile>;
{$ENDIF}
procedure InitializeInvalidNames;
function ValidFileName(const FileName: TInvalidFileName; const InvalidFileNames: TInvalidFileNames): Boolean;
function ValidFileNameStr(const FileName: ShortString; const InvalidFileNames: TInvalidFileNames): Boolean;
function StrIsPath(const S: String): Boolean;
function FEModeToPChar(FEMode: TFileExecuteMode): PChar;
procedure EnsureDirDelimeter(var Dir: String);
function ExecuteFile(FileName: String; ExecMode: TFileExecuteMode = feOpen;
InDir: Boolean = False): Boolean;
function ExtractFileFolder(FileName: String): String;
procedure ListFiles(Dir: String; var OutList: TStrings; FileExts: array of String;
NameStyles: TFileNameStyles = []; RecMode: Boolean = False);
procedure ListFolders(Dir: String; var OutList: TStrings;
NameStyles: TFileNameStyles = []; RecMode: Boolean = False);
function ExtractDriveChar(const FileName: String): Char;
function DriveCharToFileDir(DriveChar: Char): ShortString;
function DriveCharToFilePath(DriveChar: Char): ShortString;
function DriveByteToDriveChar(DriveByte: Byte): Char;
function DriveCharToDriveByte(DriveChar: Char): Byte;
function DriveExists(DriveByte: Byte): Boolean;
function GetDriveTypeChar(DriveByte: Byte): UINT;
function FileTimeToDateTime(FileTime: TFileTime): TDateTime;
function ConvertFileSize(const InputSize: Int64; ConvertFactor: ShortInt = -1): Extended;
function GetFileSize(FileName: String): Int64;
function GetFileModified(FileName: String): TDateTime;
function GetFileCreated(FileName: String): TDateTime;
function GetFileAccessed(FileName: String): TDateTime;
function GetFileAttributes(FileName: String): TFileAttributes;
const
PathDelims = [PathDelim,'/'];
MAX_PATH_DS = MAX_PATH - 1; //Max. Länge von Dateiname ohne #0-Terminal
{ Ungültige Dateinamen-Zeichen }
InvalidFilePathChars = ['*','?','"','<','>','|'];
InvalidFileNameChars = InvalidFilePathChars + ['\','/',':'];
{ Umrechnungs-Faktoren }
TB_TO_B = 4;
GB_TO_B = 3;
TB_TO_KB = 3;
MB_TO_B = 2;
GB_TO_KB = 2;
TB_TO_MB = 2;
KB_TO_B = 1;
MB_TO_KB = 1;
GB_TO_MB = 1;
TB_TO_GB = 1;
B_TO_KB = -1;
KB_TO_MB = -1;
MB_TO_GB = -1;
GB_TO_TB = -1;
B_TO_MB = -2;
KB_TO_GB = -2;
MB_TO_TB = -2;
B_TO_GB = -3;
KB_TO_TB = -3;
B_TO_TB = -4;
{ Dateierweiterungen für ListFiles() }
FXT_ANY = '*.*';
FXT_EXE = '*.exe';
FXT_TXT = '*.txt';
{ Vielleicht später mal implementieren...
FXT_IMG = ('*.jpg','*.jpeg','*.png','*.tif','*.tiff','*.bmp','*.gif');
FXT_PAS = ('*.pas','*.dpr','*.dpk','*.dfm');
FXT_MSO = ('*.doc','*.xls','*.ppt');
FXT_MSI = ('*.msi');
FXT_IMG = ('*.img','*.iso'); }
var
InvalidFileNames: TInvalidFileNames;
implementation
procedure InitializeInvalidNames;
begin
InvalidFileNames[01] := 'CON';
InvalidFileNames[02] := 'PRN';
InvalidFileNames[03] := 'AUX';
InvalidFileNames[04] := 'NUL';
{ COM... }
InvalidFileNames[05] := 'COM1';
InvalidFileNames[06] := 'COM2';
InvalidFileNames[07] := 'COM3';
InvalidFileNames[08] := 'COM4';
InvalidFileNames[09] := 'COM5';
InvalidFileNames[10] := 'COM6';
InvalidFileNames[11] := 'COM7';
InvalidFileNames[12] := 'COM8';
InvalidFileNames[13] := 'COM9';
{ LPT... }
InvalidFileNames[14] := 'LPT1';
InvalidFileNames[15] := 'LPT2';
InvalidFileNames[16] := 'LPT3';
InvalidFileNames[17] := 'LPT4';
InvalidFileNames[18] := 'LPT5';
InvalidFileNames[19] := 'LPT6';
InvalidFileNames[20] := 'LPT7';
InvalidFileNames[21] := 'LPT8';
InvalidFileNames[22] := 'LPT9';
end;
function ValidFileName(const FileName: TInvalidFileName;
const InvalidFileNames: TInvalidFileNames): Boolean;
var
Index: 1..22;
begin
InitializeInvalidNames;
Result := True;
for Index := Low(InvalidFileNames) to High(InvalidFileNames) do
begin
if InvalidFileNames[Index] = FileName then
begin
Result := False;
Exit;
end;
end;
end;
function ValidFileNameStr(const FileName: ShortString;
const InvalidFileNames: TInvalidFileNames): Boolean;
var
Index: 1..4;
TmpIFN: TInvalidFileName;
begin
Result := True;
if Length(FileName) > 4 then
begin
Exit;
end;
for Index := 1 to 4 do
begin
TmpIFN := TmpIFN + FileName[Index];
end;
Result := ValidFileName(TmpIFN,InvalidFileNames);
end;
function StrIsPath(const S: String): Boolean;
{ Prüft, ob ein Dateipfad unter Windows-Systemen gültig ist.
An dieser stelle sei gesagt: Der Rückgabewert dieser Funktion ist lediglich
ein Anhaltspunkt und keine Garantie!
Außerdem wird nicht geprüft, ob die Datei existiert. }
var
Index: 1..MAX_PATH_DS; //Integer[1..259]
SLength: SmallInt;
NoPathDelim: Boolean;
NeedPathDelim: Boolean;
FileName: ShortString;
begin
Result := True;
SLength := Length(S);
if SLength = 0 then
begin
Exit;
end;
if SLength > MAX_PATH_DS then
begin
Result := False;
Exit;
end;
{ Prüfen, ob Dateiname ungültig ist }
FileName := '';
for Index := SLength downto 1 do
begin
if S[Index] in PathDelims then
begin
Break;
end else
begin
FileName := S[Index] + FileName;
end;
end;
if ValidFileNameStr(FileName,InvalidFileNames) = False then
begin
Result := False;
Exit;
end;
{ Parse... }
NoPathDelim := True;
NeedPathDelim := False;
for Index := 1 to SLength do
begin
{ -> Doppel-Slash verhindern }
if NoPathDelim = True then
begin
if S[Index] in PathDelims then
begin
Result := False;
Exit;
end else
begin
NoPathDelim := False;
end;
end else
begin
NoPathDelim := (S[Index] in PathDelims);
end;
{ -> Drive-Char validieren }
if (NeedPathDelim = True) then
begin
if S[Index] in PathDelims then
begin
NeedPathDelim := False;
end else
begin
Result := False;
Exit;
end;
end;
if S[Index] = DriveDelim then
begin
if Index = 2 then
begin
NeedPathDelim := True;
end else
begin
Result := False;
Exit;
end;
end;
{ -> Auf ungültige Zeichen prüfen }
if S[Index] in InvalidFilePathChars then
begin
Result := False;
Exit;
end;
//For
end;
end;
function FEModeToPChar(FEMode: TFileExecuteMode): PChar;
begin
case FEMode of
feOpen: Result := 'open';
feEdit: Result := 'edit';
feExplore: Result := 'explore';
feFind: Result := 'find';
fePrint: Result := 'print';
else Result := nil;
end;
end;
procedure EnsureDirDelimeter(var Dir: String);
begin
if (Dir[Length(Dir)] <> '\') and (Dir[Length(Dir)] <> '/') then
begin
Dir := Dir + '\';
end else
begin
while Length(Dir) >= 1 do
begin
if (Dir[Length(Dir) - 1] = '\') or (Dir[Length(Dir) - 1] = '/') then
begin
Delete(Dir,Length(Dir) - 1,1);
end else
begin
Break;
end;
end;
end;
end;
procedure ListFiles(Dir: String; var OutList: TStrings; FileExts: array of String;
NameStyles: TFileNameStyles = []; RecMode: Boolean = False);
var
SRec: TSearchRec;
ExtIndex: Integer;
begin
EnsureDirDelimeter(Dir);
if Length(FileExts) < 1 then
begin
raise EMissingExts.Create('Missing file extensions');
end;
for ExtIndex := Low(FileExts) to High(FileExts) do
begin
if FindFirst(Dir + '*.*',faAnyFile,SRec) = 0 then
begin
repeat
if (SRec.Name <> '.') and (SRec.Name <> '..') then
begin
if ((SRec.Attr and faDirectory) = faDirectory) then
begin
if RecMode = True then
begin
ListFiles(Dir + SRec.Name,OutList,FileExts,NameStyles,RecMode);
end;
end else
begin
if ((ChangeFileExt(SRec.Name,ExtractFileExt(FileExts[ExtIndex])) = SRec.Name) or
(ExtractFileExt(FileExts[ExtIndex]) = '.*')) then
begin
OutList.Add(SRec.Name);
if fnDirectory in NameStyles then
begin
OutList.Strings[OutList.Count - 1] := Dir + OutList.Strings[OutList.Count - 1];
end;
if not (fnExtension in NameStyles) then
begin
OutList.Strings[OutList.Count - 1] := ChangeFileExt(OutList.Strings[OutList.Count - 1],'');
end;
end;
end;
end;
until FindNext(SRec) <> 0;
SysUtils.FindClose(SRec);
end;
end;
end;
procedure ListFolders(Dir: String; var OutList: TStrings;
NameStyles: TFileNameStyles = []; RecMode: Boolean = False);
var
SRec: TSearchRec;
begin
EnsureDirDelimeter(Dir);
if FindFirst(Dir + '*.*',faAnyFile,SRec) = 0 then
begin
repeat
if ((SRec.Attr and faDirectory) = faDirectory) and
(SRec.Name <> '.') and (SRec.Name <> '..') then
begin
if fnDirectory in NameStyles then
begin
OutList.Add(Dir + SRec.Name);
end else
begin
OutList.Add(SRec.Name);
if RecMode = True then
begin
ListFolders(Dir + SRec.Name,OutList,NameStyles,RecMode);
end;
end;
end;
until FindNext(SRec) <> 0;
SysUtils.FindClose(SRec);
end;
if fnExtension in NameStyles then
begin
raise EInvalidStyle.Create('The extension file name style is invalid for directory names and has been ignored');
end;
end;
function ExecuteFile(FileName: String; ExecMode: TFileExecuteMode = feOpen;
InDir: Boolean = False): Boolean;
begin
Result := True;
try
if InDir = True then
begin
ShellExecute(Application.Handle,FEModeToPChar(ExecMode),PChar(FileName),nil,PChar(ExtractFileDir(FileName)),SW_NORMAL);
end else
begin
ShellExecute(Application.Handle,FEModeToPChar(ExecMode),PChar(FileName),nil,nil,SW_NORMAL);
end;
except
Result := False;
end;
end;
function ExtractFileFolder(FileName: String): String;
begin
Result := ExtractFileName(ExtractFileDir(FileName)); //Name d. übergeord. Ordners
end;
function ExtractDriveChar(const FileName: String): Char;
begin
Result := FileName[1];
if Length(FileName) >= 2 then
begin
if FileName[2] <> DriveDelim then
begin
Result := #0;
end else
begin
if Length(FileName) >= 3 then
begin
if not (FileName[3] in PathDelims) then
begin
Result := #0;
end;
end;
end;
end;
end;
function DriveCharToFileDir(DriveChar: Char): ShortString;
begin
Result := DriveChar + DriveDelim;
end;
function DriveCharToFilePath(DriveChar: Char): ShortString;
begin
Result := DriveCharToFileDir(DriveChar) + PathDelim;
end;
function DriveByteToDriveChar(DriveByte: Byte): Char;
begin
Result := Chr(DriveByte + Ord('A'));
end;
function DriveCharToDriveByte(DriveChar: Char): Byte;
begin
Result := Ord(DriveChar) - Ord('A');
end;
function DriveExists(DriveByte: Byte): Boolean;
begin
Result := (GetLogicalDrives and (1 shl DriveByte) <> 0);
end;
function GetDriveTypeChar(DriveByte: Byte): UINT;
begin
Result := GetDriveType(PChar(String(DriveCharToFilePath(DriveByteToDriveChar(DriveByte)))));
end;
function FileTimeToDateTime(FileTime: TFileTime): TDateTime;
var
LocalTime: TFileTime;
SysTime: TSystemTime;
begin
FileTimeToLocalFileTime(FileTime,LocalTime);
FileTimeToSystemTime(LocalTime,SysTime);
Result := SystemTimeToDateTime(SysTime);
end;
function ConvertFileSize(const InputSize: Int64; ConvertFactor: ShortInt = -1): Extended;
begin
{ Sollte verwendet werden mit den Umrechnungs-Faktoren, die in der globalen
"const"-Section deklariert wurden. }
Result := InputSize * Power(1024,ConvertFactor);
end;
function GetFileSize(FileName: String): Int64;
var
FileHandle: THandle;
FindData: TWIN32FINDDATA;
begin
Result := -1;
if FileExists(FileName) then
begin
FileHandle := FindFirstFile(pchar(FileName),FindData);
if FileHandle = INVALID_HANDLE_VALUE then
begin
Exit;
end;
Result := (FindData.nFileSizeHigh * (MAXDWORD)) + FindData.nFileSizeLow;
Windows.FindClose(FileHandle);
end;
end;
function GetFileModified(FileName: String): TDateTime;
var
FileHandle: THandle;
FindData: TWIN32FINDDATA;
begin
Result := StrToTime('00.00.0000 00:00:00');
if FileExists(FileName) then
begin
FileHandle := FindFirstFile(PChar(FileName),FindData);
if FileHandle = INVALID_HANDLE_VALUE then
begin
Exit;
end;
Result := FileTimeToDateTime(FindData.ftLastWriteTime);
Windows.FindClose(FileHandle);
end;
end;
function GetFileCreated(FileName: String): TDateTime;
var
FileHandle: THandle;
FindData: TWIN32FINDDATA;
begin
Result := StrToTime('00.00.0000 00:00:00');
if FileExists(FileName) then
begin
FileHandle := FindFirstFile(PChar(FileName),FindData);
if FileHandle = INVALID_HANDLE_VALUE then
begin
Exit;
end;
Result := FileTimeToDateTime(FindData.ftCreationTime);
Windows.FindClose(FileHandle);
end;
end;
function GetFileAccessed(FileName: String): TDateTime;
var
FileHandle: THandle;
FindData: TWIN32FINDDATA;
begin
Result := StrToTime('00.00.0000 00:00:00');
if FileExists(FileName) then
begin
FileHandle := FindFirstFile(PChar(FileName),FindData);
if FileHandle = INVALID_HANDLE_VALUE then
begin
Exit;
end;
Result := FileTimeToDateTime(FindData.ftLastAccessTime);
Windows.FindClose(FileHandle);
end;
end;
function GetFileAttributes(FileName: String): TFileAttributes;
var
FileHandle: THandle;
FindData: TWIN32FINDDATA;
begin
Result := [];
if FileExists(FileName) then
begin
FileHandle := FindFirstFile(PChar(FileName),FindData);
if FileHandle = INVALID_HANDLE_VALUE then
begin
Exit;
end;
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_READONLY) = FILE_ATTRIBUTE_READONLY then
begin
Result := Result + [faReadOnly];
end;
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_HIDDEN) = FILE_ATTRIBUTE_HIDDEN then
begin
Result := Result + [faHidden];
end;
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_SYSTEM) = FILE_ATTRIBUTE_SYSTEM then
begin
Result := Result + [faSystem];
end;
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_ARCHIVE) = FILE_ATTRIBUTE_ARCHIVE then
begin
Result := Result + [faArchive];
end;
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_TEMPORARY) = FILE_ATTRIBUTE_TEMPORARY then
begin
Result := Result + [faTemporary];
end;
Windows.FindClose(FileHandle);
end;
end;
{ ----------------------------------------------------------------------------
TWinFileInfo
---------------------------------------------------------------------------- }
constructor TWinFileInfo.Create(AFileName: String);
begin
FFileName := AFileName;
if FileExists(FFileName) = False then
begin
raise EFileNoExist.Create('File not found: "' + FFileName + '"');
end;
end;
destructor TWinFileInfo.Destroy;
begin
//...
inherited;
end;
{ ----------------------------------------------------------------------------
TWinDrive
---------------------------------------------------------------------------- }
constructor TWinDrive.Create(ADriveChar: Char);
begin
FDriveChar := ADriveChar;
if DirectoryExists(DriveCharToFileDir(FDriveChar)) = False then
begin
raise EDriveNoExist.Create('Drive not found: "' + FDriveChar + '"');
end;
end;
destructor TWinDrive.Destroy;
begin
//...
inherited;
end;
function TWinDrive.GetSpaceTotal: Int64;
var
RootChars: array[0..4] of Char;
Root: PChar;
Dir: String;
Buffer: Int64;
begin
RootChars[0] := FDriveChar;
RootChars[1] := DriveDelim;
RootChars[2] := PathDelim;
RootChars[3] := #0;
Root := RootChars;
Dir := GetCurrentDir;
if SetCurrentDir(DriveCharToFilePath(FDriveChar)) then
begin
GetDiskFreeSpaceEx(Root,Buffer,Result,nil);
SetCurrentDir(Dir);
end else
begin
Result := -1;
end;
end;
function TWinDrive.GetSpaceFree: Int64;
var
RootChars: array[0..4] of Char;
Root: PChar;
Dir: String;
Buffer: Int64;
begin
RootChars[0] := FDriveChar;
RootChars[1] := DriveDelim;
RootChars[2] := PathDelim;
RootChars[3] := #0;
Root := RootChars;
Dir := GetCurrentDir;
if SetCurrentDir(DriveCharToFilePath(FDriveChar)) then
begin
GetDiskFreeSpaceEx(Root,Result,Buffer,nil);
SetCurrentDir(Dir);
end else
begin
Result := -1;
end;
end;
{ ----------------------------------------------------------------------------
TWinFile
---------------------------------------------------------------------------- }
constructor TWinFile.Create(AFileName: String);
begin
ExecuteMode := feOpen;
FFileName := AFileName;
FDrive := TWinDrive.Create(ExtractDriveChar(FFileName));
FInfo := TWinFileInfo.Create(FFileName);
if FileExists(FFileName) = False then
begin
raise EFileNoExist.Create('File not found: "' + FFileName + '"');
end;
end;
destructor TWinFile.Destroy;
begin
FDrive.Free;
FInfo.Free;
inherited;
end;
function TWinFile.GetExtension(WithDot: Boolean = True): String;
begin
if WithDot = True then
begin
Result := ExtractFileExt(FFileName);
end else
begin
Result := Copy(ExtractFileExt(FFileName),2,Length(ExtractFileExt(FFileName)) - 1);
end;
end;
function TWinFile.GetFileName(WithExt: Boolean = True): String;
begin
if WithExt = True then
begin
Result := ExtractFileName(FFileName); //Name + Erweiterung
end else
begin
Result := ExtractFileName(ChangeFileExt(FFileName,'')); //Nur Dateiname
end;
end;
function TWinFile.GetFolderName: String;
begin
Result := ExtractFileFolder(FFileName);
end;
function TWinFile.GetSize: Int64;
begin
Result := GetFileSize(FFileName);
end;
function TWinFile.GetPath: String;
begin
Result := ExtractFilePath(FFileName); //Gesamter Ordnerpfad (ohne Dateiname)
end;
function TWinFile.GetDir: String;
begin
Result := ExtractFileDir(FFileName);
end;
function TWinFile.GetModified: TDateTime;
begin
Result := GetFileModified(FFileName);
end;
function TWinFile.GetCreated: TDateTime;
begin
Result := GetFileCreated(FFileName);
end;
function TWinFile.GetAccessed: TDateTime;
begin
Result := GetFileAccessed(FFileName);
end;
function TWinFile.GetAttributes: TFileAttributes;
begin
Result := GetFileAttributes(FFileName);
end;
function TWinFile.GetOwner: String;
var
SecDescr: PSecurityDescriptor;
SizeNeeded, SizeNeeded2: DWORD;
OwnerSID: PSID;
OwnerDefault: BOOL;
OwnerName, DomainName: PChar;
OwnerType: SID_NAME_USE;
begin
GetMem(SecDescr,1024);
GetMem(OwnerSID,SizeOf(PSID));
GetMem(OwnerName,1024);
GetMem(DomainName,1024);
try
if GetFileSecurity(PChar(FFileName),OWNER_SECURITY_INFORMATION,SecDescr,1024,SizeNeeded) = True then
begin
if GetSecurityDescriptorOwner(SecDescr,OwnerSID,OwnerDefault) = True then
begin
SizeNeeded := 1024;
SizeNeeded2 := 1024;
if LookupAccountSID(nil,OwnerSID,OwnerName,SizeNeeded,DomainName,SizeNeeded2,OwnerType) = True then
begin
Result := OwnerName + '@' + DomainName;
end else
begin
raise ENoGetFileOwner.Create('Could not determine the file owner');
end;
end else
begin
raise ENoGetFileOwner.Create('Could not determine the file owner');
end;
end else
begin
raise ENoGetFileOwner.Create('Could not determine the file owner');
end;
finally
FreeMem(SecDescr);
FreeMem(OwnerName);
FreeMem(DomainName);
end;
end;
function TWinFile.Execute: Boolean;
begin
Result := ExecuteFile(FFileName,ExecuteMode);
end;
function TWinFile.SafeExecute: Boolean;
begin
Result := ExecuteFile(FFileName,ExecuteMode,True);
end;
end.