[NTOBJSHEX]
[reactos.git] / reactos / dll / shellext / ntobjshex / regfolder.cpp
index ff78c4d..c9f9c14 100644 (file)
@@ -1,13 +1,13 @@
 /*
  * PROJECT:     ReactOS shell extensions
  * LICENSE:     GPL - See COPYING in the top level directory
- * FILE:        dll\shellext\ntobjshex\ntobjns.cpp
+ * FILE:        dll/shellext/ntobjshex/regfolder.cpp
  * PURPOSE:     NT Object Namespace shell extension
  * PROGRAMMERS: David Quintana <gigaherz@gmail.com>
  */
 
 #include "precomp.h"
-#include "ntobjutil.h"
+#include "ntobjenum.h"
 #include <ntquery.h>
 #include "util.h"
 
@@ -124,215 +124,9 @@ public:
 
 };
 
-class CRegistryPidlManager
+class CRegistryPidlHelper
 {
-private:
-    PWSTR m_ntPath;
-    HKEY m_hRoot;
-
-    HDPA m_hDpa;
-    UINT m_hDpaCount;
-
-    int  DpaDeleteCallback(RegPidlEntry * info)
-    {
-        CoTaskMemFree(info);
-        return 0;
-    }
-
-    static int CALLBACK s_DpaDeleteCallback(void *pItem, void *pData)
-    {
-        CRegistryPidlManager * mf = (CRegistryPidlManager*) pData;
-        RegPidlEntry  * item = (RegPidlEntry*) pItem;
-        return mf->DpaDeleteCallback(item);
-    }
-
 public:
-    CRegistryPidlManager() :
-        m_ntPath(NULL),
-        m_hRoot(NULL),
-        m_hDpa(NULL),
-        m_hDpaCount(0)
-    {
-    }
-
-    ~CRegistryPidlManager()
-    {
-        DPA_DestroyCallback(m_hDpa, s_DpaDeleteCallback, this);
-    }
-
-    HRESULT Initialize(PWSTR ntPath, HKEY hRoot)
-    {
-        m_ntPath = ntPath;
-        m_hRoot = hRoot;
-        m_hDpa = NULL;
-
-        return S_OK;
-    }
-
-    HRESULT Enumerate()
-    {
-        if (m_hDpa)
-            return S_OK;
-
-        m_hDpa = DPA_Create(10);
-
-        if (!m_hDpa)
-            return E_OUTOFMEMORY;
-
-        if (wcslen(m_ntPath) == 0 && m_hRoot == NULL)
-        {
-            HRESULT hr = EnumerateRootKeys(m_hDpa, &m_hDpaCount);
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
-        }
-        else
-        {
-            HRESULT hr = EnumerateRegistryKey(m_hDpa, m_ntPath, m_hRoot, &m_hDpaCount);
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
-        }
-        return S_OK;
-    }
-
-    HRESULT FindPidlInList(PCUITEMID_CHILD pcidl, const RegPidlEntry ** pinfo)
-    {
-        HRESULT hr;
-
-        if (!m_hDpa)
-        {
-            hr = Enumerate();
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
-
-            if (!m_hDpa)
-                return E_FAIL;
-        }
-
-        RegPidlEntry * info = (RegPidlEntry *) pcidl;
-        if ((info->cb < sizeof(RegPidlEntry)) || (info->magic != REGISTRY_PIDL_MAGIC))
-        {
-            ERR("FindPidlInList: Requested pidl is not of the correct type.\n");
-            return E_INVALIDARG;
-        }
-
-        TRACE("Searching for pidl { cb=%d } in a list of %d items\n", pcidl->mkid.cb, m_hDpaCount);
-
-        for (UINT i = 0; i < m_hDpaCount; i++)
-        {
-            RegPidlEntry * pInfo = (RegPidlEntry *) DPA_GetPtr(m_hDpa, i);
-            ASSERT(pInfo);
-
-            hr = CompareIDs(0, pInfo, pcidl);
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
-
-            if (hr == S_OK)
-            {
-                *pinfo = pInfo;
-                return S_OK;
-            }
-            else
-            {
-                TRACE("Comparison returned %d\n", (int) (short) (hr & 0xFFFF));
-            }
-        }
-
-        ERR("PIDL NOT FOUND: Requested filename: %S\n", info->entryName);
-        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
-    }
-
-    HRESULT FindByName(LPCWSTR strParsingName, RegPidlEntry ** pinfo)
-    {
-        HRESULT hr;
-
-        if (!m_hDpa)
-        {
-            hr = Enumerate();
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
-
-            if (!m_hDpa)
-                return E_FAIL;
-        }
-
-
-        TRACE("Searching for '%S' in a list of %d items\n", strParsingName, m_hDpaCount);
-
-        for (int i = 0; i < (int) m_hDpaCount; i++)
-        {
-            RegPidlEntry * pInfo = (RegPidlEntry *) DPA_GetPtr(m_hDpa, i);
-            ASSERT(pInfo);
-
-            int order = CompareStringW(GetThreadLocale(), NORM_IGNORECASE,
-                pInfo->entryName, wcslen(pInfo->entryName),
-                strParsingName, wcslen(strParsingName));
-
-            if (order == CSTR_EQUAL)
-            {
-                *pinfo = pInfo;
-                return S_OK;
-            }
-        }
-
-        TRACE("Pidl not found\n");
-        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
-    }
-
-    HRESULT GetPidl(UINT index, RegPidlEntry ** pEntry)
-    {
-        HRESULT hr;
-
-        if (!m_hDpa)
-        {
-            hr = Enumerate();
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
-
-            if (!m_hDpa)
-                return E_FAIL;
-        }
-
-        *pEntry = NULL;
-
-        RegPidlEntry * entry = (RegPidlEntry *) DPA_GetPtr(m_hDpa, index);
-        if (!entry)
-        {
-            return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
-        }
-
-        *pEntry = entry;
-        return S_OK;
-    }
-
-    HRESULT GetCount(UINT * count)
-    {
-        HRESULT hr;
-
-        if (!m_hDpa)
-        {
-            hr = Enumerate();
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
-
-            if (!m_hDpa)
-                return E_FAIL;
-        }
-
-        *count = m_hDpaCount;
-        return S_OK;
-    }
-
-
-    static LPITEMIDLIST CreatePidlFromItem(const RegPidlEntry * entry)
-    {
-        LPITEMIDLIST idl = (LPITEMIDLIST) CoTaskMemAlloc(entry->cb + 2);
-        if (!idl)
-            return NULL;
-        memset(idl, 0, entry->cb + 2);
-        memcpy(idl, entry, entry->cb);
-        return idl;
-    }
-
     static HRESULT CompareIDs(LPARAM lParam, const RegPidlEntry * first, const RegPidlEntry * second)
     {
         if ((lParam & 0xFFFF0000) == SHCIDS_ALLFIELDS)
@@ -374,23 +168,33 @@ public:
                         return MAKE_HRESULT(0, 0, (USHORT) 1);
                     if (second->entryNameLength < first->entryNameLength)
                         return MAKE_HRESULT(0, 0, (USHORT) -1);
-                }
-
-                int minlength = min(first->entryNameLength, second->entryNameLength);
-                int ord = StrCmpNW(first->entryName, second->entryName, minlength);
-
-                if (ord != 0)
-                    return MAKE_HRESULT(0, 0, (USHORT) ord);
 
-                if (!canonical)
+                    int minlength = min(first->entryNameLength, second->entryNameLength);
+                    if (minlength > 0)
+                    {
+                        int ord = memcmp(first->entryName, second->entryName, minlength);
+                        if (ord != 0)
+                            return MAKE_HRESULT(0, 0, (USHORT) ord);
+                    }
+                    return S_OK;
+                }
+                else
                 {
+                    int minlength = min(first->entryNameLength, second->entryNameLength);
+                    if (minlength > 0)
+                    {
+                        int ord = StrCmpNW(first->entryName, second->entryName, minlength / sizeof(WCHAR));
+                        if (ord != 0)
+                            return MAKE_HRESULT(0, 0, (USHORT) ord);
+                    }
+
                     if (second->entryNameLength > first->entryNameLength)
                         return MAKE_HRESULT(0, 0, (USHORT) 1);
                     if (second->entryNameLength < first->entryNameLength)
                         return MAKE_HRESULT(0, 0, (USHORT) -1);
-                }
 
-                return S_OK;
+                    return S_OK;
+                }
             }
             case REGISTRY_COLUMN_TYPE:
             {
@@ -450,17 +254,36 @@ public:
         return flags & mask;
     }
 
-    BOOL IsFolder(LPCITEMIDLIST pcidl)
+    static BOOL IsFolder(LPCITEMIDLIST pcidl)
     {
-        const RegPidlEntry * entry;
-        HRESULT hr = FindPidlInList(pcidl, &entry);
-        if (FAILED_UNEXPECTEDLY(hr))
+        RegPidlEntry * entry = (RegPidlEntry*) &(pcidl->mkid);
+        if ((entry->cb < sizeof(RegPidlEntry)) || (entry->magic != REGISTRY_PIDL_MAGIC))
             return FALSE;
 
         return (entry->entryType == REG_ENTRY_KEY) ||
             (entry->entryType == REG_ENTRY_ROOT);
     }
 
+    static HRESULT GetInfoFromPidl(LPCITEMIDLIST pcidl, const RegPidlEntry ** pentry)
+    {
+        RegPidlEntry * entry = (RegPidlEntry*) &(pcidl->mkid);
+
+        if (entry->cb < sizeof(RegPidlEntry))
+        {
+            DbgPrint("PCIDL too small %l (required %l)\n", entry->cb, sizeof(RegPidlEntry));
+            return E_INVALIDARG;
+        }
+
+        if (entry->magic != REGISTRY_PIDL_MAGIC)
+        {
+            DbgPrint("PCIDL magic mismatch %04x (expected %04x)\n", entry->magic, REGISTRY_PIDL_MAGIC);
+            return E_INVALIDARG;
+        }
+
+        *pentry = entry;
+        return S_OK;
+    }
+
     static HRESULT FormatValueData(DWORD contentType, PVOID td, DWORD contentsLength, PCWSTR * strContents)
     {
         switch (contentType)
@@ -482,6 +305,40 @@ public:
             *strContents = strValue;
             return S_OK;
         }
+        case REG_MULTI_SZ:
+        {
+            PCWSTR separator = L" "; // To match regedit
+            int sepChars = wcslen(separator);
+            int strings = 0;
+            int stringChars = 0;
+
+            PCWSTR strData = (PCWSTR)td;
+            while (*strData)
+            {
+                int l = wcslen(strData);
+                stringChars += l;
+                strData += l + 1; // Skips null-terminator
+                strings++;
+            }
+
+            int cch = stringChars + (strings - 1) * sepChars + 1;
+
+            PWSTR strValue = (PWSTR)CoTaskMemAlloc(cch * sizeof(WCHAR));
+
+            strValue[0] = 0;
+
+            strData = (PCWSTR)td;
+            while (*strData)
+            {
+                StrCatW(strValue, strData);
+                strData += wcslen(strData) + 1;
+                if (*strData)
+                    StrCatW(strValue, separator);
+            }
+
+            *strContents = strValue;
+            return S_OK;
+        }
         case REG_DWORD:
         {
             DWORD bufferLength = 64 * sizeof(WCHAR);
@@ -495,24 +352,39 @@ public:
         {
             DWORD bufferLength = 64 * sizeof(WCHAR);
             PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
-            StringCbPrintfW(strValue, bufferLength, L"0x%016llx (%d)",
+            StringCbPrintfW(strValue, bufferLength, L"0x%016llx (%lld)",
                 *(LARGE_INTEGER*) td, ((LARGE_INTEGER*) td)->QuadPart);
             *strContents = strValue;
             return S_OK;
         }
+        case REG_BINARY:
+        {
+            DWORD bufferLength = (contentsLength * 3 + 1) * sizeof(WCHAR);
+            PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
+            PWSTR strTemp = strValue;
+            PBYTE data = (PBYTE)td;
+            for (int i = 0; i < contentsLength; i++)
+            {
+                StringCbPrintfW(strTemp, bufferLength, L"%02x ", data[i]);
+                strTemp += 3;
+                bufferLength -= 3;
+            }
+            *strContents = strValue;
+            return S_OK;
+        }
         default:
         {
-            PCWSTR strTodo = L"<TODO: Convert value for display>";
-            DWORD bufferLength = (wcslen(strTodo) + 1) * sizeof(WCHAR);
+            PCWSTR strFormat = L"<Unimplemented value type %d>";
+            DWORD bufferLength = (wcslen(strFormat) + 15) * sizeof(WCHAR);
             PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
-            StringCbCopyW(strValue, bufferLength, strTodo);
+            StringCbPrintfW(strValue, bufferLength, strFormat, contentType);
             *strContents = strValue;
             return S_OK;
         }
         }
     }
 
-    HRESULT FormatContentsForDisplay(const RegPidlEntry * info, PCWSTR * strContents)
+    static HRESULT FormatContentsForDisplay(const RegPidlEntry * info, HKEY rootKey, LPCWSTR ntPath, PCWSTR * strContents)
     {
         PVOID td = (((PBYTE) info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
 
@@ -527,7 +399,7 @@ public:
         {
             PVOID valueData;
             DWORD valueLength;
-            HRESULT hr = ReadRegistryValue(NULL, m_ntPath, info->entryName, &valueData, &valueLength);
+            HRESULT hr = ReadRegistryValue(rootKey, ntPath, info->entryName, &valueData, &valueLength);
             if (FAILED_UNEXPECTEDLY(hr))
             {
                 PCWSTR strEmpty = L"(Error reading value)";
@@ -566,126 +438,10 @@ public:
     }
 };
 
-class CRegistryFolderEnum :
-    public CComObjectRootEx<CComMultiThreadModelNoCS>,
-    public IEnumIDList
-{
-private:
-    CComPtr<CRegistryFolder> m_Folder;
-
-    HWND m_HwndOwner;
-    SHCONTF m_Flags;
-
-    UINT m_Index;
-    UINT m_Count;
-
-public:
-    CRegistryFolderEnum() :
-        m_HwndOwner(NULL),
-        m_Flags(0),
-        m_Index(0),
-        m_Count(0)
-    {
-    }
-
-    virtual ~CRegistryFolderEnum()
-    {
-    }
-
-    HRESULT Initialize(CRegistryFolder * folder, HWND hwndOwner, SHCONTF flags)
-    {
-        m_Folder = folder;
-
-        m_Folder->GetManager().GetCount(&m_Count);
-
-        m_HwndOwner = hwndOwner;
-        m_Flags = flags;
-
-        return Reset();
-    }
-
-    virtual HRESULT STDMETHODCALLTYPE Next(
-        ULONG celt,
-        LPITEMIDLIST *rgelt,
-        ULONG *pceltFetched)
-    {
-        if (pceltFetched)
-            *pceltFetched = 0;
-
-        if (m_Index >= m_Count)
-            return S_FALSE;
-
-        for (int i = 0; i < (int) celt;)
-        {
-            RegPidlEntry * tinfo;
-            BOOL flagsOk = FALSE;
-
-            do {
-                HRESULT hr = m_Folder->GetManager().GetPidl(m_Index++, &tinfo);
-                if (FAILED_UNEXPECTEDLY(hr))
-                    return hr;
-
-                switch (tinfo->entryType)
-                {
-                case REG_ENTRY_KEY:
-                case REG_ENTRY_ROOT:
-                    flagsOk = (m_Flags & SHCONTF_FOLDERS) != 0;
-                    break;
-                default:
-                    flagsOk = (m_Flags & SHCONTF_NONFOLDERS) != 0;
-                    break;
-                }
-            } while (m_Index < m_Count && !flagsOk);
-
-            if (flagsOk)
-            {
-                if (rgelt)
-                    rgelt[i] = m_Folder->GetManager().CreatePidlFromItem(tinfo);
-                i++;
-            }
-
-            if (m_Index == m_Count)
-            {
-                if (pceltFetched)
-                    *pceltFetched = i;
-                return (i == (int) celt) ? S_OK : S_FALSE;
-            }
-        }
-
-        if (pceltFetched) *pceltFetched = celt;
-        return S_OK;
-    }
-
-    virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
-    {
-        return Next(celt, NULL, NULL);
-    }
-
-    virtual HRESULT STDMETHODCALLTYPE Reset()
-    {
-        m_Index = 0;
-        return S_OK;
-    }
-
-    virtual HRESULT STDMETHODCALLTYPE Clone(IEnumIDList **ppenum)
-    {
-        return ShellObjectCreatorInit<CRegistryFolderEnum>(m_Folder, m_HwndOwner, m_Flags, IID_PPV_ARG(IEnumIDList, ppenum));
-    }
-
-    DECLARE_NOT_AGGREGATABLE(CRegistryFolderEnum)
-    DECLARE_PROTECT_FINAL_CONSTRUCT()
-
-    BEGIN_COM_MAP(CRegistryFolderEnum)
-        COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
-    END_COM_MAP()
-
-};
-
 //-----------------------------------------------------------------------------
 // CRegistryFolder
 
 CRegistryFolder::CRegistryFolder() :
-    m_PidlManager(NULL),
     m_shellPidl(NULL)
 {
 }
@@ -694,8 +450,6 @@ CRegistryFolder::~CRegistryFolder()
 {
     if (m_shellPidl)
         ILFree(m_shellPidl);
-    if (m_PidlManager)
-        delete m_PidlManager;
 }
 
 // IShellFolder
@@ -707,9 +461,6 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::ParseDisplayName(
     LPITEMIDLIST *ppidl,
     ULONG *pdwAttributes)
 {
-    HRESULT hr;
-    RegPidlEntry * info;
-
     if (!ppidl)
         return E_POINTER;
 
@@ -721,19 +472,45 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::ParseDisplayName(
 
     TRACE("CRegistryFolder::ParseDisplayName name=%S (ntPath=%S)\n", lpszDisplayName, m_NtPath);
 
-    hr = m_PidlManager->FindByName(lpszDisplayName, &info);
+    const RegPidlEntry * info;
+    IEnumIDList * it;
+    HRESULT hr = GetEnumNTDirectory(m_NtPath, &it);
     if (FAILED(hr))
     {
         return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
     }
 
-    *ppidl = m_PidlManager->CreatePidlFromItem(info);
+    while (TRUE)
+    {
+        hr = it->Next(1, ppidl, NULL);
 
-    if (pchEaten)
-        *pchEaten = wcslen(info->entryName);
+        if (FAILED(hr))
+            return hr;
 
-    if (pdwAttributes)
-        *pdwAttributes = m_PidlManager->ConvertAttributes(info, pdwAttributes);
+        if (hr != S_OK)
+            break;
+
+        hr = CRegistryPidlHelper::GetInfoFromPidl(*ppidl, &info);
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+
+        if (StrCmpW(info->entryName, lpszDisplayName) == 0)
+            break;
+    }
+
+    if (hr != S_OK)
+    {
+        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+    }
+
+    if (pchEaten || pdwAttributes)
+    {
+        if (pchEaten)
+            *pchEaten = wcslen(info->entryName);
+
+        if (pdwAttributes)
+            *pdwAttributes = CRegistryPidlHelper::ConvertAttributes(info, pdwAttributes);
+    }
 
     return S_OK;
 }
@@ -743,7 +520,14 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::EnumObjects(
     SHCONTF grfFlags,
     IEnumIDList **ppenumIDList)
 {
-    return ShellObjectCreatorInit<CRegistryFolderEnum>(this, hwndOwner, grfFlags, IID_PPV_ARG(IEnumIDList, ppenumIDList));
+    if (m_NtPath[0] == 0 && m_hRoot == NULL)
+    {
+        return GetEnumRegistryRoot(ppenumIDList);
+    }
+    else
+    {
+        return GetEnumRegistryKey(m_NtPath, m_hRoot, ppenumIDList);
+    }
 }
 
 HRESULT STDMETHODCALLTYPE CRegistryFolder::BindToObject(
@@ -753,11 +537,10 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::BindToObject(
     void **ppvOut)
 {
     const RegPidlEntry * info;
-    HRESULT hr;
 
     if (IsEqualIID(riid, IID_IShellFolder))
     {
-        hr = m_PidlManager->FindPidlInList(pidl, &info);
+        HRESULT hr = CRegistryPidlHelper::GetInfoFromPidl(pidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
 
@@ -813,7 +596,7 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::CompareIDs(
 {
     TRACE("CompareIDs\n");
 
-    HRESULT hr = m_PidlManager->CompareIDs(lParam, pidl1, pidl2);
+    HRESULT hr = CRegistryPidlHelper::CompareIDs(lParam, pidl1, pidl2);
     if (hr != S_OK)
         return hr;
 
@@ -880,18 +663,12 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetAttributesOf(
     {
         PCUITEMID_CHILD pidl = apidl[i];
 
-#ifndef DISABLE_STRICT_PIDL_CHECK
-        HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+        HRESULT hr = CRegistryPidlHelper::GetInfoFromPidl(pidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
-#else
-        info = (const RegPidlEntry *) pidl;
-        if (info->magic != REGISTRY_PIDL_MAGIC)
-            return E_INVALIDARG;
-#endif
 
         // Update attributes.
-        *rgfInOut = m_PidlManager->ConvertAttributes(info, rgfInOut);
+        *rgfInOut = CRegistryPidlHelper::ConvertAttributes(info, rgfInOut);
     }
 
     return S_OK;
@@ -913,12 +690,15 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetUIObjectOf(
     {
         CComPtr<IContextMenu> pcm;
 
-        HKEY keys [1];
+        DWORD res;
+        HKEY keys[1];
 
         int nkeys = _countof(keys);
-        if (cidl == 1 && m_PidlManager->IsFolder(apidl[0]))
+        if (cidl == 1 && CRegistryPidlHelper::IsFolder(apidl[0]))
         {
-            RegOpenKey(HKEY_CLASSES_ROOT, L"Folder", keys + 0);
+            res = RegOpenKey(HKEY_CLASSES_ROOT, L"Folder", keys + 0);
+            if (!NT_SUCCESS(res))
+                return HRESULT_FROM_NT(res);
         }
         else
         {
@@ -944,7 +724,7 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetUIObjectOf(
 
     if (IsEqualIID(riid, IID_IQueryAssociations))
     {
-        if (cidl == 1 && m_PidlManager->IsFolder(apidl[0]))
+        if (cidl == 1 && CRegistryPidlHelper::IsFolder(apidl[0]))
         {
             CComPtr<IQueryAssociations> pqa;
             HRESULT hr = AssocCreate(CLSID_QueryAssociations, IID_PPV_ARG(IQueryAssociations, &pqa));
@@ -968,66 +748,64 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDisplayNameOf(
     STRRET *lpName)
 {
     const RegPidlEntry * info;
-    HRESULT hr;
 
     TRACE("GetDisplayNameOf %p\n", pidl);
 
-#ifndef DISABLE_STRICT_PIDL_CHECK
-    hr = m_PidlManager->FindPidlInList(pidl, &info);
+    HRESULT hr = CRegistryPidlHelper::GetInfoFromPidl(pidl, &info);
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
-#else
-    info = (const RegPidlEntry *) pidl;
-    if (info->magic != REGISTRY_PIDL_MAGIC)
-        return E_INVALIDARG;
-#endif
 
-    if ((GET_SHGDN_RELATION(uFlags) == SHGDN_NORMAL) &&
-        (GET_SHGDN_FOR(uFlags) & SHGDN_FORPARSING))
+    if (GET_SHGDN_FOR(uFlags) & SHGDN_FOREDITING)
     {
-        WCHAR path[MAX_PATH] = { 0 };
-
-        hr = GetFullName(m_shellPidl, uFlags, path, _countof(path));
-        if (FAILED_UNEXPECTEDLY(hr))
-            return hr;
-
-        PathAppendW(path, info->entryName);
-
-        hr = MakeStrRetFromString(path, lpName);
+        hr = MakeStrRetFromString(info->entryName, info->entryNameLength, lpName);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
+    }
 
-        LPCITEMIDLIST pidlFirst = ILCloneFirst(pidl);
-        LPCITEMIDLIST pidlNext = ILGetNext(pidl);
+    WCHAR path[MAX_PATH] = { 0 };
 
-        if (pidlNext && pidlNext->mkid.cb > 0)
+    if (GET_SHGDN_FOR(uFlags) & SHGDN_FORPARSING)
+    {
+        if (GET_SHGDN_RELATION(uFlags) != SHGDN_INFOLDER)
         {
-            CComPtr<IShellFolder> psfChild;
-            hr = BindToObject(pidlFirst, NULL, IID_PPV_ARG(IShellFolder, &psfChild));
+            hr = GetFullName(m_shellPidl, uFlags, path, _countof(path));
             if (FAILED_UNEXPECTEDLY(hr))
                 return hr;
+        }
+    }
 
-            WCHAR temp[MAX_PATH];
-            STRRET childName;
+    PathAppendW(path, info->entryName);
 
-            hr = psfChild->GetDisplayNameOf(pidlNext, uFlags | SHGDN_INFOLDER, &childName);
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
+    LPCITEMIDLIST pidlNext = ILGetNext(pidl);
+    if (pidlNext && pidlNext->mkid.cb > 0)
+    {
+        LPITEMIDLIST pidlFirst = ILCloneFirst(pidl);
 
-            hr = StrRetToBufW(&childName, pidlNext, temp, _countof(temp));
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
+        CComPtr<IShellFolder> psfChild;
+        hr = BindToObject(pidlFirst, NULL, IID_PPV_ARG(IShellFolder, &psfChild));
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
 
-            PathAppendW(path, temp);
-        }
+        WCHAR temp[MAX_PATH];
+        STRRET childName;
 
-        ILFree((LPITEMIDLIST) pidlFirst);
-    }
-    else
-    {
-        MakeStrRetFromString(info->entryName, info->entryNameLength, lpName);
+        hr = psfChild->GetDisplayNameOf(pidlNext, uFlags | SHGDN_INFOLDER, &childName);
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+
+        hr = StrRetToBufW(&childName, pidlNext, temp, _countof(temp));
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
+
+        PathAppendW(path, temp);
+
+        ILFree(pidlFirst);
     }
 
+    hr = MakeStrRetFromString(path, lpName);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
     return S_OK;
 }
 
@@ -1058,16 +836,8 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::Initialize(LPCITEMIDLIST pidl)
     m_shellPidl = ILClone(pidl);
     m_hRoot = NULL;
 
-    PCWSTR ntPath = L"";
-
-    if (!m_PidlManager)
-    {
-        m_PidlManager = new CRegistryPidlManager();
-
-        StringCbCopy(m_NtPath, _countof(m_NtPath), ntPath);
-    }
-
-    return m_PidlManager->Initialize(m_NtPath, m_hRoot);
+    StringCbCopy(m_NtPath, _countof(m_NtPath), L"");
+    return S_OK;
 }
 
 // Internal
@@ -1076,11 +846,8 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::Initialize(LPCITEMIDLIST pidl, PCWSTR
     m_shellPidl = ILClone(pidl);
     m_hRoot = hRoot;
 
-    if (!m_PidlManager)
-        m_PidlManager = new CRegistryPidlManager();
-
     StringCbCopy(m_NtPath, _countof(m_NtPath), ntPath);
-    return m_PidlManager->Initialize(m_NtPath, m_hRoot);
+    return S_OK;
 }
 
 // IPersistFolder2
@@ -1146,21 +913,14 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsEx(
     VARIANT *pv)
 {
     const RegPidlEntry * info;
-    HRESULT hr;
 
     TRACE("GetDetailsEx\n");
 
     if (pidl)
     {
-#ifndef DISABLE_STRICT_PIDL_CHECK
-        hr = m_PidlManager->FindPidlInList(pidl, &info);
+        HRESULT hr = CRegistryPidlHelper::GetInfoFromPidl(pidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
-#else
-        info = (const RegPidlEntry *) pidl;
-        if (info->magic != REGISTRY_PIDL_MAGIC)
-            return E_INVALIDARG;
-#endif
 
         static const GUID storage = PSGUID_STORAGE;
         if (IsEqualGUID(pscid->fmtid, storage))
@@ -1184,7 +944,7 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsEx(
                 {
                     if (info->contentsLength > 0)
                     {
-                        PWSTR td = (PWSTR)(((PBYTE) info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
+                        PWSTR td = (PWSTR) (((PBYTE) info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
 
                         return MakeVariantString(pv, td);
                     }
@@ -1197,7 +957,7 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsEx(
             {
                 PCWSTR strValueContents;
 
-                hr = m_PidlManager->FormatContentsForDisplay(info, &strValueContents);
+                hr = CRegistryPidlHelper::FormatContentsForDisplay(info, m_hRoot, m_NtPath, &strValueContents);
                 if (FAILED_UNEXPECTEDLY(hr))
                     return hr;
 
@@ -1226,21 +986,14 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsOf(
     SHELLDETAILS *psd)
 {
     const RegPidlEntry * info;
-    HRESULT hr;
 
     TRACE("GetDetailsOf\n");
 
     if (pidl)
     {
-#ifndef DISABLE_STRICT_PIDL_CHECK
-        hr = m_PidlManager->FindPidlInList(pidl, &info);
+        HRESULT hr = CRegistryPidlHelper::GetInfoFromPidl(pidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
-#else
-        info = (const RegPidlEntry *) pidl;
-        if (info->magic != REGISTRY_PIDL_MAGIC)
-            return E_INVALIDARG;
-#endif
 
         switch (iColumn)
         {
@@ -1280,7 +1033,7 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsOf(
 
             PCWSTR strValueContents;
 
-            hr = m_PidlManager->FormatContentsForDisplay(info, &strValueContents);
+            hr = CRegistryPidlHelper::FormatContentsForDisplay(info, m_hRoot, m_NtPath, &strValueContents);
             if (FAILED_UNEXPECTEDLY(hr))
                 return hr;
 
@@ -1364,8 +1117,6 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::MessageSFVCB(UINT uMsg, WPARAM wParam
         return S_FALSE;
     case SFVM_BACKGROUNDENUM:
         return S_OK;
-    case SFVM_DEFITEMCOUNT:
-        return m_PidlManager->GetCount((UINT*) lParam);
     }
     return E_NOTIMPL;
 }