JarUnPacker/prereq/ANB ST CP/data/FileUtilsEx.pas
2023-02-02 12:02:14 +03:00

170 lines
5.3 KiB
ObjectPascal

//version 0.31 beta
unit FileUtilsEx;
{$MODE Delphi}
{$codepage UTF8}
interface
uses windows, sysutils, ShellApi, Classes;
type TExePlatform = (expUnknown, exp32Bit, exp64Bit, expOther);
//stdcalls
function FileVersion (AFileName: String): String;
function FileSize2Str (const AFileSize: Int64; AStringNames: Array of String; const ADecimalPlaces: Byte): String; Stdcall; Overload;
function FileSize2Str (const AFileSize: Int64; AStringNames: Array of String): String; Stdcall; Overload;
function FileSize2Str (const AFileSize: Int64; const ADecimalPlaces: Byte): String; Overload;
function FileSize2Str (const AFileSize: Int64): String; Overload;
function FileAccessDateToDateTime (FileTime: TFILETIME): TDateTime; Stdcall;
function RenameDir (const DirName, NewName: String): Boolean; STDCALL;
function GetEXEPlatform (const AFileName: String): TExePlatform; STDCALL;
implementation
const AFileSizeNames: Array[0..4] of String = ('Byte', 'KB', 'MB', 'GB', 'TB');
//Getting version of the file
function FileVersion (AFileName: String): String;
var szName: array[0..255] of Char;
P: Pointer;
Value: Pointer;
Len: UINT;
GetTranslationString: String;
FFileName: PChar;
FValid:boolean;
FSize: DWORD;
FHandle: DWORD;
FBuffer: PChar;
begin
try
FFileName:= StrPCopy(StrAlloc(Length(AFileName) + 1), AFileName);
FValid:= False;
FSize:= GetFileVersionInfoSize(FFileName, FHandle);
if FSize > 0 then
try
GetMem(FBuffer, FSize);
FValid:= GetFileVersionInfo(FFileName, FHandle, FSize, FBuffer);
except
FValid:= False;
raise;
end;
Result:= '';
if FValid then
VerQueryValue(FBuffer, '\VarFileInfo\Translation', P, Len)
else
P:= nil;
if P <> nil then
GetTranslationString:= IntToHex(MakeLong(HiWord(Longint(P^)), LoWord(Longint(P^))), 8);
if FValid then
begin
StrPCopy(szName, '\StringFileInfo\' + GetTranslationString + '\FileVersion');
if VerQueryValue(FBuffer, szName, Value, Len) then
Result:= StrPas(PChar(Value));
end;
finally
try
if FBuffer <> nil then
FreeMem(FBuffer, FSize);
except
end;
try
StrDispose(FFileName);
except
end;
end;
end;
//FileSize2Str
function FileSize2Str (const AFileSize: Int64; AStringNames: Array of String; const ADecimalPlaces: Byte): String; Overload;
function FrmtSize (const ASize, ADelim: Int64; const ADP: Byte): String;
var VDelim: Int64;
Indx: Byte;
begin
VDelim:= 1;
for Indx:= 0 to ADP do
VDelim:= VDelim*10;
Result:= FloatToStr(round((ASize*VDelim)/ADelim)/VDelim);
end;
const AFrmtsStr: String = '%s %s';
begin
//Bytes
if AFileSize < 1024 then
Result:= Format(AFrmtsStr, [IntToStr(AFileSize), AStringNames[0]]);
//KiloBytes
if (AFileSize >= 1024) and (AFileSize < 1048576) then
Result:= Format(AFrmtsStr, [FrmtSize(AFileSize, 1024, ADecimalPlaces), AStringNames[1]]);
//MegaBytes
if (AFileSize >= 1048576) and (AFileSize < 1073741824) then
Result:= Format(AFrmtsStr, [FrmtSize(AFileSize, 1048576, ADecimalPlaces), AStringNames[2]]);
//GigaBytes
if (AFileSize >= 1073741824) and (AFileSize < 1099511627776) then
Result:= Format(AFrmtsStr, [FrmtSize(AFileSize, 1073741824, ADecimalPlaces), AStringNames[3]]);
//TeraBytes
if (AFileSize >= 1099511627776) then
Result:= Format(AFrmtsStr, [FrmtSize(AFileSize, 1073741824, ADecimalPlaces), AStringNames[4]]);
end;
function FileSize2Str (const AFileSize: Int64; AStringNames: Array of String): String; Overload;
begin
Result:= FileSize2Str(AFileSize, AStringNames, 2);
end;
function FileSize2Str (const AFileSize: Int64; const ADecimalPlaces: Byte): String; Overload;
begin
Result:= FileSize2Str(AFileSize, AFileSizeNames, ADecimalPlaces);
end;
function FileSize2Str (const AFileSize: Int64): String; Overload;
begin
Result:= FileSize2Str(AFileSize, AFileSizeNames, 2);
end;
//FileAccessDateToDateTime
//Author: Дураг (http://www.sql.ru/forum/memberinfo.aspx?mid=32731) from http://www.sql.ru/forum/259218/kak-poluchit-datu-i-vremya-sozdaniya-fayla
function FileAccessDateToDateTime (FileTime: TFILETIME): TDateTime;
var LocalTime: TFILETIME;
DOSFileTime: DWORD;
begin
FileTimeToLocalFileTime(FileTime, LocalTime);
FileTimeToDosDateTime(LocalTime, LongRec(DOSFileTime).Hi, LongRec(DOSFileTime).Lo);
Result:= FileDateToDateTime(DOSFileTime);
end;
//RenameDir
function RenameDir (const DirName, NewName: String): Boolean;
var shellinfo: TSHFILEOPSTRUCT;
DirFrom, DirTo: String;
begin
DirFrom:= DirName;
DirTo:= NewName;
with shellinfo do
begin
Wnd:= 0;
wFunc:= FO_RENAME;
pFrom:= PChar(DirFrom);
pTo:= PChar(DirTo);
fFlags:= FOF_FILESONLY or FOF_ALLOWUNDO or FOF_SILENT or FOF_NOCONFIRMATION;
end;
SHFileOperation(shellinfo);
Result:= DirectoryExists(NewName);
end;
//GetEXEPlatform
//Author Dmitry Arefiev (http://www.sql.ru/forum/808857/kak-opredelit-razryadnost-prilozheniya)
function GetEXEPlatform (const AFileName: String): TExePlatform;
var oFS: TFileStream;
iPeOffset: Integer;
iPeHead: LongWord;
iMachineType: Word;
begin
Result:= expUnknown;
try
oFS:= TFileStream.Create(AFileName, fmOpenRead or fmShareDenyNone);
try
oFS.Seek($3C, soFromBeginning);
oFS.Read(iPeOffset, SizeOf(iPeOffset));
oFS.Seek(iPeOffset, soFromBeginning);
oFS.Read(iPeHead, SizeOf(iPeHead));
if iPeHead <> $00004550 then
Exit;
oFS.Read(iMachineType, SizeOf(iMachineType));
case iMachineType of
$8664, $0200: Result:= exp64Bit;
$014C: Result:= exp32Bit;
else
Result:= expOther;
end;
finally
oFS.Free;
end;
except
end;
end;
end.