You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
771 lines
19 KiB
771 lines
19 KiB
/*++
|
|
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
heap.c
|
|
|
|
Abstract:
|
|
|
|
This module implements verification functions for
|
|
heap management interfaces.
|
|
|
|
Author:
|
|
|
|
Silviu Calinoiu (SilviuC) 7-Mar-2001
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
|
|
#include "verifier.h"
|
|
#include "support.h"
|
|
#include "critsect.h"
|
|
#include "faults.h"
|
|
|
|
//
|
|
// During manipulation of DPH_BLOCK_INFORMATION we get this because
|
|
// pointers have a default 8 byte aligned. However they will always
|
|
// be 16-byte aligned because they are derived from heap allocated
|
|
// blocks and these are 16 byte aligned anyway.
|
|
//
|
|
|
|
#if defined(_WIN64)
|
|
#pragma warning(disable:4327)
|
|
#endif
|
|
|
|
//
|
|
// Dirty unused portions of stack in order to catch usage of
|
|
// uninitialized locals.
|
|
//
|
|
|
|
#define AVRFP_DIRTY_STACK_FREQUENCY 16
|
|
LONG AVrfpDirtyStackCounter;
|
|
|
|
#define AVRFP_DIRTY_THREAD_STACK() { \
|
|
if ((AVrfpProvider.VerifierFlags & RTL_VRF_FLG_DIRTY_STACKS) != 0) { \
|
|
if ((InterlockedIncrement(&AVrfpDirtyStackCounter) % AVRFP_DIRTY_STACK_FREQUENCY) == 0) { \
|
|
AVrfpDirtyThreadStack (); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
//
|
|
// Simple test to figure out if a heap was created by page heap or it is
|
|
// just a normal heap.
|
|
//
|
|
|
|
#define IS_PAGE_HEAP(HeapHandle) (*(PULONG)HeapHandle == 0xEEEEEEEE)
|
|
|
|
#define RAISE_NO_MEMORY_EXCEPTION() \
|
|
{ \
|
|
EXCEPTION_RECORD ER; \
|
|
ER.ExceptionCode = STATUS_NO_MEMORY; \
|
|
ER.ExceptionFlags = 0; \
|
|
ER.ExceptionRecord = NULL; \
|
|
ER.ExceptionAddress = _ReturnAddress(); \
|
|
ER.NumberParameters = 0; \
|
|
RtlRaiseException( &ER ); \
|
|
}
|
|
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
//NTSYSAPI
|
|
PVOID
|
|
NTAPI
|
|
AVrfpRtlAllocateHeap(
|
|
IN PVOID HeapHandle,
|
|
IN ULONG Flags,
|
|
IN SIZE_T Size
|
|
)
|
|
{
|
|
PVOID Result;
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_HEAP_ALLOC_APIS)) {
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_HEAP_ALLOC_FAIL);
|
|
|
|
if ((Flags & HEAP_GENERATE_EXCEPTIONS)) {
|
|
RAISE_NO_MEMORY_EXCEPTION ();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
Result = RtlAllocateHeap (HeapHandle,
|
|
Flags,
|
|
Size);
|
|
|
|
if (Result) {
|
|
|
|
AVrfLogInTracker (AVrfHeapTracker,
|
|
TRACK_HEAP_ALLOCATE,
|
|
Result, (PVOID)Size, NULL, NULL, _ReturnAddress());
|
|
}
|
|
|
|
AVRFP_DIRTY_THREAD_STACK ();
|
|
|
|
return Result;
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
//NTSYSAPI
|
|
BOOLEAN
|
|
NTAPI
|
|
AVrfpRtlFreeHeap(
|
|
IN PVOID HeapHandle,
|
|
IN ULONG Flags,
|
|
IN PVOID BaseAddress
|
|
)
|
|
{
|
|
BOOLEAN Result;
|
|
BOOL BogusAddress;
|
|
SIZE_T RequestedSize;
|
|
PDPH_BLOCK_INFORMATION BlockInformation;
|
|
|
|
//
|
|
// Initialize RequestedSize in order to be able to compile W4.
|
|
// The variable gets actually initialized when it matters but
|
|
// the compiler is not able to realize that. If while initializing
|
|
// it we get an exception then we will not use it.
|
|
//
|
|
|
|
RequestedSize = 0;
|
|
|
|
if (BaseAddress != NULL && IS_PAGE_HEAP (HeapHandle)) {
|
|
|
|
BogusAddress = FALSE;
|
|
|
|
BlockInformation = (PDPH_BLOCK_INFORMATION)BaseAddress - 1;
|
|
|
|
try {
|
|
|
|
RequestedSize = BlockInformation->RequestedSize;
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
//
|
|
// Let page heap handle the bogus block.
|
|
//
|
|
|
|
BogusAddress = TRUE;
|
|
}
|
|
|
|
if (BogusAddress == FALSE) {
|
|
|
|
AVrfpFreeMemNotify (VerifierFreeMemTypeFreeHeap,
|
|
BaseAddress,
|
|
RequestedSize,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
Result = RtlFreeHeap (HeapHandle,
|
|
Flags,
|
|
BaseAddress);
|
|
|
|
if (Result) {
|
|
|
|
AVrfLogInTracker (AVrfHeapTracker,
|
|
TRACK_HEAP_FREE,
|
|
BaseAddress, NULL, NULL, NULL, _ReturnAddress());
|
|
}
|
|
|
|
AVRFP_DIRTY_THREAD_STACK ();
|
|
|
|
return Result;
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
//NTSYSAPI
|
|
PVOID
|
|
NTAPI
|
|
AVrfpRtlReAllocateHeap(
|
|
IN PVOID HeapHandle,
|
|
IN ULONG Flags,
|
|
IN PVOID BaseAddress,
|
|
IN SIZE_T Size
|
|
)
|
|
{
|
|
PVOID Result;
|
|
BOOL BogusAddress;
|
|
SIZE_T RequestedSize;
|
|
PDPH_BLOCK_INFORMATION BlockInformation;
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_HEAP_ALLOC_APIS)) {
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_HEAP_ALLOC_FAIL);
|
|
|
|
if ((Flags & HEAP_GENERATE_EXCEPTIONS)) {
|
|
RAISE_NO_MEMORY_EXCEPTION ();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Initialize RequestedSize in order to be able to compile W4.
|
|
// The variable gets actually initialized when it matters but
|
|
// the compiler is not able to realize that. If while initializing
|
|
// it we get an exception then we will not use it.
|
|
//
|
|
|
|
RequestedSize = 0;
|
|
|
|
if (BaseAddress != NULL &&
|
|
IS_PAGE_HEAP (HeapHandle) &&
|
|
((Flags & HEAP_REALLOC_IN_PLACE_ONLY) != 0)) {
|
|
|
|
BogusAddress = FALSE;
|
|
|
|
BlockInformation = (PDPH_BLOCK_INFORMATION)BaseAddress - 1;
|
|
|
|
try {
|
|
|
|
RequestedSize = BlockInformation->RequestedSize;
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
//
|
|
// Let page heap handle the bogus block.
|
|
//
|
|
|
|
BogusAddress = TRUE;
|
|
}
|
|
|
|
if (BogusAddress == FALSE) {
|
|
|
|
AVrfpFreeMemNotify (VerifierFreeMemTypeFreeHeap,
|
|
BaseAddress,
|
|
RequestedSize,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
Result = RtlReAllocateHeap (HeapHandle,
|
|
Flags,
|
|
BaseAddress,
|
|
Size);
|
|
|
|
if (Result) {
|
|
|
|
AVrfLogInTracker (AVrfHeapTracker,
|
|
TRACK_HEAP_REALLOCATE,
|
|
BaseAddress, Result, (PVOID)Size, NULL, _ReturnAddress());
|
|
}
|
|
|
|
AVRFP_DIRTY_THREAD_STACK ();
|
|
|
|
return Result;
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
VOID
|
|
AVrfpNtdllHeapFreeCallback (
|
|
PVOID AllocationBase,
|
|
SIZE_T AllocationSize
|
|
)
|
|
{
|
|
AVrfpFreeMemNotify (VerifierFreeMemTypeFreeHeap,
|
|
AllocationBase,
|
|
AllocationSize,
|
|
NULL);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////// kernel32.dll verified exports
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
//WINBASEAPI
|
|
HANDLE
|
|
WINAPI
|
|
AVrfpHeapCreate(
|
|
IN DWORD flOptions,
|
|
IN SIZE_T dwInitialSize,
|
|
IN SIZE_T dwMaximumSize
|
|
)
|
|
{
|
|
typedef HANDLE (WINAPI * FUNCTION_TYPE) (DWORD, SIZE_T, SIZE_T);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
|
|
AVRF_INDEX_KERNEL32_HEAPCREATE);
|
|
|
|
BUMP_COUNTER (CNT_HEAPS_CREATED);
|
|
return (* Function)(flOptions, dwInitialSize, dwMaximumSize);
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
//WINBASEAPI
|
|
BOOL
|
|
WINAPI
|
|
AVrfpHeapDestroy(
|
|
IN OUT HANDLE hHeap
|
|
)
|
|
{
|
|
typedef BOOL (WINAPI * FUNCTION_TYPE) (HANDLE);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
|
|
AVRF_INDEX_KERNEL32_HEAPDESTROY);
|
|
|
|
BUMP_COUNTER (CNT_HEAPS_DESTROYED);
|
|
return (* Function)(hHeap);
|
|
}
|
|
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
//WINBASEAPI
|
|
HGLOBAL
|
|
WINAPI
|
|
AVrfpGlobalAlloc(
|
|
IN UINT uFlags,
|
|
IN SIZE_T dwBytes
|
|
)
|
|
{
|
|
typedef HGLOBAL (WINAPI * FUNCTION_TYPE) (UINT, SIZE_T);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
|
|
AVRF_INDEX_KERNEL32_GLOBALALLOC);
|
|
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_HEAP_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_HEAP_ALLOC_FAIL);
|
|
NtCurrentTeb()->LastErrorValue = ERROR_OUTOFMEMORY;
|
|
return NULL;
|
|
}
|
|
|
|
return (* Function)(uFlags, dwBytes);
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
//WINBASEAPI
|
|
HGLOBAL
|
|
WINAPI
|
|
AVrfpGlobalReAlloc(
|
|
IN HGLOBAL hMem,
|
|
IN SIZE_T dwBytes,
|
|
IN UINT uFlags
|
|
)
|
|
{
|
|
typedef HGLOBAL (WINAPI * FUNCTION_TYPE) (HGLOBAL, SIZE_T, UINT);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
|
|
AVRF_INDEX_KERNEL32_GLOBALREALLOC);
|
|
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_HEAP_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_HEAP_ALLOC_FAIL);
|
|
NtCurrentTeb()->LastErrorValue = ERROR_OUTOFMEMORY;
|
|
return NULL;
|
|
}
|
|
|
|
return (* Function)(hMem, dwBytes, uFlags);
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
//WINBASEAPI
|
|
HLOCAL
|
|
WINAPI
|
|
AVrfpLocalAlloc(
|
|
IN UINT uFlags,
|
|
IN SIZE_T uBytes
|
|
)
|
|
{
|
|
typedef HLOCAL (WINAPI * FUNCTION_TYPE) (UINT, SIZE_T);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
|
|
AVRF_INDEX_KERNEL32_LOCALALLOC);
|
|
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_HEAP_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_HEAP_ALLOC_FAIL);
|
|
NtCurrentTeb()->LastErrorValue = ERROR_OUTOFMEMORY;
|
|
return NULL;
|
|
}
|
|
|
|
return (* Function)(uFlags, uBytes);
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
//WINBASEAPI
|
|
HLOCAL
|
|
WINAPI
|
|
AVrfpLocalReAlloc(
|
|
IN HLOCAL hMem,
|
|
IN SIZE_T uBytes,
|
|
IN UINT uFlags
|
|
)
|
|
{
|
|
typedef HLOCAL (WINAPI * FUNCTION_TYPE) (HLOCAL, SIZE_T, UINT);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
|
|
AVRF_INDEX_KERNEL32_LOCALREALLOC);
|
|
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_HEAP_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_HEAP_ALLOC_FAIL);
|
|
NtCurrentTeb()->LastErrorValue = ERROR_OUTOFMEMORY;
|
|
return NULL;
|
|
}
|
|
|
|
return (* Function)(hMem, uBytes, uFlags);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////// msvcrt allocation routines
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
PVOID __cdecl
|
|
AVrfp_malloc (
|
|
IN SIZE_T Size
|
|
)
|
|
{
|
|
typedef PVOID (__cdecl * FUNCTION_TYPE) (SIZE_T);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
|
|
AVRF_INDEX_MSVCRT_MALLOC);
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_HEAP_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_HEAP_ALLOC_FAIL);
|
|
return NULL;
|
|
}
|
|
|
|
return (* Function)(Size);
|
|
}
|
|
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
PVOID __cdecl
|
|
AVrfp_calloc (
|
|
IN SIZE_T Number,
|
|
IN SIZE_T Size
|
|
)
|
|
{
|
|
typedef PVOID (__cdecl * FUNCTION_TYPE) (SIZE_T, SIZE_T);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
|
|
AVRF_INDEX_MSVCRT_CALLOC);
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_HEAP_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_HEAP_ALLOC_FAIL);
|
|
return NULL;
|
|
}
|
|
|
|
return (* Function)(Number, Size);
|
|
}
|
|
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
PVOID __cdecl
|
|
AVrfp_realloc (
|
|
IN PVOID Address,
|
|
IN SIZE_T Size
|
|
)
|
|
{
|
|
typedef PVOID (__cdecl * FUNCTION_TYPE) (PVOID, SIZE_T);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
|
|
AVRF_INDEX_MSVCRT_REALLOC);
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_HEAP_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_HEAP_ALLOC_FAIL);
|
|
return NULL;
|
|
}
|
|
|
|
return (* Function)(Address, Size);
|
|
}
|
|
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
VOID __cdecl
|
|
AVrfp_free (
|
|
IN PVOID Address
|
|
)
|
|
{
|
|
typedef VOID (__cdecl * FUNCTION_TYPE) (PVOID);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
|
|
AVRF_INDEX_MSVCRT_FREE);
|
|
|
|
(* Function)(Address);
|
|
}
|
|
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
PVOID __cdecl
|
|
AVrfp_new (
|
|
IN SIZE_T Size
|
|
)
|
|
{
|
|
typedef PVOID (__cdecl * FUNCTION_TYPE) (SIZE_T);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
|
|
AVRF_INDEX_MSVCRT_NEW);
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_HEAP_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_HEAP_ALLOC_FAIL);
|
|
return NULL;
|
|
}
|
|
|
|
return (* Function)(Size);
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
VOID __cdecl
|
|
AVrfp_delete (
|
|
IN PVOID Address
|
|
)
|
|
{
|
|
typedef VOID (__cdecl * FUNCTION_TYPE) (PVOID);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
|
|
AVRF_INDEX_MSVCRT_DELETE);
|
|
|
|
(* Function)(Address);
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
PVOID __cdecl
|
|
AVrfp_newarray (
|
|
IN SIZE_T Size
|
|
)
|
|
{
|
|
typedef PVOID (__cdecl * FUNCTION_TYPE) (SIZE_T);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
|
|
AVRF_INDEX_MSVCRT_NEWARRAY);
|
|
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_HEAP_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_HEAP_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_HEAP_ALLOC_FAIL);
|
|
return NULL;
|
|
}
|
|
|
|
return (* Function)(Size);
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
VOID __cdecl
|
|
AVrfp_deletearray (
|
|
IN PVOID Address
|
|
)
|
|
{
|
|
typedef VOID (__cdecl * FUNCTION_TYPE) (PVOID);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpMsvcrtThunks,
|
|
AVRF_INDEX_MSVCRT_DELETEARRAY);
|
|
|
|
(* Function)(Address);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////// oleaut32 BSTR allocation routines
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
BSTR
|
|
STDAPICALLTYPE
|
|
AVrfpSysAllocString(const OLECHAR * String)
|
|
{
|
|
typedef BSTR (STDAPICALLTYPE * FUNCTION_TYPE) (const OLECHAR *);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpOleaut32Thunks,
|
|
AVRF_INDEX_OLEAUT32_SYSALLOCSTRING);
|
|
|
|
BUMP_COUNTER (CNT_OLE_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_OLE_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_OLE_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_OLE_ALLOC_FAIL);
|
|
return NULL;
|
|
}
|
|
|
|
return (* Function)(String);
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
INT
|
|
STDAPICALLTYPE
|
|
AVrfpSysReAllocString(BSTR * BStr, const OLECHAR *String)
|
|
{
|
|
typedef INT (STDAPICALLTYPE * FUNCTION_TYPE) (BSTR *, const OLECHAR *);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpOleaut32Thunks,
|
|
AVRF_INDEX_OLEAUT32_SYSREALLOCSTRING);
|
|
|
|
BUMP_COUNTER (CNT_OLE_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_OLE_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_OLE_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_OLE_ALLOC_FAIL);
|
|
return FALSE;
|
|
}
|
|
|
|
return (* Function)(BStr, String);
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
BSTR
|
|
STDAPICALLTYPE
|
|
AVrfpSysAllocStringLen(const OLECHAR *String, UINT Length)
|
|
{
|
|
typedef BSTR (STDAPICALLTYPE * FUNCTION_TYPE) (const OLECHAR *, UINT);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpOleaut32Thunks,
|
|
AVRF_INDEX_OLEAUT32_SYSALLOCSTRINGLEN);
|
|
|
|
BUMP_COUNTER (CNT_OLE_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_OLE_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_OLE_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_OLE_ALLOC_FAIL);
|
|
return NULL;
|
|
}
|
|
|
|
return (* Function)(String, Length);
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
INT
|
|
STDAPICALLTYPE
|
|
AVrfpSysReAllocStringLen(BSTR * BStr, const OLECHAR * String, UINT Length)
|
|
{
|
|
typedef INT (STDAPICALLTYPE * FUNCTION_TYPE) (BSTR *, const OLECHAR *, UINT);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpOleaut32Thunks,
|
|
AVRF_INDEX_OLEAUT32_SYSREALLOCSTRINGLEN);
|
|
|
|
BUMP_COUNTER (CNT_OLE_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_OLE_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_OLE_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_OLE_ALLOC_FAIL);
|
|
return FALSE;
|
|
}
|
|
|
|
return (* Function)(BStr, String, Length);
|
|
}
|
|
|
|
#if defined(_X86_)
|
|
#pragma optimize("y", off) // disable FPO
|
|
#endif
|
|
BSTR
|
|
STDAPICALLTYPE
|
|
AVrfpSysAllocStringByteLen(LPCSTR psz, UINT len)
|
|
{
|
|
typedef BSTR (STDAPICALLTYPE * FUNCTION_TYPE) (LPCSTR, UINT);
|
|
FUNCTION_TYPE Function;
|
|
|
|
Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpOleaut32Thunks,
|
|
AVRF_INDEX_OLEAUT32_SYSALLOCSTRINGBYTELEN);
|
|
|
|
BUMP_COUNTER (CNT_OLE_ALLOC_CALLS);
|
|
|
|
if (SHOULD_FAULT_INJECT(CLS_OLE_ALLOC_APIS)) {
|
|
BUMP_COUNTER (CNT_OLE_ALLOC_FAILS);
|
|
CHECK_BREAK (BRK_OLE_ALLOC_FAIL);
|
|
return NULL;
|
|
}
|
|
|
|
return (* Function)(psz, len);
|
|
}
|
|
|