Sign in to follow this  
Followers 0
LeeVenty

DllCall GetFileSize/GetFileSizeEx 4G limit

9 posts in this topic

I want to use GetFileSize/GetFileSizeEx to get a file's size (it will larger than 4G )

now my code is like this

Func WINAPI_GetFileSize($hFile )

$BOOL = DllCall($dllName,"long","GetFileSize","hwnd",$hFile , "long*" , 0)

MsgBox(0 , "File Size" , $BOOL[0])
if @error Then Return SetError(@error,0,0)
Return SetError(@error,0,$BOOL[0])
EndFunc

It can return the right size of file which is small , I don't know how to get the the right size when the file is larger than 4G ....

Share this post


Link to post
Share on other sites



The full file size is the return value plus the second parameter. You need to shift the second parameter 32 bits to the left and have it stored in a 64 bit integer and then add the return value.

Unfortunately, bit shift in AutoIt only works on 32 bit integers. You'll have to come up with something weird in order to get the actual size.

Share this post


Link to post
Share on other sites

The full file size is the return value plus the second parameter. You need to shift the second parameter 32 bits to the left and have it stored in a 64 bit integer and then add the return value.

Unfortunately, bit shift in AutoIt only works on 32 bit integers. You'll have to come up with something weird in order to get the actual size.

thx , now I change my code , but the second parameter is always zero

Func WINAPI_GetFileSize($hFile )

Local $lpFileSizeHigh

Local $FileSizeHigh = DllStructCreate("long")

$lpFileSizeHigh = DllStructGetPtr($FileSizeHigh)

$BOOL = DllCall("Kernel32.dll","long","GetFileSize","hwnd",$hFile , "long*" , $lpFileSizeHigh)
_ArrayDisplay($BOOL)

Local $FileSizeHighNum = DllStructGetData($FileSizeHigh , 1)

MsgBox(0 , "File low Size" , $BOOL[0])
MsgBox(0 , "File High Size" , $FileSizeHighNum)

Local $FinalSize = $BOOL[0] + $FileSizeHighNum
if @error Then Return SetError(@error,0,0)
Return SetError(@error,0,$FinalSize)
EndFunc

When I want to use GetFileSize to get a 2.1GB file's size , $BOOL[0] is always like "-2145386496" and $FileSizeHighNum is always 0 . I don't know why

Share this post


Link to post
Share on other sites

Why not use FileGetSize()?

I use DllCall to write a tool for a dll testing . So I cannot use FileGetSize()...

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

One of these two DLLCalls should work:

$tUInt64 = DllStructCreate("uint64")
$tLowHigh = DllStructCreate("dword low;dword high")
$aResult = DllCall("Kernel32.dll", "DWORD", "GetFileSize", "HANDLE", $hFile, "DWORD*", 0)
DllStructSetData($tLowHigh, 1, $aResult[0])
DllStructSetData($tLowHigh, 2, $aResult[2])
MsgBox(0, '', DllStructGetData($tUInt64, 1))

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

$tInt64 = DllStructCreate("int64")
$aResult = DllCall("Kernel32.dll", "BOOL", "GetFileSizeEx", "HANDLE", $hFile, "ptr", DllStructGetPtr($tInt64))
MsgBox(0, "Erfolg: " & $aResult[0], DllStructGetData($tInt64, 1))
Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

One of these two DLLCalls should work:

$tUInt64 = DllStructCreate("uint64")
$tLowHigh = DllStructCreate("dword low;dword high")
$aResult = DllCall("Kernel32.dll", "DWORD", "GetFileSize", "HANDLE", $hFile, "DWORD*", 0)
DllStructSetData($tLowHigh, 1, $aResult[0])
DllStructSetData($tLowHigh, 2, $aResult[2])
MsgBox(0, '', DllStructGetData($tUInt64, 1))

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

$tInt64 = DllStructCreate("int64")
$aResult = DllCall("Kernel32.dll", "BOOL", "GetFileSizeEx", "HANDLE", $hFile, "ptr", DllStructGetPtr($tInt64))
MsgBox(0, "Erfolg: " & $aResult[0], DllStructGetData($tInt64, 1))

Thx for your help .. but there is still something wronng with GetFileSize()

DllStructSetData($tLowHigh, 2, $aResult[2])

$aResult[2] is still zero when the file is larger than 2G and smaller than 4G

Share this post


Link to post
Share on other sites

When I use C code , this API will work well ...

*************************************************************

HANDLE hFile = INVALID_HANDLE_VALUE;

wchar_t* pszFileName = L"D: \\test.test";

// LARGE_INTEGER liSizeHigh = { 0 };

// BOOL bRet = FALSE;

DWORD dwSizeHigh = 0;

DWORD dwSizeLow = 0;

hFile = CreateFile( pszFileName,

GENERIC_READ | GENERIC_WRITE,

0,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL);

assert(hFile != INVALID_HANDLE_VALUE);

dwSizeHigh = GetFileSize(hFile, &dwSizeLow);

assert (dwSizeLow);

return 0;

****************************************************************

Thx everybody , I use "uint" , and it works!!!

$aResult = DllCall("kernel32.dll","uint","GetFileSize","hwnd",$hFile , "ptr" , 0)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0