diff --git a/dll/win32/shell32/folders/CDrivesFolder.cpp b/dll/win32/shell32/folders/CDrivesFolder.cpp index e97b4346021..7baabd7c9dc 100644 --- a/dll/win32/shell32/folders/CDrivesFolder.cpp +++ b/dll/win32/shell32/folders/CDrivesFolder.cpp @@ -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; }