General information
Category:
Windows API functions
>Hi Carlos,
>
>>The problem is that I want to use SetFilePointerEx, I understand that I have to "split" the liDistanceToMove LARGE_INTEGER parameter into two 4 byte numbers
>
>VFP doesn't work with 64 bit integers very well. It uses 64 bit floating points internally, which have a different value range. Why do you have to split the numbers? If it's possible you should work with two 32 bit integer values all the time.
Hi Christof, thanks for your reply.
I want to use the SetFilePointerEx API function:
BOOL WINAPI SetFilePointerEx(
HANDLE hFile,
LARGE_INTEGER liDistanceToMove,
PLARGE_INTEGER lpNewFilePointer,
DWORD dwMoveMethod
);
liDistanceToMove is a LARGE_INTEGER, defined as:
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
lpNewFilePointer LONG HighPart;
};
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER,
*PLARGE_INTEGER;
The only thing I understand is that a large Integer uses 8 bytes, while an integer uses 4 bytes. Now the only way I found to pass liDistanceToMove to the API function is explained by Calvin Hsia:
DECLARE long SetFilePointerEx IN kernel32;
long hnd,;
long lDistanceToMoveL,;
long lDistanceToMoveH,;
string @lpNewFilePointer,;
long dwMoveMethod
The large integer is split into 2 integers, using:
lDistanceToMoveH = INT(lDistanceToMove/2^32)
lDistanceToMoveL = lDistanceToMove - lDistanceToMoveH * 2^32
But It seems that SET DECIMALS affect how lDistanceToMoveH is calculated for values near 4GB, so I used:
lDistanceToMoveL = lDistanceToMove % 2^32
lDistanceToMoveH = (lDistanceToMove - lDistanceToMoveL) / 2^32
That seems to work no matter what the value of SET DECIMALS is.
By the way, lpNewFilePointer is initialized as:
lpNewFilePointer = Replicate(Chr(0),8)
And I get the new file pointer position by doing:
m.lnLow = CToBin(Left(m.tcLargeInt, 4), "4rs")
m.lnHigh = CToBin(Right(m.tcLargeInt, 4), "4rs")
If m.lnLow < 0 Then
m.tnLow = m.tnLow + 2^32
Endif
If m.lnHigh < 0 Then
m.lnHigh = m.lnHigh + 2^32
Endif
m.lnLargeInt = m.lnLow + m.lnHigh * 2^32
I am pretty shure that m.lnLow has to be converted to unsigned, not so shure about m.lnHigh
Regarding the 64 bit floating point vs 64 bit integers, I understand value ranges are not the same, but it seems to work for what I need, I have only tested with files around 8GB
Carlos
Previous
Next
Reply
View the map of this thread
View the map of this thread starting from this message only
View all messages of this thread
View all messages of this thread starting from this message only