[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

svn path=/trunk/; revision=66426
This commit is contained in:
David Quintana
2015-02-23 17:13:32 +00:00
parent b7138a87f6
commit a2605cb0d4
9 changed files with 1774 additions and 72 deletions
@@ -19,6 +19,7 @@ add_library(ntobjshex SHARED
ntobjshex.cpp
ntobjutil.cpp
ntobjshex.rc
regfolder.cpp
${CMAKE_CURRENT_BINARY_DIR}/ntobjshex.def)
list(APPEND atl_rc_deps
+117 -68
View File
@@ -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 @@ enum NtObjectColumns
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 @@ public:
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 @@ public:
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 @@ public:
}
}
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 @@ public:
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 @@ public:
{
case SYMBOLICLINK_OBJECT:
case DIRECTORY_OBJECT:
case KEY_OBJECT:
flagsOk = (m_Flags & SHCONTF_FOLDERS) != 0;
break;
default:
@@ -613,7 +587,7 @@ public:
}
} 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 @@ public:
//-----------------------------------------------------------------------------
// 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() :
CNtObjectFolder::~CNtObjectFolder()
{
TRACE("Destroying CNtObjectFolder %p\n", this);
}
// IShellFolder
@@ -697,7 +666,7 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::ParseDisplayName(
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 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::BindToObject(
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);
hr = ShellObjectCreatorInit<CNtObjectFolder>(fullPidl, path, IID_PPV_ARG(IShellFolder, &psfChild));
}
LPITEMIDLIST fullPidl = ILCombine(m_shellPidl, pidl);
hr = ShellObjectCreatorInit<CNtObjectFolder>(fullPidl, path, riid, ppvOut);
ILFree(fullPidl);
ILFree(first);
return hr;
if (rest->mkid.cb > 0)
{
return psfChild->BindToObject(rest, pbcReserved, riid, ppvOut);
}
return psfChild->QueryInterface(riid, ppvOut);
}
return E_NOTIMPL;
@@ -953,18 +950,70 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetClassID(CLSID *lpClassId)
// 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)
{
m_shellPidl = ILClone(pidl);
StringCbCopy(m_NtPath, _countof(m_NtPath), ntPath);
TRACE("INITIALIZE %p CNtObjectFolder with ntPath %S\n", this, ntPath);
#if 0
m_shellPidl = ILClone(pidl);
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 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsEx(
{
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 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsEx(
{
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 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsOf(
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 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsOf(
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)
{
+176 -3
View File
@@ -36,7 +36,22 @@ const LPCWSTR ObjectTypeNames [] = {
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 @@ HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount)
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 @@ HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount)
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 @@ HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount)
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;
}
+35 -1
View File
@@ -37,8 +37,11 @@ enum OBJECT_TYPE {
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 @@ struct NtPidlSymlinkData
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);
+1
View File
@@ -47,3 +47,4 @@ DEFINE_GUID(CLSID_NtObjectFolder,
0x845b0fb2, 0x66e0, 0x416b, 0x8f, 0x91, 0x31, 0x4e, 0x23, 0xf7, 0xc1, 0x2d);
#include "ntobjns.h"
#include "regfolder.h"
File diff suppressed because it is too large Load Diff
+149
View File
@@ -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 <[email protected]>
*/
#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()
};
@@ -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
+44
View File
@@ -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);
}