Geeks With Blogs
Neil Smith [blog]code til ur fingers bleed

Ever tried getting a UNC filename from the mapped drive letter notation in a .net language?  I've just had to do it for the first time through vb.net.  Surely there's a simpler way than the following code...

Imports System.Runtime.InteropServices

Public Class Form1

    Private Const NO_ERROR As Long = 0&

    Private Const ERROR_MORE_DATA As Long = 234&

    Private Structure REMOTE_NAME_INFO

        _

        Public lpUniversalName As String

        _

        Public lpConnectionName As String

        _

        Public lpRemainingPath As String

    End Structure

 

    Private Enum INFO_LEVEL As Integer

        UNIVERSAL_NAME_INFO_LEVEL = 1

        REMOTE_NAME_INFO_LEVEL = 2

    End Enum

 

    Private Declare Auto Function WNetGetUniversalName Lib "mpr.dll" ( _

_

ByVal lpLocalPath As String, _

ByVal dwInfoLevel As INFO_LEVEL, _

ByVal lpBuffer As IntPtr, _

ByRef lpBufferSize As Integer _

) As Integer

 

    Public Function GetUniversalName( _

ByVal Path As String, _

ByRef UniversalName As String, _

ByRef ConnectionName As String, _

ByRef RemainingPath As String) As Boolean

        ' When successful, returns TRUE with UniversalName,

        ' ConnectionName, and RemainingPath data. If not

        ' successful, it may be the drive is local and not mapped.

        Dim buffer As Integer

        Dim ptrbuffer As IntPtr

        Dim status As Integer

        Dim rni As REMOTE_NAME_INFO

        Dim Success As Boolean

        Dim SafteyCount As Integer = 0

 

        UniversalName = ""

        ConnectionName = ""

        RemainingPath = ""

        buffer = 1024

 

        ptrbuffer = Marshal.AllocHGlobal(buffer)

        status = WNetGetUniversalName( _

        Path, INFO_LEVEL.REMOTE_NAME_INFO_LEVEL, _

        ptrbuffer, buffer)

        Do While True

            Select Case status

                Case NO_ERROR

                    rni = Marshal.PtrToStructure(ptrbuffer, GetType(REMOTE_NAME_INFO))

                    UniversalName = rni.lpUniversalName

                    ConnectionName = rni.lpConnectionName

                    RemainingPath = rni.lpRemainingPath

                    Success = True

                    Exit Do

                Case ERROR_MORE_DATA

                    If SafteyCount > 3 Then

                        Success = False

                        Exit Do

                    End If

                    SafteyCount += 1

                    Marshal.FreeHGlobal(ptrbuffer)

                    ptrbuffer = Marshal.AllocHGlobal(buffer)

                    status = WNetGetUniversalName(Path, _

                    INFO_LEVEL.REMOTE_NAME_INFO_LEVEL, ptrbuffer, buffer)

                Case Else

                    Success = False

                    Exit Do

            End Select

        Loop

        Marshal.FreeHGlobal(ptrbuffer)

        Return Success

    End Function

 

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

        Dim sPath As String = "x:\neil"

        Dim sUniversal As String = ""

        Dim sConn As String = ""

        Dim sRem As String = ""

        Dim sTmp = GetUniversalName(sPath, sUniversal, sConn, sRem)

 

        MessageBox.Show(sUniversal)

    End Sub

End Class

 

 

Posted on Wednesday, June 7, 2006 11:58 AM | Back to top


Comments on this post: Surely there's a simpler way!..

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Neil Smith | Powered by: GeeksWithBlogs.net