[SHELL32]
authorGiannis Adamopoulos <gadamopoulos@reactos.org>
Sun, 16 Jul 2017 15:13:02 +0000 (15:13 +0000)
committerGiannis Adamopoulos <gadamopoulos@reactos.org>
Sun, 16 Jul 2017 15:13:02 +0000 (15:13 +0000)
-CRegFolder: Implement CRegFolder::EnumObjects. Change its constructor to receive an extra parameter for the name of the key that should be enumerated.
-CEnumIDListBase: Add a new method called AppendItemsFromEnumerator to facilitate merging the contents from one IEnumIDList to another.
-Use the above in the enumerators of CControlPanelFolder, CDesktopFolder and CDrivesFolder to make them significantly simpler.

svn path=/trunk/; revision=75360

reactos/dll/win32/shell32/CEnumIDListBase.cpp
reactos/dll/win32/shell32/CEnumIDListBase.h
reactos/dll/win32/shell32/folders/CControlPanelFolder.cpp
reactos/dll/win32/shell32/folders/CDesktopFolder.cpp
reactos/dll/win32/shell32/folders/CDrivesFolder.cpp
reactos/dll/win32/shell32/folders/CRegFolder.cpp
reactos/dll/win32/shell32/wine/shell32_main.h

index c0ae7f1..5963341 100644 (file)
@@ -123,6 +123,22 @@ BOOL CEnumIDListBase::HasItemWithCLSID(LPITEMIDLIST pidl)
     return FALSE;
 }
 
+HRESULT CEnumIDListBase::AppendItemsFromEnumerator(IEnumIDList* pEnum)
+{
+    LPITEMIDLIST pidl;
+    DWORD dwFetched;
+
+    if (!pEnum)
+        return E_INVALIDARG;
+
+    pEnum->Reset();
+
+    while((S_OK == pEnum->Next(1, &pidl, &dwFetched)) && dwFetched)
+        AddToEnumList(pidl);
+
+    return S_OK;
+}
+
 /**************************************************************************
  *  IEnumIDList_fnNext
  */
index 80d9a01..262a824 100644 (file)
@@ -37,6 +37,7 @@ public:
        BOOL AddToEnumList(LPITEMIDLIST pidl);
        BOOL DeleteList();
        BOOL HasItemWithCLSID(LPITEMIDLIST pidl);
+    HRESULT AppendItemsFromEnumerator(IEnumIDList* pEnum);
 
        // *** IEnumIDList methods ***
        virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG *pceltFetched);
index 62540ab..8dc2fbb 100644 (file)
@@ -33,10 +33,9 @@ class CControlPanelEnum :
     public:
         CControlPanelEnum();
         ~CControlPanelEnum();
-        HRESULT WINAPI Initialize(DWORD dwFlags);
+        HRESULT WINAPI Initialize(DWORD dwFlags, IEnumIDList* pRegEnumerator);
         BOOL RegisterCPanelApp(LPCWSTR path);
         int RegisterRegistryCPanelApps(HKEY hkey_root, LPCWSTR szRepPath);
-        int RegisterCPanelFolders(HKEY hkey_root, LPCWSTR szRepPath);
         BOOL CreateCPanelEnumList(DWORD dwFlags);
 
         BEGIN_COM_MAP(CControlPanelEnum)
@@ -63,10 +62,11 @@ CControlPanelEnum::~CControlPanelEnum()
 {
 }
 
-HRESULT WINAPI CControlPanelEnum::Initialize(DWORD dwFlags)
+HRESULT WINAPI CControlPanelEnum::Initialize(DWORD dwFlags, IEnumIDList* pRegEnumerator)
 {
     if (CreateCPanelEnumList(dwFlags) == FALSE)
         return E_FAIL;
+    AppendItemsFromEnumerator(pRegEnumerator);
     return S_OK;
 }
 
@@ -203,35 +203,6 @@ int CControlPanelEnum::RegisterRegistryCPanelApps(HKEY hkey_root, LPCWSTR szRepP
     return cnt;
 }
 
-int CControlPanelEnum::RegisterCPanelFolders(HKEY hkey_root, LPCWSTR szRepPath)
-{
-    WCHAR name[MAX_PATH];
-    HKEY hkey;
-
-    int cnt = 0;
-
-    if (RegOpenKeyW(hkey_root, szRepPath, &hkey) == ERROR_SUCCESS)
-    {
-        for (int idx = 0; ; idx++)
-        {
-            if (RegEnumKeyW(hkey, idx, name, MAX_PATH) != ERROR_SUCCESS)
-                break;
-
-            if (*name == '{')
-            {
-                LPITEMIDLIST pidl = _ILCreateGuidFromStrW(name);
-
-                if (pidl && AddToEnumList(pidl))
-                    ++cnt;
-            }
-        }
-
-        RegCloseKey(hkey);
-    }
-
-    return cnt;
-}
-
 /**************************************************************************
  *  CControlPanelEnum::CreateCPanelEnumList()
  */
@@ -243,10 +214,6 @@ BOOL CControlPanelEnum::CreateCPanelEnumList(DWORD dwFlags)
 
     TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
 
-    /* enumerate control panel folders */
-    if (dwFlags & SHCONTF_FOLDERS)
-        RegisterCPanelFolders(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace");
-
     /* enumerate the control panel applets */
     if (dwFlags & SHCONTF_NONFOLDERS)
     {
@@ -311,7 +278,10 @@ HRESULT WINAPI CControlPanelFolder::ParseDisplayName(
 */
 HRESULT WINAPI CControlPanelFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
 {
-    return ShellObjectCreatorInit<CControlPanelEnum>(dwFlags, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
+    CComPtr<IEnumIDList> pRegEnumerator;
+    m_regFolder->EnumObjects(hwndOwner, dwFlags, &pRegEnumerator);
+
+    return ShellObjectCreatorInit<CControlPanelEnum>(dwFlags, pRegEnumerator, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
 }
 
 /**************************************************************************
@@ -657,6 +627,7 @@ HRESULT WINAPI CControlPanelFolder::Initialize(LPCITEMIDLIST pidl)
     hr = CRegFolder_CreateInstance(&CLSID_ControlPanel,
                                    pidlRoot,
                                    pszCPanelPath, 
+                                   L"ControlPanel",
                                    IID_PPV_ARG(IShellFolder2, &m_regFolder));
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
index b104e13..9255337 100644 (file)
@@ -44,54 +44,6 @@ always shows My Computer.
 /* Undocumented functions from shdocvw */
 extern "C" HRESULT WINAPI IEParseDisplayNameWithBCW(DWORD codepage, LPCWSTR lpszDisplayName, LPBC pbc, LPITEMIDLIST *ppidl);
 
-class CDesktopFolderEnum :
-    public CEnumIDListBase
-{
-    private:
-//    CComPtr                                fDesktopEnumerator;
-//    CComPtr                                fCommonDesktopEnumerator;
-    public:
-        CDesktopFolderEnum();
-        ~CDesktopFolderEnum();
-        HRESULT WINAPI Initialize(HWND hwndOwner, DWORD dwFlags, IEnumIDList *pDesktopEnumerator, IEnumIDList *pCommonDesktopEnumerator);
-
-        BEGIN_COM_MAP(CDesktopFolderEnum)
-        COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
-        END_COM_MAP()
-};
-
-int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll);
-
-static const shvheader DesktopSFHeader[] = {
-    {IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
-    {IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 10},
-    {IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
-    {IDS_SHV_COLUMN_SIZE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
-    {IDS_SHV_COLUMN_MODIFIED, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12},
-    {IDS_SHV_COLUMN_ATTRIBUTES, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10}
-};
-
-#define DESKTOPSHELLVIEWCOLUMNS 6
-
-static const DWORD dwDesktopAttributes =
-    SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
-    SFGAO_STORAGEANCESTOR | SFGAO_HASPROPSHEET | SFGAO_STORAGE | SFGAO_CANLINK;
-static const DWORD dwMyComputerAttributes =
-    SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
-    SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
-static DWORD dwMyNetPlacesAttributes =
-    SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
-    SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
-
-
-CDesktopFolderEnum::CDesktopFolderEnum()
-{
-}
-
-CDesktopFolderEnum::~CDesktopFolderEnum()
-{
-}
-
 static const WCHAR ClassicStartMenuW[] = L"SOFTWARE\\Microsoft\\Windows\\"
     L"CurrentVersion\\Explorer\\HideDesktopIcons\\ClassicStartMenu";
 
@@ -115,145 +67,88 @@ IsNamespaceExtensionHidden(const WCHAR *iid)
     return Result;
 }
 
-/**************************************************************************
- *  CreateDesktopEnumList()
- */
-
-HRESULT WINAPI CDesktopFolderEnum::Initialize(HWND hwndOwner, DWORD dwFlags, IEnumIDList *pDesktopEnumerator, IEnumIDList *pCommonDesktopEnumerator)
+static INT IsNamespaceExtensionHidden(LPCITEMIDLIST pidl)
 {
-    BOOL ret = TRUE;
-    LPITEMIDLIST pidl;
-
-    static const WCHAR MyDocumentsClassString[] = L"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
-    static const WCHAR Desktop_NameSpaceW[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\Namespace";
-
-    TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
+    GUID const *clsid = _ILGetGUIDPointer (pidl);
+    if (!clsid)
+        return -1;
 
-    /* enumerate the root folders */
-    if (dwFlags & SHCONTF_FOLDERS)
-    {
-        HKEY hkey;
-        UINT i;
-        DWORD dwResult;
+    WCHAR pwszGuid[CHARS_IN_GUID];
+    SHELL32_GUIDToStringW(*clsid, pwszGuid);
+    return IsNamespaceExtensionHidden(pwszGuid);
+}
 
-        /* create the pidl for This item */
-        if (IsNamespaceExtensionHidden(MyDocumentsClassString) < 1)
+class CDesktopFolderEnum :
+    public CEnumIDListBase
+{
+    private:
+//    CComPtr                                fDesktopEnumerator;
+//    CComPtr                                fCommonDesktopEnumerator;
+    public:
+        HRESULT WINAPI Initialize(DWORD dwFlags,IEnumIDList * pRegEnumerator, IEnumIDList *pDesktopEnumerator, IEnumIDList *pCommonDesktopEnumerator)
         {
-            ret = AddToEnumList(_ILCreateMyDocuments());
-        }
-        ret = AddToEnumList(_ILCreateMyComputer());
+            BOOL ret = TRUE;
+            LPITEMIDLIST pidl;
 
-        for (i = 0; i < 2; i++)
-        {
-            if (i == 0)
-                dwResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Desktop_NameSpaceW, 0, KEY_READ, &hkey);
-            else
-                dwResult = RegOpenKeyExW(HKEY_CURRENT_USER, Desktop_NameSpaceW, 0, KEY_READ, &hkey);
+            static const WCHAR MyDocumentsClassString[] = L"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
+
+            TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
 
-            if (dwResult == ERROR_SUCCESS)
+            /* enumerate the root folders */
+            if (dwFlags & SHCONTF_FOLDERS)
             {
-                WCHAR iid[50];
-                int i = 0;
+                AddToEnumList(_ILCreateMyComputer());
+                if (IsNamespaceExtensionHidden(MyDocumentsClassString) < 1)
+                    AddToEnumList(_ILCreateMyDocuments());
 
-                while (ret)
+                DWORD dwFetched;
+                while((S_OK == pRegEnumerator->Next(1, &pidl, &dwFetched)) && dwFetched)
                 {
-                    DWORD size;
-                    LONG r;
-
-                    size = sizeof (iid) / sizeof (iid[0]);
-                    r = RegEnumKeyExW(hkey, i, iid, &size, 0, NULL, NULL, NULL);
-                    if (ERROR_SUCCESS == r)
+                    if (IsNamespaceExtensionHidden(pidl) < 1)
                     {
-                        if (IsNamespaceExtensionHidden(iid) < 1)
-                        {
-                            pidl = _ILCreateGuidFromStrW(iid);
-                            if (pidl != NULL)
-                            {
-                                if (!HasItemWithCLSID(pidl))
-                                {
-                                    ret = AddToEnumList(pidl);
-                                }
-                                else
-                                {
-                                    SHFree(pidl);
-                                }
-                            }
-                        }
+                        if (!HasItemWithCLSID(pidl))
+                            AddToEnumList(pidl);
+                        else
+                            SHFree(pidl);
                     }
-                    else if (ERROR_NO_MORE_ITEMS == r)
-                        break;
-                    else
-                        ret = FALSE;
-                    i++;
                 }
-                RegCloseKey(hkey);
             }
-        }
-        for (i = 0; i < 2; i++)
-        {
-            if (i == 0)
-                dwResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, ClassicStartMenuW, 0, KEY_READ, &hkey);
-            else
-                dwResult = RegOpenKeyExW(HKEY_CURRENT_USER, ClassicStartMenuW, 0, KEY_READ, &hkey);
 
-            if (dwResult == ERROR_SUCCESS)
-            {
-                DWORD j = 0, dwVal, Val, dwType, dwIID;
-                LONG r;
-                WCHAR iid[50];
+            /* Enumerate the items in the two fs folders */
+            AppendItemsFromEnumerator(pDesktopEnumerator);
+            AppendItemsFromEnumerator(pCommonDesktopEnumerator);
 
-                while(ret)
-                {
-                    dwVal = sizeof(Val);
-                    dwIID = sizeof(iid) / sizeof(WCHAR);
+            return ret ? S_OK : E_FAIL;
+        }
 
-                    r = RegEnumValueW(hkey, j++, iid, &dwIID, NULL, &dwType, (LPBYTE)&Val, &dwVal);
-                    if (r == ERROR_SUCCESS)
-                    {
-                        if (Val == 0 && dwType == REG_DWORD)
-                        {
-                            pidl = _ILCreateGuidFromStrW(iid);
-                            if (pidl != NULL)
-                            {
-                                if (!HasItemWithCLSID(pidl))
-                                {
-                                    AddToEnumList(pidl);
-                                }
-                                else
-                                {
-                                    SHFree(pidl);
-                                }
-                            }
-                        }
-                    }
-                    else if (ERROR_NO_MORE_ITEMS == r)
-                        break;
-                    else
-                        ret = FALSE;
-                }
-                RegCloseKey(hkey);
-            }
 
-        }
-    }
+        BEGIN_COM_MAP(CDesktopFolderEnum)
+        COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
+        END_COM_MAP()
+};
 
-    DWORD dwFetched;
+int SHELL_ConfirmMsgBox(HWND hWnd, LPWSTR lpszText, LPWSTR lpszCaption, HICON hIcon, BOOL bYesToAll);
 
-    /* Enumerate the items in the two fs folders */
-    if (pDesktopEnumerator)
-    {
-        while((S_OK == pDesktopEnumerator->Next(1, &pidl, &dwFetched)) && dwFetched)
-            AddToEnumList(pidl);
-    }
+static const shvheader DesktopSFHeader[] = {
+    {IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 15},
+    {IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR, LVCFMT_LEFT, 10},
+    {IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10},
+    {IDS_SHV_COLUMN_SIZE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
+    {IDS_SHV_COLUMN_MODIFIED, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 12},
+    {IDS_SHV_COLUMN_ATTRIBUTES, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_LEFT, 10}
+};
 
-    if (pCommonDesktopEnumerator)
-    {
-        while((S_OK == pCommonDesktopEnumerator->Next(1, &pidl, &dwFetched)) && dwFetched)
-            AddToEnumList(pidl);
-    }
+#define DESKTOPSHELLVIEWCOLUMNS 6
 
-    return ret ? S_OK : E_FAIL;
-}
+static const DWORD dwDesktopAttributes =
+    SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
+    SFGAO_STORAGEANCESTOR | SFGAO_HASPROPSHEET | SFGAO_STORAGE | SFGAO_CANLINK;
+static const DWORD dwMyComputerAttributes =
+    SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
+    SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
+static DWORD dwMyNetPlacesAttributes =
+    SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET | SFGAO_DROPTARGET |
+    SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CANLINK;
 
 CDesktopFolder::CDesktopFolder() :
     sPathTarget(NULL),
@@ -295,6 +190,7 @@ HRESULT WINAPI CDesktopFolder::FinalConstruct()
     hr = CRegFolder_CreateInstance(&CLSID_ShellDesktop,
                                    pidlRoot,
                                    L"", 
+                                   L"Desktop",
                                    IID_PPV_ARG(IShellFolder2, &m_regFolder));
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
@@ -446,10 +342,15 @@ HRESULT WINAPI CDesktopFolder::ParseDisplayName(
  */
 HRESULT WINAPI CDesktopFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
 {
+    CComPtr<IEnumIDList> pRegEnumerator;
     CComPtr<IEnumIDList> pDesktopEnumerator;
     CComPtr<IEnumIDList> pCommonDesktopEnumerator;
     HRESULT hr;
 
+    hr = m_regFolder->EnumObjects(hwndOwner, dwFlags, &pRegEnumerator);
+    if (FAILED(hr))
+        ERR("EnumObjects for reg folder failed\n");
+
     hr = m_DesktopFSFolder->EnumObjects(hwndOwner, dwFlags, &pDesktopEnumerator);
     if (FAILED(hr))
         ERR("EnumObjects for desktop fs folder failed\n");
@@ -458,7 +359,7 @@ HRESULT WINAPI CDesktopFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUM
     if (FAILED(hr))
         ERR("EnumObjects for shared desktop fs folder failed\n");
 
-    return ShellObjectCreatorInit<CDesktopFolderEnum>(hwndOwner, dwFlags, pDesktopEnumerator, pCommonDesktopEnumerator, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
+    return ShellObjectCreatorInit<CDesktopFolderEnum>(dwFlags,pRegEnumerator, pDesktopEnumerator, pCommonDesktopEnumerator, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
 }
 
 /**************************************************************************
index f12f114..7a08824 100644 (file)
@@ -167,10 +167,28 @@ class CDrivesFolderEnum :
     public CEnumIDListBase
 {
     public:
-        CDrivesFolderEnum();
-        ~CDrivesFolderEnum();
-        HRESULT WINAPI Initialize(HWND hwndOwner, DWORD dwFlags);
-        BOOL CreateMyCompEnumList(DWORD dwFlags);
+        HRESULT WINAPI Initialize(HWND hwndOwner, DWORD dwFlags, IEnumIDList* pRegEnumerator)
+        {
+            /* enumerate the folders */
+            if (dwFlags & SHCONTF_FOLDERS)
+            {
+                WCHAR wszDriveName[] = {'A', ':', '\\', '\0'};
+                DWORD dwDrivemap = GetLogicalDrives();
+
+                while (wszDriveName[0] <= 'Z')
+                {
+                    if(dwDrivemap & 0x00000001L)
+                        AddToEnumList(_ILCreateDrive(wszDriveName));
+                    wszDriveName[0]++;
+                    dwDrivemap = dwDrivemap >> 1;
+                }
+            }
+
+            /* Enumerate the items of the reg folder */
+            AppendItemsFromEnumerator(pRegEnumerator);
+
+            return S_OK;
+        }
 
         BEGIN_COM_MAP(CDrivesFolderEnum)
         COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
@@ -200,92 +218,6 @@ static const DWORD dwDriveAttributes =
     SFGAO_HASSUBFOLDER | SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_FILESYSANCESTOR |
     SFGAO_DROPTARGET | SFGAO_HASPROPSHEET | SFGAO_CANRENAME | SFGAO_CANLINK;
 
-CDrivesFolderEnum::CDrivesFolderEnum()
-{
-}
-
-CDrivesFolderEnum::~CDrivesFolderEnum()
-{
-}
-
-HRESULT WINAPI CDrivesFolderEnum::Initialize(HWND hwndOwner, DWORD dwFlags)
-{
-    if (CreateMyCompEnumList(dwFlags) == FALSE)
-        return E_FAIL;
-
-    return S_OK;
-}
-
-/**************************************************************************
- *  CDrivesFolderEnum::CreateMyCompEnumList()
- */
-
-BOOL CDrivesFolderEnum::CreateMyCompEnumList(DWORD dwFlags)
-{
-    BOOL bRet = TRUE;
-    static const WCHAR MyComputer_NameSpaceW[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\Namespace";
-
-    TRACE("(%p)->(flags=0x%08x)\n", this, dwFlags);
-
-    /* enumerate the folders */
-    if (dwFlags & SHCONTF_FOLDERS)
-    {
-        WCHAR wszDriveName[] = {'A', ':', '\\', '\0'};
-        DWORD dwDrivemap = GetLogicalDrives();
-        HKEY hKey;
-        UINT i;
-
-        while (bRet && wszDriveName[0] <= 'Z')
-        {
-            if(dwDrivemap & 0x00000001L)
-                bRet = AddToEnumList(_ILCreateDrive(wszDriveName));
-            wszDriveName[0]++;
-            dwDrivemap = dwDrivemap >> 1;
-        }
-
-        TRACE("-- (%p)-> enumerate (mycomputer shell extensions)\n", this);
-        for (i = 0; i < 2; i++)
-        {
-            if (bRet && ERROR_SUCCESS == RegOpenKeyExW(i == 0 ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
-                    MyComputer_NameSpaceW, 0, KEY_READ, &hKey))
-            {
-                WCHAR wszBuf[50];
-                DWORD dwSize, j = 0;
-                LONG ErrorCode;
-                LPITEMIDLIST pidl;
-
-                while (bRet)
-                {
-                    dwSize = sizeof(wszBuf) / sizeof(wszBuf[0]);
-                    ErrorCode = RegEnumKeyExW(hKey, j, wszBuf, &dwSize, 0, NULL, NULL, NULL);
-                    if (ERROR_SUCCESS == ErrorCode)
-                    {
-                        if (wszBuf[0] != L'{')
-                        {
-                            dwSize = sizeof(wszBuf);
-                            RegGetValueW(hKey, wszBuf, NULL, RRF_RT_REG_SZ, NULL, wszBuf, &dwSize);
-                        }
-
-                        /* FIXME: shell extensions - the type should be PT_SHELLEXT (tested) */
-                        pidl = _ILCreateGuidFromStrW(wszBuf);
-                        if (pidl != NULL)
-                            bRet = AddToEnumList(pidl);
-                        else
-                            ERR("Invalid MyComputer namespace extesion: %s\n", wszBuf);
-                        j++;
-                    }
-                    else if (ERROR_NO_MORE_ITEMS == ErrorCode)
-                        break;
-                    else
-                        bRet = FALSE;
-                }
-                RegCloseKey(hKey);
-            }
-        }
-    }
-    return bRet;
-}
-
 CDrivesFolder::CDrivesFolder()
 {
     pidlRoot = NULL;
@@ -306,6 +238,7 @@ HRESULT WINAPI CDrivesFolder::FinalConstruct()
     HRESULT hr = CRegFolder_CreateInstance(&CLSID_MyComputer, 
                                            pidlRoot, 
                                            L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 
+                                           L"MyComputer",
                                            IID_PPV_ARG(IShellFolder2, &m_regFolder));
 
     return hr;
@@ -376,7 +309,10 @@ HRESULT WINAPI CDrivesFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLEST
 */
 HRESULT WINAPI CDrivesFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
 {
-    return ShellObjectCreatorInit<CDrivesFolderEnum>(hwndOwner, dwFlags, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
+    CComPtr<IEnumIDList> pRegEnumerator;
+    m_regFolder->EnumObjects(hwndOwner, dwFlags, &pRegEnumerator);
+
+    return ShellObjectCreatorInit<CDrivesFolderEnum>(hwndOwner, dwFlags, pRegEnumerator, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
 }
 
 /**************************************************************************
index 92eeee6..fa23312 100644 (file)
@@ -181,6 +181,80 @@ HRESULT CGuidItemExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID iid, LPVO
     return initIcon->QueryInterface(iid, ppvOut);
 }
 
+class CRegFolderEnum :
+    public CEnumIDListBase
+{
+    public:
+        CRegFolderEnum();
+        ~CRegFolderEnum();
+        HRESULT Initialize(LPCWSTR lpszEnumKeyName, DWORD dwFlags);
+        HRESULT AddItemsFromKey(HKEY hkey_root, LPCWSTR szRepPath);
+
+        BEGIN_COM_MAP(CRegFolderEnum)
+        COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
+        END_COM_MAP()
+};
+
+CRegFolderEnum::CRegFolderEnum()
+{
+}
+
+CRegFolderEnum::~CRegFolderEnum()
+{
+}
+
+HRESULT CRegFolderEnum::Initialize(LPCWSTR lpszEnumKeyName, DWORD dwFlags)
+{
+    WCHAR KeyName[MAX_PATH];
+    static const WCHAR KeyNameFormat[] = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\%s\\Namespace";
+
+    if (!(dwFlags & SHCONTF_FOLDERS))
+        return S_OK;
+
+    HRESULT hr = StringCchPrintfW(KeyName, MAX_PATH, KeyNameFormat, lpszEnumKeyName);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    AddItemsFromKey(HKEY_LOCAL_MACHINE, KeyName);
+    AddItemsFromKey(HKEY_CURRENT_USER, KeyName);
+
+    return S_OK;
+}
+
+HRESULT CRegFolderEnum::AddItemsFromKey(HKEY hkey_root, LPCWSTR szRepPath)
+{
+    WCHAR name[MAX_PATH];
+    HKEY hkey;
+
+    if (RegOpenKeyW(hkey_root, szRepPath, &hkey) != ERROR_SUCCESS)
+        return S_FALSE;
+
+    for (int idx = 0; ; idx++)
+    {
+        if (RegEnumKeyW(hkey, idx, name, MAX_PATH) != ERROR_SUCCESS)
+            break;
+
+        /* If the name of the key is not a guid try to get the default value of the key */
+        if (name[0] != L'{')
+        {
+            DWORD dwSize = sizeof(name);
+            RegGetValueW(hkey, name, NULL, RRF_RT_REG_SZ, NULL, name, &dwSize);
+        }
+
+        if (*name == '{')
+        {
+            LPITEMIDLIST pidl = _ILCreateGuidFromStrW(name);
+
+            if (pidl)
+                AddToEnumList(pidl);
+        }
+    }
+
+    RegCloseKey(hkey);
+
+    return S_OK;
+}
+
 class CRegFolder :
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IShellFolder2
@@ -188,13 +262,14 @@ class CRegFolder :
     private:
         GUID m_guid;
         CAtlStringW m_rootPath;
+        CAtlStringW m_enumKeyName;
         CComHeapPtr<ITEMIDLIST> m_pidlRoot;
 
         HRESULT GetGuidItemAttributes (LPCITEMIDLIST pidl, LPDWORD pdwAttributes);
     public:
         CRegFolder();
         ~CRegFolder();
-        HRESULT WINAPI Initialize(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath);
+        HRESULT WINAPI Initialize(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, LPCWSTR lpszEnumKeyName);
 
         // IShellFolder
         virtual HRESULT WINAPI ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, ULONG *pchEaten, PIDLIST_RELATIVE *ppidl, ULONG *pdwAttributes);
@@ -235,7 +310,7 @@ CRegFolder::~CRegFolder()
 {
 }
 
-HRESULT WINAPI CRegFolder::Initialize(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath)
+HRESULT WINAPI CRegFolder::Initialize(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, LPCWSTR lpszEnumKeyName)
 {
     memcpy(&m_guid, pGuid, sizeof(m_guid));
 
@@ -243,6 +318,10 @@ HRESULT WINAPI CRegFolder::Initialize(const GUID *pGuid, LPCITEMIDLIST pidlRoot,
     if (!m_rootPath)
         return E_OUTOFMEMORY;
 
+    m_enumKeyName = lpszEnumKeyName;
+    if (!m_enumKeyName)
+        return E_OUTOFMEMORY;
+
     m_pidlRoot.Attach(ILClone(pidlRoot));
     if (!m_pidlRoot)
         return E_OUTOFMEMORY;
@@ -319,7 +398,7 @@ HRESULT WINAPI CRegFolder::ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR l
 
 HRESULT WINAPI CRegFolder::EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
 {
-    return E_NOTIMPL;
+    return ShellObjectCreatorInit<CRegFolderEnum>(m_enumKeyName, dwFlags, IID_PPV_ARG(IEnumIDList, ppEnumIDList));
 }
 
 HRESULT WINAPI CRegFolder::BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut)
@@ -677,7 +756,7 @@ HRESULT WINAPI CRegFolder::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
 }
 
 /* In latest windows version this is exported but it takes different arguments! */
-HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, REFIID riid, void **ppv)
+HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, LPCWSTR lpszEnumKeyName, REFIID riid, void **ppv)
 {
-    return ShellObjectCreatorInit<CRegFolder>(pGuid, pidlRoot, lpszPath, riid, ppv);
+    return ShellObjectCreatorInit<CRegFolder>(pGuid, pidlRoot, lpszPath, lpszEnumKeyName, riid, ppv);
 }
index a160a53..8e17caf 100644 (file)
@@ -78,7 +78,7 @@ 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, REFIID riid, void **ppv);
+HRESULT CRegFolder_CreateInstance(const GUID *pGuid, LPCITEMIDLIST pidlRoot, LPCWSTR lpszPath, LPCWSTR lpszEnumKeyName, REFIID riid, void **ppv);
 
 /* initialisation for FORMATETC */
 #define InitFormatEtc(fe, cf, med) \