Skip to content

Commit 4dc61a2

Browse files
authored
[SHELL32] Computer folder sorting must handle mixed drives and regitems (reactos#8361)
CORE-20286
1 parent bb57f63 commit 4dc61a2

File tree

1 file changed

+36
-20
lines changed

1 file changed

+36
-20
lines changed

dll/win32/shell32/folders/CDrivesFolder.cpp

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -841,64 +841,80 @@ HRESULT WINAPI CDrivesFolder::BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcRes
841841
HRESULT WINAPI CDrivesFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
842842
{
843843
HRESULT hres;
844+
UINT iColumn = LOWORD(lParam);
845+
846+
if (iColumn >= _countof(MyComputerSFHeader))
847+
return E_INVALIDARG;
844848

845849
if (!pidl1 || !pidl2)
846850
{
847851
ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam, pidl1, pidl2);
848852
return E_INVALIDARG;
849853
}
850854

851-
if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
852-
return m_regFolder->CompareIDs(lParam, pidl1, pidl2);
853-
854-
UINT iColumn = LOWORD(lParam);
855-
if (!_ILIsDrive(pidl1) || !_ILIsDrive(pidl2) || iColumn >= _countof(MyComputerSFHeader))
855+
CHAR* pszDrive1 = _ILIsDrive(pidl1) ? _ILGetDataPointer(pidl1)->u.drive.szDriveName : NULL;
856+
if (!pszDrive1 && !IsRegItem(pidl1) && FAILED_UNEXPECTEDLY(E_INVALIDARG))
857+
return E_INVALIDARG;
858+
CHAR* pszDrive2 = _ILIsDrive(pidl2) ? _ILGetDataPointer(pidl2)->u.drive.szDriveName : NULL;
859+
if (!pszDrive2 && !IsRegItem(pidl2) && FAILED_UNEXPECTEDLY(E_INVALIDARG))
856860
return E_INVALIDARG;
857-
858-
CHAR* pszDrive1 = _ILGetDataPointer(pidl1)->u.drive.szDriveName;
859-
CHAR* pszDrive2 = _ILGetDataPointer(pidl2)->u.drive.szDriveName;
860861

861862
int result;
862863
switch (MyComputerSFHeader[iColumn].colnameid)
863864
{
864865
case IDS_SHV_COLUMN_NAME:
865866
{
866-
result = _stricmp(pszDrive1, pszDrive2);
867+
if (!pszDrive1 && !pszDrive2)
868+
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
869+
else if (pszDrive1 && pszDrive2)
870+
result = _stricmp(pszDrive1, pszDrive2);
871+
else
872+
result = (int)!pszDrive1 - (int)!pszDrive2; // Sort drives first
867873
hres = MAKE_COMPARE_HRESULT(result);
868874
break;
869875
}
870-
case IDS_SHV_COLUMN_TYPE:
871-
{
872-
/* We want to return immediately because SHELL32_CompareDetails also compares children. */
873-
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
874-
}
876+
875877
case IDS_SHV_COLUMN_DISK_CAPACITY:
876878
case IDS_SHV_COLUMN_DISK_AVAILABLE:
877879
{
880+
if (!pszDrive1 || !pszDrive2)
881+
{
882+
hres = MAKE_COMPARE_HRESULT((int)!pszDrive1 - (int)!pszDrive2);
883+
break;
884+
}
885+
878886
ULARGE_INTEGER Drive1Available, Drive1Total, Drive2Available, Drive2Total;
887+
BOOL bValid1 = FALSE, bValid2 = FALSE;
879888

880889
if (GetVolumeInformationA(pszDrive1, NULL, 0, NULL, NULL, NULL, NULL, 0))
881-
GetDiskFreeSpaceExA(pszDrive1, &Drive1Available, &Drive1Total, NULL);
890+
bValid1 = GetDiskFreeSpaceExA(pszDrive1, &Drive1Available, &Drive1Total, NULL);
882891
else
883892
Drive1Available.QuadPart = Drive1Total.QuadPart = 0;
884893

885894
if (GetVolumeInformationA(pszDrive2, NULL, 0, NULL, NULL, NULL, NULL, 0))
886-
GetDiskFreeSpaceExA(pszDrive2, &Drive2Available, &Drive2Total, NULL);
895+
bValid2 = GetDiskFreeSpaceExA(pszDrive2, &Drive2Available, &Drive2Total, NULL);
887896
else
888897
Drive2Available.QuadPart = Drive2Total.QuadPart = 0;
889898

890899
LARGE_INTEGER Diff;
891-
if (lParam == 3) /* Size */
900+
if (iColumn == IDS_SHV_COLUMN_DISK_CAPACITY) /* Size */
892901
Diff.QuadPart = Drive1Total.QuadPart - Drive2Total.QuadPart;
893902
else /* Size available */
894903
Diff.QuadPart = Drive1Available.QuadPart - Drive2Available.QuadPart;
895904

896-
hres = MAKE_COMPARE_HRESULT(Diff.QuadPart);
905+
if (bValid1 != bValid2)
906+
hres = MAKE_COMPARE_HRESULT((int)!bValid1 - (int)!bValid2);
907+
else
908+
hres = MAKE_COMPARE_HRESULT(Diff.QuadPart);
909+
897910
break;
898911
}
912+
case IDS_SHV_COLUMN_TYPE:
899913
case IDS_SHV_COLUMN_COMMENTS:
900-
hres = MAKE_COMPARE_HRESULT(0);
901-
break;
914+
{
915+
/* We want to return immediately because SHELL32_CompareDetails also compares children. */
916+
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
917+
}
902918
DEFAULT_UNREACHABLE;
903919
}
904920

0 commit comments

Comments
 (0)