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

commit 6ae11ba09d4fa8d16336a1ed40a112b3df19a474
Author:     Whindmar Saksit <whinds...@proton.me>
AuthorDate: Thu Aug 29 20:45:59 2024 +0200
Commit:     GitHub <nore...@github.com>
CommitDate: Thu Aug 29 20:45:59 2024 +0200

    [SHELL32] Don't display non-enumerable nor non-folder items in Explorer 
tree (#7189)
    
    This partially implements RegFolder required items as described by Geoff 
Chappell.
    
    CORE-19176 CORE-14061
---
 dll/win32/shell32/CDefView.cpp                     |  12 +-
 dll/win32/shell32/CEnumIDListBase.cpp              |  27 --
 dll/win32/shell32/CEnumIDListBase.h                |  16 +-
 dll/win32/shell32/folders/CControlPanelFolder.cpp  |  14 +-
 dll/win32/shell32/folders/CDesktopFolder.cpp       | 197 +++++------
 dll/win32/shell32/folders/CDesktopFolder.h         |  29 ++
 dll/win32/shell32/folders/CDrivesFolder.cpp        |  56 +++-
 dll/win32/shell32/folders/CDrivesFolder.h          |  13 +-
 dll/win32/shell32/folders/CFSFolder.cpp            |  44 ++-
 dll/win32/shell32/folders/CRegFolder.cpp           | 362 +++++++++++++--------
 dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp |   3 +-
 dll/win32/shell32/shfldr.h                         |  42 +++
 dll/win32/shell32/shlfolder.cpp                    |  28 ++
 dll/win32/shell32/wine/pidl.c                      |   2 +-
 dll/win32/shell32/wine/pidl.h                      |  14 +
 dll/win32/shell32/wine/shell32_main.h              |   2 -
 sdk/include/psdk/shobjidl.idl                      |  33 ++
 sdk/include/reactos/shellutils.h                   |  11 +
 18 files changed, 601 insertions(+), 304 deletions(-)

diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp
index 7617f85e5d7..bb3e88239c2 100644
--- a/dll/win32/shell32/CDefView.cpp
+++ b/dll/win32/shell32/CDefView.cpp
@@ -231,6 +231,7 @@ private:
     CComPtr<IShellFolderViewCB> m_pShellFolderViewCB;
     CComPtr<IShellBrowser>    m_pShellBrowser;
     CComPtr<ICommDlgBrowser>  m_pCommDlgBrowser;
+    CComPtr<IFolderFilter>    m_pFolderFilter;
     CComPtr<IShellFolderViewDual> m_pShellFolderViewDual;
     CListView                 m_ListView;
     HWND                      m_hWndParent;
@@ -636,14 +637,16 @@ HRESULT WINAPI CDefView::Initialize(IShellFolder 
*shellFolder)
 HRESULT CDefView::IncludeObject(PCUITEMID_CHILD pidl)
 {
     HRESULT ret = S_OK;
-
     if (m_pCommDlgBrowser && !(GetCommDlgViewFlags() & CDB2GVF_NOINCLUDEITEM))
     {
         TRACE("ICommDlgBrowser::IncludeObject pidl=%p\n", pidl);
         ret = m_pCommDlgBrowser->IncludeObject(this, pidl);
         TRACE("-- returns 0x%08x\n", ret);
     }
-
+    else if (m_pFolderFilter)
+    {
+        ret = m_pFolderFilter->ShouldShow(m_pSFParent, m_pidlParent, pidl);
+    }
     return ret;
 }
 
@@ -1484,7 +1487,7 @@ HRESULT CDefView::FillList(BOOL IsRefreshCommand)
     DWORD         dwFetched;
     HRESULT       hRes;
     HDPA          hdpa;
-    DWORD         dFlags = SHCONTF_NONFOLDERS | SHCONTF_FOLDERS;
+    DWORD         dFlags = SHCONTF_NONFOLDERS | ((m_FolderSettings.fFlags & 
FWF_NOSUBFOLDERS) ? 0 : SHCONTF_FOLDERS);
 
     TRACE("%p\n", this);
 
@@ -4006,6 +4009,9 @@ HRESULT STDMETHODCALLTYPE 
CDefView::SetCallback(IShellFolderViewCB  *new_cb, ISh
         *old_cb = m_pShellFolderViewCB.Detach();
 
     m_pShellFolderViewCB = new_cb;
+    m_pFolderFilter = NULL;
+    if (new_cb)
+        new_cb->QueryInterface(IID_PPV_ARG(IFolderFilter, &m_pFolderFilter));
     return S_OK;
 }
 
diff --git a/dll/win32/shell32/CEnumIDListBase.cpp 
b/dll/win32/shell32/CEnumIDListBase.cpp
index 47adf6e2ea8..d0a79b350d1 100644
--- a/dll/win32/shell32/CEnumIDListBase.cpp
+++ b/dll/win32/shell32/CEnumIDListBase.cpp
@@ -96,33 +96,6 @@ BOOL CEnumIDListBase::DeleteList()
     return TRUE;
 }
 
-/**************************************************************************
- *  HasItemWithCLSID()
- */
-BOOL CEnumIDListBase::HasItemWithCLSID(LPITEMIDLIST pidl)
-{
-    ENUMLIST *pCur;
-    IID *ptr = _ILGetGUIDPointer(pidl);
-
-    if (ptr)
-    {
-        REFIID refid = *ptr;
-        pCur = mpFirst;
-
-        while(pCur)
-        {
-            LPGUID curid = _ILGetGUIDPointer(pCur->pidl);
-            if (curid && IsEqualGUID(*curid, refid))
-            {
-                return TRUE;
-            }
-            pCur = pCur->pNext;
-        }
-    }
-
-    return FALSE;
-}
-
 HRESULT CEnumIDListBase::AppendItemsFromEnumerator(IEnumIDList* pEnum)
 {
     LPITEMIDLIST pidl;
diff --git a/dll/win32/shell32/CEnumIDListBase.h 
b/dll/win32/shell32/CEnumIDListBase.h
index 65ec9058c42..68ce0966617 100644
--- a/dll/win32/shell32/CEnumIDListBase.h
+++ b/dll/win32/shell32/CEnumIDListBase.h
@@ -27,7 +27,7 @@ class CEnumIDListBase :
        public CComObjectRootEx<CComMultiThreadModelNoCS>,
        public IEnumIDList
 {
-private:
+protected:
        ENUMLIST                                *mpFirst;
        ENUMLIST                                *mpLast;
        ENUMLIST                                *mpCurrent;
@@ -37,7 +37,19 @@ public:
        BOOL AddToEnumList(LPITEMIDLIST pidl);
        BOOL DeleteList();
        BOOL HasItemWithCLSID(LPITEMIDLIST pidl);
-    HRESULT AppendItemsFromEnumerator(IEnumIDList* pEnum);
+       HRESULT AppendItemsFromEnumerator(IEnumIDList* pEnum);
+
+       template <class T> BOOL HasItemWithCLSIDImpl(LPCITEMIDLIST pidl)
+       {
+               const CLSID * const pClsid = 
static_cast<T*>(this)->GetPidlClsid((PCUITEMID_CHILD)pidl);
+               for (ENUMLIST *pCur = mpFirst; pClsid && pCur; pCur = 
pCur->pNext)
+               {
+                       const CLSID * const pEnumClsid = 
static_cast<T*>(this)->GetPidlClsid((PCUITEMID_CHILD)pCur->pidl);
+                       if (pEnumClsid && IsEqualCLSID(*pClsid, *pEnumClsid))
+                               return TRUE;
+               }
+               return FALSE;
+       }
 
        // *** IEnumIDList methods ***
        STDMETHOD(Next)(ULONG celt, LPITEMIDLIST *rgelt, ULONG *pceltFetched) 
override;
diff --git a/dll/win32/shell32/folders/CControlPanelFolder.cpp 
b/dll/win32/shell32/folders/CControlPanelFolder.cpp
index 58d5c36353c..729112d68e8 100644
--- a/dll/win32/shell32/folders/CControlPanelFolder.cpp
+++ b/dll/win32/shell32/folders/CControlPanelFolder.cpp
@@ -23,6 +23,15 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
+static const REGFOLDERINFO g_RegFolderInfo =
+{
+    PT_CONTROLS_NEWREGITEM,
+    0, NULL,
+    CLSID_ControlPanel,
+    
L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}",
+    L"ControlPanel",
+};
+
 /***********************************************************************
 *   control panel implementation in shell namespace
 */
@@ -627,11 +636,10 @@ HRESULT WINAPI 
CControlPanelFolder::Initialize(PCIDLIST_ABSOLUTE pidl)
     pidlRoot = ILClone(pidl);
 
     /* Create the inner reg folder */
+    REGFOLDERINITDATA RegInit = { static_cast<IShellFolder*>(this), 
&g_RegFolderInfo };
     HRESULT hr;
-    hr = CRegFolder_CreateInstance(&CLSID_ControlPanel,
+    hr = CRegFolder_CreateInstance(&RegInit,
                                    pidlRoot,
-                                   
L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}",
-                                   L"ControlPanel",
                                    IID_PPV_ARG(IShellFolder2, &m_regFolder));
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
diff --git a/dll/win32/shell32/folders/CDesktopFolder.cpp 
b/dll/win32/shell32/folders/CDesktopFolder.cpp
index c95828dc6fc..ee1c10834dc 100644
--- a/dll/win32/shell32/folders/CDesktopFolder.cpp
+++ b/dll/win32/shell32/folders/CDesktopFolder.cpp
@@ -25,11 +25,35 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
+extern BOOL SHELL32_IsShellFolderNamespaceItemHidden(LPCWSTR SubKey, REFCLSID 
Clsid);
+
+static const REQUIREDREGITEM g_RequiredItems[] =
+{
+    { CLSID_MyComputer, "sysdm.cpl", 0x50 },
+    { CLSID_NetworkPlaces, "ncpa.cpl", 0x58 },
+    { CLSID_Internet, "inetcpl.cpl", 0x68 },
+};
+static const REGFOLDERINFO g_RegFolderInfo =
+{
+    PT_DESKTOP_REGITEM,
+    _countof(g_RequiredItems), g_RequiredItems,
+    CLSID_ShellDesktop,
+    L"",
+    L"Desktop",
+};
+
 static BOOL IsSelf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl)
 {
     return cidl == 0 || (cidl == 1 && apidl && _ILIsEmpty(apidl[0]));
 }
 
+static const CLSID* IsRegItem(PCUITEMID_CHILD pidl)
+{
+    if (pidl && pidl->mkid.cb == 2 + 2 + sizeof(CLSID) && pidl->mkid.abID[0] 
== PT_GUID)
+        return (const CLSID*)(&pidl->mkid.abID[2]);
+    return NULL;
+}
+
 STDMETHODIMP
 CDesktopFolder::ShellUrlParseDisplayName(
     HWND hwndOwner,
@@ -153,49 +177,13 @@ The CDesktopFolderEnum class should create two 
enumerators, one for each of the
 system folders, and enumerate the contents of each folder. Since the CRegFolder
 implementation of IShellFolder::EnumObjects enumerates the virtual items, the
 CDesktopFolderEnum is only responsible for returning the physical items.
-CDesktopFolderEnum is incorrect where it filters My Computer from the 
enumeration
-if the new start menu is used. The CDesktopViewCallback is responsible for 
filtering
-it from the view by handling the IncludeObject query to return S_FALSE. The 
enumerator
-always shows My Computer.
+CDesktopFolderViewCB is responsible for filtering hidden regitems.
+The enumerator always shows My Computer.
 */
 
 /* Undocumented functions from shdocvw */
 extern "C" HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR 
lpszDisplayName, LPBC pbc, LPITEMIDLIST *ppidl);
 
-static const WCHAR ClassicStartMenuW[] = L"SOFTWARE\\Microsoft\\Windows\\"
-    L"CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu";
-
-static INT
-IsNamespaceExtensionHidden(const WCHAR *iid)
-{
-    DWORD Result, dwResult;
-    dwResult = sizeof(DWORD);
-
-    if (RegGetValueW(HKEY_CURRENT_USER, /* FIXME use NewStartPanel when 
activated */
-                     ClassicStartMenuW,
-                     iid,
-                     RRF_RT_DWORD,
-                     NULL,
-                     &Result,
-                     &dwResult) != ERROR_SUCCESS)
-    {
-        return -1;
-    }
-
-    return Result;
-}
-
-static INT IsNamespaceExtensionHidden(LPCITEMIDLIST pidl)
-{
-    GUID const *clsid = _ILGetGUIDPointer (pidl);
-    if (!clsid)
-        return -1;
-
-    WCHAR pwszGuid[CHARS_IN_GUID];
-    SHELL32_GUIDToStringW(*clsid, pwszGuid);
-    return IsNamespaceExtensionHidden(pwszGuid);
-}
-
 class CDesktopFolderEnum :
     public CEnumIDListBase
 {
@@ -204,85 +192,20 @@ class CDesktopFolderEnum :
 //    CComPtr                                fCommonDesktopEnumerator;
     public:
 
-        void AddItemsFromClassicStartMenuKey(HKEY hKeyRoot)
+        HRESULT WINAPI Initialize(IShellFolder *pRegFolder, SHCONTF dwFlags, 
IEnumIDList *pRegEnumerator,
+                                  IEnumIDList *pDesktopEnumerator, IEnumIDList 
*pCommonDesktopEnumerator)
         {
-            DWORD dwResult;
-            HKEY hkey;
-            DWORD j = 0, dwVal, Val, dwType, dwIID;
-            LONG r;
-            WCHAR iid[50];
-            LPITEMIDLIST pidl;
-
-            dwResult = RegOpenKeyExW(hKeyRoot, ClassicStartMenuW, 0, KEY_READ, 
&hkey);
-            if (dwResult != ERROR_SUCCESS)
-                return;
-
-            while(1)
-            {
-                dwVal = sizeof(Val);
-                dwIID = sizeof(iid) / sizeof(WCHAR);
-
-                r = RegEnumValueW(hkey, j++, iid, &dwIID, NULL, &dwType, 
(LPBYTE)&Val, &dwVal);
-                if (r != ERROR_SUCCESS)
-                    break;
-
-                if (Val == 0 && dwType == REG_DWORD)
-                {
-                    pidl = _ILCreateGuidFromStrW(iid);
-                    if (pidl != NULL)
-                    {
-                        if (!HasItemWithCLSID(pidl))
-                            AddToEnumList(pidl);
-                        else
-                            SHFree(pidl);
-                    }
-                }
-            }
-            RegCloseKey(hkey);
-        }
-
-        HRESULT WINAPI Initialize(DWORD dwFlags,IEnumIDList * pRegEnumerator, 
IEnumIDList *pDesktopEnumerator, IEnumIDList *pCommonDesktopEnumerator)
-        {
-            BOOL ret = TRUE;
-            LPITEMIDLIST pidl;
-
-            static const WCHAR MyDocumentsClassString[] = 
L"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
-            static const WCHAR InternetClassString[] = 
L"{871C5380-42A0-1069-A2EA-08002B30309D}";
-
             TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
 
-            /* enumerate the root folders */
-            if (dwFlags & SHCONTF_FOLDERS)
-            {
-                AddToEnumList(_ILCreateMyComputer());
-                if (IsNamespaceExtensionHidden(MyDocumentsClassString) < 1)
-                    AddToEnumList(_ILCreateMyDocuments());
-                if (IsNamespaceExtensionHidden(InternetClassString) < 1)
-                    AddToEnumList(_ILCreateIExplore());
-
-                DWORD dwFetched;
-                while((S_OK == pRegEnumerator->Next(1, &pidl, &dwFetched)) && 
dwFetched)
-                {
-                    if (IsNamespaceExtensionHidden(pidl) < 1)
-                    {
-                        if (!HasItemWithCLSID(pidl))
-                            AddToEnumList(pidl);
-                        else
-                            SHFree(pidl);
-                    }
-                }
-                AddItemsFromClassicStartMenuKey(HKEY_LOCAL_MACHINE);
-                AddItemsFromClassicStartMenuKey(HKEY_CURRENT_USER);
-            }
+            AppendItemsFromEnumerator(pRegEnumerator);
 
             /* Enumerate the items in the two fs folders */
             AppendItemsFromEnumerator(pDesktopEnumerator);
             AppendItemsFromEnumerator(pCommonDesktopEnumerator);
 
-            return ret ? S_OK : E_FAIL;
+            return S_OK;
         }
 
-
         BEGIN_COM_MAP(CDesktopFolderEnum)
         COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
         END_COM_MAP()
@@ -337,10 +260,9 @@ HRESULT WINAPI CDesktopFolder::FinalConstruct()
         return hr;
 
     /* Create the inner reg folder */
-    hr = CRegFolder_CreateInstance(&CLSID_ShellDesktop,
+    REGFOLDERINITDATA RegInit = { static_cast<IShellFolder*>(this), 
&g_RegFolderInfo };
+    hr = CRegFolder_CreateInstance(&RegInit,
                                    pidlRoot,
-                                   L"",
-                                   L"Desktop",
                                    IID_PPV_ARG(IShellFolder2, &m_regFolder));
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
@@ -621,7 +543,8 @@ HRESULT WINAPI CDesktopFolder::EnumObjects(HWND hwndOwner, 
DWORD dwFlags, LPENUM
     if (FAILED(hr))
         ERR("EnumObjects for shared desktop fs folder failed\n");
 
-    return ShellObjectCreatorInit<CDesktopFolderEnum>(dwFlags,pRegEnumerator, 
pDesktopEnumerator, pCommonDesktopEnumerator, IID_PPV_ARG(IEnumIDList, 
ppEnumIDList));
+    return ShellObjectCreatorInit<CDesktopFolderEnum>(m_regFolder, dwFlags, 
pRegEnumerator, pDesktopEnumerator,
+                                                      
pCommonDesktopEnumerator, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
 }
 
 /**************************************************************************
@@ -726,8 +649,14 @@ HRESULT WINAPI CDesktopFolder::CreateViewObject(
     }
     else if (IsEqualIID (riid, IID_IShellView))
     {
-        SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this};
-        hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut);
+        CComPtr<CDesktopFolderViewCB> sfviewcb;
+        if (SUCCEEDED(hr = ShellObjectCreator(sfviewcb)))
+        {
+            SFV_CREATE create = { sizeof(create), this, NULL, sfviewcb };
+            hr = SHCreateShellFolderView(&create, (IShellView**)ppvOut);
+            if (SUCCEEDED(hr))
+                sfviewcb->Initialize((IShellView*)*ppvOut);
+        }
     }
     TRACE ("-- (%p)->(interface=%p)\n", this, ppvOut);
     return hr;
@@ -1102,6 +1031,48 @@ HRESULT WINAPI CDesktopFolder::CallBack(IShellFolder 
*psf, HWND hwndOwner, IData
     return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
 }
 
+/*************************************************************************
+ * CDesktopFolderViewCB
+ */
+
+bool CDesktopFolderViewCB::IsProgmanHostedBrowser(IShellView *psv)
+{
+    FOLDERSETTINGS settings;
+    return SUCCEEDED(psv->GetCurrentInfo(&settings)) && (settings.fFlags & 
FWF_DESKTOP);
+}
+
+bool CDesktopFolderViewCB::IsProgmanHostedBrowser()
+{
+    enum { Uninitialized = 0, NotHosted, IsHosted };
+    C_ASSERT(Uninitialized == 0);
+    if (m_IsProgmanHosted == Uninitialized)
+        m_IsProgmanHosted = m_pShellView && 
IsProgmanHostedBrowser(m_pShellView) ? IsHosted : NotHosted;
+    return m_IsProgmanHosted == IsHosted;
+}
+
+HRESULT WINAPI CDesktopFolderViewCB::ShouldShow(IShellFolder *psf, 
PCIDLIST_ABSOLUTE pidlFolder, PCUITEMID_CHILD pidlItem)
+{
+    const CLSID* pClsid;
+    if (IsProgmanHostedBrowser() && (pClsid = IsRegItem(pidlItem)) != NULL)
+    {
+        const BOOL NewStart = SHELL_GetSetting(SSF_STARTPANELON, 
fStartPanelOn);
+        LPCWSTR SubKey = NewStart ? L"HideDesktopIcons\\NewStartPanel" : 
L"HideDesktopIcons\\ClassicStartMenu";
+        return SHELL32_IsShellFolderNamespaceItemHidden(SubKey, *pClsid) ? 
S_FALSE : S_OK;
+    }
+    return S_OK;
+}
+
+HRESULT WINAPI CDesktopFolderViewCB::MessageSFVCB(UINT uMsg, WPARAM wParam, 
LPARAM lParam)
+{
+    switch (uMsg)
+    {
+        case SFVM_VIEWRELEASE:
+            m_pShellView = NULL;
+            return S_OK;
+    }
+    return E_NOTIMPL;
+}
+
 /*************************************************************************
  * SHGetDesktopFolder            [SHELL32.@]
  */
diff --git a/dll/win32/shell32/folders/CDesktopFolder.h 
b/dll/win32/shell32/folders/CDesktopFolder.h
index 66eda8df0ee..0f8ea5a35a2 100644
--- a/dll/win32/shell32/folders/CDesktopFolder.h
+++ b/dll/win32/shell32/folders/CDesktopFolder.h
@@ -145,4 +145,33 @@ class CDesktopFolder :
         END_COM_MAP()
 };
 
+class CDesktopFolderViewCB :
+    public CComObjectRootEx<CComMultiThreadModelNoCS>,
+    public IShellFolderViewCB,
+    public IFolderFilter
+{
+        IShellView *m_pShellView; // Not ref-counted!
+        UINT8 m_IsProgmanHosted;
+
+    public:
+        CDesktopFolderViewCB() : m_IsProgmanHosted(0) {}
+        void Initialize(IShellView *psv) { m_pShellView = psv; }
+        static bool IsProgmanHostedBrowser(IShellView *psv);
+        bool IsProgmanHostedBrowser();
+
+        // IShellFolderViewCB
+        STDMETHOD(MessageSFVCB)(UINT uMsg, WPARAM wParam, LPARAM lParam) 
override;
+
+        // IFolderFilter
+        STDMETHOD(ShouldShow)(IShellFolder *psf, PCIDLIST_ABSOLUTE pidlFolder, 
PCUITEMID_CHILD pidlItem) override;
+        STDMETHODIMP GetEnumFlags(IShellFolder*, PCIDLIST_ABSOLUTE, HWND*, 
DWORD*) override { return E_NOTIMPL; }
+
+        DECLARE_NO_REGISTRY()
+        DECLARE_NOT_AGGREGATABLE(CDesktopFolderViewCB)
+        BEGIN_COM_MAP(CDesktopFolderViewCB)
+        COM_INTERFACE_ENTRY_IID(IID_IShellFolderViewCB, IShellFolderViewCB)
+        COM_INTERFACE_ENTRY_IID(IID_IFolderFilter, IFolderFilter)
+        END_COM_MAP()
+};
+
 #endif /* _CDESKTOPFOLDER_H_ */
diff --git a/dll/win32/shell32/folders/CDrivesFolder.cpp 
b/dll/win32/shell32/folders/CDrivesFolder.cpp
index 9cc549a842a..56422f83946 100644
--- a/dll/win32/shell32/folders/CDrivesFolder.cpp
+++ b/dll/win32/shell32/folders/CDrivesFolder.cpp
@@ -55,6 +55,29 @@ static int iDriveTypeIds[7] = { IDS_DRIVE_FIXED,       /* 
DRIVE_UNKNOWN */
                                 IDS_DRIVE_FIXED        /* DRIVE_RAMDISK*/
                                 };
 
+static const REQUIREDREGITEM g_RequiredItems[] =
+{
+    { CLSID_ControlPanel, 0, 0x50 },
+};
+static const REGFOLDERINFO g_RegFolderInfo =
+{
+    PT_COMPUTER_REGITEM,
+    _countof(g_RequiredItems), g_RequiredItems,
+    CLSID_MyComputer,
+    L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
+    L"MyComputer",
+};
+
+static const CLSID* IsRegItem(PCUITEMID_CHILD pidl)
+{
+    if (pidl && pidl->mkid.cb == 2 + 2 + sizeof(CLSID))
+    {
+        if (pidl->mkid.abID[0] == PT_SHELLEXT || pidl->mkid.abID[0] == 
PT_GUID) // FIXME: Remove PT_GUID when CRegFolder is fixed
+            return (const CLSID*)(&pidl->mkid.abID[2]);
+    }
+    return NULL;
+}
+
 BOOL _ILGetDriveType(LPCITEMIDLIST pidl)
 {
     WCHAR szDrive[8];
@@ -66,6 +89,16 @@ BOOL _ILGetDriveType(LPCITEMIDLIST pidl)
     return ::GetDriveTypeW(szDrive);
 }
 
+BOOL SHELL32_IsShellFolderNamespaceItemHidden(LPCWSTR SubKey, REFCLSID Clsid)
+{
+    // If this function returns true, the item should be hidden in DefView but 
not in the Explorer folder tree.
+    WCHAR path[MAX_PATH], name[CHARS_IN_GUID];
+    wsprintfW(path, L"%s\\%s", REGSTR_PATH_EXPLORER, SubKey);
+    SHELL32_GUIDToStringW(Clsid, name);
+    DWORD data = 0, size = sizeof(data);
+    return !RegGetValueW(HKEY_CURRENT_USER, path, name, RRF_RT_DWORD, NULL, 
&data, &size) && data;
+}
+
 /***********************************************************************
 *   IShellFolder implementation
 */
@@ -643,10 +676,9 @@ HRESULT WINAPI CDrivesFolder::FinalConstruct()
     if (pidlRoot == NULL)
         return E_OUTOFMEMORY;
 
-    HRESULT hr = CRegFolder_CreateInstance(&CLSID_MyComputer,
+    REGFOLDERINITDATA RegInit = { static_cast<IShellFolder*>(this), 
&g_RegFolderInfo };
+    HRESULT hr = CRegFolder_CreateInstance(&RegInit,
                                            pidlRoot,
-                                           
L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
-                                           L"MyComputer",
                                            IID_PPV_ARG(IShellFolder2, 
&m_regFolder));
 
     return hr;
@@ -901,7 +933,7 @@ HRESULT WINAPI CDrivesFolder::CreateViewObject(HWND 
hwndOwner, REFIID riid, LPVO
     }
     else if (IsEqualIID(riid, IID_IShellView))
     {
-            SFV_CREATE sfvparams = {sizeof(SFV_CREATE), this};
+            SFV_CREATE sfvparams = { sizeof(SFV_CREATE), this, NULL, 
static_cast<IShellFolderViewCB*>(this) };
             hr = SHCreateShellFolderView(&sfvparams, (IShellView**)ppvOut);
     }
     TRACE("-- (%p)->(interface=%p)\n", this, ppvOut);
@@ -937,11 +969,17 @@ HRESULT WINAPI CDrivesFolder::GetAttributesOf(UINT cidl, 
PCUITEMID_CHILD_ARRAY a
                     *rgfInOut &= ~SFGAO_CANRENAME; // CD-ROM drive cannot 
rename
             }
             else if (_ILIsControlPanel(apidl[i]))
+            {
                 *rgfInOut &= dwControlPanelAttributes;
+            }
             else if (_ILIsSpecialFolder(*apidl))
+            {
                 m_regFolder->GetAttributesOf(1, &apidl[i], rgfInOut);
+            }
             else
+            {
                 ERR("Got unknown pidl type!\n");
+            }
         }
     }
 
@@ -1302,6 +1340,16 @@ HRESULT WINAPI 
CDrivesFolder::GetCurFolder(PIDLIST_ABSOLUTE *pidl)
     return S_OK;
 }
 
+/**************************************************************************
+ *    CDrivesFolder::ShouldShow
+ */
+HRESULT WINAPI CDrivesFolder::ShouldShow(IShellFolder *psf, PCIDLIST_ABSOLUTE 
pidlFolder, PCUITEMID_CHILD pidlItem)
+{
+    if (const CLSID* pClsid = IsRegItem(pidlItem))
+        return 
SHELL32_IsShellFolderNamespaceItemHidden(L"HideMyComputerIcons", *pClsid) ? 
S_FALSE : S_OK;
+    return S_OK;
+}
+
 /************************************************************************/
 /* IContextMenuCB interface */
 
diff --git a/dll/win32/shell32/folders/CDrivesFolder.h 
b/dll/win32/shell32/folders/CDrivesFolder.h
index 7958027b545..a4222b88362 100644
--- a/dll/win32/shell32/folders/CDrivesFolder.h
+++ b/dll/win32/shell32/folders/CDrivesFolder.h
@@ -28,7 +28,9 @@ class CDrivesFolder :
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IShellFolder2,
     public IPersistFolder2,
-    public IContextMenuCB
+    public IContextMenuCB,
+    public IShellFolderViewCB, // Only exists so DefView can get IFolderFilter
+    public IFolderFilter
 {
     private:
         /* both paths are parsible from the desktop */
@@ -73,6 +75,13 @@ class CDrivesFolder :
         // IContextMenuCB
         STDMETHOD(CallBack)(IShellFolder *psf, HWND hwndOwner, IDataObject 
*pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam) override;
 
+        // IShellFolderViewCB
+        STDMETHODIMP MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) 
override { return E_NOTIMPL; }
+
+        // IFolderFilter
+        STDMETHOD(ShouldShow)(IShellFolder *psf, PCIDLIST_ABSOLUTE pidlFolder, 
PCUITEMID_CHILD pidlItem) override;
+        STDMETHODIMP GetEnumFlags(IShellFolder*, PCIDLIST_ABSOLUTE, HWND*, 
DWORD*) override { return E_NOTIMPL; }
+
         DECLARE_REGISTRY_RESOURCEID(IDR_MYCOMPUTER)
         DECLARE_CENTRAL_INSTANCE_NOT_AGGREGATABLE(CDrivesFolder)
 
@@ -85,6 +94,8 @@ class CDrivesFolder :
         COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
         COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
         COM_INTERFACE_ENTRY_IID(IID_IContextMenuCB, IContextMenuCB)
+        COM_INTERFACE_ENTRY_IID(IID_IShellFolderViewCB, IShellFolderViewCB)
+        COM_INTERFACE_ENTRY_IID(IID_IFolderFilter, IFolderFilter)
         END_COM_MAP()
 };
 
diff --git a/dll/win32/shell32/folders/CFSFolder.cpp 
b/dll/win32/shell32/folders/CFSFolder.cpp
index 8b444f05635..bde0d6dbb42 100644
--- a/dll/win32/shell32/folders/CFSFolder.cpp
+++ b/dll/win32/shell32/folders/CFSFolder.cpp
@@ -596,13 +596,33 @@ HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, 
LPCITEMIDLIST pidl, LPDW
 
     BOOL bDirectory = (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
 
+    if (SFGAO_VALIDATE & *pdwAttributes)
+    {
+        STRRET strret;
+        LPWSTR path;
+        if (SUCCEEDED(psf->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret)) 
&&
+            SUCCEEDED(StrRetToStrW(&strret, pidl, &path)))
+        {
+            BOOL exists = PathFileExistsW(path);
+            SHFree(path);
+            if (!exists)
+                return E_FAIL;
+        }
+    }
+
     if (!bDirectory)
     {
         // 
https://git.reactos.org/?p=reactos.git;a=blob;f=dll/shellext/zipfldr/res/zipfldr.rgs;hb=032b5aacd233cd7b83ab6282aad638c161fdc400#l9
         WCHAR szFileName[MAX_PATH];
         LPWSTR pExtension;
+        BOOL hasName = _ILSimpleGetTextW(pidl, szFileName, 
_countof(szFileName));
+
+        // Vista+ feature: Hidden files with a leading tilde treated as 
super-hidden
+        // See https://devblogs.microsoft.com/oldnewthing/20170526-00/?p=96235
+        if (hasName && szFileName[0] == '~' && (dwFileAttributes & 
FILE_ATTRIBUTE_HIDDEN))
+            dwShellAttributes |= SFGAO_HIDDEN | SFGAO_SYSTEM;
 
-        if (_ILSimpleGetTextW(pidl, szFileName, _countof(szFileName)) && 
(pExtension = PathFindExtensionW(szFileName)))
+        if (hasName && (pExtension = PathFindExtensionW(szFileName)))
         {
             CLSID clsidFile;
             // FIXME: Cache this?
@@ -626,7 +646,7 @@ HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, 
LPCITEMIDLIST pidl, LPDW
                     ::RegCloseKey(hkey);
 
                     // This should be presented as directory!
-                    bDirectory = TRUE;
+                    bDirectory = (dwAttributes & SFGAO_FOLDER) != 0 || 
dwAttributes == 0;
                     TRACE("Treating '%S' as directory!\n", szFileName);
                 }
             }
@@ -650,10 +670,26 @@ HRESULT SHELL32_GetFSItemAttributes(IShellFolder * psf, 
LPCITEMIDLIST pidl, LPDW
     }
 
     if (dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
-        dwShellAttributes |=  SFGAO_HIDDEN;
+        dwShellAttributes |= SFGAO_HIDDEN | SFGAO_GHOSTED;
 
     if (dwFileAttributes & FILE_ATTRIBUTE_READONLY)
-        dwShellAttributes |=  SFGAO_READONLY;
+        dwShellAttributes |= SFGAO_READONLY;
+
+    if (dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
+        dwShellAttributes |= SFGAO_SYSTEM;
+
+    if (dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)
+        dwShellAttributes |= SFGAO_COMPRESSED;
+
+    if (dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED)
+        dwShellAttributes |= SFGAO_ENCRYPTED;
+
+    if ((SFGAO_NONENUMERATED & *pdwAttributes) && (dwFileAttributes & 
FILE_ATTRIBUTE_HIDDEN))
+    {
+        SHCONTF shcf = SHELL_GetDefaultFolderEnumSHCONTF();
+        if ((!(shcf & SHCONTF_INCLUDEHIDDEN)) || ((dwFileAttributes & 
FILE_ATTRIBUTE_SYSTEM) && !(shcf & SHCONTF_INCLUDESUPERHIDDEN)))
+            dwShellAttributes |= SFGAO_NONENUMERATED;
+    }
 
     if (SFGAO_LINK & *pdwAttributes)
     {
diff --git a/dll/win32/shell32/folders/CRegFolder.cpp 
b/dll/win32/shell32/folders/CRegFolder.cpp
index 8d8223c3924..510727a6b67 100644
--- a/dll/win32/shell32/folders/CRegFolder.cpp
+++ b/dll/win32/shell32/folders/CRegFolder.cpp
@@ -16,116 +16,114 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  
USA
+ *
+ * The required-regitem design is based on the research by Geoff Chappell
+ * 
https://www.geoffchappell.com/studies/windows/shell/shell32/classes/regfolder.htm
  */
 
 #include <precomp.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL (shell);
 
-HRESULT CALLBACK RegFolderContextMenuCallback(IShellFolder *psf,
-                                              HWND         hwnd,
-                                              IDataObject  *pdtobj,
-                                              UINT         uMsg,
-                                              WPARAM       wParam,
-                                              LPARAM       lParam)
-{
-    if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
-        return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
+#define DEFAULTSORTORDERINDEX 0x80 // The default for registry items according 
to Geoff Chappell
 
-    PIDLIST_ABSOLUTE pidlFolder;
-    PUITEMID_CHILD *apidl;
-    UINT cidl;
-    HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
-    if (FAILED_UNEXPECTEDLY(hr))
-        return hr;
+static HRESULT CRegItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE 
pidlFolder, HWND hwnd, UINT cidl,
+                                                  PCUITEMID_CHILD_ARRAY apidl, 
IShellFolder *psf, IContextMenu **ppcm);
 
-    if (_ILIsMyComputer(apidl[0]))
-    {
-        if (!SHELL_ExecuteControlPanelCPL(hwnd, L"sysdm.cpl"))
-        {
-            hr = E_FAIL;
-        }
-    }
-    else if (_ILIsDesktop(apidl[0]))
-    {
-        if (!SHELL_ExecuteControlPanelCPL(hwnd, L"desk.cpl"))
-        {
-            hr = E_FAIL;
-        }
-    }
-    else if (_ILIsNetHood(apidl[0]))
-    {
-        // FIXME path!
-        if (32 >= (UINT_PTR)ShellExecuteW(NULL,
-                                          L"open",
-                                          L"explorer.exe",
-                                          
L"::{7007ACC7-3202-11D1-AAD2-00805FC1270E}",
-                                          NULL,
-                                          SW_SHOWDEFAULT))
-        {
-            hr = E_FAIL;
-        }
-    }
-    else if (_ILIsBitBucket(apidl[0]))
-    {
-        /* FIXME: detect the drive path of bitbucket if appropiate */
-        if (!SH_ShowRecycleBinProperties(L'C'))
-            hr = E_FAIL;
-    }
-    else
+static inline UINT GetRegItemCLSIDOffset(PIDLTYPE type)
+{
+    return type == PT_CONTROLS_NEWREGITEM ? 14 : 4;
+}
+
+static LPITEMIDLIST CreateRegItem(PIDLTYPE type, REFCLSID clsid, BYTE order = 
0)
+{
+#if 1 // FIXME: CControlPanelFolder is not ready for this yet
+    if (type == PT_CONTROLS_NEWREGITEM)
+        type = PT_CONTROLS_OLDREGITEM;
+#endif
+    const UINT offset = GetRegItemCLSIDOffset(type);
+    const UINT cb = offset + sizeof(CLSID), cbTotal = cb + sizeof(WORD);
+    LPITEMIDLIST pidl = (LPITEMIDLIST)SHAlloc(cbTotal);
+    if (pidl)
     {
-        /* Tell the caller to run the default action */
-        hr = S_FALSE;
+        ZeroMemory(pidl, cbTotal); // Note: This also initializes the 
terminator WORD
+        pidl->mkid.cb = cb;
+        pidl->mkid.abID[0] = type;
+        pidl->mkid.abID[1] = order;
+        *(CLSID*)(SIZE_T(pidl) + offset) = clsid;
     }
+    return pidl;
+}
 
-    SHFree(pidlFolder);
-    _ILFreeaPidl(apidl, cidl);
-
-    return hr;
+static LPITEMIDLIST CreateRegItem(PIDLTYPE type, LPCWSTR clsidstr)
+{
+    CLSID clsid;
+    return SUCCEEDED(CLSIDFromString(clsidstr, &clsid)) ? CreateRegItem(type, 
clsid) : NULL;
 }
 
-HRESULT CGuidItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder,
-                                            HWND hwnd,
-                                            UINT cidl,
-                                            PCUITEMID_CHILD_ARRAY apidl,
-                                            IShellFolder *psf,
-                                            IContextMenu **ppcm)
+HRESULT FormatGUIDKey(LPWSTR KeyName, SIZE_T KeySize, LPCWSTR RegPath, const 
GUID* riid)
 {
-    HKEY hKeys[10];
-    UINT cKeys = 0;
+    WCHAR xriid[CHARS_IN_GUID];
+    StringFromGUID2(*riid, xriid, _countof(xriid));
+    return StringCchPrintfW(KeyName, KeySize, RegPath, xriid);
+}
 
-    GUID *pGuid = _ILGetGUIDPointer(apidl[0]);
-    if (pGuid)
+static DWORD SHELL_QueryCLSIDValue(_In_ REFCLSID clsid, _In_opt_ LPCWSTR 
SubKey, _In_opt_ LPCWSTR Value, _In_opt_ PVOID pData, _In_opt_ PDWORD pSize)
+{
+    WCHAR Path[MAX_PATH];
+    wcscpy(Path, L"CLSID\\");
+    StringFromGUID2(clsid, Path + 6, 39);
+    if (SubKey)
     {
-        WCHAR key[60];
-        wcscpy(key, L"CLSID\\");
-        StringFromGUID2(*pGuid, &key[6], 39);
-        AddClassKeyToArray(key, hKeys, &cKeys);
+        wcscpy(Path + 6 + 38, L"\\");
+        wcscpy(Path + 6 + 39, SubKey);
     }
+    return RegGetValueW(HKEY_CLASSES_ROOT, Path, Value, RRF_RT_ANY, NULL, 
pData, pSize);
+}
 
-    // FIXME: CRegFolder should be aggregated by its outer folder and should
-    // provide the attributes for all required non-registry folders.
-    // It currently does not so we have to ask the outer folder ourself so
-    // that we get the correct attributes for My Computer etc.
-    CComPtr<IShellFolder> pOuterSF;
-    SHBindToObject(NULL, pidlFolder, IID_PPV_ARG(IShellFolder, &pOuterSF));
-
-    SFGAOF att = (psf && cidl) ? SHGetAttributes(pOuterSF ? pOuterSF.p : psf, 
apidl[0], SFGAO_FOLDER) : 0;
-    if (att & SFGAO_FOLDER)
-        AddClassKeyToArray(L"Folder", hKeys, &cKeys);
-
-    return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, 
RegFolderContextMenuCallback, cKeys, hKeys, ppcm);
+static bool HasCLSIDShellFolderValue(REFCLSID clsid, LPCWSTR Value)
+{
+    return SHELL_QueryCLSIDValue(clsid, L"ShellFolder", Value, NULL, NULL) == 
ERROR_SUCCESS;
 }
 
-HRESULT FormatGUIDKey(LPWSTR KeyName, SIZE_T KeySize, LPCWSTR RegPath, const 
GUID* riid)
+struct CRegFolderInfo
 {
-    WCHAR xriid[40];
+    const REGFOLDERINFO *m_pInfo;
 
-    if (!StringFromGUID2(*riid, xriid, _countof(xriid) - 1))
-        return E_FAIL;
+    void InitializeFolderInfo(const REGFOLDERINFO *pInfo)
+    {
+        m_pInfo = pInfo;
+    }
 
-    return StringCchPrintfW(KeyName, KeySize, RegPath, xriid);
-}
+    const CLSID* IsRegItem(LPCITEMIDLIST pidl) const
+    {
+        if (pidl && pidl->mkid.cb >= sizeof(WORD) + 1 + 1 + sizeof(GUID))
+        {
+            if (pidl->mkid.abID[0] == m_pInfo->PidlType)
+                return (CLSID*)(SIZE_T(pidl) + GetCLSIDOffset());
+            if (pidl->mkid.abID[0] == PT_CONTROLS_OLDREGITEM)
+                return (CLSID*)(SIZE_T(pidl) + 
GetRegItemCLSIDOffset(PT_CONTROLS_OLDREGITEM));
+        }
+        if (const IID* pIID = _ILGetGUIDPointer(pidl))
+        {
+            FIXME("Unexpected GUID PIDL type %#x\n", pidl->mkid.abID[0]);
+            return pIID; // FIXME: Remove this when all folders have been fixed
+        }
+        return NULL;
+    }
+
+    LPITEMIDLIST CreateItem(size_t i) const
+    {
+        const REQUIREDREGITEM &item = GetAt(i);
+        return CreateRegItem(GetPidlType(), item.clsid, item.Order);
+    }
+
+    LPCWSTR GetParsingPath() const { return m_pInfo->pszParsingPath; }
+    UINT GetCLSIDOffset() const { return 
GetRegItemCLSIDOffset(m_pInfo->PidlType); }
+    PIDLTYPE GetPidlType() const { return m_pInfo->PidlType; }
+    UINT GetRequiredItemsCount() const { return m_pInfo->Count; }
+    const REQUIREDREGITEM& GetAt(size_t i) const { return m_pInfo->Items[i]; }
+};
 
 HRESULT CGuidItemExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID iid, 
LPVOID * ppvOut)
 {
@@ -213,47 +211,52 @@ HRESULT CGuidItemExtractIcon_CreateInstance(LPCITEMIDLIST 
pidl, REFIID iid, LPVO
 }
 
 class CRegFolderEnum :
-    public CEnumIDListBase
+    public CEnumIDListBase,
+    public CRegFolderInfo
 {
+    SHCONTF m_SHCTF;
     public:
-        CRegFolderEnum();
-        ~CRegFolderEnum();
-        HRESULT Initialize(LPCWSTR lpszEnumKeyName, DWORD dwFlags);
-        HRESULT AddItemsFromKey(HKEY hkey_root, LPCWSTR szRepPath);
+        HRESULT Initialize(const REGFOLDERINFO *pInfo, IShellFolder *pSF, 
DWORD dwFlags);
+        HRESULT AddItemsFromKey(IShellFolder *pSF, HKEY hkey_root, LPCWSTR 
szRepPath);
+
+        const CLSID* GetPidlClsid(PCUITEMID_CHILD pidl) { return 
IsRegItem(pidl); }
+        BOOL HasItemWithCLSID(LPCITEMIDLIST pidl) { return 
HasItemWithCLSIDImpl<CRegFolderEnum>(pidl); }
 
         BEGIN_COM_MAP(CRegFolderEnum)
         COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
         END_COM_MAP()
 };
 
-CRegFolderEnum::CRegFolderEnum()
+HRESULT CRegFolderEnum::Initialize(const REGFOLDERINFO *pInfo, IShellFolder 
*pSF, DWORD dwFlags)
 {
-}
-
-CRegFolderEnum::~CRegFolderEnum()
-{
-}
-
-HRESULT CRegFolderEnum::Initialize(LPCWSTR lpszEnumKeyName, DWORD dwFlags)
-{
-    WCHAR KeyName[MAX_PATH];
-
+    InitializeFolderInfo(pInfo);
+    m_SHCTF = (SHCONTF)dwFlags;
     if (!(dwFlags & SHCONTF_FOLDERS))
         return S_OK;
 
-    HRESULT hr = StringCchPrintfW(KeyName, MAX_PATH,
+    WCHAR KeyName[MAX_PATH];
+    HRESULT hr = StringCchPrintfW(KeyName, _countof(KeyName),
                                   
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\%s\\Namespace",
-                                  lpszEnumKeyName);
+                                  pInfo->pszEnumKeyName);
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
 
-    AddItemsFromKey(HKEY_LOCAL_MACHINE, KeyName);
-    AddItemsFromKey(HKEY_CURRENT_USER, KeyName);
-
+    // First add the required items and then the items from the registry
+    SFGAOF query = SHELL_CreateFolderEnumItemAttributeQuery(m_SHCTF, TRUE);
+    for (size_t i = 0; i < GetRequiredItemsCount(); ++i)
+    {
+        LPITEMIDLIST pidl = CreateItem(i);
+        if (pidl && SHELL_IncludeItemInFolderEnum(pSF, pidl, query, m_SHCTF))
+            AddToEnumList(pidl);
+        else
+            ILFree(pidl);
+    }
+    AddItemsFromKey(pSF, HKEY_LOCAL_MACHINE, KeyName);
+    AddItemsFromKey(pSF, HKEY_CURRENT_USER, KeyName);
     return S_OK;
 }
 
-HRESULT CRegFolderEnum::AddItemsFromKey(HKEY hkey_root, LPCWSTR szRepPath)
+HRESULT CRegFolderEnum::AddItemsFromKey(IShellFolder *pSF, HKEY hkey_root, 
LPCWSTR szRepPath)
 {
     WCHAR name[MAX_PATH];
     HKEY hkey;
@@ -275,13 +278,16 @@ HRESULT CRegFolderEnum::AddItemsFromKey(HKEY hkey_root, 
LPCWSTR szRepPath)
 
         if (*name == '{')
         {
-            LPITEMIDLIST pidl = _ILCreateGuidFromStrW(name);
-
-            if (pidl)
-                AddToEnumList(pidl);
+            if (LPITEMIDLIST pidl = CreateRegItem(GetPidlType(), name))
+            {
+                SFGAOF query = 
SHELL_CreateFolderEnumItemAttributeQuery(m_SHCTF, TRUE);
+                if (SHELL_IncludeItemInFolderEnum(pSF, pidl, query, m_SHCTF) 
&& !HasItemWithCLSID(pidl))
+                    AddToEnumList(pidl);
+                else
+                    ILFree(pidl);
+            }
         }
     }
-
     RegCloseKey(hkey);
 
     return S_OK;
@@ -301,12 +307,11 @@ enum REGFOLDERCOLUMNINDEX
 
 class CRegFolder :
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
-    public IShellFolder2
+    public IShellFolder2,
+    public CRegFolderInfo
 {
     private:
-        GUID m_guid;
-        CAtlStringW m_rootPath;
-        CAtlStringW m_enumKeyName;
+        IShellFolder *m_pOuterFolder; // Not ref-counted
         CComHeapPtr<ITEMIDLIST> m_pidlRoot;
 
         HRESULT GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD 
pdwAttributes);
@@ -315,7 +320,19 @@ class CRegFolder :
     public:
         CRegFolder();
         ~CRegFolder();
-        HRESULT WINAPI Initialize(const GUID *pGuid, LPCITEMIDLIST pidlRoot, 
LPCWSTR lpszPath, LPCWSTR lpszEnumKeyName);
+        HRESULT WINAPI Initialize(PREGFOLDERINITDATA pInit, LPCITEMIDLIST 
pidlRoot);
+
+        const REQUIREDREGITEM* IsRequiredItem(LPCITEMIDLIST pidl) const
+        {
+            const CLSID* const pCLSID = IsRegItem(pidl);
+            for (size_t i = 0; pCLSID && i < GetRequiredItemsCount(); ++i)
+            {
+                const REQUIREDREGITEM &item = GetAt(i);
+                if (item.clsid == *pCLSID)
+                    return &item;
+            }
+            return NULL;
+        }
 
         // IShellFolder
         STDMETHOD(ParseDisplayName)(HWND hwndOwner, LPBC pbc, LPOLESTR 
lpszDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG 
*pdwAttributes) override;
@@ -356,17 +373,10 @@ CRegFolder::~CRegFolder()
 {
 }
 
-HRESULT WINAPI CRegFolder::Initialize(const GUID *pGuid, LPCITEMIDLIST 
pidlRoot, LPCWSTR lpszPath, LPCWSTR lpszEnumKeyName)
+HRESULT WINAPI CRegFolder::Initialize(PREGFOLDERINITDATA pInit, LPCITEMIDLIST 
pidlRoot)
 {
-    memcpy(&m_guid, pGuid, sizeof(m_guid));
-
-    m_rootPath = lpszPath;
-    if (!m_rootPath)
-        return E_OUTOFMEMORY;
-
-    m_enumKeyName = lpszEnumKeyName;
-    if (!m_enumKeyName)
-        return E_OUTOFMEMORY;
+    InitializeFolderInfo(pInit->pInfo);
+    m_pOuterFolder = pInit->psfOuter;
 
     m_pidlRoot.Attach(ILClone(pidlRoot));
     if (!m_pidlRoot)
@@ -442,7 +452,7 @@ HRESULT WINAPI CRegFolder::ParseDisplayName(HWND hwndOwner, 
LPBC pbc, LPOLESTR l
         return E_FAIL;
     }
 
-    CComHeapPtr<ITEMIDLIST> pidlTemp(_ILCreateGuid(PT_GUID, clsid));
+    CComHeapPtr<ITEMIDLIST> pidlTemp(CreateRegItem(GetPidlType(), clsid));
     if (!pidlTemp)
         return E_OUTOFMEMORY;
 
@@ -471,7 +481,8 @@ HRESULT WINAPI CRegFolder::ParseDisplayName(HWND hwndOwner, 
LPBC pbc, LPOLESTR l
 
 HRESULT WINAPI CRegFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, 
LPENUMIDLIST *ppEnumIDList)
 {
-    return ShellObjectCreatorInit<CRegFolderEnum>(m_enumKeyName, dwFlags, 
IID_PPV_ARG(IEnumIDList, ppEnumIDList));
+    return ShellObjectCreatorInit<CRegFolderEnum>(m_pInfo, m_pOuterFolder, 
dwFlags,
+                                                  IID_PPV_ARG(IEnumIDList, 
ppEnumIDList));
 }
 
 HRESULT WINAPI CRegFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC 
pbcReserved, REFIID riid, LPVOID *ppvOut)
@@ -529,14 +540,10 @@ HRESULT WINAPI CRegFolder::CompareIDs(LPARAM lParam, 
PCUIDLIST_RELATIVE pidl1, P
 
     /* Guid folders come first compared to everything else */
     /* And Drives come before folders in My Computer */
-    if (_ILIsMyComputer(m_pidlRoot))
-    {
+    if (GetPidlType() == PT_COMPUTER_REGITEM)
         return MAKE_COMPARE_HRESULT(clsid1 ? 1 : -1);
-    }
     else
-    {
         return MAKE_COMPARE_HRESULT(clsid1 ? -1 : 1);
-    }
 }
 
 HRESULT WINAPI CRegFolder::CreateViewObject(HWND hwndOwner, REFIID riid, 
LPVOID *ppvOut)
@@ -591,7 +598,7 @@ HRESULT WINAPI CRegFolder::GetUIObjectOf(HWND hwndOwner, 
UINT cidl, PCUITEMID_CH
             return E_FAIL;
         }
 
-        hr = CGuidItemContextMenu_CreateInstance(m_pidlRoot, hwndOwner, cidl, 
apidl, static_cast<IShellFolder*>(this), (IContextMenu**)&pObj);
+        hr = CRegItemContextMenu_CreateInstance(m_pidlRoot, hwndOwner, cidl, 
apidl, static_cast<IShellFolder*>(this), (IContextMenu**)&pObj);
     }
     else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1))
     {
@@ -626,7 +633,7 @@ HRESULT WINAPI CRegFolder::GetDisplayNameOf(PCUITEMID_CHILD 
pidl, DWORD dwFlags,
             /* parsing name like ::{...} */
             pszPath[0] = ':';
             pszPath[1] = ':';
-            SHELL32_GUIDToStringW(m_guid, &pszPath[2]);
+            SHELL32_GUIDToStringW(m_pInfo->clsid, &pszPath[2]);
             strRet->uType = STRRET_WSTR;
             strRet->pOleStr = pszPath;
             return S_OK;
@@ -635,7 +642,7 @@ HRESULT WINAPI CRegFolder::GetDisplayNameOf(PCUITEMID_CHILD 
pidl, DWORD dwFlags,
         {
             BOOL bRet;
             WCHAR wstrName[MAX_PATH+1];
-            bRet = HCR_GetClassNameW(m_guid, wstrName, MAX_PATH);
+            bRet = HCR_GetClassNameW(m_pInfo->clsid, wstrName, MAX_PATH);
             if (!bRet)
                 return E_FAIL;
 
@@ -698,7 +705,7 @@ HRESULT WINAPI CRegFolder::GetDisplayNameOf(PCUITEMID_CHILD 
pidl, DWORD dwFlags,
         PWCHAR pItemName = pszPath; // GET_SHGDN_RELATION(dwFlags) == 
SHGDN_INFOLDER
         if (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER)
         {
-            hr = StringCchCopyW(pszPath, cchPath, m_rootPath);
+            hr = StringCchCopyW(pszPath, cchPath, GetParsingPath());
             if (SUCCEEDED(hr))
             {
                 pathlen = wcslen(pszPath);
@@ -861,8 +868,79 @@ HRESULT WINAPI CRegFolder::MapColumnToSCID(UINT column, 
SHCOLUMNID *pscid)
     return E_NOTIMPL;
 }
 
+static HRESULT CALLBACK RegFolderContextMenuCallback(IShellFolder *psf, HWND 
hwnd, IDataObject *pdtobj,
+                                                     UINT uMsg, WPARAM wParam, 
LPARAM lParam)
+{
+    if (uMsg != DFM_INVOKECOMMAND || wParam != DFM_CMD_PROPERTIES)
+        return SHELL32_DefaultContextMenuCallBack(psf, pdtobj, uMsg);
+
+    PIDLIST_ABSOLUTE pidlFolder;
+    PUITEMID_CHILD *apidl;
+    UINT cidl;
+    HRESULT hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    CRegFolder *pRegFolder = static_cast<CRegFolder*>(psf);
+    const REQUIREDREGITEM* pRequired = pRegFolder->IsRequiredItem(apidl[0]);
+    if (pRequired && pRequired->pszCpl)
+    {
+        WCHAR buf[MAX_PATH];
+        wsprintfW(buf, L"%hs", const_cast<LPCSTR>(pRequired->pszCpl));
+        hr = SHELL_ExecuteControlPanelCPL(hwnd, buf) ? S_OK : E_FAIL;
+    }
+#if 0 // Should never happen, CDesktopFolder.cpp handles this
+    else if (_ILIsDesktop(pidlFolder) && _ILIsDesktop(apidl[0]))
+    {
+        hr = SHELL_ExecuteControlPanelCPL(hwnd, L"desk.cpl") ? S_OK : E_FAIL;
+    }
+#endif
+    else if (_ILIsDesktop(pidlFolder) && _ILIsBitBucket(apidl[0]))
+    {
+        FIXME("Use SHOpenPropSheet on Recyclers PropertySheetHandlers from the 
registry\n");
+        hr = SH_ShowRecycleBinProperties(L'C') ? S_OK : E_FAIL;
+    }
+    else
+    {
+        hr = S_FALSE; // Tell the caller to run the default action
+    }
+
+    SHFree(pidlFolder);
+    _ILFreeaPidl(apidl, cidl);
+    return hr;
+}
+
+static HRESULT CRegItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE 
pidlFolder, HWND hwnd, UINT cidl,
+                                                  PCUITEMID_CHILD_ARRAY apidl, 
IShellFolder *psf, IContextMenu **ppcm)
+{
+    HKEY hKeys[3];
+    UINT cKeys = 0;
+
+    const GUID *pGuid = _ILGetGUIDPointer(apidl[0]);
+    if (pGuid)
+    {
+        WCHAR key[sizeof("CLSID\\") + 38];
+        wcscpy(key, L"CLSID\\");
+        StringFromGUID2(*pGuid, &key[6], 39);
+        AddClassKeyToArray(key, hKeys, &cKeys);
+    }
+
+    // FIXME: CRegFolder should be aggregated by its outer folder and should
+    // provide the attributes for all required non-registry folders.
+    // It currently does not so we have to ask the outer folder ourself so
+    // that we get the correct attributes for My Computer etc.
+    CComPtr<IShellFolder> pOuterSF;
+    SHBindToObject(NULL, pidlFolder, IID_PPV_ARG(IShellFolder, &pOuterSF));
+
+    SFGAOF att = (psf && cidl) ? SHGetAttributes(pOuterSF ? pOuterSF.p : psf, 
apidl[0], SFGAO_FOLDER) : 0;
+    if ((att & SFGAO_FOLDER) && (!pGuid || !HasCLSIDShellFolderValue(*pGuid, 
L"HideFolderVerbs")))
+        AddClassKeyToArray(L"Folder", hKeys, &cKeys);
+
+    return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, 
RegFolderContextMenuCallback, cKeys, hKeys, ppcm);
+}
+
 /* In latest windows version this is exported but it takes different 
arguments! */
-HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, 
LPCWSTR lpszPath, LPCWSTR lpszEnumKeyName, REFIID riid, void **ppv)
+HRESULT CRegFolder_CreateInstance(PREGFOLDERINITDATA pInit, LPCITEMIDLIST 
pidlRoot, REFIID riid, void **ppv)
 {
-    return ShellObjectCreatorInit<CRegFolder>(pGuid, pidlRoot, lpszPath, 
lpszEnumKeyName, riid, ppv);
+    return ShellObjectCreatorInit<CRegFolder>(pInit, pidlRoot, riid, ppv);
 }
diff --git a/dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp 
b/dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp
index 11c65fb9819..d14c1c15626 100644
--- a/dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp
+++ b/dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp
@@ -226,8 +226,7 @@ HRESULT CDesktopBrowser::Initialize(IShellDesktopTray 
*ShellDesk)
     if (!m_hWnd)
         return E_FAIL;
 
-    CSFV csfv = {sizeof(CSFV), psfDesktop};
-    hRet = SHCreateShellFolderViewEx(&csfv, &m_ShellView);
+    hRet = psfDesktop->CreateViewObject(m_hWnd, IID_PPV_ARG(IShellView, 
&m_ShellView));
     if (FAILED_UNEXPECTEDLY(hRet))
         return hRet;
 
diff --git a/dll/win32/shell32/shfldr.h b/dll/win32/shell32/shfldr.h
index 2b055833464..ff397123b8e 100644
--- a/dll/win32/shell32/shfldr.h
+++ b/dll/win32/shell32/shfldr.h
@@ -47,11 +47,53 @@ 
https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_co
 #define SHFSF_COL_FATTS         4 // File attributes
 #define SHFSF_COL_COMMENT       5
 
+typedef struct _REQUIREDREGITEM
+{
+    REFCLSID clsid;
+    LPCSTR pszCpl;
+    BYTE Order; // According to Geoff Chappell, required items have a fixed 
sort order
+} REQUIREDREGITEM;
+
+typedef struct _REGFOLDERINFO
+{
+    PIDLTYPE PidlType;
+    BYTE Count; // Count of required items
+    const REQUIREDREGITEM *Items;
+    REFCLSID clsid;
+    LPCWSTR pszParsingPath;
+    LPCWSTR pszEnumKeyName;
+} REGFOLDERINFO;
+
+typedef struct _REGFOLDERINITDATA
+{
+    IShellFolder *psfOuter;
+    const REGFOLDERINFO *pInfo;
+} REGFOLDERINITDATA, *PREGFOLDERINITDATA;
+
+HRESULT CRegFolder_CreateInstance(PREGFOLDERINITDATA pInit, LPCITEMIDLIST 
pidlRoot, REFIID riid, void **ppv);
+
 #define GET_SHGDN_FOR(dwFlags)         ((DWORD)dwFlags & (DWORD)0x0000FF00)
 #define GET_SHGDN_RELATION(dwFlags)    ((DWORD)dwFlags & (DWORD)0x000000FF)
 #define IS_SHGDN_FOR_PARSING(flags) ( ((flags) & (SHGDN_FORADDRESSBAR | 
SHGDN_FORPARSING)) == SHGDN_FORPARSING)
 #define IS_SHGDN_DESKTOPABSOLUTEPARSING(flags) ( ((flags) & 
(SHGDN_FORADDRESSBAR | SHGDN_FORPARSING | 0xFF)) == SHGDN_FORPARSING)
 
+static inline SFGAOF 
+SHELL_CreateFolderEnumItemAttributeQuery(SHCONTF Flags, BOOL ForRegItem)
+{
+    SFGAOF query = SFGAO_FOLDER | (ForRegItem ? SFGAO_NONENUMERATED : 0);
+    if (!(Flags & SHCONTF_INCLUDEHIDDEN))
+        query |= SFGAO_HIDDEN;
+    if (!(Flags & SHCONTF_INCLUDESUPERHIDDEN))
+        query |= SFGAO_HIDDEN | SFGAO_SYSTEM;
+    return query;
+}
+
+SHCONTF
+SHELL_GetDefaultFolderEnumSHCONTF();
+
+BOOL
+SHELL_IncludeItemInFolderEnum(IShellFolder *pSF, PCUITEMID_CHILD pidl, SFGAOF 
Query, SHCONTF Flags);
+
 HRESULT
 Shell_NextElement(
     _Inout_ LPWSTR *ppch,
diff --git a/dll/win32/shell32/shlfolder.cpp b/dll/win32/shell32/shlfolder.cpp
index a6ea823212f..1d32793d746 100644
--- a/dll/win32/shell32/shlfolder.cpp
+++ b/dll/win32/shell32/shlfolder.cpp
@@ -26,6 +26,34 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
+SHCONTF SHELL_GetDefaultFolderEnumSHCONTF()
+{
+    SHCONTF Flags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
+    SHELLSTATE ss;
+    SHGetSetSettings(&ss, SSF_SHOWALLOBJECTS | SSF_SHOWSUPERHIDDEN, FALSE);
+    if (ss.fShowAllObjects)
+        Flags |= SHCONTF_INCLUDEHIDDEN;
+    if (ss.fShowSuperHidden)
+        Flags |= SHCONTF_INCLUDESUPERHIDDEN;
+     return Flags;
+}
+
+BOOL SHELL_IncludeItemInFolderEnum(IShellFolder *pSF, PCUITEMID_CHILD pidl, 
SFGAOF Query, SHCONTF Flags)
+{
+    if (SUCCEEDED(pSF->GetAttributesOf(1, &pidl, &Query)))
+    {
+        if (Query & SFGAO_NONENUMERATED)
+            return FALSE;
+        if ((Query & SFGAO_HIDDEN) && !(Flags & SHCONTF_INCLUDEHIDDEN))
+            return FALSE;
+        if ((Query & (SFGAO_HIDDEN | SFGAO_SYSTEM)) == (SFGAO_HIDDEN | 
SFGAO_SYSTEM) && !(Flags & SHCONTF_INCLUDESUPERHIDDEN))
+            return FALSE;
+        if ((Flags & (SHCONTF_FOLDERS | SHCONTF_NONFOLDERS)) != 
(SHCONTF_FOLDERS | SHCONTF_NONFOLDERS))
+            return (Flags & SHCONTF_FOLDERS) ? (Query & SFGAO_FOLDER) : 
!(Query & SFGAO_FOLDER);
+    }
+    return TRUE;
+}
+
 HRESULT
 Shell_NextElement(
     _Inout_ LPWSTR *ppch,
diff --git a/dll/win32/shell32/wine/pidl.c b/dll/win32/shell32/wine/pidl.c
index 09b09112adb..54751ded772 100644
--- a/dll/win32/shell32/wine/pidl.c
+++ b/dll/win32/shell32/wine/pidl.c
@@ -1767,7 +1767,6 @@ LPITEMIDLIST _ILCreateGuidFromStrA(LPCSTR szGUID)
     }
     return _ILCreateGuid(PT_GUID, &iid);
 }
-#endif
 
 LPITEMIDLIST _ILCreateGuidFromStrW(LPCWSTR szGUID)
 {
@@ -1784,6 +1783,7 @@ LPITEMIDLIST _ILCreateGuidFromStrW(LPCWSTR szGUID)
     }
     return _ILCreateGuid(PT_GUID, &iid);
 }
+#endif /* __REACTOS__ */
 
 LPITEMIDLIST _ILCreateFromFindDataW( const WIN32_FIND_DATAW *wfd )
 {
diff --git a/dll/win32/shell32/wine/pidl.h b/dll/win32/shell32/wine/pidl.h
index b25481bd6c8..304ce1cc19b 100644
--- a/dll/win32/shell32/wine/pidl.h
+++ b/dll/win32/shell32/wine/pidl.h
@@ -104,6 +104,18 @@ extern "C" {
 #define PT_IESPECIAL2  0xb1
 #define PT_SHARE       0xc3
 
+#ifdef __REACTOS__
+#define PT_DESKTOP_REGITEM      0x1F // => SHDID_ROOT_REGITEM
+#define PT_COMPUTER_REGITEM     0x2E // => SHDID_COMPUTER_OTHER
+#define PT_FS                   0x30 // Win95 SHSimpleIDListFromPath
+#define PT_FS_FOLDER_FLAG       0x01
+#define PT_FS_FILE_FLAG         0x02
+#define PT_FS_UNICODE_FLAG      0x04
+//      PT_NET_REGITEM          0x4? // => SHDID_NET_OTHER
+#define PT_CONTROLS_OLDREGITEM  0x70
+#define PT_CONTROLS_NEWREGITEM  0x71
+#endif
+
 #include "pshpack1.h"
 typedef BYTE PIDLTYPE;
 
@@ -263,9 +275,11 @@ BOOL    _ILIsEmpty              (LPCITEMIDLIST pidl) { 
return _ILIsDesktop(pidl)
  */
 LPITEMIDLIST   _ILCreateGuid(PIDLTYPE type, REFIID guid) DECLSPEC_HIDDEN;
 
+#ifndef __REACTOS__
 /* Like _ILCreateGuid, but using the string szGUID. */
 LPITEMIDLIST   _ILCreateGuidFromStrA(LPCSTR szGUID) DECLSPEC_HIDDEN;
 LPITEMIDLIST   _ILCreateGuidFromStrW(LPCWSTR szGUID) DECLSPEC_HIDDEN;
+#endif
 
 /* Commonly used PIDLs representing file system objects. */
 LPITEMIDLIST   _ILCreateDesktop        (void) DECLSPEC_HIDDEN;
diff --git a/dll/win32/shell32/wine/shell32_main.h 
b/dll/win32/shell32/wine/shell32_main.h
index db03e2ad794..73bebc71d3b 100644
--- a/dll/win32/shell32/wine/shell32_main.h
+++ b/dll/win32/shell32/wine/shell32_main.h
@@ -90,8 +90,6 @@ HRESULT WINAPI IFileSystemBindData_Constructor(const 
WIN32_FIND_DATAW *pfd, LPBC
 HRESULT WINAPI CPanel_ExtractIconA(LPITEMIDLIST pidl, LPCSTR pszFile, UINT 
nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) 
DECLSPEC_HIDDEN;
 HRESULT WINAPI CPanel_ExtractIconW(LPITEMIDLIST pidl, LPCWSTR pszFile, UINT 
nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) 
DECLSPEC_HIDDEN;
 
-HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, 
LPCWSTR lpszPath, LPCWSTR lpszEnumKeyName, REFIID riid, void **ppv);
-
 /* initialisation for FORMATETC */
 #define InitFormatEtc(fe, cf, med) \
        {\
diff --git a/sdk/include/psdk/shobjidl.idl b/sdk/include/psdk/shobjidl.idl
index a31a145190b..8738863eb55 100644
--- a/sdk/include/psdk/shobjidl.idl
+++ b/sdk/include/psdk/shobjidl.idl
@@ -195,6 +195,7 @@ interface IShellFolder : IUnknown
     cpp_quote("#define SFGAO_HASPROPSHEET      0x00000040L")
     cpp_quote("#define SFGAO_DROPTARGET        0x00000100L")
     cpp_quote("#define SFGAO_CAPABILITYMASK    0x00000177L")
+    cpp_quote("#define SFGAO_SYSTEM            0x00001000L")
     cpp_quote("#define SFGAO_ENCRYPTED         0x00002000L")
     cpp_quote("#define SFGAO_ISSLOW            0x00004000L")
     cpp_quote("#define SFGAO_GHOSTED           0x00008000L")
@@ -1485,6 +1486,38 @@ interface ICommDlgBrowser3 : ICommDlgBrowser2
         [in] IShellView *ppshv);
 }
 
+/*****************************************************************************
+ * IFolderFilterSite & IFolderFilter interfaces
+ */
+[
+    object,
+    uuid(C0A651F5-B48B-11d2-B5ED-006097C686F6),
+    pointer_default(unique)
+]
+interface IFolderFilterSite : IUnknown
+{
+    HRESULT SetFilter([in] IUnknown* punk);
+}
+
+[
+    object,
+    uuid(9CC22886-DC8E-11d2-B1D0-00C04F8EEB3E),
+    pointer_default(unique)
+]
+interface IFolderFilter : IUnknown
+{
+    HRESULT ShouldShow(
+        [in] IShellFolder* psf,
+        [in, unique] PCIDLIST_ABSOLUTE pidlFolder,
+        [in] PCUITEMID_CHILD pidlItem);
+
+    HRESULT GetEnumFlags(
+        [in] IShellFolder* psf,
+        [in] PCIDLIST_ABSOLUTE pidlFolder,
+        [out] HWND *phwnd,
+        [in, out] DWORD *pgrfFlags);
+}
+
 /*****************************************************************************
  * IDockingWindow interface
  */
diff --git a/sdk/include/reactos/shellutils.h b/sdk/include/reactos/shellutils.h
index 17d7e0e74e7..825e834897b 100644
--- a/sdk/include/reactos/shellutils.h
+++ b/sdk/include/reactos/shellutils.h
@@ -293,6 +293,17 @@ HRESULT inline ShellDebugObjectCreator(REFIID riid, R ** 
ppv)
     return S_OK;
 }
 
+template<class T>
+HRESULT inline ShellObjectCreator(CComPtr<T> &objref)
+{
+    _CComObject<T> *pobj;
+    HRESULT hResult = _CComObject<T>::CreateInstance(&pobj);
+    objref = pobj; // AddRef() gets called here
+    if (FAILED(hResult))
+        return hResult;
+    return S_OK;
+}
+
 template<class T>
 HRESULT inline ShellObjectCreator(REFIID riid, void ** ppv)
 {

Reply via email to