2025-11-28 00:35:46 +09:00

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