214 lines
5.1 KiB
C++
214 lines
5.1 KiB
C++
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
|
|
// PARTICULAR PURPOSE.
|
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
|
|
#include "memory.h"
|
|
#include "EapHostCommon.h"
|
|
|
|
namespace SDK_METHOD_SAMPLE_COMMON
|
|
{
|
|
|
|
/// The heap handle to use for all allocations.
|
|
HANDLE g_localHeap = NULL;
|
|
|
|
/**
|
|
* Initialize a local memory heap for our use.
|
|
*
|
|
*
|
|
* @return A Win32 error code, indicating success or failure.
|
|
*
|
|
*
|
|
* @note One heap is shared across all threads that uses this code; therefore,
|
|
* care should be taken to ensure this function is called only once.
|
|
* For example, calling it inside DllMain() will ensure this.
|
|
*/
|
|
DWORD
|
|
InitializeHeap(
|
|
)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
g_localHeap = NULL; // Make sure the global value is initialized.
|
|
|
|
g_localHeap = HeapCreate(0, // Serialize access to the heap
|
|
1, // Create a 0-byte heap; allocations will increase it, as necessary.
|
|
0); // Heap is growable; limited only by available memory
|
|
if (! g_localHeap)
|
|
{
|
|
dwErr = GetLastError();
|
|
EapTrace("InitializeHeap(): Heap creation failed -- hit error %d!", dwErr);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
/**
|
|
* Clean up the local memory heap.
|
|
*
|
|
* This will free our local heap, and all allocations inside it.
|
|
*
|
|
*
|
|
* @return A Win32 error code, indicating success or failure.
|
|
*
|
|
*
|
|
* @note One heap is shared across all threads that uses this code; therefore,
|
|
* care should be taken to ensure this function is called only once.
|
|
* For example, calling it inside DllCanUnloadNow() will ensure this.
|
|
*
|
|
* @note When this function succeeds, it will also initialize the heap handle
|
|
* to NULL, to prevent the handle from being used again.
|
|
*/
|
|
DWORD
|
|
CleanupHeap(
|
|
)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
BOOL fOk = TRUE;
|
|
|
|
// Sanity check.
|
|
if (! g_localHeap)
|
|
{
|
|
EapTrace("CleanupHeap(): Heap has not been created yet; exiting.");
|
|
goto LDone;
|
|
}
|
|
|
|
// Free the heap.
|
|
fOk = HeapDestroy(g_localHeap);
|
|
if (! fOk)
|
|
{
|
|
dwErr = GetLastError();
|
|
EapTrace("CleanupHeap(): Heap destruction failed -- hit error %d!", dwErr);
|
|
goto LDone;
|
|
}
|
|
|
|
// Reinitialize the heap handle.
|
|
g_localHeap = NULL;
|
|
|
|
LDone:
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Allocate memory, using our local heap.
|
|
*
|
|
*
|
|
* @param sizeInBytes [in] The byte-length of the buffer to allocate.
|
|
*
|
|
* @param ppBuffer [out] Pointer to the new data buffer.
|
|
*
|
|
*
|
|
* @return A Win32 error code, indicating success or failure.
|
|
* ERROR_INVALID_HANDLE - if AllocateMemory is called before InitializeHeap().
|
|
*/
|
|
DWORD
|
|
AllocateMemory(
|
|
IN DWORD sizeInBytes,
|
|
IN OUT PVOID *ppBuffer
|
|
)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
// Sanity checks.
|
|
if (ppBuffer == NULL)
|
|
{
|
|
EapTrace("AllocateMemory(): Invalid buffer pointer passed in!");
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto LDone;
|
|
}
|
|
|
|
if (! g_localHeap)
|
|
{
|
|
EapTrace("AllocateMemory(): Heap has not been created yet!");
|
|
dwErr = ERROR_INVALID_HANDLE;
|
|
goto LDone;
|
|
}
|
|
|
|
// Allocate a new memory block on the heap. Use HEAP_ZERO_MEMORY to
|
|
// initialize the memory block, so callers don't have to do so.
|
|
*ppBuffer = (PBYTE)HeapAlloc(g_localHeap, HEAP_ZERO_MEMORY, sizeInBytes);
|
|
if (*ppBuffer == NULL)
|
|
{
|
|
EapTrace("AllocateMemory(): Not enough memory");
|
|
dwErr = ERROR_OUTOFMEMORY;
|
|
goto LDone;
|
|
}
|
|
|
|
LDone:
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
/**
|
|
* Free memory allocations from our local heap.
|
|
*
|
|
*
|
|
* @param ppBuffer [out] Pointer to the data buffer to free.
|
|
*
|
|
*
|
|
* @return A Win32 error code, indicating success or failure.
|
|
* ERROR_INVALID_HANDLE - if FreeMemory is called before InitializeHeap().
|
|
*
|
|
*
|
|
* @note When this function succeeds, it will also initialize the buffer
|
|
* pointer to NULL, to prevent the calling function from referencing
|
|
* the former allocation again.
|
|
*/
|
|
DWORD
|
|
FreeMemory(
|
|
IN OUT PVOID *ppBuffer
|
|
)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
BOOL fOk = TRUE;
|
|
|
|
// Sanity checks.
|
|
if (ppBuffer == NULL)
|
|
{
|
|
EapTrace("FreeMemory(): Invalid buffer pointer passed in!");
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto LDone;
|
|
}
|
|
|
|
if (! g_localHeap)
|
|
{
|
|
EapTrace("FreeMemory(): Heap has not been created yet!");
|
|
dwErr = ERROR_INVALID_HANDLE;
|
|
goto LDone;
|
|
}
|
|
|
|
// Don't try to free NULL pointers.
|
|
if (*ppBuffer == NULL)
|
|
{
|
|
// Ignore this silently.
|
|
goto LDone;
|
|
}
|
|
|
|
fOk = HeapFree(g_localHeap, 0, *ppBuffer);
|
|
if (! fOk)
|
|
{
|
|
dwErr = GetLastError();
|
|
EapTrace("FreeMemory(): Error %d while freeing memory!", dwErr);
|
|
goto LDone;
|
|
}
|
|
|
|
// Re-initialize the buffer pointer.
|
|
*ppBuffer = NULL;
|
|
|
|
LDone:
|
|
return dwErr;
|
|
}
|
|
|
|
}// End "namespace SDK_METHOD_SAMPLE_COMMON
|