Author: dquintana Date: Fri Jun 23 23:23:17 2017 New Revision: 75177
URL: http://svn.reactos.org/svn/reactos?rev=75177&view=rev Log: [NTOBJSHEX] Make nt object symlinks work more like shortcuts. Fixes the addressbar not quite knowing what to show when you click on a symlink.
Modified: trunk/reactos/dll/shellext/ntobjshex/foldercommon.h trunk/reactos/dll/shellext/ntobjshex/ntobjfolder.cpp trunk/reactos/dll/shellext/ntobjshex/ntobjfolder.h trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp trunk/reactos/dll/shellext/ntobjshex/regfolder.h
Modified: trunk/reactos/dll/shellext/ntobjshex/foldercommon.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/fold... ============================================================================== --- trunk/reactos/dll/shellext/ntobjshex/foldercommon.h [iso-8859-1] (original) +++ trunk/reactos/dll/shellext/ntobjshex/foldercommon.h [iso-8859-1] Fri Jun 23 23:23:17 2017 @@ -187,11 +187,6 @@
LPITEMIDLIST fullPidl = ILCombine(m_shellPidl, first);
- if (IsSymLink(info)) - { - return RedirectToSymLink(info, first, rest, pbcReserved, (IShellFolder**)ppvOut); - } - CComPtr<IShellFolder> psfChild; hr = InternalBindToObject(path, info, first, rest, fullPidl, pbcReserved, &psfChild);
@@ -225,16 +220,14 @@ LPBC pbcReserved, IShellFolder** ppsfChild) PURE;
+ virtual HRESULT STDMETHODCALLTYPE ResolveSymLink( + const TItemId * info, + LPITEMIDLIST * fullPidl) + { + return E_NOTIMPL; + } + public: - virtual HRESULT STDMETHODCALLTYPE RedirectToSymLink( - const TItemId * info, - LPITEMIDLIST first, - LPCITEMIDLIST rest, - LPBC pbcReserved, - IShellFolder ** ppsfChild) - { - return E_NOTIMPL; - }
virtual HRESULT STDMETHODCALLTYPE BindToStorage( LPCITEMIDLIST pidl, @@ -422,7 +415,40 @@
HKEY keys[1];
+ LPITEMIDLIST parent = m_shellPidl; + + CComPtr<IShellFolder> psfParent = this; + + LPCITEMIDLIST child; + int nkeys = _countof(keys); + if (cidl == 1 && IsSymLink(apidl[0])) + { + const TItemId * info; + HRESULT hr = GetInfoFromPidl(apidl[0], &info); + if (FAILED(hr)) + return hr; + + LPITEMIDLIST target; + hr = ResolveSymLink(info, &target); + if (FAILED(hr)) + return hr; + + CComPtr<IShellFolder> psfTarget; + hr = ::SHBindToParent(target, IID_PPV_ARG(IShellFolder, &psfTarget), &child); + if (FAILED(hr)) + { + ILFree(target); + return hr; + } + + parent = ILClone(target); + ILRemoveLastID(parent); + psfParent = psfTarget; + + apidl = &child; + } + if (cidl == 1 && IsFolder(apidl[0])) { res = RegOpenKey(HKEY_CLASSES_ROOT, L"Folder", keys + 0); @@ -434,7 +460,7 @@ nkeys = 0; }
- HRESULT hr = CDefFolderMenu_Create2(m_shellPidl, hwndOwner, cidl, apidl, this, DefCtxMenuCallback, nkeys, keys, &pcm); + HRESULT hr = CDefFolderMenu_Create2(parent, hwndOwner, cidl, apidl, psfParent, DefCtxMenuCallback, nkeys, keys, &pcm); if (FAILED_UNEXPECTEDLY(hr)) return hr;
@@ -635,9 +661,29 @@ const TItemId * entry, PULONG inMask) PURE;
- virtual BOOL STDMETHODCALLTYPE IsFolder(LPCITEMIDLIST pcidl) PURE; + virtual BOOL STDMETHODCALLTYPE IsFolder(LPCITEMIDLIST pcidl) + { + const TItemId * info; + + HRESULT hr = GetInfoFromPidl(pcidl, &info); + if (FAILED(hr)) + return hr; + + return IsFolder(info); + }
virtual BOOL STDMETHODCALLTYPE IsFolder(const TItemId * info) PURE; + + virtual BOOL STDMETHODCALLTYPE IsSymLink(LPCITEMIDLIST pcidl) + { + const TItemId * info; + + HRESULT hr = GetInfoFromPidl(pcidl, &info); + if (FAILED(hr)) + return hr; + + return IsSymLink(info); + }
virtual BOOL STDMETHODCALLTYPE IsSymLink(const TItemId * info) {
Modified: trunk/reactos/dll/shellext/ntobjshex/ntobjfolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/ntob... ============================================================================== --- trunk/reactos/dll/shellext/ntobjshex/ntobjfolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/shellext/ntobjshex/ntobjfolder.cpp [iso-8859-1] Fri Jun 23 23:23:17 2017 @@ -125,72 +125,56 @@ return info->objectType == SYMBOLICLINK_OBJECT; }
-HRESULT STDMETHODCALLTYPE CNtObjectFolder::RedirectToSymLink( +HRESULT STDMETHODCALLTYPE CNtObjectFolder::ResolveSymLink( const NtPidlEntry * info, - LPITEMIDLIST first, - LPCITEMIDLIST rest, - LPBC pbcReserved, - IShellFolder ** ppsfChild) -{ - HRESULT hr; - + LPITEMIDLIST * fullPidl) +{ WCHAR wbLink[MAX_PATH] = { 0 }; UNICODE_STRING link; RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
- hr = GetNTObjectSymbolicLinkTarget(m_NtPath, info->entryName, &link); + *fullPidl = NULL; + + HRESULT hr = GetNTObjectSymbolicLinkTarget(m_NtPath, info->entryName, &link); if (FAILED_UNEXPECTEDLY(hr)) return hr;
WCHAR path[MAX_PATH];
- if (link.Length > 0) - { - if (link.Buffer[1] == L':' && isalphaW(link.Buffer[0])) - { - StringCbCopyNW(path, _countof(path), link.Buffer, link.Length); - - 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; - - hr = psfDesktop->BindToObject(rest, pbcReserved, IID_PPV_ARG(IShellFolder, ppsfChild)); - if (FAILED(hr)) - return hr; - - return S_FALSE;; - } - - StringCbCopyW(path, _countof(path), L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{845B0FB2-66E0-416B-8F91-314E23F7C12D}"); - PathAppend(path, link.Buffer); + if (link.Length == 0) + return E_UNEXPECTED; + + if (link.Buffer[1] == L':' && isalphaW(link.Buffer[0])) + { + StringCbCopyNW(path, _countof(path), link.Buffer, link.Length);
CComPtr<IShellFolder> psfDesktop; hr = SHGetDesktopFolder(&psfDesktop); if (FAILED_UNEXPECTEDLY(hr)) return hr;
- LPITEMIDLIST pidl; - - hr = psfDesktop->ParseDisplayName(NULL, NULL, path, NULL, &pidl, NULL); - if (FAILED_UNEXPECTEDLY(hr)) - return hr; - - CComPtr<IShellFolder> psfChild; - hr = psfDesktop->BindToObject(pidl, pbcReserved, IID_PPV_ARG(IShellFolder, ppsfChild)); - ILFree(pidl); - - if (FAILED(hr)) - return hr; - - return S_FALSE;; - } - - return E_UNEXPECTED; + return psfDesktop->ParseDisplayName(NULL, NULL, path, NULL, fullPidl, NULL); + } + + StringCbCopyW(path, _countof(path), L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{845B0FB2-66E0-416B-8F91-314E23F7C12D}"); + PathAppend(path, link.Buffer); + + CComPtr<IShellFolder> psfDesktop; + hr = SHGetDesktopFolder(&psfDesktop); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + LPITEMIDLIST pidl; + + hr = psfDesktop->ParseDisplayName(NULL, NULL, path, NULL, &pidl, NULL); + if (FAILED(hr)) + return hr; + + *fullPidl = pidl; + + DumpIdList(pidl); + + return S_OK; }
HRESULT STDMETHODCALLTYPE CNtObjectFolder::InternalBindToObject( @@ -487,15 +471,6 @@ return flags & mask; }
-BOOL CNtObjectFolder::IsFolder(LPCITEMIDLIST pcidl) -{ - NtPidlEntry * info = (NtPidlEntry*) &(pcidl->mkid); - if ((info->cb < sizeof(NtPidlEntry)) || (info->magic != NT_OBJECT_PIDL_MAGIC)) - return FALSE; - - return IsFolder(info); -} - BOOL CNtObjectFolder::IsFolder(const NtPidlEntry * info) { return (info->objectType == DIRECTORY_OBJECT) ||
Modified: trunk/reactos/dll/shellext/ntobjshex/ntobjfolder.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/ntob... ============================================================================== --- trunk/reactos/dll/shellext/ntobjshex/ntobjfolder.h [iso-8859-1] (original) +++ trunk/reactos/dll/shellext/ntobjshex/ntobjfolder.h [iso-8859-1] Fri Jun 23 23:23:17 2017 @@ -63,6 +63,7 @@ SHCONTF grfFlags, IEnumIDList **ppenumIDList);
+protected: virtual HRESULT STDMETHODCALLTYPE InternalBindToObject( PWSTR path, const NtPidlEntry * info, @@ -71,13 +72,12 @@ LPITEMIDLIST fullPidl, LPBC pbcReserved, IShellFolder** ppsfChild); - virtual HRESULT STDMETHODCALLTYPE RedirectToSymLink( + + virtual HRESULT STDMETHODCALLTYPE ResolveSymLink( const NtPidlEntry * info, - LPITEMIDLIST first, - LPCITEMIDLIST rest, - LPBC pbcReserved, - IShellFolder ** ppsfChild); + LPITEMIDLIST * fullPidl);
+public: virtual HRESULT STDMETHODCALLTYPE GetDefaultColumnState( UINT iColumn, SHCOLSTATEF *pcsFlags); @@ -105,7 +105,6 @@ protected: virtual HRESULT STDMETHODCALLTYPE CompareIDs(LPARAM lParam, const NtPidlEntry * first, const NtPidlEntry * second); virtual ULONG STDMETHODCALLTYPE ConvertAttributes(const NtPidlEntry * entry, PULONG inMask); - virtual BOOL STDMETHODCALLTYPE IsFolder(LPCITEMIDLIST pcidl); virtual BOOL STDMETHODCALLTYPE IsFolder(const NtPidlEntry * info); virtual BOOL STDMETHODCALLTYPE IsSymLink(const NtPidlEntry * info);
Modified: trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/regf... ============================================================================== --- trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp [iso-8859-1] Fri Jun 23 23:23:17 2017 @@ -419,15 +419,6 @@ return flags & mask; }
-BOOL CRegistryFolder::IsFolder(LPCITEMIDLIST pcidl) -{ - RegPidlEntry * entry = (RegPidlEntry*) &(pcidl->mkid); - if ((entry->cb < sizeof(RegPidlEntry)) || (entry->magic != REGISTRY_PIDL_MAGIC)) - return FALSE; - - return IsFolder(entry); -} - BOOL CRegistryFolder::IsFolder(const RegPidlEntry * info) { return (info->entryType == REG_ENTRY_KEY) ||(info->entryType == REG_ENTRY_ROOT);
Modified: trunk/reactos/dll/shellext/ntobjshex/regfolder.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/regf... ============================================================================== --- trunk/reactos/dll/shellext/ntobjshex/regfolder.h [iso-8859-1] (original) +++ trunk/reactos/dll/shellext/ntobjshex/regfolder.h [iso-8859-1] Fri Jun 23 23:23:17 2017 @@ -63,6 +63,7 @@ SHCONTF grfFlags, IEnumIDList **ppenumIDList);
+protected: virtual HRESULT STDMETHODCALLTYPE InternalBindToObject( PWSTR path, const RegPidlEntry * info, @@ -72,6 +73,7 @@ LPBC pbcReserved, IShellFolder** ppsfChild);
+public: virtual HRESULT STDMETHODCALLTYPE GetDefaultColumnState( UINT iColumn, SHCOLSTATEF *pcsFlags); @@ -99,7 +101,6 @@ protected: virtual HRESULT STDMETHODCALLTYPE CompareIDs(LPARAM lParam, const RegPidlEntry * first, const RegPidlEntry * second); virtual ULONG STDMETHODCALLTYPE ConvertAttributes(const RegPidlEntry * entry, PULONG inMask); - virtual BOOL STDMETHODCALLTYPE IsFolder(LPCITEMIDLIST pcidl); virtual BOOL STDMETHODCALLTYPE IsFolder(const RegPidlEntry * info);
virtual HRESULT GetInfoFromPidl(LPCITEMIDLIST pcidl, const RegPidlEntry ** pentry);