CString CPathUtils::GetLongPathname(const CString& path) { if (path.IsEmpty()) return path; TCHAR pathbufcanonicalized[MAX_PATH]; // MAX_PATH ok. DWORD ret = 0; CString sRet; if (!PathIsURL(path) && PathIsRelative(path)) { ret = GetFullPathName(path, 0, NULL, NULL); if (ret) { std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret + 1]); if ((ret = GetFullPathName(path, ret, pathbuf.get(), NULL)) != 0) sRet = CString(pathbuf.get(), ret); } } else if (PathCanonicalize(pathbufcanonicalized, path)) { ret = ::GetLongPathName(pathbufcanonicalized, NULL, 0); std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret + 2]); ret = ::GetLongPathName(pathbufcanonicalized, pathbuf.get(), ret + 1); sRet = CString(pathbuf.get(), ret); } else { ret = ::GetLongPathName(path, NULL, 0); std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret + 2]); ret = ::GetLongPathName(path, pathbuf.get(), ret + 1); sRet = CString(pathbuf.get(), ret); } if (ret == 0) return path; return sRet; }
//-------------------------------------- bool Platform::createPath(const char *file) { TempAlloc< TCHAR > pathbuf( dStrlen( file ) + 1 ); #ifdef UNICODE TempAlloc< WCHAR > fileBuf( pathbuf.size ); convertUTF8toUTF16( file, fileBuf, fileBuf.size ); const WCHAR* fileName = fileBuf; const WCHAR* dir; #else const char* fileName = file; const char* dir; #endif pathbuf[ 0 ] = 0; U32 pathLen = 0; while((dir = dStrchr(fileName, '/')) != NULL) { TCHAR* pathptr = pathbuf; dMemcpy( pathptr + pathLen, fileName, ( dir - fileName ) * sizeof( TCHAR ) ); pathbuf[pathLen + dir-fileName] = 0; // ignore return value because we are fine with already existing directory CreateDirectory(pathbuf, NULL); pathLen += dir - fileName; pathbuf[pathLen++] = '\\'; fileName = dir + 1; } return true; }
CString CPathUtils::GetLongPathname(const CString& path) { if (path.IsEmpty()) return path; TCHAR pathbufcanonicalized[MAX_PATH]; // MAX_PATH ok. DWORD ret = 0; CString sRet = path; if (!PathIsURL(path) && PathIsRelative(path)) { ret = GetFullPathName(path, 0, NULL, NULL); if (ret) { std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret+1]); if ((ret = GetFullPathName(path, ret, pathbuf.get(), NULL))!=0) { sRet = CString(pathbuf.get(), ret); } } } else if (PathCanonicalize(pathbufcanonicalized, path)) { ret = ::GetLongPathName(pathbufcanonicalized, NULL, 0); if (ret == 0) return path; std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret+2]); ret = ::GetLongPathName(pathbufcanonicalized, pathbuf.get(), ret+1); // GetFullPathName() sometimes returns the full path with the wrong // case. This is not a problem on Windows since its filesystem is // case-insensitive. But for SVN that's a problem if the wrong case // is inside a working copy: the svn wc database is case sensitive. // To fix the casing of the path, we use a trick: // convert the path to its short form, then back to its long form. // That will fix the wrong casing of the path. int shortret = ::GetShortPathName(pathbuf.get(), NULL, 0); if (shortret) { std::unique_ptr<TCHAR[]> shortpath(new TCHAR[shortret+2]); if (::GetShortPathName(pathbuf.get(), shortpath.get(), shortret+1)) { int ret2 = ::GetLongPathName(shortpath.get(), pathbuf.get(), ret+1); if (ret2) sRet = CString(pathbuf.get(), ret2); } } } else { ret = ::GetLongPathName(path, NULL, 0); if (ret == 0) return path; std::unique_ptr<TCHAR[]> pathbuf(new TCHAR[ret+2]); ret = ::GetLongPathName(path, pathbuf.get(), ret+1); sRet = CString(pathbuf.get(), ret); // fix the wrong casing of the path. See above for details. int shortret = ::GetShortPathName(pathbuf.get(), NULL, 0); if (shortret) { std::unique_ptr<TCHAR[]> shortpath(new TCHAR[shortret+2]); if (::GetShortPathName(pathbuf.get(), shortpath.get(), shortret+1)) { int ret2 = ::GetLongPathName(shortpath.get(), pathbuf.get(), ret+1); if (ret2) sRet = CString(pathbuf.get(), ret2); } } } if (ret == 0) return path; return sRet; }