mirror of https://github.com/lianthony/NT4.0
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.
315 lines
6.3 KiB
315 lines
6.3 KiB
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
pdict.cxx
|
|
|
|
Abstract:
|
|
|
|
Implements a dictionary for handling pointers.
|
|
|
|
Notes:
|
|
|
|
|
|
History:
|
|
|
|
Aug 25, 1994 RyszardK Created
|
|
|
|
----------------------------------------------------------------------------*/
|
|
|
|
#include <sysinc.h>
|
|
#include <rpc.h>
|
|
#include <rpcndr.h>
|
|
|
|
#include <ntsdexts.h>
|
|
#include <ntdbg.h>
|
|
|
|
extern "C" {
|
|
#include <ndrtypes.h>
|
|
#include <ndrp.h>
|
|
}
|
|
|
|
#include "bufout.hxx"
|
|
|
|
BOOL
|
|
PTR_DICT::IsInDictionary(
|
|
long Key
|
|
)
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Checks if the pointer withe given key is in the dictionary,
|
|
|
|
Arguments:
|
|
|
|
Offset - the offset of the pointer in the struct
|
|
|
|
Returns:
|
|
TRUE - is
|
|
FALSE - is not
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
Dict_Status Status;
|
|
|
|
POINTER_DESC Entry;
|
|
|
|
Entry.Offset = Key;
|
|
Entry.pMember = NULL;
|
|
|
|
Status = Dict_Find( &Entry );
|
|
|
|
if ( Status == EMPTY_DICTIONARY || Status == ITEM_NOT_FOUND )
|
|
return FALSE;
|
|
else
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void
|
|
PTR_DICT::Register(
|
|
long Offset,
|
|
POINTER * pMember
|
|
)
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Adds a pointer to the dictionary
|
|
|
|
Arguments:
|
|
|
|
Offset - the offset of the pointer in the struct
|
|
pMember - the pointer object
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
Dict_Status Status;
|
|
|
|
POINTER_DESC * pEntry = new POINTER_DESC;
|
|
|
|
pEntry->Offset = Offset;
|
|
pEntry->pMember = pMember;
|
|
|
|
Status = Dict_Find( pEntry );
|
|
|
|
switch( Status )
|
|
{
|
|
case EMPTY_DICTIONARY:
|
|
case ITEM_NOT_FOUND:
|
|
|
|
Dict_Insert( pEntry );
|
|
EntryCount++;
|
|
break;
|
|
|
|
default:
|
|
ABORT1( "Offset already in the dictionary? %x\n", Offset );
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
int
|
|
PTR_DICT::Compare(
|
|
pUserType pE1,
|
|
pUserType pE2
|
|
)
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Offset is the key that orders the entries.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
if( ((POINTER_DESC *)pE1)->Offset < ((POINTER_DESC *)pE2)->Offset )
|
|
return( 1 );
|
|
else
|
|
if( ((POINTER_DESC *)pE1)->Offset > ((POINTER_DESC *)pE2)->Offset )
|
|
return( -1 );
|
|
else
|
|
return( 0 );
|
|
}
|
|
|
|
POINTER_DESC *
|
|
PTR_DICT::GetFirst()
|
|
{
|
|
Dict_Status Status;
|
|
POINTER_DESC * pFirst = 0;
|
|
|
|
Status = Dict_Next( 0 );
|
|
|
|
if ( Status == SUCCESS )
|
|
pFirst = (POINTER_DESC *)Dict_Curr_Item();
|
|
|
|
return( pFirst );
|
|
}
|
|
|
|
POINTER_DESC *
|
|
PTR_DICT::GetNext()
|
|
{
|
|
Dict_Status Status;
|
|
POINTER_DESC *pCurr, *pNext = 0;
|
|
|
|
pCurr = (POINTER_DESC *)Dict_Curr_Item();
|
|
|
|
if ( pCurr )
|
|
{
|
|
Status = Dict_Next( pCurr );
|
|
if ( Status == SUCCESS )
|
|
pNext = (POINTER_DESC *)Dict_Curr_Item();
|
|
}
|
|
|
|
return( pNext );
|
|
}
|
|
|
|
POINTER_DESC *
|
|
PTR_DICT::GetPrev()
|
|
{
|
|
Dict_Status Status;
|
|
POINTER_DESC *pCurr, *pPrev = 0;
|
|
|
|
pCurr = (POINTER_DESC *)Dict_Curr_Item();
|
|
|
|
if ( pCurr )
|
|
{
|
|
Status = Dict_Prev( pCurr );
|
|
if ( Status == SUCCESS )
|
|
pPrev = (POINTER_DESC *)Dict_Curr_Item();
|
|
}
|
|
|
|
return( pPrev );
|
|
}
|
|
|
|
POINTER *
|
|
PTR_DICT::GetPointerMember( long BufferOffset )
|
|
{
|
|
Dict_Status Status;
|
|
POINTER_DESC Item;
|
|
POINTER_DESC *pCurr = 0;
|
|
POINTER * pMember = NULL;
|
|
|
|
Item.Offset = BufferOffset;
|
|
Status = Dict_Find( & Item );
|
|
|
|
switch( Status )
|
|
{
|
|
case EMPTY_DICTIONARY:
|
|
case ITEM_NOT_FOUND:
|
|
break;
|
|
|
|
default:
|
|
pCurr = (POINTER_DESC *) Dict_Curr_Item();
|
|
pMember = pCurr->pMember;
|
|
if ( BufferOffset != pCurr->Offset )
|
|
Print("Offset mismatch actual=%x, dict=%x\n",
|
|
BufferOffset,
|
|
pCurr->Offset );
|
|
break;
|
|
}
|
|
|
|
return( pMember );
|
|
}
|
|
|
|
void
|
|
PTR_DICT::AddDictEntries(
|
|
PTR_DICT * pDict )
|
|
{
|
|
if ( pDict->GetCount() )
|
|
{
|
|
POINTER_DESC * pDesc;
|
|
|
|
while ( pDict->GetNext() )
|
|
;
|
|
|
|
pDesc = (POINTER_DESC *)pDict->Dict_Curr_Item();
|
|
|
|
while ( pDesc )
|
|
{
|
|
Register( pDesc->Offset, pDesc->pMember );
|
|
|
|
pDesc = pDict->GetPrev();
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
PTR_DICT::DeleteDictMembers()
|
|
/*++
|
|
Deleting members themselves can't be a part of the dictionary destructor.
|
|
The reason is that the members describe pointers and the pointer's span
|
|
of life may depend on the parent object not on the current object that
|
|
would tak away its dictionary when desctructing itself.
|
|
In other words, only the topmost parent can remove the members after
|
|
printing them.
|
|
--*/
|
|
{
|
|
POINTER_DESC * pDesc;
|
|
unsigned short Count;
|
|
Dict_Status Status;
|
|
|
|
if ( (Count = GetCount()) == 0 )
|
|
return;
|
|
|
|
pDesc = (POINTER_DESC *)Dict_Curr_Item();
|
|
|
|
while ( pDesc )
|
|
{
|
|
Status = Dict_Delete( (void **) &pDesc );
|
|
if ( Status != ITEM_NOT_FOUND &&
|
|
Status != EMPTY_DICTIONARY &&
|
|
Status != NULL_ITEM )
|
|
{
|
|
delete pDesc->pMember;
|
|
pDesc = (POINTER_DESC *)Dict_Curr_Item();
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
PTR_DICT::OutputPointees(
|
|
NDR * pObject
|
|
)
|
|
/*
|
|
Deletes the pointer members after printing pointees.
|
|
*/
|
|
{
|
|
PTR_DICT * pParentDict = pObject->GetParentDict();
|
|
|
|
if ( pParentDict )
|
|
{
|
|
// Move members to parent dictionary to output pointees later.
|
|
|
|
pParentDict->AddDictEntries( this );
|
|
return;
|
|
}
|
|
|
|
if ( GetCount() )
|
|
{
|
|
POINTER_DESC *pDesc, *pDescDone;
|
|
|
|
while ( GetNext() )
|
|
;
|
|
|
|
pDesc = (POINTER_DESC *)Dict_Curr_Item();
|
|
|
|
IndentInc();
|
|
|
|
while ( pDesc )
|
|
{
|
|
pDesc->pMember->Output();
|
|
pDescDone = pDesc;
|
|
pDesc = GetPrev();
|
|
delete pDescDone->pMember;
|
|
}
|
|
|
|
IndentDec();
|
|
}
|
|
}
|