Browse for folder returns Mapped path not UNC path

Im using the Browse for Folder  and File Open Save api to allow users to edit paths to documents and folders.  This of course returns the Mapped path instead of the UNC path.  However I need the UNC path because of inconsistent mapping of network drives among users.  Looking for some code to help make this happen as well as some ideas on how to implement this on a form level.

Thanks
LVL 11
BillPowellAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

RimvisCommented:
Look at this link:

 Translating a Mapped Drive to a UNC Path
http://vbnet.mvps.org/index.html?code/network/uncfrommappeddrive.htm

It's for pure VB, but you should be able to translate it to VBA.
0
Gustav BrockCIOCommented:
Here is the bare bone code to copy and paste into a new module:

Option Compare Database
Option Explicit

Private Const UNIVERSAL_NAME_INFO_LEVEL As Long = &H1&

Private Declare Function WNetGetUniversalName Lib "mpr.dll" Alias "WNetGetUniversalNameA" ( _
  ByVal lpLocalPath As String, _
  ByVal dwInfoLevel As Long, _
  ByRef lpBuffer As Any, _
  ByRef lpBufferSize As Long) _
  As Long

Private Type UNIVERSAL_NAME_INFO
  lpUniversalName As String * &H400&
End Type

Public Function GetUniversalPath( _
  ByVal strDrivePath As String) _
  As String

' Get UNC path from remote drive letter or drive letter and file name.
' Empty string is returned for local or non-mapped drive letters.
' Remote path is *not* validated except for the drive letter.
'
' Example:

'   s:\docs\letter.txt
'
' may return
'
'   \\FS1\SYS\DATA\docs\letter.txt
'
' 2002-03-25. Cactus Data ApS, CPH.
 
  Dim typBuffer   As UNIVERSAL_NAME_INFO
  Dim lngBuffer   As Long
  Dim strPath     As String
 
  ' Obtain needed buffer size.
  Call WNetGetUniversalName(strDrivePath, UNIVERSAL_NAME_INFO_LEVEL, 0, lngBuffer)
  ' Retrieve UNC info.
  Call WNetGetUniversalName(strDrivePath, UNIVERSAL_NAME_INFO_LEVEL, typBuffer, lngBuffer)
 
  ' Extract UNC path from mixed buffer.
  strPath = typBuffer.lpUniversalName
  strPath = Mid$(strPath, InStr(strPath, vbNullChar) + 1)
  strPath = Left$(strPath, InStr(strPath, vbNullChar) - 1)

  GetUniversalPath = strPath

End Function

/gustav
0
BillPowellAuthor Commented:
Ok, I will give this a try.  Its probably worth mentioning that sometimes the mapping will be to a local drive.  Does this pose any problems since there is no UNC path for your C drive?
0
flavoCommented:
not sure if you gat ananswer, but i use this ( it reutrns c:\ for c:\ and d:\ for d:\ - for partitioned hdd)

used like LetterToUNC("M:") and retruns \\sever\path\

Option Compare Database
Option Explicit
'
Private Declare Function SHBrowseForFolder Lib "shell32.dll" Alias _
           "SHBrowseForFolderA" (lpBrowseInfo As BrowseForFolderInfo _
                                ) As Long
Private Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias _
           "SHGetPathFromIDListA" (ByVal pidl As Long, _
                                   ByVal pszPath As String _
                                  ) As Long
                                 
Private Const RESOURCETYPE_ANY = &H0
Private Const RESOURCE_CONNECTED = &H1

      Private Type NETRESOURCE
         dwScope As Long
         dwType As Long
         dwDisplayType As Long
         dwUsage As Long
         lpLocalName As Long
         lpRemoteName As Long
         lpComment As Long
         lpProvider As Long
      End Type

      Private Declare Function WNetOpenEnum Lib "mpr.dll" Alias _
         "WNetOpenEnumA" (ByVal dwScope As Long, ByVal dwType As Long, _
         ByVal dwUsage As Long, lpNetResource As Any, lphEnum As Long) _
         As Long

      Private Declare Function WNetEnumResource Lib "mpr.dll" Alias _
         "WNetEnumResourceA" (ByVal hEnum As Long, lpcCount As Long, _
         lpBuffer As Any, lpBufferSize As Long) As Long

      Private Declare Function WNetCloseEnum Lib "mpr.dll" ( _
         ByVal hEnum As Long) As Long

      Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" _
         (ByVal lpString As Any) As Long

      Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" _
         (ByVal lpString1 As Any, ByVal lpString2 As Any) As Long

Private Type BrowseForFolderInfo
 hOwner         As Long
 pidlRoot       As Long
 pszDisplayName As String
 lpszTitle      As String
 ulFlags        As Long
 lpfn           As Long
 lParam         As Long
 iImage         As Long
End Type



    Function LetterToUNC(DriveLetter As String) As String
         Dim hEnum As Long
         Dim NetInfo(1023) As NETRESOURCE
         Dim entries As Long
         Dim nStatus As Long
         Dim LocalName As String
         Dim UNCName As String
         Dim i As Long
         Dim r As Long


        If DriveLetter = "C:" Then
            LetterToUNC = "C:"
            Exit Function
        ElseIf DriveLetter = "D:" Then
            LetterToUNC = "D:"
            Exit Function
        End If
       

         ' Begin the enumeration
         nStatus = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_ANY, _
            0&, ByVal 0&, hEnum)

         LetterToUNC = "Drive Letter Not Found"

         'Check for success from open enum
         If ((nStatus = 0) And (hEnum <> 0)) Then
            ' Set number of entries
            entries = 1024

            ' Enumerate the resource
            nStatus = WNetEnumResource(hEnum, entries, NetInfo(0), _
               CLng(Len(NetInfo(0))) * 1024)

            ' Check for success
            If nStatus = 0 Then
               For i = 0 To entries - 1
                  ' Get the local name
                  LocalName = ""
                  If NetInfo(i).lpLocalName <> 0 Then
                     LocalName = Space(lstrlen(NetInfo(i).lpLocalName) + 1)
                     r = lstrcpy(LocalName, NetInfo(i).lpLocalName)
                  End If

                  ' Strip null character from end
                  If Len(LocalName) <> 0 Then
                     LocalName = Left(LocalName, (Len(LocalName) - 1))
                  End If

                  If UCase$(LocalName) = UCase$(DriveLetter) Then
                     ' Get the remote name
                     UNCName = ""
                     If NetInfo(i).lpRemoteName <> 0 Then
                        UNCName = Space(lstrlen(NetInfo(i).lpRemoteName) _
                           + 1)
                        r = lstrcpy(UNCName, NetInfo(i).lpRemoteName)
                     End If

                     ' Strip null character from end
                     If Len(UNCName) <> 0 Then
                        UNCName = Left(UNCName, (Len(UNCName) _
                           - 1))
                     End If

                     ' Return the UNC path to drive
                     LetterToUNC = UNCName

                     ' Exit the loop
                     Exit For
                  End If
               Next i
            End If
         End If

         ' End enumeration
         nStatus = WNetCloseEnum(hEnum)
      End Function
0
Gustav BrockCIOCommented:
> Its probably worth mentioning that sometimes the mapping will be to a local drive.  
> Does this pose any problems since there is no UNC path for your C drive?

No other problem than an UNC path for a non-shared local drive is empty.
If you need a path returned anyway, modify the code to return the original path if no UNC path is fournd:

  ...
  strPath = Left$(strPath, InStr(strPath, vbNullChar) - 1)

  If Len(strPath) = 0 Then
    strPath = strDrivePath
  End If

  GetUniversalPath = strPath
  ...

/gustav
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Access

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.