/*
* PROJECT: ReactOS shell extensions
* LICENSE: GPL - See COPYING in the top level directory
- * FILE: dll\shellext\ntobjshex\ntobjns.cpp
+ * FILE: dll/shellext/ntobjshex/regfolder.cpp
* PURPOSE: NT Object Namespace shell extension
* PROGRAMMERS: David Quintana <gigaherz@gmail.com>
*/
#include "precomp.h"
-#include "ntobjutil.h"
-#include <ntquery.h>
-#include "util.h"
-#define DFM_MERGECONTEXTMENU 1 // uFlags LPQCMINFO
-#define DFM_INVOKECOMMAND 2 // idCmd pszArgs
-#define DFM_INVOKECOMMANDEX 12 // idCmd PDFMICS
-#define DFM_GETDEFSTATICID 14 // idCmd * 0
-
-#define SHCIDS_ALLFIELDS 0x80000000L
-#define SHCIDS_CANONICALONLY 0x10000000L
-
-#define GET_SHGDN_FOR(dwFlags) ((DWORD)dwFlags & (DWORD)0x0000FF00)
-#define GET_SHGDN_RELATION(dwFlags) ((DWORD)dwFlags & (DWORD)0x000000FF)
-
-WINE_DEFAULT_DEBUG_CHANNEL(ntobjshex);
-
-// {1C6D6E08-2332-4A7B-A94D-6432DB2B5AE6}
-const GUID CLSID_RegistryFolder = { 0x1c6d6e08, 0x2332, 0x4a7b, { 0xa9, 0x4d, 0x64, 0x32, 0xdb, 0x2b, 0x5a, 0xe6 } };
-
-// {18A4B504-F6D8-4D8A-8661-6296514C2CF0}
-static const GUID GUID_RegistryColumns = { 0x18a4b504, 0xf6d8, 0x4d8a, { 0x86, 0x61, 0x62, 0x96, 0x51, 0x4c, 0x2c, 0xf0 } };
-
-enum RegistryColumns
-{
- REGISTRY_COLUMN_NAME = 0,
- REGISTRY_COLUMN_TYPE = 1,
- REGISTRY_COLUMN_VALUE = 2,
-};
-
-class CRegistryFolderExtractIcon :
- public CComObjectRootEx<CComMultiThreadModelNoCS>,
- public IExtractIconW
-{
- PCIDLIST_ABSOLUTE m_pcidlFolder;
- PCITEMID_CHILD m_pcidlChild;
-
-public:
- CRegistryFolderExtractIcon() :
- m_pcidlFolder(NULL),
- m_pcidlChild(NULL)
- {
-
- }
-
- virtual ~CRegistryFolderExtractIcon()
- {
- if (m_pcidlFolder)
- ILFree((LPITEMIDLIST) m_pcidlFolder);
- if (m_pcidlChild)
- ILFree((LPITEMIDLIST) m_pcidlChild);
- }
-
- HRESULT Initialize(PCIDLIST_ABSOLUTE parent, UINT cidl, PCUITEMID_CHILD_ARRAY apidl)
- {
- m_pcidlFolder = ILClone(parent);
- if (cidl != 1)
- return E_INVALIDARG;
- m_pcidlChild = ILClone(apidl[0]);
- return S_OK;
- }
-
- virtual HRESULT STDMETHODCALLTYPE GetIconLocation(
- UINT uFlags,
- LPWSTR szIconFile,
- UINT cchMax,
- INT *piIndex,
- UINT *pwFlags)
- {
- const RegPidlEntry * entry = (RegPidlEntry *) m_pcidlChild;
-
- if ((entry->cb < sizeof(RegPidlEntry)) || (entry->magic != REGISTRY_PIDL_MAGIC))
- return E_INVALIDARG;
-
- UINT flags = 0;
-
- switch (entry->entryType)
- {
- case REG_ENTRY_KEY:
- case REG_ENTRY_ROOT:
- GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
- *piIndex = -IDI_REGISTRYKEY;
- *pwFlags = flags;
- return S_OK;
- case REG_ENTRY_VALUE:
- GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
- *piIndex = -IDI_REGISTRYVALUE;
- *pwFlags = flags;
- return S_OK;
- default:
- GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
- *piIndex = -IDI_NTOBJECTITEM;
- *pwFlags = flags;
- return S_OK;
- }
- }
-
- virtual HRESULT STDMETHODCALLTYPE Extract(
- LPCWSTR pszFile,
- UINT nIconIndex,
- HICON *phiconLarge,
- HICON *phiconSmall,
- UINT nIconSize)
- {
- return SHDefExtractIconW(pszFile, nIconIndex, 0, phiconLarge, phiconSmall, nIconSize);
- }
-
- DECLARE_NOT_AGGREGATABLE(CRegistryFolderExtractIcon)
- DECLARE_PROTECT_FINAL_CONSTRUCT()
-
- BEGIN_COM_MAP(CRegistryFolderExtractIcon)
- COM_INTERFACE_ENTRY_IID(IID_IExtractIconW, IExtractIconW)
- END_COM_MAP()
-
-};
-
-class CRegistryPidlManager
-{
-private:
- PWSTR m_ntPath;
- HKEY m_hRoot;
-
- HDPA m_hDpa;
- UINT m_hDpaCount;
-
- int DpaDeleteCallback(RegPidlEntry * info)
- {
- CoTaskMemFree(info);
- return 0;
- }
-
- static int CALLBACK s_DpaDeleteCallback(void *pItem, void *pData)
- {
- CRegistryPidlManager * mf = (CRegistryPidlManager*) pData;
- RegPidlEntry * item = (RegPidlEntry*) pItem;
- return mf->DpaDeleteCallback(item);
- }
-
-public:
- CRegistryPidlManager() :
- m_ntPath(NULL),
- m_hRoot(NULL),
- m_hDpa(NULL),
- m_hDpaCount(0)
- {
- }
-
- ~CRegistryPidlManager()
- {
- DPA_DestroyCallback(m_hDpa, s_DpaDeleteCallback, this);
- }
-
- HRESULT Initialize(PWSTR ntPath, HKEY hRoot)
- {
- m_ntPath = ntPath;
- m_hRoot = hRoot;
-
- m_hDpa = DPA_Create(10);
-
- if (!m_hDpa)
- return E_OUTOFMEMORY;
-
- if (wcslen(m_ntPath) == 0 && m_hRoot == NULL)
- {
- HRESULT hr = EnumerateRootKeys(m_hDpa, &m_hDpaCount);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
- }
- else
- {
- HRESULT hr = EnumerateRegistryKey(m_hDpa, m_ntPath, m_hRoot, &m_hDpaCount);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
- }
-
- return S_OK;
- }
-
- HRESULT FindPidlInList(PCUITEMID_CHILD pcidl, RegPidlEntry ** pinfo)
- {
- HRESULT hr;
-
- if (!m_hDpa)
- {
- return E_FAIL;
- }
-
- RegPidlEntry * info = (RegPidlEntry *) pcidl;
- if ((info->cb < sizeof(RegPidlEntry)) || (info->magic != REGISTRY_PIDL_MAGIC))
- {
- ERR("FindPidlInList: Requested pidl is not of the correct type.\n");
- return E_INVALIDARG;
- }
-
- TRACE("Searching for pidl { cb=%d } in a list of %d items\n", pcidl->mkid.cb, m_hDpaCount);
-
- for (UINT i = 0; i < m_hDpaCount; i++)
- {
- RegPidlEntry * pInfo = (RegPidlEntry *) DPA_GetPtr(m_hDpa, i);
- ASSERT(pInfo);
-
- hr = CompareIDs(0, pInfo, pcidl);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- if (hr == S_OK)
- {
- *pinfo = pInfo;
- return S_OK;
- }
- else
- {
- TRACE("Comparison returned %d\n", (int) (short) (hr & 0xFFFF));
- }
- }
-
- ERR("PIDL NOT FOUND: Requested filename: %S\n", info->entryName);
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
-
- HRESULT FindByName(LPCWSTR strParsingName, RegPidlEntry ** pinfo)
- {
- if (!m_hDpa)
- {
- return E_FAIL;
- }
-
- TRACE("Searching for '%S' in a list of %d items\n", strParsingName, m_hDpaCount);
-
- for (int i = 0; i < (int) m_hDpaCount; i++)
- {
- RegPidlEntry * pInfo = (RegPidlEntry *) DPA_GetPtr(m_hDpa, i);
- ASSERT(pInfo);
-
- int order = CompareStringW(GetThreadLocale(), NORM_IGNORECASE,
- pInfo->entryName, wcslen(pInfo->entryName),
- strParsingName, wcslen(strParsingName));
-
- if (order == CSTR_EQUAL)
- {
- *pinfo = pInfo;
- return S_OK;
- }
- }
-
- TRACE("Pidl not found\n");
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
-
- HRESULT GetPidl(UINT index, RegPidlEntry ** pEntry)
- {
- *pEntry = NULL;
-
- RegPidlEntry * entry = (RegPidlEntry *) DPA_GetPtr(m_hDpa, index);
- if (!entry)
- {
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
-
- *pEntry = entry;
- return S_OK;
- }
-
- HRESULT GetCount(UINT * count)
- {
- *count = m_hDpaCount;
- return S_OK;
- }
-
-
- static LPITEMIDLIST CreatePidlFromItem(RegPidlEntry * entry)
- {
- LPITEMIDLIST idl = (LPITEMIDLIST) CoTaskMemAlloc(entry->cb + 2);
- if (!idl)
- return NULL;
- memset(idl, 0, entry->cb + 2);
- memcpy(idl, entry, entry->cb);
- return idl;
- }
-
- HRESULT CompareIDs(LPARAM lParam, RegPidlEntry * first, RegPidlEntry * second)
- {
- if (LOWORD(lParam) != 0)
- {
- DbgPrint("Unsupported sorting mode.\n");
- return E_INVALIDARG;
- }
-
- if (HIWORD(lParam) == SHCIDS_ALLFIELDS)
- {
- int minsize = min(first->cb, second->cb);
- int ord = memcmp(second, first, minsize);
-
- if (ord != 0)
- return MAKE_HRESULT(0, 0, (USHORT) ord);
-
- if (second->cb > first->cb)
- return MAKE_HRESULT(0, 0, (USHORT) 1);
- if (second->cb < first->cb)
- return MAKE_HRESULT(0, 0, (USHORT) -1);
- }
- else if (HIWORD(lParam) == SHCIDS_CANONICALONLY)
- {
- int minlength = min(first->entryNameLength, second->entryNameLength);
- int ord = StrCmpNW(first->entryName, second->entryName, minlength);
-
- if (ord != 0)
- return MAKE_HRESULT(0, 0, (USHORT) ord);
-
- if (second->entryNameLength > first->entryNameLength)
- return MAKE_HRESULT(0, 0, (USHORT) 1);
- if (second->entryNameLength < first->entryNameLength)
- return MAKE_HRESULT(0, 0, (USHORT) -1);
- }
- else
- {
- bool f1 = (first->entryType == REG_ENTRY_KEY) || (first->entryType == REG_ENTRY_ROOT);
- bool f2 = (second->entryType == REG_ENTRY_KEY) || (second->entryType == REG_ENTRY_ROOT);
-
- if (f1 && !f2)
- return MAKE_HRESULT(0, 0, (USHORT) -1);
- if (f2 && !f1)
- return MAKE_HRESULT(0, 0, (USHORT) 1);
-
- int minlength = min(first->entryNameLength, second->entryNameLength);
- int ord = StrCmpNW(first->entryName, second->entryName, minlength);
-
- if (ord != 0)
- return MAKE_HRESULT(0, 0, (USHORT) ord);
-
- if (second->entryNameLength > first->entryNameLength)
- return MAKE_HRESULT(0, 0, (USHORT) 1);
- if (second->entryNameLength < first->entryNameLength)
- return MAKE_HRESULT(0, 0, (USHORT) -1);
- }
-
- return S_OK;
- }
-
- HRESULT CompareIDs(LPARAM lParam, RegPidlEntry * first, LPCITEMIDLIST pcidl)
- {
- LPCITEMIDLIST p = pcidl;
- RegPidlEntry * second = (RegPidlEntry*) &(p->mkid);
- if ((second->cb < sizeof(RegPidlEntry)) || (second->magic != REGISTRY_PIDL_MAGIC))
- return E_INVALIDARG;
-
- return CompareIDs(lParam, first, second);
- }
-
- HRESULT CompareIDs(LPARAM lParam, LPCITEMIDLIST pcidl1, LPCITEMIDLIST pcidl2)
- {
- LPCITEMIDLIST p = pcidl1;
- RegPidlEntry * first = (RegPidlEntry*) &(p->mkid);
- if ((first->cb < sizeof(RegPidlEntry)) || (first->magic != REGISTRY_PIDL_MAGIC))
- return E_INVALIDARG;
-
- return CompareIDs(lParam, first, pcidl2);
- }
-
- ULONG ConvertAttributes(RegPidlEntry * entry, PULONG inMask)
- {
- ULONG mask = inMask ? *inMask : 0xFFFFFFFF;
- ULONG flags = 0;
-
- if ((entry->entryType == REG_ENTRY_KEY) ||
- (entry->entryType == REG_ENTRY_ROOT))
- flags |= SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_BROWSABLE;
-
- return flags & mask;
- }
-
- BOOL IsFolder(LPCITEMIDLIST pcidl)
- {
- RegPidlEntry * entry;
- HRESULT hr = FindPidlInList(pcidl, &entry);
- if (FAILED_UNEXPECTEDLY(hr))
- return FALSE;
-
- return (entry->entryType == REG_ENTRY_KEY) ||
- (entry->entryType == REG_ENTRY_ROOT);
- }
-
- HRESULT FormatValueData(DWORD contentType, PVOID td, DWORD contentsLength, PCWSTR * strContents)
- {
- switch (contentType)
- {
- case 0:
- {
- PCWSTR strTodo = L"";
- DWORD bufferLength = (wcslen(strTodo) + 1) * sizeof(WCHAR);
- PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
- StringCbCopyW(strValue, bufferLength, strTodo);
- *strContents = strValue;
- return S_OK;
- }
- case REG_SZ:
- case REG_EXPAND_SZ:
- {
- PWSTR strValue = (PWSTR) CoTaskMemAlloc(contentsLength + sizeof(WCHAR));
- StringCbCopyNW(strValue, contentsLength + sizeof(WCHAR), (LPCWSTR) td, contentsLength);
- *strContents = strValue;
- return S_OK;
- }
- case REG_DWORD:
- {
- DWORD bufferLength = 64 * sizeof(WCHAR);
- PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
- StringCbPrintfW(strValue, bufferLength, L"0x%08x (%d)",
- *(DWORD*) td, *(DWORD*) td);
- *strContents = strValue;
- return S_OK;
- }
- case REG_QWORD:
- {
- DWORD bufferLength = 64 * sizeof(WCHAR);
- PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
- StringCbPrintfW(strValue, bufferLength, L"0x%016llx (%d)",
- *(LARGE_INTEGER*) td, ((LARGE_INTEGER*) td)->QuadPart);
- *strContents = strValue;
- return S_OK;
- }
- default:
- {
- PCWSTR strTodo = L"<TODO: Convert value for display>";
- DWORD bufferLength = (wcslen(strTodo) + 1) * sizeof(WCHAR);
- PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
- StringCbCopyW(strValue, bufferLength, strTodo);
- *strContents = strValue;
- return S_OK;
- }
- }
- }
-
- HRESULT FormatContentsForDisplay(RegPidlEntry * info, PCWSTR * strContents)
- {
- PVOID td = (((PBYTE) info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
-
- if (info->entryType == REG_ENTRY_VALUE_WITH_CONTENT)
- {
- if (info->contentsLength > 0)
- {
- return FormatValueData(info->contentType, td, info->contentsLength, strContents);
- }
- }
- else if (info->entryType == REG_ENTRY_VALUE)
- {
- PVOID valueData;
- DWORD valueLength;
- HRESULT hr = ReadRegistryValue(NULL, m_ntPath, info->entryName, &valueData, &valueLength);
- if (FAILED_UNEXPECTEDLY(hr))
- {
- PCWSTR strEmpty = L"(Error reading value)";
- DWORD bufferLength = (wcslen(strEmpty) + 1) * sizeof(WCHAR);
- PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
- StringCbCopyW(strValue, bufferLength, strEmpty);
- *strContents = strValue;
- return S_OK;
- }
-
- if (valueLength > 0)
- {
- hr = FormatValueData(info->contentType, valueData, valueLength, strContents);
-
- CoTaskMemFree(valueData);
-
- return hr;
- }
- }
- else
- {
- PCWSTR strEmpty = L"";
- DWORD bufferLength = (wcslen(strEmpty) + 1) * sizeof(WCHAR);
- PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
- StringCbCopyW(strValue, bufferLength, strEmpty);
- *strContents = strValue;
- return S_OK;
- }
-
- PCWSTR strEmpty = L"(Empty)";
- DWORD bufferLength = (wcslen(strEmpty) + 1) * sizeof(WCHAR);
- PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
- StringCbCopyW(strValue, bufferLength, strEmpty);
- *strContents = strValue;
- return S_OK;
- }
-};
-
-class CRegistryFolderEnum :
- public CComObjectRootEx<CComMultiThreadModelNoCS>,
- public IEnumIDList
-{
-private:
- CComPtr<CRegistryFolder> m_Folder;
-
- HWND m_HwndOwner;
- SHCONTF m_Flags;
-
- UINT m_Index;
- UINT m_Count;
-
-public:
- CRegistryFolderEnum() :
- m_HwndOwner(NULL),
- m_Flags(0),
- m_Index(0),
- m_Count(0)
- {
- }
-
- virtual ~CRegistryFolderEnum()
- {
- }
-
- HRESULT Initialize(CRegistryFolder * folder, HWND hwndOwner, SHCONTF flags)
- {
- m_Folder = folder;
-
- m_Folder->GetManager().GetCount(&m_Count);
-
- m_HwndOwner = hwndOwner;
- m_Flags = flags;
-
- return Reset();
- }
-
- virtual HRESULT STDMETHODCALLTYPE Next(
- ULONG celt,
- LPITEMIDLIST *rgelt,
- ULONG *pceltFetched)
- {
- if (pceltFetched)
- *pceltFetched = 0;
-
- if (m_Index >= m_Count)
- return S_FALSE;
-
- for (int i = 0; i < (int) celt;)
- {
- RegPidlEntry * tinfo;
- BOOL flagsOk = FALSE;
-
- do {
- HRESULT hr = m_Folder->GetManager().GetPidl(m_Index++, &tinfo);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- switch (tinfo->entryType)
- {
- case REG_ENTRY_KEY:
- case REG_ENTRY_ROOT:
- flagsOk = (m_Flags & SHCONTF_FOLDERS) != 0;
- break;
- default:
- flagsOk = (m_Flags & SHCONTF_NONFOLDERS) != 0;
- break;
- }
- } while (m_Index < m_Count && !flagsOk);
-
- if (flagsOk)
- {
- if (rgelt)
- rgelt[i] = m_Folder->GetManager().CreatePidlFromItem(tinfo);
- i++;
- }
-
- if (m_Index == m_Count)
- {
- if (pceltFetched)
- *pceltFetched = i;
- return (i == (int) celt) ? S_OK : S_FALSE;
- }
- }
-
- if (pceltFetched) *pceltFetched = celt;
- return S_OK;
- }
-
- virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
- {
- return Next(celt, NULL, NULL);
- }
-
- virtual HRESULT STDMETHODCALLTYPE Reset()
- {
- m_Index = 0;
- return S_OK;
- }
-
- virtual HRESULT STDMETHODCALLTYPE Clone(IEnumIDList **ppenum)
- {
- return ShellObjectCreatorInit<CRegistryFolderEnum>(m_Folder, m_HwndOwner, m_Flags, IID_PPV_ARG(IEnumIDList, ppenum));
- }
-
- DECLARE_NOT_AGGREGATABLE(CRegistryFolderEnum)
- DECLARE_PROTECT_FINAL_CONSTRUCT()
-
- BEGIN_COM_MAP(CRegistryFolderEnum)
- COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
- END_COM_MAP()
-
-};
-
-//-----------------------------------------------------------------------------
-// CRegistryFolder
-
-CRegistryFolder::CRegistryFolder() :
- m_PidlManager(NULL),
- m_shellPidl(NULL)
-{
-}
-
-CRegistryFolder::~CRegistryFolder()
-{
- TRACE("Destroying CRegistryFolder %p\n", this);
-}
-
-// IShellFolder
-HRESULT STDMETHODCALLTYPE CRegistryFolder::ParseDisplayName(
- HWND hwndOwner,
- LPBC pbcReserved,
- LPOLESTR lpszDisplayName,
- ULONG *pchEaten,
- LPITEMIDLIST *ppidl,
- ULONG *pdwAttributes)
-{
- HRESULT hr;
- RegPidlEntry * info;
-
- if (!ppidl)
- return E_POINTER;
-
- if (pchEaten)
- *pchEaten = 0;
-
- if (pdwAttributes)
- *pdwAttributes = 0;
-
- TRACE("CRegistryFolder::ParseDisplayName name=%S (ntPath=%S)\n", lpszDisplayName, m_NtPath);
-
- hr = m_PidlManager->FindByName(lpszDisplayName, &info);
- if (FAILED(hr))
- {
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
-
- *ppidl = m_PidlManager->CreatePidlFromItem(info);
-
- if (pchEaten)
- *pchEaten = wcslen(info->entryName);
-
- if (pdwAttributes)
- *pdwAttributes = m_PidlManager->ConvertAttributes(info, pdwAttributes);
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE CRegistryFolder::EnumObjects(
- HWND hwndOwner,
- SHCONTF grfFlags,
- IEnumIDList **ppenumIDList)
-{
- return ShellObjectCreatorInit<CRegistryFolderEnum>(this, hwndOwner, grfFlags, IID_PPV_ARG(IEnumIDList, ppenumIDList));
-}
-
-HRESULT STDMETHODCALLTYPE CRegistryFolder::BindToObject(
- LPCITEMIDLIST pidl,
- LPBC pbcReserved,
- REFIID riid,
- void **ppvOut)
-{
- RegPidlEntry * info;
- HRESULT hr;
-
- if (IsEqualIID(riid, IID_IShellFolder))
- {
- hr = m_PidlManager->FindPidlInList(pidl, &info);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- LPITEMIDLIST first = ILCloneFirst(pidl);
- LPCITEMIDLIST rest = ILGetNext(pidl);
-
- LPITEMIDLIST fullPidl = ILCombine(m_shellPidl, first);
-
- CComPtr<IShellFolder> psfChild;
- if (wcslen(m_NtPath) == 0 && m_hRoot == NULL)
- {
- hr = ShellObjectCreatorInit<CRegistryFolder>(fullPidl, L"", info->rootKey, IID_PPV_ARG(IShellFolder, &psfChild));
- }
- else
- {
- WCHAR path[MAX_PATH];
-
- StringCbCopyW(path, _countof(path), m_NtPath);
-
- PathAppendW(path, info->entryName);
+WINE_DEFAULT_DEBUG_CHANNEL(ntobjshex);
- hr = ShellObjectCreatorInit<CRegistryFolder>(fullPidl, path, m_hRoot, IID_PPV_ARG(IShellFolder, &psfChild));
- }
+// {1C6D6E08-2332-4A7B-A94D-6432DB2B5AE6}
+const GUID CLSID_RegistryFolder = { 0x1c6d6e08, 0x2332, 0x4a7b, { 0xa9, 0x4d, 0x64, 0x32, 0xdb, 0x2b, 0x5a, 0xe6 } };
- ILFree(fullPidl);
- ILFree(first);
+// {18A4B504-F6D8-4D8A-8661-6296514C2CF0}
+static const GUID GUID_RegistryColumns = { 0x18a4b504, 0xf6d8, 0x4d8a, { 0x86, 0x61, 0x62, 0x96, 0x51, 0x4c, 0x2c, 0xf0 } };
- if (rest->mkid.cb > 0)
- {
- return psfChild->BindToObject(rest, pbcReserved, riid, ppvOut);
- }
+enum RegistryColumns
+{
+ REGISTRY_COLUMN_NAME = 0,
+ REGISTRY_COLUMN_TYPE,
+ REGISTRY_COLUMN_VALUE,
+ REGISTRY_COLUMN_END
+};
- return psfChild->QueryInterface(riid, ppvOut);
- }
+// -------------------------------
+// CRegistryFolderExtractIcon
+CRegistryFolderExtractIcon::CRegistryFolderExtractIcon() :
+ m_pcidlFolder(NULL),
+ m_pcidlChild(NULL)
+{
- return E_NOTIMPL;
}
-HRESULT STDMETHODCALLTYPE CRegistryFolder::BindToStorage(
- LPCITEMIDLIST pidl,
- LPBC pbcReserved,
- REFIID riid,
- void **ppvObj)
+CRegistryFolderExtractIcon::~CRegistryFolderExtractIcon()
{
- UNIMPLEMENTED;
- return E_NOTIMPL;
+ if (m_pcidlFolder)
+ ILFree((LPITEMIDLIST)m_pcidlFolder);
+ if (m_pcidlChild)
+ ILFree((LPITEMIDLIST)m_pcidlChild);
}
-HRESULT STDMETHODCALLTYPE CRegistryFolder::CompareIDs(
- LPARAM lParam,
- LPCITEMIDLIST pidl1,
- LPCITEMIDLIST pidl2)
+HRESULT CRegistryFolderExtractIcon::Initialize(LPCWSTR ntPath, PCIDLIST_ABSOLUTE parent, UINT cidl, PCUITEMID_CHILD_ARRAY apidl)
{
- TRACE("CompareIDs\n");
-
- HRESULT hr = m_PidlManager->CompareIDs(lParam, pidl1, pidl2);
- if (hr != S_OK)
- return hr;
-
- LPCITEMIDLIST rest1 = ILGetNext(pidl1);
- LPCITEMIDLIST rest2 = ILGetNext(pidl2);
-
- bool hasNext1 = (rest1->mkid.cb > 0);
- bool hasNext2 = (rest2->mkid.cb > 0);
-
- if (hasNext1 || hasNext2)
- {
- if (hasNext1 && !hasNext2)
- return MAKE_HRESULT(0, 0, (USHORT) -1);
-
- if (hasNext2 && !hasNext1)
- return MAKE_HRESULT(0, 0, (USHORT) 1);
-
- LPCITEMIDLIST first1 = ILCloneFirst(pidl1);
-
- CComPtr<IShellFolder> psfNext;
- hr = BindToObject(first1, NULL, IID_PPV_ARG(IShellFolder, &psfNext));
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- return psfNext->CompareIDs(lParam, rest1, rest2);
- }
-
+ m_pcidlFolder = ILClone(parent);
+ if (cidl != 1)
+ return E_INVALIDARG;
+ m_pcidlChild = ILClone(apidl[0]);
return S_OK;
}
-HRESULT STDMETHODCALLTYPE CRegistryFolder::CreateViewObject(
- HWND hwndOwner,
- REFIID riid,
- void **ppvOut)
+HRESULT STDMETHODCALLTYPE CRegistryFolderExtractIcon::GetIconLocation(
+ UINT uFlags,
+ LPWSTR szIconFile,
+ UINT cchMax,
+ INT *piIndex,
+ UINT *pwFlags)
{
- if (!IsEqualIID(riid, IID_IShellView))
- return E_NOINTERFACE;
-
- SFV_CREATE sfv;
- sfv.cbSize = sizeof(sfv);
- sfv.pshf = this;
- sfv.psvOuter = NULL;
- sfv.psfvcb = this;
-
- return SHCreateShellFolderView(&sfv, (IShellView**) ppvOut);
-}
+ const RegPidlEntry * entry = (RegPidlEntry *)m_pcidlChild;
-HRESULT STDMETHODCALLTYPE CRegistryFolder::GetAttributesOf(
- UINT cidl,
- PCUITEMID_CHILD_ARRAY apidl,
- SFGAOF *rgfInOut)
-{
- RegPidlEntry * info;
- HRESULT hr;
+ if ((entry->cb < sizeof(RegPidlEntry)) || (entry->magic != REGISTRY_PIDL_MAGIC))
+ return E_INVALIDARG;
- TRACE("GetAttributesOf\n");
+ UINT flags = 0;
- if (cidl == 0)
+ switch (entry->entryType)
{
- *rgfInOut &= SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_BROWSABLE;
+ case REG_ENTRY_KEY:
+ case REG_ENTRY_ROOT:
+ GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
+ *piIndex = -IDI_REGISTRYKEY;
+ *pwFlags = flags;
+ return S_OK;
+ case REG_ENTRY_VALUE:
+ GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
+ *piIndex = -IDI_REGISTRYVALUE;
+ *pwFlags = flags;
+ return S_OK;
+ default:
+ GetModuleFileNameW(g_hInstance, szIconFile, cchMax);
+ *piIndex = -IDI_NTOBJECTITEM;
+ *pwFlags = flags;
return S_OK;
}
-
- for (int i = 0; i < (int) cidl; i++)
- {
- PCUITEMID_CHILD pidl = apidl[i];
-
- hr = m_PidlManager->FindPidlInList(pidl, &info);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- // Update attributes.
- *rgfInOut = m_PidlManager->ConvertAttributes(info, rgfInOut);
- }
-
- return S_OK;
}
-HRESULT STDMETHODCALLTYPE CRegistryFolder::GetUIObjectOf(
- HWND hwndOwner,
- UINT cidl,
- PCUITEMID_CHILD_ARRAY apidl,
- REFIID riid,
- UINT *prgfInOut,
- void **ppvOut)
+HRESULT STDMETHODCALLTYPE CRegistryFolderExtractIcon::Extract(
+ LPCWSTR pszFile,
+ UINT nIconIndex,
+ HICON *phiconLarge,
+ HICON *phiconSmall,
+ UINT nIconSize)
{
- TRACE("GetUIObjectOf\n");
-
- if (IsEqualIID(riid, IID_IContextMenu) ||
- IsEqualIID(riid, IID_IContextMenu2) ||
- IsEqualIID(riid, IID_IContextMenu3))
- {
- CComPtr<IContextMenu> pcm;
-
- HKEY keys [1];
-
- int nkeys = _countof(keys);
- if (cidl == 1 && m_PidlManager->IsFolder(apidl[0]))
- {
- RegOpenKey(HKEY_CLASSES_ROOT, L"Folder", keys + 0);
- }
- else
- {
- nkeys = 0;
- }
-
- HRESULT hr = CDefFolderMenu_Create2(m_shellPidl, hwndOwner, cidl, apidl, this, DefCtxMenuCallback, nkeys, keys, &pcm);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- return pcm->QueryInterface(riid, ppvOut);
- }
-
- if (IsEqualIID(riid, IID_IExtractIconW))
- {
- return ShellObjectCreatorInit<CRegistryFolderExtractIcon>(m_shellPidl, cidl, apidl, riid, ppvOut);
- }
-
- if (IsEqualIID(riid, IID_IDataObject))
- {
- return CIDLData_CreateFromIDArray(m_shellPidl, cidl, apidl, (IDataObject**) ppvOut);
- }
-
- if (IsEqualIID(riid, IID_IQueryAssociations))
- {
- if (cidl == 1 && m_PidlManager->IsFolder(apidl[0]))
- {
- CComPtr<IQueryAssociations> pqa;
- HRESULT hr = AssocCreate(CLSID_QueryAssociations, IID_PPV_ARG(IQueryAssociations, &pqa));
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- hr = pqa->Init(ASSOCF_INIT_DEFAULTTOFOLDER, L"NTObjShEx.RegFolder", NULL, hwndOwner);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
+ return SHDefExtractIconW(pszFile, nIconIndex, 0, phiconLarge, phiconSmall, nIconSize);
+}
- return pqa->QueryInterface(riid, ppvOut);
- }
- }
+// CRegistryFolder
- return E_NOTIMPL;
+CRegistryFolder::CRegistryFolder()
+{
}
-HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDisplayNameOf(
- LPCITEMIDLIST pidl,
- SHGDNF uFlags,
- STRRET *lpName)
+CRegistryFolder::~CRegistryFolder()
{
- RegPidlEntry * info;
- HRESULT hr;
-
- TRACE("GetDisplayNameOf %p\n", pidl);
-
- hr = m_PidlManager->FindPidlInList(pidl, &info);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
+}
- if ((GET_SHGDN_RELATION(uFlags) == SHGDN_NORMAL) &&
- (GET_SHGDN_FOR(uFlags) & SHGDN_FORPARSING))
+// IShellFolder
+HRESULT STDMETHODCALLTYPE CRegistryFolder::EnumObjects(
+ HWND hwndOwner,
+ SHCONTF grfFlags,
+ IEnumIDList **ppenumIDList)
+{
+ if (m_NtPath[0] == 0 && m_hRoot == NULL)
{
- WCHAR path[MAX_PATH] = { 0 };
-
- hr = GetFullName(m_shellPidl, uFlags, path, _countof(path));
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- PathAppendW(path, info->entryName);
-
- hr = MakeStrRetFromString(path, lpName);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- LPCITEMIDLIST pidlFirst = ILCloneFirst(pidl);
- LPCITEMIDLIST pidlNext = ILGetNext(pidl);
-
- if (pidlNext && pidlNext->mkid.cb > 0)
- {
- CComPtr<IShellFolder> psfChild;
- hr = BindToObject(pidlFirst, NULL, IID_PPV_ARG(IShellFolder, &psfChild));
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- WCHAR temp[MAX_PATH];
- STRRET childName;
-
- hr = psfChild->GetDisplayNameOf(pidlNext, uFlags | SHGDN_INFOLDER, &childName);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- hr = StrRetToBufW(&childName, pidlNext, temp, _countof(temp));
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- PathAppendW(path, temp);
- }
-
- ILFree((LPITEMIDLIST) pidlFirst);
+ return GetEnumRegistryRoot(ppenumIDList);
}
else
{
- MakeStrRetFromString(info->entryName, info->entryNameLength, lpName);
+ return GetEnumRegistryKey(m_NtPath, m_hRoot, ppenumIDList);
}
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE CRegistryFolder::SetNameOf(
- HWND hwnd,
- LPCITEMIDLIST pidl,
- LPCOLESTR lpszName,
- SHGDNF uFlags,
- LPITEMIDLIST *ppidlOut)
-{
- UNIMPLEMENTED;
- return E_NOTIMPL;
}
-// IPersist
-HRESULT STDMETHODCALLTYPE CRegistryFolder::GetClassID(CLSID *lpClassId)
+HRESULT STDMETHODCALLTYPE CRegistryFolder::InternalBindToObject(
+ PWSTR path,
+ const RegPidlEntry * info,
+ LPITEMIDLIST first,
+ LPCITEMIDLIST rest,
+ LPITEMIDLIST fullPidl,
+ LPBC pbcReserved,
+ IShellFolder** ppsfChild)
{
- if (!lpClassId)
- return E_POINTER;
+ if (wcslen(m_NtPath) == 0 && m_hRoot == NULL)
+ {
+ return ShellObjectCreatorInit<CRegistryFolder>(fullPidl, L"", info->rootKey, IID_PPV_ARG(IShellFolder, ppsfChild));
+ }
- *lpClassId = CLSID_RegistryFolder;
- return S_OK;
+ return ShellObjectCreatorInit<CRegistryFolder>(fullPidl, path, m_hRoot, IID_PPV_ARG(IShellFolder, ppsfChild));
}
-// IPersistFolder
HRESULT STDMETHODCALLTYPE CRegistryFolder::Initialize(LPCITEMIDLIST pidl)
{
m_shellPidl = ILClone(pidl);
m_hRoot = NULL;
- PCWSTR ntPath = L"";
-
- if (!m_PidlManager)
- {
- m_PidlManager = new CRegistryPidlManager();
-
- StringCbCopy(m_NtPath, _countof(m_NtPath), ntPath);
- }
-
- return m_PidlManager->Initialize(m_NtPath, m_hRoot);
+ StringCbCopy(m_NtPath, _countof(m_NtPath), L"");
+ return S_OK;
}
-// Internal
HRESULT STDMETHODCALLTYPE CRegistryFolder::Initialize(LPCITEMIDLIST pidl, PCWSTR ntPath, HKEY hRoot)
{
m_shellPidl = ILClone(pidl);
m_hRoot = hRoot;
- if (!m_PidlManager)
- m_PidlManager = new CRegistryPidlManager();
-
StringCbCopy(m_NtPath, _countof(m_NtPath), ntPath);
- return m_PidlManager->Initialize(m_NtPath, m_hRoot);
-}
-
-// IPersistFolder2
-HRESULT STDMETHODCALLTYPE CRegistryFolder::GetCurFolder(LPITEMIDLIST * pidl)
-{
- if (pidl)
- *pidl = ILClone(m_shellPidl);
- if (!m_shellPidl)
- return S_FALSE;
- return S_OK;
-}
-
-// IShellFolder2
-HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDefaultSearchGUID(
- GUID *lpguid)
-{
- UNIMPLEMENTED;
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CRegistryFolder::EnumSearches(
- IEnumExtraSearch **ppenum)
-{
- UNIMPLEMENTED;
- return E_NOTIMPL;
-}
-
-HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDefaultColumn(
- DWORD dwReserved,
- ULONG *pSort,
- ULONG *pDisplay)
-{
- if (pSort)
- *pSort = 0;
- if (pDisplay)
- *pDisplay = 0;
return S_OK;
}
const SHCOLUMNID *pscid,
VARIANT *pv)
{
- RegPidlEntry * info;
- HRESULT hr;
+ const RegPidlEntry * info;
TRACE("GetDetailsEx\n");
if (pidl)
{
- hr = m_PidlManager->FindPidlInList(pidl, &info);
+ HRESULT hr = GetInfoFromPidl(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
{
if (info->contentsLength > 0)
{
- PWSTR td = (PWSTR)(((PBYTE) info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
+ PWSTR td = (PWSTR)(((PBYTE)info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
return MakeVariantString(pv, td);
}
{
PCWSTR strValueContents;
- hr = m_PidlManager->FormatContentsForDisplay(info, &strValueContents);
+ hr = FormatContentsForDisplay(info, m_hRoot, m_NtPath, &strValueContents);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = MakeVariantString(pv, strValueContents);
- CoTaskMemFree((PVOID) strValueContents);
+ CoTaskMemFree((PVOID)strValueContents);
return hr;
UINT iColumn,
SHELLDETAILS *psd)
{
- RegPidlEntry * info;
- HRESULT hr;
+ const RegPidlEntry * info;
TRACE("GetDetailsOf\n");
if (pidl)
{
- hr = m_PidlManager->FindPidlInList(pidl, &info);
+ HRESULT hr = GetInfoFromPidl(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
{
if (info->contentsLength > 0)
{
- PWSTR td = (PWSTR) (((PBYTE) info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
+ PWSTR td = (PWSTR)(((PBYTE)info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
return MakeStrRetFromString(td, info->contentsLength, &(psd->str));
}
PCWSTR strValueContents;
- hr = m_PidlManager->FormatContentsForDisplay(info, &strValueContents);
+ hr = FormatContentsForDisplay(info, m_hRoot, m_NtPath, &strValueContents);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
hr = MakeStrRetFromString(strValueContents, &(psd->str));
- CoTaskMemFree((PVOID) strValueContents);
+ CoTaskMemFree((PVOID)strValueContents);
return hr;
}
return E_INVALIDARG;
}
-HRESULT STDMETHODCALLTYPE CRegistryFolder::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
+HRESULT CRegistryFolder::CompareIDs(LPARAM lParam, const RegPidlEntry * first, const RegPidlEntry * second)
+{
+ HRESULT hr;
+
+ LPARAM sortMode = lParam & 0xFFFF0000;
+ LPARAM column = lParam & 0x0000FFFF;
+
+ if (sortMode == SHCIDS_ALLFIELDS)
+ {
+ if (column != 0)
+ return E_INVALIDARG;
+
+ int minsize = min(first->cb, second->cb);
+ hr = MAKE_COMPARE_HRESULT(memcmp(second, first, minsize));
+ if (hr != S_EQUAL)
+ return hr;
+
+ return MAKE_COMPARE_HRESULT(second->cb - first->cb);
+ }
+
+ switch (column)
+ {
+ case REGISTRY_COLUMN_NAME:
+ return CompareName(lParam, first, second);
+
+ case REGISTRY_COLUMN_TYPE:
+ return MAKE_COMPARE_HRESULT(second->contentType - first->contentType);
+
+ case REGISTRY_COLUMN_VALUE:
+ // Can't sort by link target yet
+ return E_INVALIDARG;
+ }
+
+ DbgPrint("Unsupported sorting mode.\n");
+ return E_INVALIDARG;
+}
+
+ULONG CRegistryFolder::ConvertAttributes(const RegPidlEntry * entry, PULONG inMask)
+{
+ ULONG mask = inMask ? *inMask : 0xFFFFFFFF;
+ ULONG flags = 0;
+
+ if ((entry->entryType == REG_ENTRY_KEY) ||
+ (entry->entryType == REG_ENTRY_ROOT))
+ flags |= SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_BROWSABLE;
+
+ 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);
+}
+
+HRESULT CRegistryFolder::GetInfoFromPidl(LPCITEMIDLIST pcidl, const RegPidlEntry ** pentry)
+{
+ RegPidlEntry * entry = (RegPidlEntry*) &(pcidl->mkid);
+
+ if (entry->cb < sizeof(RegPidlEntry))
+ {
+ DbgPrint("PCIDL too small %l (required %l)\n", entry->cb, sizeof(RegPidlEntry));
+ return E_INVALIDARG;
+ }
+
+ if (entry->magic != REGISTRY_PIDL_MAGIC)
+ {
+ DbgPrint("PCIDL magic mismatch %04x (expected %04x)\n", entry->magic, REGISTRY_PIDL_MAGIC);
+ return E_INVALIDARG;
+ }
+
+ *pentry = entry;
+ return S_OK;
+}
+
+HRESULT CRegistryFolder::FormatValueData(DWORD contentType, PVOID td, DWORD contentsLength, PCWSTR * strContents)
{
- switch (uMsg)
+ switch (contentType)
+ {
+ case 0:
+ {
+ PCWSTR strTodo = L"";
+ DWORD bufferLength = (wcslen(strTodo) + 1) * sizeof(WCHAR);
+ PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
+ StringCbCopyW(strValue, bufferLength, strTodo);
+ *strContents = strValue;
+ return S_OK;
+ }
+ case REG_SZ:
+ case REG_EXPAND_SZ:
+ {
+ PWSTR strValue = (PWSTR)CoTaskMemAlloc(contentsLength + sizeof(WCHAR));
+ StringCbCopyNW(strValue, contentsLength + sizeof(WCHAR), (LPCWSTR)td, contentsLength);
+ *strContents = strValue;
+ return S_OK;
+ }
+ case REG_MULTI_SZ:
+ {
+ PCWSTR separator = L" "; // To match regedit
+ size_t sepChars = wcslen(separator);
+ int strings = 0;
+ int stringChars = 0;
+
+ PCWSTR strData = (PCWSTR)td;
+ while (*strData)
+ {
+ size_t len = wcslen(strData);
+ stringChars += len;
+ strData += len + 1; // Skips null-terminator
+ strings++;
+ }
+
+ int cch = stringChars + (strings - 1) * sepChars + 1;
+
+ PWSTR strValue = (PWSTR)CoTaskMemAlloc(cch * sizeof(WCHAR));
+
+ strValue[0] = 0;
+
+ strData = (PCWSTR)td;
+ while (*strData)
+ {
+ StrCatW(strValue, strData);
+ strData += wcslen(strData) + 1;
+ if (*strData)
+ StrCatW(strValue, separator);
+ }
+
+ *strContents = strValue;
+ return S_OK;
+ }
+ case REG_DWORD:
+ {
+ DWORD bufferLength = 64 * sizeof(WCHAR);
+ PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
+ StringCbPrintfW(strValue, bufferLength, L"0x%08x (%d)",
+ *(DWORD*)td, *(DWORD*)td);
+ *strContents = strValue;
+ return S_OK;
+ }
+ case REG_QWORD:
+ {
+ DWORD bufferLength = 64 * sizeof(WCHAR);
+ PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
+ StringCbPrintfW(strValue, bufferLength, L"0x%016llx (%lld)",
+ *(LARGE_INTEGER*)td, ((LARGE_INTEGER*)td)->QuadPart);
+ *strContents = strValue;
+ return S_OK;
+ }
+ case REG_BINARY:
{
- case SFVM_DEFVIEWMODE:
+ DWORD bufferLength = (contentsLength * 3 + 1) * sizeof(WCHAR);
+ PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
+ PWSTR strTemp = strValue;
+ PBYTE data = (PBYTE)td;
+ for (DWORD i = 0; i < contentsLength; i++)
+ {
+ StringCbPrintfW(strTemp, bufferLength, L"%02x ", data[i]);
+ strTemp += 3;
+ bufferLength -= 3;
+ }
+ *strContents = strValue;
+ return S_OK;
+ }
+ default:
{
- FOLDERVIEWMODE* pViewMode = (FOLDERVIEWMODE*) lParam;
- *pViewMode = FVM_DETAILS;
+ PCWSTR strFormat = L"<Unimplemented value type %d>";
+ DWORD bufferLength = (wcslen(strFormat) + 15) * sizeof(WCHAR);
+ PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
+ StringCbPrintfW(strValue, bufferLength, strFormat, contentType);
+ *strContents = strValue;
return S_OK;
}
}
- return E_NOTIMPL;
}
-HRESULT CRegistryFolder::DefCtxMenuCallback(IShellFolder * /*psf*/, HWND /*hwnd*/, IDataObject * /*pdtobj*/, UINT uMsg, WPARAM /*wParam*/, LPARAM /*lParam*/)
+HRESULT CRegistryFolder::FormatContentsForDisplay(const RegPidlEntry * info, HKEY rootKey, LPCWSTR ntPath, PCWSTR * strContents)
{
- switch (uMsg)
+ PVOID td = (((PBYTE)info) + FIELD_OFFSET(RegPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
+
+ if (info->entryType == REG_ENTRY_VALUE_WITH_CONTENT)
+ {
+ if (info->contentsLength > 0)
+ {
+ return FormatValueData(info->contentType, td, info->contentsLength, strContents);
+ }
+ }
+ else if (info->entryType == REG_ENTRY_VALUE)
+ {
+ PVOID valueData;
+ DWORD valueLength;
+ HRESULT hr = ReadRegistryValue(rootKey, ntPath, info->entryName, &valueData, &valueLength);
+ if (FAILED_UNEXPECTEDLY(hr))
+ {
+ PCWSTR strEmpty = L"(Error reading value)";
+ DWORD bufferLength = (wcslen(strEmpty) + 1) * sizeof(WCHAR);
+ PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
+ StringCbCopyW(strValue, bufferLength, strEmpty);
+ *strContents = strValue;
+ return S_OK;
+ }
+
+ if (valueLength > 0)
+ {
+ hr = FormatValueData(info->contentType, valueData, valueLength, strContents);
+
+ CoTaskMemFree(valueData);
+
+ return hr;
+ }
+ }
+ else
{
- case DFM_MERGECONTEXTMENU:
+ PCWSTR strEmpty = L"";
+ DWORD bufferLength = (wcslen(strEmpty) + 1) * sizeof(WCHAR);
+ PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
+ StringCbCopyW(strValue, bufferLength, strEmpty);
+ *strContents = strValue;
return S_OK;
- case DFM_INVOKECOMMAND:
- case DFM_INVOKECOMMANDEX:
- case DFM_GETDEFSTATICID: // Required for Windows 7 to pick a default
- return S_FALSE;
}
- return E_NOTIMPL;
+
+ PCWSTR strEmpty = L"(Empty)";
+ DWORD bufferLength = (wcslen(strEmpty) + 1) * sizeof(WCHAR);
+ PWSTR strValue = (PWSTR)CoTaskMemAlloc(bufferLength);
+ StringCbCopyW(strValue, bufferLength, strEmpty);
+ *strContents = strValue;
+ return S_OK;
}