/*++ Copyright (c) 2000 Microsoft Corporation Module Name: macros.h Abstract: Some macros for NDISPROT. Environment: Kernel mode only. Revision History: --*/ #ifndef MIN #define MIN(_a, _b) ((_a) < (_b)? (_a): (_b)) #endif #if DBG // 引用计数加1 #define NPROT_REF_OPEN(_pOpen) ndisprotDbgRefOpen(_pOpen, __FILENUMBER, __LINE__) // 引用计数减1 #define NPROT_DEREF_OPEN(_pOpen) ndisprotDbgDerefOpen(_pOpen, __FILENUMBER, __LINE__) #else // 不是DBG的场合,DBG的场合是输出了一些LOG信息,然后调用了下面的例程 #define NPROT_REF_OPEN(_pOpen) ndisprotRefOpen(_pOpen) #define NPROT_DEREF_OPEN(_pOpen) ndisprotDerefOpen(_pOpen) #endif // // Spinlock macros // #if DBG_SPIN_LOCK // 同样的做法,DBG的场合多做了一些事情,然后调用非DBG场合对应的例程 #define NPROT_INIT_LOCK(_pLock) / ndisprotAllocateSpinLock(_pLock, __FILENUMBER, __LINE__) #define NPROT_FREE_LOCK(_pLock) / ndisprotFreeSpinLock(_pLock, __FILENUMBER, __LINE__) #define NPROT_ACQUIRE_LOCK(_pLock) / ndisprotAcquireSpinLock(_pLock, __FILENUMBER, __LINE__) #define NPROT_RELEASE_LOCK(_pLock) / ndisprotReleaseSpinLock(_pLock, __FILENUMBER, __LINE__) #define NPROT_FREE_DBG_LOCK() / ndisprotFreeDbgLock() #else #define NPROT_INIT_LOCK(_pLock) NdisAllocateSpinLock(_pLock) #define NPROT_FREE_LOCK(_pLock) NdisFreeSpinLock(_pLock) #define NPROT_ACQUIRE_LOCK(_pLock) NdisAcquireSpinLock(_pLock) #define NPROT_RELEASE_LOCK(_pLock) NdisReleaseSpinLock(_pLock) #define NPROT_FREE_DBG_LOCK() #endif // DBG // // List manipulation. // #define NPROT_INIT_LIST_HEAD(_pList) InitializeListHead(_pList) #define NPROT_IS_LIST_EMPTY(_pList) IsListEmpty(_pList) #define NPROT_INSERT_HEAD_LIST(_pList, _pEnt) InsertHeadList(_pList, _pEnt) #define NPROT_INSERT_TAIL_LIST(_pList, _pEnt) InsertTailList(_pList, _pEnt) #define NPROT_REMOVE_ENTRY_LIST(_pEnt) RemoveEntryList(_pEnt) // // Receive packet queueing. // #define NPROT_LIST_ENTRY_TO_RCV_PKT(_pEnt) / CONTAINING_RECORD(CONTAINING_RECORD(_pEnt, NPROT_RECV_PACKET_RSVD, Link), NDIS_PACKET, ProtocolReserved) #define NPROT_RCV_PKT_TO_LIST_ENTRY(_pPkt) / (&((PNPROT_RECV_PACKET_RSVD)&((_pPkt)->ProtocolReserved[0]))->Link) // // In case we allocate a receive packet of our own to copy and queue // received data, we might have to also allocate an auxiliary NDIS_BUFFER // to map part of the receive buffer (skipping the header bytes), so as // to satisfy NdisTransferData. In such cases, we keep a pointer to the // fully mapped receive buffer in the packet reserved space: // #define NPROT_RCV_PKT_TO_ORIGINAL_BUFFER(_pPkt) / (((PNPROT_RECV_PACKET_RSVD)&((_pPkt)->ProtocolReserved[0]))->pOriginalBuffer) // // Send packet context. // #define NPROT_IRP_FROM_SEND_PKT(_pPkt) / (((PNPROT_SEND_PACKET_RSVD)&((_pPkt)->ProtocolReserved[0]))->pIrp) #define NPROT_SEND_PKT_RSVD(_pPkt) / ((PNPROT_SEND_PACKET_RSVD)&((_pPkt)->ProtocolReserved[0])) #define NPROT_REF_SEND_PKT(_pPkt) / (VOID)NdisInterlockedIncrement((PLONG)&NPROT_SEND_PKT_RSVD(_pPkt)->RefCount) #define NPROT_DEREF_SEND_PKT(_pPkt) / { / if (NdisInterlockedDecrement((PLONG)&NPROT_SEND_PKT_RSVD(_pPkt)->RefCount) == 0) / { / NdisFreePacket(_pPkt); / } / } #ifdef NDIS51 // // Cancel IDs are generated by using the partial cancel ID we got from // NDIS ORed with a monotonically increasing locally generated ID. // #define NPROT_CANCEL_ID_LOW_MASK (((ULONG_PTR)-1) >> 8) // 下面的宏定义,直接理解是把Globals.LocalCancelId的引用,转换为PLONG类型,然后原子加1(意思是指向下一个PLONG) // 然后和NPROT_CANCEL_ID_LOW_MASK(0x00FFFFFF)做与运算,就是保留低3个字节,然后和Globals.PartialCancelId做或运算 // 但是具体的原理还要看后面的代码分析 #define NPROT_GET_NEXT_CANCEL_ID() / (PVOID)(Globals.PartialCancelId | / ((NdisInterlockedIncrement((PLONG)&Globals.LocalCancelId)) & NPROT_CANCEL_ID_LOW_MASK)) #endif // NDIS51 // // Memory allocation // #if DBG #define NPROT_ALLOC_MEM(_pVar, _Size) / (_pVar) = ndisprotAuditAllocMem( / (PVOID)&(_pVar), / _Size, / __FILENUMBER, / __LINE__); #define NPROT_FREE_MEM(_pMem) / ndisprotAuditFreeMem(_pMem); #else #define NPROT_ALLOC_MEM(_pVar, _Size) / NdisAllocateMemoryWithTag((PVOID *)(&_pVar), (_Size), NPROT_ALLOC_TAG) #define NPROT_FREE_MEM(_pMem) / NdisFreeMemory(_pMem, 0, 0) #endif // DBG #define NPROT_ZERO_MEM(_pMem, _ByteCount) / NdisZeroMemory(_pMem, _ByteCount) #define NPROT_COPY_MEM(_pDst, _pSrc, _ByteCount) / NdisMoveMemory(_pDst, _pSrc, _ByteCount) #define NPROT_MEM_CMP(_p1, _p2, _ByteCount) / NdisEqualMemory(_p1, _p2, _ByteCount) #define NPROT_SET_MEM(_pMem, _ByteVal, _ByteCount) / NdisFillMemory(_pMem, _ByteCount, _ByteVal) // // Events. // #define NPROT_INIT_EVENT(_pEvent) NdisInitializeEvent(_pEvent) #define NPROT_SIGNAL_EVENT(_pEvent) NdisSetEvent(_pEvent) #define NPROT_WAIT_EVENT(_pEvent, _MsToWait) ( NdisWaitEvent(_pEvent, _MsToWait) ) // // Flags // // 以下宏定义,先把_Mask的为取反,把_FlagsVar和_Mask做与运算,把_Mask中0的位也同样设置到_FlagsVar中,相当于初始化 // 然后开始真正的位设置和_BitsToSet做或运算 #define NPROT_SET_FLAGS(_FlagsVar, _Mask, _BitsToSet) / (_FlagsVar) = ((_FlagsVar) & ~(_Mask)) | (_BitsToSet) // 从以下这个宏看,_FlagsVar一次只设置一个状态,而不可以把多个状体保留在_FlagsVar中 #define NPROT_TEST_FLAGS(_FlagsVar, _Mask, _BitsToCheck) / (((_FlagsVar) & (_Mask)) == (_BitsToCheck)) // // Block the calling thread for the given duration: // #define NPROT_SLEEP(_Seconds) / { / NDIS_EVENT _SleepEvent; / NdisInitializeEvent(&_SleepEvent); / // 等待Event,如果过了_Seconds秒后还没有设置Event,那么本次等待结束, // 其实这个Event永远不会被设置,相当于程序睡了_Seconds秒 if(NdisWaitEvent(&_SleepEvent, _Seconds*1000)){}; / } // 枚举NDIS的状态转换为NT的状态 #define NDIS_STATUS_TO_NT_STATUS(_NdisStatus, _pNtStatus) / { / /* / * The following NDIS status codes map directly to NT status codes. / */ / if (((NDIS_STATUS_SUCCESS == (_NdisStatus)) || / (NDIS_STATUS_PENDING == (_NdisStatus)) || / (NDIS_STATUS_BUFFER_OVERFLOW == (_NdisStatus)) || / (NDIS_STATUS_FAILURE == (_NdisStatus)) || / (NDIS_STATUS_RESOURCES == (_NdisStatus)) || / (NDIS_STATUS_NOT_SUPPORTED == (_NdisStatus)))) / { / *(_pNtStatus) = (NTSTATUS)(_NdisStatus); / } / else if (NDIS_STATUS_BUFFER_TOO_SHORT == (_NdisStatus)) / { / /* / * The above NDIS status codes require a little special casing. / */ / *(_pNtStatus) = STATUS_BUFFER_TOO_SMALL; / } / else if (NDIS_STATUS_INVALID_LENGTH == (_NdisStatus)) / { / *(_pNtStatus) = STATUS_INVALID_BUFFER_SIZE; / } / else if (NDIS_STATUS_INVALID_DATA == (_NdisStatus)) / { / *(_pNtStatus) = STATUS_INVALID_PARAMETER; / } / else if (NDIS_STATUS_ADAPTER_NOT_FOUND == (_NdisStatus)) / { / *(_pNtStatus) = STATUS_NO_MORE_ENTRIES; / } / else if (NDIS_STATUS_ADAPTER_NOT_READY == (_NdisStatus)) / { / *(_pNtStatus) = STATUS_DEVICE_NOT_READY; / } / else / { / *(_pNtStatus) = STATUS_UNSUCCESSFUL; / } / }