Hello all. I'm using an API function via PInvoke, with the interesting data being returned to a pointer. My application crashes when attempting to free the pointer. If run with no breakpoints, the application hangs on Line 61 below. After the first run, it will then throw a memory exception whether run at full speed or stepping through.
Please look over the code below and point me in the right direction.
Thanks!

Imports System.Runtime.InteropServices

Module Module1
    Partial Public Class PInvoke

       ' Have to use Pointer to return pathnames
       ' StringBuilder only returns first NULL-terminated string
        <DllImportAttribute("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Unicode, _
                            EntryPoint:="GetVolumePathNamesForVolumeNameW")> _
        Public Shared Function _
            GetMountPointsPtr(<[In]()> <MarshalAs(UnmanagedType.LPTStr)> _
                           ByVal sVolumeName As String, _
                            ByVal lpBuffer As IntPtr, _
                            ByVal uintBufferLen As UInteger, _
                            <Out()> ByRef uintReturnLen As UInteger) _
                            As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    End Class

Sub Main()
    ListMountPoints()
End Sub

' if no Volume GUID passed to sub, use the one corresponding to my USB stick
Private Sub ListMountPoints(Optional strVolumeName As String = _
                                    "\\?\Volume{9a615499-414c-11e0-bd72-78e7d1722cbc}\")

    Try
        Dim uintBufferLen As UInteger = CUInt(IntPtr.Size)
        Dim uintRequiredBufferLen As UInteger = 0
        Dim Win32ErrVal As Integer = 0
        Dim lpBuffer As IntPtr = Marshal.AllocHGlobal(IntPtr.Size)

        ' call function to get Required Buffer Length first
        PInvoke.GetMountPointsPtr(strVolumeName, lpBuffer, uintBufferLen, uintRequiredBufferLen)

        Win32ErrVal = Marshal.GetLastWin32Error()
        If Win32ErrVal = 234 Then
            'expected return value (ERROR_MORE_DATA), as our initial buffer is not large enough
        ElseIf Win32ErrVal = 2 Then
            ' oops
            MsgBox("File not found, invalid volume specified?")
            Exit Sub
        Else
            Throw New ApplicationException("Exception getting required buffer size from GetMountPointsPtr")
        End If

        ' reallocate the IntPtr with the right size
        lpBuffer = Marshal.ReAllocHGlobal(lpBuffer, CType(uintRequiredBufferLen, IntPtr))
        ' now set the buffer length
        uintBufferLen = uintRequiredBufferLen
        'zero out the length indicator
        uintRequiredBufferLen = 0
        ' reset errVal
        Win32ErrVal = 0

        If CBool(Not (PInvoke.GetMountPointsPtr(strVolumeName, lpBuffer, uintBufferLen, uintRequiredBufferLen))) Then
            Throw New ApplicationException("Exception Occured @ line 51!")
        End If

        ' retrieve the mountpoints(s)
        Dim strOutput As String = Marshal.PtrToStringUni(lpBuffer, CInt(uintRequiredBufferLen))
        '
        ' the app either hangs on FreeHGlobal or throws an exception 
        ' (System Error Code 998, ERROR_NOACCESS, Invalid access to memory location.)

        '
        Marshal.FreeHGlobal(lpBuffer)
        lpBuffer = IntPtr.Zero

        Console.WriteLine(strVolumeName + " has the following mountpoints: " + vbCrLf + strOutput.ToString)
        ' on my system this produces the following output:
        ' "\\?\Volume{9a615499-414c-11e0-bd72-78e7d1722cbc}\ has the following mountpoints: _  
        ' F:\ C:\mount\ D:\mount\"

    Catch ex As Exception
        ' have to declare new errVal, Try block out of scope now?
        Dim errVal As Integer = Marshal.GetLastWin32Error()
        MsgBox(ex.Message + " The last Win32 error was: " + CStr(errVal))
    End Try
End Sub
End Module

Solved! The API function returns the buffer length required in TCHARs, I needed to double that length requirement to get the byte count required for my pointer.

Also, in the original post, I stated line 61 as the point where I would get the access violation - after formatting and edits, that became line 68.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.