Author: dquintana
Date: Mon Feb 23 17:13:32 2015
New Revision: 66426
URL:
http://svn.reactos.org/svn/reactos?rev=66426&view=rev
Log:
[NTOBJSHEX]
* Fix all the size calculations broken by r66425.
* Fix subfolder navigation (in windows).
* Fix enumeration skipping the last item.
* Add the beginning of a registry folder implementation. It doesn't display all data
types yet, and it doesn't support editing or searching.
CORE-9244
Added:
trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp (with props)
trunk/reactos/dll/shellext/ntobjshex/regfolder.h (with props)
trunk/reactos/dll/shellext/ntobjshex/util.h (with props)
Modified:
trunk/reactos/dll/shellext/ntobjshex/CMakeLists.txt
trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp
trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp
trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h
trunk/reactos/dll/shellext/ntobjshex/precomp.h
trunk/reactos/dll/shellext/ntobjshex/resource.h
Modified: trunk/reactos/dll/shellext/ntobjshex/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/CMa…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/ntobjshex/CMakeLists.txt [iso-8859-1] Mon Feb 23 17:13:32
2015
@@ -19,6 +19,7 @@
ntobjshex.cpp
ntobjutil.cpp
ntobjshex.rc
+ regfolder.cpp
${CMAKE_CURRENT_BINARY_DIR}/ntobjshex.def)
list(APPEND atl_rc_deps
Modified: trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjns.cpp [iso-8859-1] Mon Feb 23 17:13:32
2015
@@ -9,6 +9,7 @@
#include "precomp.h"
#include "ntobjutil.h"
#include <ntquery.h>
+#include "util.h"
#define SHCIDS_ALLFIELDS 0x80000000L
#define SHCIDS_CANONICALONLY 0x10000000L
@@ -32,45 +33,6 @@
NTOBJECT_COLUMN_LINKTARGET = 3,
};
-static HRESULT MakeStrRetFromString(LPCWSTR string, DWORD cbLength, STRRET * str)
-{
- str->uType = STRRET_WSTR;
-
- DWORD blen = cbLength + sizeof(WCHAR);
- str->pOleStr = (LPWSTR) CoTaskMemAlloc(blen);
- return StringCbCopyNW(str->pOleStr, blen, string, cbLength);
-}
-
-static HRESULT MakeStrRetFromString(LPCWSTR string, STRRET * str)
-{
- DWORD stringLength = wcslen(string) * sizeof(WCHAR);
- return MakeStrRetFromString(string, stringLength, str);
-}
-
-static HRESULT MakeVariantString(VARIANT * pv, PCWSTR string)
-{
- V_VT(pv) = VT_BSTR;
- V_BSTR(pv) = SysAllocString(string);
- return S_OK;
-}
-
-static HRESULT GetFullName(PCIDLIST_ABSOLUTE pidl, DWORD uFlags, PWSTR strName, DWORD
cchName)
-{
- CComPtr<IShellFolder> psfDesktop;
- STRRET str;
- HRESULT hr;
-
- hr = SHGetDesktopFolder(&psfDesktop);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- hr = psfDesktop->GetDisplayNameOf(pidl, uFlags, &str);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- return StrRetToBufW(&str, pidl, strName, cchName);
-}
-
class CNtObjectFolderContextMenu :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IContextMenu
@@ -113,7 +75,8 @@
const NtPidlEntry * entry = (NtPidlEntry *) m_pcidlChild;
if ((entry->objectType == DIRECTORY_OBJECT) ||
- (entry->objectType == SYMBOLICLINK_OBJECT))
+ (entry->objectType == SYMBOLICLINK_OBJECT) ||
+ (entry->objectType == KEY_OBJECT))
{
MENUITEMINFOW mii;
@@ -373,6 +336,13 @@
return E_FAIL;
}
+ NtPidlEntry * info = (NtPidlEntry *) pcidl;
+ if ((info->cb < sizeof(NtPidlEntry)) || (info->magic !=
NT_OBJECT_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++)
@@ -395,7 +365,7 @@
}
}
- TRACE("Pidl not found\n");
+ ERR("PIDL NOT FOUND: Requested filename: %S\n", info->entryName);
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
@@ -537,6 +507,9 @@
if (entry->objectType == SYMBOLICLINK_OBJECT)
flags |= SFGAO_LINK | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_BROWSABLE;
+ if (entry->objectType == KEY_OBJECT)
+ flags |= SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_BROWSABLE;
+
return flags & mask;
}
@@ -605,6 +578,7 @@
{
case SYMBOLICLINK_OBJECT:
case DIRECTORY_OBJECT:
+ case KEY_OBJECT:
flagsOk = (m_Flags & SHCONTF_FOLDERS) != 0;
break;
default:
@@ -613,7 +587,7 @@
}
} while (m_Index < m_Count && !flagsOk);
- if (m_Index < m_Count)
+ if (flagsOk)
{
if (rgelt)
rgelt[i] = m_Folder->GetManager().CreatePidlFromItem(tinfo);
@@ -660,12 +634,6 @@
//-----------------------------------------------------------------------------
// CNtObjectFolder
-extern "C"
-HRESULT WINAPI CMergedFolder_Constructor(REFIID riid, LPVOID *ppv)
-{
- return ShellObjectCreator<CNtObjectFolder>(riid, ppv);
-}
-
CNtObjectFolder::CNtObjectFolder() :
m_PidlManager(NULL),
m_shellPidl(NULL)
@@ -674,6 +642,7 @@
CNtObjectFolder::~CNtObjectFolder()
{
+ TRACE("Destroying CNtObjectFolder %p\n", this);
}
// IShellFolder
@@ -697,7 +666,7 @@
if (pdwAttributes)
*pdwAttributes = 0;
- TRACE("ParseDisplayName name=%S\n", lpszDisplayName);
+ TRACE("CNtObjectFolder::ParseDisplayName name=%S (ntPath=%S)\n",
lpszDisplayName, m_NtPath);
hr = m_PidlManager->FindByName(lpszDisplayName, &info);
if (FAILED(hr))
@@ -743,36 +712,64 @@
return E_ACCESSDENIED;
WCHAR path[MAX_PATH];
+ StringCbCopyW(path, _countof(path), m_NtPath);
+ PathAppendW(path, info->entryName);
+
+ LPITEMIDLIST first = ILCloneFirst(pidl);
+ LPCITEMIDLIST rest = ILGetNext(pidl);
+
+ LPITEMIDLIST fullPidl = ILCombine(m_shellPidl, first);
if (info->objectType == SYMBOLICLINK_OBJECT)
{
- NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
sizeof(NtPidlEntry) + info->entryNameLength + sizeof(WCHAR));
+ NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
FIELD_OFFSET(NtPidlEntry,entryName) + info->entryNameLength + sizeof(WCHAR));
if (symlink->targetNameLength > 0)
{
- StringCbCopyW(path, _countof(path), symlink->targetName);
+ if (symlink->targetName[1] == L':' &&
isalphaW(symlink->targetName[0]))
+ {
+ ERR("TODO: Navigating to WIN32 PATH from NT PATH.\n");
+ return E_NOTIMPL;
+ }
+
+ StringCbCopyW(path, _countof(path),
L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{845B0FB2-66E0-416B-8F91-314E23F7C12D}");
+ PathAppend(path, symlink->targetName);
+
+ 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;
}
else
{
return E_UNEXPECTED;
}
}
+
+ CComPtr<IShellFolder> psfChild;
+
+ if (info->objectType == KEY_OBJECT)
+ {
+ hr = ShellObjectCreatorInit<CRegistryFolder>(fullPidl, path,
IID_PPV_ARG(IShellFolder, &psfChild));
+ }
else
{
- StringCbCopyW(path, _countof(path), m_NtPath);
-
- PathAppendW(path, info->entryName);
-
- DbgPrint("BindToObject for Directory %S\n", path);
- }
-
- LPITEMIDLIST fullPidl = ILCombine(m_shellPidl, pidl);
-
- hr = ShellObjectCreatorInit<CNtObjectFolder>(fullPidl, path, riid,
ppvOut);
+ hr = ShellObjectCreatorInit<CNtObjectFolder>(fullPidl, path,
IID_PPV_ARG(IShellFolder, &psfChild));
+ }
ILFree(fullPidl);
-
- return hr;
+ ILFree(first);
+
+ if (rest->mkid.cb > 0)
+ {
+ return psfChild->BindToObject(rest, pbcReserved, riid, ppvOut);
+ }
+
+ return psfChild->QueryInterface(riid, ppvOut);
}
return E_NOTIMPL;
@@ -953,18 +950,70 @@
// IPersistFolder
HRESULT STDMETHODCALLTYPE CNtObjectFolder::Initialize(LPCITEMIDLIST pidl)
{
- return Initialize(pidl, L"\\");
+ m_shellPidl = ILClone(pidl);
+
+ PCWSTR ntPath = L"\\";
+
+#if 0
+ WCHAR debugTemp[MAX_PATH];
+ GetFullName(m_shellPidl, SHGDN_FORPARSING, debugTemp, _countof(debugTemp));
+ DbgPrint("INITIALIZE CRegistryFolder PIDL PATH: %S (ntPath: %S)\n",
debugTemp, ntPath);
+
+ if (ntPath[wcslen(ntPath)-1] == L'\\' && debugTemp[wcslen(debugTemp)
- 1] != L'\\')
+ wcscat(debugTemp, L"\\");
+
+ PCWSTR guidTemp = L"::{845B0FB2-66E0-416B-8F91-314E23F7C12D}";
+
+ PCWSTR findTemp = StrStrW(debugTemp, guidTemp);
+ PCWSTR nextTemp = findTemp + wcslen(guidTemp);
+
+ if (wcscmp(nextTemp, ntPath))
+ {
+ DbgPrint("WHAT THE F, the NT PATH DOES NOT MATCH\n");
+ return E_FAIL;
+ }
+#endif
+
+ if (!m_PidlManager)
+ {
+ m_PidlManager = new CNtObjectPidlManager();
+
+ StringCbCopy(m_NtPath, _countof(m_NtPath), ntPath);
+ }
+
+ return m_PidlManager->Initialize(m_NtPath);
}
// Internal
HRESULT STDMETHODCALLTYPE CNtObjectFolder::Initialize(LPCITEMIDLIST pidl, PCWSTR ntPath)
{
+ TRACE("INITIALIZE %p CNtObjectFolder with ntPath %S\n", this, ntPath);
+
+#if 0
m_shellPidl = ILClone(pidl);
- StringCbCopy(m_NtPath, _countof(m_NtPath), ntPath);
-
+ WCHAR debugTemp[MAX_PATH];
+ GetFullName(m_shellPidl, SHGDN_FORPARSING, debugTemp, _countof(debugTemp));
+ DbgPrint("INITIALIZE CNtObjectFolder PIDL PATH: %S (ntPath: %S)\n",
debugTemp, ntPath);
+
+ if (ntPath[wcslen(ntPath) - 1] == L'\\' &&
debugTemp[wcslen(debugTemp) - 1] != L'\\')
+ wcscat(debugTemp, L"\\");
+
+ PCWSTR guidTemp = L"::{845B0FB2-66E0-416B-8F91-314E23F7C12D}";
+
+ PCWSTR findTemp = StrStrW(debugTemp, guidTemp);
+ PCWSTR nextTemp = findTemp + wcslen(guidTemp);
+
+ if (wcscmp(nextTemp, ntPath))
+ {
+ DbgPrint("WHAT THE F, the NT PATH DOES NOT MATCH\n");
+ return E_FAIL;
+ }
+#endif
+
if (!m_PidlManager)
m_PidlManager = new CNtObjectPidlManager();
+ StringCbCopy(m_NtPath, _countof(m_NtPath), ntPath);
return m_PidlManager->Initialize(m_NtPath);
}
@@ -1055,7 +1104,7 @@
{
if (info->objectType < 0)
{
- NtPidlTypeData * td = (NtPidlTypeData*) (((PBYTE) info) +
sizeof(NtPidlEntry) + info->entryNameLength + sizeof(WCHAR));
+ NtPidlTypeData * td = (NtPidlTypeData*) (((PBYTE) info) +
FIELD_OFFSET(NtPidlEntry,entryName) + info->entryNameLength + sizeof(WCHAR));
if (td->typeNameLength > 0)
{
@@ -1089,7 +1138,7 @@
{
if (info->objectType == SYMBOLICLINK_OBJECT)
{
- NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
sizeof(NtPidlEntry) + info->entryNameLength + sizeof(WCHAR));
+ NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
FIELD_OFFSET(NtPidlEntry,entryName) + info->entryNameLength + sizeof(WCHAR));
if (symlink->targetNameLength > 0)
{
@@ -1134,7 +1183,7 @@
if (info->objectType < 0)
{
- NtPidlTypeData * td = (NtPidlTypeData*) (((PBYTE) info) +
sizeof(NtPidlEntry) + info->entryNameLength + sizeof(WCHAR));
+ NtPidlTypeData * td = (NtPidlTypeData*) (((PBYTE) info) +
FIELD_OFFSET(NtPidlEntry,entryName) + info->entryNameLength + sizeof(WCHAR));
if (td->typeNameLength > 0)
MakeStrRetFromString(td->typeName, td->typeNameLength,
&(psd->str));
@@ -1170,7 +1219,7 @@
if (info->objectType == SYMBOLICLINK_OBJECT)
{
- NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
sizeof(NtPidlEntry) + info->entryNameLength + sizeof(WCHAR));
+ NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
FIELD_OFFSET(NtPidlEntry,entryName) + info->entryNameLength + sizeof(WCHAR));
if (symlink->targetNameLength > 0)
{
Modified: trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjutil.cpp [iso-8859-1] Mon Feb 23 17:13:32
2015
@@ -36,7 +36,22 @@
0
};
-static DWORD NtOpenObject(OBJECT_TYPE type, HANDLE* phandle, DWORD access, LPCWSTR path)
+const LPCWSTR RegistryTypeNames[] = {
+ L"REG_NONE",
+ L"REG_SZ",
+ L"REG_EXPAND_SZ",
+ L"REG_BINARY",
+ L"REG_DWORD",
+ L"REG_DWORD_BIG_ENDIAN",
+ L"REG_LINK",
+ L"REG_MULTI_SZ",
+ L"REG_RESOURCE_LIST",
+ L"REG_FULL_RESOURCE_DESCRIPTOR",
+ L"REG_RESOURCE_REQUIREMENTS_LIST ",
+ L"REG_QWORD"
+};
+
+static DWORD NtOpenObject(OBJECT_TYPE type, PHANDLE phandle, DWORD access, LPCWSTR path)
{
UNICODE_STRING ustr;
@@ -128,7 +143,7 @@
UNICODE_STRING link;
RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
- DWORD entryBufferLength = sizeof(NtPidlEntry) + sizeof(WCHAR);
+ DWORD entryBufferLength = FIELD_OFFSET(NtPidlEntry,entryName) +
sizeof(WCHAR);
if (info->Name.Buffer)
entryBufferLength += info->Name.Length;
@@ -183,7 +198,7 @@
memset(entry, 0, entryBufferLength);
- entry->cb = sizeof(NtPidlEntry);
+ entry->cb = FIELD_OFFSET(NtPidlEntry,entryName);
entry->magic = NT_OBJECT_PIDL_MAGIC;
entry->objectType = otype;
entry->objectInformation = object;
@@ -242,3 +257,161 @@
return S_OK;
}
+
+HRESULT EnumerateRegistryKey(HDPA hdpa, PCWSTR path, HKEY root, UINT * hdpaCount)
+{
+ *hdpaCount = 0;
+
+ HKEY hkey;
+
+ DWORD res;
+ if (root)
+ {
+ res = RegOpenKeyExW(root, *path == '\\' ? path + 1 : path, 0,
STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hkey);
+ }
+ else
+ {
+ res = NtOpenObject(KEY_OBJECT, (PHANDLE)&hkey, STANDARD_RIGHTS_READ |
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, path);
+ }
+ if (!NT_SUCCESS(res))
+ {
+ ERR("RegOpenKeyExW failed for path %S with status=%x\n", path, res);
+ return HRESULT_FROM_NT(res);
+ }
+
+ for (int idx = 0;; ++idx)
+ {
+ WCHAR name[MAX_PATH];
+ DWORD cchName = _countof(name);
+
+ WCHAR className[MAX_PATH];
+ DWORD cchClass = _countof(className);
+
+ if (RegEnumKeyExW(hkey, idx, name, &cchName, 0, className, &cchClass,
NULL))
+ break;
+
+ name[cchName] = 0;
+ className[cchClass] = 0;
+
+ REG_ENTRY_TYPE otype = REG_ENTRY_KEY;
+
+ DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry,entryName) + sizeof(WCHAR) +
cchName * sizeof(WCHAR);
+
+ if (cchClass > 0)
+ {
+ entryBufferLength += sizeof(WCHAR) + cchClass * sizeof(WCHAR);
+ }
+
+ RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength);
+ if (!entry)
+ return E_OUTOFMEMORY;
+
+ memset(entry, 0, entryBufferLength);
+
+ entry->cb = FIELD_OFFSET(NtPidlEntry,entryName);
+ entry->magic = REGISTRY_PIDL_MAGIC;
+ entry->entryType = otype;
+
+ if (cchName > 0)
+ {
+ entry->entryNameLength = cchName * sizeof(WCHAR);
+ StringCbCopyNW(entry->entryName, entryBufferLength, name,
entry->entryNameLength);
+ entry->cb += entry->entryNameLength + sizeof(WCHAR);
+ }
+ else
+ {
+ entry->entryNameLength = 0;
+ entry->entryName[0] = 0;
+ entry->cb += sizeof(WCHAR);
+ }
+
+ if (cchClass)
+ {
+ PWSTR contentData = (PWSTR) ((PBYTE) entry + entry->cb);
+ DWORD remainingSpace = entryBufferLength - entry->cb;
+
+ entry->contentsLength = cchClass * sizeof(WCHAR);
+ StringCbCopyNW(contentData, remainingSpace, className,
entry->contentsLength);
+
+ entry->cb += entry->contentsLength + sizeof(WCHAR);
+ }
+
+ DPA_AppendPtr(hdpa, entry);
+ (*hdpaCount)++;
+
+ }
+
+ for (int idx = 0;; ++idx)
+ {
+ WCHAR name[MAX_PATH];
+ DWORD cchName = _countof(name);
+ DWORD type;
+ DWORD dataSize;
+
+ if (RegEnumValueW(hkey, idx, name, &cchName, 0, &type, NULL,
&dataSize))
+ break;
+
+ REG_ENTRY_TYPE otype = REG_ENTRY_VALUE;
+
+ DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry,entryName) + sizeof(WCHAR) +
cchName * sizeof(WCHAR);
+
+ BOOL copyData = dataSize < 32;
+ if (copyData)
+ {
+ entryBufferLength += dataSize + sizeof(WCHAR);
+
+ otype = REG_ENTRY_VALUE_WITH_CONTENT;
+ }
+
+ RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength);
+ if (!entry)
+ return E_OUTOFMEMORY;
+
+ memset(entry, 0, entryBufferLength);
+
+ entry->cb = FIELD_OFFSET(RegPidlEntry, entryName);
+ entry->magic = REGISTRY_PIDL_MAGIC;
+ entry->entryType = otype;
+
+ if (cchName > 0)
+ {
+ entry->entryNameLength = cchName * sizeof(WCHAR);
+ StringCbCopyNW(entry->entryName, entryBufferLength, name,
entry->entryNameLength);
+ entry->cb += entry->entryNameLength + sizeof(WCHAR);
+ }
+ else
+ {
+ entry->entryNameLength = 0;
+ entry->entryName[0] = 0;
+ entry->cb += sizeof(WCHAR);
+ }
+
+ if (copyData)
+ {
+ PBYTE contentData = (PBYTE) ((PBYTE) entry + entry->cb);
+
+ entry->contentsLength = dataSize;
+
+ // In case it's an unterminated string, RegGetValue will add the NULL
termination
+ dataSize += sizeof(WCHAR);
+
+ if (!RegQueryValueExW(hkey, name, NULL, NULL, contentData, &dataSize))
+ {
+ entry->cb += entry->contentsLength + sizeof(WCHAR);
+ }
+ else
+ {
+ entry->contentsLength = 0;
+ entry->cb += sizeof(WCHAR);
+ }
+
+ }
+
+ DPA_AppendPtr(hdpa, entry);
+ (*hdpaCount)++;
+ }
+
+ RegCloseKey(hkey);
+
+ return S_OK;
+}
Modified: trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/nto…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/ntobjshex/ntobjutil.h [iso-8859-1] Mon Feb 23 17:13:32
2015
@@ -37,8 +37,11 @@
extern const LPCWSTR ObjectTypeNames[];
#define NT_OBJECT_PIDL_MAGIC (USHORT)0x9A03
+#define REGISTRY_PIDL_MAGIC (USHORT)0x5364
#include <pshpack1.h>
+
+// NT OBJECT browsere
struct NtPidlEntry
{
USHORT cb;
@@ -65,6 +68,37 @@
USHORT targetNameLength;
WCHAR targetName[ANYSIZE_ARRAY];
};
+
+// REGISTRY browsere
+enum REG_ENTRY_TYPE
+{
+ REG_ENTRY_KEY,
+ REG_ENTRY_VALUE,
+ REG_ENTRY_VALUE_WITH_CONTENT
+ // any more?
+};
+extern const LPCWSTR RegistryTypeNames [];
+
+struct RegPidlEntry
+{
+ USHORT cb;
+ USHORT magic; // 0x5364 ~~~ "REGK"
+
+ REG_ENTRY_TYPE entryType;
+
+ USHORT entryNameLength;
+
+ // For Value entries, this contains the value contents, if it's resonably small.
+ // For Key entries, this contains the custom class name
+ DWORD contentType;
+ USHORT contentsLength;
+
+ WCHAR entryName[0];
+
+};
+
+
#include <poppack.h>
-HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount);
+HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount);
+HRESULT EnumerateRegistryKey(HDPA hdpa, PCWSTR path, HKEY root, UINT * hdpaCount);
Modified: trunk/reactos/dll/shellext/ntobjshex/precomp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/pre…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/precomp.h [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/ntobjshex/precomp.h [iso-8859-1] Mon Feb 23 17:13:32 2015
@@ -47,3 +47,4 @@
0x845b0fb2, 0x66e0, 0x416b, 0x8f, 0x91, 0x31, 0x4e, 0x23, 0xf7, 0xc1, 0x2d);
#include "ntobjns.h"
+#include "regfolder.h"
Added: 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 (added)
+++ trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp [iso-8859-1] Mon Feb 23 17:13:32
2015
@@ -0,0 +1,1248 @@
+/*
+* PROJECT: ReactOS shell extensions
+* LICENSE: GPL - See COPYING in the top level directory
+* FILE: dll\shellext\ntobjshex\ntobjns.cpp
+* PURPOSE: NT Object Namespace shell extension
+* PROGRAMMERS: David Quintana <gigaherz(a)gmail.com>
+*/
+
+#include "precomp.h"
+#include "ntobjutil.h"
+#include <ntquery.h>
+#include "util.h"
+
+#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 CRegistryFolderContextMenu :
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IContextMenu
+{
+ PCIDLIST_ABSOLUTE m_pcidlFolder;
+ PCITEMID_CHILD m_pcidlChild;
+ UINT m_idFirst;
+
+public:
+ CRegistryFolderContextMenu() :
+ m_pcidlFolder(NULL),
+ m_pcidlChild(NULL),
+ m_idFirst(0)
+ {
+
+ }
+
+ virtual ~CRegistryFolderContextMenu()
+ {
+ 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;
+ }
+
+ // IContextMenu
+ virtual HRESULT WINAPI QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst,
UINT idCmdLast, UINT uFlags)
+ {
+ m_idFirst = idCmdFirst;
+
+ const RegPidlEntry * entry = (RegPidlEntry *) m_pcidlChild;
+
+ if (entry->entryType == REG_ENTRY_KEY)
+ {
+ MENUITEMINFOW mii;
+
+ WCHAR open [] = L"Open";
+ WCHAR opennewwindow [] = L"Open in new window";
+
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU | MIIM_ID;
+ mii.fType = MFT_STRING;
+ mii.wID = idCmdFirst++;
+ mii.dwTypeData = open;
+ mii.cch = _countof(open);
+ mii.fState = MFS_ENABLED | MFS_DEFAULT;
+ mii.hSubMenu = NULL;
+ InsertMenuItemW(hmenu, idCmdFirst, TRUE, &mii);
+
+ if (!(uFlags & CMF_DEFAULTONLY) && idCmdFirst <= idCmdLast)
+ {
+ ZeroMemory(&mii, sizeof(mii));
+ mii.cbSize = sizeof(mii);
+ mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU | MIIM_ID;
+ mii.fType = MFT_STRING;
+ mii.wID = idCmdFirst++;
+ mii.dwTypeData = opennewwindow;
+ mii.cch = _countof(opennewwindow);
+ mii.fState = MFS_ENABLED;
+ mii.hSubMenu = NULL;
+ InsertMenuItemW(hmenu, idCmdFirst, FALSE, &mii);
+ }
+ }
+
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, idCmdFirst - m_idFirst);
+ }
+
+ virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
+ {
+ if (LOWORD(lpici->lpVerb) == m_idFirst || !lpici->lpVerb)
+ {
+ LPITEMIDLIST fullPidl = ILCombine(m_pcidlFolder, m_pcidlChild);
+
+ SHELLEXECUTEINFO sei = { 0 };
+ sei.cbSize = sizeof(sei);
+ sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
+ sei.lpIDList = fullPidl;
+ sei.lpClass = L"folder";
+ sei.hwnd = lpici->hwnd;
+ sei.nShow = lpici->nShow;
+ sei.lpVerb = L"open";
+ BOOL bRes = ::ShellExecuteEx(&sei);
+
+ ILFree(fullPidl);
+
+ return bRes ? S_OK : HRESULT_FROM_WIN32(GetLastError());
+ }
+ else if (LOWORD(lpici->lpVerb) == (m_idFirst + 1))
+ {
+ LPITEMIDLIST fullPidl = ILCombine(m_pcidlFolder, m_pcidlChild);
+
+ SHELLEXECUTEINFO sei = { 0 };
+ sei.cbSize = sizeof(sei);
+ sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
+ sei.lpIDList = fullPidl;
+ sei.lpClass = L"folder";
+ sei.hwnd = lpici->hwnd;
+ sei.nShow = lpici->nShow;
+ sei.lpVerb = L"opennewwindow";
+ BOOL bRes = ::ShellExecuteEx(&sei);
+
+ ILFree(fullPidl);
+
+ return bRes ? S_OK : HRESULT_FROM_WIN32(GetLastError());
+ }
+ return E_NOTIMPL;
+ }
+
+ virtual HRESULT WINAPI GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved,
LPSTR pszName, UINT cchMax)
+ {
+ if (idCmd == m_idFirst)
+ {
+ if (uType == GCS_VERBW)
+ {
+ return StringCchCopyW((LPWSTR) pszName, cchMax, L"open");
+ }
+ }
+ else if (idCmd == (m_idFirst + 1))
+ {
+ if (uType == GCS_VERBW)
+ {
+ return StringCchCopyW((LPWSTR) pszName, cchMax,
L"opennewwindow");
+ }
+ }
+ return E_NOTIMPL;
+ }
+
+ DECLARE_NOT_AGGREGATABLE(CRegistryFolderContextMenu)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CRegistryFolderContextMenu)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
+ END_COM_MAP()
+
+};
+
+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:
+ 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;
+
+ 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_hDpa(NULL),
+ m_hDpaCount(0)
+ {
+ }
+
+ ~CRegistryPidlManager()
+ {
+ DPA_DestroyCallback(m_hDpa, s_DpaDeleteCallback, this);
+ }
+
+ HRESULT Initialize(PWSTR ntPath)
+ {
+ m_ntPath = ntPath;
+
+ m_hDpa = DPA_Create(10);
+
+ if (!m_hDpa)
+ return E_OUTOFMEMORY;
+
+ HRESULT hr = EnumerateRegistryKey(m_hDpa, m_ntPath, NULL, &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)
+ return E_INVALIDARG;
+
+ if (second->cb > first->cb)
+ return MAKE_HRESULT(0, 0, (USHORT) 1);
+ if (second->cb < first->cb)
+ return MAKE_HRESULT(0, 0, (USHORT) -1);
+
+ if (second->entryNameLength > first->entryNameLength)
+ return MAKE_HRESULT(0, 0, (USHORT) 1);
+ if (second->entryNameLength < first->entryNameLength)
+ return MAKE_HRESULT(0, 0, (USHORT) -1);
+
+ if (HIWORD(lParam) == SHCIDS_ALLFIELDS)
+ {
+ int ord = memcmp(second, first, first->cb);
+
+ if (ord != 0)
+ return MAKE_HRESULT(0, 0, (USHORT) ord);
+ }
+ else if (HIWORD(lParam) == SHCIDS_CANONICALONLY)
+ {
+ int ord = StrCmpNW(second->entryName, first->entryName,
first->entryNameLength);
+
+ if (ord != 0)
+ return MAKE_HRESULT(0, 0, (USHORT) ord);
+ }
+ else
+ {
+ int ord = (int) second->entryType - (int) first->entryType;
+
+ if (ord > 0)
+ return MAKE_HRESULT(0, 0, (USHORT) 1);
+ if (ord < 0)
+ return MAKE_HRESULT(0, 0, (USHORT) -1);
+
+ ord = StrCmpNW(second->entryName, first->entryName,
first->entryNameLength/sizeof(WCHAR));
+
+ if (ord != 0)
+ return MAKE_HRESULT(0, 0, (USHORT) ord);
+ }
+
+ 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)
+ flags |= SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_BROWSABLE;
+
+ return flags & mask;
+ }
+
+ HRESULT FormatContentsForDisplay(RegPidlEntry * info, PCWSTR * strContents)
+ {
+ PVOID td = (((PBYTE) info) + FIELD_OFFSET(RegPidlEntry,entryName) +
info->entryNameLength + sizeof(WCHAR));
+
+ if (info->contentsLength > 0)
+ {
+ if (info->entryType == REG_ENTRY_VALUE_WITH_CONTENT)
+ {
+ switch (info->contentType)
+ {
+ case REG_SZ:
+ case REG_EXPAND_SZ:
+ {
+ PWSTR strValue = (PWSTR) CoTaskMemAlloc(info->contentsLength +
sizeof(WCHAR));
+ StringCbCopyNW(strValue, info->contentsLength + sizeof(WCHAR),
(LPCWSTR) td, info->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;
+ }
+ }
+ }
+ else
+ {
+ PCWSTR strTodo = L"<TODO: Query non-embedded value>";
+ DWORD bufferLength = (wcslen(strTodo) + 1) * sizeof(WCHAR);
+ PWSTR strValue = (PWSTR) CoTaskMemAlloc(bufferLength);
+ StringCbCopyW(strValue, bufferLength, strTodo);
+ *strContents = strValue;
+ return S_OK;
+ }
+ }
+ else
+ {
+ 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:
+ 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;
+
+#if 0
+ if (!(info->objectInformation.GrantedAccess & (STANDARD_RIGHTS_READ |
FILE_LIST_DIRECTORY)))
+ return E_ACCESSDENIED;
+#endif
+
+ WCHAR path[MAX_PATH];
+
+ StringCbCopyW(path, _countof(path), m_NtPath);
+
+ PathAppendW(path, info->entryName);
+
+ LPITEMIDLIST first = ILCloneFirst(pidl);
+ LPCITEMIDLIST rest = ILGetNext(pidl);
+
+ LPITEMIDLIST fullPidl = ILCombine(m_shellPidl, first);
+
+ CComPtr<IShellFolder> psfChild;
+ hr = ShellObjectCreatorInit<CRegistryFolder>(fullPidl, path,
IID_PPV_ARG(IShellFolder, &psfChild));
+
+ ILFree(fullPidl);
+ ILFree(first);
+
+ if (rest->mkid.cb > 0)
+ {
+ return psfChild->BindToObject(rest, pbcReserved, riid, ppvOut);
+ }
+
+ return psfChild->QueryInterface(riid, ppvOut);
+ }
+
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CRegistryFolder::BindToStorage(
+ LPCITEMIDLIST pidl,
+ LPBC pbcReserved,
+ REFIID riid,
+ void **ppvObj)
+{
+ UNIMPLEMENTED;
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CRegistryFolder::CompareIDs(
+ LPARAM lParam,
+ LPCITEMIDLIST pidl1,
+ LPCITEMIDLIST pidl2)
+{
+ TRACE("CompareIDs\n");
+ return m_PidlManager->CompareIDs(lParam, pidl1, pidl2);
+}
+
+HRESULT STDMETHODCALLTYPE CRegistryFolder::CreateViewObject(
+ HWND hwndOwner,
+ REFIID riid,
+ void **ppvOut)
+{
+ if (!IsEqualIID(riid, IID_IShellView))
+ return E_NOINTERFACE;
+
+ SFV_CREATE sfv;
+ sfv.cbSize = sizeof(sfv);
+ sfv.pshf = this;
+ sfv.psvOuter = NULL;
+ sfv.psfvcb = NULL;
+
+ return SHCreateShellFolderView(&sfv, (IShellView**) ppvOut);
+}
+
+HRESULT STDMETHODCALLTYPE CRegistryFolder::GetAttributesOf(
+ UINT cidl,
+ PCUITEMID_CHILD_ARRAY apidl,
+ SFGAOF *rgfInOut)
+{
+ RegPidlEntry * info;
+ HRESULT hr;
+
+ TRACE("GetAttributesOf\n");
+
+ if (cidl == 0)
+ {
+ *rgfInOut &= SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_BROWSABLE;
+ 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)
+{
+ TRACE("GetUIObjectOf\n");
+
+ if (IsEqualIID(riid, IID_IContextMenu))
+ {
+ return ShellObjectCreatorInit<CRegistryFolderContextMenu>(m_shellPidl,
cidl, apidl, riid, ppvOut);
+ //return CDefFolderMenu_Create2(m_shellPidl, hwndOwner, cidl, apidl, this,
ContextMenuCallback, 0, NULL, (IContextMenu**) ppvOut);
+ }
+
+ if (IsEqualIID(riid, IID_IExtractIconW))
+ {
+ return ShellObjectCreatorInit<CRegistryFolderExtractIcon>(m_shellPidl,
cidl, apidl, riid, ppvOut);
+ }
+
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDisplayNameOf(
+ LPCITEMIDLIST pidl,
+ SHGDNF uFlags,
+ STRRET *lpName)
+{
+ 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))
+ {
+ 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 pidlNext = ILGetNext(pidl);
+
+ if (pidlNext && pidlNext->mkid.cb > 0)
+ {
+ CComPtr<IShellFolder> psfChild;
+ hr = BindToObject(pidl, 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);
+ }
+ }
+ else
+ {
+ MakeStrRetFromString(info->entryName, info->entryNameLength, lpName);
+ }
+
+ 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)
+{
+ if (!lpClassId)
+ return E_POINTER;
+
+ *lpClassId = CLSID_RegistryFolder;
+ return S_OK;
+}
+
+// IPersistFolder
+HRESULT STDMETHODCALLTYPE CRegistryFolder::Initialize(LPCITEMIDLIST pidl)
+{
+ m_shellPidl = ILClone(pidl);
+
+ PCWSTR ntPath = L"\\REGISTRY";
+
+#if 0
+ WCHAR debugTemp[MAX_PATH];
+ GetFullName(m_shellPidl, SHGDN_FORPARSING, debugTemp, _countof(debugTemp));
+ DbgPrint("INITIALIZE CRegistryFolder PIDL PATH: %S (ntPath: %S)\n",
debugTemp, ntPath);
+
+ if (ntPath[wcslen(ntPath) - 1] == L'\\' &&
debugTemp[wcslen(debugTemp) - 1] != L'\\')
+ wcscat(debugTemp, L"\\");
+
+ PCWSTR guidTemp = L"::{845B0FB2-66E0-416B-8F91-314E23F7C12D}";
+
+ PCWSTR findTemp = StrStrW(debugTemp, guidTemp);
+ PCWSTR nextTemp = findTemp + wcslen(guidTemp);
+
+ if (wcscmp(nextTemp, ntPath))
+ {
+ DbgPrint("WHAT THE F, the NT PATH DOES NOT MATCH\n");
+ return E_FAIL;
+ }
+#endif
+
+ if (!m_PidlManager)
+ {
+ m_PidlManager = new CRegistryPidlManager();
+
+ StringCbCopy(m_NtPath, _countof(m_NtPath), ntPath);
+ }
+
+ return m_PidlManager->Initialize(m_NtPath);
+}
+
+// Internal
+HRESULT STDMETHODCALLTYPE CRegistryFolder::Initialize(LPCITEMIDLIST pidl, PCWSTR ntPath)
+{
+ m_shellPidl = ILClone(pidl);
+
+#if 0
+ WCHAR debugTemp[MAX_PATH];
+ GetFullName(m_shellPidl, SHGDN_FORPARSING, debugTemp, _countof(debugTemp));
+ DbgPrint("INITIALIZE CRegistryFolder PIDL PATH: %S (ntPath: %S)\n",
debugTemp, ntPath);
+
+ if (ntPath[wcslen(ntPath) - 1] == L'\\' &&
debugTemp[wcslen(debugTemp) - 1] != L'\\')
+ wcscat(debugTemp, L"\\");
+
+ PCWSTR guidTemp = L"::{845B0FB2-66E0-416B-8F91-314E23F7C12D}";
+
+ PCWSTR findTemp = StrStrW(debugTemp, guidTemp);
+ PCWSTR nextTemp = findTemp + wcslen(guidTemp);
+
+ if (wcscmp(nextTemp, ntPath))
+ {
+ DbgPrint("WHAT THE F, the NT PATH DOES NOT MATCH\n");
+ return E_FAIL;
+ }
+#endif
+
+ if (!m_PidlManager)
+ m_PidlManager = new CRegistryPidlManager();
+
+ StringCbCopy(m_NtPath, _countof(m_NtPath), ntPath);
+ return m_PidlManager->Initialize(m_NtPath);
+}
+
+// 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;
+}
+
+HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDefaultColumnState(
+ UINT iColumn,
+ SHCOLSTATEF *pcsFlags)
+{
+ switch (iColumn)
+ {
+ case REGISTRY_COLUMN_NAME:
+ *pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
+ return S_OK;
+ case REGISTRY_COLUMN_TYPE:
+ *pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
+ return S_OK;
+ case REGISTRY_COLUMN_VALUE:
+ *pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT | SHCOLSTATE_SLOW;
+ return S_OK;
+ }
+
+ return E_INVALIDARG;
+}
+
+HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsEx(
+ LPCITEMIDLIST pidl,
+ const SHCOLUMNID *pscid,
+ VARIANT *pv)
+{
+ RegPidlEntry * info;
+ HRESULT hr;
+
+ TRACE("GetDetailsEx\n");
+
+ if (pidl)
+ {
+ hr = m_PidlManager->FindPidlInList(pidl, &info);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ static const GUID storage = PSGUID_STORAGE;
+ if (IsEqualGUID(pscid->fmtid, storage))
+ {
+ if (pscid->pid == PID_STG_NAME)
+ {
+ return MakeVariantString(pv, info->entryName);
+ }
+ else if (pscid->pid == PID_STG_STORAGETYPE)
+ {
+ return MakeVariantString(pv, RegistryTypeNames[info->entryType]);
+ }
+ else if (pscid->pid == PID_STG_CONTENTS)
+ {
+ PCWSTR strValueContents;
+
+ hr = m_PidlManager->FormatContentsForDisplay(info,
&strValueContents);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ if (hr == S_FALSE)
+ {
+ V_VT(pv) = VT_EMPTY;
+ return S_OK;
+ }
+
+ hr = MakeVariantString(pv, strValueContents);
+
+ CoTaskMemFree((PVOID)strValueContents);
+
+ return hr;
+
+ }
+ }
+ }
+
+ return E_INVALIDARG;
+}
+
+HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsOf(
+ LPCITEMIDLIST pidl,
+ UINT iColumn,
+ SHELLDETAILS *psd)
+{
+ RegPidlEntry * info;
+ HRESULT hr;
+
+ TRACE("GetDetailsOf\n");
+
+ if (pidl)
+ {
+ hr = m_PidlManager->FindPidlInList(pidl, &info);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ switch (iColumn)
+ {
+ case REGISTRY_COLUMN_NAME:
+ psd->fmt = LVCFMT_LEFT;
+
+ if (info->entryNameLength > 0)
+ {
+ return MakeStrRetFromString(info->entryName, info->entryNameLength,
&(psd->str));
+ }
+ return MakeStrRetFromString(L"(Default)", &(psd->str));
+
+ case REGISTRY_COLUMN_TYPE:
+ psd->fmt = LVCFMT_LEFT;
+
+ return MakeStrRetFromString(RegistryTypeNames[info->entryType],
&(psd->str));
+
+ case REGISTRY_COLUMN_VALUE:
+ psd->fmt = LVCFMT_LEFT;
+
+ PCWSTR strValueContents;
+
+ hr = m_PidlManager->FormatContentsForDisplay(info,
&strValueContents);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ if (hr == S_FALSE)
+ {
+ return MakeStrRetFromString(L"(Empty)", &(psd->str));
+ }
+
+ hr = MakeStrRetFromString(strValueContents, &(psd->str));
+
+ CoTaskMemFree((PVOID) strValueContents);
+
+ return hr;
+ }
+ }
+ else
+ {
+ switch (iColumn)
+ {
+ case REGISTRY_COLUMN_NAME:
+ psd->fmt = LVCFMT_LEFT;
+ psd->cxChar = 30;
+
+ // TODO: Make localizable
+ MakeStrRetFromString(L"Object Name", &(psd->str));
+ return S_OK;
+ case REGISTRY_COLUMN_TYPE:
+ psd->fmt = LVCFMT_LEFT;
+ psd->cxChar = 20;
+
+ // TODO: Make localizable
+ MakeStrRetFromString(L"Content Type", &(psd->str));
+ return S_OK;
+ case REGISTRY_COLUMN_VALUE:
+ psd->fmt = LVCFMT_LEFT;
+ psd->cxChar = 20;
+
+ // TODO: Make localizable
+ MakeStrRetFromString(L"Value", &(psd->str));
+ return S_OK;
+ }
+ }
+
+ return E_INVALIDARG;
+}
+
+HRESULT STDMETHODCALLTYPE CRegistryFolder::MapColumnToSCID(
+ UINT iColumn,
+ SHCOLUMNID *pscid)
+{
+ static const GUID storage = PSGUID_STORAGE;
+ switch (iColumn)
+ {
+ case REGISTRY_COLUMN_NAME:
+ pscid->fmtid = storage;
+ pscid->pid = PID_STG_NAME;
+ return S_OK;
+ case REGISTRY_COLUMN_TYPE:
+ pscid->fmtid = storage;
+ pscid->pid = PID_STG_STORAGETYPE;
+ return S_OK;
+ case REGISTRY_COLUMN_VALUE:
+ pscid->fmtid = storage;
+ pscid->pid = PID_STG_CONTENTS;
+ return S_OK;
+ }
+ return E_INVALIDARG;
+}
Propchange: trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: 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 (added)
+++ trunk/reactos/dll/shellext/ntobjshex/regfolder.h [iso-8859-1] Mon Feb 23 17:13:32
2015
@@ -0,0 +1,149 @@
+/*
+ * PROJECT: ReactOS system libraries
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: dll\win32\stobject\stobject.cpp
+ * PURPOSE: Systray shell service object
+ * PROGRAMMERS: Robert Naumann
+ David Quintana <gigaherz(a)gmail.com>
+ */
+#pragma once
+
+extern const GUID CLSID_RegistryFolder;
+
+class CRegistryPidlManager;
+
+class CRegistryFolder :
+ public CComCoClass<CRegistryFolder, &CLSID_RegistryFolder>,
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IShellFolder2,
+ public IPersistFolder2
+{
+ CRegistryPidlManager * m_PidlManager;
+
+ WCHAR m_NtPath[MAX_PATH];
+
+ LPITEMIDLIST m_shellPidl;
+
+public:
+
+ CRegistryFolder();
+ virtual ~CRegistryFolder();
+
+ CRegistryPidlManager& GetManager() { return *m_PidlManager; }
+
+ // IShellFolder
+ virtual HRESULT STDMETHODCALLTYPE ParseDisplayName(
+ HWND hwndOwner,
+ LPBC pbcReserved,
+ LPOLESTR lpszDisplayName,
+ ULONG *pchEaten,
+ LPITEMIDLIST *ppidl,
+ ULONG *pdwAttributes);
+
+ virtual HRESULT STDMETHODCALLTYPE EnumObjects(
+ HWND hwndOwner,
+ SHCONTF grfFlags,
+ IEnumIDList **ppenumIDList);
+
+ virtual HRESULT STDMETHODCALLTYPE BindToObject(
+ LPCITEMIDLIST pidl,
+ LPBC pbcReserved,
+ REFIID riid,
+ void **ppvOut);
+
+ virtual HRESULT STDMETHODCALLTYPE BindToStorage(
+ LPCITEMIDLIST pidl,
+ LPBC pbcReserved,
+ REFIID riid,
+ void **ppvObj);
+
+ virtual HRESULT STDMETHODCALLTYPE CompareIDs(
+ LPARAM lParam,
+ LPCITEMIDLIST pidl1,
+ LPCITEMIDLIST pidl2);
+
+ virtual HRESULT STDMETHODCALLTYPE CreateViewObject(
+ HWND hwndOwner,
+ REFIID riid,
+ void **ppvOut);
+
+ virtual HRESULT STDMETHODCALLTYPE GetAttributesOf(
+ UINT cidl,
+ PCUITEMID_CHILD_ARRAY apidl,
+ SFGAOF *rgfInOut);
+
+ virtual HRESULT STDMETHODCALLTYPE GetUIObjectOf(
+ HWND hwndOwner,
+ UINT cidl,
+ PCUITEMID_CHILD_ARRAY apidl,
+ REFIID riid,
+ UINT *prgfInOut,
+ void **ppvOut);
+
+ virtual HRESULT STDMETHODCALLTYPE GetDisplayNameOf(
+ LPCITEMIDLIST pidl,
+ SHGDNF uFlags,
+ STRRET *lpName);
+
+ virtual HRESULT STDMETHODCALLTYPE SetNameOf(
+ HWND hwnd,
+ LPCITEMIDLIST pidl,
+ LPCOLESTR lpszName,
+ SHGDNF uFlags,
+ LPITEMIDLIST *ppidlOut);
+
+ // IShellFolder2
+ virtual HRESULT STDMETHODCALLTYPE GetDefaultSearchGUID(
+ GUID *lpguid);
+
+ virtual HRESULT STDMETHODCALLTYPE EnumSearches(
+ IEnumExtraSearch **ppenum);
+
+ virtual HRESULT STDMETHODCALLTYPE GetDefaultColumn(
+ DWORD dwReserved,
+ ULONG *pSort,
+ ULONG *pDisplay);
+
+ virtual HRESULT STDMETHODCALLTYPE GetDefaultColumnState(
+ UINT iColumn,
+ SHCOLSTATEF *pcsFlags);
+
+ virtual HRESULT STDMETHODCALLTYPE GetDetailsEx(
+ LPCITEMIDLIST pidl,
+ const SHCOLUMNID *pscid,
+ VARIANT *pv);
+
+ virtual HRESULT STDMETHODCALLTYPE GetDetailsOf(
+ LPCITEMIDLIST pidl,
+ UINT iColumn,
+ SHELLDETAILS *psd);
+
+ virtual HRESULT STDMETHODCALLTYPE MapColumnToSCID(
+ UINT iColumn,
+ SHCOLUMNID *pscid);
+
+ // IPersist
+ virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *lpClassId);
+
+ // IPersistFolder
+ virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidl);
+
+ // IPersistFolder2
+ virtual HRESULT STDMETHODCALLTYPE GetCurFolder(LPITEMIDLIST * pidl);
+
+ // Internal
+ HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidl, PCWSTR ntPath);
+
+ DECLARE_REGISTRY_RESOURCEID(IDR_NTOBJECTFOLDER)
+ DECLARE_NOT_AGGREGATABLE(CRegistryFolder)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CRegistryFolder)
+ COM_INTERFACE_ENTRY_IID(IID_IShellFolder, IShellFolder)
+ COM_INTERFACE_ENTRY_IID(IID_IShellFolder2, IShellFolder2)
+ COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
+ COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
+ COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
+ END_COM_MAP()
+
+};
Propchange: trunk/reactos/dll/shellext/ntobjshex/regfolder.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/shellext/ntobjshex/resource.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/res…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/resource.h [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/ntobjshex/resource.h [iso-8859-1] Mon Feb 23 17:13:32 2015
@@ -7,6 +7,9 @@
#define IDI_NTOBJECTDEVICE 5
#define IDI_NTOBJECTPORT 6
+#define IDI_REGISTRYKEY 32
+#define IDI_REGISTRYVALUE 33
+
#define IDS_NAME 101
#define IDR_NTOBJECTFOLDER 1001
Added: trunk/reactos/dll/shellext/ntobjshex/util.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/uti…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/util.h (added)
+++ trunk/reactos/dll/shellext/ntobjshex/util.h [iso-8859-1] Mon Feb 23 17:13:32 2015
@@ -0,0 +1,44 @@
+#pragma once
+
+#ifndef INLINE
+#define INLINE inline
+#endif
+
+HRESULT INLINE MakeStrRetFromString(LPCWSTR string, DWORD cbLength, STRRET * str)
+{
+ str->uType = STRRET_WSTR;
+
+ DWORD blen = cbLength + sizeof(WCHAR);
+ str->pOleStr = (LPWSTR) CoTaskMemAlloc(blen);
+ return StringCbCopyNW(str->pOleStr, blen, string, cbLength);
+}
+
+HRESULT INLINE MakeStrRetFromString(LPCWSTR string, STRRET * str)
+{
+ DWORD stringLength = wcslen(string) * sizeof(WCHAR);
+ return MakeStrRetFromString(string, stringLength, str);
+}
+
+HRESULT INLINE MakeVariantString(VARIANT * pv, PCWSTR string)
+{
+ V_VT(pv) = VT_BSTR;
+ V_BSTR(pv) = SysAllocString(string);
+ return S_OK;
+}
+
+HRESULT INLINE GetFullName(PCIDLIST_ABSOLUTE pidl, DWORD uFlags, PWSTR strName, DWORD
cchName)
+{
+ CComPtr<IShellFolder> psfDesktop;
+ STRRET str;
+ HRESULT hr;
+
+ hr = SHGetDesktopFolder(&psfDesktop);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ hr = psfDesktop->GetDisplayNameOf(pidl, uFlags, &str);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ return StrRetToBufW(&str, pidl, strName, cchName);
+}
Propchange: trunk/reactos/dll/shellext/ntobjshex/util.h
------------------------------------------------------------------------------
svn:eol-style = native