[NTOBJSHEX]

* Fix comparison length: StrCmpNW takes chars, not bytes.
* While at it, make canonical comparisons use memcmp instead of string comparison, as we only care about equality, not ordering.
Better fix for CORE-9432

svn path=/trunk/; revision=67181
This commit is contained in:
David Quintana 2015-04-12 19:00:26 +00:00
parent 6abe431f5a
commit 5dee29daa3
3 changed files with 66 additions and 109 deletions

View file

@ -213,21 +213,21 @@ public:
return E_FAIL; return E_FAIL;
} }
NtPidlEntry * info = (NtPidlEntry *) pcidl; const NtPidlEntry * info = (const NtPidlEntry *) pcidl;
if ((info->cb < sizeof(NtPidlEntry)) || (info->magic != NT_OBJECT_PIDL_MAGIC)) if ((info->cb < sizeof(NtPidlEntry)) || (info->magic != NT_OBJECT_PIDL_MAGIC))
{ {
ERR("FindPidlInList: Requested pidl is not of the correct type.\n"); ERR("FindPidlInList: Requested pidl is not of the correct type.\n");
return E_INVALIDARG; return E_INVALIDARG;
} }
TRACE("Searching for pidl { cb=%d } in a list of %d items\n", pcidl->mkid.cb, m_hDpaCount); 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++) for (UINT i = 0; i < m_hDpaCount; i++)
{ {
NtPidlEntry * pInfo = (NtPidlEntry *) DPA_GetPtr(m_hDpa, i); const NtPidlEntry * pInfo = (const NtPidlEntry *) DPA_GetPtr(m_hDpa, i);
ASSERT(pInfo); ASSERT(pInfo);
hr = CompareIDs(0, pInfo, pcidl); hr = CompareIDs(SHCIDS_CANONICALONLY, pInfo, info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -238,11 +238,13 @@ public:
} }
else else
{ {
TRACE("Comparison returned %d\n", (int) (short) (hr & 0xFFFF)); TRACE("Comparison returned %d for '%S'\n", (int) (short) (hr & 0xFFFF), pInfo->entryName);
} }
} }
ERR("PIDL NOT FOUND: Requested filename: %S\n", info->entryName); ERR("PIDL NOT FOUND: Requested filename: %S\n", info->entryName);
*pinfo = NULL;
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
} }
@ -284,11 +286,9 @@ public:
HRESULT GetPidl(UINT index, NtPidlEntry ** pEntry) HRESULT GetPidl(UINT index, NtPidlEntry ** pEntry)
{ {
HRESULT hr;
if (!m_hDpa) if (!m_hDpa)
{ {
hr = Enumerate(); HRESULT hr = Enumerate();
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -310,11 +310,9 @@ public:
HRESULT GetCount(UINT * count) HRESULT GetCount(UINT * count)
{ {
HRESULT hr;
if (!m_hDpa) if (!m_hDpa)
{ {
hr = Enumerate(); HRESULT hr = Enumerate();
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -377,23 +375,33 @@ public:
return MAKE_HRESULT(0, 0, (USHORT) 1); return MAKE_HRESULT(0, 0, (USHORT) 1);
if (second->entryNameLength < first->entryNameLength) if (second->entryNameLength < first->entryNameLength)
return MAKE_HRESULT(0, 0, (USHORT) -1); return MAKE_HRESULT(0, 0, (USHORT) -1);
int minlength = min(first->entryNameLength, second->entryNameLength);
if (minlength > 0)
{
int ord = memcmp(first->entryName, second->entryName, minlength);
if (ord != 0)
return MAKE_HRESULT(0, 0, (USHORT) ord);
}
return S_OK;
} }
else
int minlength = min(first->entryNameLength, second->entryNameLength);
int ord = StrCmpNW(first->entryName, second->entryName, minlength);
if (ord != 0)
return MAKE_HRESULT(0, 0, (USHORT) ord);
if (!canonical)
{ {
int minlength = min(first->entryNameLength, second->entryNameLength);
if (minlength > 0)
{
int ord = StrCmpNW(first->entryName, second->entryName, minlength / sizeof(WCHAR));
if (ord != 0)
return MAKE_HRESULT(0, 0, (USHORT) ord);
}
if (second->entryNameLength > first->entryNameLength) if (second->entryNameLength > first->entryNameLength)
return MAKE_HRESULT(0, 0, (USHORT) 1); return MAKE_HRESULT(0, 0, (USHORT) 1);
if (second->entryNameLength < first->entryNameLength) if (second->entryNameLength < first->entryNameLength)
return MAKE_HRESULT(0, 0, (USHORT) -1); return MAKE_HRESULT(0, 0, (USHORT) -1);
}
return S_OK; return S_OK;
}
} }
case NTOBJECT_COLUMN_TYPE: case NTOBJECT_COLUMN_TYPE:
{ {
@ -623,7 +631,6 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::ParseDisplayName(
LPITEMIDLIST *ppidl, LPITEMIDLIST *ppidl,
ULONG *pdwAttributes) ULONG *pdwAttributes)
{ {
HRESULT hr;
NtPidlEntry * info; NtPidlEntry * info;
if (!ppidl) if (!ppidl)
@ -637,7 +644,7 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::ParseDisplayName(
TRACE("CNtObjectFolder::ParseDisplayName name=%S (ntPath=%S)\n", lpszDisplayName, m_NtPath); TRACE("CNtObjectFolder::ParseDisplayName name=%S (ntPath=%S)\n", lpszDisplayName, m_NtPath);
hr = m_PidlManager->FindByName(lpszDisplayName, &info); HRESULT hr = m_PidlManager->FindByName(lpszDisplayName, &info);
if (FAILED(hr)) if (FAILED(hr))
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
@ -669,11 +676,10 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::BindToObject(
void **ppvOut) void **ppvOut)
{ {
const NtPidlEntry * info; const NtPidlEntry * info;
HRESULT hr;
if (IsEqualIID(riid, IID_IShellFolder)) if (IsEqualIID(riid, IID_IShellFolder))
{ {
hr = m_PidlManager->FindPidlInList(pidl, &info); HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -830,15 +836,9 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetAttributesOf(
{ {
PCUITEMID_CHILD pidl = apidl[i]; PCUITEMID_CHILD pidl = apidl[i];
#ifndef DISABLE_STRICT_PIDL_CHECK
HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info); HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
#else
info = (const NtPidlEntry *) pidl;
if (info->magic != NT_OBJECT_PIDL_MAGIC)
return E_INVALIDARG;
#endif
// Update attributes. // Update attributes.
*rgfInOut = m_PidlManager->ConvertAttributes(info, rgfInOut); *rgfInOut = m_PidlManager->ConvertAttributes(info, rgfInOut);
@ -918,19 +918,12 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDisplayNameOf(
STRRET *lpName) STRRET *lpName)
{ {
const NtPidlEntry * info; const NtPidlEntry * info;
HRESULT hr;
TRACE("GetDisplayNameOf %p\n", pidl); TRACE("GetDisplayNameOf %p\n", pidl);
#ifndef DISABLE_STRICT_PIDL_CHECK HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
hr = m_PidlManager->FindPidlInList(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
#else
info = (const NtPidlEntry *) pidl;
if (info->magic != NT_OBJECT_PIDL_MAGIC)
return E_INVALIDARG;
#endif
if ((GET_SHGDN_RELATION(uFlags) == SHGDN_NORMAL) && if ((GET_SHGDN_RELATION(uFlags) == SHGDN_NORMAL) &&
(GET_SHGDN_FOR(uFlags) & SHGDN_FORPARSING)) (GET_SHGDN_FOR(uFlags) & SHGDN_FORPARSING))
@ -1102,15 +1095,9 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsEx(
if (pidl) if (pidl)
{ {
#ifndef DISABLE_STRICT_PIDL_CHECK
HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info); HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
#else
info = (const NtPidlEntry *) pidl;
if (info->magic != NT_OBJECT_PIDL_MAGIC)
return E_INVALIDARG;
#endif
static const GUID storage = PSGUID_STORAGE; static const GUID storage = PSGUID_STORAGE;
if (IsEqualGUID(pscid->fmtid, storage)) if (IsEqualGUID(pscid->fmtid, storage))
@ -1185,15 +1172,9 @@ HRESULT STDMETHODCALLTYPE CNtObjectFolder::GetDetailsOf(
if (pidl) if (pidl)
{ {
#ifndef DISABLE_STRICT_PIDL_CHECK
HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info); HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
#else
info = (const NtPidlEntry *) pidl;
if (info->magic != NT_OBJECT_PIDL_MAGIC)
return E_INVALIDARG;
#endif
switch (iColumn) switch (iColumn)
{ {

View file

@ -48,6 +48,3 @@ DEFINE_GUID(CLSID_NtObjectFolder,
#include "ntobjns.h" #include "ntobjns.h"
#include "regfolder.h" #include "regfolder.h"
// Workaround for missing entries
#define DISABLE_STRICT_PIDL_CHECKS

View file

@ -208,21 +208,21 @@ public:
return E_FAIL; return E_FAIL;
} }
RegPidlEntry * info = (RegPidlEntry *) pcidl; const RegPidlEntry * info = (const RegPidlEntry *) pcidl;
if ((info->cb < sizeof(RegPidlEntry)) || (info->magic != REGISTRY_PIDL_MAGIC)) if ((info->cb < sizeof(RegPidlEntry)) || (info->magic != REGISTRY_PIDL_MAGIC))
{ {
ERR("FindPidlInList: Requested pidl is not of the correct type.\n"); ERR("FindPidlInList: Requested pidl is not of the correct type.\n");
return E_INVALIDARG; return E_INVALIDARG;
} }
TRACE("Searching for pidl { cb=%d } in a list of %d items\n", pcidl->mkid.cb, m_hDpaCount); 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++) for (UINT i = 0; i < m_hDpaCount; i++)
{ {
RegPidlEntry * pInfo = (RegPidlEntry *) DPA_GetPtr(m_hDpa, i); const RegPidlEntry * pInfo = (const RegPidlEntry *) DPA_GetPtr(m_hDpa, i);
ASSERT(pInfo); ASSERT(pInfo);
hr = CompareIDs(0, pInfo, pcidl); hr = CompareIDs(SHCIDS_CANONICALONLY, pInfo, info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -233,11 +233,13 @@ public:
} }
else else
{ {
TRACE("Comparison returned %d\n", (int) (short) (hr & 0xFFFF)); TRACE("Comparison returned %d for '%S'\n", (int) (short) (hr & 0xFFFF), pInfo->entryName);
} }
} }
ERR("PIDL NOT FOUND: Requested filename: %S\n", info->entryName); ERR("PIDL NOT FOUND: Requested filename: %S\n", info->entryName);
*pinfo = NULL;
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
} }
@ -280,11 +282,9 @@ public:
HRESULT GetPidl(UINT index, RegPidlEntry ** pEntry) HRESULT GetPidl(UINT index, RegPidlEntry ** pEntry)
{ {
HRESULT hr;
if (!m_hDpa) if (!m_hDpa)
{ {
hr = Enumerate(); HRESULT hr = Enumerate();
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -306,11 +306,9 @@ public:
HRESULT GetCount(UINT * count) HRESULT GetCount(UINT * count)
{ {
HRESULT hr;
if (!m_hDpa) if (!m_hDpa)
{ {
hr = Enumerate(); HRESULT hr = Enumerate();
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -374,23 +372,33 @@ public:
return MAKE_HRESULT(0, 0, (USHORT) 1); return MAKE_HRESULT(0, 0, (USHORT) 1);
if (second->entryNameLength < first->entryNameLength) if (second->entryNameLength < first->entryNameLength)
return MAKE_HRESULT(0, 0, (USHORT) -1); return MAKE_HRESULT(0, 0, (USHORT) -1);
int minlength = min(first->entryNameLength, second->entryNameLength);
if (minlength > 0)
{
int ord = memcmp(first->entryName, second->entryName, minlength);
if (ord != 0)
return MAKE_HRESULT(0, 0, (USHORT) ord);
}
return S_OK;
} }
else
int minlength = min(first->entryNameLength, second->entryNameLength);
int ord = StrCmpNW(first->entryName, second->entryName, minlength);
if (ord != 0)
return MAKE_HRESULT(0, 0, (USHORT) ord);
if (!canonical)
{ {
int minlength = min(first->entryNameLength, second->entryNameLength);
if (minlength > 0)
{
int ord = StrCmpNW(first->entryName, second->entryName, minlength / sizeof(WCHAR));
if (ord != 0)
return MAKE_HRESULT(0, 0, (USHORT) ord);
}
if (second->entryNameLength > first->entryNameLength) if (second->entryNameLength > first->entryNameLength)
return MAKE_HRESULT(0, 0, (USHORT) 1); return MAKE_HRESULT(0, 0, (USHORT) 1);
if (second->entryNameLength < first->entryNameLength) if (second->entryNameLength < first->entryNameLength)
return MAKE_HRESULT(0, 0, (USHORT) -1); return MAKE_HRESULT(0, 0, (USHORT) -1);
}
return S_OK; return S_OK;
}
} }
case REGISTRY_COLUMN_TYPE: case REGISTRY_COLUMN_TYPE:
{ {
@ -707,7 +715,6 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::ParseDisplayName(
LPITEMIDLIST *ppidl, LPITEMIDLIST *ppidl,
ULONG *pdwAttributes) ULONG *pdwAttributes)
{ {
HRESULT hr;
RegPidlEntry * info; RegPidlEntry * info;
if (!ppidl) if (!ppidl)
@ -721,7 +728,7 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::ParseDisplayName(
TRACE("CRegistryFolder::ParseDisplayName name=%S (ntPath=%S)\n", lpszDisplayName, m_NtPath); TRACE("CRegistryFolder::ParseDisplayName name=%S (ntPath=%S)\n", lpszDisplayName, m_NtPath);
hr = m_PidlManager->FindByName(lpszDisplayName, &info); HRESULT hr = m_PidlManager->FindByName(lpszDisplayName, &info);
if (FAILED(hr)) if (FAILED(hr))
{ {
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
@ -753,11 +760,10 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::BindToObject(
void **ppvOut) void **ppvOut)
{ {
const RegPidlEntry * info; const RegPidlEntry * info;
HRESULT hr;
if (IsEqualIID(riid, IID_IShellFolder)) if (IsEqualIID(riid, IID_IShellFolder))
{ {
hr = m_PidlManager->FindPidlInList(pidl, &info); HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
@ -880,15 +886,9 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetAttributesOf(
{ {
PCUITEMID_CHILD pidl = apidl[i]; PCUITEMID_CHILD pidl = apidl[i];
#ifndef DISABLE_STRICT_PIDL_CHECK
HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info); HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
#else
info = (const RegPidlEntry *) pidl;
if (info->magic != REGISTRY_PIDL_MAGIC)
return E_INVALIDARG;
#endif
// Update attributes. // Update attributes.
*rgfInOut = m_PidlManager->ConvertAttributes(info, rgfInOut); *rgfInOut = m_PidlManager->ConvertAttributes(info, rgfInOut);
@ -968,19 +968,12 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDisplayNameOf(
STRRET *lpName) STRRET *lpName)
{ {
const RegPidlEntry * info; const RegPidlEntry * info;
HRESULT hr;
TRACE("GetDisplayNameOf %p\n", pidl); TRACE("GetDisplayNameOf %p\n", pidl);
#ifndef DISABLE_STRICT_PIDL_CHECK HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
hr = m_PidlManager->FindPidlInList(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
#else
info = (const RegPidlEntry *) pidl;
if (info->magic != REGISTRY_PIDL_MAGIC)
return E_INVALIDARG;
#endif
if ((GET_SHGDN_RELATION(uFlags) == SHGDN_NORMAL) && if ((GET_SHGDN_RELATION(uFlags) == SHGDN_NORMAL) &&
(GET_SHGDN_FOR(uFlags) & SHGDN_FORPARSING)) (GET_SHGDN_FOR(uFlags) & SHGDN_FORPARSING))
@ -1146,21 +1139,14 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsEx(
VARIANT *pv) VARIANT *pv)
{ {
const RegPidlEntry * info; const RegPidlEntry * info;
HRESULT hr;
TRACE("GetDetailsEx\n"); TRACE("GetDetailsEx\n");
if (pidl) if (pidl)
{ {
#ifndef DISABLE_STRICT_PIDL_CHECK HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
hr = m_PidlManager->FindPidlInList(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
#else
info = (const RegPidlEntry *) pidl;
if (info->magic != REGISTRY_PIDL_MAGIC)
return E_INVALIDARG;
#endif
static const GUID storage = PSGUID_STORAGE; static const GUID storage = PSGUID_STORAGE;
if (IsEqualGUID(pscid->fmtid, storage)) if (IsEqualGUID(pscid->fmtid, storage))
@ -1226,21 +1212,14 @@ HRESULT STDMETHODCALLTYPE CRegistryFolder::GetDetailsOf(
SHELLDETAILS *psd) SHELLDETAILS *psd)
{ {
const RegPidlEntry * info; const RegPidlEntry * info;
HRESULT hr;
TRACE("GetDetailsOf\n"); TRACE("GetDetailsOf\n");
if (pidl) if (pidl)
{ {
#ifndef DISABLE_STRICT_PIDL_CHECK HRESULT hr = m_PidlManager->FindPidlInList(pidl, &info);
hr = m_PidlManager->FindPidlInList(pidl, &info);
if (FAILED_UNEXPECTEDLY(hr)) if (FAILED_UNEXPECTEDLY(hr))
return hr; return hr;
#else
info = (const RegPidlEntry *) pidl;
if (info->magic != REGISTRY_PIDL_MAGIC)
return E_INVALIDARG;
#endif
switch (iColumn) switch (iColumn)
{ {