Home > other >  SEEK_FAILURE What to do if SetFilePointer fails if file is over 4.1 GB
SEEK_FAILURE What to do if SetFilePointer fails if file is over 4.1 GB

Time:10-12

If SetFilePointer(hFile, 0&, ByVal 0&, FILE_END) _
    = INVALID_SET_FILE_POINTER Then

This call raises the HBF_SEEK_FAILURE error ( 45603) at some point of time.

The decoded API error message is:

Seek Error Error 87 Wrong parameter

I believe it fails when the file size is over 4.1 GB.

What could I do to work around this problem?

I have read here that this error is a valid response if a file is over 4 GB. So should I just ignore it?

According to a suggestion, I am now using the Ex version, but I get a Wrong DLL Calling Convention error:

Public Sub SeekEnd()
    RaiseErrorIfClosed
        
    If SetFilePointerEx(hFile, 0&, ByVal 0&, FILE_END) _
        = INVALID_SET_FILE_POINTER Then
            RaiseError HBF_SEEK_FAILURE
    End If
End Sub

Thank you!

CodePudding user response:

The easy solution; call SetFilePointerEx instead.

If you want to continue using SetFilePointer with large files then you should set the lpDistanceToMoveHigh parameter to a valid pointer (which may point to a value that is 0 in this specific case).

When lpDistanceToMoveHigh is set you can check the return value like this:

If SetFilePointer(...) = INVALID_SET_FILE_POINTER _
AndAlso If Not Err.LastDLLError = 0
  ' Handle error
Else
  ' Success
End If

Here is a version that uses SetFilePointerEx

Private Declare Function SetFilePointerEx Lib "kernel32" ( _
        ByVal hFile As Long, _
        ByVal liDistanceToMove As Currency, _
        ByRef lpNewFilePointer As Currency, _
        ByVal dwMoveMethod As Long) As Boolean

Public Function SeekEOF() As Currency
'       NEW
' Seek to a base 0 EOF and return the pointer position
' The returned value is the new ABSOLUTE pointer positon.
    Dim RetVal As Long
    Dim tmpPosition As Currency
    Dim returnedPosition As Currency
    RaiseErrorIfClosed
    tmpPosition = 0@
    RetVal = SetFilePointerEx(hFile, (tmpPosition), returnedPosition, FILE_END) ' seek relative to the END of the file. thius returns a pointer to the final byte ?
    If RetVal = 0 Then  ' failed
        RaiseError HBFH_SEEK_FAILURE
    End If
    fCurrentPointerPosition = (returnedPosition) * 10000@
    If fCurrentPointerPosition <> Me.fileSize() Then 'gosh, what could have happened ? BASE 0 compared to BASE 1 position should=file size (ie 1 past the last byte!)
        RaiseError HBFH_SEEK_FAILURE
    End If
    SeekEOF = fCurrentPointerPosition ' returns the BASE 0 absolute pointer positon which is 1 past the last byte
End Function
  • Related