I'm looking for a method to get corresponding local path for a given UNC path. Microsoft provides a small library CheckLCL for this purpose. This library is not supported on all Windows versions. Does anybody know any open source method for this?
There is also MAPI function ScLocalPathFromUNC, but am not sure if it works on all platforms.
After some googling and digging in MSDN i have the following solution:
#include <Crtdbg.h> // for debug stuff
#include "Winnetwk.h" // for WNetGetUniversalName()
#include "Lm.h" // for NetShareGetInfo()
#include "pystring.h" // from http://code.google.com/p/pystring
#pragma comment( lib, "Mpr.lib" ) // for WNetGetUniversalName()
#pragma comment( lib, "Netapi32.lib" ) // for NetShareGetInfo()
//-----------------------------------------------------------------------------
// converts x:\\folder -> \\\\server\\share\\folder
bool ConvertLocalPathToUNC(const char* szFilePath, std::string& strUNC)
{
// get size of the remote name buffer
DWORD dwBufferSize = 0;
char szBuff[2];
if (::WNetGetUniversalName(szFilePath, UNIVERSAL_NAME_INFO_LEVEL, szBuff, &dwBufferSize) == ERROR_MORE_DATA)
{
// get remote name of the share
char* buf = new char[dwBufferSize];
UNIVERSAL_NAME_INFO* puni = (UNIVERSAL_NAME_INFO*) buf;
if (::WNetGetUniversalName(szFilePath, UNIVERSAL_NAME_INFO_LEVEL, buf, &dwBufferSize) == NO_ERROR)
{
strUNC = puni->lpUniversalName;
delete [] buf;
return true;
}
delete [] buf;
}
return false;
}
//-----------------------------------------------------------------------------
// converts \\\\server\\share\\folder -> x:\\folder
bool ConvertUNCToLocalPath(const char* szUNC, std::string& strLocalPath)
{
// get share name from UNC
std::string strUNC(szUNC);
std::vector< std::string > vecTokens;
pystring::split(strUNC, vecTokens, _T("\\"));
if (vecTokens.size() < 4)
return false;
// we need wchar for NetShareGetInfo()
std::wstring strShare(vecTokens[3].length(), L' ');
std::copy(vecTokens[3].begin(), vecTokens[3].end(), strShare.begin());
PSHARE_INFO_502 BufPtr;
NET_API_STATUS res;
if ((res = NetShareGetInfo(NULL, const_cast<LPWSTR>(strShare.c_str()), 502, (LPBYTE*) &BufPtr)) == ERROR_SUCCESS)
{
// print the retrieved data.
_RPTF3(_CRT_WARN, _T("%ls\t%ls\t%u\n"), BufPtr->shi502_netname, BufPtr->shi502_path, BufPtr->shi502_current_uses);
std::wstring strPath(BufPtr->shi502_path);
strLocalPath.assign(strPath.begin(), strPath.end());
// build local path
for (size_t i = 4; i < vecTokens.size(); ++i)
{
if (!pystring::endswith(strLocalPath, _T("\\")))
strLocalPath += _T("\\");
strLocalPath += vecTokens[i];
}
// Validate the value of the shi502_security_descriptor member.
if (IsValidSecurityDescriptor(BufPtr->shi502_security_descriptor))
_RPTF0(_CRT_WARN, _T("It has a valid Security Descriptor.\n"));
else
_RPTF0(_CRT_WARN, _T("It does not have a valid Security Descriptor.\n"));
// Free the allocated memory.
NetApiBufferFree(BufPtr);
}
else
return false;
return true;
}
The System.Uri class may be some help.
http://msdn.microsoft.com/en-us/library/system.uri.aspx
It is similar to UNC and has a IsUNC()
method.