Author: dquintana
Date: Fri Aug 21 14:26:25 2015
New Revision: 68783
URL: 
http://svn.reactos.org/svn/reactos?rev=68783&view=rev
Log:
[NTOBJSHEX]
* Use lazy enumeration of the nt objects and registry keys, as intended for the
IEnumIDList interface.
* Display of the NT Object creation date has been lost in the process, but it was only
really used by symlinks.
* Symlink target display doesn't appear to work at the moment, will fix later.
Modified:
    trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp
    trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp
    trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h
    trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp
Modified: trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp    [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp    [iso-8859-1] Fri Aug 21 14:26:25
2015
@@ -34,7 +34,6 @@
 {
     NTOBJECT_COLUMN_NAME = 0,
     NTOBJECT_COLUMN_TYPE,
-    NTOBJECT_COLUMN_CREATEDATE,
     NTOBJECT_COLUMN_LINKTARGET,
     NTOBJECT_COLUMN_END
 };
@@ -43,28 +42,25 @@
     public CComObjectRootEx<CComMultiThreadModelNoCS>,
     public IExtractIconW
 {
-    PCIDLIST_ABSOLUTE m_pcidlFolder;
-    PCITEMID_CHILD    m_pcidlChild;
+    PCITEMID_CHILD m_pcidlChild;
+    LPCWSTR m_NtPath;
 public:
     CNtObjectFolderExtractIcon() :
-        m_pcidlFolder(NULL),
-        m_pcidlChild(NULL)
+        m_pcidlChild(NULL), m_NtPath(NULL)
     {
     }
     virtual ~CNtObjectFolderExtractIcon()
     {
-        if (m_pcidlFolder)
-            ILFree((LPITEMIDLIST) m_pcidlFolder);
         if (m_pcidlChild)
             ILFree((LPITEMIDLIST) m_pcidlChild);
     }
-    HRESULT Initialize(PCIDLIST_ABSOLUTE parent, UINT cidl, PCUITEMID_CHILD_ARRAY apidl)
-    {
-        m_pcidlFolder = ILClone(parent);
+    HRESULT Initialize(LPCWSTR ntPath, UINT cidl, PCUITEMID_CHILD_ARRAY apidl)
+    {
+        m_NtPath = ntPath;
         if (cidl != 1)
             return E_INVALIDARG;
         m_pcidlChild = ILClone(apidl[0]);
@@ -85,11 +81,6 @@
         UINT flags = 0;
-#define GIL_CHECKSHIELD 0x0200
-#define GIL_SHIELD 0x0200
-        if (uFlags & GIL_CHECKSHIELD &&
!(entry->objectInformation.GrantedAccess & STANDARD_RIGHTS_READ))
-            flags |= GIL_SHIELD;
-
         switch (entry->objectType)
         {
         case DIRECTORY_OBJECT:
@@ -145,193 +136,21 @@
 private:
     PWSTR m_ntPath;
-    HDPA m_hDpa;
-    UINT m_hDpaCount;
-
-    int  DpaDeleteCallback(NtPidlEntry * info)
-    {
-        CoTaskMemFree(info);
-        return 0;
-    }
-
-    static int CALLBACK s_DpaDeleteCallback(void *pItem, void *pData)
-    {
-        CNtObjectPidlManager * mf = (CNtObjectPidlManager*) pData;
-        NtPidlEntry  * item = (NtPidlEntry*) pItem;
-        return mf->DpaDeleteCallback(item);
-    }
-
 public:
     CNtObjectPidlManager() :
-        m_ntPath(NULL),
-        m_hDpa(NULL),
-        m_hDpaCount(0)
+        m_ntPath(NULL)
     {
     }
     ~CNtObjectPidlManager()
     {
-        DPA_DestroyCallback(m_hDpa, s_DpaDeleteCallback, this);
     }
     HRESULT Initialize(PWSTR ntPath)
     {
         m_ntPath = ntPath;
-        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;
-
-        HRESULT hr = EnumerateNtDirectory(m_hDpa, m_ntPath, &m_hDpaCount);
-        if (FAILED_UNEXPECTEDLY(hr))
-            return hr;
-
-        return S_OK;
-    }
-
-    HRESULT FindPidlInList(PCUITEMID_CHILD pcidl, const NtPidlEntry ** pinfo)
-    {
-        HRESULT hr;
-
-        if (!m_hDpa)
-        {
-            hr = Enumerate();
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
-
-            if (!m_hDpa)
-                return E_FAIL;
-        }
-
-        const NtPidlEntry * info = (const NtPidlEntry *) pcidl;
-        if ((info->cb < sizeof(NtPidlEntry)) || (info->magic !=
NT_OBJECT_PIDL_MAGIC))
-        {
-            ERR("FindPidlInList: Requested pidl is not of the correct
type.\n");
-            return E_INVALIDARG;
-        }
-
-        TRACE("Searching for pidl { name='%S' } in a list of %d
items\n", info->entryName, m_hDpaCount);
-
-        for (UINT i = 0; i < m_hDpaCount; i++)
-        {
-            const NtPidlEntry * pInfo = (const NtPidlEntry *) DPA_GetPtr(m_hDpa, i);
-            ASSERT(pInfo);
-
-            hr = CompareIDs(SHCIDS_CANONICALONLY, pInfo, info);
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
-
-            if (hr == S_OK)
-            {
-                *pinfo = pInfo;
-                return S_OK;
-            }
-            else
-            {
-                TRACE("Comparison returned %d for '%S'\n", (int)
(short) (hr & 0xFFFF), pInfo->entryName);
-            }
-        }
-
-        ERR("PIDL NOT FOUND: Requested filename: %S\n", info->entryName);
-        *pinfo = NULL;
-
-        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
-    }
-
-    HRESULT FindByName(LPCWSTR strParsingName, NtPidlEntry ** 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++)
-        {
-            NtPidlEntry * pInfo = (NtPidlEntry *) 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, NtPidlEntry ** pEntry)
-    {
-        if (!m_hDpa)
-        {
-            HRESULT hr = Enumerate();
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
-
-            if (!m_hDpa)
-                return E_FAIL;
-        }
-
-        *pEntry = NULL;
-
-        NtPidlEntry * entry = (NtPidlEntry *) DPA_GetPtr(m_hDpa, index);
-        if (!entry)
-        {
-            return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
-        }
-
-        *pEntry = entry;
-        return S_OK;
-    }
-
-    HRESULT GetCount(UINT * count)
-    {
-        if (!m_hDpa)
-        {
-            HRESULT hr = Enumerate();
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
-
-            if (!m_hDpa)
-                return E_FAIL;
-        }
-
-        *count = m_hDpaCount;
-        return S_OK;
-    }
-
-    static LPITEMIDLIST CreatePidlFromItem(const NtPidlEntry * 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;
+
+        return S_OK;
     }
     static HRESULT CompareIDs(LPARAM lParam, const NtPidlEntry * first, const NtPidlEntry
* second)
@@ -413,16 +232,6 @@
                 return S_OK;
             }
-            case NTOBJECT_COLUMN_CREATEDATE:
-            {
-                LONGLONG ord = second->objectInformation.CreateTime.QuadPart -
first->objectInformation.CreateTime.QuadPart;
-                if (ord > 0)
-                    return MAKE_HRESULT(0, 0, (USHORT) 1);
-                if (ord < 0)
-                    return MAKE_HRESULT(0, 0, (USHORT) -1);
-
-                return S_OK;
-            }
             case NTOBJECT_COLUMN_LINKTARGET:
             {
                 // Can't sort by value
@@ -478,131 +287,34 @@
     BOOL IsFolder(LPCITEMIDLIST pcidl)
     {
-        const NtPidlEntry * entry;
-        HRESULT hr = FindPidlInList(pcidl, &entry);
-        if (FAILED_UNEXPECTEDLY(hr))
+        NtPidlEntry * entry = (NtPidlEntry*) &(pcidl->mkid);
+        if ((entry->cb < sizeof(NtPidlEntry)) || (entry->magic !=
NT_OBJECT_PIDL_MAGIC))
             return FALSE;
         return (entry->objectType == DIRECTORY_OBJECT) ||
             (entry->objectType == SYMBOLICLINK_OBJECT) ||
             (entry->objectType == KEY_OBJECT);
     }
-};
-
-class CNtObjectFolderEnum :
-    public CComObjectRootEx<CComMultiThreadModelNoCS>,
-    public IEnumIDList
-{
-private:
-    CComPtr<CNtObjectFolder> m_Folder;
-
-    HWND m_HwndOwner;
-    SHCONTF m_Flags;
-
-    UINT m_Index;
-    UINT m_Count;
-
-public:
-    CNtObjectFolderEnum() :
-        m_HwndOwner(NULL),
-        m_Flags(0),
-        m_Index(0),
-        m_Count(0)
-    {
-    }
-
-    virtual ~CNtObjectFolderEnum()
-    {
-    }
-
-    HRESULT Initialize(CNtObjectFolder * 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;)
-        {
-            NtPidlEntry * tinfo;
-            BOOL flagsOk = FALSE;
-
-            do {
-                HRESULT hr = m_Folder->GetManager().GetPidl(m_Index++, &tinfo);
-                if (FAILED_UNEXPECTEDLY(hr))
-                    return hr;
-
-                switch (tinfo->objectType)
-                {
-                case SYMBOLICLINK_OBJECT:
-                case DIRECTORY_OBJECT:
-                case KEY_OBJECT:
-                    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<CNtObjectFolderEnum>(m_Folder, m_HwndOwner,
m_Flags, IID_PPV_ARG(IEnumIDList, ppenum));
-    }
-
-    DECLARE_NOT_AGGREGATABLE(CNtObjectFolderEnum)
-    DECLARE_PROTECT_FINAL_CONSTRUCT()
-
-    BEGIN_COM_MAP(CNtObjectFolderEnum)
-        COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
-    END_COM_MAP()
-
+
+    virtual HRESULT GetInfoFromPidl(LPCITEMIDLIST pcidl, const NtPidlEntry ** pentry)
+    {
+        NtPidlEntry * entry = (NtPidlEntry*) &(pcidl->mkid);
+
+        if (entry->cb < sizeof(NtPidlEntry))
+        {
+            DbgPrint("PCIDL too small %l (required %l)\n", entry->cb,
sizeof(NtPidlEntry));
+            return E_INVALIDARG;
+        }
+
+        if (entry->magic != NT_OBJECT_PIDL_MAGIC)
+        {
+            DbgPrint("PCIDL magic mismatch %04x (expected %04x)\n",
entry->magic, NT_OBJECT_PIDL_MAGIC);
+            return E_INVALIDARG;
+        }
+
+        *pentry = entry;
+        return S_OK;
+    }
 };
 //-----------------------------------------------------------------------------
@@ -631,8 +343,6 @@
     LPITEMIDLIST *ppidl,
     ULONG *pdwAttributes)
 {
-    NtPidlEntry * info;
-
     if (!ppidl)
         return E_POINTER;
@@ -644,19 +354,43 @@
     TRACE("CNtObjectFolder::ParseDisplayName name=%S (ntPath=%S)\n",
lpszDisplayName, m_NtPath);
-    HRESULT hr = m_PidlManager->FindByName(lpszDisplayName, &info);
+    const NtPidlEntry * info;
+    IEnumIDList * it;
+    HRESULT hr = GetEnumNTDirectory(m_NtPath, &it);
     if (FAILED(hr))
+        return hr;
+
+    while (TRUE)
+    {
+        hr = it->Next(1, ppidl, NULL);
+
+        if (FAILED(hr))
+            return hr;
+
+        if (hr != S_OK)
+            break;
+
+        hr = m_PidlManager->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);
     }
-    *ppidl = m_PidlManager->CreatePidlFromItem(info);
-
-    if (pchEaten)
-        *pchEaten = wcslen(info->entryName);
-
-    if (pdwAttributes)
-        *pdwAttributes = m_PidlManager->ConvertAttributes(info, pdwAttributes);
+    if (pchEaten || pdwAttributes)
+    {
+        if (pchEaten)
+            *pchEaten = wcslen(info->entryName);
+
+        if (pdwAttributes)
+            *pdwAttributes = m_PidlManager->ConvertAttributes(info, pdwAttributes);
+    }
     return S_OK;
 }
@@ -666,7 +400,7 @@
     SHCONTF grfFlags,
     IEnumIDList **ppenumIDList)
 {
-    return ShellObjectCreatorInit<CNtObjectFolderEnum>(this, hwndOwner, grfFlags,
IID_PPV_ARG(IEnumIDList, ppenumIDList));
+    return GetEnumNTDirectory(m_NtPath, ppenumIDList);
 }
 HRESULT STDMETHODCALLTYPE CNtObjectFolder::BindToObject(
@@ -679,13 +413,10 @@
     if (IsEqualIID(riid, IID_IShellFolder))
     {
-        HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+        HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
-        if (!(info->objectInformation.GrantedAccess & (STANDARD_RIGHTS_READ |
FILE_LIST_DIRECTORY)))
-            return E_ACCESSDENIED;
-
         WCHAR path[MAX_PATH];
         StringCbCopyW(path, _countof(path), m_NtPath);
@@ -699,18 +430,32 @@
         if (info->objectType == SYMBOLICLINK_OBJECT)
         {
-            NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
-
-            if (symlink->targetNameLength > 0)
-            {
-                if (symlink->targetName[1] == L':' &&
isalphaW(symlink->targetName[0]))
+            WCHAR wbLink[MAX_PATH] = { 0 };
+            UNICODE_STRING link;
+            RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
+
+            hr = GetNTObjectSymbolicLinkTarget(m_NtPath, info->entryName, &link);
+            if (FAILED_UNEXPECTEDLY(hr))
+                return hr;
+
+            if (link.Length > 0)
+            {
+                if (link.Buffer[1] == L':' && isalphaW(link.Buffer[0]))
                 {
-                    ERR("TODO: Navigating to WIN32 PATH from NT PATH.\n");
-                    return E_NOTIMPL;
+                    CComPtr<IShellFolder> psfDesktop;
+                    hr = SHGetDesktopFolder(&psfDesktop);
+                    if (FAILED_UNEXPECTEDLY(hr))
+                        return hr;
+
+                    hr = psfDesktop->ParseDisplayName(NULL, NULL, path, NULL,
&first, NULL);
+                    if (FAILED_UNEXPECTEDLY(hr))
+                        return hr;
+
+                    return psfDesktop->BindToObject(rest, pbcReserved, riid, ppvOut);
                 }
                 StringCbCopyW(path, _countof(path),
L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{845B0FB2-66E0-416B-8F91-314E23F7C12D}");
-                PathAppend(path, symlink->targetName);
+                PathAppend(path, link.Buffer);
                 CComPtr<IShellFolder> psfDesktop;
                 hr = SHGetDesktopFolder(&psfDesktop);
@@ -731,7 +476,7 @@
         if (info->objectType == KEY_OBJECT)
         {
-            hr = ShellObjectCreatorInit<CRegistryFolder>(fullPidl, path,
(HKEY)NULL, IID_PPV_ARG(IShellFolder, &psfChild));
+            hr = ShellObjectCreatorInit<CRegistryFolder>(fullPidl, path, (HKEY)
NULL, IID_PPV_ARG(IShellFolder, &psfChild));
         }
         else
         {
@@ -824,7 +569,7 @@
 {
     const NtPidlEntry * info;
-    TRACE("GetAttributesOf\n");
+    TRACE("GetAttributesOf %d\n", cidl);
     if (cidl == 0)
     {
@@ -836,7 +581,7 @@
     {
         PCUITEMID_CHILD pidl = apidl[i];
-        HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+        HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
@@ -855,6 +600,7 @@
     UINT *prgfInOut,
     void **ppvOut)
 {
+    DWORD res;
     TRACE("GetUIObjectOf\n");
     if (IsEqualIID(riid, IID_IContextMenu) ||
@@ -863,12 +609,14 @@
     {
         CComPtr<IContextMenu> pcm;
-        HKEY keys [1];
+        HKEY keys[1];
         int nkeys = _countof(keys);
         if (cidl == 1 && m_PidlManager->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
         {
@@ -884,12 +632,12 @@
     if (IsEqualIID(riid, IID_IExtractIconW))
     {
-        return ShellObjectCreatorInit<CNtObjectFolderExtractIcon>(m_shellPidl,
cidl, apidl, riid, ppvOut);
+        return ShellObjectCreatorInit<CNtObjectFolderExtractIcon>(m_NtPath, cidl,
apidl, riid, ppvOut);
     }
     if (IsEqualIID(riid, IID_IDataObject))
     {
-        return CIDLData_CreateFromIDArray(m_shellPidl, cidl, apidl,
(IDataObject**)ppvOut);
+        return CIDLData_CreateFromIDArray(m_shellPidl, cidl, apidl, (IDataObject**)
ppvOut);
     }
     if (IsEqualIID(riid, IID_IQueryAssociations))
@@ -921,7 +669,7 @@
     TRACE("GetDisplayNameOf %p\n", pidl);
-    HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+    HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
@@ -964,7 +712,7 @@
             PathAppendW(path, temp);
         }
-        ILFree((LPITEMIDLIST)pidlFirst);
+        ILFree((LPITEMIDLIST) pidlFirst);
     }
     else
     {
@@ -1073,11 +821,8 @@
     case NTOBJECT_COLUMN_TYPE:
         *pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
         return S_OK;
-    case NTOBJECT_COLUMN_CREATEDATE:
-        *pcsFlags = SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT;
-        return S_OK;
     case NTOBJECT_COLUMN_LINKTARGET:
-        *pcsFlags = SHCOLSTATE_TYPE_STR;
+        *pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_SLOW;
         return S_OK;
     }
@@ -1095,7 +840,7 @@
     if (pidl)
     {
-        HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+        HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
@@ -1126,35 +871,25 @@
                     return MakeVariantString(pv, ObjectTypeNames[info->objectType]);
                 }
             }
-            else if (pscid->pid == PID_STG_WRITETIME)
-            {
-                DOUBLE varTime;
-                SYSTEMTIME stime;
-                FileTimeToSystemTime((FILETIME*)
&(info->objectInformation.CreateTime), &stime);
-                SystemTimeToVariantTime(&stime, &varTime);
-
-                V_VT(pv) = VT_DATE;
-                V_DATE(pv) = varTime;
-                return S_OK;
-            }
         }
         else if (IsEqualGUID(pscid->fmtid, GUID_NtObjectColumns))
         {
-            if (pscid->pid == NTOBJECT_COLUMN_LINKTARGET)
-            {
-                if (info->objectType == SYMBOLICLINK_OBJECT)
+            if (pscid->pid == NTOBJECT_COLUMN_LINKTARGET &&
info->objectType == SYMBOLICLINK_OBJECT)
+            {
+                WCHAR wbLink[MAX_PATH] = { 0 };
+                UNICODE_STRING link;
+                RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
+
+                HRESULT hr = GetNTObjectSymbolicLinkTarget(m_NtPath, info->entryName,
&link);
+
+                if (!FAILED_UNEXPECTEDLY(hr) && link.Length > 0)
                 {
-                    NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
-
-                    if (symlink->targetNameLength > 0)
-                    {
-                        return MakeVariantString(pv, symlink->targetName);
-                    }
+                    return MakeVariantString(pv, link.Buffer);
                 }
-
-                V_VT(pv) = VT_EMPTY;
-                return S_OK;
-            }
+            }
+
+            V_VT(pv) = VT_EMPTY;
+            return S_OK;
         }
     }
@@ -1172,7 +907,7 @@
     if (pidl)
     {
-        HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+        HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
@@ -1198,43 +933,28 @@
             else
                 MakeStrRetFromString(ObjectTypeNames[info->objectType],
&(psd->str));
             return S_OK;
-        case NTOBJECT_COLUMN_CREATEDATE:
+        case NTOBJECT_COLUMN_LINKTARGET:
+        {
             psd->fmt = LVCFMT_LEFT;
-            if (info->objectInformation.CreateTime.QuadPart != 0)
-            {
-                WCHAR dbuff[128];
-                PWSTR tbuff;
-                SYSTEMTIME stime;
-                FileTimeToSystemTime((LPFILETIME)
&(info->objectInformation.CreateTime), &stime);
-                GetDateFormat(LOCALE_USER_DEFAULT, 0, &stime, NULL, dbuff,
_countof(dbuff));
-                tbuff = dbuff + wcslen(dbuff);
-                *tbuff++ = L' ';
-                GetTimeFormat(LOCALE_USER_DEFAULT, 0, &stime, NULL, tbuff,
_countof(dbuff) - (tbuff - dbuff));
-
-                MakeStrRetFromString(dbuff, &(psd->str));
-                return S_OK;
-            }
-
-            MakeStrRetFromString(L"", &(psd->str));
-            return S_OK;
-
-        case NTOBJECT_COLUMN_LINKTARGET:
-            psd->fmt = LVCFMT_LEFT;
-
             if (info->objectType == SYMBOLICLINK_OBJECT)
             {
-                NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
-
-                if (symlink->targetNameLength > 0)
+                WCHAR wbLink[MAX_PATH] = { 0 };
+                UNICODE_STRING link;
+                RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
+
+                HRESULT hr = GetNTObjectSymbolicLinkTarget(m_NtPath, info->entryName,
&link);
+
+                if (!FAILED_UNEXPECTEDLY(hr) && link.Length > 0)
                 {
-                    MakeStrRetFromString(symlink->targetName,
symlink->targetNameLength, &(psd->str));
+                    MakeStrRetFromString(link.Buffer, link.Length, &(psd->str));
                     return S_OK;
                 }
             }
             MakeStrRetFromString(L"", &(psd->str));
             return S_OK;
+        }
         }
     }
     else
@@ -1255,13 +975,6 @@
             // TODO: Make localizable
             MakeStrRetFromString(L"Object Type", &(psd->str));
             return S_OK;
-        case NTOBJECT_COLUMN_CREATEDATE:
-            psd->fmt = LVCFMT_LEFT;
-            psd->cxChar = 20;
-
-            // TODO: Make localizable
-            MakeStrRetFromString(L"Creation Time", &(psd->str));
-            return S_OK;
         case NTOBJECT_COLUMN_LINKTARGET:
             psd->fmt = LVCFMT_LEFT;
             psd->cxChar = 30;
@@ -1290,10 +1003,6 @@
         pscid->fmtid = storage;
         pscid->pid = PID_STG_STORAGETYPE;
         return S_OK;
-    case NTOBJECT_COLUMN_CREATEDATE:
-        pscid->fmtid = storage;
-        pscid->pid = PID_STG_WRITETIME;
-        return S_OK;
     case NTOBJECT_COLUMN_LINKTARGET:
         pscid->fmtid = GUID_NtObjectColumns;
         pscid->pid = NTOBJECT_COLUMN_LINKTARGET;
@@ -1316,8 +1025,6 @@
         return S_FALSE;
     case SFVM_BACKGROUNDENUM:
         return S_OK;
-    case SFVM_DEFITEMCOUNT:
-        return m_PidlManager->GetCount((UINT*) lParam);
     }
     return E_NOTIMPL;
 }
Modified: trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp  [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp  [iso-8859-1] Fri Aug 21 14:26:25
2015
@@ -23,6 +23,17 @@
 WINE_DEFAULT_DEBUG_CHANNEL(ntobjshex);
+static struct RootKeyEntry {
+    HKEY key;
+    PCWSTR keyName;
+} RootKeys [] = {
+    { HKEY_CLASSES_ROOT, L"HKEY_CLASSES_ROOT" },
+    { HKEY_CURRENT_USER, L"HKEY_CURRENT_USER" },
+    { HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE" },
+    { HKEY_USERS, L"HKEY_USERS" },
+    { HKEY_CURRENT_CONFIG, L"HKEY_CURRENT_CONFIG" }
+};
+
 typedef NTSTATUS(__stdcall* pfnNtGenericOpen)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
 typedef NTSTATUS(__stdcall* pfnNtOpenFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK, ULONG, ULONG);
@@ -36,7 +47,7 @@
     0
 };
-const LPCWSTR RegistryTypeNames[] = {
+const LPCWSTR RegistryTypeNames [] = {
     L"REG_NONE",
     L"REG_SZ",
     L"REG_EXPAND_SZ",
@@ -99,218 +110,132 @@
     return UNKNOWN_OBJECT_TYPE;
 }
-HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount)
-{
+HRESULT ReadRegistryValue(HKEY root, PCWSTR path, PCWSTR valueName, PVOID * valueData,
PDWORD valueLength)
+{
+    HKEY hkey;
+
+    DWORD res;
+    if (root)
+    {
+        res = RegOpenKeyExW(root, *path == '\\' ? path + 1 : path, 0,
STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, &hkey);
+    }
+    else
+    {
+        res = NtOpenObject(KEY_OBJECT, (PHANDLE) &hkey, STANDARD_RIGHTS_READ |
KEY_QUERY_VALUE, path);
+    }
+    if (!NT_SUCCESS(res))
+    {
+        ERR("RegOpenKeyExW failed for path %S with status=%x\n", path, res);
+        return HRESULT_FROM_NT(res);
+    }
+
+    res = RegQueryValueExW(hkey, valueName, NULL, NULL, NULL, valueLength);
+    if (!NT_SUCCESS(res))
+    {
+        ERR("RegQueryValueExW failed for path %S with status=%x\n", path, res);
+        return HRESULT_FROM_NT(res);
+    }
+
+    if (*valueLength > 0)
+    {
+        PBYTE data = (PBYTE) CoTaskMemAlloc(*valueLength);;
+        *valueData = data;
+
+        res = RegQueryValueExW(hkey, valueName, NULL, NULL, data, valueLength);
+        if (!NT_SUCCESS(res))
+        {
+            CoTaskMemFree(data);
+            *valueData = NULL;
+
+            RegCloseKey(hkey);
+
+            ERR("RegOpenKeyExW failed for path %S with status=%x\n", path,
res);
+            return HRESULT_FROM_NT(res);
+        }
+    }
+    else
+    {
+        *valueData = NULL;
+    }
+
+    RegCloseKey(hkey);
+
+    return S_OK;
+}
+
+HRESULT GetNTObjectSymbolicLinkTarget(LPCWSTR path, LPCWSTR entryName, PUNICODE_STRING
LinkTarget)
+{
+    HANDLE handle;
     WCHAR buffer[MAX_PATH];
-    PWSTR pend;
-
-    *hdpaCount = 0;
+    LPWSTR pend = buffer;
     StringCbCopyExW(buffer, sizeof(buffer), path, &pend, NULL, 0);
-
-    ULONG enumContext = 0;
-    HANDLE directory = NULL;
-
-    DWORD err = NtOpenObject(DIRECTORY_OBJECT, &directory, FILE_LIST_DIRECTORY,
buffer);
-    if (!NT_SUCCESS(err))
-    {
-        ERR("NtOpenDirectoryObject failed for path %S with status=%x\n",
buffer, err);
-        return HRESULT_FROM_NT(err);
-    }
     if (pend[-1] != '\\')
         *pend++ = '\\';
-
-    BYTE dirbuffer[2048];
-
-    BOOL first = TRUE;
-    while (NtQueryDirectoryObject(directory, dirbuffer, 2048, TRUE, first,
&enumContext, NULL) == STATUS_SUCCESS)
-    {
-        first = FALSE;
-        POBJECT_DIRECTORY_INFORMATION info = (POBJECT_DIRECTORY_INFORMATION) dirbuffer;
-        //for (; info->Name.Buffer != NULL; info++)
-        {
-            if (info->Name.Buffer)
-            {
-                StringCbCopyNW(pend, sizeof(buffer), info->Name.Buffer,
info->Name.Length);
-            }
-
-            OBJECT_TYPE otype = MapTypeNameToType(info->TypeName.Buffer,
info->TypeName.Length);
-            OBJECT_BASIC_INFORMATION object = { 0 };
-
-            WCHAR wbLink[_MAX_PATH] = { 0 };
-            UNICODE_STRING link;
-            RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
-
-            DWORD entryBufferLength = FIELD_OFFSET(NtPidlEntry,entryName) +
sizeof(WCHAR);
-            if (info->Name.Buffer)
-                entryBufferLength += info->Name.Length;
-
-            if (otype < 0)
-            {
-                entryBufferLength += FIELD_OFFSET(NtPidlTypeData,typeName) +
sizeof(WCHAR);
-
-                if (info->TypeName.Buffer)
-                {
-                    entryBufferLength += info->TypeName.Length;
-                }
-            }
-
-            if (otype == SYMBOLICLINK_OBJECT)
-            {
-                entryBufferLength += FIELD_OFFSET(NtPidlSymlinkData,targetName) +
sizeof(WCHAR);
-            }
-
-            DWORD access = STANDARD_RIGHTS_READ;
-            if ((otype == DIRECTORY_OBJECT) ||
-                (otype == SYMBOLICLINK_OBJECT))
-                access |= FILE_LIST_DIRECTORY;
-
-            HANDLE handle;
-            if (!NtOpenObject(otype, &handle, access, buffer))
-            {
-                DWORD read;
-
-                if (!NT_SUCCESS(NtQueryObject(handle, ObjectBasicInformation,
&object, sizeof(OBJECT_BASIC_INFORMATION), &read)))
-                {
-                    ZeroMemory(&object, sizeof(OBJECT_BASIC_INFORMATION));
-                }
-
-                if (otype == SYMBOLICLINK_OBJECT)
-                {
-                    if (NtQuerySymbolicLinkObject(handle, &link, NULL) ==
STATUS_SUCCESS)
-                    {
-                        entryBufferLength += link.Length;
-                    }
-                    else
-                    {
-                        link.Length = 0;
-                    }
-                }
-
-                NtClose(handle);
-            }
-
-            NtPidlEntry* entry = (NtPidlEntry*) CoTaskMemAlloc(entryBufferLength);
-            if (!entry)
-                return E_OUTOFMEMORY;
-
-            memset(entry, 0, entryBufferLength);
-
-            entry->cb = FIELD_OFFSET(NtPidlEntry,entryName);
-            entry->magic = NT_OBJECT_PIDL_MAGIC;
-            entry->objectType = otype;
-            entry->objectInformation = object;
-            memset(entry->objectInformation.Reserved, 0,
sizeof(entry->objectInformation.Reserved));
-
-            if (info->Name.Buffer)
-            {
-                entry->entryNameLength = info->Name.Length;
-                StringCbCopyNW(entry->entryName, entryBufferLength,
info->Name.Buffer, info->Name.Length);
-                entry->cb += entry->entryNameLength + sizeof(WCHAR);
-            }
-            else
-            {
-                entry->entryNameLength = 0;
-                entry->entryName[0] = 0;
-                entry->cb += sizeof(WCHAR);
-            }
-
-            if (otype < 0)
-            {
-                NtPidlTypeData * typedata = (NtPidlTypeData*) ((PBYTE) entry +
entry->cb);
-                DWORD remainingSpace = entryBufferLength - ((PBYTE)
(typedata->typeName) - (PBYTE) entry);
-
-                if (info->TypeName.Buffer)
-                {
-                    typedata->typeNameLength = info->TypeName.Length;
-                    StringCbCopyNW(typedata->typeName, remainingSpace,
info->TypeName.Buffer, info->TypeName.Length);
-
-                    entry->cb += typedata->typeNameLength + sizeof(WCHAR);
-                }
-                else
-                {
-                    typedata->typeNameLength = 0;
-                    typedata->typeName[0] = 0;
-                    entry->cb += typedata->typeNameLength + sizeof(WCHAR);
-                }
-            }
-
-            if (otype == SYMBOLICLINK_OBJECT)
-            {
-                NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) ((PBYTE) entry +
entry->cb);
-                DWORD remainingSpace = entryBufferLength - ((PBYTE)
(symlink->targetName) - (PBYTE) entry);
-
-                symlink->targetNameLength = link.Length;
-                StringCbCopyNW(symlink->targetName, remainingSpace, link.Buffer,
link.Length);
-
-                entry->cb += symlink->targetNameLength + sizeof(WCHAR);
-            }
-
-            DPA_AppendPtr(hdpa, entry);
-            (*hdpaCount)++;
-        }
-    }
-
-    NtClose(directory);
+    StringCbCatW(buffer, sizeof(buffer), entryName);
+
+    DbgPrint("GetNTObjectSymbolicLinkTarget %d\n", buffer);
+
+    LinkTarget->Length = 0;
+
+    DWORD err = NtOpenObject(SYMBOLICLINK_OBJECT, &handle, 0, buffer);
+    if (!NT_SUCCESS(err))
+        return HRESULT_FROM_NT(err);
+
+    err = NT_SUCCESS(NtQuerySymbolicLinkObject(handle, LinkTarget, NULL));
+    if (!NT_SUCCESS(err))
+        return HRESULT_FROM_NT(err);
+
+    NtClose(handle);
     return S_OK;
 }
-HRESULT EnumerateRegistryKey(HDPA hdpa, PCWSTR path, HKEY root, UINT * hdpaCount)
-{
-    *hdpaCount = 0;
-
-    HKEY hkey;
-
-    DWORD res;
-    if (root)
-    {
-        res = RegOpenKeyExW(root, *path == '\\' ? path + 1 : path, 0,
STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hkey);
-    }
-    else
-    {
-        res = NtOpenObject(KEY_OBJECT, (PHANDLE)&hkey, STANDARD_RIGHTS_READ |
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, path);
-    }
-    if (!NT_SUCCESS(res))
-    {
-        ERR("RegOpenKeyExW failed for path %S with status=%x\n", path, res);
-        return HRESULT_FROM_NT(res);
-    }
-
-    for (int idx = 0;; ++idx)
-    {
-        WCHAR name[MAX_PATH];
-        DWORD cchName = _countof(name);
-
-        WCHAR className[MAX_PATH];
-        DWORD cchClass = _countof(className);
-
-        if (RegEnumKeyExW(hkey, idx, name, &cchName, 0, className, &cchClass,
NULL))
-            break;
-
-        name[cchName] = 0;
-        className[cchClass] = 0;
-
-        REG_ENTRY_TYPE otype = REG_ENTRY_KEY;
-
-        DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry,entryName) + sizeof(WCHAR) +
cchName * sizeof(WCHAR);
-
-        if (cchClass > 0)
-        {
-            entryBufferLength += sizeof(WCHAR) + cchClass * sizeof(WCHAR);
-        }
-
+class CEnumRegRoot :
+    public CComObjectRootEx<CComMultiThreadModelNoCS>,
+    public IEnumIDList
+{
+    UINT m_idx;
+
+public:
+    CEnumRegRoot()
+        : m_idx(0)
+    {
+    }
+
+    ~CEnumRegRoot()
+    {
+    }
+
+    HRESULT EnumerateNext(LPITEMIDLIST* ppidl)
+    {
+        if (m_idx >= _countof(RootKeys))
+            return S_FALSE;
+
+        RootKeyEntry& key = RootKeys[m_idx++];
+
+        PCWSTR name = key.keyName;
+        DWORD cchName = wcslen(name);
+
+        REG_ENTRY_TYPE otype = REG_ENTRY_ROOT;
+
+        DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry, entryName) + sizeof(WCHAR) +
cchName * sizeof(WCHAR);
+
+        // allocate space for the terminator
+        entryBufferLength += 2;
+
         RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength);
         if (!entry)
             return E_OUTOFMEMORY;
         memset(entry, 0, entryBufferLength);
-        entry->cb = FIELD_OFFSET(NtPidlEntry,entryName);
+        entry->cb = FIELD_OFFSET(RegPidlEntry, entryName);
         entry->magic = REGISTRY_PIDL_MAGIC;
         entry->entryType = otype;
+        entry->rootKey = key.key;
         if (cchName > 0)
         {
@@ -325,6 +250,154 @@
             entry->cb += sizeof(WCHAR);
         }
+        *ppidl = (LPITEMIDLIST) entry;
+        return S_OK;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG
*pceltFetched)
+    {
+        if (pceltFetched)
+            *pceltFetched = 0;
+
+        while (celt-- > 0)
+        {
+            HRESULT hr = EnumerateNext(rgelt);
+            if (hr != S_OK)
+                return hr;
+
+            if (pceltFetched)
+                (*pceltFetched)++;
+            if (rgelt)
+                rgelt++;
+        }
+
+        return S_OK;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
+    {
+        while (celt > 0)
+        {
+            HRESULT hr = EnumerateNext(NULL);
+            if (FAILED(hr))
+                return hr;
+            if (hr != S_OK)
+                break;
+        }
+
+        return S_OK;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Reset()
+    {
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Clone(IEnumIDList **ppenum)
+    {
+        return E_NOTIMPL;
+    }
+
+    DECLARE_NOT_AGGREGATABLE(CEnumRegRoot)
+    DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+    BEGIN_COM_MAP(CEnumRegRoot)
+        COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
+    END_COM_MAP()
+
+};
+
+class CEnumRegKey :
+    public CComObjectRootEx<CComMultiThreadModelNoCS>,
+    public IEnumIDList
+{
+    PCWSTR m_path;
+    HKEY m_hkey;
+    BOOL m_values;
+    int m_idx;
+
+public:
+    CEnumRegKey()
+        : m_path(NULL), m_hkey(NULL), m_values(FALSE), m_idx(0)
+    {
+    }
+
+    ~CEnumRegKey()
+    {
+        RegCloseKey(m_hkey);
+    }
+
+    HRESULT Initialize(PCWSTR path, HKEY root)
+    {
+        m_path = path;
+
+        DWORD res;
+        if (root)
+        {
+            res = RegOpenKeyExW(root, *path == '\\' ? path + 1 : path, 0,
STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &m_hkey);
+        }
+        else
+        {
+            res = NtOpenObject(KEY_OBJECT, (PHANDLE) &m_hkey, STANDARD_RIGHTS_READ |
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, path);
+        }
+        if (!NT_SUCCESS(res))
+        {
+            ERR("RegOpenKeyExW failed for path %S with status=%x\n", path,
res);
+            return HRESULT_FROM_NT(res);
+        }
+
+        return S_OK;
+    }
+
+    HRESULT NextKey(LPITEMIDLIST* ppidl)
+    {
+        WCHAR name[MAX_PATH];
+        DWORD cchName = _countof(name);
+
+        WCHAR className[MAX_PATH];
+        DWORD cchClass = _countof(className);
+
+        if (RegEnumKeyExW(m_hkey, m_idx++, name, &cchName, 0, className,
&cchClass, NULL))
+            return S_FALSE;
+
+        name[cchName] = 0;
+        className[cchClass] = 0;
+
+        REG_ENTRY_TYPE otype = REG_ENTRY_KEY;
+
+        DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry, entryName) + sizeof(WCHAR) +
cchName * sizeof(WCHAR);
+
+        if (cchClass > 0)
+        {
+            entryBufferLength += sizeof(WCHAR) + cchClass * sizeof(WCHAR);
+        }
+
+        // allocate space for the terminator
+        entryBufferLength += 2;
+
+        RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength);
+        if (!entry)
+            return E_OUTOFMEMORY;
+
+        memset(entry, 0, entryBufferLength);
+
+        entry->cb = FIELD_OFFSET(RegPidlEntry, entryName);
+        entry->magic = REGISTRY_PIDL_MAGIC;
+        entry->entryType = otype;
+
+        if (cchName > 0)
+        {
+            entry->entryNameLength = cchName * sizeof(WCHAR);
+            StringCbCopyNW(entry->entryName, entryBufferLength, name,
entry->entryNameLength);
+            entry->cb += entry->entryNameLength + sizeof(WCHAR);
+        }
+        else
+        {
+            entry->entryNameLength = 0;
+            entry->entryName[0] = 0;
+            entry->cb += sizeof(WCHAR);
+        }
+
         if (cchClass)
         {
             PWSTR contentData = (PWSTR) ((PBYTE) entry + entry->cb);
@@ -336,24 +409,23 @@
             entry->cb += entry->contentsLength + sizeof(WCHAR);
         }
-        DPA_AppendPtr(hdpa, entry);
-        (*hdpaCount)++;
-
-    }
-
-    for (int idx = 0;; ++idx)
+        *ppidl = (LPITEMIDLIST) entry;
+        return S_OK;
+    }
+
+    HRESULT NextValue(LPITEMIDLIST* ppidl)
     {
         WCHAR name[MAX_PATH];
         DWORD cchName = _countof(name);
-        DWORD type;
-        DWORD dataSize;
-
-        if (RegEnumValueW(hkey, idx, name, &cchName, 0, &type, NULL,
&dataSize))
-            break;
+        DWORD type = 0;
+        DWORD dataSize = 0;
+
+        if (RegEnumValueW(m_hkey, m_idx++, name, &cchName, 0, &type, NULL,
&dataSize))
+            return S_FALSE;
         REG_ENTRY_TYPE otype = REG_ENTRY_VALUE;
-        DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry,entryName) + sizeof(WCHAR) +
cchName * sizeof(WCHAR);
+        DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry, entryName) + sizeof(WCHAR) +
cchName * sizeof(WCHAR);
         BOOL copyData = dataSize < 32;
         if (copyData)
@@ -362,8 +434,8 @@
             otype = REG_ENTRY_VALUE_WITH_CONTENT;
         }
-
-        RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength);
+
+        RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength + 2);
         if (!entry)
             return E_OUTOFMEMORY;
@@ -396,7 +468,7 @@
             // In case it's an unterminated string, RegGetValue will add the NULL
termination
             dataSize += sizeof(WCHAR);
-            if (!RegQueryValueExW(hkey, name, NULL, NULL, contentData, &dataSize))
+            if (!RegQueryValueExW(m_hkey, name, NULL, NULL, contentData, &dataSize))
             {
                 entry->cb += entry->contentsLength + sizeof(WCHAR);
             }
@@ -408,54 +480,168 @@
         }
-        DPA_AppendPtr(hdpa, entry);
-        (*hdpaCount)++;
-    }
-
-    RegCloseKey(hkey);
-
-    return S_OK;
-}
-
-HRESULT EnumerateRootKeys(HDPA hdpa, UINT * hdpaCount)
-{
-    *hdpaCount = 0;
-
-    static struct {
-        HKEY key;
-        PCWSTR keyName;
-    } rootKeys [] = {
-        { HKEY_CLASSES_ROOT, L"HKEY_CLASSES_ROOT" },
-        { HKEY_CURRENT_USER, L"HKEY_CURRENT_USER" },
-        { HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE" },
-        { HKEY_USERS, L"HKEY_USERS" },
-        { HKEY_CURRENT_CONFIG, L"HKEY_CURRENT_CONFIG" }
-    };
-
-    for (UINT i = 0; i < _countof(rootKeys); i++)
-    {
-        PCWSTR name = rootKeys[i].keyName;
-        DWORD cchName = wcslen(rootKeys[i].keyName);
-
-        REG_ENTRY_TYPE otype = REG_ENTRY_ROOT;
-
-        DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry, entryName) + sizeof(WCHAR) +
cchName * sizeof(WCHAR);
-
-        RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength);
+        *ppidl = (LPITEMIDLIST) entry;
+        return S_OK;
+    }
+
+    HRESULT EnumerateNext(LPITEMIDLIST* ppidl)
+    {
+        if (!m_values)
+        {
+            HRESULT hr = NextKey(ppidl);
+            if (hr != S_FALSE)
+                return hr;
+
+            // switch to values.
+            m_values = TRUE;
+            m_idx = 0;
+        }
+
+        return NextValue(ppidl);
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG
*pceltFetched)
+    {
+        if (pceltFetched)
+            *pceltFetched = 0;
+
+        while (celt-- > 0)
+        {
+            HRESULT hr = EnumerateNext(rgelt);
+            if (hr != S_OK)
+                return hr;
+
+            if (pceltFetched)
+                (*pceltFetched)++;
+            if (rgelt)
+                rgelt++;
+        }
+
+        return S_OK;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
+    {
+        while (celt > 0)
+        {
+            HRESULT hr = EnumerateNext(NULL);
+            if (FAILED(hr))
+                return hr;
+            if (hr != S_OK)
+                break;
+        }
+
+        return S_OK;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Reset()
+    {
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Clone(IEnumIDList **ppenum)
+    {
+        return E_NOTIMPL;
+    }
+
+    DECLARE_NOT_AGGREGATABLE(CEnumRegKey)
+    DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+    BEGIN_COM_MAP(CEnumRegKey)
+        COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
+    END_COM_MAP()
+};
+
+class CEnumNTDirectory :
+    public CComObjectRootEx<CComMultiThreadModelNoCS>,
+    public IEnumIDList
+{
+    WCHAR buffer[MAX_PATH];
+    HANDLE m_directory;
+    BOOL m_first;
+    ULONG m_enumContext;
+    PWSTR m_pend;
+
+public:
+    CEnumNTDirectory()
+        : m_directory(NULL), m_first(TRUE), m_enumContext(0), m_pend(NULL)
+    {
+    }
+
+    ~CEnumNTDirectory()
+    {
+        NtClose(m_directory);
+    }
+
+    HRESULT Initialize(PCWSTR path)
+    {
+        StringCbCopyExW(buffer, sizeof(buffer), path, &m_pend, NULL, 0);
+
+        DWORD err = NtOpenObject(DIRECTORY_OBJECT, &m_directory, FILE_LIST_DIRECTORY,
buffer);
+        if (!NT_SUCCESS(err))
+        {
+            ERR("NtOpenDirectoryObject failed for path %S with status=%x\n",
buffer, err);
+            return HRESULT_FROM_NT(err);
+        }
+
+        if (m_pend[-1] != '\\')
+            *m_pend++ = '\\';
+
+        return S_OK;
+    }
+
+    HRESULT EnumerateNext(LPITEMIDLIST* ppidl)
+    {
+        BYTE dirbuffer[2048];
+        if (!NT_SUCCESS(NtQueryDirectoryObject(m_directory, dirbuffer, 2048, TRUE,
m_first, &m_enumContext, NULL)))
+            return S_FALSE;
+
+        // if ppidl is NULL, assume the caller was Skip(),
+        // so we don't care about the info
+        if (!ppidl)
+            return S_OK;
+
+        m_first = FALSE;
+        POBJECT_DIRECTORY_INFORMATION info = (POBJECT_DIRECTORY_INFORMATION) dirbuffer;
+
+        if (info->Name.Buffer)
+        {
+            StringCbCopyNW(m_pend, sizeof(buffer), info->Name.Buffer,
info->Name.Length);
+        }
+
+        OBJECT_TYPE otype = MapTypeNameToType(info->TypeName.Buffer,
info->TypeName.Length);
+
+        DWORD entryBufferLength = FIELD_OFFSET(NtPidlEntry, entryName) + sizeof(WCHAR);
+        if (info->Name.Buffer)
+            entryBufferLength += info->Name.Length;
+
+        if (otype < 0)
+        {
+            entryBufferLength += FIELD_OFFSET(NtPidlTypeData, typeName) + sizeof(WCHAR);
+
+            if (info->TypeName.Buffer)
+            {
+                entryBufferLength += info->TypeName.Length;
+            }
+        }
+
+        // allocate space for the terminator
+        entryBufferLength += 2;
+
+        NtPidlEntry* entry = (NtPidlEntry*) CoTaskMemAlloc(entryBufferLength);
         if (!entry)
             return E_OUTOFMEMORY;
         memset(entry, 0, entryBufferLength);
         entry->cb = FIELD_OFFSET(NtPidlEntry, entryName);
-        entry->magic = REGISTRY_PIDL_MAGIC;
-        entry->entryType = otype;
-        entry->rootKey = rootKeys[i].key;
-
-        if (cchName > 0)
-        {
-            entry->entryNameLength = cchName * sizeof(WCHAR);
-            StringCbCopyNW(entry->entryName, entryBufferLength, name,
entry->entryNameLength);
+        entry->magic = NT_OBJECT_PIDL_MAGIC;
+        entry->objectType = otype;
+
+        if (info->Name.Buffer)
+        {
+            entry->entryNameLength = info->Name.Length;
+            StringCbCopyNW(entry->entryName, entryBufferLength, info->Name.Buffer,
info->Name.Length);
             entry->cb += entry->entryNameLength + sizeof(WCHAR);
         }
         else
@@ -464,58 +650,95 @@
             entry->entryName[0] = 0;
             entry->cb += sizeof(WCHAR);
         }
-
-        DPA_AppendPtr(hdpa, entry);
-        (*hdpaCount)++;
-
-    }
-
-    return S_OK;
+
+        if (otype < 0)
+        {
+            NtPidlTypeData * typedata = (NtPidlTypeData*) ((PBYTE) entry + entry->cb);
+            DWORD remainingSpace = entryBufferLength - ((PBYTE) (typedata->typeName) -
(PBYTE) entry);
+
+            if (info->TypeName.Buffer)
+            {
+                typedata->typeNameLength = info->TypeName.Length;
+                StringCbCopyNW(typedata->typeName, remainingSpace,
info->TypeName.Buffer, info->TypeName.Length);
+
+                entry->cb += typedata->typeNameLength + sizeof(WCHAR);
+            }
+            else
+            {
+                typedata->typeNameLength = 0;
+                typedata->typeName[0] = 0;
+                entry->cb += typedata->typeNameLength + sizeof(WCHAR);
+            }
+        }
+
+        *ppidl = (LPITEMIDLIST) entry;
+
+        return S_OK;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG
*pceltFetched)
+    {
+        if (pceltFetched)
+            *pceltFetched = 0;
+
+        while (celt-- > 0)
+        {
+            HRESULT hr = EnumerateNext(rgelt);
+            if (hr != S_OK)
+                return hr;
+
+            if (pceltFetched)
+                (*pceltFetched)++;
+            if (rgelt)
+                rgelt++;
+        }
+
+        return S_OK;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
+    {
+        while (celt > 0)
+        {
+            HRESULT hr = EnumerateNext(NULL);
+            if (FAILED(hr))
+                return hr;
+            if (hr != S_OK)
+                break;
+        }
+
+        return S_OK;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Reset()
+    {
+        return E_NOTIMPL;
+    }
+
+    virtual HRESULT STDMETHODCALLTYPE Clone(IEnumIDList **ppenum)
+    {
+        return E_NOTIMPL;
+    }
+
+    DECLARE_NOT_AGGREGATABLE(CEnumNTDirectory)
+    DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+    BEGIN_COM_MAP(CEnumNTDirectory)
+        COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
+    END_COM_MAP()
+};
+
+HRESULT GetEnumRegistryRoot(IEnumIDList ** ppil)
+{
+    return ShellObjectCreator<CEnumRegRoot>(IID_PPV_ARG(IEnumIDList, ppil));
 }
-HRESULT ReadRegistryValue(HKEY root, PCWSTR path, PCWSTR valueName, PVOID * valueData,
PDWORD valueLength)
-{
-    HKEY hkey;
-
-    DWORD res;
-    if (root)
-    {
-        res = RegOpenKeyExW(root, *path == '\\' ? path + 1 : path, 0,
STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, &hkey);
-    }
-    else
-    {
-        res = NtOpenObject(KEY_OBJECT, (PHANDLE) &hkey, STANDARD_RIGHTS_READ |
KEY_QUERY_VALUE, path);
-    }
-    if (!NT_SUCCESS(res))
-    {
-        ERR("RegOpenKeyExW failed for path %S with status=%x\n", path, res);
-        return HRESULT_FROM_NT(res);
-    }
-
-    res = RegQueryValueExW(hkey, valueName, NULL, NULL, NULL, valueLength);
-
-    if (*valueLength > 0)
-    {
-        *valueData = (PBYTE) CoTaskMemAlloc(*valueLength);
-
-        res = RegQueryValueExW(hkey, valueName, NULL, NULL, (PBYTE) *valueData,
valueLength);
-        if (!NT_SUCCESS(res))
-        {
-            CoTaskMemFree(*valueData);
-            *valueData = NULL;
-
-            RegCloseKey(hkey);
-
-            ERR("RegOpenKeyExW failed for path %S with status=%x\n", path,
res);
-            return HRESULT_FROM_NT(res);
-        }
-    }
-    else
-    {
-        *valueData = NULL;
-    }
-
-    RegCloseKey(hkey);
-
-    return S_OK;
+HRESULT GetEnumRegistryKey(LPCWSTR path, HKEY root, IEnumIDList ** ppil)
+{
+    return ShellObjectCreatorInit<CEnumRegKey>(path, root, IID_PPV_ARG(IEnumIDList,
ppil));
+}
+
+HRESULT GetEnumNTDirectory(LPCWSTR path, IEnumIDList ** ppil)
+{
+    return ShellObjectCreatorInit<CEnumNTDirectory>(path, IID_PPV_ARG(IEnumIDList,
ppil));
 }
Modified: trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h    [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h    [iso-8859-1] Fri Aug 21 14:26:25
2015
@@ -50,23 +50,14 @@
     // If this is -1, there will be a NtPidlTypeData following this, and before any other
extensions
     OBJECT_TYPE objectType;
-    OBJECT_BASIC_INFORMATION objectInformation;
-
     USHORT entryNameLength;
     WCHAR entryName[ANYSIZE_ARRAY];
-
 };
 struct NtPidlTypeData
 {
     USHORT typeNameLength;
     WCHAR typeName[ANYSIZE_ARRAY];
-};
-
-struct NtPidlSymlinkData
-{
-    USHORT targetNameLength;
-    WCHAR targetName[ANYSIZE_ARRAY];
 };
 // REGISTRY browser
@@ -107,8 +98,10 @@
 #include <poppack.h>
-HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount);
-HRESULT EnumerateRegistryKey(HDPA hdpa, PCWSTR path, HKEY root, UINT * hdpaCount);
-HRESULT EnumerateRootKeys(HDPA hdpa, UINT * hdpaCount);
+HRESULT ReadRegistryValue(HKEY root, PCWSTR path, PCWSTR valueName, PVOID * valueData,
PDWORD valueLength);
-HRESULT ReadRegistryValue(HKEY root, PCWSTR path, PCWSTR valueName, PVOID * valueData,
PDWORD valueLength);
+HRESULT GetEnumRegistryRoot(IEnumIDList ** ppil);
+HRESULT GetEnumRegistryKey(LPCWSTR path, HKEY root, IEnumIDList ** ppil);
+HRESULT GetEnumNTDirectory(LPCWSTR path, IEnumIDList ** ppil);
+
+HRESULT GetNTObjectSymbolicLinkTarget(LPCWSTR path, LPCWSTR entryName, PUNICODE_STRING
LinkTarget);
Modified: trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/reg…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp  [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp  [iso-8859-1] Fri Aug 21 14:26:25
2015
@@ -23,6 +23,7 @@
 #define GET_SHGDN_RELATION(dwFlags)    ((DWORD)dwFlags & (DWORD)0x000000FF)
 WINE_DEFAULT_DEBUG_CHANNEL(ntobjshex);
+
 // {1C6D6E08-2332-4A7B-A94D-6432DB2B5AE6}
 const GUID CLSID_RegistryFolder = { 0x1c6d6e08, 0x2332, 0x4a7b, { 0xa9, 0x4d, 0x64, 0x32,
0xdb, 0x2b, 0x5a, 0xe6 } };
@@ -130,9 +131,6 @@
     PWSTR m_ntPath;
     HKEY m_hRoot;
-    HDPA m_hDpa;
-    UINT m_hDpaCount;
-
     int  DpaDeleteCallback(RegPidlEntry * info)
     {
         CoTaskMemFree(info);
@@ -149,186 +147,20 @@
 public:
     CRegistryPidlManager() :
         m_ntPath(NULL),
-        m_hRoot(NULL),
-        m_hDpa(NULL),
-        m_hDpaCount(0)
+        m_hRoot(NULL)
     {
     }
     ~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;
-        }
-
-        const RegPidlEntry * info = (const 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 { name='%S' } in a list of %d
items\n", info->entryName, m_hDpaCount);
-
-        for (UINT i = 0; i < m_hDpaCount; i++)
-        {
-            const RegPidlEntry * pInfo = (const RegPidlEntry *) DPA_GetPtr(m_hDpa, i);
-            ASSERT(pInfo);
-
-            hr = CompareIDs(SHCIDS_CANONICALONLY, pInfo, info);
-            if (FAILED_UNEXPECTEDLY(hr))
-                return hr;
-
-            if (hr == S_OK)
-            {
-                *pinfo = pInfo;
-                return S_OK;
-            }
-            else
-            {
-                TRACE("Comparison returned %d for '%S'\n", (int)
(short) (hr & 0xFFFF), pInfo->entryName);
-            }
-        }
-
-        ERR("PIDL NOT FOUND: Requested filename: %S\n", info->entryName);
-        *pinfo = NULL;
-
-        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)
-    {
-        if (!m_hDpa)
-        {
-            HRESULT 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)
-    {
-        if (!m_hDpa)
-        {
-            HRESULT 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;
+
+        return S_OK;
     }
     static HRESULT CompareIDs(LPARAM lParam, const RegPidlEntry * first, const
RegPidlEntry * second)
@@ -460,13 +292,32 @@
     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);
+    }
+
+    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)
@@ -572,121 +423,6 @@
         *strContents = strValue;
         return S_OK;
     }
-};
-
-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()
-
 };
 //-----------------------------------------------------------------------------
@@ -715,8 +451,6 @@
     LPITEMIDLIST *ppidl,
     ULONG *pdwAttributes)
 {
-    RegPidlEntry * info;
-
     if (!ppidl)
         return E_POINTER;
@@ -728,19 +462,45 @@
     TRACE("CRegistryFolder::ParseDisplayName name=%S (ntPath=%S)\n",
lpszDisplayName, m_NtPath);
-    HRESULT 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);
-
-    if (pchEaten)
-        *pchEaten = wcslen(info->entryName);
-
-    if (pdwAttributes)
-        *pdwAttributes = m_PidlManager->ConvertAttributes(info, pdwAttributes);
+    while (TRUE)
+    {
+        hr = it->Next(1, ppidl, NULL);
+
+        if (FAILED(hr))
+            return hr;
+
+        if (hr != S_OK)
+            break;
+
+        hr = m_PidlManager->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 = m_PidlManager->ConvertAttributes(info, pdwAttributes);
+    }
     return S_OK;
 }
@@ -750,7 +510,14 @@
     SHCONTF grfFlags,
     IEnumIDList **ppenumIDList)
 {
-    return ShellObjectCreatorInit<CRegistryFolderEnum>(this, hwndOwner, grfFlags,
IID_PPV_ARG(IEnumIDList, ppenumIDList));
+    if (wcslen(m_NtPath) == 0 && m_hRoot == NULL)
+    {
+        return GetEnumRegistryRoot(ppenumIDList);
+    }
+    else
+    {
+        return GetEnumRegistryKey(m_NtPath, m_hRoot, ppenumIDList);
+    }
 }
 HRESULT STDMETHODCALLTYPE CRegistryFolder::BindToObject(
@@ -763,7 +530,7 @@
     if (IsEqualIID(riid, IID_IShellFolder))
     {
-        HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+        HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
@@ -886,7 +653,7 @@
     {
         PCUITEMID_CHILD pidl = apidl[i];
-        HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+        HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
@@ -913,12 +680,15 @@
     {
         CComPtr<IContextMenu> pcm;
-        HKEY keys [1];
+        DWORD res;
+        HKEY keys[1];
         int nkeys = _countof(keys);
         if (cidl == 1 && m_PidlManager->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
         {
@@ -971,7 +741,7 @@
     TRACE("GetDisplayNameOf %p\n", pidl);
-    HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+    HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
     if (FAILED_UNEXPECTEDLY(hr))
         return hr;
@@ -1144,7 +914,7 @@
     if (pidl)
     {
-        HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+        HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
@@ -1170,7 +940,7 @@
                 {
                     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);
                     }
@@ -1217,7 +987,7 @@
     if (pidl)
     {
-        HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+        HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
@@ -1343,8 +1113,6 @@
         return S_FALSE;
     case SFVM_BACKGROUNDENUM:
         return S_OK;
-    case SFVM_DEFITEMCOUNT:
-        return m_PidlManager->GetCount((UINT*) lParam);
     }
     return E_NOTIMPL;
 }