mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +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)
|
||||
{
|
||||
m_ntPath = ntPath;
|
||||
m_hDpa = NULL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT Enumerate()
|
||||
{
|
||||
if (m_hDpa)
|
||||
return S_OK;
|
||||
|
||||
m_hDpa = DPA_Create(10);
|
||||
|
||||
|
@ -196,7 +205,12 @@ public:
|
|||
|
||||
if (!m_hDpa)
|
||||
{
|
||||
return E_FAIL;
|
||||
hr = Enumerate();
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
if (!m_hDpa)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
NtPidlEntry * info = (NtPidlEntry *) pcidl;
|
||||
|
@ -234,9 +248,16 @@ public:
|
|||
|
||||
HRESULT FindByName(LPCWSTR strParsingName, NtPidlEntry ** pinfo)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
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);
|
||||
|
@ -263,6 +284,18 @@ public:
|
|||
|
||||
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;
|
||||
|
||||
NtPidlEntry * entry = (NtPidlEntry *) DPA_GetPtr(m_hDpa, index);
|
||||
|
@ -277,11 +310,22 @@ public:
|
|||
|
||||
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;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
static LPITEMIDLIST CreatePidlFromItem(NtPidlEntry * entry)
|
||||
{
|
||||
LPITEMIDLIST idl = (LPITEMIDLIST) CoTaskMemAlloc(entry->cb + 2);
|
||||
|
@ -292,7 +336,7 @@ public:
|
|||
return idl;
|
||||
}
|
||||
|
||||
HRESULT CompareIDs(LPARAM lParam, NtPidlEntry * first, NtPidlEntry * second)
|
||||
static HRESULT CompareIDs(LPARAM lParam, NtPidlEntry * first, NtPidlEntry * second)
|
||||
{
|
||||
if ((lParam & 0xFFFF0000) == SHCIDS_ALLFIELDS)
|
||||
{
|
||||
|
@ -387,7 +431,7 @@ public:
|
|||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
HRESULT CompareIDs(LPARAM lParam, NtPidlEntry * first, LPCITEMIDLIST pcidl)
|
||||
static HRESULT CompareIDs(LPARAM lParam, NtPidlEntry * first, LPCITEMIDLIST pcidl)
|
||||
{
|
||||
LPCITEMIDLIST p = pcidl;
|
||||
NtPidlEntry * second = (NtPidlEntry*) &(p->mkid);
|
||||
|
@ -397,7 +441,7 @@ public:
|
|||
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;
|
||||
NtPidlEntry * first = (NtPidlEntry*) &(p->mkid);
|
||||
|
@ -407,7 +451,7 @@ public:
|
|||
return CompareIDs(lParam, first, pcidl2);
|
||||
}
|
||||
|
||||
ULONG ConvertAttributes(NtPidlEntry * entry, PULONG inMask)
|
||||
static ULONG ConvertAttributes(NtPidlEntry * entry, PULONG inMask)
|
||||
{
|
||||
ULONG mask = inMask ? *inMask : 0xFFFFFFFF;
|
||||
ULONG flags = SFGAO_HASPROPSHEET | SFGAO_CANLINK;
|
||||
|
@ -564,7 +608,10 @@ CNtObjectFolder::CNtObjectFolder() :
|
|||
|
||||
CNtObjectFolder::~CNtObjectFolder()
|
||||
{
|
||||
TRACE("Destroying CNtObjectFolder %p\n", this);
|
||||
if (m_shellPidl)
|
||||
ILFree(m_shellPidl);
|
||||
if (m_PidlManager)
|
||||
delete m_PidlManager;
|
||||
}
|
||||
|
||||
// IShellFolder
|
||||
|
|
|
@ -164,6 +164,15 @@ public:
|
|||
{
|
||||
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);
|
||||
|
||||
|
@ -182,7 +191,6 @@ public:
|
|||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -192,7 +200,12 @@ public:
|
|||
|
||||
if (!m_hDpa)
|
||||
{
|
||||
return E_FAIL;
|
||||
hr = Enumerate();
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
if (!m_hDpa)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
RegPidlEntry * info = (RegPidlEntry *) pcidl;
|
||||
|
@ -230,11 +243,19 @@ public:
|
|||
|
||||
HRESULT FindByName(LPCWSTR strParsingName, RegPidlEntry ** pinfo)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
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);
|
||||
|
||||
for (int i = 0; i < (int) m_hDpaCount; i++)
|
||||
|
@ -259,6 +280,18 @@ public:
|
|||
|
||||
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;
|
||||
|
||||
RegPidlEntry * entry = (RegPidlEntry *) DPA_GetPtr(m_hDpa, index);
|
||||
|
@ -273,6 +306,18 @@ public:
|
|||
|
||||
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;
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -288,7 +333,7 @@ public:
|
|||
return idl;
|
||||
}
|
||||
|
||||
HRESULT CompareIDs(LPARAM lParam, RegPidlEntry * first, RegPidlEntry * second)
|
||||
static HRESULT CompareIDs(LPARAM lParam, RegPidlEntry * first, RegPidlEntry * second)
|
||||
{
|
||||
if ((lParam & 0xFFFF0000) == SHCIDS_ALLFIELDS)
|
||||
{
|
||||
|
@ -373,7 +418,7 @@ public:
|
|||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
HRESULT CompareIDs(LPARAM lParam, RegPidlEntry * first, LPCITEMIDLIST pcidl)
|
||||
static HRESULT CompareIDs(LPARAM lParam, RegPidlEntry * first, LPCITEMIDLIST pcidl)
|
||||
{
|
||||
LPCITEMIDLIST p = pcidl;
|
||||
RegPidlEntry * second = (RegPidlEntry*) &(p->mkid);
|
||||
|
@ -383,7 +428,7 @@ public:
|
|||
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;
|
||||
RegPidlEntry * first = (RegPidlEntry*) &(p->mkid);
|
||||
|
@ -393,7 +438,7 @@ public:
|
|||
return CompareIDs(lParam, first, pcidl2);
|
||||
}
|
||||
|
||||
ULONG ConvertAttributes(RegPidlEntry * entry, PULONG inMask)
|
||||
static ULONG ConvertAttributes(RegPidlEntry * entry, PULONG inMask)
|
||||
{
|
||||
ULONG mask = inMask ? *inMask : 0xFFFFFFFF;
|
||||
ULONG flags = 0;
|
||||
|
@ -416,7 +461,7 @@ public:
|
|||
(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)
|
||||
{
|
||||
|
@ -647,7 +692,10 @@ CRegistryFolder::CRegistryFolder() :
|
|||
|
||||
CRegistryFolder::~CRegistryFolder()
|
||||
{
|
||||
TRACE("Destroying CRegistryFolder %p\n", this);
|
||||
if (m_shellPidl)
|
||||
ILFree(m_shellPidl);
|
||||
if (m_PidlManager)
|
||||
delete m_PidlManager;
|
||||
}
|
||||
|
||||
// IShellFolder
|
||||
|
|
Loading…
Reference in a new issue