2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
5 * PURPOSE: Port allocation
6 * PROGRAMMERS: arty (ayerkes@speakeasy.net)
8 * arty 20041114 Created
13 NTSTATUS
PortsStartup( PPORT_SET PortSet
,
15 UINT PortsToManage
) {
16 PortSet
->StartingPort
= StartingPort
;
17 PortSet
->PortsToOversee
= PortsToManage
;
19 PortSet
->ProtoBitBuffer
=
20 ExAllocatePoolWithTag( NonPagedPool
, (PortSet
->PortsToOversee
+ 7) / 8,
22 if(!PortSet
->ProtoBitBuffer
) return STATUS_INSUFFICIENT_RESOURCES
;
23 RtlInitializeBitMap( &PortSet
->ProtoBitmap
,
24 PortSet
->ProtoBitBuffer
,
25 PortSet
->PortsToOversee
);
26 RtlClearAllBits( &PortSet
->ProtoBitmap
);
27 KeInitializeSpinLock( &PortSet
->Lock
);
28 return STATUS_SUCCESS
;
31 VOID
PortsShutdown( PPORT_SET PortSet
) {
32 ExFreePoolWithTag( PortSet
->ProtoBitBuffer
, PORT_SET_TAG
);
35 VOID
DeallocatePort( PPORT_SET PortSet
, ULONG Port
) {
39 ASSERT(Port
>= PortSet
->StartingPort
);
40 ASSERT(Port
< PortSet
->StartingPort
+ PortSet
->PortsToOversee
);
42 KeAcquireSpinLock( &PortSet
->Lock
, &OldIrql
);
43 RtlClearBits( &PortSet
->ProtoBitmap
, Port
- PortSet
->StartingPort
, 1 );
44 KeReleaseSpinLock( &PortSet
->Lock
, OldIrql
);
47 BOOLEAN
AllocatePort( PPORT_SET PortSet
, ULONG Port
) {
53 if ((Port
< PortSet
->StartingPort
) ||
54 (Port
>= PortSet
->StartingPort
+ PortSet
->PortsToOversee
))
59 Port
-= PortSet
->StartingPort
;
61 KeAcquireSpinLock( &PortSet
->Lock
, &OldIrql
);
62 Clear
= RtlAreBitsClear( &PortSet
->ProtoBitmap
, Port
, 1 );
63 if( Clear
) RtlSetBits( &PortSet
->ProtoBitmap
, Port
, 1 );
64 KeReleaseSpinLock( &PortSet
->Lock
, OldIrql
);
69 ULONG
AllocateAnyPort( PPORT_SET PortSet
) {
73 KeAcquireSpinLock( &PortSet
->Lock
, &OldIrql
);
74 AllocatedPort
= RtlFindClearBits( &PortSet
->ProtoBitmap
, 1, 0 );
75 if( AllocatedPort
!= (ULONG
)-1 ) {
76 RtlSetBit( &PortSet
->ProtoBitmap
, AllocatedPort
);
77 AllocatedPort
+= PortSet
->StartingPort
;
78 KeReleaseSpinLock( &PortSet
->Lock
, OldIrql
);
79 return htons(AllocatedPort
);
81 KeReleaseSpinLock( &PortSet
->Lock
, OldIrql
);
86 ULONG
AllocatePortFromRange( PPORT_SET PortSet
, ULONG Lowest
, ULONG Highest
) {
90 if ((Lowest
< PortSet
->StartingPort
) ||
91 (Highest
>= PortSet
->StartingPort
+ PortSet
->PortsToOversee
))
96 Lowest
-= PortSet
->StartingPort
;
97 Highest
-= PortSet
->StartingPort
;
99 KeAcquireSpinLock( &PortSet
->Lock
, &OldIrql
);
100 AllocatedPort
= RtlFindClearBits( &PortSet
->ProtoBitmap
, 1, Lowest
);
101 if( AllocatedPort
!= (ULONG
)-1 && AllocatedPort
<= Highest
) {
102 RtlSetBit( &PortSet
->ProtoBitmap
, AllocatedPort
);
103 AllocatedPort
+= PortSet
->StartingPort
;
104 KeReleaseSpinLock( &PortSet
->Lock
, OldIrql
);
105 return htons(AllocatedPort
);
107 KeReleaseSpinLock( &PortSet
->Lock
, OldIrql
);