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

📄 epacket.c

📁 sloedgy open sip stack source code
💻 C
📖 第 1 页 / 共 3 页
字号:

  PLIST_ENTRY       RequestListEntry;
  PINTERNAL_REQUEST pRequest;
  PPACKET_RESERVED  pReserved;
  EPACKET_OID *  OidData;
  NDIS_STATUS       Status;
  

  // Acquire request element from list
  NdisAcquireSpinLock(&Open->RequestSpinLock);
  
  if (IsListEmpty(&Open->RequestList)) { 
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
    NdisReleaseSpinLock(&Open->RequestSpinLock);
    return NDIS_STATUS_SUCCESS;
  }

  RequestListEntry = RemoveHeadList(&Open->RequestList);
  NdisReleaseSpinLock(&Open->RequestSpinLock);
  
  pReserved = CONTAINING_RECORD(RequestListEntry, PACKET_RESERVED, ListElement);
  pRequest  = CONTAINING_RECORD(pReserved, INTERNAL_REQUEST, Reserved);
  OidData   = (EPACKET_OID*)(pDiocParms->lpvInBuffer);

  if ((pDiocParms->cbInBuffer != pDiocParms->cbOutBuffer) ||
      (pDiocParms->cbInBuffer < sizeof(*OidData) - sizeof(OidData->Data) + OidData->Length)) {
    *(DWORD *)pDiocParms->lpcbBytesReturned = 1;
    return NDIS_STATUS_BUFFER_TOO_SHORT;
  }

  // The buffer is valid
  pReserved->lpBuffer          = (PVOID)PacketPageLock(pDiocParms->lpvInBuffer, pDiocParms->cbInBuffer);
  pReserved->lpcbBytesReturned = (PVOID)PacketPageLock(pDiocParms->lpcbBytesReturned, sizeof(DWORD));
  pReserved->lpoOverlapped     = (PVOID)PacketPageLock(pDiocParms->lpoOverlapped, sizeof(OVERLAPPED));
  pReserved->cbBuffer          = pDiocParms->cbInBuffer;
  pReserved->hDevice           = pDiocParms->hDevice;
  pReserved->tagProcess        = pDiocParms->tagProcess;
  
  if (FunctionCode == IOCTL_EPACKET_SET_OID) {                      
    pRequest->Request.RequestType                                  = NdisRequestSetInformation;
    pRequest->Request.DATA.SET_INFORMATION.Oid                     = OidData->Oid;
    pRequest->Request.DATA.SET_INFORMATION.InformationBufferLength = OidData->Length;
    pRequest->Request.DATA.SET_INFORMATION.InformationBuffer       = OidData->Data;
  } 
  else {
    if (OidData->Oid >= 0x01000000)
      pRequest->Request.RequestType = NdisRequestQueryInformation;
    else
      pRequest->Request.RequestType = NdisRequestGeneric1;
    pRequest->Request.DATA.QUERY_INFORMATION.Oid                     = OidData->Oid;
    pRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength = OidData->Length;
    pRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer       = OidData->Data;
  }

  // submit the request
  NdisRequest(&Status, Open->AdapterHandle, &pRequest->Request);

  if (Status == NDIS_STATUS_PENDING)
    return(-1);      // This will make DeviceIOControl return ERROR_IO_PENDING

  PacketRequestComplete(Open, &pRequest->Request, Status);
  return Status;
}


///////////////////////////////////////////////////////////////////////////////

NDIS_STATUS NDIS_API PacketReceiveIndicate(IN NDIS_HANDLE ProtocolBindingContext,
                                           IN NDIS_HANDLE MacReceiveContext,
                                           IN PVOID       HeaderBuffer,
                                           IN UINT        HeaderBufferSize,
                                           IN PVOID       LookaheadBuffer,
                                           IN UINT        LookaheadBufferSize,
                                           IN UINT        PacketSize)
{
  // upcall on packet arrival

  POPEN_INSTANCE      Open;
  PLIST_ENTRY         PacketListEntry;
  PNDIS_PACKET        pPacket;
  NDIS_STATUS         Status;
  UINT                BytesTransfered = 0;
  PPACKET_RESERVED    pReserved;


  if (HeaderBufferSize != ETHERNET_HEADER_LENGTH)
    return NDIS_STATUS_NOT_ACCEPTED;
  
  Open = (POPEN_INSTANCE) ProtocolBindingContext;
  
  //  See if there are any pending reads that we can satisfy
  NdisAcquireSpinLock(&Open->RcvQSpinLock); // fixed 5.11.97
  
  if (IsListEmpty(&Open->RcvList)) { 
    NdisReleaseSpinLock(&Open->RcvQSpinLock);
    return NDIS_STATUS_NOT_ACCEPTED;
  }

  PacketListEntry = RemoveHeadList(&Open->RcvList);
  NdisReleaseSpinLock(&Open->RcvQSpinLock);
  
  pReserved = CONTAINING_RECORD(PacketListEntry, PACKET_RESERVED, ListElement);
  pPacket = CONTAINING_RECORD(pReserved, NDIS_PACKET, ProtocolReserved);
  
  // Copy the MAC header
  NdisMoveMemory(RESERVED(pPacket)->lpBuffer, HeaderBuffer, HeaderBufferSize);

  //  Call the Mac to transfer the data portion of the packet
  NdisTransferData(&Status, Open->AdapterHandle, MacReceiveContext, 0, PacketSize, pPacket, &BytesTransfered);
  if (Status == NDIS_STATUS_PENDING)
    return NDIS_STATUS_PENDING;

  if (Status == NDIS_STATUS_SUCCESS) {
    PacketTransferDataComplete(Open, pPacket, Status, BytesTransfered);
    return NDIS_STATUS_SUCCESS;
  }

  PacketTransferDataComplete(Open, pPacket, Status, 0);
  return NDIS_STATUS_SUCCESS;
}


///////////////////////////////////////////////////////////////////////////////

VOID NDIS_API PacketReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext)
{
  // upcall when receive complete
}


///////////////////////////////////////////////////////////////////////////////

VOID NDIS_API PacketStatus(IN NDIS_HANDLE ProtocolBindingContext,
                           IN NDIS_STATUS Status,
                           IN PVOID       StatusBuffer,
                           IN UINT        StatusBufferSize)
{
  // get packet status
}


///////////////////////////////////////////////////////////////////////////////

VOID NDIS_API PacketStatusComplete(IN NDIS_HANDLE ProtocolBindingContext)
{
  // completion handler
}


///////////////////////////////////////////////////////////////////////////////

VOID NDIS_API PacketBindAdapterComplete(IN NDIS_HANDLE  ProtocolBindingContext,
                                        IN NDIS_STATUS  Status,
                                        IN NDIS_STATUS  OpenErrorStatus)
{
  // upcall on Bind completion

  POPEN_INSTANCE Open = (POPEN_INSTANCE)ProtocolBindingContext;

  // If the binding is unsuccessful then we deallocate data structures in 
  // preparation for unloading
  if (Status != NDIS_STATUS_SUCCESS) {
    NdisFreeSpinLock(&Open->RequestSpinLock);
    NdisFreeSpinLock(&Open->RcvQSpinLock);

    NdisFreeBufferPool(Open->BufferPool);
    NdisFreePacketPool(Open->PacketPool);

    NdisFreeMemory(Open, sizeof(OPEN_INSTANCE), 0);
  }
  else {
    // Insert New Adapter into list
    InsertTailList(&GlobalDeviceExtension->OpenList, &Open->ListElement);
  }
}


///////////////////////////////////////////////////////////////////////////////

VOID NDIS_API PacketBindAdapter(OUT PNDIS_STATUS pStatus,
                                IN  NDIS_HANDLE  BindAdapterContext,
                                IN  PNDIS_STRING pAdapterName,
                                IN  PVOID        SystemSpecific1,
                                IN  PVOID        SystemSpecific2)
{
  //   bind this driver to a NIC
  
  POPEN_INSTANCE    oiNew;
  NDIS_STATUS	    ErrorStatus, AllocStatus;
  UINT              Medium;
  NDIS_MEDIUM       MediumArray = NdisMedium802_3;
  UINT              i;


  //  allocate some memory for the open structure
  NdisAllocateMemory((PVOID *)&oiNew, sizeof(OPEN_INSTANCE), 0, -1);
  if (oiNew == NULL) { // not enough memory
    *pStatus = NDIS_STATUS_RESOURCES;
    return;
  }
  
  NdisZeroMemory((PVOID)oiNew, sizeof(OPEN_INSTANCE));
  
  // Save Binding Context
  oiNew->BindAdapterContext = BindAdapterContext;
  
  // Save the device handle
  oiNew->hDevice = (DWORD)SystemSpecific1;
  
  // Allocate a packet pool for our xmit and receive packets
  NdisAllocatePacketPool(&AllocStatus,
                         &(oiNew->PacketPool),
                         TRANSMIT_PACKETS,
                         sizeof(PACKET_RESERVED));
  if (AllocStatus != NDIS_STATUS_SUCCESS) { // not enough memory
    NdisFreeMemory(oiNew, sizeof(OPEN_INSTANCE), 0);
    *pStatus = NDIS_STATUS_RESOURCES;
    return;
  }
  
  // Allocate a buffer pool for our xmit and receive buffers
  NdisAllocateBufferPool(&AllocStatus, &(oiNew->BufferPool), TRANSMIT_PACKETS);
  if (AllocStatus != NDIS_STATUS_SUCCESS) { // not enough memory
    NdisFreeMemory(oiNew, sizeof(OPEN_INSTANCE), 0);
    *pStatus = NDIS_STATUS_RESOURCES;
    return;
  }

  //  list to hold irp's that want to reset the adapter
  NdisAllocateSpinLock(&oiNew->ResetSpinLock);
  InitializeListHead(&oiNew->ResetIrpList);

  //  Initialize list for holding pending read requests
  NdisAllocateSpinLock(&oiNew->RcvQSpinLock);
  InitializeListHead(&oiNew->RcvList);
  
  //  Initialize the request list
  NdisAllocateSpinLock(&oiNew->RequestSpinLock);
  InitializeListHead(&oiNew->RequestList);
  
  //  link up the request stored in our open block
  for (i = 0; i < MAX_REQUESTS; i++) {
    // Braces are required as InsertTailList macro has multiple statements in it
    InsertTailList(&oiNew->RequestList, &oiNew->Requests[i].Reserved.ListElement);
  }
  
  //  Try to open the MAC
  NdisOpenAdapter(pStatus, &ErrorStatus, &oiNew->AdapterHandle, &Medium, &MediumArray, 1,
                  GlobalDeviceExtension->NdisProtocolHandle, oiNew, pAdapterName, 0, NULL);
  
  //  Save the status returned by NdisOpenAdapter for completion routine
  oiNew->Status = *pStatus;
  
  switch (*pStatus) {
    case NDIS_STATUS_PENDING:
      break;
    
    case NDIS_STATUS_SUCCESS:
      ErrorStatus = NDIS_STATUS_SUCCESS;
    
      // fall through to completion routine with oiNew->Status 
      // set to !NDIS_STATUS_PENDING
    
    default:
      PacketBindAdapterComplete(oiNew, *pStatus, ErrorStatus);
      break;
  }
}


///////////////////////////////////////////////////////////////////////////////

VOID NDIS_API PacketUnbindAdapterComplete(IN POPEN_INSTANCE Open,
                                          IN NDIS_STATUS Status)
{
  // upcall on NdisCloseAdapter completion


  // If Open->Status == NDIS_STATUS_PENDING then we must complete the pended unbinding
  if (Open->Status == NDIS_STATUS_PENDING) {
    NdisCompleteUnbindAdapter(Open->BindAdapterContext, Status);
    Open->Status = NDIS_STATUS_SUCCESS;
  }

  if (Status != NDIS_STATUS_SUCCESS)
    return;

  // Remove Adapter from global list
  RemoveEntryList(&Open->ListElement);

  // Free Memory
  NdisFreeSpinLock(&Open->RequestSpinLock);
  NdisFreeSpinLock(&Open->RcvQSpinLock);
  NdisFreeSpinLock(&Open->ResetSpinLock);

  NdisFreeBufferPool(Open->BufferPool);

  NdisFreePacketPool(Open->PacketPool);

  NdisFreeMemory(Open, sizeof(OPEN_INSTANCE), 0);
}


///////////////////////////////////////////////////////////////////////////////

VOID NDIS_API PacketUnbindAdapter(OUT PNDIS_STATUS   Status,
                                  IN  POPEN_INSTANCE Open,
                                  IN  POPEN_INSTANCE junk)
{
  // detach protocol from the NIC clean up any pending I/O requests

  PLIST_ENTRY  PacketListEntry;
  PNDIS_PACKET pPacket;


  //  The open instance of the device is about to close
  //  We need to complete all pending I/O requests
  //  First we complete any pending read requests
  NdisAcquireSpinLock(&Open->RcvQSpinLock);

  while (!IsListEmpty(&Open->RcvList)) {
    PacketListEntry = RemoveHeadList(&Open->RcvList);
    pPacket = CONTAINING_RECORD(PacketListEntry, NDIS_PACKET, ProtocolReserved);

    //  complete normally
    PacketTransferDataComplete(Open, pPacket, NDIS_STATUS_SUCCESS, 0);
  }

  NdisReleaseSpinLock(&Open->RcvQSpinLock);

  // close the adapter
  NdisCloseAdapter(Status, Open->AdapterHandle);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -