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.
 
 
 
 
 
 

431 lines
9.6 KiB

/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
ntrtlbuffer2.c
Abstract:
Author:
Jay Krell (JayKrell) January 2002
Environment:
Revision History:
--*/
#include "ntrtlbuffer2.h"
#include "ntrtlbuffer2p.h"
#if DBG
VOID
FASTCALL
RtlpAssertBuffer2Consistency(
PPRIVATE_RTL_BUFFER2 Buffer
)
{
ASSERT(Buffer->AllocatedSize >= Buffer->RequestedSize);
if (Buffer->Buffer == Buffer->StaticBuffer) {
ASSERT(Buffer->AllocatedSize == Buffer->StaticBufferSize);
}
}
PVOID
FASTCALL
RtlpFindNonNullInPointerArray(
PVOID * PointerArray,
SIZE_T SizeOfArray
)
{
SIZE_T i;
PVOID p;
p = NULL;
for ( i = 0 ; i != SizeOfArray ; ++i )
{
p = PointerArray[i];
if (p != NULL)
{
break;
}
}
return p;
}
NTSTATUS
FASTCALL
RtlpValidateBuffer2Class(
PPRIVATE_RTL_BUFFER2 Class
)
{
FN_PROLOG();
PVOID Allocate[5] = { NULL, NULL, NULL, NULL, NULL };
PVOID Free[2] = { NULL, NULL };
PRTL_BUFFER2_CLASS_UALLOCATOR u;
PVOID HeapHandle;
BOOL NeedHeapHandle;
BOOL Failed;
CHECK_PARAMETER(Buffer != NULL);
Failed = FALSE;
NeedHeapHandle = FALSE;
u = &Class->uAllocator;
switch (Class->AllocatorType)
{
default:
DbgPrint("%s: bad Class->AllocatorType.\n", __FUNCTION__);
Allocate[0] = (PVOID)1;
Free[0] = (PVOID)1;
Failed = TRUE;
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_NTRTL_STRING_CALLBACKS:
Allocate[0] = u->NtrtlStringRoutines.Allocate;
Free[0] = u->NtrtlStringRoutines.Free;
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_POOL_CALLBACKS:
#if defined(_EX_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTOSP_) || defined(_WDM_) || defined(_NTHAL_)
Allocate[0] = u->NtkernelPool.Allocate;
Allocate[1] = u->NtkernelPool.AllocateWithQuota;
Allocate[2] = u->NtkernelPool.AllocateWithTag;
Allocate[3] = u->NtkernelPool.AllocateWithQuotaTag;
Allocate[4] = u->NtkernelPool.AllocateWithTagPriority;
Free[0] = u->NtkernelPool.Free;
Free[1] = u->NtkernelPool.FreeWithTag;
#else
DbgPrint("%s: You need to compile this code with more headers.\n", __FUNCTION__);
ORIGINATE_INVALID_PARAMETER();
#endif
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_NTRTL_HEAP_CALLBACKS:
Allocate[0] = u->NtrtlHeap.Allocate;
Free[0] = u->NtrtlHeap.Free;
NeadHeapHandle = TRUE;
HeapHandle = u->NtrtlHeap.HeapHandle;
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_WIN32_HEAP_CALLBACKS:
Allocate[0] = u->Win32Heap.Allocate;
Free[0] = u->Win32Heap.Free;
NeadHeapHandle = TRUE;
HeapHandle = u->Win32Heap.HeapHandle;
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_WIN32_CRT_CALLBACKS:
Allocate[0] = u->Crt.malloc;
Free[0] = u->Crt.free;
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_IMALLOC:
Allocate[0] = u->Malloc
Free[0] = u->Malloc;
break;
}
if (NeedHeapHandle && HeapHandle == NULL)
{
DbgPrint("%s: NeadHeapHandle && HeapHandle == NULL\n", __FUNCTION__);
Failed = TRUE;
}
// ensure we have an allocate and a free routine
if (RtlpFindNonNullInPointerArray(Allocate, RTL_NUMBER_OF(Allocate)) == NULL)
{
DbgPrint("%s: missing allocate routine\n", __FUNCTION__);
Failed = TRUE;
}
// ensure we have an allocate and a free routine
if (RtlpFindNonNullInPointerArray(Free, RTL_NUMBER_OF(Free)) == NULL)
{
DbgPrint("%s: missing free routine\n", __FUNCTION__);
Failed = TRUE;
}
if (Failed)
{
goto Exit;
}
FN_EPILOG();
}
VOID
FASTCALL
RtlpBuffer2ClassFree(
PRTL_BUFFER2_CLASS Class,
PVOID p
)
{
PRTL_BUFFER2_CLASS_UALLOCATOR u;
if (p == NULL) {
goto Exit;
}
u = &Class->uAllocator;
switch (Class->AllocatorType)
{
default:
DbgPrint("%s: bad Class->AllocatorType.\n", __FUNCTION__);
ORIGINATE_INVALID_PARAMETER();
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_NTRTL_STRING_CALLBACKS:
(*u->NtrtlStringRoutines.Free)(
p);
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_POOL_CALLBACKS:
#if defined(_EX_) || defined(_NTDDK_) || defined(_NTIFS_) || defined(_NTOSP_) || defined(_WDM_) || defined(_NTHAL_)
ASSERT(u->NtkernelPool.FreeWithTag != NULL || u->NtkernelPool.Free != NULL);
if (u->NtkernelPool.FreeWithTag != NULL)
{
(*u->NtkernelPool.FreeWithTag)(p, u->NtkernelPool.Tag);
}
else if (u->NtkernelPool.Free != NULL)
{
(*u->NtkernelPool.Free)(p);
}
#else
DbgPrint("%s: You need to compile this code with more headers.\n", __FUNCTION__);
ORIGINATE_INVALID_PARAMETER();
#endif
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_NTRTL_HEAP_CALLBACKS:
(*u->NtrtlHeap.Free)(
u->NtrtlHeap.HeapHandle,
0,
p);
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_WIN32_HEAP_CALLBACKS:
(*u->Win32Heap.Free)(
u->Win32Heap.HeapHandle,
0,
p);
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_WIN32_CRT_CALLBACKS:
(*u->Crt.Free)(
p);
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_IMALLOC:
break;
}
Exit:
return;
}
BOOL
FASTCALL
RtlpBuffer2ClassCanReallocate(
PRTL_BUFFER2_CLASS Class
)
{
PVOID * pp;
PRTL_BUFFER2_CLASS_UALLOCATOR u;
u = &Class->uAllocator;
switch (Class->AllocatorType)
{
default:
ASSERT(FALSE);
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_NTRTL_STRING_CALLBACKS:
case RTL_BUFFER2_CLASS_ALLOCATOR_POOL_CALLBACKS:
pp = NULL; // FALSE
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_NTRTL_HEAP_CALLBACKS:
pp = (PVOID*)&u->NtrtlHeap.Reallocate;
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_WIN32_HEAP_CALLBACKS:
pp = (PVOID*)&u->Win32Heap.Reallocate;
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_WIN32_CRT_CALLBACKS:
pp = (PVOID*)&u->Crt.Reallocate;
break;
case RTL_BUFFER2_CLASS_ALLOCATOR_IMALLOC:
pp = (PVOID*)&pp; // TRUE
break;
}
return (pp != NULL && *pp != NULL);
}
RETURN_TYPE
NTAPI
RtlEnsureBufferSizeEx2(
PRTL_BUFFER2 Buffer,
SIZE_T Size
OUT PVOID * p OPTIONAL
)
{
FN_PROLOG();
CHECK_PARAMETER(Buffer != NULL);
if (p != NULL) {
*p = NULL;
}
Ret = RtlEnsureBufferSize2(Buffer, Size);
if (MY_FAILED(Ret)) {
goto Exit;
}
if (p != NULL) {
*p = RtlpGetBuffer2(Buffer);
}
FN_EPILOG();
}
PVOID
FASTCALL
RtlpBuffer2ClassAllocate(
PRTL_BUFFER2_CLASS Class,
SIZE_T Size
)
{
PVOID p;
switch (p
p = NULL;
Exit:
return p;
}
VOID
FASTCALL
RtlpBuffer2ClassError(
PRTL_BUFFER2_CLASS Class
)
{
}
RETURN_TYPE
NTAPI
RtlpInitBuffer2(
PPRIVATE_RTL_BUFFER2 Buffer,
struct _RTL_BUFFER_CLASS * Class,
PVOID StaticBuffer,
SIZE_T StaticBufferSize
)
{
FN_PROLOG();
Ret = RtlpValidateBuffer2Class(Class);
if (MY_FAILED(Ret)) {
goto Exit;
}
if (StaticBufferSize != 0 && StaticBuffer == NULL) {
//
// This could mean do an initial allocation.
//
// Status = RtlpBuffer2ClassAllocate(Class, StaticBufferSize, &StaticBuffer);
// if (!NT_SUCCESS(Status)) {
// goto Exit;
// }
//
ORIGINATE_INVALID_PARAMETER();
}
Buffer->Buffer = StaticBuffer;
Buffer->StaticBuffer = StaticBuffer;
Buffer->StaticBufferSize = StaticBufferSize;
Buffer->AllocatedSize = StaticBufferSize;
Buffer->RequestedSize = 0;
Buffer->Class = Class;
RtlpAssertBuffer2Consistency(Buffer);
FN_EPILOG();
}
RETURN_TYPE
NTAPI
RtlInitBuffer2(
PRTL_BUFFER2 OpaqueBuffer,
struct _RTL_BUFFER_CLASS * Class,
PVOID StaticBuffer,
SIZE_T StaticBufferSize
)
{
return RtlpInitBuffer2((PPRIVATE_RTL_BUFFER2)OpaqueBuffer, Class, StaticBuffer, StaticBufferSize);
}
VOID
FASTCALL
RtlpFreeBuffer2(
PPRIVATE_RTL_BUFFER2 Buffer
)
{
FN_PROLOG();
PRIVATE_RTL_BUFFER2 Local;
RtlpAssertBuffer2Consistency(Buffer);
Local.StaticBuffer = Buffer->StaticBuffer;
Local.Buffer = Buffer->Buffer;
Local.Class = Buffer->Class;
if (Local.Buffer != Local.StaticBuffer) {
RtlpBuffer2ClassFree(Local.Class, Local.Buffer);
}
Ret = RtlpInitBuffer2(Buffer, Local.Class, Local.StaticBuffer, Buffer->StaticBufferSize);
ASSERT(MY_SUCCESS(Ret));
}
VOID
FASTCALL
RtlFreeBuffer2(
PRTL_BUFFER2 OpaqueBuffer
)
{
RtlpFreeBuffer2((PPRIVATE_RTL_BUFFER2)OpaqueBuffer);
}
SIZE_T
FASTCALL
RtlGetAllocatedBufferSize2(
PRTL_BUFFER2 Buffer,
)
{
ASSERT(Buffer != NULL);
return RtlpGetAllocatedBufferSize2(Buffer);
}
SIZE_T
FASTCALL
RtlGetRequestedBufferSize2(
PRTL_BUFFER2 Buffer,
OUT PSIZE_T Size
)
{
ASSERT(Buffer != NULL);
return RtlpGetRequestedBufferSize2(Buffer);
}
PVOID
FASTCALL
RtlGetBuffer2(
PRTL_BUFFER2 Buffer
)
{
ASSERT(Buffer != NULL);
return RtlpGetBuffer2(Buffer);
}