mirror of
https://github.com/reactos/reactos.git
synced 2025-02-21 16:04:57 +00:00
[ATL]
- Add CComHeapPtr implementation and tests. Patch by Mark Jansen. CORE-10344 #resolve svn path=/trunk/; revision=69593
This commit is contained in:
parent
1920e426e7
commit
237a82dc51
5 changed files with 234 additions and 0 deletions
|
@ -836,6 +836,94 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
// 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:
|
||||
|
|
|
@ -4,6 +4,7 @@ add_library(apitest apitest.c)
|
|||
add_dependencies(apitest xdk)
|
||||
|
||||
add_subdirectory(advapi32)
|
||||
add_subdirectory(atl)
|
||||
add_subdirectory(browseui)
|
||||
add_subdirectory(com)
|
||||
add_subdirectory(crt)
|
||||
|
|
123
rostests/apitests/atl/CComHeapPtr.cpp
Normal file
123
rostests/apitests/atl/CComHeapPtr.cpp
Normal file
|
@ -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);
|
||||
}
|
12
rostests/apitests/atl/CMakeLists.txt
Normal file
12
rostests/apitests/atl/CMakeLists.txt
Normal file
|
@ -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)
|
10
rostests/apitests/atl/testlist.c
Normal file
10
rostests/apitests/atl/testlist.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#define STANDALONE
|
||||
#include <apitest.h>
|
||||
|
||||
extern void func_CComHeapPtr(void);
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "CComHeapPtr", func_CComHeapPtr },
|
||||
{ 0, 0 }
|
||||
};
|
Loading…
Reference in a new issue