I need to use the SetFilePointer function of kernel32 to read a sector of the disk whose address is contained in a double for size problems. I know that the ReadFile function accepts the loword as long and hiword as long parameters, but I couldn't split my double address into two words.
I tried several methods using Mod and Fix, but in the end I only had overflow errors.
LoWord = CLng(dNum Mod CDbl(4294967295)) 'Dont care the number I use, I always get overflow error
or
LoWord = CLng(FMod(dNum, 4294967295#))
HiWord = CLng(dNum - (FMod(dNum, 4294967295#))) 'tryed different number to see the behaviour, don't care
where
Public Function FMod(a As Double, b As Double) As Double
FMod = a - Fix(a / b) * b
'http://en.wikipedia.org/wiki/Machine_epsilon
'Unfortunately, this function can only be accurate when `a / b` is outside [-2.22E-16,+2.22E-16]
'Without this correction, FMod(.66, .06) = 5.55111512312578E-17 when it should be 0
If FMod >= -2 ^ -52 And FMod <= 2 ^ -52 Then '+/- 2.22E-16
FMod = 0
End If
End Function
I tried to convert the double to byteArray or hexadecimal string to try a "manual" byte shift, but with no luck.
I already see the Convert Double into 8-bytes array, but the sample without modification always convert dNum=1 in [0, 0, 0, 0, 0, 0, 240, 63] as result and it don't seem the right one.
Do you have some tip or some other way to read sectors with a big address from a disk in VB6?
Thank you all for reading my question.
To better specify what I'm doing: I know that maybe vb6 isn't the best choice, but now I've started with this ... I read a sector number from an INI file (is variable) in hexadecimal format (as a string) which I convert to Long (but should it be carried in double, or what?), considering 512 bytes per sector. The number of bytes I have to read from the disk, starting from that sector on, is a constant.
When I use the function
Call SetFilePointer(hDevice, iStartSec * BytesPerSector, 0, FILE_BEGIN)
I have to specify the number of bytes and then I have to multiply by 512. This cause me the overflow I'm trying to bypass.
I tried also this method:
Private Type TKK_Dbl
Value As Double
End Type
Private Type Dbl2Long
LowVal As Long
HighVal As Long
End Type
Private D As TKK_Dbl
Private L As Dbl2Long
in function...
D.Value = CDbl(iStartSec) * CDbl(BytesPerSector)
LSet L = D
Call SetFilePointer(hDevice, L.LowVal, L.HighVal, FILE_BEGIN)
But it does not worked for me.