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_
|
|||
|
|
|||
|
|
|||
|
|