[NTOBJSHEX]
authorDavid Quintana <gigaherz@gmail.com>
Wed, 21 Jun 2017 22:32:34 +0000 (22:32 +0000)
committerDavid Quintana <gigaherz@gmail.com>
Wed, 21 Jun 2017 22:32:34 +0000 (22:32 +0000)
* Fixed NT object symbolic link target retrieval.
* Fixed NT path parsing (didn't consider paths sub sub-folders in them).
* Fixed BindToObject to properly resolve the target path for symlinks.
* Made the maximum embedded content length for registry keys a bit bigger.

svn path=/trunk/; revision=75160

reactos/dll/shellext/ntobjshex/ntobjenum.cpp
reactos/dll/shellext/ntobjshex/ntobjfolder.cpp

index 0e4bba0..0d205e4 100644 (file)
@@ -172,7 +172,10 @@ HRESULT GetNTObjectSymbolicLinkTarget(LPCWSTR path, LPCWSTR entryName, PUNICODE_
     StringCbCopyExW(buffer, sizeof(buffer), path, &pend, NULL, 0);
 
     if (pend[-1] != '\\')
+    {
         *pend++ = '\\';
+        *pend = 0;
+    }
 
     StringCbCatW(buffer, sizeof(buffer), entryName);
 
@@ -180,11 +183,11 @@ HRESULT GetNTObjectSymbolicLinkTarget(LPCWSTR path, LPCWSTR entryName, PUNICODE_
 
     LinkTarget->Length = 0;
 
-    DWORD err = NtOpenObject(SYMBOLICLINK_OBJECT, &handle, 0, buffer);
+    DWORD err = NtOpenObject(SYMBOLICLINK_OBJECT, &handle, SYMBOLIC_LINK_QUERY, buffer);
     if (!NT_SUCCESS(err))
         return HRESULT_FROM_NT(err);
 
-    err = NT_SUCCESS(NtQuerySymbolicLinkObject(handle, LinkTarget, NULL));
+    err = NtQuerySymbolicLinkObject(handle, LinkTarget, NULL);
     if (!NT_SUCCESS(err))
         return HRESULT_FROM_NT(err);
 
@@ -429,7 +432,7 @@ public:
 
         DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry, entryName) + sizeof(WCHAR) + cchName * sizeof(WCHAR);
 
-        BOOL copyData = dataSize < 32;
+        BOOL copyData = dataSize < 256;
         if (copyData)
         {
             entryBufferLength += dataSize + sizeof(WCHAR);
index fb1b12b..aef53a7 100644 (file)
@@ -338,6 +338,9 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::ParseDisplayName(
     if (FAILED(hr))
         return hr;
 
+    PWSTR end = StrChrW(lpszDisplayName, '\\');
+    int length = end ? end - lpszDisplayName : wcslen(lpszDisplayName);
+
     while (TRUE)
     {
         hr = it->Next(1, ppidl, NULL);
@@ -346,30 +349,46 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::ParseDisplayName(
             return hr;
 
         if (hr != S_OK)
-            break;
+            return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
 
         hr = CNtObjectPidlHelper::GetInfoFromPidl(*ppidl, &info);
         if (FAILED_UNEXPECTEDLY(hr))
             return hr;
 
-        if (StrCmpW(info->entryName, lpszDisplayName) == 0)
+        if (StrCmpNW(info->entryName, lpszDisplayName, length) == 0)
             break;
     }
 
-    if (hr != S_OK)
+    // if has remaining path to parse (and the path didn't just terminate in a backslash)
+    if (end && wcslen(end) > 1)
     {
-        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
-    }
+        CComPtr<IShellFolder> psfChild;
+        hr = BindToObject(*ppidl, pbcReserved, IID_PPV_ARG(IShellFolder, &psfChild));
+        if (FAILED_UNEXPECTEDLY(hr))
+            return hr;
 
-    if (pchEaten || pdwAttributes)
-    {
-        if (pchEaten)
-            *pchEaten = wcslen(info->entryName);
+        LPITEMIDLIST child;
+        hr = psfChild->ParseDisplayName(hwndOwner, pbcReserved, end + 1, pchEaten, &child, pdwAttributes);
+        if (FAILED(hr))
+            return hr;
+
+        LPITEMIDLIST old = *ppidl;
+        *ppidl = ILCombine(old, child);
+        ILFree(old);
 
+        // Count the path separator
+        if (pchEaten)
+            (*pchEaten) += 1;
+    }
+    else
+    {
         if (pdwAttributes)
             *pdwAttributes = CNtObjectPidlHelper::ConvertAttributes(info, pdwAttributes);
     }
 
+    if (pchEaten)
+        *pchEaten += wcslen(info->entryName);
+
     return S_OK;
 }
 
@@ -398,7 +417,6 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::BindToObject(
         WCHAR path[MAX_PATH];
 
         StringCbCopyW(path, _countof(path), m_NtPath);
-
         PathAppendW(path, info->entryName);
 
         LPITEMIDLIST first = ILCloneFirst(pidl);
@@ -440,9 +458,17 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::BindToObject(
                 if (FAILED_UNEXPECTEDLY(hr))
                     return hr;
 
-                hr = psfDesktop->ParseDisplayName(NULL, NULL, path, NULL, &first, NULL);
+                LPITEMIDLIST pidl;
+
+                hr = psfDesktop->ParseDisplayName(NULL, NULL, path, NULL, &pidl, NULL);
                 if (FAILED_UNEXPECTEDLY(hr))
                     return hr;
+
+                CComPtr<IShellFolder> psfChild;
+                hr =  psfDesktop->BindToObject(pidl, NULL, riid, ppvOut);
+                ILFree(pidl);
+
+                return hr;
             }
             else
             {
@@ -533,9 +559,9 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::CreateViewObject(
 
     SFV_CREATE sfv;
     sfv.cbSize = sizeof(sfv);
-    sfv.pshf = this;
+    sfv.pshf = static_cast<IShellFolder*>(this);
     sfv.psvOuter = NULL;
-    sfv.psfvcb = this;
+    sfv.psfvcb = static_cast<IShellFolderViewCB*>(this);
 
     return SHCreateShellFolderView(&sfv, (IShellView**) ppvOut);
 }