https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e0248f4f5198f3d8ed17956da32da09afb36003d

commit e0248f4f5198f3d8ed17956da32da09afb36003d
Author:     Egor Ananyin <[email protected]>
AuthorDate: Tue Dec 20 23:58:30 2022 +0300
Commit:     GitHub <[email protected]>
CommitDate: Tue Dec 20 23:58:30 2022 +0300

    [NTOBJSHEX] Fix sorting elements by different columns (#4947)
    
    - Add ability to sort NT objects by symlinks
    - Add ability to sort registry entries by type/value
    
    CORE-18761 CORE-18762
---
 dll/shellext/ntobjshex/ntobjfolder.cpp | 23 ++++++++++++++++++++--
 dll/shellext/ntobjshex/regfolder.cpp   | 35 +++++++++++++++++++++++++++++++---
 2 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/dll/shellext/ntobjshex/ntobjfolder.cpp 
b/dll/shellext/ntobjshex/ntobjfolder.cpp
index 020dcc35bfe..f4aef063103 100644
--- a/dll/shellext/ntobjshex/ntobjfolder.cpp
+++ b/dll/shellext/ntobjshex/ntobjfolder.cpp
@@ -463,8 +463,27 @@ HRESULT CNtObjectFolder::CompareIDs(LPARAM lParam, const 
NtPidlEntry * first, co
             return MAKE_COMPARE_HRESULT(second->objectType - 
first->objectType);
 
         case NTOBJECT_COLUMN_LINKTARGET:
-            // Can't sort by link target yet
-            return E_INVALIDARG;
+        {
+            if (first->objectType != SYMBOLICLINK_OBJECT && second->objectType 
!= SYMBOLICLINK_OBJECT)
+                return CompareName(lParam, first, second);
+
+            if (first->objectType != SYMBOLICLINK_OBJECT || second->objectType 
!= SYMBOLICLINK_OBJECT)
+                return first->objectType != SYMBOLICLINK_OBJECT ? 
S_GREATERTHAN : S_LESSTHAN;
+
+            WCHAR wbLink1[MAX_PATH] = { 0 }, wbLink2[MAX_PATH] = { 0 };
+            UNICODE_STRING firstLink, secondLink;
+            RtlInitEmptyUnicodeString(&firstLink, wbLink1, sizeof(wbLink1));
+
+            if (FAILED_UNEXPECTEDLY(GetNTObjectSymbolicLinkTarget(m_NtPath, 
first->entryName, &firstLink)))
+                return E_INVALIDARG;
+
+            RtlInitEmptyUnicodeString(&secondLink, wbLink2, sizeof(wbLink2));
+
+            if (FAILED_UNEXPECTEDLY(GetNTObjectSymbolicLinkTarget(m_NtPath, 
second->entryName, &secondLink)))
+                return E_INVALIDARG;
+
+            return MAKE_COMPARE_HRESULT(RtlCompareUnicodeString(&firstLink, 
&secondLink, TRUE));
+        }
     }
 
     DbgPrint("Unsupported sorting mode.\n");
diff --git a/dll/shellext/ntobjshex/regfolder.cpp 
b/dll/shellext/ntobjshex/regfolder.cpp
index 685a40cf866..e8369f8d24c 100644
--- a/dll/shellext/ntobjshex/regfolder.cpp
+++ b/dll/shellext/ntobjshex/regfolder.cpp
@@ -409,11 +409,40 @@ HRESULT CRegistryFolder::CompareIDs(LPARAM lParam, const 
RegPidlEntry * first, c
             return CompareName(lParam, first, second);
 
         case REGISTRY_COLUMN_TYPE:
-            return MAKE_COMPARE_HRESULT(second->contentType - 
first->contentType);
+        {
+            if (first->entryType != second->entryType)
+                return MAKE_COMPARE_HRESULT(second->entryType - 
first->entryType);
+
+            if (first->entryType == REG_ENTRY_KEY)
+            {
+                if (first->contentsLength == 0 || second->contentsLength == 0)
+                    return (first->contentsLength == 0) ? S_GREATERTHAN : 
S_LESSTHAN;
+
+                PWSTR firstKey = (PWSTR)(((PBYTE)first) + 
FIELD_OFFSET(RegPidlEntry, entryName) + first->entryNameLength + sizeof(WCHAR));
+                PWSTR secondKey = (PWSTR)(((PBYTE)second) + 
FIELD_OFFSET(RegPidlEntry, entryName) + second->entryNameLength + 
sizeof(WCHAR));
+                return MAKE_COMPARE_HRESULT(lstrcmpW(firstKey, secondKey));
+            }
+
+            return CompareName(lParam, first, second);
+        }
 
         case REGISTRY_COLUMN_VALUE:
-            // Can't sort by link target yet
-            return E_INVALIDARG;
+        {
+            PCWSTR firstContent, secondContent;
+
+            if (FAILED_UNEXPECTEDLY(FormatContentsForDisplay(first, m_hRoot, 
m_NtPath, &firstContent)))
+                return E_INVALIDARG;
+
+            if (FAILED_UNEXPECTEDLY(FormatContentsForDisplay(second, m_hRoot, 
m_NtPath, &secondContent)))
+                return E_INVALIDARG;
+
+            hr = MAKE_COMPARE_HRESULT(lstrcmpW(firstContent, secondContent));
+
+            CoTaskMemFree((LPVOID)firstContent);
+            CoTaskMemFree((LPVOID)secondContent);
+
+            return hr;
+        }
     }
 
     DbgPrint("Unsupported sorting mode.\n");

Reply via email to