⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 epacket.c

📁 sloedgy open sip stack source code
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * 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 + -