mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
[NTOBJSHEX]
* Fix leak of the PIDL and PIDL Manager from the shell folder destructors. * Switch PIDL Manager to a lazy enumeration so it won't lookup the folder contents unless/until they are needed. svn path=/trunk/; revision=66745
This commit is contained in:
parent
287b968fc1
commit
be7e5a84eb
2 changed files with 112 additions and 17 deletions
|
@ -177,6 +177,15 @@ public:
|
||||||
HRESULT Initialize(PWSTR ntPath)
|
HRESULT Initialize(PWSTR ntPath)
|
||||||
{
|
{
|
||||||
m_ntPath = ntPath;
|
m_ntPath = ntPath;
|
||||||
|
m_hDpa = NULL;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT Enumerate()
|
||||||
|
{
|
||||||
|
if (m_hDpa)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
m_hDpa = DPA_Create(10);
|
m_hDpa = DPA_Create(10);
|
||||||
|
|
||||||
|
@ -196,7 +205,12 @@ public:
|
||||||
|
|
||||||
if (!m_hDpa)
|
if (!m_hDpa)
|
||||||
{
|
{
|
||||||
return E_FAIL;
|
hr = Enumerate();
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (!m_hDpa)
|
||||||
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NtPidlEntry * info = (NtPidlEntry *) pcidl;
|
NtPidlEntry * info = (NtPidlEntry *) pcidl;
|
||||||
|
@ -234,9 +248,16 @@ public:
|
||||||
|
|
||||||
HRESULT FindByName(LPCWSTR strParsingName, NtPidlEntry ** pinfo)
|
HRESULT FindByName(LPCWSTR strParsingName, NtPidlEntry ** pinfo)
|
||||||
{
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
if (!m_hDpa)
|
if (!m_hDpa)
|
||||||
{
|
{
|
||||||
return E_FAIL;
|
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);
|
TRACE("Searching for '%S' in a list of %d items\n", strParsingName, m_hDpaCount);
|
||||||
|
@ -263,6 +284,18 @@ public:
|
||||||
|
|
||||||
HRESULT GetPidl(UINT index, NtPidlEntry ** pEntry)
|
HRESULT GetPidl(UINT index, NtPidlEntry ** pEntry)
|
||||||
{
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!m_hDpa)
|
||||||
|
{
|
||||||
|
hr = Enumerate();
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (!m_hDpa)
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
*pEntry = NULL;
|
*pEntry = NULL;
|
||||||
|
|
||||||
NtPidlEntry * entry = (NtPidlEntry *) DPA_GetPtr(m_hDpa, index);
|
NtPidlEntry * entry = (NtPidlEntry *) DPA_GetPtr(m_hDpa, index);
|
||||||
|
@ -277,11 +310,22 @@ public:
|
||||||
|
|
||||||
HRESULT GetCount(UINT * count)
|
HRESULT GetCount(UINT * count)
|
||||||
{
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!m_hDpa)
|
||||||
|
{
|
||||||
|
hr = Enumerate();
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (!m_hDpa)
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
*count = m_hDpaCount;
|
*count = m_hDpaCount;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static LPITEMIDLIST CreatePidlFromItem(NtPidlEntry * entry)
|
static LPITEMIDLIST CreatePidlFromItem(NtPidlEntry * entry)
|
||||||
{
|
{
|
||||||
LPITEMIDLIST idl = (LPITEMIDLIST) CoTaskMemAlloc(entry->cb + 2);
|
LPITEMIDLIST idl = (LPITEMIDLIST) CoTaskMemAlloc(entry->cb + 2);
|
||||||
|
@ -292,7 +336,7 @@ public:
|
||||||
return idl;
|
return idl;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CompareIDs(LPARAM lParam, NtPidlEntry * first, NtPidlEntry * second)
|
static HRESULT CompareIDs(LPARAM lParam, NtPidlEntry * first, NtPidlEntry * second)
|
||||||
{
|
{
|
||||||
if ((lParam & 0xFFFF0000) == SHCIDS_ALLFIELDS)
|
if ((lParam & 0xFFFF0000) == SHCIDS_ALLFIELDS)
|
||||||
{
|
{
|
||||||
|
@ -387,7 +431,7 @@ public:
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CompareIDs(LPARAM lParam, NtPidlEntry * first, LPCITEMIDLIST pcidl)
|
static HRESULT CompareIDs(LPARAM lParam, NtPidlEntry * first, LPCITEMIDLIST pcidl)
|
||||||
{
|
{
|
||||||
LPCITEMIDLIST p = pcidl;
|
LPCITEMIDLIST p = pcidl;
|
||||||
NtPidlEntry * second = (NtPidlEntry*) &(p->mkid);
|
NtPidlEntry * second = (NtPidlEntry*) &(p->mkid);
|
||||||
|
@ -397,7 +441,7 @@ public:
|
||||||
return CompareIDs(lParam, first, second);
|
return CompareIDs(lParam, first, second);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CompareIDs(LPARAM lParam, LPCITEMIDLIST pcidl1, LPCITEMIDLIST pcidl2)
|
static HRESULT CompareIDs(LPARAM lParam, LPCITEMIDLIST pcidl1, LPCITEMIDLIST pcidl2)
|
||||||
{
|
{
|
||||||
LPCITEMIDLIST p = pcidl1;
|
LPCITEMIDLIST p = pcidl1;
|
||||||
NtPidlEntry * first = (NtPidlEntry*) &(p->mkid);
|
NtPidlEntry * first = (NtPidlEntry*) &(p->mkid);
|
||||||
|
@ -407,7 +451,7 @@ public:
|
||||||
return CompareIDs(lParam, first, pcidl2);
|
return CompareIDs(lParam, first, pcidl2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG ConvertAttributes(NtPidlEntry * entry, PULONG inMask)
|
static ULONG ConvertAttributes(NtPidlEntry * entry, PULONG inMask)
|
||||||
{
|
{
|
||||||
ULONG mask = inMask ? *inMask : 0xFFFFFFFF;
|
ULONG mask = inMask ? *inMask : 0xFFFFFFFF;
|
||||||
ULONG flags = SFGAO_HASPROPSHEET | SFGAO_CANLINK;
|
ULONG flags = SFGAO_HASPROPSHEET | SFGAO_CANLINK;
|
||||||
|
@ -564,7 +608,10 @@ CNtObjectFolder::CNtObjectFolder() :
|
||||||
|
|
||||||
CNtObjectFolder::~CNtObjectFolder()
|
CNtObjectFolder::~CNtObjectFolder()
|
||||||
{
|
{
|
||||||
TRACE("Destroying CNtObjectFolder %p\n", this);
|
if (m_shellPidl)
|
||||||
|
ILFree(m_shellPidl);
|
||||||
|
if (m_PidlManager)
|
||||||
|
delete m_PidlManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IShellFolder
|
// IShellFolder
|
||||||
|
|
|
@ -164,6 +164,15 @@ public:
|
||||||
{
|
{
|
||||||
m_ntPath = ntPath;
|
m_ntPath = ntPath;
|
||||||
m_hRoot = hRoot;
|
m_hRoot = hRoot;
|
||||||
|
m_hDpa = NULL;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT Enumerate()
|
||||||
|
{
|
||||||
|
if (m_hDpa)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
m_hDpa = DPA_Create(10);
|
m_hDpa = DPA_Create(10);
|
||||||
|
|
||||||
|
@ -182,7 +191,6 @@ public:
|
||||||
if (FAILED_UNEXPECTEDLY(hr))
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +200,12 @@ public:
|
||||||
|
|
||||||
if (!m_hDpa)
|
if (!m_hDpa)
|
||||||
{
|
{
|
||||||
return E_FAIL;
|
hr = Enumerate();
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (!m_hDpa)
|
||||||
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegPidlEntry * info = (RegPidlEntry *) pcidl;
|
RegPidlEntry * info = (RegPidlEntry *) pcidl;
|
||||||
|
@ -230,11 +243,19 @@ public:
|
||||||
|
|
||||||
HRESULT FindByName(LPCWSTR strParsingName, RegPidlEntry ** pinfo)
|
HRESULT FindByName(LPCWSTR strParsingName, RegPidlEntry ** pinfo)
|
||||||
{
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
if (!m_hDpa)
|
if (!m_hDpa)
|
||||||
{
|
{
|
||||||
return E_FAIL;
|
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);
|
TRACE("Searching for '%S' in a list of %d items\n", strParsingName, m_hDpaCount);
|
||||||
|
|
||||||
for (int i = 0; i < (int) m_hDpaCount; i++)
|
for (int i = 0; i < (int) m_hDpaCount; i++)
|
||||||
|
@ -259,6 +280,18 @@ public:
|
||||||
|
|
||||||
HRESULT GetPidl(UINT index, RegPidlEntry ** pEntry)
|
HRESULT GetPidl(UINT index, RegPidlEntry ** pEntry)
|
||||||
{
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!m_hDpa)
|
||||||
|
{
|
||||||
|
hr = Enumerate();
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (!m_hDpa)
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
*pEntry = NULL;
|
*pEntry = NULL;
|
||||||
|
|
||||||
RegPidlEntry * entry = (RegPidlEntry *) DPA_GetPtr(m_hDpa, index);
|
RegPidlEntry * entry = (RegPidlEntry *) DPA_GetPtr(m_hDpa, index);
|
||||||
|
@ -273,6 +306,18 @@ public:
|
||||||
|
|
||||||
HRESULT GetCount(UINT * count)
|
HRESULT GetCount(UINT * count)
|
||||||
{
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!m_hDpa)
|
||||||
|
{
|
||||||
|
hr = Enumerate();
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (!m_hDpa)
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
*count = m_hDpaCount;
|
*count = m_hDpaCount;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -288,7 +333,7 @@ public:
|
||||||
return idl;
|
return idl;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CompareIDs(LPARAM lParam, RegPidlEntry * first, RegPidlEntry * second)
|
static HRESULT CompareIDs(LPARAM lParam, RegPidlEntry * first, RegPidlEntry * second)
|
||||||
{
|
{
|
||||||
if ((lParam & 0xFFFF0000) == SHCIDS_ALLFIELDS)
|
if ((lParam & 0xFFFF0000) == SHCIDS_ALLFIELDS)
|
||||||
{
|
{
|
||||||
|
@ -373,7 +418,7 @@ public:
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CompareIDs(LPARAM lParam, RegPidlEntry * first, LPCITEMIDLIST pcidl)
|
static HRESULT CompareIDs(LPARAM lParam, RegPidlEntry * first, LPCITEMIDLIST pcidl)
|
||||||
{
|
{
|
||||||
LPCITEMIDLIST p = pcidl;
|
LPCITEMIDLIST p = pcidl;
|
||||||
RegPidlEntry * second = (RegPidlEntry*) &(p->mkid);
|
RegPidlEntry * second = (RegPidlEntry*) &(p->mkid);
|
||||||
|
@ -383,7 +428,7 @@ public:
|
||||||
return CompareIDs(lParam, first, second);
|
return CompareIDs(lParam, first, second);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT CompareIDs(LPARAM lParam, LPCITEMIDLIST pcidl1, LPCITEMIDLIST pcidl2)
|
static HRESULT CompareIDs(LPARAM lParam, LPCITEMIDLIST pcidl1, LPCITEMIDLIST pcidl2)
|
||||||
{
|
{
|
||||||
LPCITEMIDLIST p = pcidl1;
|
LPCITEMIDLIST p = pcidl1;
|
||||||
RegPidlEntry * first = (RegPidlEntry*) &(p->mkid);
|
RegPidlEntry * first = (RegPidlEntry*) &(p->mkid);
|
||||||
|
@ -393,7 +438,7 @@ public:
|
||||||
return CompareIDs(lParam, first, pcidl2);
|
return CompareIDs(lParam, first, pcidl2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG ConvertAttributes(RegPidlEntry * entry, PULONG inMask)
|
static ULONG ConvertAttributes(RegPidlEntry * entry, PULONG inMask)
|
||||||
{
|
{
|
||||||
ULONG mask = inMask ? *inMask : 0xFFFFFFFF;
|
ULONG mask = inMask ? *inMask : 0xFFFFFFFF;
|
||||||
ULONG flags = 0;
|
ULONG flags = 0;
|
||||||
|
@ -416,7 +461,7 @@ public:
|
||||||
(entry->entryType == REG_ENTRY_ROOT);
|
(entry->entryType == REG_ENTRY_ROOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT FormatValueData(DWORD contentType, PVOID td, DWORD contentsLength, PCWSTR * strContents)
|
static HRESULT FormatValueData(DWORD contentType, PVOID td, DWORD contentsLength, PCWSTR * strContents)
|
||||||
{
|
{
|
||||||
switch (contentType)
|
switch (contentType)
|
||||||
{
|
{
|
||||||
|
@ -647,7 +692,10 @@ CRegistryFolder::CRegistryFolder() :
|
||||||
|
|
||||||
CRegistryFolder::~CRegistryFolder()
|
CRegistryFolder::~CRegistryFolder()
|
||||||
{
|
{
|
||||||
TRACE("Destroying CRegistryFolder %p\n", this);
|
if (m_shellPidl)
|
||||||
|
ILFree(m_shellPidl);
|
||||||
|
if (m_PidlManager)
|
||||||
|
delete m_PidlManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IShellFolder
|
// IShellFolder
|
||||||
|
|
Loading…
Reference in a new issue