From eb4e4b6e9fda041daeb7f49633ed09a3e86b2d67 Mon Sep 17 00:00:00 2001 From: David Quintana Date: Wed, 21 Jun 2017 22:32:34 +0000 Subject: [PATCH] [NTOBJSHEX] * 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 | 9 ++-- .../dll/shellext/ntobjshex/ntobjfolder.cpp | 52 ++++++++++++++----- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/reactos/dll/shellext/ntobjshex/ntobjenum.cpp b/reactos/dll/shellext/ntobjshex/ntobjenum.cpp index 0e4bba0eccd..0d205e4e7d5 100644 --- a/reactos/dll/shellext/ntobjshex/ntobjenum.cpp +++ b/reactos/dll/shellext/ntobjshex/ntobjenum.cpp @@ -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); diff --git a/reactos/dll/shellext/ntobjshex/ntobjfolder.cpp b/reactos/dll/shellext/ntobjshex/ntobjfolder.cpp index fb1b12b1d1b..aef53a74d6c 100644 --- a/reactos/dll/shellext/ntobjshex/ntobjfolder.cpp +++ b/reactos/dll/shellext/ntobjshex/ntobjfolder.cpp @@ -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 psfChild; + hr = BindToObject(*ppidl, pbcReserved, IID_PPV_ARG(IShellFolder, &psfChild)); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; - if (pchEaten || pdwAttributes) - { + 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 = wcslen(info->entryName); - + (*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 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(this); sfv.psvOuter = NULL; - sfv.psfvcb = this; + sfv.psfvcb = static_cast(this); return SHCreateShellFolderView(&sfv, (IShellView**) ppvOut); }