2010-02-23 89 views
1

我正在寻找一种获取给定UNC路径的相应本地路径的方法。微软为此提供了一个小型库CheckLCL。所有Windows版本都不支持此库。有人知道任何开源方法吗?如何将UNC转换为本地路径

还有MAPI功能ScLocalPathFromUNC,但我不确定它是否适用于所有平台。

+0

看起来不再支持库,因为它的安全模型是根本性的缺陷。它绕过了共享安全。在这种情况下,你根本无法获得新版本。 – MSalters 2010-02-23 10:12:50

回答

4

经过一番google搜索,并在MSDN挖我有以下解决方案:

#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; 
}