StringCbCopyExW(buffer, sizeof(buffer), path, &pend, NULL, 0);
if (pend[-1] != '\\')
+ {
*pend++ = '\\';
+ *pend = 0;
+ }
StringCbCatW(buffer, sizeof(buffer), entryName);
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);
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);
if (FAILED(hr))
return hr;
+ PWSTR end = StrChrW(lpszDisplayName, '\\');
+ int length = end ? end - lpszDisplayName : wcslen(lpszDisplayName);
+
while (TRUE)
{
hr = it->Next(1, ppidl, NULL);
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;
}
WCHAR path[MAX_PATH];
StringCbCopyW(path, _countof(path), m_NtPath);
-
PathAppendW(path, info->entryName);
LPITEMIDLIST first = ILCloneFirst(pidl);
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
{
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);
}