457 lines
13 KiB
C
457 lines
13 KiB
C
/*++
|
||
|
||
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_
|
||
|
||
|
||
|