|
|
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
atkutils.h
Abstract:
This module contains miscellaneous support routines.
Author:
Jameel Hyder (jameelh@microsoft.com) Nikhil Kamkolkar (nikhilk@microsoft.com)
Revision History: 19 Jun 1992 Initial Version
Notes: Tab stop: 4 --*/
#ifndef _ATKUTILS_
#define _ATKUTILS_
// SpinLock Macros
#if DBG
#define INITIALIZE_SPIN_LOCK(_pLock) \
{ \ KeInitializeSpinLock(&(_pLock)->SpinLock); \ (_pLock)->FileLineLock = 0; \ } #else // DBG
#define INITIALIZE_SPIN_LOCK(_pLock) \
{ \ KeInitializeSpinLock(&(_pLock)->SpinLock); \ } #endif
#if DBG
#define ACQUIRE_SPIN_LOCK(_pLock, _pOldIrql) \
{ \ KeAcquireSpinLock(&(_pLock)->SpinLock, \ _pOldIrql); \ (_pLock)->FileLineLock = (FILENUM | __LINE__); \ }
#define ACQUIRE_SPIN_LOCK_DPC(_pLock) \
{ \ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); \ KeAcquireSpinLockAtDpcLevel(&(_pLock)->SpinLock); \ (_pLock)->FileLineLock = (FILENUM | __LINE__ | 0x80000000); \ }
#define RELEASE_SPIN_LOCK(_pLock, _OldIrql) \
{ \ ASSERT ((_pLock)->FileLineLock != 0); \ ASSERT (((_pLock)->FileLineLock & 0x80000000) == 0); \ (_pLock)->FileLineLock = 0; \ (_pLock)->FileLineUnlock = (FILENUM | __LINE__); \ KeReleaseSpinLock(&(_pLock)->SpinLock, \ _OldIrql); \ }
#define RELEASE_SPIN_LOCK_DPC(_pLock) \
{ \ ASSERT ((_pLock)->FileLineLock != 0); \ ASSERT ((_pLock)->FileLineLock & 0x80000000); \ (_pLock)->FileLineLock = 0; \ (_pLock)->FileLineUnlock = (FILENUM | __LINE__ | 0x80000000); \ KeReleaseSpinLockFromDpcLevel(&(_pLock)->SpinLock); \ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); \ }
#else // DBG
#define ACQUIRE_SPIN_LOCK(_pLock, _pOldIrql) \
{ \ KeAcquireSpinLock(&(_pLock)->SpinLock, \ _pOldIrql); \ }
#define ACQUIRE_SPIN_LOCK_DPC(_pLock) \
{ \ KeAcquireSpinLockAtDpcLevel(&(_pLock)->SpinLock); \ }
#define RELEASE_SPIN_LOCK(_pLock, _OldIrql) \
{ \ KeReleaseSpinLock(&(_pLock)->SpinLock, \ (_OldIrql)); \ }
#define RELEASE_SPIN_LOCK_DPC(_pLock) \
{ \ KeReleaseSpinLockFromDpcLevel(&(_pLock)->SpinLock); \ } \
#endif // DBG
// Macros for ExInterlocked calls
#define INTERLOCKED_INCREMENT_LONG(p, l) InterlockedIncrement(p)
#define INTERLOCKED_DECREMENT_LONG(p, l) InterlockedDecrement(p)
#define INTERLOCKED_INCREMENT_LONG_DPC(p, l) InterlockedIncrement(p)
#define INTERLOCKED_DECREMENT_LONG_DPC(p, l) InterlockedDecrement(p)
#define INTERLOCKED_ADD_STATISTICS(p, v, l) ExInterlockedAddLargeStatistic(p, v)
#define INTERLOCKED_ADD_ULONG(p, v, l) ExInterlockedAddUlong(p, v, l)
#define INTERLOCKED_ADD_LARGE_INTGR(p, v, l) ExInterlockedAddLargeInteger(p, v, l)
#define INTERLOCKED_ADD_ULONG_DPC(p, v, l) ExInterlockedAddUlong(p, v, l)
#define INTERLOCKED_ADD_LARGE_INTGR_DPC(p, v, l) ExInterlockedAddLargeInteger(p, v, l)
#define ATALK_NODES_EQUAL(N1, N2) \
((((N1)->atn_Network == (N2)->atn_Network) || \ ((N1)->atn_Network == 0) || \ ((N2)->atn_Network == 0)) && \ ((N1)->atn_Node == (N2)->atn_Node))
#define ATALK_ADDRS_EQUAL(A1, A2) \
((((A1)->ata_Network == (A2)->ata_Network) || \ ((A1)->ata_Network == 0) || \ ((A2)->ata_Network == 0)) && \ ((A1)->ata_Node == (A2)->ata_Node) && \ ((A1)->ata_Socket == (A2)->ata_Socket))
#define INVALID_ADDRESS(pAddr) \
(((pAddr)->ata_Network > LAST_VALID_NETWORK) || \ (((pAddr)->ata_Node > MAX_USABLE_ATALKNODE) && \ ((pAddr)->ata_Node != ATALK_BROADCAST_NODE)) || \ ((pAddr)->ata_Socket < FIRST_VALID_SOCKET) || \ ((pAddr)->ata_Socket > LAST_VALID_SOCKET))
#define ATALKADDR_TO_TDI(pTdiAddr, pAtalkAddr) \
{ \ (pTdiAddr)->TAAddressCount = 1; \ (pTdiAddr)->Address[0].AddressLength = sizeof(TDI_ADDRESS_APPLETALK); \ (pTdiAddr)->Address[0].AddressType = TDI_ADDRESS_TYPE_APPLETALK; \ (pTdiAddr)->Address[0].Address[0].Network = (pAtalkAddr)->ata_Network; \ (pTdiAddr)->Address[0].Address[0].Node = (pAtalkAddr)->ata_Node; \ (pTdiAddr)->Address[0].Address[0].Socket = (pAtalkAddr)->ata_Socket; \ }
#define TDI_TO_ATALKADDR(pAtalkAddr, pTdiAddr) \
{ \ ASSERTMSG("TdiAddrCount is not 1\n", \ ((pTdiAddr)->TAAddressCount == 1)); \ \ ASSERTMSG("TdiAddrLen invalid\n", \ ((pTdiAddr)->Address[0].AddressLength >= \ sizeof(TDI_ADDRESS_APPLETALK))); \ \ ASSERTMSG("TdiAddrType invalid\n", \ ((pTdiAddr)->Address[0].AddressType == \ TDI_ADDRESS_TYPE_APPLETALK)); \ \ (pAtalkAddr)->ata_Network = (pTdiAddr)->Address[0].Address[0].Network;\ (pAtalkAddr)->ata_Node = (pTdiAddr)->Address[0].Address[0].Node; \ (pAtalkAddr)->ata_Socket = (pTdiAddr)->Address[0].Address[0].Socket;\ }
#define IN_NETWORK_RANGE(NetworkNumber, pRte) \
(((pRte)->rte_NwRange.anr_FirstNetwork == NetworkNumber) || \ ((NetworkNumber >= (pRte)->rte_NwRange.anr_FirstNetwork) && \ (NetworkNumber <= (pRte)->rte_NwRange.anr_LastNetwork)))
#define WITHIN_NETWORK_RANGE(NetworkNumber, pRange) \
(((pRange)->anr_FirstNetwork == NetworkNumber) || \ ((NetworkNumber >= (pRange)->anr_FirstNetwork) && \ (NetworkNumber <= (pRange)->anr_LastNetwork)))
#define COPY_NETWORK_ADDR(_Dst, _Src) \
{ \ *((ULONG UNALIGNED *)(_Dst)) = *((ULONG UNALIGNED *)(_Src)); \ *((USHORT UNALIGNED *)((UCHAR *)(_Dst)+4)) = \ *((USHORT UNALIGNED *)((UCHAR *)(_Src)+4)); \ }
// Hash functions
// Make sure we're positive [thus the shift by 7 rather than 8].
// Only hash node and socket; due to the "zero matches all" for
// non-extended network numbers.
#define HASH_ATALK_ADDR(address) \
((USHORT)(((address)->ata_Node << 7) + \ ((address)->ata_Socket & 0x7F)))
#define HASH_ATALK_NODE(address) \
((USHORT)((((address)->atn_Network & 0x3C) >> 2) + \ (address)->atn_Node & 0x04))
#define HASH_ID_SRCADDR(id, pSrcAddr) \
((id) + (((pSrcAddr)->ata_Node >> 2) + ((pSrcAddr)->ata_Network & 0xFF)))
/*
* The following macros deal with on-the-wire integer and long values * * On the wire format is big-endian i.e. a long value of 0x01020304 is * represented as 01 02 03 04. Similarly an int value of 0x0102 is * represented as 01 02. * * The host format is not assumed since it will vary from processor to * processor. */
// Get a byte from on-the-wire format to a short in the host format
#define GETBYTE2SHORT(DstPtr, SrcPtr) \
*(PUSHORT)(DstPtr) = (USHORT) (*(PBYTE)(SrcPtr))
// Get a byte from on-the-wire format to a dword in the host format
#define GETBYTE2DWORD(DstPtr, SrcPtr) \
*(PDWORD)(DstPtr) = (DWORD) (*(PBYTE)(SrcPtr))
// Get a short from on-the-wire format to a dword in the host format
#define GETSHORT2DWORD(DstPtr, SrcPtr) \
*(PDWORD)(DstPtr) = ((*((PBYTE)(SrcPtr)+0) << 8) + \ (*((PBYTE)(SrcPtr)+1)))
// Get a short from on-the-wire format to a short in the host format
#define GETSHORT2SHORT(DstPtr, SrcPtr) \
*(PUSHORT)(DstPtr) = ((*((PBYTE)(SrcPtr)+0) << 8) + \ (*((PBYTE)(SrcPtr)+1)))
// Get a dword from on-the-wire format to a dword in the host format
#define GETDWORD2DWORD(DstPtr, SrcPtr) \
*(PDWORD)(DstPtr) = ((*((PBYTE)(SrcPtr)+0) << 24) + \ (*((PBYTE)(SrcPtr)+1) << 16) + \ (*((PBYTE)(SrcPtr)+2) << 8) + \ (*((PBYTE)(SrcPtr)+3)))
// Put a dword from the host format to a short to on-the-wire format
#define PUTBYTE2BYTE(DstPtr, Src) \
*((PBYTE)(DstPtr)) = (BYTE)(Src)
// Put a dword from the host format to a short to on-the-wire format
#define PUTSHORT2BYTE(DstPtr, Src) \
*((PBYTE)(DstPtr)) = ((USHORT)(Src) % 256)
// Put a dword from the host format to a short to on-the-wire format
#define PUTSHORT2SHORT(DstPtr, Src) \
*((PBYTE)(DstPtr)+0) = (BYTE) ((USHORT)(Src) >> 8), \ *((PBYTE)(DstPtr)+1) = (BYTE)(Src)
// Put a dword from the host format to a byte to on-the-wire format
#define PUTDWORD2BYTE(DstPtr, Src) \
*(PBYTE)(DstPtr) = (BYTE)(Src)
// Put a dword from the host format to a short to on-the-wire format
#define PUTDWORD2SHORT(DstPtr, Src) \
*((PBYTE)(DstPtr)+0) = (BYTE) ((DWORD)(Src) >> 8), \ *((PBYTE)(DstPtr)+1) = (BYTE) (Src)
// Put a dword from the host format to a dword to on-the-wire format
#define PUTDWORD2DWORD(DstPtr, Src) \
*((PBYTE)(DstPtr)+0) = (BYTE) ((DWORD)(Src) >> 24), \ *((PBYTE)(DstPtr)+1) = (BYTE) ((DWORD)(Src) >> 16), \ *((PBYTE)(DstPtr)+2) = (BYTE) ((DWORD)(Src) >> 8), \ *((PBYTE)(DstPtr)+3) = (BYTE) (Src)
// MIN/MAX macros
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
extern BYTE AtalkUpCaseTable[];
extern VOID AtalkUpCase( IN PBYTE pSrc, IN BYTE SrcLen, OUT PBYTE pDst );
extern BOOLEAN AtalkCompareCaseInsensitive( IN PBYTE s1, IN PBYTE s2 );
extern int AtalkOrderCaseInsensitive( IN PBYTE s1, IN PBYTE s2 );
#define AtalkFixedCompareCaseInsensitive(s1, l1, s2, l2) \
(((l1) == (l2)) && AtalkCompareFixedCaseInsensitive(s1, s2, l1))
extern BOOLEAN AtalkCompareFixedCaseInsensitive( IN PBYTE s1, IN PBYTE s2, IN int len );
#define AtalkFixedCompareCaseSensitive(s1, l1, s2, l2) \
((l1 == l2) && !memcmp(s1, s2, l1))
extern PBYTE AtalkSearchBuf( IN PBYTE pBuf, IN BYTE BufLen, IN BYTE SearchChar );
int GetTokenLen( IN PBYTE pTokStr, IN int WildStringLen, IN BYTE NBP_WILD_CHARACTER );
BOOLEAN SubStringMatch( IN PBYTE pTarget, IN PBYTE pTokStr, IN int StringLen, IN int TokStrLen ); extern BOOLEAN AtalkCheckNetworkRange( IN PATALK_NETWORKRANGE NetworkRange );
#define AtalkRangesOverlap(pRange1, pRange2) \
(((pRange1)->anr_LastNetwork >= (pRange2)->anr_FirstNetwork) && \ ((pRange1)->anr_FirstNetwork <= (pRange2)->anr_LastNetwork))
extern BOOLEAN AtalkIsPrime( long Step );
extern LONG AtalkRandomNumber( VOID );
extern VOID AtalkDbgIncCount( IN DWORD *Value );
extern VOID AtalkDbgDecCount( IN DWORD *Value );
// Used for calculating round trip times using Van Jacobson algorithm
typedef struct { ULONG rt_New; SHORT rt_Min; SHORT rt_Max; SHORT rt_Ave; SHORT rt_Dev; SHORT rt_Base; } RT, *PRT;
#define AtalkInitializeRT(pRT, Initial, Min, Max) \
{ \ (pRT)->rt_Min = Min; \ (pRT)->rt_Max = Max; \ (pRT)->rt_Base = Initial; \ (pRT)->rt_Ave = Min; \ (pRT)->rt_Dev = 0; \ }
#define AtalkCalculateNewRT(pRT) \
{ \ SHORT baseT, error; \ \ /* VAN JACOBSEN Algorithm. From Internetworking with Tcp/ip (Comer). */\ \ if ((pRT)->rt_New == 0) \ (pRT)->rt_New = 1; /* Do not let this go to zero */ \ \ error = (SHORT)((pRT)->rt_New) - ((pRT)->rt_Ave >> 3); \ (pRT)->rt_Ave += error; \ /* Make sure not too small */ \ if ((pRT)->rt_Ave <= 0) \ { \ (pRT)->rt_Ave = (pRT)->rt_Min; \ } \ \ if (error < 0) \ error = -error; \ \ error -= ((pRT)->rt_Dev >> 2); \ (pRT)->rt_Dev += error; \ if ((pRT)->rt_Dev <= 0) \ (pRT)->rt_Dev = 1; \ \ baseT = ((((pRT)->rt_Ave >> 2) + (pRT)->rt_Dev) >> 1); \ \ /* If less then min - set it */ \ if (baseT < (pRT)->rt_Min) \ baseT = (pRT)->rt_Min; \ \ /* If greater than max - set it */ \ if (baseT > (pRT)->rt_Max) \ baseT = (pRT)->rt_Max; \ \ /* Set the new value */ \ (pRT)->rt_Base = baseT; \ }
extern BOOLEAN AtalkWaitTE( IN PKEVENT pEvent, IN ULONG TimeInMs );
extern VOID AtalkSleep( IN ULONG TimeInMs );
NTSTATUS AtalkGetProtocolSocketType( PATALK_DEV_CTX Context, PUNICODE_STRING RemainingFileName, PBYTE ProtocolType, PBYTE SocketType );
INT AtalkIrpGetEaCreateType( IN PIRP Irp);
LOCAL LONG atalkStringHash( IN PBYTE String, IN BYTE StrLen );
#endif // _ATKUTILS_
|