Skip to content

Commit

Permalink
#146 : Do not use MAX_PATH if possible to support long path names
Browse files Browse the repository at this point in the history
  • Loading branch information
clechasseur committed Aug 28, 2021
1 parent 6f40960 commit bcc72ed
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 30 deletions.
1 change: 1 addition & 0 deletions HISTORY
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Version 20.0 (202?-??-??)
- Fixed crash when clicking in Icon column header [https://github.com/clechasseur/pathcopycopy/issues/142]
- New custom command element to display command when files and/or folders are selected [https://github.com/clechasseur/pathcopycopy/issues/125]
- Better support for high DPI monitors [https://github.com/clechasseur/pathcopycopy/issues/131]
- Better support for long path names [https://github.com/clechasseur/pathcopycopy/issues/146]


Version 19.0 (2020-08-08)
Expand Down
4 changes: 2 additions & 2 deletions PathCopyCopy/actions/src/LaunchExecutablePathAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ namespace PCC
void LaunchExecutablePathAction::Act(const std::wstring& p_Paths,
HWND const p_hWnd) const
{
auto files = p_Paths;
auto files{p_Paths};
if (m_UseFilelist) {
// Get path to temp directory
std::wstring tempDirPath(MAX_PATH + 1, L'\0');
Expand Down Expand Up @@ -96,7 +96,7 @@ namespace PCC
}

// Look for files placeholder in arguments. If it's not there, append the files.
auto arguments = m_Arguments;
auto arguments{m_Arguments};
std::wregex placeholderRegex(FILES_ARGUMENT_PLACEHOLDER,
std::regex_constants::ECMAScript | std::regex_constants::icase);
std::wsmatch match;
Expand Down
9 changes: 6 additions & 3 deletions PathCopyCopy/plugins/src/LongPathPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,12 @@ namespace PCC

std::wstring path(p_File);
if (!path.empty()) {
std::wstring longPath(MAX_PATH + 1, L'\0');
if (::GetLongPathNameW(p_File.c_str(), &*longPath.begin(), gsl::narrow<DWORD>(longPath.size())) != 0) {
path = longPath.c_str();
const auto bufferSize = ::GetLongPathNameW(p_File.c_str(), nullptr, 0);
if (bufferSize != 0) {
std::wstring longPath(bufferSize, L'\0');
if (::GetLongPathNameW(p_File.c_str(), &*longPath.begin(), gsl::narrow<DWORD>(longPath.size())) != 0) {
path = longPath.c_str();
}
}

// Append separator if needed.
Expand Down
9 changes: 6 additions & 3 deletions PathCopyCopy/plugins/src/ShortPathPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,12 @@ namespace PCC

std::wstring path(p_File);
if (!path.empty()) {
std::wstring shortPath(MAX_PATH + 1, L'\0');
if (::GetShortPathNameW(p_File.c_str(), &*shortPath.begin(), gsl::narrow<DWORD>(shortPath.size())) != 0) {
path = shortPath.c_str();
const auto bufferSize = ::GetShortPathNameW(p_File.c_str(), nullptr, 0);
if (bufferSize != 0) {
std::wstring shortPath(bufferSize, L'\0');
if (::GetShortPathNameW(p_File.c_str(), &*shortPath.begin(), gsl::narrow<DWORD>(shortPath.size())) != 0) {
path = shortPath.c_str();
}
}

// Append separator if needed.
Expand Down
9 changes: 6 additions & 3 deletions PathCopyCopy/plugins/src/ShortUNCFolderPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,12 @@ namespace PCC

// Now ask for a short version and return it.
if (!path.empty()) {
std::wstring shortPath(MAX_PATH + 1, L'\0');
if (::GetShortPathNameW(path.c_str(), &*shortPath.begin(), gsl::narrow<DWORD>(shortPath.size())) != 0) {
path = shortPath.c_str();
const auto bufferSize = ::GetShortPathNameW(path.c_str(), nullptr, 0);
if (bufferSize != 0) {
std::wstring shortPath(bufferSize, L'\0');
if (::GetShortPathNameW(path.c_str(), &*shortPath.begin(), gsl::narrow<DWORD>(shortPath.size())) != 0) {
path = shortPath.c_str();
}
}
}
return path;
Expand Down
9 changes: 6 additions & 3 deletions PathCopyCopy/plugins/src/ShortUNCPathPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,12 @@ namespace PCC

// Now ask for a short version and return it.
if (!path.empty()) {
std::wstring shortPath(MAX_PATH + 1, L'\0');
if (::GetShortPathNameW(path.c_str(), &*shortPath.begin(), gsl::narrow<DWORD>(shortPath.size())) != 0) {
path = shortPath.c_str();
const auto bufferSize = ::GetShortPathNameW(path.c_str(), nullptr, 0);
if (bufferSize != 0) {
std::wstring shortPath(bufferSize, L'\0');
if (::GetShortPathNameW(path.c_str(), &*shortPath.begin(), gsl::narrow<DWORD>(shortPath.size())) != 0) {
path = shortPath.c_str();
}
}
}
return path;
Expand Down
8 changes: 4 additions & 4 deletions PathCopyCopy/src/PathCopyCopyContextMenuExt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,10 @@ STDMETHODIMP CPathCopyCopyContextMenuExt::Initialize(
m_vFiles.reserve(fileCount);

// Get each file in turn.
std::wstring buffer(MAX_PATH + 1, L'\0');
for(UINT i = 0; i < fileCount; ++i) {
const UINT copiedCount = ::DragQueryFileW(static_cast<HDROP>(stgMedium.Get().hGlobal),
i, &*buffer.begin(), gsl::narrow<UINT>(buffer.size()));
for (UINT i = 0; i < fileCount; ++i) {
const auto bufferSize = ::DragQueryFileW(static_cast<HDROP>(stgMedium.Get().hGlobal), i, nullptr, 0);
std::wstring buffer(bufferSize + 1, L'\0');
::DragQueryFileW(static_cast<HDROP>(stgMedium.Get().hGlobal), i, &*buffer.begin(), gsl::narrow<UINT>(buffer.size()));
m_vFiles.emplace_back(buffer.c_str());
}
} else {
Expand Down
27 changes: 15 additions & 12 deletions PathCopyCopy/src/PluginUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,18 +169,21 @@ namespace PCC
flagsAndAttributes,
nullptr);
if (hFile != nullptr) {
std::wstring finalPath(MAX_PATH + 1, L'\0');
const auto finalPathRes = ::GetFinalPathNameByHandleW(hFile,
&*finalPath.begin(),
MAX_PATH,
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
if (finalPathRes != 0) {
p_rPath = finalPath.c_str();

// Fetching symlink target probably left us with a weird path, fix it
// because Explorer can't handle paths with \\?\ in them.
StringUtils::ReplaceAll(p_rPath, UNC_DRIVE_SYMLINK_PREFIX, L"");
StringUtils::ReplaceAll(p_rPath, LOCAL_DRIVE_SYMLINK_PREFIX, L"");
const auto bufferSize = ::GetFinalPathNameByHandleW(hFile, nullptr, 0, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
if (bufferSize != 0) {
std::wstring finalPath(bufferSize + 1, L'\0');
const auto finalPathRes = ::GetFinalPathNameByHandleW(hFile,
&*finalPath.begin(),
bufferSize + 1,
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
if (finalPathRes != 0) {
p_rPath = finalPath.c_str();

// Fetching symlink target probably left us with a weird path, fix it
// because Explorer can't handle paths with \\?\ in them.
StringUtils::ReplaceAll(p_rPath, UNC_DRIVE_SYMLINK_PREFIX, L"");
StringUtils::ReplaceAll(p_rPath, LOCAL_DRIVE_SYMLINK_PREFIX, L"");
}
}
}
}
Expand Down

0 comments on commit bcc72ed

Please sign in to comment.