Hi!

I would like to use the SetFilePointer API to create a several GB large file, but I can't do that because 64-bits numbers are required to create files larger than 2 GB.

SetFilePointer API is declared like this:

DWORD SetFilePointer(
HANDLE hFile, // handle of file
LONG lDistanceToMove, // number of bytes to move file pointer
PLONG lpDistanceToMoveHigh,//address of high-order word of distance to move
DWORD dwMoveMethod // how to move
);


I would like to use "lpDistanceToMoveHigh" to create larger files, but I don't know how retrieve that "high-order word" that is required.

I tried this:

;////////////////////////////////////////////

.data
Multidata dd 1024,1048576,1073741824

.data?
NrOfBytesLow dd ?
NrOfBytesHigh dd ?


.code

...

NrOfBytesLow=20 (for creating a 20 GB large file)
esi=2 (for multiplying with 1074741824 (1 GB))



mov eax,NrOfBytesLow
imul Multidata
adc eax,0 ;necessary?
mov NrOfBytesLow,eax
mov ,edx


invoke SetFilePointer,CreateFileHandle,NrOfBytesLow,offset NrOfBytesHigh,FILE_BEGIN


;////////////////////////////////////////////

The above should create a 20 GB large file, but when using this method with SetFilePointer, the maximum possible filesize is only increased from 2 to 4 GB.

Questions:

Why can't i create larger files?
Is 4 GB the maximum when using 64-bits numbers?
Can I use a shift instruction (shr /shl) instead of multiplying ?



/Delight
Posted on 2001-10-06 10:11:01 by Delight
Maximum value in 32 bit: 4294967296 (calculate by doing 2^32)

Maximum value in 64 bit: 18446744073709551616 (this is 2^64)

So that's a whole lot bigger :)

You have to calculate the DWORDs like this:

upper = Int(value / (2^33))
lower = value - upper

(NOTE: Int truncates anything after the decimal point, it doesn't round here!)

I believe my formulas (formulae :grin: ) are correct, but they are not tested. I'm a bit unsure about the 33. Anybody?

Also, note that you have to pass the low dword as a direct value and the upper dword as a pointer according to your MSDN snippet.
Posted on 2001-10-06 10:28:00 by Qweerdy
I think that you have to set the value of to 5 in order to get a ~20GB filepointer.That means 5 times 4 294 967 296 Bytes of the NrOfBytesLow value which then can be zero. So if you give an address for the pointer lpDistanceToMoveHigh that means the NrOfBytesLow now reach up to 4 Gigabytes.

NrOfBytesLow = 1 073 741 824
= 1 (is 4GB)
should be 5 GB

NrOfBytesLow = 3 221 225 472
= 0 (is 0 GB the value, not the pointer)
should be 3GB

NrOfBytesLow = 0
=20
should be 80 GB


wolf
Posted on 2001-10-06 13:59:47 by Unregistered
:confused:

The largest possible file created without the high-order word is almost 2 gb (2^31 -2 bytes). When using it, I think the maximimum filesize should be 2^63 -2 bytes - thousands of GB!

Something is wrong with my code, but it can't be totaly wrong because the largest file that can be created is increased! Not to thousends of GB ,only 4 GB!!!

So, why can't I use imul to get that high word?

Has it something to do with that all file pointer values are signed values???

Does someone have an example of how to use the high-word data in SetFilePointer?

/Delight
Posted on 2001-10-07 06:37:44 by Delight
Delight,
the maximum file size of FAT32 file system is 4GB - 2 Bytes. So you should be sure you are writing to a NTFS drive.

japheth
Posted on 2001-10-07 07:11:41 by japheth
If the maximum file size of FAT32 file system is 4GB-2 Bytes that's the problem! Thank you Japheth! :)


/Delight
Posted on 2001-10-08 02:22:32 by Delight