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

📄 epacket.c

📁 sloedgy open sip stack source code
💻 C
📖 第 1 页 / 共 3 页
字号:
  // Save status returned from NdisCloseAdapter for completion routine
  Open->Status = *Status;

  if (*Status != NDIS_STATUS_PENDING)
    PacketUnbindAdapterComplete(Open, *Status);
}


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

VOID NDIS_API PacketUnload()
{
  // deregister the protocol, free remaining memory 
  //  - called by NdisCloseAdapter when last adapter closed

  NDIS_STATUS Status;
  
  if (GlobalDeviceExtension != NULL) {
    NdisDeregisterProtocol(&Status, GlobalDeviceExtension->NdisProtocolHandle);
    
    if (Status == NDIS_STATUS_SUCCESS)
      NdisFreeMemory(GlobalDeviceExtension, sizeof(DEVICE_EXTENSION), 0);
    GlobalDeviceExtension = NULL;
  }
}


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

NTSTATUS NDIS_API DriverEntry(IN PDRIVER_OBJECT  DriverObject,
                              IN PUNICODE_STRING RegistryPath)

{
  // initialiae the driver

  NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar;
  NDIS_STRING ProtoName = NDIS_STRING_CONST("EPACKET");
  NDIS_STATUS Status;


  // Because the driver can be loaded once for each Netcard on the system,
  // and because DriverEntry is called each time, we must ensure that
  // initialization is performed only once.
  if (GlobalDeviceExtension != NULL)
    return NDIS_STATUS_SUCCESS;
        
  NdisAllocateMemory((PVOID *)&GlobalDeviceExtension, sizeof(DEVICE_EXTENSION), 0, -1 );
  if (GlobalDeviceExtension == NULL)
    return NDIS_STATUS_RESOURCES;

  NdisZeroMemory((UCHAR*)GlobalDeviceExtension, sizeof(DEVICE_EXTENSION));
  NdisZeroMemory((UCHAR*)&ProtocolChar, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  ProtocolChar.MajorNdisVersion            = 0x03;
  ProtocolChar.MinorNdisVersion            = 0x0a;
  ProtocolChar.Reserved                    = 0;
  ProtocolChar.OpenAdapterCompleteHandler  = PacketBindAdapterComplete;
  ProtocolChar.CloseAdapterCompleteHandler = PacketUnbindAdapterComplete;
  ProtocolChar.SendCompleteHandler         = PacketSendComplete;
  ProtocolChar.TransferDataCompleteHandler = PacketTransferDataComplete;
  ProtocolChar.ResetCompleteHandler        = PacketResetComplete;
  ProtocolChar.RequestCompleteHandler      = PacketRequestComplete;
  ProtocolChar.ReceiveHandler              = PacketReceiveIndicate;
  ProtocolChar.ReceiveCompleteHandler      = PacketReceiveComplete;
  ProtocolChar.StatusHandler               = PacketStatus;
  ProtocolChar.StatusCompleteHandler       = PacketStatusComplete;
  ProtocolChar.BindAdapterHandler          = PacketBindAdapter;
  ProtocolChar.UnbindAdapterHandler        = PacketUnbindAdapter;
  ProtocolChar.UnloadProtocolHandler       = PacketUnload;
  ProtocolChar.Name                        = ProtoName;
  
  NdisRegisterProtocol(&Status,
                       &GlobalDeviceExtension->NdisProtocolHandle,
                       &ProtocolChar,
                       sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  
  if (Status != NDIS_STATUS_SUCCESS) {
    NdisFreeMemory(GlobalDeviceExtension, sizeof(DEVICE_EXTENSION), 0);
    return Status;
  }
  
  // initialize open list
  InitializeListHead(&GlobalDeviceExtension->OpenList);
  
  // initialize global device extension
  GlobalDeviceExtension->DriverObject = DriverObject;
  
  return Status;
}


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

POPEN_INSTANCE GetOpen(DWORD handle)
{
  // return a specified Open Instance      

  PLIST_ENTRY     pHead = &GlobalDeviceExtension->OpenList;
  PLIST_ENTRY     pTemp;
  POPEN_INSTANCE  Open;
  

  if (GlobalDeviceExtension == NULL)
    return NULL;
  
  // search the list for the Open Instance containing the specified handle
  
  for (pTemp = pHead->Flink; pTemp != pHead; pTemp = pTemp->Flink) {
    Open = CONTAINING_RECORD(pTemp, OPEN_INSTANCE, ListElement);        
    if (Open && Open->hDevice == handle)
      return Open;
  }
  
  return NULL; // just in case
}


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

VOID PacketAllocatePacketBuffer(PNDIS_STATUS    pStatus,
                                POPEN_INSTANCE  pOpen,
                                PNDIS_PACKET    *ppPacket,
                                PDIOCPARAMETERS pDiocParms,
                                DWORD           FunctionCode )
{
  // allocate a buffer for reading/writing

  PNDIS_BUFFER pNdisBuffer;
  PNDIS_PACKET pPacket;
  

  //  Try to get a packet from our list of free ones
  NdisAllocatePacket(pStatus, ppPacket, pOpen->PacketPool);
  
  if (*pStatus != NDIS_STATUS_SUCCESS) {
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
    return;
  }
  
  pPacket = *ppPacket;
  
  // Buffers used asynchronously must be page locked
  switch (FunctionCode) {
    case IOCTL_EPACKET_READ:
      RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvOutBuffer, pDiocParms->cbOutBuffer);
      RESERVED(pPacket)->cbBuffer = pDiocParms->cbOutBuffer;
      break;
    
    case IOCTL_EPACKET_WRITE:
      RESERVED(pPacket)->lpBuffer = (PVOID)PacketPageLock(pDiocParms->lpvInBuffer, pDiocParms->cbInBuffer);
      RESERVED(pPacket)->cbBuffer = pDiocParms->cbInBuffer;
      break;
    
    default:
      // recycle the packet
      NdisReinitializePacket(pPacket);
    
      // Put the packet on the free queue
      NdisFreePacket(pPacket);
    
      *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
      *pStatus = NDIS_STATUS_NOT_ACCEPTED;
      return;
  }
  
  RESERVED(pPacket)->lpcbBytesReturned = (PVOID)PacketPageLock(pDiocParms->lpcbBytesReturned, sizeof(DWORD));
  RESERVED(pPacket)->lpoOverlapped     = (PVOID)PacketPageLock(pDiocParms->lpoOverlapped, sizeof(OVERLAPPED));
  RESERVED(pPacket)->hDevice           = pDiocParms->hDevice;
  RESERVED(pPacket)->tagProcess        = pDiocParms->tagProcess;
  
  switch (FunctionCode) {
    case IOCTL_EPACKET_READ:
      NdisAllocateBuffer(pStatus,
                         &pNdisBuffer,
                         pOpen->BufferPool,
                         (PVOID)(RESERVED(pPacket)->lpBuffer + ETHERNET_HEADER_LENGTH),
                         pDiocParms->cbOutBuffer);
      break;
    
    case IOCTL_EPACKET_WRITE:
      NdisAllocateBuffer(pStatus,
                         &pNdisBuffer,
                         pOpen->BufferPool,
                         (PVOID)RESERVED(pPacket)->lpBuffer,
                         pDiocParms->cbInBuffer);
      break;
  }
  
  if (*pStatus == NDIS_STATUS_SUCCESS)
    NdisChainBufferAtFront(pPacket, pNdisBuffer); // Attach buffer to Packet
  else {
    NdisReinitializePacket(pPacket);  // recycle the packet
    NdisFreePacket(pPacket);          // Put the packet on the free queue
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
  }
}


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

DWORD PacketRead(POPEN_INSTANCE     Open,
                 DWORD              dwDDB,
                 DWORD              hDevice,
                 PDIOCPARAMETERS    pDiocParms)
{
  // read a packet

  NDIS_STATUS     Status;
  PNDIS_PACKET    pPacket;
  
  //  Check that the buffer can hold a max length Ethernet packet
  if (pDiocParms->cbOutBuffer < ETHERNET_PACKET_LENGTH) {
    *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0; // Need bigger buffer       
    return NDIS_STATUS_SUCCESS;
  }
  
  PacketAllocatePacketBuffer(&Status, Open, &pPacket, pDiocParms, IOCTL_EPACKET_READ);
  
  if (Status == NDIS_STATUS_SUCCESS) {
    //  Put this packet in a list of pending reads.
    //  The receive indication handler will attempt to remove packets
    //  from this list for use in transfer data calls
    NdisAcquireSpinLock(&Open->RcvQSpinLock); // fixed 6.11.97
    InsertTailList(&Open->RcvList, &RESERVED(pPacket)->ListElement);
    NdisReleaseSpinLock(&Open->RcvQSpinLock);
  }

  return -1;  // This will make DeviceIOControl return ERROR_IO_PENDING
}


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

DWORD PacketWrite(POPEN_INSTANCE    Open,
                  DWORD             dwDDB,
                  DWORD             hDevice,
                  PDIOCPARAMETERS   pDiocParms)
{
  // write a packet

  PNDIS_PACKET    pPacket;
  NDIS_STATUS     Status;

  
  PacketAllocatePacketBuffer(&Status, Open, &pPacket, pDiocParms, IOCTL_EPACKET_WRITE);
  if (Status != NDIS_STATUS_SUCCESS)
    return 0;   // This will return immediately with no data written
  
  // Call the MAC
  NdisSend(&Status, Open->AdapterHandle, pPacket);
  if (Status != NDIS_STATUS_PENDING) {
    //  The send didn't pend so call the completion handler now
    PacketSendComplete(Open, pPacket, Status);
  }

  return(-1); // This will make DeviceIOControl return ERROR_IO_PENDING
}


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

DWORD _stdcall PacketIOControl(DWORD           dwService,
                               DWORD           dwDDB,
                               DWORD           hDevice,
                               PDIOCPARAMETERS pDiocParms) 
{
  // called from applications

  POPEN_INSTANCE  Open;
  NDIS_STATUS     Status;
  UCHAR           AdapterBuffer[5];
  NDIS_STRING     AdapterName = NDIS_STRING_CONST(AdapterBuffer);


  switch (dwService) {
    case DIOC_OPEN:
      return NDIS_STATUS_SUCCESS;
    
    case DIOC_CLOSEHANDLE:
      if ((Open = GetOpen(hDevice)) != NULL)
        PacketUnbindAdapter(&Status, Open, NULL);
      return NDIS_STATUS_SUCCESS;

    case IOCTL_EPACKET_VERSION:
      if (pDiocParms->cbOutBuffer < 2)
        *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;
      else {
        ((BYTE *)pDiocParms->lpvOutBuffer)[0] = MAJOR_VERSION;
        ((BYTE *)pDiocParms->lpvOutBuffer)[1] = MINOR_VERSION;
        *(DWORD *)pDiocParms->lpcbBytesReturned = 2;
      }
      return NDIS_STATUS_SUCCESS;

    case IOCTL_EPACKET_BIND:
      memcpy(AdapterName.Buffer, (BYTE *)pDiocParms->lpvInBuffer,
             min(strlen((char *)pDiocParms->lpvInBuffer), sizeof(AdapterBuffer)-1));
      AdapterName.Buffer[sizeof(AdapterBuffer)-1] = '\0';
      PacketBindAdapter(&Status,
                        GlobalDeviceExtension->NdisProtocolHandle,
                        &AdapterName,
                        (PVOID)hDevice, /* special */
                        NULL);
      // Note: If the above usage of the 4'th arg to PacketBindAdapter
      //       causes problems, use a global variable instead.
      if (Status == NDIS_STATUS_SUCCESS || Status == NDIS_STATUS_PENDING) {
        *(DWORD *)pDiocParms->lpcbBytesReturned = 1;
        return NDIS_STATUS_SUCCESS;
      }
      break;

    case IOCTL_EPACKET_SET_OID:
    case IOCTL_EPACKET_QUERY_OID:
      if ((Open = GetOpen(hDevice)) != NULL)
        return PacketRequest(Open, dwService, dwDDB, hDevice, pDiocParms);
      break;
    
    case IOCTL_EPACKET_READ:
      if ((Open = GetOpen(hDevice)) != NULL)
        return PacketRead(Open, dwDDB, hDevice, pDiocParms);
      break;
    
    case IOCTL_EPACKET_WRITE:
      if ((Open = GetOpen(hDevice)) != NULL)
        return PacketWrite(Open, dwDDB, hDevice, pDiocParms);
      break;
  }

  *(DWORD *)pDiocParms->lpcbBytesReturned = 0;
  return NDIS_STATUS_SUCCESS;
}


// End of File ////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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