Leaked source code of windows server 2003
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.
 
 
 
 
 
 

385 lines
12 KiB

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
ntrtlbuffer3.c
Abstract:
Author:
Jay Krell (JayKrell) January 2002
Environment:
Revision History:
--*/
#include "ntrtlbuffer3.h"
typedef struct _REVEAL_RTL_BYTE_BUFFER3 {
PREVEAL_RTL_BYTE_BUFFER3 Self; // for heap allocated "mini dynamic"
PVOID Buffer;
SIZE_T RequestedSize;
SIZE_T AllocatedSize;
PVOID StaticBuffer;
SIZE_T StaticBufferSize;
PCRTL_BUFFER3_ALLOCATOR Traits;
PVOID TraitsContext;
} REVEAL_RTL_BYTE_BUFFER3, *PREVEAL_RTL_BYTE_BUFFER3;
typedef const REVEAL_RTL_BYTE_BUFFER3 * PCREVEAL_RTL_BYTE_BUFFER3;
PREVEAL_RTL_BYTE_BUFFER3
RtlpRevealByteBuffer3(
PRTL_BYTE_BUFFER3 OpaqueBuffer
)
{
return ((PREVEAL_RTL_BYTE_BUFFER3)OpaqueBuffer)->Self;
}
RTL_BUFFER3_RETURN
FASTCALL
RtlInitByteBuffer3(
ULONG Flags,
SIZE_T SizeofBuffer,
PRTL_BYTE_BUFFER3 Buffer,
SIZE_T SizeofStaticBuffer,
PBYTE StaticBuffer,
SIZE_T SizeofTraits,
PCRTL_BUFFER3_ALLOCATOR Traits,
PVOID TraitsContext
)
{
RTL_BUFFER3_RETURN Ret;
PREVEAL_RTL_BYTE_BUFFER3 Revealed;
BOOL NewStaticWithMiniDynamic;
if (SizeofBuffer < sizeof(*Buffer))
{
if (SizeofBuffer < (sizeof(ULONG_PTR)))
{
goto InvalidParameter;
}
if (Traits == NULL)
{
goto InvalidParameter;
}
if (!RTL_CONTAINS_FIELD(Traits, SizeofTraits, CanAllocate))
{
goto InvalidParameter;
}
if (!RTL_CONTAINS_FIELD(Traits, SizeofTraits, Allocate))
{
goto InvalidParameter;
}
if (!Traits->CanAllocate(TraitsContext))
{
goto InvalidParameter;
}
NewStaticWithMiniDynamic = (StaticBuffer == NULL && SizeofStaticBuffer != 0);
RevealedSize = sizeof(*Revealed;
if (NewStaticWithMiniDynamic)
{
RevealedSize += SizeofStaticBuffer;
}
Revealed = (PREVEAL_RTL_BYTE_BUFFER3)Traits->Allocate(TraitsContext, RevealedSize);
if (Revealed == NULL)
{
if (NewStaticWithMiniDynamic)
{
NewStaticWithMiniDynamic = FALSE;
Revealed = (PREVEAL_RTL_BYTE_BUFFER3)Traits->Allocate(TraitsContext, sizeof(*Revealed));
}
if (Revealed == NULL)
{
goto CallbackError;
}
}
if (NewStaticWithMiniDynamic)
{
StaticBuffer = (PBYTE)(Revealed + 1);
}
}
else
{
Revealed = (PREVEAL_RTL_BYTE_BUFFER3)Buffer;
}
((PREVEAL_RTL_BYTE_BUFFER3)OpaqueBuffer)->Self = Revealed;
Revealed->StaticBuffer = StaticBuffer;
Revealed->StaticBufferSize = SizeofStaticBuffer;
Revealed->RequestedSize = 0;
Revealed->AllocatedSize = SizeofStaticBuffer;
Revealed->Buffer = StaticBuffer;
Revealed->Traits = Traits;
Revealed->TraitsContext = TraitsContext;
Ret = RTL_BUFFER3_SUCCESS;
Exit:
return Ret;
InvalidParameter:
Ret = RTL_BUFFER3_INVALID_PARAMETER;
goto Exit;
CallbackError:
Ret = RTL_BUFFER3_CALLBACK_ERROR;
goto Exit;
}
BOOL FASTCALL RtlBuffer3Allocator_CanAllocate_False(PVOID VoidContext) { return FALSE; }
BOOL FASTCALL RtlBuffer3Allocator_CanAllocate_True(PVOID VoidContext) { return TRUE; }
BOOL FASTCALL RtlBuffer3Allocator_CanReallocate_False(PVOID VoidContext) { return FALSE; }
BOOL FASTCALL RtlBuffer3Allocator_CanReallocate_True(PVOID VoidContext) { return TRUE; }
#if defined(_WINBASE_)
#define RtlpBuffer3Allocator_Win32HeapGetHeap(c) \
(((c) != NULL && (c)->UsePrivateHeap) ? (c)->PrivateHeap : GetProcessHeap())
#define RtlpBuffer3Allocator_Win32HeapGetError(c) \
(((c) != NULL && (c)->UsePrivateError) ? (c)->PrivateOutOfMemoryError : ERROR_NO_MEMORY)
#define RtlpBuffer3Allocator_Win32HeapGetFlags(c) \
(((c) != NULL) ? (c)->HeapFlags : 0)
#define RtlpBuffer3Allocator_Win32HeapSetLastError(c) \
(((c) == NULL || (c)->DoNotSetLastError) ? ((void)0) : SetLastError(RtlpBuffer3Allocator_Win32HeapGetError(c)))
PVOID FASTCALL RtlBuffer3Allocator_Win32HeapAllocate(PVOID VoidContext, SIZE_T NumberOfBytes)
{
PVOID p;
PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
p = HeapAlloc(RtlpBuffer3Allocator_Win32HeapGetHeap(Context), RtlpBuffer3Allocator_Win32HeapGetFlags(Context), NumberOfBytes);
if (p == NULL)
RtlpBuffer3Allocator_Win32HeapSetLastError(Context);
return p;
}
VOID FASTCALL RtlBuffer3Allocator_Win32HeapFree(PVOID VoidContext, PVOID Pointer);
{
PVOID p;
PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
HeapFree(RtlpBuffer3Allocator_Win32HeapGetHeap(Context), RtlpBuffer3Allocator_Win32HeapGetFlags(Context), Pointer);
}
PVOID FASTCALL RtlBuffer3Allocator_Win32HeapReallocate(PVOID VoidContext, PVOID OldPointer, SIZE_T NewSize)
{
PVOID p;
PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
p = HeapReAlloc(RtlpBuffer3Allocator_Win32HeapGetHeap(Context), RtlpBuffer3Allocator_Win32HeapGetFlags(Context), OldPointer, NewSize);
if (p == NULL)
RtlpBuffer3Allocator_Win32HeapSetLastError(Context);
return p;
}
#endif
#if defined(_NTRTL_) || defined(_NTURTL_)
#if RTLBUFFER3_KERNELMODE
#define RtlpBuffer3Allocator_NtHeapGetHeap(c) \
(ASSERT((c) != NULL), ASSERT((c)->UsePrivateHeap), ASSERT((c)->PrivateHeap != NULL), (c)->PrivateHeap)
#define RtlpBuffer3Allocator_NtHeapGetFlags(c) \
(ASSERT((c) != NULL), (c)->HeapFlags)
#else
#define RtlpBuffer3Allocator_NtHeapGetHeap(c) \
(((c) != NULL && (c)->UsePrivateHeap) ? (c)->PrivateHeap : RtlProcessHeap())
#define RtlpBuffer3Allocator_NtHeapGetFlags(c) \
(((c) != NULL) ? (c)->HeapFlags : 0)
#endif
PVOID FASTCALL RtlBuffer3Allocator_NtHeapAllocate(PVOID VoidContext, SIZE_T NumberOfBytes)
{
PVOID p;
PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
p = RtlAllocateHeap(RtlpBuffer3Allocator_NtHeapGetHeap(Context), RtlpBuffer3Allocator_NtHeapGetFlags(Context), NumberOfBytes);
return p;
}
VOID FASTCALL RtlBuffer3Allocator_NtHeapFree(PVOID VoidContext, PVOID Pointer);
{
PVOID p;
PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
RtlFreeHeap(RtlpBuffer3Allocator_NtHeapGetHeap(Context), RtlpBuffer3Allocator_NtHeapGetFlags(Context), Pointer);
}
PVOID FASTCALL RtlBuffer3Allocator_NtHeapReallocate(PVOID VoidContext, PVOID OldPointer, SIZE_T NewSize)
{
#if RTLBUFFER3_KERNELMODE || !defined(_NTURTL_)
return NULL;
#else
PVOID p;
PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
p = RtlReAllocateHeap(RtlpBuffer3Allocator_NtHeapGetHeap(Context), RtlpBuffer3Allocator_NtHeapGetFlags(Context), OldPointer, NewSize);
return p;
#endif
}
#endif
SIZE_T FASTCALL * RtlBuffer3Allocator_FixedAllocationSize(PVOID VoidContext, SIZE_T CurrentAllocatedSize, SIZE_T RequiredSize)
{
return CurrentAllocatedSize;
}
SIZE_T FASTCALL * RtlBuffer3Allocator_DoublingAllocationSize(PVOID VoidContext, SIZE_T CurrentAllocatedSize, SIZE_T RequiredSize)
{
CurrentAllocatedSize += CurrentAllocatedSize;
return (RequiredSize >= CurrentAllocatedSize) ? RequiredSize : CurrentAllocatedSize;
}
SIZE_T FASTCALL * RtlBuffer3Allocator_MinimumAlocationSize(PVOID VoidContext, SIZE_T CurrentAllocatedSize, SIZE_T RequiredSize)
{
return RequiredSize;
}
//
// RtlAllocateStringRoutine is not exported outside of ntoskrnl.exe and ntdll.dll.
// RtlFreeStringRoutine is exported directly enough via RtlFreeUnicodeString.
//
// see base\ntdll\ldrinit.c and base\ntos\ex\pool.c for the definitions
// of RtlAllocateStringRoutine and RtlFreeStringRoutine.
//
VOID FASTCALL RtlBuffer3Allocator_NtStringFree(PVOID VoidContext, PVOID Pointer)
{
UNICODE_STRING UnicodeString;
UnicodeString.Buffer = (PWSTR)Pointer;
RtlFreeUnicodeString(&UnicodeString);
}
#if RTLBUFFER3_NTKERNEL || RTLBUFFER3_NTDLL
PVOID FASTCALL RtlBuffer3Allocator_NtStringAllocate(PVOID VoidContext, SIZE_T NumberOfBytes)
{
return (*RtlAllocateStringRoutine)(NumberOfBytes);
}
#elif RTLBUFFER3_USERMODE
PVOID FASTCALL RtlBuffer3Allocator_NtStringAllocate(PVOID VoidContext, SIZE_T NumberOfBytes)
{
return RtlAllocateHeap(RtlProcessHeap(), 0, NumberOfBytes);
}
#elif RTLBUFFER3_KERNELMODE
PVOID FASTCALL RtlBuffer3Allocator_NtStringAllocate(PVOID VoidContext, SIZE_T NumberOfBytes)
{
#undef ExAllocatePoolWithTag
return ExAllocatePoolWithTag(PagedPool,NumberOfBytes,'grtS');
}
#endif
#if RTLBUFFER3_KERNELMODE && (defined(_EX_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTOSP_) || defined(_WDM_) || defined(_NTHAL_))
#define RtlpBuffer3Allocator_NtkernelPool_GetWhichFunction(c) \
(((c) != NULL) ? (c)->WhichFunction : RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL)
#define RtlpBuffer3Allocator_NtkernelPool_GetTag(c) \
(((c) != NULL) ? (c)->Tag : 0)
#define RtlpBuffer3Allocator_NtkernelPool_GetType(c) \
(((c) != NULL) ? (c)->Type : NonPagedPool)
#define RtlpBuffer3Allocator_NtkernelPool_GetPriority(c) \
(((c) != NULL) ? (c)->Priority : NormalPoolPriority)
#undef ExAllocatePoolWithTag
#undef ExAllocatePool
#undef ExAllocatePoolWithQuota
#undef ExAllocatePoolWithQuotaTag
#undef ExFreePool
#undef ExFreePoolWithTag
PVOID FASTCALL RtlBuffer3Allocator_NtkernelPoolAllocate(PVOID VoidContext, SIZE_T NumberOfBytes)
{
PVOID p;
PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
switch (RtlpBuffer3Allocator_NtkernelPool_GetWhichFunction(Context))
{
default:
case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL:
p = ExAllocatePool(
RtlpBuffer3Allocator_NtkernelPool_GetType(Context),
NumberOfBytes
);
break;
case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_TAG:
p = ExAllocatePoolWithTag(
RtlpBuffer3Allocator_NtkernelPool_GetType(Context),
NumberOfBytes,
RtlpBuffer3Allocator_NtkernelPool_GetTag(Context)
);
break;
case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_QUOTA:
p = ExAllocatePoolWithQuota(
RtlpBuffer3Allocator_NtkernelPool_GetType(Context),
NumberOfBytes
);
break;
case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_QUOTA_TAG:
p = ExAllocatePoolWithQuotaTag(
RtlpBuffer3Allocator_NtkernelPool_GetType(Context),
NumberOfBytes,
RtlpBuffer3Allocator_NtkernelPool_GetTag(Context)
);
break;
case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_TAG_PRIORITY:
p = ExAllocatePoolWithTagPriority(
RtlpBuffer3Allocator_NtkernelPool_GetType(Context),
NumberOfBytes,
RtlpBuffer3Allocator_NtkernelPool_GetTag(Context),
RtlpBuffer3Allocator_NtkernelPool_GetPriority(Context)
);
break;
}
return p;
}
VOID FASTCALL RtlBuffer3Allocator_NtKernelPoolFree(PVOID VoidContext, PVOID Pointer)
{
PRTL_BUFFER3_ALLOCATOR_WIN32HEAP Context;
//
// ExFreePool/ExAllocatePoolWithTag, pretty unique among allocators, does not accept NULL.
//
if (Pointer == NULL)
return;
Context = (PRTL_BUFFER3_ALLOCATOR_WIN32HEAP)VoidContext;
switch (RtlpBuffer3Allocator_NtkernelPool_GetWhichFunction(Context))
{
default:
case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL:
case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_QUOTA:
ExFreePool(Pointer);
break;
case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_TAG:
case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_QUOTA_TAG:
case RTL_BUFFER3_ALLOCATOR_NTKERNELPOOL_ALLOCATE_EX_ALLOCATE_POOL_WITH_TAG_PRIORITY:
ExAllocatePoolWithTag(Pointer);
break;
}
}
#endif