21#include <winpr/config.h> 
   27#if !defined(_WIN32) || (defined(__MINGW32__) && !defined(_UCRT)) 
   32#define WINPR_ALIGNED_MEM_SIGNATURE 0x0BA0BAB 
   34#define WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(_memptr) \ 
   35  (WINPR_ALIGNED_MEM*)(((size_t)(((BYTE*)(_memptr)) - sizeof(WINPR_ALIGNED_MEM)))) 
   40#define TAG WINPR_TAG("crt") 
   42struct winpr_aligned_mem
 
   48typedef struct winpr_aligned_mem WINPR_ALIGNED_MEM;
 
   50void* winpr_aligned_malloc(
size_t size, 
size_t alignment)
 
   52  return winpr_aligned_offset_malloc(size, alignment, 0);
 
   55void* winpr_aligned_calloc(
size_t count, 
size_t size, 
size_t alignment)
 
   57  return winpr_aligned_recalloc(NULL, count, size, alignment);
 
   60void* winpr_aligned_realloc(
void* memblock, 
size_t size, 
size_t alignment)
 
   62  return winpr_aligned_offset_realloc(memblock, size, alignment, 0);
 
   65void* winpr_aligned_recalloc(
void* memblock, 
size_t num, 
size_t size, 
size_t alignment)
 
   67  return winpr_aligned_offset_recalloc(memblock, num, size, alignment, 0);
 
   70void* winpr_aligned_offset_malloc(
size_t size, 
size_t alignment, 
size_t offset)
 
   74  uintptr_t basesize = 0;
 
   76  void* memblock = NULL;
 
   77  WINPR_ALIGNED_MEM* pMem = NULL;
 
   80  if (alignment % 2 == 1)
 
   88  if (alignment < 
sizeof(
void*))
 
   89    alignment = 
sizeof(
void*);
 
   91  if (alignment > SIZE_MAX - 
sizeof(WINPR_ALIGNED_MEM))
 
   94  header = 
sizeof(WINPR_ALIGNED_MEM) + alignment;
 
   96  if (size > SIZE_MAX - header)
 
   99  alignsize = size + header;
 
  101#if defined(_ISOC11_SOURCE) 
  102  base = aligned_alloc(alignment, alignsize);
 
  103#elif defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) || (_XOPEN_SOURCE >= 600) 
  104  if (posix_memalign(&base, alignment, alignsize) != 0)
 
  107  base = malloc(alignsize);
 
  112  basesize = (uintptr_t)base;
 
  114  if ((offset > UINTPTR_MAX) || (header > UINTPTR_MAX - offset) ||
 
  115      (basesize > UINTPTR_MAX - header - offset))
 
  121  memblock = (
void*)(((basesize + header + offset) & ~(alignment - 1)) - offset);
 
  122  pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
 
  123  pMem->sig = WINPR_ALIGNED_MEM_SIGNATURE;
 
  124  pMem->base_addr = base;
 
  129void* winpr_aligned_offset_realloc(
void* memblock, 
size_t size, 
size_t alignment, 
size_t offset)
 
  132  void* newMemblock = NULL;
 
  133  WINPR_ALIGNED_MEM* pMem = NULL;
 
  134  WINPR_ALIGNED_MEM* pNewMem = NULL;
 
  137    return winpr_aligned_offset_malloc(size, alignment, offset);
 
  139  pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
 
  141  if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
 
  144             "_aligned_offset_realloc: memory block was not allocated by _aligned_malloc!");
 
  150    winpr_aligned_free(memblock);
 
  154  newMemblock = winpr_aligned_offset_malloc(size, alignment, offset);
 
  159  pNewMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(newMemblock);
 
  160  copySize = (pNewMem->size < pMem->size) ? pNewMem->size : pMem->size;
 
  161  CopyMemory(newMemblock, memblock, copySize);
 
  162  winpr_aligned_free(memblock);
 
  166static inline size_t cMIN(
size_t a, 
size_t b)
 
  173void* winpr_aligned_offset_recalloc(
void* memblock, 
size_t num, 
size_t size, 
size_t alignment,
 
  176  char* newMemblock = NULL;
 
  177  WINPR_ALIGNED_MEM* pMem = NULL;
 
  178  WINPR_ALIGNED_MEM* pNewMem = NULL;
 
  182    newMemblock = winpr_aligned_offset_malloc(size * num, alignment, offset);
 
  186      pNewMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(newMemblock);
 
  187      ZeroMemory(newMemblock, pNewMem->size);
 
  193  pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
 
  195  if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
 
  198             "_aligned_offset_recalloc: memory block was not allocated by _aligned_malloc!");
 
  202  if ((num == 0) || (size == 0))
 
  205  if (pMem->size > (1ull * num * size) + alignment)
 
  208  newMemblock = winpr_aligned_offset_malloc(size * num, alignment, offset);
 
  213  pNewMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(newMemblock);
 
  215    const size_t csize = cMIN(pMem->size, pNewMem->size);
 
  216    memcpy(newMemblock, memblock, csize);
 
  217    ZeroMemory(newMemblock + csize, pNewMem->size - csize);
 
  220  winpr_aligned_free(memblock);
 
  224size_t winpr_aligned_msize(
void* memblock, WINPR_ATTR_UNUSED 
size_t alignment,
 
  225                           WINPR_ATTR_UNUSED 
size_t offset)
 
  227  WINPR_ALIGNED_MEM* pMem = NULL;
 
  232  pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
 
  234  if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
 
  236    WLog_ERR(TAG, 
"_aligned_msize: memory block was not allocated by _aligned_malloc!");
 
  243void winpr_aligned_free(
void* memblock)
 
  245  WINPR_ALIGNED_MEM* pMem = NULL;
 
  250  pMem = WINPR_ALIGNED_MEM_STRUCT_FROM_PTR(memblock);
 
  252  if (pMem->sig != WINPR_ALIGNED_MEM_SIGNATURE)
 
  254    WLog_ERR(TAG, 
"_aligned_free: memory block was not allocated by _aligned_malloc!");
 
  258  free(pMem->base_addr);