252 lines
5.2 KiB
C++
252 lines
5.2 KiB
C++
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
pointerq.cxx
|
|
|
|
Abstract :
|
|
|
|
This file contains the routines for the pointer queues
|
|
|
|
Author :
|
|
|
|
Mike Zoran mzoran Jun 2000.
|
|
|
|
Revision History :
|
|
|
|
---------------------------------------------------------------------*/
|
|
#include "ndrp.h"
|
|
#include "hndl.h"
|
|
#include "ndrole.h"
|
|
#include "attack.h"
|
|
#include "pointerq.h"
|
|
|
|
void
|
|
NDR32_POINTER_QUEUE_STATE::Free(
|
|
NDR_POINTER_QUEUE_ELEMENT *pElement
|
|
)
|
|
{
|
|
#if defined(DBG)
|
|
memset( pElement, 0xBD, NdrMaxPointerQueueElement);
|
|
#endif
|
|
|
|
pElement->pNext = pFreeList;
|
|
pFreeList = pElement;
|
|
}
|
|
|
|
NDR_POINTER_QUEUE_ELEMENT *
|
|
NDR32_POINTER_QUEUE_STATE::Allocate()
|
|
{
|
|
NDR_POINTER_QUEUE_ELEMENT *pNewElement;
|
|
if ( pFreeList )
|
|
{
|
|
pNewElement = pFreeList;
|
|
pFreeList = pNewElement->pNext;
|
|
}
|
|
else
|
|
{
|
|
pNewElement = InternalAllocate();
|
|
}
|
|
#if defined(DBG)
|
|
memset( pNewElement, 0xDB, NdrMaxPointerQueueElement );
|
|
#endif
|
|
return pNewElement;
|
|
}
|
|
|
|
|
|
void
|
|
NDR32_POINTER_QUEUE_STATE::FreeAll()
|
|
{
|
|
while ( pAllocationList )
|
|
{
|
|
AllocationElement *pThisAlloc = pAllocationList;
|
|
pAllocationList = pAllocationList->pNext;
|
|
I_RpcFree( pThisAlloc );
|
|
}
|
|
}
|
|
|
|
NDR_POINTER_QUEUE_ELEMENT *
|
|
NDR32_POINTER_QUEUE_STATE::InternalAllocate()
|
|
{
|
|
if ( !pAllocationList ||
|
|
(ItemsToAllocate == pAllocationList->ItemsAllocated ) )
|
|
{
|
|
|
|
struct AllocationElement *pElement =
|
|
(struct AllocationElement *)I_RpcAllocate( sizeof(AllocationElement) );
|
|
if ( !pElement )
|
|
{
|
|
RpcRaiseException( RPC_S_OUT_OF_MEMORY );
|
|
}
|
|
|
|
pElement->pNext = pAllocationList;
|
|
pElement->ItemsAllocated = 0;
|
|
pAllocationList = pElement;
|
|
}
|
|
|
|
return (NDR_POINTER_QUEUE_ELEMENT*)
|
|
(NDR_POINTER_QUEUE_ELEMENT*)pAllocationList->Data[pAllocationList->ItemsAllocated++];
|
|
|
|
}
|
|
|
|
#if defined(BUILD_NDR64)
|
|
|
|
NDR_POINTER_QUEUE_ELEMENT *
|
|
NDR64_POINTER_QUEUE_STATE::Allocate()
|
|
{
|
|
NDR_POINTER_QUEUE_ELEMENT *pNewElement;
|
|
if ( pProcContext->pQueueFreeList )
|
|
{
|
|
pNewElement = pProcContext->pQueueFreeList;
|
|
pProcContext->pQueueFreeList = pNewElement->pNext;
|
|
}
|
|
else
|
|
{
|
|
pNewElement = (NDR_POINTER_QUEUE_ELEMENT *)
|
|
NdrpAlloca( &pProcContext->AllocateContext,
|
|
NdrMaxPointerQueueElement );
|
|
}
|
|
#if defined(DBG)
|
|
memset( pNewElement, 0xDB, NdrMaxPointerQueueElement );
|
|
#endif
|
|
|
|
return pNewElement;
|
|
}
|
|
|
|
void
|
|
NDR64_POINTER_QUEUE_STATE::Free(
|
|
NDR_POINTER_QUEUE_ELEMENT *pElement
|
|
)
|
|
{
|
|
#if defined(DBG)
|
|
memset( pElement, 0xBD, NdrMaxPointerQueueElement);
|
|
#endif
|
|
|
|
pElement->pNext = pProcContext->pQueueFreeList;
|
|
pProcContext->pQueueFreeList = pElement;
|
|
}
|
|
|
|
#endif
|
|
|
|
inline NDR_POINTER_QUEUE::STORAGE::STORAGE( ) :
|
|
pHead(NULL),
|
|
pPrevHead(NULL),
|
|
pPrevInsertPointer(NULL),
|
|
pInsertPointer(&pHead)
|
|
{
|
|
}
|
|
|
|
inline void NDR_POINTER_QUEUE::STORAGE::MergeContext()
|
|
{
|
|
// Add old list to end of this list.
|
|
if ( pPrevHead )
|
|
{
|
|
// Append list
|
|
*pInsertPointer = pPrevHead;
|
|
// Set insert pointer to end of old list
|
|
pInsertPointer = pPrevInsertPointer;
|
|
}
|
|
|
|
pPrevHead = NULL;
|
|
pPrevInsertPointer = NULL;
|
|
}
|
|
|
|
inline void NDR_POINTER_QUEUE::STORAGE::NewContext()
|
|
{
|
|
|
|
pPrevHead = pHead;
|
|
pPrevInsertPointer = pInsertPointer;
|
|
|
|
pHead = NULL;
|
|
pInsertPointer = &pHead;
|
|
|
|
}
|
|
|
|
inline void NDR_POINTER_QUEUE::STORAGE::InsertTail( NDR_POINTER_QUEUE_ELEMENT *pNewNode )
|
|
{
|
|
*pInsertPointer = pNewNode;
|
|
pNewNode->pNext = NULL;
|
|
pInsertPointer = &pNewNode->pNext;
|
|
}
|
|
|
|
inline NDR_POINTER_QUEUE_ELEMENT *NDR_POINTER_QUEUE::STORAGE::RemoveHead()
|
|
{
|
|
|
|
NDR_POINTER_QUEUE_ELEMENT *pOldHead = pHead;
|
|
|
|
if (!pHead)
|
|
{
|
|
return pHead;
|
|
}
|
|
|
|
if ( !pHead->pNext )
|
|
{
|
|
// Last item, reinitialize list.
|
|
pHead = NULL;
|
|
pInsertPointer = &pHead->pNext;
|
|
}
|
|
else
|
|
{
|
|
pHead = pHead->pNext;
|
|
}
|
|
|
|
return pOldHead;
|
|
}
|
|
|
|
|
|
|
|
#if defined(DBG)
|
|
ulong NdrPointerQueueLogLevel;
|
|
#endif
|
|
|
|
void NDR_POINTER_QUEUE::Enque( NDR_POINTER_QUEUE_ELEMENT * pElement )
|
|
{
|
|
|
|
Storage.InsertTail( pElement );
|
|
|
|
#if defined(DBG)
|
|
if ( NdrPointerQueueLogLevel )
|
|
{
|
|
DbgPrint( "Queing Element %p\n", pElement );
|
|
pElement->Print();
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
void NDR_POINTER_QUEUE::Dispatch()
|
|
{
|
|
while ( 1 )
|
|
{
|
|
|
|
NDR_POINTER_QUEUE_ELEMENT *pHead = Storage.RemoveHead();
|
|
|
|
if ( !pHead )
|
|
return;
|
|
|
|
#if defined(DBG)
|
|
if ( NdrPointerQueueLogLevel )
|
|
{
|
|
DbgPrint( "Dispatching Element: %p\n", pHead );
|
|
pHead->Print();
|
|
}
|
|
#endif
|
|
|
|
Storage.NewContext();
|
|
pHead->Dispatch( pStubMsg );
|
|
pQueueState->Free( pHead );
|
|
Storage.MergeContext();
|
|
|
|
}
|
|
}
|
|
|
|
NDR_POINTER_QUEUE::NDR_POINTER_QUEUE( PMIDL_STUB_MESSAGE pNewStubMsg,
|
|
NDR_POINTER_QUEUE_STATE *pNewState ) :
|
|
pStubMsg( pNewStubMsg ),
|
|
Storage(),
|
|
pQueueState(pNewState)
|
|
{
|
|
}
|