Author: tfaber Date: Sun Oct 18 10:46:11 2015 New Revision: 69593
URL: http://svn.reactos.org/svn/reactos?rev=69593&view=rev Log: [ATL] - Add CComHeapPtr implementation and tests. Patch by Mark Jansen. CORE-10344 #resolve
Added: trunk/rostests/apitests/atl/ trunk/rostests/apitests/atl/CComHeapPtr.cpp (with props) trunk/rostests/apitests/atl/CMakeLists.txt (with props) trunk/rostests/apitests/atl/testlist.c (with props) Modified: trunk/reactos/lib/atl/atlbase.h trunk/rostests/apitests/CMakeLists.txt
Modified: trunk/reactos/lib/atl/atlbase.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlbase.h?rev=69593... ============================================================================== --- trunk/reactos/lib/atl/atlbase.h [iso-8859-1] (original) +++ trunk/reactos/lib/atl/atlbase.h [iso-8859-1] Sun Oct 18 10:46:11 2015 @@ -836,6 +836,94 @@ } };
+ +// TODO: When someone needs it, make the allocator a template, so you can use it for both +// CoTask* allocations, and CRT-like allocations (malloc, realloc, free) +template<class T> +class CComHeapPtr +{ +public: + CComHeapPtr() : + m_Data(NULL) + { + } + + explicit CComHeapPtr(T *lp) : + m_Data(lp) + { + } + + explicit CComHeapPtr(CComHeapPtr<T> &lp) + { + m_Data = lp.Detach(); + } + + ~CComHeapPtr() + { + Release(); + } + + T *operator = (CComHeapPtr<T> &lp) + { + if (lp.m_Data != m_Data) + Attach(lp.Detach()); + return *this; + } + + bool Allocate(size_t nElements = 1) + { + ATLASSERT(m_Data == NULL); + m_Data = static_cast<T*>(::CoTaskMemAlloc(nElements * sizeof(T))); + return m_Data != NULL; + } + + bool Reallocate(_In_ size_t nElements) + { + T* newData = static_cast<T*>(::CoTaskMemRealloc(m_Data, nElements * sizeof(T))); + if (newData == NULL) + return false; + m_Data = newData; + return true; + } + + void Release() + { + if (m_Data) + { + ::CoTaskMemFree(m_Data); + m_Data = NULL; + } + } + + void Attach(T *lp) + { + Release(); + m_Data = lp; + } + + T *Detach() + { + T *saveP = m_Data; + m_Data = NULL; + return saveP; + } + + T **operator &() + { + ATLASSERT(m_Data == NULL); + return &m_Data; + } + + operator T* () const + { + return m_Data; + } + +protected: + T *m_Data; +}; + + class CComBSTR { public:
Modified: trunk/rostests/apitests/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/CMakeLists.txt?re... ============================================================================== --- trunk/rostests/apitests/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/apitests/CMakeLists.txt [iso-8859-1] Sun Oct 18 10:46:11 2015 @@ -4,6 +4,7 @@ add_dependencies(apitest xdk)
add_subdirectory(advapi32) +add_subdirectory(atl) add_subdirectory(browseui) add_subdirectory(com) add_subdirectory(crt)
Added: trunk/rostests/apitests/atl/CComHeapPtr.cpp URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/CComHeapPtr.c... ============================================================================== --- trunk/rostests/apitests/atl/CComHeapPtr.cpp (added) +++ trunk/rostests/apitests/atl/CComHeapPtr.cpp [iso-8859-1] Sun Oct 18 10:46:11 2015 @@ -0,0 +1,123 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Test for CComHeapPtr + * PROGRAMMER: Mark Jansen + */ + +#include <apitest.h> +#include <atlbase.h> +#include <atlcom.h> + +static PDWORD test_Alloc(DWORD value) +{ + PDWORD ptr = (PDWORD)::CoTaskMemAlloc(sizeof(DWORD)); + *ptr = value; + return ptr; +} + + +static LONG g_OpenAllocations = 0; +static LONG g_Reallocations = 0; + +struct CMallocSpy : public IMallocSpy +{ + STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) + { + if (IsEqualGUID(riid, IID_IMallocSpy)) + { + *ppvObject = this; + } + return S_OK; + } + + virtual ULONG STDMETHODCALLTYPE AddRef() { return 1; } + virtual ULONG STDMETHODCALLTYPE Release() { return 1; } + virtual ULONG STDMETHODCALLTYPE PreAlloc(ULONG cbRequest) { return cbRequest; } + virtual LPVOID STDMETHODCALLTYPE PostAlloc(LPVOID pActual) + { + InterlockedIncrement(&g_OpenAllocations); + return pActual; + } + virtual LPVOID STDMETHODCALLTYPE PreFree(LPVOID pRequest, BOOL) { return pRequest; } + virtual void STDMETHODCALLTYPE PostFree(BOOL fSpyed) + { + if (fSpyed) + InterlockedDecrement(&g_OpenAllocations); + } + virtual ULONG STDMETHODCALLTYPE PreRealloc(LPVOID pRequest, ULONG cbRequest, LPVOID *ppNewRequest, BOOL) + { + *ppNewRequest = pRequest; + return cbRequest; + } + virtual LPVOID STDMETHODCALLTYPE PostRealloc(LPVOID pActual, BOOL fSpyed) + { + if (fSpyed) + InterlockedIncrement(&g_Reallocations); + return pActual; + } + virtual LPVOID STDMETHODCALLTYPE PreGetSize(LPVOID pRequest, BOOL) { return pRequest; } + virtual ULONG STDMETHODCALLTYPE PostGetSize(ULONG cbActual, BOOL) { return cbActual; } + virtual LPVOID STDMETHODCALLTYPE PreDidAlloc(LPVOID pRequest, BOOL) { return pRequest; } + virtual int STDMETHODCALLTYPE PostDidAlloc(LPVOID, BOOL, int fActual) { return fActual; } + virtual void STDMETHODCALLTYPE PreHeapMinimize() {} + virtual void STDMETHODCALLTYPE PostHeapMinimize() {} +}; + +static CMallocSpy g_Spy; + + +START_TEST(CComHeapPtr) +{ + HRESULT hr = CoRegisterMallocSpy(&g_Spy); + ok(SUCCEEDED(hr), "Expected CoRegisterMallocSpy to succeed, but it failed: 0x%lx\n", hr); + + { + ok(g_OpenAllocations == 0, "Expected there to be 0 allocations, was: %ld\n", g_OpenAllocations); + CComHeapPtr<DWORD> heapPtr1; + ok(g_OpenAllocations == 0, "Expected there to be 0 allocations, was: %ld\n", g_OpenAllocations); + CComHeapPtr<DWORD> heapPtr2(test_Alloc(0x11111111)); + ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations); + + ok((PDWORD)heapPtr1 == NULL, "Expected heapPtr1 to be NULL, was: 0x%p\n", (PDWORD)heapPtr1); + ok((PDWORD)heapPtr2 != NULL, "Expected heapPtr2 to not be NULL\n"); + ok(*heapPtr2 == 0x11111111, "Expected *heapPtr2 to be 0x11111111, but was: 0x%lx\n", *heapPtr2); + + { + ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations); + CComHeapPtr<DWORD> heapPtrSteal1(heapPtr1); + ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations); + ok((PDWORD)heapPtr1 == NULL, "Expected heapPtr1 to be NULL, was: 0x%p\n", (PDWORD)heapPtr1); + ok((PDWORD)heapPtrSteal1 == NULL, "Expected heapPtrSteal1 to be NULL, was: 0x%p\n", (PDWORD)heapPtrSteal1); + CComHeapPtr<DWORD> heapPtrSteal2(heapPtr2); + ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations); + ok((PDWORD)heapPtr2 == NULL, "Expected heapPtr2 to be NULL, was: 0x%p\n", (PDWORD)heapPtr2); + ok((PDWORD)heapPtrSteal2 != NULL, "Expected heapPtrSteal2 to not be NULL\n"); + ok(*heapPtrSteal2 == 0x11111111, "Expected *heapPtrSteal2 to be 0x11111111, but was: 0x%lx\n", *heapPtrSteal2); + } + ok(g_OpenAllocations == 0, "Expected there to be 0 allocations, was: %ld\n", g_OpenAllocations); + + ok(heapPtr1.Allocate(1), "Expected Allocate to succeed\n"); + ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations); + ok(g_Reallocations == 0, "Expected there to be 0 reallocations, was: %ld\n", g_Reallocations); + + *heapPtr1 = 0x22222222; + ok(*heapPtr1 == 0x22222222, "Expected *heapPtr1 to be 0x22222222, but was: 0x%lx\n", *heapPtr1); + + ok(heapPtr1.Reallocate(2), "Expected Reallocate to succeed\n"); + heapPtr1[1] = 0x33333333; + ok(*heapPtr1 == 0x22222222, "Expected *heapPtr1 to be 0x22222222, but was: 0x%lx\n", *heapPtr1); + ok(g_Reallocations == 1, "Expected there to be 1 reallocations, was: %ld\n", g_Reallocations); + ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations); + + heapPtr2 = heapPtr1; + ok(g_OpenAllocations == 1, "Expected there to be 1 allocations, was: %ld\n", g_OpenAllocations); + ok(*heapPtr2 == 0x22222222, "Expected *heapPtr2 to be 0x33333333, but was: 0x%lx\n", *heapPtr2); + ok(heapPtr2[1] == 0x33333333, "Expected heapPtr2[1] to be 0x33333333, but was: 0x%lx\n", heapPtr2[1]); + ok((PDWORD)heapPtr1 == NULL, "Expected heapPtr1 to be NULL, was: 0x%p\n", (PDWORD)heapPtr1); + } + ok(g_OpenAllocations == 0, "Expected there to be 0 allocations, was: %ld\n", g_OpenAllocations); + + hr = CoRevokeMallocSpy(); + ok(SUCCEEDED(hr), "Expected CoRevokeMallocSpy to succeed, but it failed: 0x%lx\n", hr); +}
Propchange: trunk/rostests/apitests/atl/CComHeapPtr.cpp ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/rostests/apitests/atl/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/CMakeLists.tx... ============================================================================== --- trunk/rostests/apitests/atl/CMakeLists.txt (added) +++ trunk/rostests/apitests/atl/CMakeLists.txt [iso-8859-1] Sun Oct 18 10:46:11 2015 @@ -0,0 +1,12 @@ + +set_cpp(WITH_RUNTIME) + +include_directories(${REACTOS_SOURCE_DIR}/lib/atl) + +add_executable(atl_apitest + CComHeapPtr.cpp + testlist.c) +target_link_libraries(atl_apitest wine uuid) +set_module_type(atl_apitest win32cui) +add_importlibs(atl_apitest ole32 oleaut32 msvcrt kernel32) +add_cd_file(TARGET atl_apitest DESTINATION reactos/bin FOR all)
Propchange: trunk/rostests/apitests/atl/CMakeLists.txt ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/rostests/apitests/atl/testlist.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/atl/testlist.c?re... ============================================================================== --- trunk/rostests/apitests/atl/testlist.c (added) +++ trunk/rostests/apitests/atl/testlist.c [iso-8859-1] Sun Oct 18 10:46:11 2015 @@ -0,0 +1,10 @@ +#define STANDALONE +#include <apitest.h> + +extern void func_CComHeapPtr(void); + +const struct test winetest_testlist[] = +{ + { "CComHeapPtr", func_CComHeapPtr }, + { 0, 0 } +};
Propchange: trunk/rostests/apitests/atl/testlist.c ------------------------------------------------------------------------------ svn:eol-style = native