function GetRealFileSize (
const aFileName :
string) : Int64;
{ - Returns real size of a file on the disk (in bytes) }
{ - aFileName is the name of the file that shall be checked, including path }
{ - Works with every version of Windows - but under Win 9x the result may be }
{ inaccurate because GetDiskFreeSpace returns an incorrect value }
{ (See Microsoft Platform SDK for details) }
{ - Also works with compressed files }
{ - If an error occurs, the Result is negative }
var
ClusterSize : Cardinal;
SectorPerCluster : Cardinal;
BytesPerSector : Cardinal;
NumberOfFreeClusters : Cardinal;
TotalNumberOfClusters : Cardinal;
FileSize : Cardinal;
RealSize : Cardinal;
FileHandle : Cardinal;
OSVersInfo : OSVersionInfo;
Drive : AnsiString;
begin
Result := -1;
FileHandle := 0;
{ Check file }
if not FileExists(aFileName)
then Exit;
{ Check version of operating system }
OSVersInfo.dwOSVersionInfoSize := SizeOf(OSVersInfo);
if not GetVersionEx(OSVersInfo)
then Exit;
{ Windows NT, 2000, XP, 2003 }
if OSVersInfo.dwPlatformId = VER_PLATFORM_WIN32_NT
then
begin
FileSize := GetCompressedFileSize(PAnsiChar(aFileName), @FileSize);
{ Check for errors }
if FileSize=$FFFFFFFFthen
begin
MessageBox(0, PChar(SysErrorMessage(GetLastError)), '
', MB_OK
or MB_ICONERROR);
end;
end else
{ Windows 95, 98, ME }
try
FileHandle := CreateFile(PChar(aFileName),
GENERIC_READ,
FILE_SHARE_READ,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
FileSize := GetFileSize(FileHandle,@FileSize);
{ Check for errors }
if FileSize=$FFFFFFFF
then
begin
MessageBox(0, PChar(SysErrorMessage(GetLastError)), '
', MB_OK
or MB_ICONERROR);
end;
finally
FileClose(FileHandle);
end;
{ Check number of bytes per cluster }
Drive := ExtractFileDrive(aFileName);
if Drive[Length(Drive)]<>'
\'
then Drive := Drive+'
\';
if not GetDiskFreeSpace(PChar(Drive),
SectorPerCluster,
BytesPerSector,
NumberOfFreeClusters,
TotalNumberOfClusters)
then
begin
MessageBox(0, PChar(SysErrorMessage(GetLastError)), '
', MB_OK
or MB_ICONERROR);
Exit;
end;
ClusterSize := SectorPerCluster * BytesPerSector;
{ Calculate real size of file }
if not ((FileSize
mod ClusterSize) = 0)
then
begin
RealSize := ((FileSize
div ClusterSize) * ClusterSize) + ClusterSize
end else
begin
RealSize := FileSize;
end;
{ Return the real size }
Result := RealSize;
end;