Re: The following Marshal code almost works

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Jay B. Harlow [MVP - Outlook] (Jay_Harlow_MVP_at_msn.com)
Date: 02/09/05


Date: Wed, 9 Feb 2005 10:08:10 -0600

Just Me,
First I would "improve it" via using Environment.GetLogicalDrives instead.

Is there a reason you are not using Environment.GetLogicalDrives?

According to Adam's book Marshal.PtrToStringAuto(IntPtr, Integer) should
*NOT* terminate at the first null character, where as the
Marshal.PtrToStringAuto(IntPtr) does. Are you certain its getting truncated
& not simply the Debugger stops displaying after the null char? Remember the
Debugger treats the null char as a string terminator!

If I actually needed to call Kernel32.GetLogicalDriveStrings I would use
Marshal.AllocHGlobal instead of Marshal.StringToHGlobalAuto, as
Marshal.StringToHGlobalAuto is more for when you need to pass a string into
Win32, not return a string from Win32...

Something like:
        Dim lDrives As String
        Dim lLenOflDrives As Integer = Kernel.GetLogicalDriveStrings(0,
IntPtr.Zero)
        Dim lPointerToMemory As IntPtr = Marshal.AllocHGlobal(lLenOflDrives
* 2)
        Dim rc As Integer = Kernel.GetLogicalDriveStrings(lLenOflDrives,
lPointerToMemory)
        If rc <> 0 Then
            lDrives = Marshal.PtrToStringAuto(lPointerToMemory,
lLenOflDrives) 'Text to first null, e.g, a:\
            Marshal.FreeHGlobal(lPointerToMemory)
            Dim drives() As String = lDrives.Split(ControlChars.NullChar)
        End If

For information on P/Invoke I normally reference Adam Nathan's book ".NET
and COM - The Complete Interoperability Guide" from SAMS Press.

Hope this helps
Jay

" Just Me" <groups@a-znet.com> wrote in message
news:eIq8dqrDFHA.960@TK2MSFTNGP09.phx.gbl...
> The following almost works.
> The problem is Marshal.PtrToStringAuto seems to terminate at the first
> null so I don't get the full string.
>
> Any suggestions on how to fix this?
> Or how to improve the code?
>
> Thanks
>
> PS I added the +1 because as I understand the GetLogicalDriveStrings doc
> there will be an uncounted null at the end for Unicode. Agree?
>
> Dim lDrives As String
> Dim lLenOflDrives As Integer
> Dim lPointerToMemory As IntPtr
> lLenOflDrives = Kernel.GetLogicalDriveStrings(0, Nothing)
> Dim lDrivesSB As New StringBuilder(lLenOflDrives + 1)
> lDrivesSB.Insert(0, ChrW(33), lLenOflDrives + 1)
> lPointerToMemory = Marshal.StringToHGlobalAuto(lDrivesSB.ToString)
> 'Get the list of dirves. Returns a:\<null>c:\<null><null>
> If Kernel.GetLogicalDriveStrings(lLenOflDrives, lPointerToMemory) Then
> 'Would need to use PtrToStringAnsi if GetLogicalDriveStrings were declared
> CharSet.Ansi
> lDrives = Marshal.PtrToStringAuto(lPointerToMemory, lLenOflDrives + 1)
> 'Text to first null, e.g, a:\
> Marshal.FreeHGlobal(lPointerToMemory)
> 'See if aDrive is in the list
> DriveExists = InStr(1, lDrives, drive, CompareMethod.Text)
> End If
>



Relevant Pages

  • Re: connect to WMI object directly
    ... you can easily bind to a specific process ... > this way I will have to go through all the results to perform an operation,> like Terminate for example. ... >> Public Shared Sub EnumerateProcesses(ByVal machineName As String, ... >> Dim co As ConnectionOptions ...
    (microsoft.public.win32.programmer.wmi)
  • Re: GetTempPath API
    ... if you look at the string in the Autos window you ... >> I don't know if this helps but it did not matter the size of the buffer ... It still did not terminate the string. ... >> Dim Path As String ...
    (microsoft.public.dotnet.languages.vb)
  • Search pattern
    ... Dim strfile As String ... Dim bAddressFound As Boolean ... Dim strCurrentChar As String ...
    (comp.databases.ms-access)
  • Auto Write Name and Merge across
    ... Dim Sheetname01 As String ... Dim WeekName01 As String ...
    (microsoft.public.excel.misc)
  • Re: multiplatform (pocketPC & desktopPC) (Daniel !!)
    ... Friend Versione As String ... Public Sub GetMyConnectionPalmare() ... Dim errorMessages As String ... Private Function GetDS_Desktop(ByVal SQL As String) As DataSet ...
    (microsoft.public.dotnet.framework.compactframework)