| 41 | } |
| 42 | |
| 43 | CTGitPath CTempFiles::GetTempFilePath(bool bRemoveAtEnd, const CTGitPath& path /* = CTGitPath() */, const CGitHash& hash /* = CGitHash() */) |
| 44 | { |
| 45 | DWORD len = GetTortoiseGitTempPath(0, nullptr); |
| 46 | |
| 47 | auto temppath = std::make_unique<wchar_t[]>(len + 1); |
| 48 | auto tempF = std::make_unique<wchar_t[]>(len + 50); |
| 49 | GetTortoiseGitTempPath(len + 1, temppath.get()); |
| 50 | CTGitPath tempfile; |
| 51 | CString possibletempfile; |
| 52 | if (path.IsEmpty()) |
| 53 | { |
| 54 | ::GetTempFileName (temppath.get(), L"git", 0, tempF.get()); |
| 55 | tempfile = CTGitPath(tempF.get()); |
| 56 | } |
| 57 | else |
| 58 | { |
| 59 | int i=0; |
| 60 | do |
| 61 | { |
| 62 | // use the UI path, which does unescaping for urls |
| 63 | CString filename = path.GetBaseFilename(); |
| 64 | // remove illegal chars which could be present in urls |
| 65 | filename.Remove('?'); |
| 66 | filename.Remove('*'); |
| 67 | filename.Remove('<'); |
| 68 | filename.Remove('>'); |
| 69 | filename.Remove('|'); |
| 70 | filename.Remove('"'); |
| 71 | // the inner loop assures that the resulting path is < MAX_PATH |
| 72 | // if that's not possible without reducing the 'filename' to less than 5 chars, use a path |
| 73 | // that's longer than MAX_PATH (in that case, we can't really do much to avoid longer paths) |
| 74 | do |
| 75 | { |
| 76 | if (!hash.IsEmpty()) |
| 77 | possibletempfile.Format(L"%s%s-%s.%3.3x%s", temppath.get(), static_cast<LPCWSTR>(filename), static_cast<LPCWSTR>(hash.ToString(g_Git.GetShortHASHLength())), i, static_cast<LPCWSTR>(path.GetFileExtension())); |
| 78 | else |
| 79 | possibletempfile.Format(L"%s%s.%3.3x%s", temppath.get(), static_cast<LPCWSTR>(filename), i, static_cast<LPCWSTR>(path.GetFileExtension())); |
| 80 | tempfile.SetFromWin(possibletempfile); |
| 81 | filename.Truncate(std::max(0, filename.GetLength() - 1)); |
| 82 | } while (filename.GetLength() > 4 && tempfile.GetWinPathString().GetLength() >= MAX_PATH); |
| 83 | ++i; |
| 84 | // now create the temp file in a thread safe way, so that subsequent calls to GetTempFile() return different filenames. |
| 85 | CAutoFile hFile = CreateFile(tempfile.GetWinPath(), GENERIC_READ, FILE_SHARE_READ, nullptr, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, nullptr); |
| 86 | const auto lastErr = GetLastError(); |
| 87 | if (hFile || ((lastErr != ERROR_FILE_EXISTS) && (lastErr != ERROR_ACCESS_DENIED))) |
| 88 | break; |
| 89 | } while (true); |
| 90 | } |
| 91 | if (bRemoveAtEnd) |
| 92 | m_TempFileList.AddPath(tempfile); |
| 93 | return tempfile; |
| 94 | } |
| 95 | |
| 96 | void CTempFiles::DeleteOldTempFiles() |
| 97 | { |