835 lines
19 KiB
C++
835 lines
19 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 1997.
|
||
|
//
|
||
|
// File: lht.cxx
|
||
|
//
|
||
|
// Contents: Context handle management for servers
|
||
|
//
|
||
|
// Classes:
|
||
|
//
|
||
|
// Functions:
|
||
|
//
|
||
|
// History: 1-31-97 RichardW Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include <lsapch.hxx>
|
||
|
|
||
|
#include "sht.hxx"
|
||
|
#include "lht.hxx"
|
||
|
|
||
|
//
|
||
|
// Due to the high number of connections for servers, the client context list
|
||
|
// for a particular session could grow into the thousands. At that stage, a
|
||
|
// linear list that is searched to validate a handle is prohibitively expensive.
|
||
|
//
|
||
|
// Thus, the faster, if more expensive to set up and add handle package
|
||
|
//
|
||
|
|
||
|
HP_INITIALIZE_FN LhtInitialize ;
|
||
|
HP_CREATE_FN LhtCreate ;
|
||
|
HP_DELETE_FN LhtDelete ;
|
||
|
HP_ADD_HANDLE_FN LhtAddHandle ;
|
||
|
HP_DELETE_HANDLE_FN LhtDeleteHandle ;
|
||
|
HP_VALIDATE_HANDLE_FN LhtValidateHandle ;
|
||
|
HP_REF_HANDLE_FN LhtRefHandle ;
|
||
|
HP_DEREF_HANDLE_KEY_FN LhtDerefHandleKey ;
|
||
|
HP_GET_HANDLE_CONTEXT_FN LhtGetHandleContext ;
|
||
|
HP_RELEASE_CONTEXT_FN LhtReleaseContext ;
|
||
|
|
||
|
HANDLE_PACKAGE LargeHandlePackage = {
|
||
|
sizeof( LARGE_HANDLE_TABLE ),
|
||
|
LhtInitialize,
|
||
|
LhtCreate,
|
||
|
LhtDelete,
|
||
|
LhtAddHandle,
|
||
|
LhtDeleteHandle,
|
||
|
LhtValidateHandle,
|
||
|
LhtRefHandle,
|
||
|
LhtDerefHandleKey,
|
||
|
LhtGetHandleContext,
|
||
|
LhtReleaseContext
|
||
|
};
|
||
|
|
||
|
|
||
|
ULONG LhtFastMem ;
|
||
|
ULONG LhtShiftValues[] = { 4, 12, 16, 20 };
|
||
|
|
||
|
|
||
|
#define IndexFromHandle( Level, Handle ) \
|
||
|
( ( ((PSecHandle) Handle)->dwUpper >> LhtShiftValues[ Level ] ) & HANDLE_TABLE_MASK )
|
||
|
|
||
|
#define LhtLockTable( t ) \
|
||
|
if ( (((PLARGE_HANDLE_TABLE) t)->Flags & LHT_NO_SERIALIZE ) == 0 ) \
|
||
|
{ \
|
||
|
RtlEnterCriticalSection( &((PLARGE_HANDLE_TABLE)t)->Lock ); \
|
||
|
}
|
||
|
|
||
|
#define LhtUnlockTable( t ) \
|
||
|
if ( (((PLARGE_HANDLE_TABLE) t)->Flags & LHT_NO_SERIALIZE ) == 0 ) \
|
||
|
{ \
|
||
|
RtlLeaveCriticalSection( &((PLARGE_HANDLE_TABLE)t)->Lock ); \
|
||
|
}
|
||
|
|
||
|
|
||
|
#define LHT_ACTION_ADDREF 0
|
||
|
#define LHT_ACTION_DELREF 1
|
||
|
#define LHT_ACTION_FORCEDEL 2
|
||
|
#define LHT_ACTION_VALIDATE 3
|
||
|
#define LHT_ACTION_ADDHANDLE 4
|
||
|
#define LHT_ACTION_DELHANDLE 5
|
||
|
|
||
|
#define LHT_ACTION_MASK 0x0000FFFF
|
||
|
#define LHT_ACTION_LOCKED 0x00010000
|
||
|
#define LHTP_DEREF_NOT_DEL 0x10000000
|
||
|
#define LHTP_HANDLE_CHECKED 0x20000000
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LhtInitialize
|
||
|
//
|
||
|
// Synopsis: Initializes the LHT handle package
|
||
|
//
|
||
|
// Arguments: (none)
|
||
|
//
|
||
|
// History: 2-03-97 RichardW Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL
|
||
|
LhtInitialize(
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
return TRUE ;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LhtCreate
|
||
|
//
|
||
|
// Synopsis: Creates a large handle table. The table is referenced through
|
||
|
// the returned pointer
|
||
|
//
|
||
|
// Arguments: [Flags] -- Flags as defined by handle.hxx
|
||
|
//
|
||
|
// History: 2-03-97 RichardW Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
PVOID
|
||
|
LhtCreate(
|
||
|
IN ULONG Flags,
|
||
|
IN PVOID HandleTable,
|
||
|
IN PHP_ENUM_CALLBACK_FN Callback
|
||
|
)
|
||
|
{
|
||
|
PLARGE_HANDLE_TABLE Table ;
|
||
|
ULONG i;
|
||
|
|
||
|
if ( HandleTable )
|
||
|
{
|
||
|
Table = (PLARGE_HANDLE_TABLE) HandleTable ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Table = (PLARGE_HANDLE_TABLE) LsapAllocatePrivateHeap( sizeof( LARGE_HANDLE_TABLE ) );
|
||
|
}
|
||
|
|
||
|
if ( Table )
|
||
|
{
|
||
|
Table->Tag = LHT_TAG ;
|
||
|
Table->Flags = 0 ;
|
||
|
|
||
|
Table->Flags = (Flags & HANDLE_PACKAGE_GENERAL_FLAGS);
|
||
|
|
||
|
|
||
|
if ( Flags & HANDLE_PACKAGE_CALLBACK_ON_DELETE )
|
||
|
{
|
||
|
Table->DeleteCallback = Callback ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Table->DeleteCallback = NULL ;
|
||
|
}
|
||
|
|
||
|
if ( HandleTable )
|
||
|
{
|
||
|
Table->Flags |= LHT_NO_FREE ;
|
||
|
}
|
||
|
|
||
|
Table->Depth = 0 ;
|
||
|
|
||
|
|
||
|
if ( ( Flags & LHT_NO_SERIALIZE ) == 0 )
|
||
|
{
|
||
|
NTSTATUS Status = RtlInitializeCriticalSection( &Table->Lock );
|
||
|
|
||
|
if (!NT_SUCCESS(Status))
|
||
|
{
|
||
|
if ( !HandleTable )
|
||
|
{
|
||
|
LsapFreePrivateHeap( Table );
|
||
|
}
|
||
|
|
||
|
Table = NULL ;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( Table )
|
||
|
{
|
||
|
|
||
|
for ( i = 0 ; i < HANDLE_TABLE_SIZE ; i++ )
|
||
|
{
|
||
|
SmallHandlePackage.Create( Flags | HANDLE_PACKAGE_NO_SERIALIZE,
|
||
|
& Table->Lists[i],
|
||
|
Callback );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return Table ;
|
||
|
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LhtpDeleteTable
|
||
|
//
|
||
|
// Synopsis: Delete table worker function
|
||
|
//
|
||
|
// Arguments: [Table] --
|
||
|
// [Callback] --
|
||
|
//
|
||
|
// History: 4-15-97 RichardW Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID
|
||
|
LhtpDeleteTable(
|
||
|
PLARGE_HANDLE_TABLE Table,
|
||
|
PHP_ENUM_CALLBACK_FN Callback
|
||
|
)
|
||
|
{
|
||
|
ULONG Index ;
|
||
|
PSEC_HANDLE_ENTRY Entry ;
|
||
|
PLIST_ENTRY Scan ;
|
||
|
|
||
|
LhtLockTable( Table );
|
||
|
|
||
|
for ( Index = 0 ; Index < HANDLE_TABLE_SIZE ; Index++ )
|
||
|
{
|
||
|
if ( Table->Lists[Index].Flags & LHT_SUB_TABLE )
|
||
|
{
|
||
|
LhtpDeleteTable( (PLARGE_HANDLE_TABLE) Table->Lists[Index].List.Flink,
|
||
|
Callback );
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SmallHandlePackage.Delete( &Table->Lists[ Index ], Callback );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LhtUnlockTable( Table );
|
||
|
|
||
|
if ( (Table->Flags & LHT_NO_SERIALIZE) == 0 )
|
||
|
{
|
||
|
RtlDeleteCriticalSection( &Table->Lock );
|
||
|
}
|
||
|
|
||
|
if ( ( Table->Flags & LHT_NO_FREE ) == 0 )
|
||
|
{
|
||
|
LsapFreePrivateHeap( Table );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LhtDelete
|
||
|
//
|
||
|
// Synopsis: Delete a table
|
||
|
//
|
||
|
// Arguments: [HandleTable] --
|
||
|
// [Callback] --
|
||
|
//
|
||
|
// History: 4-15-97 RichardW Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL
|
||
|
LhtDelete(
|
||
|
PVOID HandleTable,
|
||
|
PHP_ENUM_CALLBACK_FN Callback
|
||
|
)
|
||
|
{
|
||
|
PLARGE_HANDLE_TABLE Table ;
|
||
|
|
||
|
Table = (PLARGE_HANDLE_TABLE) HandleTable ;
|
||
|
|
||
|
LhtLockTable( Table );
|
||
|
|
||
|
Table->Flags |= LHT_DELETE_PENDING ;
|
||
|
|
||
|
LhtpDeleteTable( Table, Callback );
|
||
|
|
||
|
return TRUE ;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LhtpFindHandle
|
||
|
//
|
||
|
// Synopsis: Worker function that grovels a handle table
|
||
|
//
|
||
|
// Arguments: [HandleTable] -- Table to scan
|
||
|
// [Handle] -- handle to search for
|
||
|
// [Action] -- action to take on the handle record
|
||
|
//
|
||
|
// History: 2-03-97 RichardW Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
PSEC_HANDLE_ENTRY
|
||
|
LhtpFindHandle(
|
||
|
PVOID HandleTable,
|
||
|
PSecHandle Handle,
|
||
|
ULONG Action,
|
||
|
PBOOL Removed,
|
||
|
PVOID * FinalTable OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
PLARGE_HANDLE_TABLE Table ;
|
||
|
PSEC_HANDLE_ENTRY Entry ;
|
||
|
PLIST_ENTRY Scan ;
|
||
|
ULONG Index ;
|
||
|
BOOL Locked ;
|
||
|
|
||
|
Table = (PLARGE_HANDLE_TABLE) HandleTable ;
|
||
|
|
||
|
LhtLockTable( Table );
|
||
|
|
||
|
Entry = NULL ;
|
||
|
|
||
|
while ( TRUE )
|
||
|
{
|
||
|
Index = (ULONG) IndexFromHandle( Table->Depth, Handle );
|
||
|
|
||
|
if ( Table->Lists[ Index ].Flags & LHT_SUB_TABLE )
|
||
|
{
|
||
|
Table = (PLARGE_HANDLE_TABLE) Table->Lists[ Index ].List.Flink ;
|
||
|
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
Entry = ShtpFindHandle( &Table->Lists[ Index ], Handle, Action, Removed );
|
||
|
|
||
|
if ( FinalTable )
|
||
|
{
|
||
|
*FinalTable = &Table->Lists[ Index ] ;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
Table = (PLARGE_HANDLE_TABLE) HandleTable ;
|
||
|
|
||
|
LhtUnlockTable( Table );
|
||
|
|
||
|
return Entry ;
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LhtpConvertSmallToLarge
|
||
|
//
|
||
|
// Synopsis: Worker to convert small tables to large
|
||
|
//
|
||
|
// Arguments: [Small] --
|
||
|
// [Large] --
|
||
|
//
|
||
|
// History: 7-08-97 RichardW Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL
|
||
|
LhtpConvertSmallToLarge(
|
||
|
PSMALL_HANDLE_TABLE Small,
|
||
|
PLARGE_HANDLE_TABLE Large
|
||
|
)
|
||
|
{
|
||
|
ULONG NewIndex ;
|
||
|
PSEC_HANDLE_ENTRY Entry ;
|
||
|
|
||
|
while ( Entry = ShtpPopHandle( Small ) )
|
||
|
{
|
||
|
NewIndex = (ULONG) IndexFromHandle( Large->Depth, &(Entry->Handle) );
|
||
|
|
||
|
ShtpInsertHandle( &Large->Lists[ NewIndex ], Entry );
|
||
|
|
||
|
}
|
||
|
|
||
|
return TRUE ;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LhtpExpandTable
|
||
|
//
|
||
|
// Synopsis: Expands the given index into its own table
|
||
|
//
|
||
|
// Effects: New table associated with given index
|
||
|
//
|
||
|
// Arguments: [Table] -- Source table
|
||
|
// [Index] -- Source index
|
||
|
//
|
||
|
// Requires: Table must be write-locked
|
||
|
//
|
||
|
// History: 1-31-97 RichardW Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL
|
||
|
LhtpExpandTable(
|
||
|
PLARGE_HANDLE_TABLE Table,
|
||
|
ULONG Index
|
||
|
)
|
||
|
{
|
||
|
PLARGE_HANDLE_TABLE NewTable ;
|
||
|
PLIST_ENTRY List;
|
||
|
ULONG NewFlags ;
|
||
|
|
||
|
NewFlags = HANDLE_PACKAGE_NO_SERIALIZE ;
|
||
|
|
||
|
if ( Table->DeleteCallback )
|
||
|
{
|
||
|
NewFlags |= HANDLE_PACKAGE_CALLBACK_ON_DELETE ;
|
||
|
}
|
||
|
|
||
|
NewTable = (PLARGE_HANDLE_TABLE) LhtCreate( NewFlags |
|
||
|
LHT_CHILD,
|
||
|
NULL,
|
||
|
Table->DeleteCallback );
|
||
|
|
||
|
if ( !NewTable )
|
||
|
{
|
||
|
return FALSE ;
|
||
|
}
|
||
|
|
||
|
NewTable->Depth = Table->Depth + 1 ;
|
||
|
|
||
|
NewTable->Parent = Table ;
|
||
|
|
||
|
NewTable->IndexOfParent = Index ;
|
||
|
|
||
|
LhtpConvertSmallToLarge( &Table->Lists[ Index ], NewTable );
|
||
|
|
||
|
Table->Lists[ Index ].List.Flink = (PLIST_ENTRY) NewTable ;
|
||
|
|
||
|
Table->Lists[ Index ].Flags = LHT_SUB_TABLE ;
|
||
|
|
||
|
return TRUE ;
|
||
|
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LhtConvertSmallToLarge
|
||
|
//
|
||
|
// Synopsis: Converts a small handle table to a large one
|
||
|
//
|
||
|
// Arguments: [Small] --
|
||
|
//
|
||
|
// History: 7-08-97 RichardW Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
PVOID
|
||
|
LhtConvertSmallToLarge(
|
||
|
PVOID Small
|
||
|
)
|
||
|
{
|
||
|
PLARGE_HANDLE_TABLE Large ;
|
||
|
PSMALL_HANDLE_TABLE SmallTable = (PSMALL_HANDLE_TABLE) Small ;
|
||
|
PULONG Tag ;
|
||
|
|
||
|
Tag = (PULONG) Small ;
|
||
|
|
||
|
if ( *Tag == LHT_TAG )
|
||
|
{
|
||
|
return Small ;
|
||
|
}
|
||
|
|
||
|
if ( *Tag != SHT_TAG )
|
||
|
{
|
||
|
return NULL ;
|
||
|
}
|
||
|
|
||
|
Large = (PLARGE_HANDLE_TABLE) LhtCreate( (SmallTable->DeleteCallback ?
|
||
|
HANDLE_PACKAGE_CALLBACK_ON_DELETE : 0),
|
||
|
NULL,
|
||
|
SmallTable->DeleteCallback );
|
||
|
|
||
|
if ( Large )
|
||
|
{
|
||
|
LhtpConvertSmallToLarge( SmallTable, Large );
|
||
|
|
||
|
ShtDelete( Small, NULL );
|
||
|
|
||
|
return Large ;
|
||
|
}
|
||
|
|
||
|
return NULL ;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LhtAddHandle
|
||
|
//
|
||
|
// Synopsis: Add a handle to a handle table
|
||
|
//
|
||
|
// Arguments: [HandleTable] -- Table to add the handle to
|
||
|
// [Handle] -- Handle to add
|
||
|
//
|
||
|
// History: 2-03-97 RichardW Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL
|
||
|
LhtAddHandle(
|
||
|
PVOID HandleTable,
|
||
|
PSecHandle Handle,
|
||
|
PVOID Context,
|
||
|
ULONG Flags
|
||
|
)
|
||
|
{
|
||
|
PSEC_HANDLE_ENTRY Entry ;
|
||
|
PLARGE_HANDLE_TABLE Table ;
|
||
|
ULONG Index ;
|
||
|
|
||
|
|
||
|
Table = (PLARGE_HANDLE_TABLE) HandleTable ;
|
||
|
|
||
|
LhtLockTable( Table );
|
||
|
|
||
|
Entry = LhtpFindHandle( HandleTable,
|
||
|
Handle,
|
||
|
LHT_ACTION_ADDHANDLE,
|
||
|
NULL,
|
||
|
NULL );
|
||
|
|
||
|
if ( Entry )
|
||
|
{
|
||
|
LhtUnlockTable( Table );
|
||
|
|
||
|
return TRUE ;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// No entry, need to insert one.
|
||
|
//
|
||
|
|
||
|
while ( TRUE )
|
||
|
{
|
||
|
Index = (ULONG) IndexFromHandle( Table->Depth, Handle );
|
||
|
|
||
|
if ( Table->Lists[ Index ].Flags & LHT_SUB_TABLE )
|
||
|
{
|
||
|
Table = (PLARGE_HANDLE_TABLE) Table->Lists[ Index ].List.Flink ;
|
||
|
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if(SmallHandlePackage.AddHandle( &Table->Lists[ Index ], Handle, Context, Flags ))
|
||
|
{
|
||
|
if ( Table->Lists[ Index ].Count > HANDLE_SPLIT_THRESHOLD )
|
||
|
{
|
||
|
LhtpExpandTable( Table, Index );
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
LhtUnlockTable( (PLARGE_HANDLE_TABLE)HandleTable );
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
Table = (PLARGE_HANDLE_TABLE) HandleTable ;
|
||
|
|
||
|
Table->Count++;
|
||
|
|
||
|
LhtUnlockTable( Table );
|
||
|
|
||
|
return TRUE ;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LhtDeleteHandle
|
||
|
//
|
||
|
// Synopsis: Delete a handle from the table
|
||
|
//
|
||
|
// Arguments: [HandleTable] -- Table
|
||
|
// [Handle] -- Handle to delete
|
||
|
// [Force] -- Force delete, even if handle is not ref'd to zero
|
||
|
//
|
||
|
// History: 2-03-97 RichardW Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL
|
||
|
LhtDeleteHandle(
|
||
|
PVOID HandleTable,
|
||
|
PSecHandle Handle,
|
||
|
ULONG Options
|
||
|
)
|
||
|
{
|
||
|
PSEC_HANDLE_ENTRY Entry ;
|
||
|
PLARGE_HANDLE_TABLE Table ;
|
||
|
BOOL Removed;
|
||
|
ULONG Action ;
|
||
|
|
||
|
if ( Options & DELHANDLE_FORCE )
|
||
|
{
|
||
|
Action = LHT_ACTION_FORCEDEL ;
|
||
|
}
|
||
|
else if ( Options & LHTP_DEREF_NOT_DEL )
|
||
|
{
|
||
|
Action = LHT_ACTION_DELREF | LHTP_HANDLE_CHECKED ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Action = LHT_ACTION_DELHANDLE ;
|
||
|
}
|
||
|
|
||
|
|
||
|
Entry = LhtpFindHandle( HandleTable,
|
||
|
Handle,
|
||
|
Action,
|
||
|
&Removed,
|
||
|
NULL );
|
||
|
|
||
|
if ( Entry )
|
||
|
{
|
||
|
if ( Removed )
|
||
|
{
|
||
|
Table = (PLARGE_HANDLE_TABLE) HandleTable ;
|
||
|
|
||
|
LhtLockTable( Table );
|
||
|
|
||
|
Table->Count--;
|
||
|
|
||
|
LhtUnlockTable( Table );
|
||
|
|
||
|
if ( (Table->DeleteCallback) &&
|
||
|
((Options & DELHANDLE_NO_CALLBACK) == 0 ) &&
|
||
|
((Entry->Flags & SEC_HANDLE_FLAG_NO_CALLBACK ) == 0 ) )
|
||
|
{
|
||
|
Table->DeleteCallback(
|
||
|
&Entry->Handle,
|
||
|
Entry->Context,
|
||
|
Entry->HandleIssuedCount // Entry->RefCount
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if ( ( Entry->Flags & SEC_HANDLE_FLAG_DELETE_PENDING ) == 0 )
|
||
|
{
|
||
|
LsapFreePrivateHeap( Entry );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE ;
|
||
|
}
|
||
|
|
||
|
return FALSE ;
|
||
|
}
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: LhtValidateHandle
|
||
|
//
|
||
|
// Synopsis: Validate that a handle is within the table
|
||
|
//
|
||
|
// Arguments: [HandleTable] --
|
||
|
// [Handle] --
|
||
|
//
|
||
|
// History: 2-03-97 RichardW Created
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL
|
||
|
LhtValidateHandle(
|
||
|
PVOID HandleTable,
|
||
|
PSecHandle Handle,
|
||
|
BOOL Deref
|
||
|
)
|
||
|
{
|
||
|
PSEC_HANDLE_ENTRY Entry ;
|
||
|
PLARGE_HANDLE_TABLE Table ;
|
||
|
BOOL Removed ;
|
||
|
|
||
|
Entry = LhtpFindHandle(
|
||
|
HandleTable,
|
||
|
Handle,
|
||
|
(Deref ? LHT_ACTION_DELHANDLE : LHT_ACTION_VALIDATE),
|
||
|
&Removed,
|
||
|
NULL );
|
||
|
|
||
|
if ( Entry )
|
||
|
{
|
||
|
|
||
|
if ( Removed )
|
||
|
{
|
||
|
Table = (PLARGE_HANDLE_TABLE) HandleTable ;
|
||
|
|
||
|
LhtLockTable( Table );
|
||
|
|
||
|
Table->Count--;
|
||
|
|
||
|
LhtUnlockTable( Table );
|
||
|
|
||
|
if ( ( Table->DeleteCallback ) &&
|
||
|
( ( Entry->Flags & SEC_HANDLE_FLAG_NO_CALLBACK) == 0 ) )
|
||
|
{
|
||
|
Table->DeleteCallback(
|
||
|
&Entry->Handle,
|
||
|
Entry->Context,
|
||
|
Entry->HandleIssuedCount // Entry->RefCount
|
||
|
);
|
||
|
}
|
||
|
|
||
|
if ( ( Entry->Flags & SEC_HANDLE_FLAG_DELETE_PENDING ) == 0 )
|
||
|
{
|
||
|
LsapFreePrivateHeap( Entry );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return FALSE ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
PVOID
|
||
|
LhtRefHandle(
|
||
|
PVOID HandleTable,
|
||
|
PSecHandle Handle
|
||
|
)
|
||
|
{
|
||
|
PSEC_HANDLE_ENTRY Entry ;
|
||
|
|
||
|
Entry = LhtpFindHandle(
|
||
|
HandleTable,
|
||
|
Handle,
|
||
|
LHT_ACTION_ADDREF,
|
||
|
NULL,
|
||
|
NULL );
|
||
|
|
||
|
return Entry ;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
LhtDerefHandleKey(
|
||
|
PVOID HandleTable,
|
||
|
PVOID HandleKey
|
||
|
)
|
||
|
{
|
||
|
PSEC_HANDLE_ENTRY Entry = (PSEC_HANDLE_ENTRY) HandleKey ;
|
||
|
|
||
|
LhtDeleteHandle( HandleTable, &Entry->Handle, LHTP_DEREF_NOT_DEL );
|
||
|
}
|
||
|
|
||
|
PVOID
|
||
|
LhtGetHandleContext(
|
||
|
PVOID HandleTable,
|
||
|
PSecHandle Handle
|
||
|
)
|
||
|
{
|
||
|
PSEC_HANDLE_ENTRY Entry ;
|
||
|
|
||
|
Entry = LhtpFindHandle(
|
||
|
HandleTable,
|
||
|
Handle,
|
||
|
LHT_ACTION_ADDREF,
|
||
|
NULL,
|
||
|
NULL );
|
||
|
|
||
|
if ( Entry )
|
||
|
{
|
||
|
return Entry->Context ;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return NULL ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
LhtReleaseContext(
|
||
|
PVOID HandleTable,
|
||
|
PSecHandle Handle
|
||
|
)
|
||
|
{
|
||
|
PSEC_HANDLE_ENTRY Entry ;
|
||
|
PLARGE_HANDLE_TABLE Table ;
|
||
|
BOOL Removed;
|
||
|
|
||
|
Entry = LhtpFindHandle( HandleTable,
|
||
|
Handle,
|
||
|
LHT_ACTION_DELREF,
|
||
|
&Removed,
|
||
|
NULL );
|
||
|
|
||
|
if ( Entry )
|
||
|
{
|
||
|
if ( Removed )
|
||
|
{
|
||
|
Table = (PLARGE_HANDLE_TABLE) HandleTable ;
|
||
|
|
||
|
LhtLockTable( Table );
|
||
|
|
||
|
Table->Count--;
|
||
|
|
||
|
LhtUnlockTable( Table );
|
||
|
|
||
|
if ( ( Table->DeleteCallback ) &&
|
||
|
( ( Entry->Flags & SEC_HANDLE_FLAG_NO_CALLBACK ) == 0 ) )
|
||
|
{
|
||
|
Table->DeleteCallback( &Entry->Handle, Entry->Context, Entry->RefCount );
|
||
|
}
|
||
|
|
||
|
if ( ( Entry->Flags & SEC_HANDLE_FLAG_DELETE_PENDING ) == 0 )
|
||
|
{
|
||
|
LsapFreePrivateHeap( Entry );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE ;
|
||
|
}
|
||
|
|
||
|
return FALSE ;
|
||
|
}
|