From be7e5a84eb99aeb51d649425a4c184e09d9d67bc Mon Sep 17 00:00:00 2001 From: David Quintana Date: Mon, 16 Mar 2015 20:47:05 +0000 Subject: [PATCH] [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 --- reactos/dll/shellext/ntobjshex/ntobjns.cpp | 63 ++++++++++++++++--- reactos/dll/shellext/ntobjshex/regfolder.cpp | 66 +++++++++++++++++--- 2 files changed, 112 insertions(+), 17 deletions(-) diff --git a/reactos/dll/shellext/ntobjshex/ntobjns.cpp b/reactos/dll/shellext/ntobjshex/ntobjns.cpp index 4cc2c74d336..10f491cc7f7 100644 --- a/reactos/dll/shellext/ntobjshex/ntobjns.cpp +++ b/reactos/dll/shellext/ntobjshex/ntobjns.cpp @@ -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 diff --git a/reactos/dll/shellext/ntobjshex/regfolder.cpp b/reactos/dll/shellext/ntobjshex/regfolder.cpp index 0e5468e622b..f96ecfa75ca 100644 --- a/reactos/dll/shellext/ntobjshex/regfolder.cpp +++ b/reactos/dll/shellext/ntobjshex/regfolder.cpp @@ -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