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=6959…
==============================================================================
--- 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?r…
==============================================================================
--- 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.…
==============================================================================
--- 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.t…
==============================================================================
--- 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?r…
==============================================================================
--- 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