GetCompressedFileSizeW lazarus / 21-General ---------------------------------------------------------------------- HomeBoy38 · 2023-11-22 18:02 Hi, I want to retrieve the file size of a NTFS compressed file, using GetCompressedFileSizeW: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i CompSizeL, CompSizeH: DWORD;CompSizeL := GetCompressedFileSizeW(PWideChar(MyFilePathLong), @CompSizeH);  This is correctly working for small files (less than 4 GB). As far as the file is bigger, the size is wrong. Either I have not understood what really is in CompSizeH, either it is because I have no idea of how to put both sizes into another variable (which kind I should use?). I have tried a bunch of ways to get the correct size, everything failed. I have an idea on how to have my code working, but I want to share my questionning to have a chance to learn something and maybe help someone else. Thanks ---------------------------------------------------------------------- Fibonacci · 2023-11-22 18:06 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses Windows; var  l, h: dword;  li: LARGE_INTEGER; begin  l := GetCompressedFileSizeW('...', @h);   li.LowPart := l;  li.HighPart := h;   writeln('size = ', li.QuadPart);  readln;end. ---------------------------------------------------------------------- HomeBoy38 · 2023-11-22 18:34 Wow, you were fast! I found that somewhere, but I did not understood it and was not able to reproduce it correctly. With your answer, I totally understood that and was able to correct my code. Thanks a lot! ---------------------------------------------------------------------- KodeZwerg · 2023-11-22 19:31 Here's a two-in-one method that, if succeed, gives back filesize for both situations, compressed and uncompressed: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function GetFileSizeEx(hFile: THandle; lpFileSize: PULARGE_INTEGER): BOOL; stdcall; external 'kernel32.dll' name 'GetFileSizeEx';function GetFileSize(const AFileName: UnicodeString; out AValue: UInt64): Boolean;var  FileSizeHigh,  FileSizeLow: DWORD;  hFile: THandle;  LargeFileSize: ULARGE_INTEGER;begin  hFile := CreateFileW(PWideChar(AFileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);  if (hFile = INVALID_HANDLE_VALUE) then    Exit(False);  try    FileSizeLow := GetCompressedFileSizeW(PWideChar(AFileName), @FileSizeHigh);    if (not FileSizeLow = INVALID_FILE_SIZE) then      begin        AValue := UInt64(FileSizeHigh) shl 32 or FileSizeLow;        Result := True;    end    else      begin        if (not GetFileSizeEx(hFile, @LargeFileSize)) then          Exit(False);        AValue := LargeFileSize.QuadPart;        Result := True;      end;  finally    CloseHandle(hFile);  end;end; ---------------------------------------------------------------------- Remy Lebeau · 2023-11-23 20:40 Quote from: KodeZwerg on November 22, 2023, 08:31:04 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i FileSizeLow := GetCompressedFileSizeW(PWideChar(AFileName), @FileSizeHigh);if (not FileSizeLow = INVALID_FILE_SIZE) then That is not the correct way to check for success when the 2nd parameter is not nil.  For files >= 4GB, the returned FileSizeLow can be $FFFFFFFF (ie, INVALID_FILE_SIZE) for valid file sizes, so you MUST check GetLastError() to differentiate success from failure.  This is documented behavior: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf- fileapi-getcompressedfilesizew QuoteIf the return value is INVALID_FILE_SIZE and lpFileSizeHigh is non-NULL, an application must call GetLastError to determine whether the function has succeeded (value is NO_ERROR) or failed (value is other than NO_ERROR). So, use this instead: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i if (FileSizeLow <> INVALID_FILE_SIZE) or (GetLastError() = 0) then ---------------------------------------------------------------------- HomeBoy38 · 2023-11-24 07:07 I did not experienced this when I tested Fibonacci's suggestion, my file was correctly processed instead of showing an error in the log. In my test case, the 6 GB file reported 2 GB in filesizelow. But you are right, Microsoft's documentation says that, but I think it is in rare case exceptions. I am not really concerned for my tool (not a big deal if I am in that case) but it may help other people experiencing such issue Thanks ---------------------------------------------------------------------- Remy Lebeau · 2023-11-26 20:13 Quote from: HomeBoy38 on November 24, 2023, 08:07:43 amIn my test case, the 6 GB file reported 2 GB in filesizelow. Correct.  6GB is 6442450944 (hex $180000000), which has its lower 32 bits as 2147483648 (hex $80000000), which is 2GB. Quote from: HomeBoy38 on November 24, 2023, 08:07:43 amBut you are right, Microsoft's documentation says that, but I think it is in rare case exceptions. Any file size that is an even multiple of 4GB (minus 1) will have its low 32bits set as $FFFFFFFF, eg: $0FFFFFFFF = 4294967295 (4GB - 1) $1FFFFFFFF = 8589934591  (8GB - 1) $2FFFFFFFF = 12884901887 (12GB - 1) $3FFFFFFFF = 17179869183 (16GB - 1) etc... So, your code would fail on such files if you don't check the error code as Microsoft describes. 6GB is obviously not an even multiple of 4GB.