📄 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.1 2006/06/29 04:19:28 joegenbaclor
* *** empty log message ***
*
* 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_SEG
PDEVICE_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -