CTGitPath CTempFiles::ConstructTempPath(const CTGitPath& path) { DWORD len = ::GetTempPath(0, nullptr); auto temppath = std::make_unique<TCHAR[]>(len + 1); auto tempF = std::make_unique<TCHAR[]>(len + 50); ::GetTempPath (len+1, temppath.get()); CTGitPath tempfile; CString possibletempfile; if (path.IsEmpty()) { ::GetTempFileName(temppath.get(), L"tsm", 0, tempF.get()); tempfile = CTGitPath (tempF.get()); } else { int i=0; do { // use the UI path, which does unescaping for urls CString filename = path.GetUIFileOrDirectoryName(); // remove illegal chars which could be present in urls filename.Remove('?'); filename.Remove('*'); filename.Remove('<'); filename.Remove('>'); filename.Remove('|'); filename.Remove('"'); // the inner loop assures that the resulting path is < MAX_PATH // if that's not possible without reducing the 'filename' to less than 5 chars, use a path // that's longer than MAX_PATH (in that case, we can't really do much to avoid longer paths) do { possibletempfile.Format(L"%s%s.tsm%3.3x.tmp%s", temppath.get(), (LPCTSTR)filename, i, (LPCTSTR)path.GetFileExtension()); tempfile.SetFromWin(possibletempfile); filename = filename.Left(filename.GetLength()-1); } while ( (filename.GetLength() > 4) && (tempfile.GetWinPathString().GetLength() >= MAX_PATH)); i++; } while (PathFileExists(tempfile.GetWinPath())); } // caller has to actually grab the file path return tempfile; }