📄 epacket.c
字号:
/* * epacket.c * * Ethernet Packet Interface to NDIS drivers. * * Copyright 1998 Equivalence Pty. Ltd. * * Original code by William Ingle (address unknown) * * $Log: epacket.c,v $ * Revision 1.2 1998/10/06 10:24:42 robertj * Fixed hang when using reset command, removed the command! * * Revision 1.1 1998/09/28 08:08:31 robertj * Initial revision * */#include <basedef.h>#include <vmm.h>#include <ndis.h>#include <vwin32.h>#include <string.h>#include <epacket.h> // From PWLib#include "lock.h"#pragma intrinsic(memset,memcpy,strlen,strcat,strcpy)///////////////////////////////////////////////////////////////////////////////#define MAJOR_VERSION 1#define MINOR_VERSION 2#define MAX_OPEN 4#define MAX_REQUESTS 4#define TRANSMIT_PACKETS 64 //was 16#define ETHERNET_HEADER_LENGTH 14#define ETHERNET_DATA_LENGTH 1500#define ETHERNET_PACKET_LENGTH (ETHERNET_HEADER_LENGTH+ETHERNET_DATA_LENGTH)typedef struct _PACKET_RESERVED { LIST_ENTRY ListElement; char* lpBuffer; DWORD cbBuffer; DWORD* lpcbBytesReturned; OVERLAPPED* lpoOverlapped; DWORD hDevice; DWORD tagProcess;} PACKET_RESERVED, *PPACKET_RESERVED;typedef struct _INTERNAL_REQUEST { PACKET_RESERVED Reserved; NDIS_REQUEST Request;} INTERNAL_REQUEST, *PINTERNAL_REQUEST;typedef struct _OPEN_INSTANCE { LIST_ENTRY ListElement; DWORD hDevice; NDIS_STATUS Status; NDIS_HANDLE AdapterHandle; NDIS_HANDLE BindAdapterContext; NDIS_HANDLE PacketPool; NDIS_HANDLE BufferPool; NDIS_SPIN_LOCK RcvQSpinLock; LIST_ENTRY RcvList; NDIS_SPIN_LOCK RequestSpinLock; LIST_ENTRY RequestList; NDIS_SPIN_LOCK ResetSpinLock; LIST_ENTRY ResetIrpList; INTERNAL_REQUEST Requests[MAX_REQUESTS];} OPEN_INSTANCE, *POPEN_INSTANCE;typedef struct _DEVICE_EXTENSION { PDRIVER_OBJECT DriverObject; NDIS_HANDLE NdisProtocolHandle; LIST_ENTRY OpenList;} DEVICE_EXTENSION, *PDEVICE_EXTENSION;#define RESERVED(_p) ((PPACKET_RESERVED)((_p)->ProtocolReserved))//// define wrapper for VWIN32_DIOCCompletionRoutine //void VXDINLINE VWIN32_DIOCCompletionRoutine( DWORD hEvent ){ _asm mov ebx, hEvent VxDCall( VWIN32_DIOCCompletionRoutine );}#pragma VxD_LOCKED_CODE_SEG#pragma VxD_LOCKED_DATA_SEGPDEVICE_EXTENSION GlobalDeviceExtension = NULL; /////////////////////////////////////////////////////////////////////////////// VOID NDIS_API PacketTransferDataComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status, IN UINT BytesTransfered){ // upcall when no more data available POPEN_INSTANCE Open = (POPEN_INSTANCE)ProtocolBindingContext; PPACKET_RESERVED pReserved = (PPACKET_RESERVED)(pPacket->ProtocolReserved); OVERLAPPED * pOverlap = (OVERLAPPED *)(pReserved->lpoOverlapped); PNDIS_BUFFER pNdisBuffer; // free buffer descriptor NdisUnchainBufferAtFront(pPacket, &pNdisBuffer); if (pNdisBuffer) NdisFreeBuffer(pNdisBuffer); // set total bytes returned BytesTransfered += ETHERNET_HEADER_LENGTH; *pReserved->lpcbBytesReturned += BytesTransfered; pOverlap->O_InternalHigh = *(pReserved->lpcbBytesReturned); // The internal member of overlapped structure contains // a pointer to the event structure that will be signalled, // resuming the execution of the waitng GetOverlappedResult // call. VWIN32_DIOCCompletionRoutine(pOverlap->O_Internal); // Unlock buffers PacketPageUnlock(pReserved->lpBuffer, pReserved->cbBuffer); PacketPageUnlock(pReserved->lpcbBytesReturned, sizeof(DWORD)); PacketPageUnlock(pReserved->lpoOverlapped, sizeof(OVERLAPPED)); // recycle the packet NdisReinitializePacket(pPacket); // Put the packet on the free queue NdisFreePacket(pPacket);}///////////////////////////////////////////////////////////////////////////////VOID NDIS_API PacketSendComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_PACKET pPacket, IN NDIS_STATUS Status){ // upcall on completion of send PNDIS_BUFFER pNdisBuffer; PPACKET_RESERVED Reserved = (PPACKET_RESERVED)pPacket->ProtocolReserved; // free buffer descriptor NdisUnchainBufferAtFront(pPacket, &pNdisBuffer); if (pNdisBuffer) NdisFreeBuffer(pNdisBuffer); // return status Reserved->lpoOverlapped->O_InternalHigh = Status; // The internal member of overlapped structure contains // a pointer to the event structure that will be signalled, // resuming the execution of the waiting GetOverlappedResult // call. VWIN32_DIOCCompletionRoutine(Reserved->lpoOverlapped->O_Internal); // Unlock buffers PacketPageUnlock(Reserved->lpBuffer, Reserved->cbBuffer); PacketPageUnlock(Reserved->lpcbBytesReturned, sizeof(DWORD)); PacketPageUnlock(Reserved->lpoOverlapped, sizeof(OVERLAPPED)); // recycle the packet NdisReinitializePacket(pPacket); // Put the packet back on the free list NdisFreePacket(pPacket);}///////////////////////////////////////////////////////////////////////////////VOID NDIS_API PacketResetComplete(IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_STATUS Status){ // upcall on reset completion POPEN_INSTANCE Open = (POPEN_INSTANCE)ProtocolBindingContext; PLIST_ENTRY ResetListEntry; // remove the reset request from the list NdisAcquireSpinLock(&Open->ResetSpinLock); if (IsListEmpty(&Open->ResetIrpList)) { NdisReleaseSpinLock(&Open->ResetSpinLock); return; } ResetListEntry = RemoveHeadList(&Open->ResetIrpList); NdisReleaseSpinLock(&Open->ResetSpinLock); // Acquire request element from list NdisAcquireSpinLock(&Open->RequestSpinLock); InsertTailList(&Open->RequestList, ResetListEntry); NdisReleaseSpinLock(&Open->RequestSpinLock);}///////////////////////////////////////////////////////////////////////////////NDIS_STATUS NDIS_API PacketReset(POPEN_INSTANCE pOpen){ // reset the protocol PLIST_ENTRY ResetListEntry; NDIS_STATUS Status; // Acquire request element from list NdisAllocateSpinLock(&pOpen->RequestSpinLock); if (IsListEmpty(&pOpen->RequestList)) { NdisReleaseSpinLock(&pOpen->RequestSpinLock); return NDIS_STATUS_RESOURCES; } ResetListEntry = RemoveHeadList(&pOpen->RequestList); NdisReleaseSpinLock(&pOpen->RequestSpinLock); // Insert Reset IRP into Request Queue NdisAcquireSpinLock(&pOpen->ResetSpinLock); InsertTailList(&pOpen->ResetIrpList, ResetListEntry); NdisReleaseSpinLock(&pOpen->ResetSpinLock); // Reset the adapter NdisReset(&Status, pOpen->AdapterHandle); if (Status != NDIS_STATUS_PENDING) PacketResetComplete(pOpen, Status); return Status;}///////////////////////////////////////////////////////////////////////////////VOID NDIS_API PacketRequestComplete(IN NDIS_HANDLE ProtocolBindingContext, IN PNDIS_REQUEST NdisRequest, IN NDIS_STATUS Status){ // perform a packet request complete POPEN_INSTANCE Open = (POPEN_INSTANCE)ProtocolBindingContext; PINTERNAL_REQUEST pRequest = CONTAINING_RECORD(NdisRequest, INTERNAL_REQUEST, Request); PPACKET_RESERVED pReserved = &pRequest->Reserved; OVERLAPPED * pOverlap = (OVERLAPPED *)pReserved->lpoOverlapped; EPACKET_OID * oidData = (EPACKET_OID*)pReserved->lpBuffer; if (Status == NDIS_STATUS_SUCCESS) { // set total bytes returned *pReserved->lpcbBytesReturned = oidData->Length + sizeof(EPACKET_OID) - sizeof(oidData->Data); pOverlap->O_InternalHigh = *(pReserved->lpcbBytesReturned); } else { *pReserved->lpcbBytesReturned = 0; // set total bytes returned pOverlap->O_InternalHigh = *pReserved->lpcbBytesReturned; oidData->Length = Status; // return status in oidData if there is an error } // The internal member of overlapped structure contains // a pointer to the event structure that will be signalled, // resuming the execution of the waitng GetOverlappedResult // call. VWIN32_DIOCCompletionRoutine(pOverlap->O_Internal); // Unlock buffers PacketPageUnlock(pReserved->lpBuffer, pReserved->cbBuffer); PacketPageUnlock(pReserved->lpcbBytesReturned, sizeof(DWORD)); PacketPageUnlock(pReserved->lpoOverlapped, sizeof(OVERLAPPED)); // Return request element to list NdisAcquireSpinLock(&Open->RequestSpinLock); InsertTailList(&Open->RequestList, &pReserved->ListElement); NdisReleaseSpinLock(&Open->RequestSpinLock);}///////////////////////////////////////////////////////////////////////////////DWORD NDIS_API PacketRequest(POPEN_INSTANCE Open, DWORD FunctionCode, DWORD dwDDB, DWORD hDevice, PDIOCPARAMETERS pDiocParms){ // perform a packet request PLIST_ENTRY RequestListEntry;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -