Author: gadamopoulos
Date: Fri Nov 4 23:11:29 2016
New Revision: 73128
URL:
http://svn.reactos.org/svn/reactos?rev=73128&view=rev
Log:
[SHELL32]
- Implement comparing child items in CompareIDs method of our IShellFolder immplementation
in shell32 as this is the expected behaviour according to tests and documentation.
- This was removed after each folder got its own implementation (we used a single one from
wine that did handle it).
May fix CORE-12106.
Modified:
trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp
trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp
trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp
trunk/reactos/dll/win32/shell32/shfldr.h
trunk/reactos/dll/win32/shell32/shlfolder.cpp
Modified: trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CDrivesFolder.cpp [iso-8859-1] Fri Nov 4
23:11:29 2016
@@ -358,6 +358,8 @@
HRESULT WINAPI CDrivesFolder::CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1,
PCUIDLIST_RELATIVE pidl2)
{
+ HRESULT hres;
+
if (!pidl1 || !pidl2)
{
ERR("Got null pidl pointer (%Ix %p %p)!\n", lParam, pidl1, pidl2);
@@ -365,7 +367,7 @@
}
if (_ILIsSpecialFolder(pidl1) || _ILIsSpecialFolder(pidl2))
- m_regFolder->CompareIDs(lParam, pidl1, pidl2);
+ return m_regFolder->CompareIDs(lParam, pidl1, pidl2);
if (!_ILIsDrive(pidl1) || !_ILIsDrive(pidl2) || LOWORD(lParam) >=
MYCOMPUTERSHELLVIEWCOLUMNS)
return E_INVALIDARG;
@@ -379,10 +381,12 @@
case 0: /* name */
{
result = stricmp(pszDrive1, pszDrive2);
- return MAKE_COMPARE_HRESULT(result);
+ hres = MAKE_COMPARE_HRESULT(result);
+ break;
}
case 1: /* Type */
{
+ /* We want to return immediately because SHELL32_CompareDetails also compares
children. */
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
}
case 2: /* Size */
@@ -406,10 +410,17 @@
else /* Size available */
Diff.QuadPart = Drive1Available.QuadPart - Drive2Available.QuadPart;
- return MAKE_COMPARE_HRESULT(Diff.QuadPart);
- }
- }
- return E_INVALIDARG;
+ hres = MAKE_COMPARE_HRESULT(Diff.QuadPart);
+ break;
+ }
+ default:
+ return E_INVALIDARG;
+ }
+
+ if (HRESULT_CODE(hres) == 0)
+ return SHELL32_CompareChildren(this, lParam, pidl1, pidl2);
+
+ return hres;
}
/**************************************************************************
Modified: trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CFSFolder.cpp [iso-8859-1] Fri Nov 4 23:11:29
2016
@@ -344,6 +344,10 @@
case 4: /* Attributes */
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
}
+
+ if (result == 0)
+ return SHELL32_CompareChildren(this, lParam, pidl1, pidl2);
+
return MAKE_COMPARE_HRESULT(result);
}
Modified: trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/folders/CRegFolder.cpp [iso-8859-1] Fri Nov 4
23:11:29 2016
@@ -282,21 +282,24 @@
return E_INVALIDARG;
}
- BOOL bIsGuidFolder1 = _ILIsSpecialFolder(pidl1);
- BOOL bIsGuidFolder2 = _ILIsSpecialFolder(pidl2);
-
- if (!bIsGuidFolder1 && !bIsGuidFolder2)
+ GUID const *clsid1 = _ILGetGUIDPointer (pidl1);
+ GUID const *clsid2 = _ILGetGUIDPointer (pidl2);
+
+ if (!clsid1 && !clsid2)
{
ERR("Got no guid pidl!\n");
return E_INVALIDARG;
}
- else if (bIsGuidFolder1 && bIsGuidFolder2)
- {
+ else if (clsid1 && clsid2)
+ {
+ if (memcmp(clsid1, clsid2, sizeof(GUID)) == 0)
+ return SHELL32_CompareChildren(this, lParam, pidl1, pidl2);
+
return SHELL32_CompareDetails(this, lParam, pidl1, pidl2);
}
/* Guid folders come first compared to everything else */
- return MAKE_COMPARE_HRESULT(bIsGuidFolder1 ? -1 : 1);
+ return MAKE_COMPARE_HRESULT(clsid1 ? -1 : 1);
}
HRESULT WINAPI CRegFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut)
Modified: trunk/reactos/dll/win32/shell32/shfldr.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shfldr.h…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shfldr.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/shfldr.h [iso-8859-1] Fri Nov 4 23:11:29 2016
@@ -53,6 +53,8 @@
HRESULT SHELL32_CompareDetails(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1,
LPCITEMIDLIST pidl2);
+HRESULT SHELL32_CompareChildren(IShellFolder2* psf, LPARAM lParam, LPCITEMIDLIST pidl1,
LPCITEMIDLIST pidl2);
+
HRESULT SHELL32_CoCreateInitSF (LPCITEMIDLIST pidlRoot, LPCWSTR pathRoot,
LPCITEMIDLIST pidlChild, const GUID* clsid, int csidl, REFIID riid,
LPVOID *ppvOut);
Modified: trunk/reactos/dll/win32/shell32/shlfolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shlfolde…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shlfolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/shlfolder.cpp [iso-8859-1] Fri Nov 4 23:11:29 2016
@@ -435,6 +435,29 @@
return S_OK;
}
+HRESULT SHELL32_CompareChildren(IShellFolder2* psf, LPARAM lParam, LPCITEMIDLIST pidl1,
LPCITEMIDLIST pidl2)
+{
+ PUIDLIST_RELATIVE nextpidl1 = ILGetNext (pidl1);
+ PUIDLIST_RELATIVE nextpidl2 = ILGetNext (pidl2);
+
+ bool isEmpty1 = _ILIsDesktop(nextpidl1);
+ bool isEmpty2 = _ILIsDesktop(nextpidl2);
+ if (isEmpty1 || isEmpty2)
+ return MAKE_COMPARE_HRESULT(isEmpty2 - isEmpty1);
+
+ PITEMID_CHILD firstpidl = ILCloneFirst (pidl1);
+ if (!firstpidl)
+ return E_OUTOFMEMORY;
+
+ CComPtr<IShellFolder> psf2;
+ HRESULT hr = psf->BindToObject(firstpidl, 0, IID_PPV_ARG(IShellFolder,
&psf2));
+ ILFree(firstpidl);
+ if (FAILED(hr))
+ return MAKE_COMPARE_HRESULT(0);
+
+ return psf2->CompareIDs(lParam, nextpidl1, nextpidl2);
+}
+
HRESULT SHELL32_CompareDetails(IShellFolder2* isf, LPARAM lParam, LPCITEMIDLIST pidl1,
LPCITEMIDLIST pidl2)
{
SHELLDETAILS sd;
@@ -458,6 +481,8 @@
return MAKE_COMPARE_HRESULT(1);
int ret = wcsicmp(wszItem1, wszItem2);
+ if (ret == 0)
+ return SHELL32_CompareChildren(isf, lParam, pidl1, pidl2);
return MAKE_COMPARE_HRESULT(ret);
}