[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
This commit is contained in:
David Quintana 2017-06-21 22:32:34 +00:00
parent 04201ba762
commit eb4e4b6e9f
2 changed files with 45 additions and 16 deletions

View 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);

View 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)
{
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<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);
}