reactos/lib/drivers/ip/network/ports.c
Cameron Gutman 2044568591 - Make PortsStartup return NTSTATUS so we can make sure memory allocated succeeded
- Change the callers to check the return status

svn path=/branches/aicom-network-fixes/; revision=36006
2008-09-06 21:30:09 +00:00

113 lines
3.4 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/ports.c
* PURPOSE: Port allocation
* PROGRAMMERS: arty (ayerkes@speakeasy.net)
* REVISIONS:
* arty 20041114 Created
*/
#include "precomp.h"
NTSTATUS PortsStartup( PPORT_SET PortSet,
UINT StartingPort,
UINT PortsToManage ) {
PortSet->StartingPort = StartingPort;
PortSet->PortsToOversee = PortsToManage;
PortSet->LastAllocatedPort = PortSet->StartingPort +
PortSet->PortsToOversee - 1;
PortSet->ProtoBitBuffer =
PoolAllocateBuffer( (PortSet->PortsToOversee + 7) / 8 );
if(!PortSet->ProtoBitBuffer) return STATUS_INSUFFICIENT_RESOURCES;
RtlInitializeBitMap( &PortSet->ProtoBitmap,
PortSet->ProtoBitBuffer,
PortSet->PortsToOversee );
RtlClearAllBits( &PortSet->ProtoBitmap );
ExInitializeFastMutex( &PortSet->Mutex );
return STATUS_SUCCESS;
}
VOID PortsShutdown( PPORT_SET PortSet ) {
PoolFreeBuffer( PortSet->ProtoBitBuffer );
}
VOID DeallocatePort( PPORT_SET PortSet, ULONG Port ) {
Port = htons(Port);
ASSERT(Port >= PortSet->StartingPort);
ASSERT(Port < PortSet->StartingPort + PortSet->PortsToOversee);
RtlClearBits( &PortSet->ProtoBitmap, Port - PortSet->StartingPort, 1 );
}
BOOLEAN AllocatePort( PPORT_SET PortSet, ULONG Port ) {
BOOLEAN Clear;
Port = htons(Port);
ASSERT(Port >= PortSet->StartingPort);
Port -= PortSet->StartingPort;
ExAcquireFastMutex( &PortSet->Mutex );
Clear = RtlAreBitsClear( &PortSet->ProtoBitmap, Port, 1 );
if( Clear ) RtlSetBits( &PortSet->ProtoBitmap, Port, 1 );
ExReleaseFastMutex( &PortSet->Mutex );
return Clear;
}
ULONG AllocateAnyPort( PPORT_SET PortSet ) {
ULONG AllocatedPort;
ULONG Next;
if (PortSet->StartingPort + PortSet->PortsToOversee <=
PortSet->LastAllocatedPort + 1) {
Next = PortSet->StartingPort;
} else {
Next = PortSet->LastAllocatedPort + 1;
}
Next -= PortSet->StartingPort;
ExAcquireFastMutex( &PortSet->Mutex );
AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, 0 );
if( AllocatedPort != (ULONG)-1 ) {
RtlSetBit( &PortSet->ProtoBitmap, AllocatedPort );
AllocatedPort += PortSet->StartingPort;
PortSet->LastAllocatedPort = AllocatedPort;
}
ExReleaseFastMutex( &PortSet->Mutex );
AllocatedPort = htons(AllocatedPort);
return AllocatedPort;
}
ULONG AllocatePortFromRange( PPORT_SET PortSet, ULONG Lowest, ULONG Highest ) {
ULONG AllocatedPort;
ULONG Next;
if (PortSet->StartingPort + PortSet->PortsToOversee <=
PortSet->LastAllocatedPort + 1) {
Next = PortSet->StartingPort;
} else {
Next = PortSet->LastAllocatedPort + 1;
}
if (Next < Lowest || Highest <= Next) {
Next = Lowest;
}
Next -= PortSet->StartingPort;
Lowest -= PortSet->StartingPort;
Highest -= PortSet->StartingPort;
ExAcquireFastMutex( &PortSet->Mutex );
AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, Next );
if( AllocatedPort != (ULONG)-1 && AllocatedPort >= Lowest &&
AllocatedPort <= Highest) {
RtlSetBit( &PortSet->ProtoBitmap, AllocatedPort );
AllocatedPort += PortSet->StartingPort;
PortSet->LastAllocatedPort = AllocatedPort;
}
ExReleaseFastMutex( &PortSet->Mutex );
AllocatedPort = htons(AllocatedPort);
return AllocatedPort;
}