Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


Browse for folder returns Mapped path not UNC path

Posted on 2004-11-02
Medium Priority
Last Modified: 2012-06-22
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.

Question by:BillPowell
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 19

Expert Comment

ID: 12472903
Look at this link:

 Translating a Mapped Drive to a UNC Path

It's for pure VB, but you should be able to translate it to VBA.
LVL 52

Expert Comment

by:Gustav Brock
ID: 12473383
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

  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

LVL 11

Author Comment

ID: 12477889
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?
LVL 34

Assisted Solution

flavo earned 400 total points
ID: 12480748
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 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
            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
LVL 52

Accepted Solution

Gustav Brock earned 1600 total points
ID: 12480789
> 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


Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Access custom database properties are useful for storing miscellaneous bits of information in a format that persists through database closing and reopening.  This article shows how to create and use them.
Instead of error trapping or hard-coding for non-updateable fields when using QODBC, let VBA automatically disable them when forms open. This way, users can view but not change the data. Part 1 explained how to use schema tables to do this. Part 2 h…
What’s inside an Access Desktop Database. Will look at the basic interface, Navigation Pane (Database Container), Tables, Queries, Forms, Report, Macro’s, and VBA code.
In Microsoft Access, learn the trick to repeating sub-report headings at the top of each page. The problem with sub-reports and headings: Add a dummy group to the sub report using the expression =1: Set the “Repeat Section” property of the dummy…

597 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question