troubleshooting Question

Using WINAPI calls to download a very large file. Fatal error occurs only when I try to do a DoEvents. Need to update a progressBar, as the file downloads.. (VarPtr might be issue)

Avatar of Jeanette Durham
Jeanette DurhamFlag for United States of America asked on
Visual Basic.NET
4 Comments1 Solution505 ViewsLast Modified:
Dear Experts

Ok, I've got this program, and I'm updating it to .net. The portion of the program with the error is supposed to retreive a file over the internet, and save it to disk. This worked in vb6, and I'm not sure why it's not working here. I feel that it is /very/ close to working, but it isn't quite right. I think there is something wrong with the way I'm trying to compensate for the now non-existant VarPtr function. Anyways, two things are happening. The first, the file just starts at 0k and stays there, and the second is this fatal error which occurs whenever I try to put in any line relating to a 'DoEvents' call. I think when my program does the doEvents, it is losing the handles somehow, or windows is moving them or something. Here is the code for this, any help would be greatly appreciated!

~Michael@iondataexpress.com

'---------------- solution off of experts exchange
      'https://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_22084328.html
      
      Private Declare Function InternetOpenW Lib "wininet.dll" (ByVal lpszCallerName As Integer, ByVal dwAccessType As Integer, ByVal lpszProxyName As Integer, ByVal lpszProxyBypass As Integer, ByVal dwFlags As Integer) As Integer
      Private Declare Function InternetOpenUrlW Lib "wininet.dll" (ByVal hInternet As Integer, ByVal lpszUrl As Integer, ByVal lpszHeaders As Integer, ByVal dwHeadersLength As Integer, ByVal dwFlags As Integer, ByVal dwContext As Integer) As Integer
      Private Declare Function InternetReadFile Lib "wininet.dll" (ByVal hFile As Integer, ByVal sBuffer As Integer, ByVal lNumBytesToRead As Integer, ByRef lNumberOfBytesRead As Integer) As Integer
      Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInternet As Integer) As Integer
      Private Declare Function CreateFileW Lib "kernel32" (ByVal lpFileName As Integer, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, ByVal lpSecurityAttributes As Integer, ByVal dwCreationDisposition As Integer, ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As Integer) As Integer
      Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Integer, ByVal lpBuffer As Integer, ByVal nNumberOfBytesToWrite As Integer, ByRef lpNumberOfBytesWritten As Integer, ByVal lpOverlapped As Integer) As Integer
      Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Integer) As Integer
      
      Const GWrite As Integer = 1073741824
      Const Create As Integer = 2
      Const Context As Integer = 2
      Const Multiple As Integer = 1024
      Const Reload As Integer = &H80000000

    'if the other varPtr doesn't work, use this one
    Public Function VarPtr(ByVal o As Object) As Integer
        Dim GC As System.Runtime.InteropServices.GCHandle = System.Runtime.InteropServices.GCHandle.Alloc(o, System.Runtime.InteropServices.GCHandleType.Pinned)
        Dim ret As Integer = GC.AddrOfPinnedObject.ToInt32
        GC.Free()
        Return ret
    End Function

    Public Sub httpGet(ByVal File As String, ByVal httpUrl As String, Optional ByRef Kilobytes As Integer = 1)
        Dim bytes() As Byte
        Dim hOpen As Integer
        Dim hConn As Integer
        Dim cFile As Integer
        Dim bSize As Integer
        Dim bRead As Integer
        Dim myFile As Scripting.File

        Dim handle As Runtime.InteropServices.GCHandle
        Dim strPtr As IntPtr

        'Dim value As String = "Bob"
        'handle = Runtime.InteropServices.GCHandle.Alloc(value, Runtime.InteropServices.GCHandleType.Pinned)
        ''2) Get the address of the pinned object
        'Dim strPtr As IntPtr = handle.AddrOfPinnedObject()
        ''3) Free the handle:
        'handle.Free()

        hOpen = InternetOpenW(0, 1, 0, 0, 1)

        handle = Runtime.InteropServices.GCHandle.Alloc(httpUrl, Runtime.InteropServices.GCHandleType.Pinned)
        strPtr = handle.AddrOfPinnedObject()
        hConn = InternetOpenUrlW(hOpen, strPtr, 0, 0, Reload, Context)
        handle.Free()

        handle = Runtime.InteropServices.GCHandle.Alloc(File, Runtime.InteropServices.GCHandleType.Pinned)
        strPtr = handle.AddrOfPinnedObject
        cFile = CreateFileW(strPtr, GWrite, 0, 0, Create, 0, 0)
        handle.Free()

        myFile = mainForm.myFSO.GetFile(File)

        If cFile <> (-1) And hConn <> 0 Then
            bSize = (Kilobytes * Multiple)
            ReDim bytes(bSize)
            Do
                'UPGRADE_ISSUE: VarPtr function is not supported. Click for more: 'mshelp://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="367764E5-F3F8-4E43-AC3E-7FE0B5E074E2"'
                If InternetReadFile(hConn, VarPtr(bytes(0)), bSize, bRead) Then
                    'UPGRADE_ISSUE: VarPtr function is not supported. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="367764E5-F3F8-4E43-AC3E-7FE0B5E074E2"'
                    WriteFile(cFile, VarPtr(bytes(0)), bSize, 0, 0)
                Else
                    Exit Do
                End If
                'Application.DoEvents()    <<<<------This is the line that errs out.
                frmProgress.Refresh()
                If frmProgress.ProgressBar1.Maximum >= myFile.Size Then frmProgress.ProgressBar1.Value = myFile.Size
            Loop While bRead <> 0
        End If
        InternetCloseHandle(hConn)
        InternetCloseHandle(hOpen)
        CloseHandle(cFile)
    End Sub

These are the errors and descriptions for this (interestingly enough, each time I run it, it doesn't always produce the same error:

1) AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

2) FatalExecutionEngineError was detected: The runtime has encountered a fatal error. The address of the error was at 0x7a00d227, on thread 0xc94. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
ASKER CERTIFIED SOLUTION
shahprabal

Our community of experts have been thoroughly vetted for their expertise and industry experience.

Join our community to see this answer!
Unlock 1 Answer and 4 Comments.
Start Free Trial
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 4 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros