Author: dquintana
Date: Fri Aug 21 14:26:25 2015
New Revision: 68783
URL:
http://svn.reactos.org/svn/reactos?rev=68783&view=rev
Log:
[NTOBJSHEX]
* Use lazy enumeration of the nt objects and registry keys, as intended for the
IEnumIDList interface.
* Display of the NT Object creation date has been lost in the process, but it was only
really used by symlinks.
* Symlink target display doesn't appear to work at the moment, will fix later.
Modified:
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/regfolder.cpp
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] Fri Aug 21 14:26:25
2015
@@ -34,7 +34,6 @@
{
NTOBJECT_COLUMN_NAME = 0,
NTOBJECT_COLUMN_TYPE,
- NTOBJECT_COLUMN_CREATEDATE,
NTOBJECT_COLUMN_LINKTARGET,
NTOBJECT_COLUMN_END
};
@@ -43,28 +42,25 @@
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IExtractIconW
{
- PCIDLIST_ABSOLUTE m_pcidlFolder;
- PCITEMID_CHILD m_pcidlChild;
+ PCITEMID_CHILD m_pcidlChild;
+ LPCWSTR m_NtPath;
public:
CNtObjectFolderExtractIcon() :
- m_pcidlFolder(NULL),
- m_pcidlChild(NULL)
+ m_pcidlChild(NULL), m_NtPath(NULL)
{
}
virtual ~CNtObjectFolderExtractIcon()
{
- 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);
+ HRESULT Initialize(LPCWSTR ntPath, UINT cidl, PCUITEMID_CHILD_ARRAY apidl)
+ {
+ m_NtPath = ntPath;
if (cidl != 1)
return E_INVALIDARG;
m_pcidlChild = ILClone(apidl[0]);
@@ -85,11 +81,6 @@
UINT flags = 0;
-#define GIL_CHECKSHIELD 0x0200
-#define GIL_SHIELD 0x0200
- if (uFlags & GIL_CHECKSHIELD &&
!(entry->objectInformation.GrantedAccess & STANDARD_RIGHTS_READ))
- flags |= GIL_SHIELD;
-
switch (entry->objectType)
{
case DIRECTORY_OBJECT:
@@ -145,193 +136,21 @@
private:
PWSTR m_ntPath;
- HDPA m_hDpa;
- UINT m_hDpaCount;
-
- int DpaDeleteCallback(NtPidlEntry * info)
- {
- CoTaskMemFree(info);
- return 0;
- }
-
- static int CALLBACK s_DpaDeleteCallback(void *pItem, void *pData)
- {
- CNtObjectPidlManager * mf = (CNtObjectPidlManager*) pData;
- NtPidlEntry * item = (NtPidlEntry*) pItem;
- return mf->DpaDeleteCallback(item);
- }
-
public:
CNtObjectPidlManager() :
- m_ntPath(NULL),
- m_hDpa(NULL),
- m_hDpaCount(0)
+ m_ntPath(NULL)
{
}
~CNtObjectPidlManager()
{
- DPA_DestroyCallback(m_hDpa, s_DpaDeleteCallback, this);
}
HRESULT Initialize(PWSTR ntPath)
{
m_ntPath = ntPath;
- m_hDpa = NULL;
-
- return S_OK;
- }
-
- HRESULT Enumerate()
- {
- if (m_hDpa)
- return S_OK;
-
- m_hDpa = DPA_Create(10);
-
- if (!m_hDpa)
- return E_OUTOFMEMORY;
-
- HRESULT hr = EnumerateNtDirectory(m_hDpa, m_ntPath, &m_hDpaCount);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- return S_OK;
- }
-
- HRESULT FindPidlInList(PCUITEMID_CHILD pcidl, const NtPidlEntry ** pinfo)
- {
- HRESULT hr;
-
- if (!m_hDpa)
- {
- hr = Enumerate();
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- if (!m_hDpa)
- return E_FAIL;
- }
-
- const NtPidlEntry * info = (const 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 { name='%S' } in a list of %d
items\n", info->entryName, m_hDpaCount);
-
- for (UINT i = 0; i < m_hDpaCount; i++)
- {
- const NtPidlEntry * pInfo = (const NtPidlEntry *) DPA_GetPtr(m_hDpa, i);
- ASSERT(pInfo);
-
- hr = CompareIDs(SHCIDS_CANONICALONLY, pInfo, info);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- if (hr == S_OK)
- {
- *pinfo = pInfo;
- return S_OK;
- }
- else
- {
- TRACE("Comparison returned %d for '%S'\n", (int)
(short) (hr & 0xFFFF), pInfo->entryName);
- }
- }
-
- ERR("PIDL NOT FOUND: Requested filename: %S\n", info->entryName);
- *pinfo = NULL;
-
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
-
- HRESULT FindByName(LPCWSTR strParsingName, NtPidlEntry ** pinfo)
- {
- HRESULT hr;
-
- if (!m_hDpa)
- {
- hr = Enumerate();
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- 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++)
- {
- NtPidlEntry * pInfo = (NtPidlEntry *) 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, NtPidlEntry ** pEntry)
- {
- if (!m_hDpa)
- {
- HRESULT hr = Enumerate();
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- if (!m_hDpa)
- return E_FAIL;
- }
-
- *pEntry = NULL;
-
- NtPidlEntry * entry = (NtPidlEntry *) DPA_GetPtr(m_hDpa, index);
- if (!entry)
- {
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
-
- *pEntry = entry;
- return S_OK;
- }
-
- HRESULT GetCount(UINT * count)
- {
- if (!m_hDpa)
- {
- HRESULT hr = Enumerate();
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- if (!m_hDpa)
- return E_FAIL;
- }
-
- *count = m_hDpaCount;
- return S_OK;
- }
-
- static LPITEMIDLIST CreatePidlFromItem(const NtPidlEntry * 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;
+
+ return S_OK;
}
static HRESULT CompareIDs(LPARAM lParam, const NtPidlEntry * first, const NtPidlEntry
* second)
@@ -413,16 +232,6 @@
return S_OK;
}
- case NTOBJECT_COLUMN_CREATEDATE:
- {
- LONGLONG ord = second->objectInformation.CreateTime.QuadPart -
first->objectInformation.CreateTime.QuadPart;
- if (ord > 0)
- return MAKE_HRESULT(0, 0, (USHORT) 1);
- if (ord < 0)
- return MAKE_HRESULT(0, 0, (USHORT) -1);
-
- return S_OK;
- }
case NTOBJECT_COLUMN_LINKTARGET:
{
// Can't sort by value
@@ -478,131 +287,34 @@
BOOL IsFolder(LPCITEMIDLIST pcidl)
{
- const NtPidlEntry * entry;
- HRESULT hr = FindPidlInList(pcidl, &entry);
- if (FAILED_UNEXPECTEDLY(hr))
+ NtPidlEntry * entry = (NtPidlEntry*) &(pcidl->mkid);
+ if ((entry->cb < sizeof(NtPidlEntry)) || (entry->magic !=
NT_OBJECT_PIDL_MAGIC))
return FALSE;
return (entry->objectType == DIRECTORY_OBJECT) ||
(entry->objectType == SYMBOLICLINK_OBJECT) ||
(entry->objectType == KEY_OBJECT);
}
-};
-
-class CNtObjectFolderEnum :
- public CComObjectRootEx<CComMultiThreadModelNoCS>,
- public IEnumIDList
-{
-private:
- CComPtr<CNtObjectFolder> m_Folder;
-
- HWND m_HwndOwner;
- SHCONTF m_Flags;
-
- UINT m_Index;
- UINT m_Count;
-
-public:
- CNtObjectFolderEnum() :
- m_HwndOwner(NULL),
- m_Flags(0),
- m_Index(0),
- m_Count(0)
- {
- }
-
- virtual ~CNtObjectFolderEnum()
- {
- }
-
- HRESULT Initialize(CNtObjectFolder * 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;)
- {
- NtPidlEntry * tinfo;
- BOOL flagsOk = FALSE;
-
- do {
- HRESULT hr = m_Folder->GetManager().GetPidl(m_Index++, &tinfo);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- switch (tinfo->objectType)
- {
- case SYMBOLICLINK_OBJECT:
- case DIRECTORY_OBJECT:
- case KEY_OBJECT:
- 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<CNtObjectFolderEnum>(m_Folder, m_HwndOwner,
m_Flags, IID_PPV_ARG(IEnumIDList, ppenum));
- }
-
- DECLARE_NOT_AGGREGATABLE(CNtObjectFolderEnum)
- DECLARE_PROTECT_FINAL_CONSTRUCT()
-
- BEGIN_COM_MAP(CNtObjectFolderEnum)
- COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
- END_COM_MAP()
-
+
+ virtual HRESULT GetInfoFromPidl(LPCITEMIDLIST pcidl, const NtPidlEntry ** pentry)
+ {
+ NtPidlEntry * entry = (NtPidlEntry*) &(pcidl->mkid);
+
+ if (entry->cb < sizeof(NtPidlEntry))
+ {
+ DbgPrint("PCIDL too small %l (required %l)\n", entry->cb,
sizeof(NtPidlEntry));
+ return E_INVALIDARG;
+ }
+
+ if (entry->magic != NT_OBJECT_PIDL_MAGIC)
+ {
+ DbgPrint("PCIDL magic mismatch %04x (expected %04x)\n",
entry->magic, NT_OBJECT_PIDL_MAGIC);
+ return E_INVALIDARG;
+ }
+
+ *pentry = entry;
+ return S_OK;
+ }
};
//-----------------------------------------------------------------------------
@@ -631,8 +343,6 @@
LPITEMIDLIST *ppidl,
ULONG *pdwAttributes)
{
- NtPidlEntry * info;
-
if (!ppidl)
return E_POINTER;
@@ -644,19 +354,43 @@
TRACE("CNtObjectFolder::ParseDisplayName name=%S (ntPath=%S)\n",
lpszDisplayName, m_NtPath);
- HRESULT hr = m_PidlManager->FindByName(lpszDisplayName, &info);
+ const NtPidlEntry * info;
+ IEnumIDList * it;
+ HRESULT hr = GetEnumNTDirectory(m_NtPath, &it);
if (FAILED(hr))
+ return hr;
+
+ while (TRUE)
+ {
+ hr = it->Next(1, ppidl, NULL);
+
+ if (FAILED(hr))
+ return hr;
+
+ if (hr != S_OK)
+ break;
+
+ hr = m_PidlManager->GetInfoFromPidl(*ppidl, &info);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ if (StrCmpW(info->entryName, lpszDisplayName) == 0)
+ break;
+ }
+
+ if (hr != S_OK)
{
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);
+ if (pchEaten || pdwAttributes)
+ {
+ if (pchEaten)
+ *pchEaten = wcslen(info->entryName);
+
+ if (pdwAttributes)
+ *pdwAttributes = m_PidlManager->ConvertAttributes(info, pdwAttributes);
+ }
return S_OK;
}
@@ -666,7 +400,7 @@
SHCONTF grfFlags,
IEnumIDList **ppenumIDList)
{
- return ShellObjectCreatorInit<CNtObjectFolderEnum>(this, hwndOwner, grfFlags,
IID_PPV_ARG(IEnumIDList, ppenumIDList));
+ return GetEnumNTDirectory(m_NtPath, ppenumIDList);
}
HRESULT STDMETHODCALLTYPE CNtObjectFolder::BindToObject(
@@ -679,13 +413,10 @@
if (IsEqualIID(riid, IID_IShellFolder))
{
- HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+ HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
- if (!(info->objectInformation.GrantedAccess & (STANDARD_RIGHTS_READ |
FILE_LIST_DIRECTORY)))
- return E_ACCESSDENIED;
-
WCHAR path[MAX_PATH];
StringCbCopyW(path, _countof(path), m_NtPath);
@@ -699,18 +430,32 @@
if (info->objectType == SYMBOLICLINK_OBJECT)
{
- NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
-
- if (symlink->targetNameLength > 0)
- {
- if (symlink->targetName[1] == L':' &&
isalphaW(symlink->targetName[0]))
+ WCHAR wbLink[MAX_PATH] = { 0 };
+ UNICODE_STRING link;
+ RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
+
+ hr = GetNTObjectSymbolicLinkTarget(m_NtPath, info->entryName, &link);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ if (link.Length > 0)
+ {
+ if (link.Buffer[1] == L':' && isalphaW(link.Buffer[0]))
{
- ERR("TODO: Navigating to WIN32 PATH from NT PATH.\n");
- return E_NOTIMPL;
+ 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;
+
+ return psfDesktop->BindToObject(rest, pbcReserved, riid, ppvOut);
}
StringCbCopyW(path, _countof(path),
L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{845B0FB2-66E0-416B-8F91-314E23F7C12D}");
- PathAppend(path, symlink->targetName);
+ PathAppend(path, link.Buffer);
CComPtr<IShellFolder> psfDesktop;
hr = SHGetDesktopFolder(&psfDesktop);
@@ -731,7 +476,7 @@
if (info->objectType == KEY_OBJECT)
{
- hr = ShellObjectCreatorInit<CRegistryFolder>(fullPidl, path,
(HKEY)NULL, IID_PPV_ARG(IShellFolder, &psfChild));
+ hr = ShellObjectCreatorInit<CRegistryFolder>(fullPidl, path, (HKEY)
NULL, IID_PPV_ARG(IShellFolder, &psfChild));
}
else
{
@@ -824,7 +569,7 @@
{
const NtPidlEntry * info;
- TRACE("GetAttributesOf\n");
+ TRACE("GetAttributesOf %d\n", cidl);
if (cidl == 0)
{
@@ -836,7 +581,7 @@
{
PCUITEMID_CHILD pidl = apidl[i];
- HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+ HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@@ -855,6 +600,7 @@
UINT *prgfInOut,
void **ppvOut)
{
+ DWORD res;
TRACE("GetUIObjectOf\n");
if (IsEqualIID(riid, IID_IContextMenu) ||
@@ -863,12 +609,14 @@
{
CComPtr<IContextMenu> pcm;
- HKEY keys [1];
+ HKEY keys[1];
int nkeys = _countof(keys);
if (cidl == 1 && m_PidlManager->IsFolder(apidl[0]))
{
- RegOpenKey(HKEY_CLASSES_ROOT, L"Folder", keys + 0);
+ res = RegOpenKey(HKEY_CLASSES_ROOT, L"Folder", keys + 0);
+ if (!NT_SUCCESS(res))
+ return HRESULT_FROM_NT(res);
}
else
{
@@ -884,12 +632,12 @@
if (IsEqualIID(riid, IID_IExtractIconW))
{
- return ShellObjectCreatorInit<CNtObjectFolderExtractIcon>(m_shellPidl,
cidl, apidl, riid, ppvOut);
+ return ShellObjectCreatorInit<CNtObjectFolderExtractIcon>(m_NtPath, cidl,
apidl, riid, ppvOut);
}
if (IsEqualIID(riid, IID_IDataObject))
{
- return CIDLData_CreateFromIDArray(m_shellPidl, cidl, apidl,
(IDataObject**)ppvOut);
+ return CIDLData_CreateFromIDArray(m_shellPidl, cidl, apidl, (IDataObject**)
ppvOut);
}
if (IsEqualIID(riid, IID_IQueryAssociations))
@@ -921,7 +669,7 @@
TRACE("GetDisplayNameOf %p\n", pidl);
- HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+ HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@@ -964,7 +712,7 @@
PathAppendW(path, temp);
}
- ILFree((LPITEMIDLIST)pidlFirst);
+ ILFree((LPITEMIDLIST) pidlFirst);
}
else
{
@@ -1073,11 +821,8 @@
case NTOBJECT_COLUMN_TYPE:
*pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT;
return S_OK;
- case NTOBJECT_COLUMN_CREATEDATE:
- *pcsFlags = SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT;
- return S_OK;
case NTOBJECT_COLUMN_LINKTARGET:
- *pcsFlags = SHCOLSTATE_TYPE_STR;
+ *pcsFlags = SHCOLSTATE_TYPE_STR | SHCOLSTATE_SLOW;
return S_OK;
}
@@ -1095,7 +840,7 @@
if (pidl)
{
- HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+ HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@@ -1126,35 +871,25 @@
return MakeVariantString(pv, ObjectTypeNames[info->objectType]);
}
}
- else if (pscid->pid == PID_STG_WRITETIME)
- {
- DOUBLE varTime;
- SYSTEMTIME stime;
- FileTimeToSystemTime((FILETIME*)
&(info->objectInformation.CreateTime), &stime);
- SystemTimeToVariantTime(&stime, &varTime);
-
- V_VT(pv) = VT_DATE;
- V_DATE(pv) = varTime;
- return S_OK;
- }
}
else if (IsEqualGUID(pscid->fmtid, GUID_NtObjectColumns))
{
- if (pscid->pid == NTOBJECT_COLUMN_LINKTARGET)
- {
- if (info->objectType == SYMBOLICLINK_OBJECT)
+ if (pscid->pid == NTOBJECT_COLUMN_LINKTARGET &&
info->objectType == SYMBOLICLINK_OBJECT)
+ {
+ WCHAR wbLink[MAX_PATH] = { 0 };
+ UNICODE_STRING link;
+ RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
+
+ HRESULT hr = GetNTObjectSymbolicLinkTarget(m_NtPath, info->entryName,
&link);
+
+ if (!FAILED_UNEXPECTEDLY(hr) && link.Length > 0)
{
- NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
-
- if (symlink->targetNameLength > 0)
- {
- return MakeVariantString(pv, symlink->targetName);
- }
+ return MakeVariantString(pv, link.Buffer);
}
-
- V_VT(pv) = VT_EMPTY;
- return S_OK;
- }
+ }
+
+ V_VT(pv) = VT_EMPTY;
+ return S_OK;
}
}
@@ -1172,7 +907,7 @@
if (pidl)
{
- HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+ HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@@ -1198,43 +933,28 @@
else
MakeStrRetFromString(ObjectTypeNames[info->objectType],
&(psd->str));
return S_OK;
- case NTOBJECT_COLUMN_CREATEDATE:
+ case NTOBJECT_COLUMN_LINKTARGET:
+ {
psd->fmt = LVCFMT_LEFT;
- if (info->objectInformation.CreateTime.QuadPart != 0)
- {
- WCHAR dbuff[128];
- PWSTR tbuff;
- SYSTEMTIME stime;
- FileTimeToSystemTime((LPFILETIME)
&(info->objectInformation.CreateTime), &stime);
- GetDateFormat(LOCALE_USER_DEFAULT, 0, &stime, NULL, dbuff,
_countof(dbuff));
- tbuff = dbuff + wcslen(dbuff);
- *tbuff++ = L' ';
- GetTimeFormat(LOCALE_USER_DEFAULT, 0, &stime, NULL, tbuff,
_countof(dbuff) - (tbuff - dbuff));
-
- MakeStrRetFromString(dbuff, &(psd->str));
- return S_OK;
- }
-
- MakeStrRetFromString(L"", &(psd->str));
- return S_OK;
-
- case NTOBJECT_COLUMN_LINKTARGET:
- psd->fmt = LVCFMT_LEFT;
-
if (info->objectType == SYMBOLICLINK_OBJECT)
{
- NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) (((PBYTE) info) +
FIELD_OFFSET(NtPidlEntry, entryName) + info->entryNameLength + sizeof(WCHAR));
-
- if (symlink->targetNameLength > 0)
+ WCHAR wbLink[MAX_PATH] = { 0 };
+ UNICODE_STRING link;
+ RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
+
+ HRESULT hr = GetNTObjectSymbolicLinkTarget(m_NtPath, info->entryName,
&link);
+
+ if (!FAILED_UNEXPECTEDLY(hr) && link.Length > 0)
{
- MakeStrRetFromString(symlink->targetName,
symlink->targetNameLength, &(psd->str));
+ MakeStrRetFromString(link.Buffer, link.Length, &(psd->str));
return S_OK;
}
}
MakeStrRetFromString(L"", &(psd->str));
return S_OK;
+ }
}
}
else
@@ -1255,13 +975,6 @@
// TODO: Make localizable
MakeStrRetFromString(L"Object Type", &(psd->str));
return S_OK;
- case NTOBJECT_COLUMN_CREATEDATE:
- psd->fmt = LVCFMT_LEFT;
- psd->cxChar = 20;
-
- // TODO: Make localizable
- MakeStrRetFromString(L"Creation Time", &(psd->str));
- return S_OK;
case NTOBJECT_COLUMN_LINKTARGET:
psd->fmt = LVCFMT_LEFT;
psd->cxChar = 30;
@@ -1290,10 +1003,6 @@
pscid->fmtid = storage;
pscid->pid = PID_STG_STORAGETYPE;
return S_OK;
- case NTOBJECT_COLUMN_CREATEDATE:
- pscid->fmtid = storage;
- pscid->pid = PID_STG_WRITETIME;
- return S_OK;
case NTOBJECT_COLUMN_LINKTARGET:
pscid->fmtid = GUID_NtObjectColumns;
pscid->pid = NTOBJECT_COLUMN_LINKTARGET;
@@ -1316,8 +1025,6 @@
return S_FALSE;
case SFVM_BACKGROUNDENUM:
return S_OK;
- case SFVM_DEFITEMCOUNT:
- return m_PidlManager->GetCount((UINT*) lParam);
}
return E_NOTIMPL;
}
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] Fri Aug 21 14:26:25
2015
@@ -23,6 +23,17 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntobjshex);
+static struct RootKeyEntry {
+ HKEY key;
+ PCWSTR keyName;
+} RootKeys [] = {
+ { HKEY_CLASSES_ROOT, L"HKEY_CLASSES_ROOT" },
+ { HKEY_CURRENT_USER, L"HKEY_CURRENT_USER" },
+ { HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE" },
+ { HKEY_USERS, L"HKEY_USERS" },
+ { HKEY_CURRENT_CONFIG, L"HKEY_CURRENT_CONFIG" }
+};
+
typedef NTSTATUS(__stdcall* pfnNtGenericOpen)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
typedef NTSTATUS(__stdcall* pfnNtOpenFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK, ULONG, ULONG);
@@ -36,7 +47,7 @@
0
};
-const LPCWSTR RegistryTypeNames[] = {
+const LPCWSTR RegistryTypeNames [] = {
L"REG_NONE",
L"REG_SZ",
L"REG_EXPAND_SZ",
@@ -99,218 +110,132 @@
return UNKNOWN_OBJECT_TYPE;
}
-HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount)
-{
+HRESULT ReadRegistryValue(HKEY root, PCWSTR path, PCWSTR valueName, PVOID * valueData,
PDWORD valueLength)
+{
+ HKEY hkey;
+
+ DWORD res;
+ if (root)
+ {
+ res = RegOpenKeyExW(root, *path == '\\' ? path + 1 : path, 0,
STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, &hkey);
+ }
+ else
+ {
+ res = NtOpenObject(KEY_OBJECT, (PHANDLE) &hkey, STANDARD_RIGHTS_READ |
KEY_QUERY_VALUE, path);
+ }
+ if (!NT_SUCCESS(res))
+ {
+ ERR("RegOpenKeyExW failed for path %S with status=%x\n", path, res);
+ return HRESULT_FROM_NT(res);
+ }
+
+ res = RegQueryValueExW(hkey, valueName, NULL, NULL, NULL, valueLength);
+ if (!NT_SUCCESS(res))
+ {
+ ERR("RegQueryValueExW failed for path %S with status=%x\n", path,
res);
+ return HRESULT_FROM_NT(res);
+ }
+
+ if (*valueLength > 0)
+ {
+ PBYTE data = (PBYTE) CoTaskMemAlloc(*valueLength);;
+ *valueData = data;
+
+ res = RegQueryValueExW(hkey, valueName, NULL, NULL, data, valueLength);
+ if (!NT_SUCCESS(res))
+ {
+ CoTaskMemFree(data);
+ *valueData = NULL;
+
+ RegCloseKey(hkey);
+
+ ERR("RegOpenKeyExW failed for path %S with status=%x\n", path,
res);
+ return HRESULT_FROM_NT(res);
+ }
+ }
+ else
+ {
+ *valueData = NULL;
+ }
+
+ RegCloseKey(hkey);
+
+ return S_OK;
+}
+
+HRESULT GetNTObjectSymbolicLinkTarget(LPCWSTR path, LPCWSTR entryName, PUNICODE_STRING
LinkTarget)
+{
+ HANDLE handle;
WCHAR buffer[MAX_PATH];
- PWSTR pend;
-
- *hdpaCount = 0;
+ LPWSTR pend = buffer;
StringCbCopyExW(buffer, sizeof(buffer), path, &pend, NULL, 0);
-
- ULONG enumContext = 0;
- HANDLE directory = NULL;
-
- DWORD err = NtOpenObject(DIRECTORY_OBJECT, &directory, FILE_LIST_DIRECTORY,
buffer);
- if (!NT_SUCCESS(err))
- {
- ERR("NtOpenDirectoryObject failed for path %S with status=%x\n",
buffer, err);
- return HRESULT_FROM_NT(err);
- }
if (pend[-1] != '\\')
*pend++ = '\\';
-
- BYTE dirbuffer[2048];
-
- BOOL first = TRUE;
- while (NtQueryDirectoryObject(directory, dirbuffer, 2048, TRUE, first,
&enumContext, NULL) == STATUS_SUCCESS)
- {
- first = FALSE;
- POBJECT_DIRECTORY_INFORMATION info = (POBJECT_DIRECTORY_INFORMATION) dirbuffer;
- //for (; info->Name.Buffer != NULL; info++)
- {
- if (info->Name.Buffer)
- {
- StringCbCopyNW(pend, sizeof(buffer), info->Name.Buffer,
info->Name.Length);
- }
-
- OBJECT_TYPE otype = MapTypeNameToType(info->TypeName.Buffer,
info->TypeName.Length);
- OBJECT_BASIC_INFORMATION object = { 0 };
-
- WCHAR wbLink[_MAX_PATH] = { 0 };
- UNICODE_STRING link;
- RtlInitEmptyUnicodeString(&link, wbLink, sizeof(wbLink));
-
- DWORD entryBufferLength = FIELD_OFFSET(NtPidlEntry,entryName) +
sizeof(WCHAR);
- if (info->Name.Buffer)
- entryBufferLength += info->Name.Length;
-
- if (otype < 0)
- {
- entryBufferLength += FIELD_OFFSET(NtPidlTypeData,typeName) +
sizeof(WCHAR);
-
- if (info->TypeName.Buffer)
- {
- entryBufferLength += info->TypeName.Length;
- }
- }
-
- if (otype == SYMBOLICLINK_OBJECT)
- {
- entryBufferLength += FIELD_OFFSET(NtPidlSymlinkData,targetName) +
sizeof(WCHAR);
- }
-
- DWORD access = STANDARD_RIGHTS_READ;
- if ((otype == DIRECTORY_OBJECT) ||
- (otype == SYMBOLICLINK_OBJECT))
- access |= FILE_LIST_DIRECTORY;
-
- HANDLE handle;
- if (!NtOpenObject(otype, &handle, access, buffer))
- {
- DWORD read;
-
- if (!NT_SUCCESS(NtQueryObject(handle, ObjectBasicInformation,
&object, sizeof(OBJECT_BASIC_INFORMATION), &read)))
- {
- ZeroMemory(&object, sizeof(OBJECT_BASIC_INFORMATION));
- }
-
- if (otype == SYMBOLICLINK_OBJECT)
- {
- if (NtQuerySymbolicLinkObject(handle, &link, NULL) ==
STATUS_SUCCESS)
- {
- entryBufferLength += link.Length;
- }
- else
- {
- link.Length = 0;
- }
- }
-
- NtClose(handle);
- }
-
- NtPidlEntry* entry = (NtPidlEntry*) CoTaskMemAlloc(entryBufferLength);
- if (!entry)
- return E_OUTOFMEMORY;
-
- memset(entry, 0, entryBufferLength);
-
- entry->cb = FIELD_OFFSET(NtPidlEntry,entryName);
- entry->magic = NT_OBJECT_PIDL_MAGIC;
- entry->objectType = otype;
- entry->objectInformation = object;
- memset(entry->objectInformation.Reserved, 0,
sizeof(entry->objectInformation.Reserved));
-
- if (info->Name.Buffer)
- {
- entry->entryNameLength = info->Name.Length;
- StringCbCopyNW(entry->entryName, entryBufferLength,
info->Name.Buffer, info->Name.Length);
- entry->cb += entry->entryNameLength + sizeof(WCHAR);
- }
- else
- {
- entry->entryNameLength = 0;
- entry->entryName[0] = 0;
- entry->cb += sizeof(WCHAR);
- }
-
- if (otype < 0)
- {
- NtPidlTypeData * typedata = (NtPidlTypeData*) ((PBYTE) entry +
entry->cb);
- DWORD remainingSpace = entryBufferLength - ((PBYTE)
(typedata->typeName) - (PBYTE) entry);
-
- if (info->TypeName.Buffer)
- {
- typedata->typeNameLength = info->TypeName.Length;
- StringCbCopyNW(typedata->typeName, remainingSpace,
info->TypeName.Buffer, info->TypeName.Length);
-
- entry->cb += typedata->typeNameLength + sizeof(WCHAR);
- }
- else
- {
- typedata->typeNameLength = 0;
- typedata->typeName[0] = 0;
- entry->cb += typedata->typeNameLength + sizeof(WCHAR);
- }
- }
-
- if (otype == SYMBOLICLINK_OBJECT)
- {
- NtPidlSymlinkData * symlink = (NtPidlSymlinkData*) ((PBYTE) entry +
entry->cb);
- DWORD remainingSpace = entryBufferLength - ((PBYTE)
(symlink->targetName) - (PBYTE) entry);
-
- symlink->targetNameLength = link.Length;
- StringCbCopyNW(symlink->targetName, remainingSpace, link.Buffer,
link.Length);
-
- entry->cb += symlink->targetNameLength + sizeof(WCHAR);
- }
-
- DPA_AppendPtr(hdpa, entry);
- (*hdpaCount)++;
- }
- }
-
- NtClose(directory);
+ StringCbCatW(buffer, sizeof(buffer), entryName);
+
+ DbgPrint("GetNTObjectSymbolicLinkTarget %d\n", buffer);
+
+ LinkTarget->Length = 0;
+
+ DWORD err = NtOpenObject(SYMBOLICLINK_OBJECT, &handle, 0, buffer);
+ if (!NT_SUCCESS(err))
+ return HRESULT_FROM_NT(err);
+
+ err = NT_SUCCESS(NtQuerySymbolicLinkObject(handle, LinkTarget, NULL));
+ if (!NT_SUCCESS(err))
+ return HRESULT_FROM_NT(err);
+
+ NtClose(handle);
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);
- }
-
+class CEnumRegRoot :
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IEnumIDList
+{
+ UINT m_idx;
+
+public:
+ CEnumRegRoot()
+ : m_idx(0)
+ {
+ }
+
+ ~CEnumRegRoot()
+ {
+ }
+
+ HRESULT EnumerateNext(LPITEMIDLIST* ppidl)
+ {
+ if (m_idx >= _countof(RootKeys))
+ return S_FALSE;
+
+ RootKeyEntry& key = RootKeys[m_idx++];
+
+ PCWSTR name = key.keyName;
+ DWORD cchName = wcslen(name);
+
+ REG_ENTRY_TYPE otype = REG_ENTRY_ROOT;
+
+ DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry, entryName) + sizeof(WCHAR) +
cchName * sizeof(WCHAR);
+
+ // allocate space for the terminator
+ entryBufferLength += 2;
+
RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength);
if (!entry)
return E_OUTOFMEMORY;
memset(entry, 0, entryBufferLength);
- entry->cb = FIELD_OFFSET(NtPidlEntry,entryName);
+ entry->cb = FIELD_OFFSET(RegPidlEntry, entryName);
entry->magic = REGISTRY_PIDL_MAGIC;
entry->entryType = otype;
+ entry->rootKey = key.key;
if (cchName > 0)
{
@@ -325,6 +250,154 @@
entry->cb += sizeof(WCHAR);
}
+ *ppidl = (LPITEMIDLIST) entry;
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG
*pceltFetched)
+ {
+ if (pceltFetched)
+ *pceltFetched = 0;
+
+ while (celt-- > 0)
+ {
+ HRESULT hr = EnumerateNext(rgelt);
+ if (hr != S_OK)
+ return hr;
+
+ if (pceltFetched)
+ (*pceltFetched)++;
+ if (rgelt)
+ rgelt++;
+ }
+
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
+ {
+ while (celt > 0)
+ {
+ HRESULT hr = EnumerateNext(NULL);
+ if (FAILED(hr))
+ return hr;
+ if (hr != S_OK)
+ break;
+ }
+
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Reset()
+ {
+ return E_NOTIMPL;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Clone(IEnumIDList **ppenum)
+ {
+ return E_NOTIMPL;
+ }
+
+ DECLARE_NOT_AGGREGATABLE(CEnumRegRoot)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CEnumRegRoot)
+ COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
+ END_COM_MAP()
+
+};
+
+class CEnumRegKey :
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IEnumIDList
+{
+ PCWSTR m_path;
+ HKEY m_hkey;
+ BOOL m_values;
+ int m_idx;
+
+public:
+ CEnumRegKey()
+ : m_path(NULL), m_hkey(NULL), m_values(FALSE), m_idx(0)
+ {
+ }
+
+ ~CEnumRegKey()
+ {
+ RegCloseKey(m_hkey);
+ }
+
+ HRESULT Initialize(PCWSTR path, HKEY root)
+ {
+ m_path = path;
+
+ DWORD res;
+ if (root)
+ {
+ res = RegOpenKeyExW(root, *path == '\\' ? path + 1 : path, 0,
STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &m_hkey);
+ }
+ else
+ {
+ res = NtOpenObject(KEY_OBJECT, (PHANDLE) &m_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);
+ }
+
+ return S_OK;
+ }
+
+ HRESULT NextKey(LPITEMIDLIST* ppidl)
+ {
+ WCHAR name[MAX_PATH];
+ DWORD cchName = _countof(name);
+
+ WCHAR className[MAX_PATH];
+ DWORD cchClass = _countof(className);
+
+ if (RegEnumKeyExW(m_hkey, m_idx++, name, &cchName, 0, className,
&cchClass, NULL))
+ return S_FALSE;
+
+ 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);
+ }
+
+ // allocate space for the terminator
+ entryBufferLength += 2;
+
+ 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 (cchClass)
{
PWSTR contentData = (PWSTR) ((PBYTE) entry + entry->cb);
@@ -336,24 +409,23 @@
entry->cb += entry->contentsLength + sizeof(WCHAR);
}
- DPA_AppendPtr(hdpa, entry);
- (*hdpaCount)++;
-
- }
-
- for (int idx = 0;; ++idx)
+ *ppidl = (LPITEMIDLIST) entry;
+ return S_OK;
+ }
+
+ HRESULT NextValue(LPITEMIDLIST* ppidl)
{
WCHAR name[MAX_PATH];
DWORD cchName = _countof(name);
- DWORD type;
- DWORD dataSize;
-
- if (RegEnumValueW(hkey, idx, name, &cchName, 0, &type, NULL,
&dataSize))
- break;
+ DWORD type = 0;
+ DWORD dataSize = 0;
+
+ if (RegEnumValueW(m_hkey, m_idx++, name, &cchName, 0, &type, NULL,
&dataSize))
+ return S_FALSE;
REG_ENTRY_TYPE otype = REG_ENTRY_VALUE;
- DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry,entryName) + sizeof(WCHAR) +
cchName * sizeof(WCHAR);
+ DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry, entryName) + sizeof(WCHAR) +
cchName * sizeof(WCHAR);
BOOL copyData = dataSize < 32;
if (copyData)
@@ -362,8 +434,8 @@
otype = REG_ENTRY_VALUE_WITH_CONTENT;
}
-
- RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength);
+
+ RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength + 2);
if (!entry)
return E_OUTOFMEMORY;
@@ -396,7 +468,7 @@
// In case it's an unterminated string, RegGetValue will add the NULL
termination
dataSize += sizeof(WCHAR);
- if (!RegQueryValueExW(hkey, name, NULL, NULL, contentData, &dataSize))
+ if (!RegQueryValueExW(m_hkey, name, NULL, NULL, contentData, &dataSize))
{
entry->cb += entry->contentsLength + sizeof(WCHAR);
}
@@ -408,54 +480,168 @@
}
- DPA_AppendPtr(hdpa, entry);
- (*hdpaCount)++;
- }
-
- RegCloseKey(hkey);
-
- return S_OK;
-}
-
-HRESULT EnumerateRootKeys(HDPA hdpa, UINT * hdpaCount)
-{
- *hdpaCount = 0;
-
- static struct {
- HKEY key;
- PCWSTR keyName;
- } rootKeys [] = {
- { HKEY_CLASSES_ROOT, L"HKEY_CLASSES_ROOT" },
- { HKEY_CURRENT_USER, L"HKEY_CURRENT_USER" },
- { HKEY_LOCAL_MACHINE, L"HKEY_LOCAL_MACHINE" },
- { HKEY_USERS, L"HKEY_USERS" },
- { HKEY_CURRENT_CONFIG, L"HKEY_CURRENT_CONFIG" }
- };
-
- for (UINT i = 0; i < _countof(rootKeys); i++)
- {
- PCWSTR name = rootKeys[i].keyName;
- DWORD cchName = wcslen(rootKeys[i].keyName);
-
- REG_ENTRY_TYPE otype = REG_ENTRY_ROOT;
-
- DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry, entryName) + sizeof(WCHAR) +
cchName * sizeof(WCHAR);
-
- RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength);
+ *ppidl = (LPITEMIDLIST) entry;
+ return S_OK;
+ }
+
+ HRESULT EnumerateNext(LPITEMIDLIST* ppidl)
+ {
+ if (!m_values)
+ {
+ HRESULT hr = NextKey(ppidl);
+ if (hr != S_FALSE)
+ return hr;
+
+ // switch to values.
+ m_values = TRUE;
+ m_idx = 0;
+ }
+
+ return NextValue(ppidl);
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG
*pceltFetched)
+ {
+ if (pceltFetched)
+ *pceltFetched = 0;
+
+ while (celt-- > 0)
+ {
+ HRESULT hr = EnumerateNext(rgelt);
+ if (hr != S_OK)
+ return hr;
+
+ if (pceltFetched)
+ (*pceltFetched)++;
+ if (rgelt)
+ rgelt++;
+ }
+
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
+ {
+ while (celt > 0)
+ {
+ HRESULT hr = EnumerateNext(NULL);
+ if (FAILED(hr))
+ return hr;
+ if (hr != S_OK)
+ break;
+ }
+
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Reset()
+ {
+ return E_NOTIMPL;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Clone(IEnumIDList **ppenum)
+ {
+ return E_NOTIMPL;
+ }
+
+ DECLARE_NOT_AGGREGATABLE(CEnumRegKey)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CEnumRegKey)
+ COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
+ END_COM_MAP()
+};
+
+class CEnumNTDirectory :
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IEnumIDList
+{
+ WCHAR buffer[MAX_PATH];
+ HANDLE m_directory;
+ BOOL m_first;
+ ULONG m_enumContext;
+ PWSTR m_pend;
+
+public:
+ CEnumNTDirectory()
+ : m_directory(NULL), m_first(TRUE), m_enumContext(0), m_pend(NULL)
+ {
+ }
+
+ ~CEnumNTDirectory()
+ {
+ NtClose(m_directory);
+ }
+
+ HRESULT Initialize(PCWSTR path)
+ {
+ StringCbCopyExW(buffer, sizeof(buffer), path, &m_pend, NULL, 0);
+
+ DWORD err = NtOpenObject(DIRECTORY_OBJECT, &m_directory, FILE_LIST_DIRECTORY,
buffer);
+ if (!NT_SUCCESS(err))
+ {
+ ERR("NtOpenDirectoryObject failed for path %S with status=%x\n",
buffer, err);
+ return HRESULT_FROM_NT(err);
+ }
+
+ if (m_pend[-1] != '\\')
+ *m_pend++ = '\\';
+
+ return S_OK;
+ }
+
+ HRESULT EnumerateNext(LPITEMIDLIST* ppidl)
+ {
+ BYTE dirbuffer[2048];
+ if (!NT_SUCCESS(NtQueryDirectoryObject(m_directory, dirbuffer, 2048, TRUE,
m_first, &m_enumContext, NULL)))
+ return S_FALSE;
+
+ // if ppidl is NULL, assume the caller was Skip(),
+ // so we don't care about the info
+ if (!ppidl)
+ return S_OK;
+
+ m_first = FALSE;
+ POBJECT_DIRECTORY_INFORMATION info = (POBJECT_DIRECTORY_INFORMATION) dirbuffer;
+
+ if (info->Name.Buffer)
+ {
+ StringCbCopyNW(m_pend, sizeof(buffer), info->Name.Buffer,
info->Name.Length);
+ }
+
+ OBJECT_TYPE otype = MapTypeNameToType(info->TypeName.Buffer,
info->TypeName.Length);
+
+ DWORD entryBufferLength = FIELD_OFFSET(NtPidlEntry, entryName) + sizeof(WCHAR);
+ if (info->Name.Buffer)
+ entryBufferLength += info->Name.Length;
+
+ if (otype < 0)
+ {
+ entryBufferLength += FIELD_OFFSET(NtPidlTypeData, typeName) + sizeof(WCHAR);
+
+ if (info->TypeName.Buffer)
+ {
+ entryBufferLength += info->TypeName.Length;
+ }
+ }
+
+ // allocate space for the terminator
+ entryBufferLength += 2;
+
+ NtPidlEntry* entry = (NtPidlEntry*) 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;
- entry->rootKey = rootKeys[i].key;
-
- if (cchName > 0)
- {
- entry->entryNameLength = cchName * sizeof(WCHAR);
- StringCbCopyNW(entry->entryName, entryBufferLength, name,
entry->entryNameLength);
+ entry->magic = NT_OBJECT_PIDL_MAGIC;
+ entry->objectType = otype;
+
+ if (info->Name.Buffer)
+ {
+ entry->entryNameLength = info->Name.Length;
+ StringCbCopyNW(entry->entryName, entryBufferLength, info->Name.Buffer,
info->Name.Length);
entry->cb += entry->entryNameLength + sizeof(WCHAR);
}
else
@@ -464,58 +650,95 @@
entry->entryName[0] = 0;
entry->cb += sizeof(WCHAR);
}
-
- DPA_AppendPtr(hdpa, entry);
- (*hdpaCount)++;
-
- }
-
- return S_OK;
+
+ if (otype < 0)
+ {
+ NtPidlTypeData * typedata = (NtPidlTypeData*) ((PBYTE) entry +
entry->cb);
+ DWORD remainingSpace = entryBufferLength - ((PBYTE) (typedata->typeName) -
(PBYTE) entry);
+
+ if (info->TypeName.Buffer)
+ {
+ typedata->typeNameLength = info->TypeName.Length;
+ StringCbCopyNW(typedata->typeName, remainingSpace,
info->TypeName.Buffer, info->TypeName.Length);
+
+ entry->cb += typedata->typeNameLength + sizeof(WCHAR);
+ }
+ else
+ {
+ typedata->typeNameLength = 0;
+ typedata->typeName[0] = 0;
+ entry->cb += typedata->typeNameLength + sizeof(WCHAR);
+ }
+ }
+
+ *ppidl = (LPITEMIDLIST) entry;
+
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG
*pceltFetched)
+ {
+ if (pceltFetched)
+ *pceltFetched = 0;
+
+ while (celt-- > 0)
+ {
+ HRESULT hr = EnumerateNext(rgelt);
+ if (hr != S_OK)
+ return hr;
+
+ if (pceltFetched)
+ (*pceltFetched)++;
+ if (rgelt)
+ rgelt++;
+ }
+
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
+ {
+ while (celt > 0)
+ {
+ HRESULT hr = EnumerateNext(NULL);
+ if (FAILED(hr))
+ return hr;
+ if (hr != S_OK)
+ break;
+ }
+
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Reset()
+ {
+ return E_NOTIMPL;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE Clone(IEnumIDList **ppenum)
+ {
+ return E_NOTIMPL;
+ }
+
+ DECLARE_NOT_AGGREGATABLE(CEnumNTDirectory)
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+ BEGIN_COM_MAP(CEnumNTDirectory)
+ COM_INTERFACE_ENTRY_IID(IID_IEnumIDList, IEnumIDList)
+ END_COM_MAP()
+};
+
+HRESULT GetEnumRegistryRoot(IEnumIDList ** ppil)
+{
+ return ShellObjectCreator<CEnumRegRoot>(IID_PPV_ARG(IEnumIDList, ppil));
}
-HRESULT ReadRegistryValue(HKEY root, PCWSTR path, PCWSTR valueName, PVOID * valueData,
PDWORD valueLength)
-{
- HKEY hkey;
-
- DWORD res;
- if (root)
- {
- res = RegOpenKeyExW(root, *path == '\\' ? path + 1 : path, 0,
STANDARD_RIGHTS_READ | KEY_QUERY_VALUE, &hkey);
- }
- else
- {
- res = NtOpenObject(KEY_OBJECT, (PHANDLE) &hkey, STANDARD_RIGHTS_READ |
KEY_QUERY_VALUE, path);
- }
- if (!NT_SUCCESS(res))
- {
- ERR("RegOpenKeyExW failed for path %S with status=%x\n", path, res);
- return HRESULT_FROM_NT(res);
- }
-
- res = RegQueryValueExW(hkey, valueName, NULL, NULL, NULL, valueLength);
-
- if (*valueLength > 0)
- {
- *valueData = (PBYTE) CoTaskMemAlloc(*valueLength);
-
- res = RegQueryValueExW(hkey, valueName, NULL, NULL, (PBYTE) *valueData,
valueLength);
- if (!NT_SUCCESS(res))
- {
- CoTaskMemFree(*valueData);
- *valueData = NULL;
-
- RegCloseKey(hkey);
-
- ERR("RegOpenKeyExW failed for path %S with status=%x\n", path,
res);
- return HRESULT_FROM_NT(res);
- }
- }
- else
- {
- *valueData = NULL;
- }
-
- RegCloseKey(hkey);
-
- return S_OK;
+HRESULT GetEnumRegistryKey(LPCWSTR path, HKEY root, IEnumIDList ** ppil)
+{
+ return ShellObjectCreatorInit<CEnumRegKey>(path, root, IID_PPV_ARG(IEnumIDList,
ppil));
+}
+
+HRESULT GetEnumNTDirectory(LPCWSTR path, IEnumIDList ** ppil)
+{
+ return ShellObjectCreatorInit<CEnumNTDirectory>(path, IID_PPV_ARG(IEnumIDList,
ppil));
}
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] Fri Aug 21 14:26:25
2015
@@ -50,23 +50,14 @@
// If this is -1, there will be a NtPidlTypeData following this, and before any other
extensions
OBJECT_TYPE objectType;
- OBJECT_BASIC_INFORMATION objectInformation;
-
USHORT entryNameLength;
WCHAR entryName[ANYSIZE_ARRAY];
-
};
struct NtPidlTypeData
{
USHORT typeNameLength;
WCHAR typeName[ANYSIZE_ARRAY];
-};
-
-struct NtPidlSymlinkData
-{
- USHORT targetNameLength;
- WCHAR targetName[ANYSIZE_ARRAY];
};
// REGISTRY browser
@@ -107,8 +98,10 @@
#include <poppack.h>
-HRESULT EnumerateNtDirectory(HDPA hdpa, PCWSTR path, UINT * hdpaCount);
-HRESULT EnumerateRegistryKey(HDPA hdpa, PCWSTR path, HKEY root, UINT * hdpaCount);
-HRESULT EnumerateRootKeys(HDPA hdpa, UINT * hdpaCount);
+HRESULT ReadRegistryValue(HKEY root, PCWSTR path, PCWSTR valueName, PVOID * valueData,
PDWORD valueLength);
-HRESULT ReadRegistryValue(HKEY root, PCWSTR path, PCWSTR valueName, PVOID * valueData,
PDWORD valueLength);
+HRESULT GetEnumRegistryRoot(IEnumIDList ** ppil);
+HRESULT GetEnumRegistryKey(LPCWSTR path, HKEY root, IEnumIDList ** ppil);
+HRESULT GetEnumNTDirectory(LPCWSTR path, IEnumIDList ** ppil);
+
+HRESULT GetNTObjectSymbolicLinkTarget(LPCWSTR path, LPCWSTR entryName, PUNICODE_STRING
LinkTarget);
Modified: trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/shellext/ntobjshex/reg…
==============================================================================
--- trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/shellext/ntobjshex/regfolder.cpp [iso-8859-1] Fri Aug 21 14:26:25
2015
@@ -23,6 +23,7 @@
#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 } };
@@ -130,9 +131,6 @@
PWSTR m_ntPath;
HKEY m_hRoot;
- HDPA m_hDpa;
- UINT m_hDpaCount;
-
int DpaDeleteCallback(RegPidlEntry * info)
{
CoTaskMemFree(info);
@@ -149,186 +147,20 @@
public:
CRegistryPidlManager() :
m_ntPath(NULL),
- m_hRoot(NULL),
- m_hDpa(NULL),
- m_hDpaCount(0)
+ m_hRoot(NULL)
{
}
~CRegistryPidlManager()
{
- DPA_DestroyCallback(m_hDpa, s_DpaDeleteCallback, this);
}
HRESULT Initialize(PWSTR ntPath, HKEY hRoot)
{
m_ntPath = ntPath;
m_hRoot = hRoot;
- m_hDpa = NULL;
-
- return S_OK;
- }
-
- HRESULT Enumerate()
- {
- if (m_hDpa)
- return S_OK;
-
- 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, const RegPidlEntry ** pinfo)
- {
- HRESULT hr;
-
- if (!m_hDpa)
- {
- hr = Enumerate();
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- if (!m_hDpa)
- return E_FAIL;
- }
-
- const RegPidlEntry * info = (const 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 { name='%S' } in a list of %d
items\n", info->entryName, m_hDpaCount);
-
- for (UINT i = 0; i < m_hDpaCount; i++)
- {
- const RegPidlEntry * pInfo = (const RegPidlEntry *) DPA_GetPtr(m_hDpa, i);
- ASSERT(pInfo);
-
- hr = CompareIDs(SHCIDS_CANONICALONLY, pInfo, info);
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- if (hr == S_OK)
- {
- *pinfo = pInfo;
- return S_OK;
- }
- else
- {
- TRACE("Comparison returned %d for '%S'\n", (int)
(short) (hr & 0xFFFF), pInfo->entryName);
- }
- }
-
- ERR("PIDL NOT FOUND: Requested filename: %S\n", info->entryName);
- *pinfo = NULL;
-
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
-
- HRESULT FindByName(LPCWSTR strParsingName, RegPidlEntry ** pinfo)
- {
- HRESULT hr;
-
- if (!m_hDpa)
- {
- hr = Enumerate();
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- 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)
- {
- if (!m_hDpa)
- {
- HRESULT hr = Enumerate();
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- if (!m_hDpa)
- return E_FAIL;
- }
-
- *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)
- {
- if (!m_hDpa)
- {
- HRESULT hr = Enumerate();
- if (FAILED_UNEXPECTEDLY(hr))
- return hr;
-
- if (!m_hDpa)
- return E_FAIL;
- }
-
- *count = m_hDpaCount;
- return S_OK;
- }
-
-
- static LPITEMIDLIST CreatePidlFromItem(const 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;
+
+ return S_OK;
}
static HRESULT CompareIDs(LPARAM lParam, const RegPidlEntry * first, const
RegPidlEntry * second)
@@ -460,13 +292,32 @@
BOOL IsFolder(LPCITEMIDLIST pcidl)
{
- const RegPidlEntry * entry;
- HRESULT hr = FindPidlInList(pcidl, &entry);
- if (FAILED_UNEXPECTEDLY(hr))
+ RegPidlEntry * entry = (RegPidlEntry*) &(pcidl->mkid);
+ if ((entry->cb < sizeof(RegPidlEntry)) || (entry->magic !=
REGISTRY_PIDL_MAGIC))
return FALSE;
return (entry->entryType == REG_ENTRY_KEY) ||
(entry->entryType == REG_ENTRY_ROOT);
+ }
+
+ HRESULT 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;
}
static HRESULT FormatValueData(DWORD contentType, PVOID td, DWORD contentsLength,
PCWSTR * strContents)
@@ -572,121 +423,6 @@
*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()
-
};
//-----------------------------------------------------------------------------
@@ -715,8 +451,6 @@
LPITEMIDLIST *ppidl,
ULONG *pdwAttributes)
{
- RegPidlEntry * info;
-
if (!ppidl)
return E_POINTER;
@@ -728,19 +462,45 @@
TRACE("CRegistryFolder::ParseDisplayName name=%S (ntPath=%S)\n",
lpszDisplayName, m_NtPath);
- HRESULT hr = m_PidlManager->FindByName(lpszDisplayName, &info);
+ const RegPidlEntry * info;
+ IEnumIDList * it;
+ HRESULT hr = GetEnumNTDirectory(m_NtPath, &it);
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);
+ while (TRUE)
+ {
+ hr = it->Next(1, ppidl, NULL);
+
+ if (FAILED(hr))
+ return hr;
+
+ if (hr != S_OK)
+ break;
+
+ hr = m_PidlManager->GetInfoFromPidl(*ppidl, &info);
+ if (FAILED_UNEXPECTEDLY(hr))
+ return hr;
+
+ if (StrCmpW(info->entryName, lpszDisplayName) == 0)
+ break;
+ }
+
+ if (hr != S_OK)
+ {
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ }
+
+ if (pchEaten || pdwAttributes)
+ {
+ if (pchEaten)
+ *pchEaten = wcslen(info->entryName);
+
+ if (pdwAttributes)
+ *pdwAttributes = m_PidlManager->ConvertAttributes(info, pdwAttributes);
+ }
return S_OK;
}
@@ -750,7 +510,14 @@
SHCONTF grfFlags,
IEnumIDList **ppenumIDList)
{
- return ShellObjectCreatorInit<CRegistryFolderEnum>(this, hwndOwner, grfFlags,
IID_PPV_ARG(IEnumIDList, ppenumIDList));
+ if (wcslen(m_NtPath) == 0 && m_hRoot == NULL)
+ {
+ return GetEnumRegistryRoot(ppenumIDList);
+ }
+ else
+ {
+ return GetEnumRegistryKey(m_NtPath, m_hRoot, ppenumIDList);
+ }
}
HRESULT STDMETHODCALLTYPE CRegistryFolder::BindToObject(
@@ -763,7 +530,7 @@
if (IsEqualIID(riid, IID_IShellFolder))
{
- HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+ HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@@ -886,7 +653,7 @@
{
PCUITEMID_CHILD pidl = apidl[i];
- HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+ HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@@ -913,12 +680,15 @@
{
CComPtr<IContextMenu> pcm;
- HKEY keys [1];
+ DWORD res;
+ HKEY keys[1];
int nkeys = _countof(keys);
if (cidl == 1 && m_PidlManager->IsFolder(apidl[0]))
{
- RegOpenKey(HKEY_CLASSES_ROOT, L"Folder", keys + 0);
+ res = RegOpenKey(HKEY_CLASSES_ROOT, L"Folder", keys + 0);
+ if (!NT_SUCCESS(res))
+ return HRESULT_FROM_NT(res);
}
else
{
@@ -971,7 +741,7 @@
TRACE("GetDisplayNameOf %p\n", pidl);
- HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+ HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@@ -1144,7 +914,7 @@
if (pidl)
{
- HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+ HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@@ -1170,7 +940,7 @@
{
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);
}
@@ -1217,7 +987,7 @@
if (pidl)
{
- HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
+ HRESULT hr = m_PidlManager->GetInfoFromPidl(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr))
return hr;
@@ -1343,8 +1113,6 @@
return S_FALSE;
case SFVM_BACKGROUNDENUM:
return S_OK;
- case SFVM_DEFITEMCOUNT:
- return m_PidlManager->GetCount((UINT*) lParam);
}
return E_NOTIMPL;
}