[SHELL32] Computer folder sorting must handle mixed drives and regitems (#8361)

CORE-20286
This commit is contained in:
Whindmar Saksit
2025-09-01 17:38:36 +02:00
committed by GitHub
parent bb57f63a26
commit 4dc61a2518
+36 -20
View File
@@ -841,6 +841,10 @@ HRESULT WINAPI CDrivesFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcRes
HRESULT WINAPI CDrivesFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
{
HRESULT hres;
UINT iColumn = LOWORD(lParam);
if (iColumn >= _countof(MyComputerSFHeader))
return E_INVALIDARG;
if (!pidl1 || !pidl2)
{
@@ -848,57 +852,69 @@ HRESULT WINAPI CDrivesFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1
return E_INVALIDARG;
}
if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
return m_regFolder->CompareIDs(lParam, pidl1, pidl2);
UINT iColumn = LOWORD(lParam);
if (!_ILIsDrive(pidl1) || !_ILIsDrive(pidl2) || iColumn >= _countof(MyComputerSFHeader))
CHAR* pszDrive1 = _ILIsDrive(pidl1) ? _ILGetDataPointer(pidl1)->u.drive.szDriveName : NULL;
if (!pszDrive1 && !IsRegItem(pidl1) && FAILED_UNEXPECTEDLY(E_INVALIDARG))
return E_INVALIDARG;
CHAR* pszDrive2 = _ILIsDrive(pidl2) ? _ILGetDataPointer(pidl2)->u.drive.szDriveName : NULL;
if (!pszDrive2 && !IsRegItem(pidl2) && FAILED_UNEXPECTEDLY(E_INVALIDARG))
return E_INVALIDARG;
CHAR* pszDrive1 = _ILGetDataPointer(pidl1)->u.drive.szDriveName;
CHAR* pszDrive2 = _ILGetDataPointer(pidl2)->u.drive.szDriveName;
int result;
switch (MyComputerSFHeader[iColumn].colnameid)
{
case IDS_SHV_COLUMN_NAME:
{
result = _stricmp(pszDrive1, pszDrive2);
if (!pszDrive1 && !pszDrive2)
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
else if (pszDrive1 && pszDrive2)
result = _stricmp(pszDrive1, pszDrive2);
else
result = (int)!pszDrive1 - (int)!pszDrive2; // Sort drives first
hres = MAKE_COMPARE_HRESULT(result);
break;
}
case IDS_SHV_COLUMN_TYPE:
{
/* We want to return immediately because SHELL32_CompareDetails also compares children. */
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
}
case IDS_SHV_COLUMN_DISK_CAPACITY:
case IDS_SHV_COLUMN_DISK_AVAILABLE:
{
if (!pszDrive1 || !pszDrive2)
{
hres = MAKE_COMPARE_HRESULT((int)!pszDrive1 - (int)!pszDrive2);
break;
}
ULARGE_INTEGER Drive1Available, Drive1Total, Drive2Available, Drive2Total;
BOOL bValid1 = FALSE, bValid2 = FALSE;
if (GetVolumeInformationA(pszDrive1, NULL, 0, NULL, NULL, NULL, NULL, 0))
GetDiskFreeSpaceExA(pszDrive1, &Drive1Available, &Drive1Total, NULL);
bValid1 = GetDiskFreeSpaceExA(pszDrive1, &Drive1Available, &Drive1Total, NULL);
else
Drive1Available.QuadPart = Drive1Total.QuadPart = 0;
if (GetVolumeInformationA(pszDrive2, NULL, 0, NULL, NULL, NULL, NULL, 0))
GetDiskFreeSpaceExA(pszDrive2, &Drive2Available, &Drive2Total, NULL);
bValid2 = GetDiskFreeSpaceExA(pszDrive2, &Drive2Available, &Drive2Total, NULL);
else
Drive2Available.QuadPart = Drive2Total.QuadPart = 0;
LARGE_INTEGER Diff;
if (lParam == 3) /* Size */
if (iColumn == IDS_SHV_COLUMN_DISK_CAPACITY) /* Size */
Diff.QuadPart = Drive1Total.QuadPart - Drive2Total.QuadPart;
else /* Size available */
Diff.QuadPart = Drive1Available.QuadPart - Drive2Available.QuadPart;
hres = MAKE_COMPARE_HRESULT(Diff.QuadPart);
if (bValid1 != bValid2)
hres = MAKE_COMPARE_HRESULT((int)!bValid1 - (int)!bValid2);
else
hres = MAKE_COMPARE_HRESULT(Diff.QuadPart);
break;
}
case IDS_SHV_COLUMN_TYPE:
case IDS_SHV_COLUMN_COMMENTS:
hres = MAKE_COMPARE_HRESULT(0);
break;
{
/* We want to return immediately because SHELL32_CompareDetails also compares children. */
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
}
DEFAULT_UNREACHABLE;
}