|
|
/****************************************************************************/ // misc.c
//
// Miscellaneous TermDD routines.
//
// Copyright (C) 1998-2000 Microsoft Corporation
/****************************************************************************/
#include <precomp.h>
#pragma hdrstop
#if DBG
LIST_ENTRY IcaGlobalPoolListHead; ULONG IcaTotalAllocations = 0; ULONG IcaTotalFrees = 0; ULONG IcaTotalBytesAllocated = 0; KSPIN_LOCK IcaDebugSpinLock;
typedef struct _ICA_POOL_HEADER { LIST_ENTRY GlobalPoolListEntry; PCHAR FileName; ULONG LineNumber; ULONG Size; ULONG InUse; } ICA_POOL_HEADER, *PICA_POOL_HEADER;
typedef struct _ICA_POOL_TRAILER { ULONG Size; ULONG_PTR CheckSum; } ICA_POOL_TRAILER, *PICA_POOL_TRAILER;
void IcaInitializeDebugData(void) { KeInitializeSpinLock(&IcaDebugSpinLock); InitializeListHead(&IcaGlobalPoolListHead); }
BOOLEAN IcaLockConnection(PICA_CONNECTION pConnect) { PERESOURCE pResource = &pConnect->Resource; PLIST_ENTRY Head, Next; PICA_STACK pStack; KIRQL oldIrql; ULONG i; BOOLEAN Result;
TRACE((pConnect, TC_ICADD, TT_SEM, "TermDD: IcaLockConnection: 0x%x\n", pResource));
/*
* Ensure we don't already have the connection locked */ ASSERT( !ExIsResourceAcquiredExclusiveLite( pResource ) );
/*
* Reference and lock the connection object */ IcaReferenceConnection( pConnect ); KeEnterCriticalRegion(); // Disable APC calls when holding a resource.
Result = ExAcquireResourceExclusive( pResource, TRUE );
/*
* Ensure we don't own any stack locks */ Head = &pConnect->StackHead; for ( Next = Head->Flink; Next != Head; Next = Next->Flink ) { pStack = CONTAINING_RECORD( Next, ICA_STACK, StackEntry ); ASSERT( !ExIsResourceAcquiredExclusiveLite( &pStack->Resource ) ); }
/*
* Ensure we don't own any channel locks */ IcaLockChannelTable(&pConnect->ChannelTableLock);
for ( i = 0; i < sizeof(pConnect->pChannel) / sizeof(*pConnect->pChannel); i++ ) { if (pConnect->pChannel[i]) { ASSERT(!ExIsResourceAcquiredExclusiveLite(&pConnect->pChannel[i]->Resource)); } } IcaUnlockChannelTable(&pConnect->ChannelTableLock);
return Result; }
void IcaUnlockConnection(PICA_CONNECTION pConnect) { PERESOURCE pResource = &pConnect->Resource;
TRACE((pConnect, TC_ICADD, TT_SEM, "TermDD: IcaUnlockConnection: 0x%x\n", pResource));
/*
* Ensure we already have the connection locked */ ASSERT(ExIsResourceAcquiredExclusiveLite(pResource));
ExReleaseResource(pResource); KeLeaveCriticalRegion(); // Resume APC calls after releasing resource.
IcaDereferenceConnection(pConnect); }
BOOLEAN IcaLockStack(PICA_STACK pStack) { PERESOURCE pResource = &pStack->Resource; PICA_CONNECTION pConnect; PLIST_ENTRY Head, Next; PICA_STACK pNextStack; KIRQL oldIrql; ULONG i; BOOLEAN Result;
/*
* Ensure we don't already have the stack locked */ ASSERT( !ExIsResourceAcquiredExclusiveLite( pResource ) );
/*
* Reference and lock the stack object */ IcaReferenceStack( pStack ); KeEnterCriticalRegion(); // Disable APC calls when holding a resource.
Result = ExAcquireResourceExclusive( pResource, TRUE );
TRACESTACK((pStack, TC_ICADD, TT_SEM, "TermDD: IcaLockStack: 0x%x\n", pStack));
/*
* Ensure we don't own any other stack locks */ pConnect = IcaGetConnectionForStack( pStack ); Head = &pConnect->StackHead; for ( Next = Head->Flink; Next != Head; Next = Next->Flink ) { pNextStack = CONTAINING_RECORD( Next, ICA_STACK, StackEntry ); if ( pNextStack != pStack ) { ASSERT( !ExIsResourceAcquiredExclusiveLite( &pNextStack->Resource ) ); } }
/*
* Ensure we don't own any channel locks */ IcaLockChannelTable(&pConnect->ChannelTableLock); for ( i = 0; i < sizeof(pConnect->pChannel) / sizeof(*pConnect->pChannel); i++ ) { if ( pConnect->pChannel[i] ) { ASSERT( !ExIsResourceAcquiredExclusiveLite( &pConnect->pChannel[i]->Resource ) ); } } IcaUnlockChannelTable(&pConnect->ChannelTableLock);
return Result; }
void IcaUnlockStack(PICA_STACK pStack) { PERESOURCE pResource = &pStack->Resource;
TRACESTACK((pStack, TC_ICADD, TT_SEM, "TermDD: IcaUnlockStack: 0x%x\n", pStack));
/*
* Ensure we already have the stack locked */ ASSERT(ExIsResourceAcquiredExclusiveLite(pResource));
ExReleaseResource(pResource); KeLeaveCriticalRegion(); // Resume APC calls after releasing resource.
IcaDereferenceStack(pStack); }
BOOLEAN IcaLockChannel(PICA_CHANNEL pChannel) { PERESOURCE pResource = &pChannel->Resource;
TRACECHANNEL((pChannel, TC_ICADD, TT_SEM, "TermDD: IcaLockChannel: cc %u, vc %d\n", pChannel->ChannelClass, pChannel->VirtualClass));
IcaReferenceChannel(pChannel);
// Need to disable APC calls when holding a resource.
KeEnterCriticalRegion(); return ExAcquireResourceExclusive(pResource, TRUE); }
void IcaUnlockChannel(IN PICA_CHANNEL pChannel) { PERESOURCE pResource = &pChannel->Resource;
TRACECHANNEL((pChannel, TC_ICADD, TT_SEM, "TermDD: IcaUnlockChannel: cc %u, vc %d\n", pChannel->ChannelClass, pChannel->VirtualClass));
/*
* Ensure we already have the channel locked */ ASSERT(ExIsResourceAcquiredExclusiveLite(pResource));
ExReleaseResource(pResource); KeLeaveCriticalRegion(); // Resume APC calls after releasing resource.
IcaDereferenceChannel(pChannel); }
PVOID IcaAllocatePool( IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN PCHAR FileName, IN ULONG LineNumber, IN BOOLEAN WithQuota) { PICA_POOL_HEADER header; PICA_POOL_TRAILER trailer; KIRQL oldIrql;
ASSERT( PoolType == NonPagedPool || PoolType == NonPagedPoolMustSucceed );
// make sure number of bytes are 64bit aligned
NumberOfBytes = (NumberOfBytes + 7) & ~7;
if (WithQuota) { try { header = ExAllocatePoolWithQuotaTag( PoolType, NumberOfBytes + sizeof(*header) + sizeof(*trailer), ICA_POOL_TAG ); } except( EXCEPTION_EXECUTE_HANDLER ) { return NULL; } } else { header = ExAllocatePoolWithTag( PoolType, NumberOfBytes + sizeof(*header) + sizeof(*trailer), ICA_POOL_TAG ); }
if (header == NULL) { return NULL; }
header->FileName = FileName; header->LineNumber = LineNumber; header->Size = NumberOfBytes; header->InUse = 1;
trailer = (PICA_POOL_TRAILER)((PCHAR)(header + 1) + NumberOfBytes); trailer->Size = NumberOfBytes; trailer->CheckSum = (ULONG_PTR)header + (ULONG_PTR)FileName + LineNumber + NumberOfBytes;
InterlockedIncrement( &IcaTotalAllocations );
ExInterlockedAddUlong( &IcaTotalBytesAllocated, header->Size, &IcaDebugSpinLock );
ExInterlockedInsertTailList( &IcaGlobalPoolListHead, &header->GlobalPoolListEntry, &IcaDebugSpinLock );
return (PVOID)(header + 1); }
void IcaFreePool(IN PVOID Pointer) { KIRQL oldIrql; PICA_POOL_HEADER header = (PICA_POOL_HEADER)Pointer - 1; PICA_POOL_TRAILER trailer;
trailer = (PICA_POOL_TRAILER)((PCHAR)(header + 1) + header->Size); ASSERT( header->Size == trailer->Size ); ASSERT( trailer->CheckSum = (ULONG_PTR)header + (ULONG_PTR)header->FileName + header->LineNumber + header->Size );
InterlockedIncrement( &IcaTotalFrees );
ExInterlockedAddUlong( &IcaTotalBytesAllocated, -1*header->Size, &IcaDebugSpinLock );
KeAcquireSpinLock( &IcaDebugSpinLock, &oldIrql ); RemoveEntryList( &header->GlobalPoolListEntry ); KeReleaseSpinLock( &IcaDebugSpinLock, oldIrql );
header->GlobalPoolListEntry.Flink = (PLIST_ENTRY)(-1); header->GlobalPoolListEntry.Blink = (PLIST_ENTRY)(-1); header->InUse = 0;
if (header->Size == trailer->Size) RtlFillMemory(Pointer, header->Size, 0xff);
ExFreePool((PVOID)header); }
#endif
|