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/fol…
==============================================================================
--- 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/nto…
==============================================================================
--- 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/nto…
==============================================================================
--- 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/reg…
==============================================================================
--- 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/reg…
==============================================================================
--- 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);