Example #1
0
// Create a packet buffer
PACKET_BUFFER *NeoNewPacketBuffer()
{
	PACKET_BUFFER *p;
	NDIS_STATUS ret;

	// Memory allocation
	p = NeoZeroMalloc(sizeof(PACKET_BUFFER));
	// Memory allocation for packet
	p->Buf = NeoMalloc(NEO_MAX_PACKET_SIZE);
	// Allocate the buffer pool
	NdisAllocateBufferPool(&ret, &p->BufferPool, 1);
	// Allocate the buffer
	NdisAllocateBuffer(&ret, &p->NdisBuffer, p->BufferPool, p->Buf, NEO_MAX_PACKET_SIZE);
	// Secure the packet pool
	NdisAllocatePacketPool(&ret, &p->PacketPool, 1, PROTOCOL_RESERVED_SIZE_IN_PACKET);
	// Secure the packet
	NdisAllocatePacket(&ret, &p->NdisPacket, p->PacketPool);
	NDIS_SET_PACKET_HEADER_SIZE(p->NdisPacket, NEO_PACKET_HEADER_SIZE);
	// Attach the buffer to the packet
	NdisChainBufferAtFront(p->NdisPacket, p->NdisBuffer);

	return p;
}
Example #2
0
void divert_init(void)
{
	int i;
	struct divert_packet *dp;
	NDIS_STATUS status;

	for (i = 0; i < QUEUE_SIZE; i++) {
		dp = ExAllocatePoolWithTag(PagedPool, sizeof(*dp),
					   (ULONG) "ao");

		if (!dp)
			DbgPrint("ExAllocatePoolWithTag()");

		memset(dp, 0, sizeof(*dp));

		dp->dp_next = _packet_free.dp_next;
		_packet_free.dp_next = dp;
	}

	NdisAllocateSpinLock(&_lock);

	NdisAllocateBufferPool(&status, &_buf_pool, QUEUE_SIZE);
	NdisAllocatePacketPool(&status, &_packet_pool, QUEUE_SIZE, 16);
}
Example #3
0
BOOLEAN
ArcCreateFilter(
    IN PNDIS_MINIPORT_BLOCK Miniport,
    IN ARC_FILTER_CHANGE FilterChangeAction,
    IN ARC_DEFERRED_CLOSE CloseAction,
    UCHAR AdapterAddress,
    IN PNDIS_SPIN_LOCK Lock,
    OUT PARC_FILTER *Filter
    )

/*++

Routine Description:

    This routine is used to create and initialize the Arcnet filter database.

Arguments:

    Miniport - Pointer to the mini-port object.

    ChangeAction - Action routine to call when a binding sets or clears
    a particular filter class and it is the first or only binding using
    the filter class.

    CloseAction - This routine is called if a binding closes while
    it is being indicated to via NdisIndicateReceive.  It will be
    called upon return from NdisIndicateReceive.

    AdapterAddress - the address of the adapter associated with this filter
    database.

    Lock - Pointer to the lock that should be held when mutual exclusion
    is required.

    Filter - A pointer to an ARC_FILTER.  This is what is allocated and
    created by this routine.

Return Value:

    If the function returns false then one of the parameters exceeded
    what the filter was willing to support.

--*/

{

    PARC_FILTER LocalFilter;
    NDIS_STATUS AllocStatus;

    //
    // Allocate the database and it's associated arrays.
    //

    AllocStatus = NdisAllocateMemory(&LocalFilter, sizeof(ARC_FILTER), 0, HighestAcceptableMax);
    *Filter = LocalFilter;

    if (AllocStatus != NDIS_STATUS_SUCCESS) {
        return FALSE;
    }

    NdisZeroMemory(
        LocalFilter,
        sizeof(ARC_FILTER)
        );

    LocalFilter->Miniport = Miniport;
    LocalFilter->FreeBindingMask = (ULONG)(-1);
    LocalFilter->OpenList = NULL;
    LocalFilter->AdapterAddress = AdapterAddress ;
    LocalFilter->Lock = Lock;
    LocalFilter->FilterChangeAction = FilterChangeAction;
    LocalFilter->CloseAction = CloseAction;

    NdisAllocateBufferPool(
        &AllocStatus,
        (PNDIS_HANDLE)(&LocalFilter->ReceiveBufferPool),
        ARC_RECEIVE_BUFFERS
        );

    if (AllocStatus != NDIS_STATUS_SUCCESS) {

        NdisFreeMemory(LocalFilter, sizeof(ARC_FILTER), 0);
        return(FALSE);
    }

    ArcReferencePackage();

    return TRUE;

}
Example #4
0
NDIS_STATUS NICAllocAdapter(
    PMP_ADAPTER *pAdapter)
{
    PMP_ADAPTER Adapter = NULL;
    PNDIS_PACKET Packet;
    PNDIS_BUFFER Buffer;
    PUCHAR pTCBMem;
    PTCB  pTCB;
    NDIS_STATUS Status;

    LONG index;

    DEBUGP(MP_TRACE, ("--> NICAllocAdapter\n"));

    PAGED_CODE();

    *pAdapter = NULL;

    do
    {
        //
        // Allocate memory for adapter context
        //
        Status = NdisAllocateMemoryWithTag(
            &Adapter, 
            sizeof(MP_ADAPTER), 
            NIC_TAG);
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("Failed to allocate memory for adapter context\n"));
            break;
        }
        //
        // Zero the memory block
        //
        NdisZeroMemory(Adapter, sizeof(MP_ADAPTER));
        NdisInitializeListHead(&Adapter->List);

        //
        // Initialize Send & Recv listheads and corresponding 
        // spinlocks.
        //
        //NdisInitializeListHead(&Adapter->RecvWaitList);
        //NdisInitializeListHead(&Adapter->SendWaitList);
        //NdisInitializeListHead(&Adapter->SendFreeList);
        NdisAllocateSpinLock(&Adapter->SendLock);                                                  

        //NdisInitializeListHead(&Adapter->RecvFreeList);
        NdisAllocateSpinLock(&Adapter->RecvLock);  


				//allocate a packet pool
				NdisAllocatePacketPool(
            &Status,
            &Adapter->LdnRecvPacketPoolHandle,
            1,
            PROTOCOL_RESERVED_SIZE_IN_PACKET);
        
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocatePacketPool failed\n"));
            break;
        }
				
				//allocate a single packet in the pool
				NdisAllocatePacket(
                &Status,
                &Adapter->LdnRecvPacket,
                Adapter->LdnRecvPacketPoolHandle);
        if(Status != NDIS_STATUS_SUCCESS)
        {
                DEBUGP(MP_ERROR, ("NdisAllocatePacket failed\n"));
                break;
        }
				
				
				//allocate a buffer pool
				NdisAllocateBufferPool(
            &Status,
            &Adapter->LdnRecvBufferPoolHandle,
            1);
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocateBufferPool for recv buffer failed\n"));
            break;
        }
				
				//allocate a single buffer in the buffer pool
				NdisAllocateBuffer(
                &Status,
                &Adapter->LdnRecvPacketBuffer,
                Adapter->LdnRecvBufferPoolHandle,
                (PVOID)&Adapter->LdnRecvPacketBufferData[0],
                NIC_BUFFER_SIZE);
        if(Status != NDIS_STATUS_SUCCESS)
        {
                DEBUGP(MP_ERROR, ("NdisAllocateBuffer failed\n"));
                break;
        }
				
				//chain the buffer to the packet
				NdisChainBufferAtBack(Adapter->LdnRecvPacket,
						Adapter->LdnRecvPacketBuffer);
				
	      NDIS_SET_PACKET_STATUS(Adapter->LdnRecvPacket, NDIS_STATUS_RESOURCES);
				NDIS_SET_PACKET_HEADER_SIZE(Adapter->LdnRecvPacket, ETH_HEADER_SIZE);
  


        /*//
        // Allocate lookside list for Receive Control blocks.
        //
        NdisInitializeNPagedLookasideList(
                    &Adapter->RecvLookaside,
                    NULL, // No Allocate function
                    NULL, // No Free function
                    0,    // Reserved for system use
                    sizeof(RCB),
                    NIC_TAG, 
                    0); // Reserved for system use
                    
        MP_SET_FLAG(Adapter, fMP_ADAPTER_RECV_LOOKASIDE); 
        
        //
        // Allocate packet pool for receive indications
        //
        NdisAllocatePacketPool(
            &Status,
            &Adapter->RecvPacketPoolHandle,
            NIC_MAX_BUSY_RECVS,
            PROTOCOL_RESERVED_SIZE_IN_PACKET);
        
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocatePacketPool failed\n"));
            break;
        }
        //
        // Initialize receive packets
        //
        for(index=0; index < NIC_MAX_BUSY_RECVS; index++)
        {
            //
            // Allocate a packet descriptor for receive packets
            // from a preallocated pool.
            //
            NdisAllocatePacket(
                &Status,
                &Packet,
                Adapter->RecvPacketPoolHandle);
            if(Status != NDIS_STATUS_SUCCESS)
            {
                DEBUGP(MP_ERROR, ("NdisAllocatePacket failed\n"));
                break;
            }
            
            NDIS_SET_PACKET_HEADER_SIZE(Packet, ETH_HEADER_SIZE);

            //
            // Insert it into the list of free receive packets.
            //
            NdisInterlockedInsertTailList(
                &Adapter->RecvFreeList, 
                (PLIST_ENTRY)&Packet->MiniportReserved[0], 
                &Adapter->RecvLock);
        }
        
        //
        // Allocate a huge block of memory for all TCB's
        //
        Status = NdisAllocateMemoryWithTag(
            &pTCBMem, 
            sizeof(TCB) * NIC_MAX_BUSY_SENDS, 
            NIC_TAG);
        
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("Failed to allocate memory for TCB's\n"));
            break;
        }
        NdisZeroMemory(pTCBMem, sizeof(TCB) * NIC_MAX_BUSY_SENDS);
        Adapter->TCBMem = pTCBMem;

        //
        // Allocate a buffer pool for send buffers.
        //

        NdisAllocateBufferPool(
            &Status,
            &Adapter->SendBufferPoolHandle,
            NIC_MAX_BUSY_SENDS);
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocateBufferPool for send buffer failed\n"));
            break;
        }

        //
        // Divide the TCBMem blob into TCBs and create a buffer
        // descriptor for the Data portion of the TCBs.
        //
        for(index=0; index < NIC_MAX_BUSY_SENDS; index++)
        {
            pTCB = (PTCB) pTCBMem;
            //
            // Create a buffer descriptor for the Data portion of the TCBs.
            // Buffer descriptors are nothing but MDLs on NT systems.
            //
            NdisAllocateBuffer(
                &Status,
                &Buffer,
                Adapter->SendBufferPoolHandle,
                (PVOID)&pTCB->Data[0],
                NIC_BUFFER_SIZE);
            if(Status != NDIS_STATUS_SUCCESS)
            {
                DEBUGP(MP_ERROR, ("NdisAllocateBuffer failed\n"));
                break;
            }

            //
            // Initialize the TCB structure.
            // 
            pTCB->Buffer = Buffer;
            pTCB->pData = (PUCHAR) &pTCB->Data[0];       
            pTCB->Adapter = Adapter;

            NdisInterlockedInsertTailList(
                &Adapter->SendFreeList, 
                &pTCB->List, 
                &Adapter->SendLock);

            pTCBMem = pTCBMem + sizeof(TCB);
        }*/

    } while(FALSE);


    *pAdapter = Adapter;

    //
    // In the failure case, the caller of this routine will end up
    // calling NICFreeAdapter to free all the successfully allocated
    // resources.
    //
    DEBUGP(MP_TRACE, ("<-- NICAllocAdapter\n"));

    return(Status);

}
Example #5
0
/*+
 *
 * AllocateAdapterMemory
 *
 * Routine Description:
 *
 *     This routine allocates memory for:
 *
 *     - Transmit descriptor ring
 *     - Receive descriptor ring
 *     - Receive buffers
 *     - Transmit buffer
 *     - Setup buffer
 *
 * Arguments:
 *
 *     Adapter - The adapter to allocate memory for.
 *
 * Functional description
 *
 *     For each allocated zone, we maintain a set of pointers:
 *        - virtual & physical addresses of the allocated block
 *        - virtual & physical addresses of the aligned structure (descriptor ring, buffer,...)
 *          whithin  the block
 *
 * Return Value:
 *
 *     Returns FALSE if an allocation fails.
 *
-*/
extern
BOOLEAN
AllocateAdapterMemory(
        IN PDC21X4_ADAPTER Adapter
        )
{
   PDC21X4_TRANSMIT_DESCRIPTOR TransmitDescriptor;
   PDC21X4_RECEIVE_DESCRIPTOR ReceiveDescriptor;

   NDIS_STATUS Status;

   PRCV_HEADER RcvHeader;
   PNDIS_PACKET Packet;

   ULONG AllocSize;
   PULONG AllocVa;
   NDIS_PHYSICAL_ADDRESS AllocPa;
   ULONG Va;

   ULONG Pa;

   UINT i;
   ULONG Offset;

   INT TransmitDescriptorRingSize;
   INT ReceiveDescriptorRingSize;

   Adapter->RcvHeaderSize =
           ((RCV_HEADER_SIZE + Adapter->CacheLineSize - 1) / Adapter->CacheLineSize)
         * Adapter->CacheLineSize;


#if _DBG
   DbgPrint("Alloc Rcv_ring[%d desc.], Txm_ring[%d desc.], setup_buf[%d]...\n",
      Adapter->ReceiveRingSize,
      TRANSMIT_RING_SIZE,
      DC21X4_SETUP_BUFFER_SIZE
      );
#endif

   // Allocate space for transmit descriptor ring,
   // the receive descriptor ring and the setup buffer

   TransmitDescriptorRingSize =
      Adapter->DescriptorSize * TRANSMIT_RING_SIZE;
   ReceiveDescriptorRingSize =
      Adapter->DescriptorSize * Adapter->ReceiveRingSize;

   Adapter->DescriptorRing.AllocSize =
      TransmitDescriptorRingSize
      + ReceiveDescriptorRingSize
      + DC21X4_SETUP_BUFFER_SIZE
      + Adapter->CacheLineSize;

   NdisMAllocateSharedMemory(
      Adapter->MiniportAdapterHandle,
      Adapter->DescriptorRing.AllocSize,
      FALSE,                                           // NON-CACHED
      (PVOID *)&Adapter->DescriptorRing.AllocVa,       // virtual ...
      &Adapter->DescriptorRing.AllocPa                 // and physical address of the allocation
      );

   // Check the allocation success

   if ((PVOID)Adapter->DescriptorRing.AllocVa == (PVOID)NULL) {
      return FALSE;
   }
   if (NdisGetPhysicalAddressHigh(Adapter->DescriptorRing.AllocPa) != 0) {
      return FALSE;
   }

   NdisZeroMemory (
      (PVOID)(Adapter->DescriptorRing.AllocVa),
      (ULONG)(Adapter->DescriptorRing.AllocSize)
      );

   // Align to the next cache line boundary

   AlignStructure (
      &Adapter->DescriptorRing,
      Adapter->CacheLineSize
      );

   Adapter->TransmitDescriptorRingVa = Adapter->DescriptorRing.Va;
   Adapter->TransmitDescriptorRingPa = Adapter->DescriptorRing.Pa;
   Offset = TransmitDescriptorRingSize;

   Adapter->ReceiveDescriptorRingVa =  Adapter->DescriptorRing.Va + Offset;
   Adapter->ReceiveDescriptorRingPa =  Adapter->DescriptorRing.Pa + Offset;
   Offset += ReceiveDescriptorRingSize;

   Adapter->SetupBufferVa = Adapter->DescriptorRing.Va + Offset;
   Adapter->SetupBufferPa = Adapter->DescriptorRing.Pa + Offset;

   //Initialize the setup buffer

   NdisZeroMemory (
      (PVOID)(Adapter->SetupBufferVa),
      DC21X4_SETUP_BUFFER_SIZE
      );


   // Allocate a pool of NDIS buffers

   NdisAllocateBufferPool(
        &Status,
        &Adapter->FlushBufferPoolHandle,
        ( Adapter->ReceiveRingSize
        + Adapter->ExtraReceiveBuffers
        + DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS
        + DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS )
        );

   if (Status != NDIS_STATUS_SUCCESS) {
      return FALSE;
   }


   //  Allocate a pool of packets.
#if _DBG
   DbgPrint("Allocate PacketPool [%d packets]\n",
      Adapter->ExtraReceivePackets);
#endif
   NdisAllocatePacketPool(
      &Status,
      &Adapter->ReceivePacketPool,
      Adapter->ExtraReceivePackets,
      0
      );

   if (Status != NDIS_STATUS_SUCCESS) {
      return FALSE;
   }

   // Allocate all of the packets out of the packet pool
   // and place them on a queue.

   for (i = 0; i < Adapter->ExtraReceivePackets; i++) {

      // Allocate a packet from the pool.
      NdisAllocatePacket(
         &Status,
         &Packet,
         Adapter->ReceivePacketPool
         );
      if (Status != NDIS_STATUS_SUCCESS) {
         return(FALSE);
      }

      // Set the header size in the packet's Out-Of-Band information.
      // All other fields in the Out-Of-Band information have been
      // initialized to 0 by NdisAllocatePacket().

      NDIS_SET_PACKET_HEADER_SIZE(Packet, ETH_HEADER_SIZE);

      // Place it on the receive packet free list.

      RCV_RESERVED(Packet)->Next = Adapter->FreePacketList;
      Adapter->FreePacketList = Packet;
   }

   //  Clear out the free receive list of buffers.
   Adapter->FreeRcvList = NULL;


   //  We allocate the receive buffers.  We allocate both
   //  the buffers for the descriptor ring and the extra
   //  buffers and place them all on the free queue.

#if _DBG
   DbgPrint("Allocate Receive Buffers [%d]\n",
      Adapter->ExtraReceiveBuffers+Adapter->ReceiveRingSize);
#endif

   // Attempt to allocate all the receive buffer space
   // in one block
   // If it fails,allocate each buffer individually

   //  Allocation size
   Adapter->RcvBufferSpace.AllocSize =
      ((Adapter->ExtraReceiveBuffers + Adapter->ReceiveRingSize)
      * (DC21X4_RECEIVE_BUFFER_SIZE + Adapter->RcvHeaderSize))
      + Adapter->CacheLineSize;


   NdisMAllocateSharedMemory(
      Adapter->MiniportAdapterHandle,
      Adapter->RcvBufferSpace.AllocSize,
      TRUE,
      (PVOID *)&Adapter->RcvBufferSpace.AllocVa,
      &Adapter->RcvBufferSpace.AllocPa
      );

   // Check the allocation success
   if (((PVOID)Adapter->RcvBufferSpace.AllocVa != (PVOID)NULL)
      && (NdisGetPhysicalAddressHigh(Adapter->RcvBufferSpace.AllocPa) == 0)) {

        NdisZeroMemory (
          (PVOID)(Adapter->RcvBufferSpace.AllocVa),
          (ULONG)(Adapter->RcvBufferSpace.AllocSize)
          );

       // Align to the next cache line boundary

       AlignStructure (
          &Adapter->RcvBufferSpace,
          Adapter->CacheLineSize
          );

       //  Allocation size needed for the receive buffer
       AllocSize = DC21X4_RECEIVE_BUFFER_SIZE
                 + Adapter->RcvHeaderSize;
       Offset=0;
   }
   else
   {
       //  Allocation size needed for the receive buffer
       AllocSize = DC21X4_RECEIVE_BUFFER_SIZE
                 + Adapter->RcvHeaderSize
                 + Adapter->CacheLineSize;


       Adapter->RcvBufferSpace.Va=0;
   }

   for (i = 0;
      i < (Adapter->ExtraReceiveBuffers + Adapter->ReceiveRingSize);
      i++
      ) {

      if (Adapter->RcvBufferSpace.Va != 0) {

          Va = Adapter->RcvBufferSpace.Va + Offset;
          Pa = Adapter->RcvBufferSpace.Pa + Offset;
          Offset += AllocSize;

      }
      else
      {
          //  Allocate a receive buffer.

          NdisMAllocateSharedMemory(
             Adapter->MiniportAdapterHandle,
             AllocSize,
             TRUE,
             (PVOID *)&AllocVa,
             &AllocPa
             );
          if (((PVOID)AllocVa == (PVOID)NULL)
             || (NdisGetPhysicalAddressHigh(AllocPa) != 0)) {
             return FALSE;
          }

          NdisZeroMemory(AllocVa, AllocSize);

          //  Align on the cache line boundary

          Offset = Adapter->CacheLineSize - ((ULONG)AllocVa % Adapter->CacheLineSize);
          Va = (ULONG)(AllocVa) + Offset;
          Pa = NdisGetPhysicalAddressLow(AllocPa) + Offset;

      }

      //The receive header points to the aligned va.

      RcvHeader = (PRCV_HEADER)Va;

      RcvHeader->AllocVa = (ULONG)AllocVa;
      RcvHeader->AllocPa = AllocPa;
      RcvHeader->AllocSize = (USHORT)AllocSize;

      // These addresses point to the data buffer

      RcvHeader->Va = (ULONG)(Va + Adapter->RcvHeaderSize);
      RcvHeader->Pa = Pa + Adapter->RcvHeaderSize;
      RcvHeader->Size = DC21X4_RECEIVE_BUFFER_SIZE;

#if DBG
      RcvHeader->Signature = 'dHxR';
#if _DBG
      DbgPrint(
         "%-3d RcvHeader: %lx, RcvBuffer: %lx/%lx, HeaderSize: %lx\n",
         i,RcvHeader,
         RcvHeader->Va,
         RcvHeader->Pa,
         Adapter->RcvHeaderSize
         );
#endif
#endif
      //  Allocate an NDIS flush buffer for each receive buffer.

      NdisAllocateBuffer(
         &Status,
         &RcvHeader->FlushBuffer,
         Adapter->FlushBufferPoolHandle,
         (PVOID)RcvHeader->Va,
         DC21X4_RECEIVE_BUFFER_SIZE
         );
      if (Status != NDIS_STATUS_SUCCESS) {
         return FALSE;
      }

      // Grab a packet off of the free packet list and
      // associate it with the buffer.

      Packet = Adapter->FreePacketList;
      Adapter->FreePacketList = RCV_RESERVED(Packet)->Next;

      // Chain the buffer on the packet.

      NdisChainBufferAtFront(Packet, RcvHeader->FlushBuffer);

      // Save a pointer to the receive header with the packet.

      RCV_RESERVED(Packet)->RcvHeader = RcvHeader;

      // Save the packet with the receive header.

      RcvHeader->Packet = Packet;

      // Place the descriptor on the free queue.

      RcvHeader->Next = Adapter->FreeRcvList;
      Adapter->FreeRcvList = RcvHeader;

      Adapter->CurrentReceiveBufferCount++;
   }


#if _DBG
   DbgPrint("Init Rcv ring..\n");
#endif

   //  Assign the receive buffers to the descriptors.

   for (i = 0,
      ReceiveDescriptor = (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa,
      Pa = Adapter->ReceiveDescriptorRingPa;
      i < Adapter->ReceiveRingSize;
      i++,
      (PCHAR)ReceiveDescriptor += Adapter->DescriptorSize,
      Pa += Adapter->DescriptorSize
      ) {

      // Grab a receive buffer from the free list.

      ASSERT(Adapter->FreeRcvList != NULL);
      RcvHeader = Adapter->FreeRcvList;
      Adapter->FreeRcvList = RcvHeader->Next;

      Adapter->CurrentReceiveBufferCount--;

      // Associate the buffer with the descriptor.

      ReceiveDescriptor->RcvHeader = RcvHeader;
      ReceiveDescriptor->FirstBufferAddress = RcvHeader->Pa;


      ReceiveDescriptor->Status = DESC_OWNED_BY_DC21X4;
      ReceiveDescriptor->Control = DC21X4_RECEIVE_BUFFER_SIZE;

      ReceiveDescriptor->Next =
         (PDC21X4_RECEIVE_DESCRIPTOR)((PCHAR)ReceiveDescriptor + Adapter->DescriptorSize);

   }

   //last descriptor of the ring

   (PCHAR)ReceiveDescriptor -= Adapter->DescriptorSize;
   ReceiveDescriptor->Control |= DC21X4_RDES_SECOND_ADDR_CHAINED;
   ReceiveDescriptor->SecondBufferAddress = Adapter->ReceiveDescriptorRingPa;
   ReceiveDescriptor->Next =
      (PDC21X4_RECEIVE_DESCRIPTOR)Adapter->ReceiveDescriptorRingVa;

#if _DBG
   DbgPrint("Init Txm ring..\n");
#endif

   // Initialize the Transmit Descriptor ring

   for (i=0,
      TransmitDescriptor = (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa,
      Pa = Adapter->TransmitDescriptorRingPa;
      i < TRANSMIT_RING_SIZE;
      i++,
      (PCHAR)TransmitDescriptor += Adapter->DescriptorSize,
      Pa += Adapter->DescriptorSize
      ) {

      TransmitDescriptor->MapTableIndex = i * NUMBER_OF_SEGMENT_PER_DESC;
      TransmitDescriptor->DescriptorPa = Pa;
      TransmitDescriptor->Next =
         (PDC21X4_TRANSMIT_DESCRIPTOR)((PCHAR)TransmitDescriptor + Adapter->DescriptorSize);

   }

   //last descriptor of the ring
   (PCHAR)TransmitDescriptor -= Adapter->DescriptorSize;
   TransmitDescriptor->Control = DC21X4_TDES_SECOND_ADDR_CHAINED;
   TransmitDescriptor->SecondBufferAddress = Adapter->TransmitDescriptorRingPa;
   TransmitDescriptor->Next =
      (PDC21X4_TRANSMIT_DESCRIPTOR)Adapter->TransmitDescriptorRingVa;


   // Txm buffers

   for (i = 0;i < DC21X4_NUMBER_OF_MAX_TRANSMIT_BUFFERS;i ++) {

      Adapter->MaxTransmitBuffer[i].AllocSize =
         DC21X4_MAX_TRANSMIT_BUFFER_SIZE + Adapter->CacheLineSize;

      NdisMAllocateSharedMemory(
         Adapter->MiniportAdapterHandle,
         Adapter->MaxTransmitBuffer[i].AllocSize,
         TRUE,                                           // CACHED
         (PVOID *)&Adapter->MaxTransmitBuffer[i].AllocVa,   // virtual ...
         &Adapter->MaxTransmitBuffer[i].AllocPa             // and physical address of the buffer allocation
         );

      // Check the allocation success

      if (((PVOID)Adapter->MaxTransmitBuffer[i].AllocVa == (PVOID)NULL)
         || (NdisGetPhysicalAddressHigh(Adapter->MaxTransmitBuffer[i].AllocPa) != 0)) {
         return FALSE;
      }

      // Align the buffer on the cache line boundary

      AlignStructure (
         &Adapter->MaxTransmitBuffer[i],
         Adapter->CacheLineSize
         );


      // Allocate an NDIS flush buffer for each transmit buffer

      NdisAllocateBuffer(
         &Status,
         &Adapter->MaxTransmitBuffer[i].FlushBuffer,
         Adapter->FlushBufferPoolHandle,
         (PVOID)Adapter->MaxTransmitBuffer[i].Va,
         DC21X4_MAX_TRANSMIT_BUFFER_SIZE
         );

      if (Status != NDIS_STATUS_SUCCESS) {
         return FALSE;
      }
   }

   // Allocate the minimal packet buffers

   Adapter->MinTransmitBuffer[0].AllocSize =
       (DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS * DC21X4_MIN_TRANSMIT_BUFFER_SIZE)
     + Adapter->CacheLineSize;

   NdisMAllocateSharedMemory(
     Adapter->MiniportAdapterHandle,
     Adapter->MinTransmitBuffer[0].AllocSize,
     TRUE,                                              // CACHED
     (PVOID *)&Adapter->MinTransmitBuffer[0].AllocVa,   // virtual ...
     &Adapter->MinTransmitBuffer[0].AllocPa             // and physical address of the buffer allocation
     );

   // Check the allocation success

   if (((PVOID)Adapter->MinTransmitBuffer[0].AllocVa == (PVOID)NULL)
       || (NdisGetPhysicalAddressHigh(Adapter->MinTransmitBuffer[0].AllocPa) != 0)) {

	  Adapter->DontUseMinTransmitBuffer = TRUE;
      return TRUE;
   }

   // Align the buffer on the cache line boundary

   AlignStructure (
      &Adapter->MinTransmitBuffer[0],
      Adapter->CacheLineSize
      );

   for (i = 0;i < DC21X4_NUMBER_OF_MIN_TRANSMIT_BUFFERS;i ++) {

      Offset = i * DC21X4_MIN_TRANSMIT_BUFFER_SIZE;

      Adapter->MinTransmitBuffer[i].Va =
          Adapter->MinTransmitBuffer[0].Va + Offset;

      Adapter->MinTransmitBuffer[i].Pa =
          Adapter->MinTransmitBuffer[0].Pa + Offset;

      // Allocate an NDIS flush buffer for each transmit buffer

      NdisAllocateBuffer(
         &Status,
         &Adapter->MinTransmitBuffer[i].FlushBuffer,
         Adapter->FlushBufferPoolHandle,
         (PVOID)Adapter->MinTransmitBuffer[i].Va,
         DC21X4_MIN_TRANSMIT_BUFFER_SIZE
         );

      if (Status != NDIS_STATUS_SUCCESS) {
         return FALSE;
      }
   }

   // Allocation has completed successfully

   return TRUE;
}
Example #6
0
static
NDIS_STATUS
BindAdapterByName(PNDIS_STRING DeviceName)
{
    NDIS_STATUS OpenErrorStatus;
    PNDISUIO_ADAPTER_CONTEXT AdapterContext;
    NDIS_MEDIUM SupportedMedia[1] = {NdisMedium802_3};
    UINT SelectedMedium;
    NDIS_STATUS Status;
    NDIS_REQUEST Request;

    /* Allocate the adapter context */
    AdapterContext = ExAllocatePool(NonPagedPool, sizeof(*AdapterContext));
    if (!AdapterContext)
    {
        return NDIS_STATUS_RESOURCES;
    }

    /* Set up the adapter context */
    RtlZeroMemory(AdapterContext, sizeof(*AdapterContext));
    KeInitializeEvent(&AdapterContext->AsyncEvent, SynchronizationEvent, FALSE);
    KeInitializeEvent(&AdapterContext->PacketReadEvent, SynchronizationEvent, FALSE);
    KeInitializeSpinLock(&AdapterContext->Spinlock);
    InitializeListHead(&AdapterContext->PacketList);
    InitializeListHead(&AdapterContext->OpenEntryList);
    AdapterContext->OpenCount = 0;

    AdapterContext->DeviceName.Length =
    AdapterContext->DeviceName.MaximumLength = DeviceName->Length;
    AdapterContext->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceName->Length);
    if (!AdapterContext->DeviceName.Buffer)
    {
        ExFreePool(AdapterContext);
        return NDIS_STATUS_RESOURCES;
    }

    /* Copy the device name into the adapter context */
    RtlCopyMemory(AdapterContext->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
    
    DPRINT("Binding adapter %wZ\n", &AdapterContext->DeviceName);

    /* Create the buffer pool */
    NdisAllocateBufferPool(&Status,
                           &AdapterContext->BufferPoolHandle,
                           50);
    if (Status != NDIS_STATUS_SUCCESS)
    {
        DPRINT1("Failed to allocate buffer pool with status 0x%x\n", Status);
        RtlFreeUnicodeString(&AdapterContext->DeviceName);
        ExFreePool(AdapterContext);
        return Status;
    }

    /* Create the packet pool */
    NdisAllocatePacketPool(&Status,
                           &AdapterContext->PacketPoolHandle,
                           25,
                           PROTOCOL_RESERVED_SIZE_IN_PACKET);
    if (Status != NDIS_STATUS_SUCCESS)
    {
        DPRINT1("Failed to allocate packet pool with status 0x%x\n", Status);
        NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
        RtlFreeUnicodeString(&AdapterContext->DeviceName);
        ExFreePool(AdapterContext);
        return Status;
    }

    /* Send the open request */
    NdisOpenAdapter(&Status,
                    &OpenErrorStatus,
                    &AdapterContext->BindingHandle,
                    &SelectedMedium,
                    SupportedMedia,
                    1,
                    GlobalProtocolHandle,
                    AdapterContext,
                    DeviceName,
                    0,
                    NULL);
    
    /* Wait for a pending open */
    if (Status == NDIS_STATUS_PENDING)
    {
        KeWaitForSingleObject(&AdapterContext->AsyncEvent,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);
        Status = AdapterContext->AsyncStatus;
    }
    
    /* Check the final status */
    if (Status != NDIS_STATUS_SUCCESS)
    {
        DPRINT1("Failed to open adapter for bind with status 0x%x\n", Status);
        NdisFreePacketPool(AdapterContext->PacketPoolHandle);
        NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
        RtlFreeUnicodeString(&AdapterContext->DeviceName);
        ExFreePool(AdapterContext);
        return Status;
    }
    
    /* Get the MAC options */
    Request.RequestType = NdisRequestQueryInformation;
    Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAC_OPTIONS;
    Request.DATA.QUERY_INFORMATION.InformationBuffer = &AdapterContext->MacOptions;
    Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(ULONG);
    NdisRequest(&Status,
                AdapterContext->BindingHandle,
                &Request);

    /* Wait for a pending request */
    if (Status == NDIS_STATUS_PENDING)
    {
        KeWaitForSingleObject(&AdapterContext->AsyncEvent,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);
        Status = AdapterContext->AsyncStatus;
    }
    
    /* Check the final status */
    if (Status != NDIS_STATUS_SUCCESS)
    {
        NDIS_STATUS CloseStatus;

        DPRINT1("Failed to get MAC options with status 0x%x\n", Status);

        NdisCloseAdapter(&CloseStatus,
                         AdapterContext->BindingHandle);
        if (CloseStatus == NDIS_STATUS_PENDING)
        {
            KeWaitForSingleObject(&AdapterContext->AsyncEvent,
                                  Executive,
                                  KernelMode,
                                  FALSE,
                                  NULL);
        }

        NdisFreePacketPool(AdapterContext->PacketPoolHandle);
        NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
        RtlFreeUnicodeString(&AdapterContext->DeviceName);
        ExFreePool(AdapterContext);
        return Status;
    }
    
    /* Add the adapter context to the global list */
    ExInterlockedInsertTailList(&GlobalAdapterList,
                                &AdapterContext->ListEntry,
                                &GlobalAdapterListLock);

    return STATUS_SUCCESS;
}
Example #7
0
NTSTATUS
DriverEntry (
	PDRIVER_OBJECT DriverObject,
	PUNICODE_STRING RegistryString
	)
/*++

Routine Description:

	Diver entry point. Initializes global variables and complete hook operation.


Arguments:

	DriverObject - A pointer to this driver, provided by system.

	RegistryString - A pointer to register path used by this driver, provided by system.


Return Value:

	Returns corresponding NTSTATUS to indicate success or failure.


Author:

	xiaonie

	2012/07/12


--*/
{
	NTSTATUS status;
	DbgPrint("NDIS Hook ------ start!\r\n");

	// check os version
	if (OS_VERSION_XP != GetOsVersion()) {
		DbgPrint("Only XP supported!\r\n");
		return STATUS_UNSUCCESSFUL;
	}

	// setup unload routine for this driver
	DriverObject->DriverUnload = OnUnload;

	// init global viaribles.
	KeInitializeSpinLock(&g_lock);
	InitializeListHead(&g_linkListHead);

	NdisAllocatePacketPool(&status,&g_PacketPool, 0x1000, PROTOCOL_RESERVED_SIZE_IN_PACKET);
	if (status != NDIS_STATUS_SUCCESS/* || g_PacketPool == NULL*/) {
		DbgPrint("alloc packet pool failed!\r\n");
		return status;
	}

	NdisAllocateBufferPool(&status, &g_BufferPool, 0x10);
	if(status != NDIS_STATUS_SUCCESS/* || g_BufferPool == NULL*/) {
		DbgPrint("alloc buffer pool failed!\r\n");
		NdisFreePacketPool(g_PacketPool);
		return status;
	}

	// hook nids routines
	status = HookNdis();

	if (!NT_SUCCESS(status)) {
		DbgPrint("HookNdis failed!\r\n");
		NdisFreeBufferPool(g_BufferPool);
		NdisFreePacketPool(g_PacketPool);
	}
	return status;
}
Example #8
0
VOID
	natpBindAdapter(
		OUT PNDIS_STATUS Status,
		IN  NDIS_HANDLE BindContext,
		IN  PNDIS_STRING DeviceName,
		IN  PVOID SystemSpecific1,
		IN  PVOID SystemSpecific2
		)
{
	NDIS_HANDLE ConfigHandle = NULL;
	PNDIS_CONFIGURATION_PARAMETER Param;
	NDIS_STRING DeviceStr = UPPER_BINDINGS;
	PFILTER_ADAPTER pAdapt = NULL;
	NDIS_STATUS Sts;
	UINT MediumIndex, i;
	ULONG TotalSize;
	WCHAR DevicePrefix[]  = L"\\Device\\";

	UNREFERENCED_PARAMETER(BindContext);
	UNREFERENCED_PARAMETER(SystemSpecific2);

	__try{
		
		NdisOpenProtocolConfiguration(
			Status,
			&ConfigHandle,
			SystemSpecific1
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisReadConfiguration(
			Status,
			&Param,
			ConfigHandle,
			&DeviceStr,
			NdisParameterString
			);
		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		TotalSize = sizeof(FILTER_ADAPTER) + Param->ParameterData.StringData.MaximumLength + DeviceName->MaximumLength;
		NdisAllocateMemoryWithTag(&pAdapt, TotalSize, NAT_TAG);

		if (NULL == pAdapt){
			*Status = NDIS_STATUS_RESOURCES;
			__leave;
		}


		NdisZeroMemory(pAdapt, TotalSize);
		pAdapt->DeviceName.MaximumLength = Param->ParameterData.StringData.MaximumLength;
		pAdapt->DeviceName.Length = Param->ParameterData.StringData.Length;
		pAdapt->DeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(FILTER_ADAPTER));
		NdisMoveMemory(
			pAdapt->DeviceName.Buffer,
			Param->ParameterData.StringData.Buffer,
			Param->ParameterData.StringData.MaximumLength
			);
		if(sizeof(DevicePrefix) >= DeviceName->Length){
		
			
		}else{
		
			pAdapt->RootDeviceName.MaximumLength = DeviceName->MaximumLength;
			pAdapt->RootDeviceName.Length = DeviceName->Length - sizeof(DevicePrefix) + sizeof(WCHAR);
			pAdapt->RootDeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(FILTER_ADAPTER) + Param->ParameterData.StringData.MaximumLength);
			NdisMoveMemory(
				pAdapt->RootDeviceName.Buffer,
				DeviceName->Buffer + sizeof(DevicePrefix)/sizeof(WCHAR) - 1,
				DeviceName->MaximumLength - sizeof(DevicePrefix)/sizeof(WCHAR) + 1
				);
		}

		NdisInitializeEvent(&pAdapt->Event);
		NdisAllocateSpinLock(&pAdapt->Lock);

		natInitControlBlock(&pAdapt->ctrl);

		NdisAllocatePacketPoolEx(
			Status,
			&pAdapt->SndPP1,
			MIN_PACKET_POOL_SIZE,
			MAX_PACKET_POOL_SIZE,
			PROTOCOL_RESERVED_SIZE_IN_PACKET
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisAllocatePacketPoolEx(
			Status,
			&pAdapt->SndPP2,
			MIN_PACKET_POOL_SIZE,
			MAX_PACKET_POOL_SIZE,
			PROTOCOL_RESERVED_SIZE_IN_PACKET
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisAllocateBufferPool(
			Status,
			&pAdapt->SndBP,
			MIN_PACKET_POOL_SIZE
			);
		if ( *Status != NDIS_STATUS_SUCCESS )
			__leave;

		NdisAllocatePacketPoolEx(
			Status,
			&pAdapt->RcvPP1,
			MIN_PACKET_POOL_SIZE,
			MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
			PROTOCOL_RESERVED_SIZE_IN_PACKET
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisAllocatePacketPoolEx(
			Status,
			&pAdapt->RcvPP2,
			MIN_PACKET_POOL_SIZE,
			MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
			PROTOCOL_RESERVED_SIZE_IN_PACKET
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisAllocateBufferPool(
			Status,
			&pAdapt->RcvBP,
			MIN_PACKET_POOL_SIZE
			);
		if ( *Status != NDIS_STATUS_SUCCESS )
			__leave;

		NdisOpenAdapter(
			Status,
			&Sts,
			&pAdapt->BindingHandle,
			&MediumIndex,
			MediumArray,
			sizeof(MediumArray)/sizeof(NDIS_MEDIUM),
			ProtHandle,
			pAdapt,
			DeviceName,
			0,NULL
			);

		if (*Status == NDIS_STATUS_PENDING){
			NdisWaitEvent(&pAdapt->Event, 0);
			*Status = pAdapt->Status;
		}

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;
		pAdapt->Medium = MediumArray[MediumIndex];

		pAdapt->MiniportInitPending = TRUE;
		NdisInitializeEvent(&pAdapt->MiniportInitEvent);

		*Status = 
			NdisIMInitializeDeviceInstanceEx(
				DriverHandle,
				&pAdapt->DeviceName,
				pAdapt
				);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;
		StartQueryInfo( pAdapt );

	} __finally{
	}

	if (ConfigHandle != NULL)
		NdisCloseConfiguration(ConfigHandle);

	if(NDIS_STATUS_SUCCESS != *Status){
		
		if (pAdapt != NULL){
			
			if (pAdapt->BindingHandle != NULL){

				NDIS_STATUS    LocalStatus;

				NdisResetEvent(&pAdapt->Event);

				NdisCloseAdapter(&LocalStatus, pAdapt->BindingHandle);
				pAdapt->BindingHandle = NULL;

				if (LocalStatus == NDIS_STATUS_PENDING){
					NdisWaitEvent(&pAdapt->Event, 0);
					LocalStatus = pAdapt->Status;
				}
			}

			natFreeAllItems(&pAdapt->ctrl);
			natFreeAllFwSessionsAndRules(&pAdapt->ctrl);

			for(i = 0;i<FLT_FW_SESSION_HASH_TBL_SZ;i++)
				NdisFreeSpinLock(pAdapt->ctrl.FwSessionLocks + i);

			NdisFreeSpinLock(&pAdapt->ctrl.IcmpRuleLock);
			NdisFreeSpinLock(&pAdapt->ctrl.UdpRuleLock);
			NdisFreeSpinLock(&pAdapt->ctrl.TcpRuleLock);

			natmFreeAllPacketPools(pAdapt);

			NdisFreeSpinLock(&pAdapt->Lock);

			NdisFreeMemory(pAdapt, 0, 0);
			pAdapt = NULL;
		}
	}
}
Example #9
0
/******************************************************************************
 *
 *  Name: AllocateRxQ()
 *
 *  Description: Allocate Rx Buffer
 *
 *  Arguments:  PMRVDRV_ADAPTER Adapter
 *    
 *  Return Value: NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE
 * 
 *  Notes:        
 *
 *****************************************************************************/
NDIS_STATUS AllocateRxQ(
  IN PMRVDRV_ADAPTER Adapter
  )
{

  ULONG i;
    NDIS_STATUS tStatus;
    BOOLEAN                 bSuccess = TRUE;
    PACKET_QUEUE_NODE       **pNode;
    PNDIS_PACKET_OOB_DATA   pOOB; 

    /// Initialize rx-related variables 
    Adapter->RxBufferPoolHandle = 
    Adapter->RxPacketPoolHandle = NULL;
    //
    InitializeQKeeper(&Adapter->RxPacketFreeQueue);
    // 
    for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
    {
        Adapter->pRxBufVM[i] = NULL;
        Adapter->pRxBuffer[i] = NULL;
        Adapter->pRxPacket[i] = NULL;
    }

    /// Allocate all needed memory space 
    do
    {
     // packet pool 
     NdisAllocatePacketPoolEx(
                                &tStatus, 
                                &Adapter->RxPacketPoolHandle,
                                MRVDRV_NUM_RX_PKT_IN_QUEUE,
                                MRVDRV_NUM_RX_PKT_IN_QUEUE, 
                                PROTOCOL_RESERVED_SIZE_IN_PACKET);

        if ( tStatus != NDIS_STATUS_SUCCESS )
        {
            DBGPRINT(DBG_LOAD | DBG_ERROR,
                    (L"Unable to allocate packet pool!\n"));
            return tStatus;
        }

        // buffer pool 
        NdisAllocateBufferPool(
                               &tStatus,
                               &Adapter->RxBufferPoolHandle,
                               MRVDRV_NUM_RX_PKT_IN_QUEUE);
        
        if ( tStatus != NDIS_STATUS_SUCCESS )
        {
            DBGPRINT(DBG_LOAD | DBG_ERROR,
                    (L"Unable to allocate buffer pool!\n"));
            bSuccess = FALSE;
            break;
        }

    // assign space to used three array 
        for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ )
        {                          
          // data payload space array 
           tStatus = NdisAllocateMemoryWithTag(
                         &Adapter->pRxBufVM[i], 
                         MRVDRV_ETH_RX_PACKET_BUFFER_SIZE,
                         MRVDRV_MEMORY_TAG);
           //to hide unused packet header ahead of pointer.   
           //(ULONG)Adapter->pRxBufVM[i] += (sizeof(RxPD)+sizeof(pkt.Len)+sizeof(pkt.Type));
           (ULONG)Adapter->pRxBufVM[i] += MRVDRV_ETH_RX_HIDDEN_HEADER_SIZE;

            if ( tStatus != NDIS_STATUS_SUCCESS )
            {
                bSuccess = FALSE;
                break;
            }
                      
            // buffer array 
            NdisAllocateBuffer(
                                &tStatus,
                                &Adapter->pRxBuffer[i],
                                Adapter->RxBufferPoolHandle,
                                Adapter->pRxBufVM[i],
                                (MRVDRV_ETH_RX_PACKET_BUFFER_SIZE-MRVDRV_ETH_RX_HIDDEN_HEADER_SIZE));

            if ( tStatus != NDIS_STATUS_SUCCESS )
            {
                bSuccess = FALSE;
                break;
            }

      // packet array   
            NdisAllocatePacket(
                               &tStatus, 
                               &Adapter->pRxPacket[i],
                               Adapter->RxPacketPoolHandle);

            if ( tStatus != NDIS_STATUS_SUCCESS )
            {
                bSuccess = FALSE;
                break;
            }

            // init OBB space
            pOOB = NDIS_OOB_DATA_FROM_PACKET(Adapter->pRxPacket[i]);
            NdisZeroMemory(pOOB, sizeof(NDIS_PACKET_OOB_DATA));
            NDIS_SET_PACKET_HEADER_SIZE(Adapter->pRxPacket[i], MRVDRV_ETH_HEADER_SIZE);

            // chain the packet and buffer 
            NdisChainBufferAtFront(Adapter->pRxPacket[i],
                                   Adapter->pRxBuffer[i]);

            // fill packet node 
            Adapter->RxPacketQueueNode[i].pPacket = Adapter->pRxPacket[i];
    
            pNode = (PACKET_QUEUE_NODE **)Adapter->pRxPacket[i]->MiniportReserved;
            *pNode = &Adapter->RxPacketQueueNode[i];
            
            // insert to free queue
            InsertQNodeAtTail(&Adapter->RxPacketFreeQueue, &Adapter->RxPacketQueueNode[i]);

        }   // end of for(;;)

    } while (0);

    if ( ! bSuccess )
    {
        // clean up all
        FreeRxQ(Adapter);
        return NDIS_STATUS_FAILURE;
    }

    Adapter->sNumOutstandingRxPacket = 0;

    return NDIS_STATUS_SUCCESS;
}
Example #10
0
NTSTATUS NTAPI
TiDispatch(
  PDEVICE_OBJECT DeviceObject,
  PIRP Irp)
/*
 * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
 * ARGUMENTS:
 *     DeviceObject = Pointer to a device object for this driver
 *     Irp          = Pointer to a I/O request packet
 * RETURNS:
 *     Status of the operation
 */
{


  NTSTATUS Status;
  PIO_STACK_LOCATION IrpSp;

  IrpSp  = IoGetCurrentIrpStackLocation(Irp);

  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Called. IRP is at (0x%X).\n", Irp));
  DbgPrint("TiDispatch Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp);
  Irp->IoStatus.Information = 0;

#if 0
  Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp);
  if (NT_SUCCESS(Status)) {
    TiDispatchInternal(DeviceObject, Irp);
    Status = STATUS_PENDING;
  } else {
#else
  if (TRUE) {
#endif
    /* See if this request is TCP/IP specific */
    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
    case IOCTL_TCP_QUERY_INFORMATION_EX:
      TI_DbgPrint(MIN_TRACE, ("TCP_QUERY_INFORMATION_EX\n"));
      Status = DispTdiQueryInformationEx(Irp, IrpSp);
      break;

    case IOCTL_TCP_SET_INFORMATION_EX:
      TI_DbgPrint(MIN_TRACE, ("TCP_SET_INFORMATION_EX\n"));
      Status = DispTdiSetInformationEx(Irp, IrpSp);
      break;

    case IOCTL_SET_IP_ADDRESS:
      TI_DbgPrint(MIN_TRACE, ("SET_IP_ADDRESS\n"));
      Status = DispTdiSetIPAddress(Irp, IrpSp);
      break;

    case IOCTL_DELETE_IP_ADDRESS:
      TI_DbgPrint(MIN_TRACE, ("DELETE_IP_ADDRESS\n"));
      Status = DispTdiDeleteIPAddress(Irp, IrpSp);
      break;

    default:
      TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n",
          IrpSp->Parameters.DeviceIoControl.IoControlCode));
      Status = STATUS_NOT_IMPLEMENTED;
      break;
    }
  }

  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Leaving. Status = (0x%X).\n", Status));

  return IRPFinish( Irp, Status );


}
NTSTATUS
DriverEntry(
		  PDRIVER_OBJECT DriverObject,
		  PUNICODE_STRING RegistryPath)
{
  NTSTATUS Status;
  UNICODE_STRING strIpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME);
  UNICODE_STRING strRawDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME);
  UNICODE_STRING strUdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME);
  UNICODE_STRING strTcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME);
  UNICODE_STRING strNdisDeviceName = RTL_CONSTANT_STRING(TCPIP_PROTOCOL_NAME);
  NDIS_STATUS NdisStatus;
  LARGE_INTEGER DueTime;
  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] \n"));
  
  //_asm int 3;

  KdPrint(("driver entery..................\n"));

  /* TdiInitialize() ? */

  /* FIXME: Create symbolic links in Win32 namespace */

  /* Initialize our periodic timer and its associated DPC object. When the
     timer expires, the IPTimeout deferred procedure call (DPC) is queued */
  KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
  KeInitializeTimer(&IPTimer);
	 
  /* Create IP device object */
  Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  ChewInit( IPDeviceObject );
	 

  /* Create RawIP device object */
  Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create UDP device object */
  Status = IoCreateDevice(DriverObject, 0, &strUdpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create TCP device object */
  Status = IoCreateDevice(DriverObject, 0, &strTcpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }


  /* Setup network layer and transport layer entities */
  KeInitializeSpinLock(&EntityListLock);
  EntityList = ExAllocatePoolWithTag(NonPagedPool,
                                     sizeof(TDIEntityID) * MAX_TDI_ENTITIES,
                                     TDI_ENTITY_TAG );

  if (!EntityList) {
    TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  EntityCount = 0;
  EntityMax   = MAX_TDI_ENTITIES;

  /* Allocate NDIS packet descriptors */
  NdisAllocatePacketPoolEx(&NdisStatus, &GlobalPacketPool, 500, 1500, sizeof(PACKET_CONTEXT));
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Allocate NDIS buffer descriptors */
  NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 2000);
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Initialize address file list and protecting spin lock */
  InitializeListHead(&AddressFileListHead);
  KeInitializeSpinLock(&AddressFileListLock);

  /* Initialize connection endpoint list and protecting spin lock */
  InitializeListHead(&ConnectionEndpointListHead);
  KeInitializeSpinLock(&ConnectionEndpointListLock);

  /* Initialize interface list and protecting spin lock */
  InitializeListHead(&InterfaceListHead);
  KeInitializeSpinLock(&InterfaceListLock);



  /* Initialize network level protocol subsystem */
  IPStartup(RegistryPath);

  /* Initialize transport level protocol subsystems */
  Status = RawIPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = UDPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = TCPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = ICMPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  /* Use direct I/O */
  IPDeviceObject->Flags    |= DO_DIRECT_IO;
  RawIPDeviceObject->Flags |= DO_DIRECT_IO;
  UDPDeviceObject->Flags   |= DO_DIRECT_IO;
  TCPDeviceObject->Flags   |= DO_DIRECT_IO;

  /* Initialize the driver object with this driver's entry points */
  DriverObject->MajorFunction[IRP_MJ_CREATE]  = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_CLOSE]   = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = TiDispatchInternal;
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TiDispatch;

  DriverObject->DriverUnload = TiUnload;

  /* Open loopback adapter */
  Status = LoopRegisterAdapter(NULL, NULL);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Register protocol with NDIS */
  /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
  Status = LANRegisterProtocol(&strNdisDeviceName);
  if (!NT_SUCCESS(Status)) {
	  TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status));
	  TiWriteErrorLog(
      DriverObject,
      EVENT_TRANSPORT_REGISTER_FAILED,
      TI_ERROR_DRIVERENTRY,
      Status,
      NULL,
      0,
      NULL);
      TiUnload(DriverObject);
      return Status;
  }

  /* Start the periodic timer with an initial and periodic
     relative expiration time of IP_TIMEOUT milliseconds */
  DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000;
  KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc);

  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Finished\n"));


  return STATUS_SUCCESS;

}
Example #11
0
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;
  }
}
Example #12
0
DWORD PacketOpen(PNDIS_STRING AdapterName,DWORD dwDDB,DWORD hDevice,PDIOCPARAMETERS pDiocParms)
{

    LARGE_INTEGER		SystemTime;
    __int64				ltime1;
    PDEVICE_EXTENSION	pde;
    POPEN_INSTANCE 		oiNew;
    NDIS_STATUS			nsErrorStatus, nsOpenStatus;
    UINT           	i;
    UINT           	uiMedium;
    NDIS_STRING		NameStr;
    NDIS_STATUS	Status;


    pde = GlobalDeviceExtension;
    /*Allocate an element that describe an adapter*/
    NdisAllocateMemory( (PVOID *)&oiNew, sizeof( OPEN_INSTANCE ), 0, -1 );
    if ( oiNew == NULL )
    {
        return NDIS_STATUS_FAILURE;
    }
    NdisZeroMemory( (PVOID)oiNew, sizeof( OPEN_INSTANCE ) );
    /*allocate a pool for the packet headers*/

    NdisAllocatePacketPool( &nsErrorStatus,
                            &(oiNew->PacketPool),
                            TRANSMIT_PACKETS,
                            sizeof(PACKET_RESERVED) );

    IF_TRACE_MSG( "PACKET_RESERVED_a :%lx",sizeof(PACKET_RESERVED));
    if ( nsErrorStatus != NDIS_STATUS_SUCCESS )
    {
        IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus );
        NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) ,  0 );
        TRACE_LEAVE( "BindAdapter" );
        return NDIS_STATUS_FAILURE;
    }


    /*allocate a buffer pool for the packet data*/
    NdisAllocateBufferPool( &nsErrorStatus,
                            &(oiNew->BufferPool),
                            TRANSMIT_PACKETS );
    if ( nsErrorStatus != NDIS_STATUS_SUCCESS )
    {
        IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus );
        NdisFreePacketPool( oiNew->PacketPool );
        NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) ,  0 );
        TRACE_LEAVE( "BindAdapter" );
        return NDIS_STATUS_FAILURE;
    }
    NdisAllocateSpinLock( &(oiNew->ResetSpinLock) );
    InitializeListHead( &(oiNew->ResetIrpList) );
    NdisAllocateSpinLock( &(oiNew->RcvQSpinLock) );
    InitializeListHead( &(oiNew->RcvList) );
    NdisAllocateSpinLock( &(oiNew->RequestSpinLock) );
    InitializeListHead( &(oiNew->RequestList) );

    for ( i=0; i<MAX_REQUESTS; i++ )
    {
        InsertTailList( &(oiNew->RequestList), &(oiNew->Requests[i].Reserved.ListElement) );
    }

    oiNew->Status = NDIS_STATUS_PENDING;

    /*initialize the timer variables for this session*/

    SystemTime=GetDate();

    ltime1=((__int64)SystemTime.HighPart*86400);
    ltime1+=(__int64)(SystemTime.LowPart/1000);	//current time from 1980 in seconds
    ltime1+=(__int64)315532800;	//current time from 1970 (Unix format) in seconds
    ltime1*=1193182;
    ltime1+=(SystemTime.LowPart%1000)*1193182/1000; //current time from 1970 in ticks
    ltime1-=QuerySystemTime();	//boot time from 1970 in ticks
    oiNew->StartTime=ltime1;


    oiNew->Dropped=0;		//reset the dropped packets counter
    oiNew->Received=0;		//reset the received packets counter
    oiNew->bpfprogram=NULL;	//set an accept-all filter
    oiNew->bpfprogramlen=0;
    oiNew->BufSize=0;		//set an empty buffer
    oiNew->Buffer=NULL;		//reset the buffer
    oiNew->Bhead=0;
    oiNew->Btail=0;
    oiNew->BLastByte=0;
    oiNew->TimeOut=0;		//reset the timeouts
    oiNew->ReadTimeoutTimer=0;
    oiNew->mode=0;			//set capture mode
    oiNew->Nbytes=0;		//reset the counters
    oiNew->Npackets=0;
    oiNew->hDevice=hDevice;
    oiNew->tagProcess=pDiocParms->tagProcess;
    oiNew->ReadEvent=0;		//reset the read event

    NdisAllocateSpinLock( &(oiNew->CountersLock) );
    /*open the MAC driver calling NDIS*/
    NdisOpenAdapter( &nsOpenStatus,
                     &nsErrorStatus,
                     &oiNew->AdapterHandle,
                     &uiMedium,
                     MediumArray,
                     NUM_NDIS_MEDIA,
                     pde->NdisProtocolHandle,
                     oiNew,
                     AdapterName,
                     0,
                     NULL );

    IF_TRACE_MSG( "Open Status                   : %lx", nsOpenStatus );
    IF_TRACE_MSG( "Error Status                  : %lx", nsErrorStatus );
    IF_TRACE_MSG( "Completion Status             : %lx", oiNew->Status );

    if ( nsOpenStatus == NDIS_STATUS_PENDING )
    {
        while ( oiNew->Status == NDIS_STATUS_PENDING )
            YieldExecution();
    }
    else
    {
        PacketOpenAdapterComplete( oiNew, nsOpenStatus, nsErrorStatus );
    }

    Status = oiNew->Status;
    if ( Status != NDIS_STATUS_SUCCESS )
    {
        NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) ,  0 );
        return NDIS_STATUS_FAILURE;
    }
    else
    {

    }

    TRACE_LEAVE( "BindAdapter" );

    /*return succesfully*/
    return STATUS_SUCCESS;

}
Example #13
0
/************************************************************
Function used by NDIS to update the VXD when a new MAC driver
is added
************************************************************/
VOID NDIS_API PacketBindAdapter( OUT PNDIS_STATUS Status,
                                 IN  NDIS_HANDLE  BindAdapterContext,
                                 IN  PNDIS_STRING AdapterName,
                                 IN  PVOID        SystemSpecific1,
                                 IN  PVOID        SystemSpecific2 )
{
    PDEVICE_EXTENSION	pde;
    POPEN_INSTANCE		oiNew;
    NDIS_STATUS			nsErrorStatus, nsOpenStatus;
    UINT           		uiMedium;
    UINT           		i;
    PWRAPPER_PROTOCOL_BLOCK				pWPBlock;
    PNDIS_PROTOCOL_CHARACTERISTICS	pNPChar;
    PADAPTER_NAME		AName;
    PWRAPPER_MAC_BLOCK	pWMBlock;
    PNDIS_MAC_CHARACTERISTICS	  pNMChar;
    BYTE                *lpzName;


    TRACE_ENTER( "BindAdapter" );
    pde = GlobalDeviceExtension;
    /*Allocate an element that describe an adapter*/
    NdisAllocateMemory( (PVOID *)&AName, sizeof(ADAPTER_NAME), 0, -1 );
    if ( AName == NULL )
    {
        *Status = NDIS_STATUS_RESOURCES;
        return;
    }

    NdisAllocateMemory( (PVOID *)&oiNew, sizeof( OPEN_INSTANCE ), 0, -1 );
    if ( oiNew == NULL )
    {
        *Status = 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 pool for the packet headers*/

    NdisAllocatePacketPool( &nsErrorStatus,
                            &(oiNew->PacketPool),
                            TRANSMIT_PACKETS,
                            sizeof(PACKET_RESERVED) );

    IF_TRACE_MSG( "PACKET_RESERVED_b :%lx",sizeof(PACKET_RESERVED));
    if ( nsErrorStatus != NDIS_STATUS_SUCCESS )
    {
        IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus );
        NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) ,  0 );
        *Status = NDIS_STATUS_RESOURCES;
        TRACE_LEAVE( "BindAdapter" );
        return;
    }


    /*allocate a pool for the packet data*/

    NdisAllocateBufferPool( &nsErrorStatus,
                            &(oiNew->BufferPool),
                            TRANSMIT_PACKETS );
    if ( nsErrorStatus != NDIS_STATUS_SUCCESS )
    {
        IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus );
        NdisFreePacketPool( oiNew->PacketPool );
        NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) ,  0 );
        *Status = NDIS_STATUS_RESOURCES;
        TRACE_LEAVE( "BindAdapter" );
        return;
    }
    NdisAllocateSpinLock( &(oiNew->ResetSpinLock) );
    InitializeListHead( &(oiNew->ResetIrpList) );
    NdisAllocateSpinLock( &(oiNew->RcvQSpinLock) );
    InitializeListHead( &(oiNew->RcvList) );
    NdisAllocateSpinLock( &(oiNew->RequestSpinLock) );
    InitializeListHead( &(oiNew->RequestList) );

    for ( i=0; i<MAX_REQUESTS; i++ )
    {
        InsertTailList( &(oiNew->RequestList), &(oiNew->Requests[i].Reserved.ListElement) );
    }
    oiNew->Status = NDIS_STATUS_PENDING;
    oiNew->BindAdapterContext = BindAdapterContext;

    /*open the MAC driver calling NDIS*/

    oiNew->hDevice=0;
    oiNew->tagProcess=0;

    NdisOpenAdapter( &nsOpenStatus,
                     &nsErrorStatus,
                     &oiNew->AdapterHandle,
                     &uiMedium,
                     MediumArray,
                     NUM_NDIS_MEDIA,
                     pde->NdisProtocolHandle,
                     oiNew,
                     AdapterName,
                     0,
                     NULL );
    IF_TRACE_MSG( "Open Status                   : %lx", nsOpenStatus );
    IF_TRACE_MSG( "Error Status                  : %lx", nsErrorStatus );
    IF_TRACE_MSG( "Completion Status             : %lx", oiNew->Status );
    if ( nsOpenStatus == NDIS_STATUS_PENDING )
    {
        while ( oiNew->Status == NDIS_STATUS_PENDING )
            YieldExecution();
    }
    else
    {
        PacketOpenAdapterComplete( oiNew, nsOpenStatus, nsErrorStatus );
    }

    pWPBlock = ((PWRAPPER_OPEN_BLOCK)(oiNew->AdapterHandle))->ProtocolHandle;
    pNPChar  = &pWPBlock->ProtocolCharacteristics;
    IF_TRACE_MSG( "Protocol                      : %s",  pNPChar->Name.Buffer );
    IF_TRACE_MSG( "Protocol Handle               : %lx", pde->NdisProtocolHandle );
    IF_TRACE_MSG( "PWRAPPER_OPEN_BLOCK           : %lx", oiNew->AdapterHandle );
    IF_TRACE_MSG( "PWRAPPER_PROTOCOL_BLOCK       : %lx", pWPBlock );
    IF_TRACE_MSG( "NDIS_PROTOCOL_CHARACTERISTICS : %lx", pNPChar );
    IF_TRACE_MSG( "Name                          : %lx", &pNPChar->Name );
    IF_TRACE_MSG( "Adapter Name                  : %s",  AdapterName->Buffer );
    *Status = oiNew->Status;

    if ( *Status != NDIS_STATUS_SUCCESS )
    {
        NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) ,  0 );
        IF_TRACE( "Bind Operation FAILED!" );
    }
    else
    {
        AName->realnamestr.Length=AdapterName->Length;
        AName->realnamestr.MaximumLength=AdapterName->MaximumLength;
        AName->realnamestr.Buffer=AName->realname;
        for(i=0; i<32; i++)AName->realname[i]=AdapterName->Buffer[i];

        pWMBlock = ((PWRAPPER_OPEN_BLOCK)(oiNew->AdapterHandle))->MacHandle;
        pNMChar  = &pWMBlock->MacCharacteristics;
        lpzName  = pNMChar->Name.Buffer;
        for(i=0; i<32; i++)AName->devicename[i]=lpzName[i];
        InsertTailList( &GlobalDeviceExtension->AdapterNames, &AName->ListElement);

        //close the adapter
        NdisCloseAdapter(&nsErrorStatus,oiNew->AdapterHandle);

        if ( nsErrorStatus == NDIS_STATUS_PENDING )
        {
            while ( oiNew->Status == NDIS_STATUS_PENDING )
                YieldExecution();
        }
        else
        {
            PacketUnbindAdapterComplete( oiNew, nsErrorStatus );
        }
        *Status = oiNew->Status;
        if ( *Status == NDIS_STATUS_SUCCESS )
        {
            //remove this adapter from the list of open adapters
            RemoveEntryList(&(oiNew->ListElement));
            //free the memory
            NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) ,  0 );
        }
        else
        {
            IF_TRACE( "Close Operation FAILED!" );
        }

    }

    TRACE_LEAVE( "BindAdapter" );
    return;
}
Example #14
0
/*
 * Opens the specified adapter and binds the protocol to it
 *
 * Arguments
 *		AdapterName		- The name of the adapter with which binding should happen
 *
 * Return Value
 *		Return TRUE if successfully bound otherwise returns FALSE
 *
 */
BOOL PKTOpenAdapter (PNDIS_STRING pAdapterName)
{
	POPEN_INSTANCE	pOI;
	NDIS_STATUS		nsOpen;
	NDIS_STATUS		nsError;
	SYSTEMTIME		SystemTime;
	FILETIME		FileTime;
	LARGE_INTEGER	liSysTime;
	LARGE_INTEGER	TimeFreq;
	LARGE_INTEGER	PTime;
	UINT			uiMedium;


	// Check if an instance is already opened
	if (g_pDeviceExtension->pOpenInstance) {
		SetLastError (ERROR_ALREADY_INITIALIZED);
		return FALSE;
	}

	// Time initialization
	GetSystemTime (&SystemTime);
	if (! (SystemTimeToFileTime (&SystemTime, &FileTime) &&
		QueryPerformanceCounter (&PTime) && QueryPerformanceFrequency (&TimeFreq))) {
		return FALSE;
	}
	NdisMoveMemory (&liSysTime, &FileTime, sizeof (LARGE_INTEGER));
	
	
	
	// allocate an instance that describes the adapter
	NdisAllocateMemory (&pOI, sizeof (OPEN_INSTANCE), 0, NDIS_ADDR_M1);
	if (pOI == NULL) {
		return FALSE;
	}
	NdisZeroMemory (pOI, sizeof (OPEN_INSTANCE));

	// init struct variables
	pOI->bpfprogram			= NULL;		//set an accept-all filter
	pOI->bpfprogramlen		= 0;
	pOI->BufSize			= 0;		//set an empty buffer
	pOI->Buffer				= NULL;		//reset the buffer
	pOI->Bhead				= 0;
	pOI->Btail				= 0;
	pOI->BLastByte			= 0;
	pOI->TimeOut			= 0;		//reset the timeouts


	// create the shared name read event
	pOI->ReadEvent = CreateEvent (NULL, FALSE, FALSE, SH_EVENT_NAME);
	if (pOI->ReadEvent == NULL) {
		NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0);
		return FALSE;
	}

	// set time values
	pOI->StartTime.QuadPart = (((liSysTime.QuadPart) % 10000000) * TimeFreq.QuadPart)/10000000;
	liSysTime.QuadPart = liSysTime.QuadPart / 10000000 - 11644473600;
	pOI->StartTime.QuadPart += (liSysTime.QuadPart) * TimeFreq.QuadPart - PTime.QuadPart;


	// allocate pool for the packet headers
	NdisAllocatePacketPool (&nsError, &(pOI->PacketPool), 
		TRANSMIT_PACKETS, sizeof (PACKET_RESERVED));
	if (nsError != NDIS_STATUS_SUCCESS) {
		CloseHandle (pOI->ReadEvent);
		NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0);
		return FALSE;
	}


	// allocate buffer pool for the packet data
	NdisAllocateBufferPool (&nsError, &(pOI->BufferPool), TRANSMIT_PACKETS);
	if (nsError != NDIS_STATUS_SUCCESS) {
		CloseHandle (pOI->ReadEvent);
		NdisFreePacketPool (pOI->PacketPool);
		NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0);
		return FALSE;
	}

	// set status pending
	pOI->Status = NDIS_STATUS_PENDING;

	// open the MAC driver
	NdisOpenAdapter (&nsOpen, &nsError, &pOI->AdapterHandle, &uiMedium, MediumArray,
		NUM_NDIS_MEDIA, g_pDeviceExtension->NdisProtocolHandle, pOI, pAdapterName, 0, NULL);


	if (nsOpen == NDIS_STATUS_PENDING) {
		SuspendExecution (pOI);
	} else {
		PacketOpenAdapterComplete (pOI, nsOpen, nsError);
	}

	// free the packet instance if not successful
	if (pOI->Status != NDIS_STATUS_SUCCESS) {
		CloseHandle (pOI->ReadEvent);
		NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0);
		return FALSE;
	}

	return TRUE;
}
NTSTATUS
DriverEntry(
	IN	PDRIVER_OBJECT		DriverObject,
	IN	PUNICODE_STRING		RegistryPath
	)
/*++

Routine Description:

	First entry point to be called, when this driver is loaded.
	Register with NDIS as an intermediate driver.

Arguments:

	DriverObject - pointer to the system's driver object structure
		for this driver
	
	RegistryPath - system's registry path for this driver
	
Return Value:

	STATUS_SUCCESS if all initialization is successful, STATUS_XXX
	error code if not.

--*/
{
	NDIS_STATUS						Status;
	NDIS_PROTOCOL_CHARACTERISTICS	PChars;
	NDIS_MINIPORT_CHARACTERISTICS	MChars;
	PNDIS_CONFIGURATION_PARAMETER	Param;
	NDIS_STRING						Name;

	Status = NDIS_STATUS_SUCCESS;
	NdisAllocateSpinLock(&GlobalLock);

	//初始化自定义变量
	NdisAllocateSpinLock(&PacketListLock);
	InitializeListHead(&PacketList);

	NdisAllocateSpinLock(&ReadIrpLock);
	ReadIrp = NULL;
	ReadCount=0;
	PacketCount=0;
	RecvBufferPool=NULL;
	SendBufferPool=NULL;

	PendedSendCount=0;
    NdisAllocateSpinLock(&WriteIrpLock);
    InitializeListHead(&PendedWritesList);

#ifdef NDIS51
	PartialCancelId = NdisGeneratePartialCancelId();
    PartialCancelId <<= ((sizeof(PVOID) - 1) * 8);
#endif

	pAdaptTotal=NULL;
//	TotalMacBuffer=NULL;
	CurrentNum=0;

    NdisAllocateBufferPool(
            &Status,
            &RecvBufferPool,
            MAX_RECV_PACKET_POOL_SIZE);
	NdisAllocateBufferPool(
            &Status,
            &SendBufferPool,
            MAX_SEND_PACKET_POOL_SIZE);

	NdisMInitializeWrapper(&NdisWrapperHandle, DriverObject, RegistryPath, NULL);

	do
	{
		//
		// Register the miniport with NDIS. Note that it is the miniport
		// which was started as a driver and not the protocol. Also the miniport
		// must be registered prior to the protocol since the protocol's BindAdapter
		// handler can be initiated anytime and when it is, it must be ready to
		// start driver instances.
		//

		NdisZeroMemory(&MChars, sizeof(NDIS_MINIPORT_CHARACTERISTICS));

		MChars.MajorNdisVersion = PASSTHRU_MAJOR_NDIS_VERSION;
		MChars.MinorNdisVersion = PASSTHRU_MINOR_NDIS_VERSION;

		MChars.InitializeHandler = MPInitialize;
		MChars.QueryInformationHandler = MPQueryInformation;
		MChars.SetInformationHandler = MPSetInformation;
		MChars.ResetHandler = MPReset;
		MChars.TransferDataHandler = MPTransferData;
		MChars.HaltHandler = MPHalt;
#ifdef NDIS51_MINIPORT
		MChars.CancelSendPacketsHandler = MPCancelSendPackets;
		MChars.PnPEventNotifyHandler = MPDevicePnPEvent;
		MChars.AdapterShutdownHandler = MPAdapterShutdown;
#endif // NDIS51_MINIPORT

		//
		// We will disable the check for hang timeout so we do not
		// need a check for hang handler!
		//
		MChars.CheckForHangHandler = NULL;
		MChars.ReturnPacketHandler = MPReturnPacket;

		//
		// Either the Send or the SendPackets handler should be specified.
		// If SendPackets handler is specified, SendHandler is ignored
		//
		MChars.SendHandler = NULL;	// MPSend;
		MChars.SendPacketsHandler = MPSendPackets;

		Status = NdisIMRegisterLayeredMiniport(NdisWrapperHandle,
   											   &MChars,
   											   sizeof(MChars),
										   	   &DriverHandle);
		if (Status != NDIS_STATUS_SUCCESS)
		{
			break;
		}

#ifndef WIN9X
		NdisMRegisterUnloadHandler(NdisWrapperHandle, PtUnload);
#endif

		//
		// Now register the protocol.
		//
		NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
		PChars.MajorNdisVersion = PASSTHRU_PROT_MAJOR_NDIS_VERSION;
		PChars.MinorNdisVersion = PASSTHRU_PROT_MINOR_NDIS_VERSION;

		//
		// Make sure the protocol-name matches the service-name
		// (from the INF) under which this protocol is installed.
		// This is needed to ensure that NDIS can correctly determine
		// the binding and call us to bind to miniports below.
		//
		NdisInitUnicodeString(&Name, L"Passthru");	// Protocol name
		PChars.Name = Name;
		PChars.OpenAdapterCompleteHandler = PtOpenAdapterComplete;
		PChars.CloseAdapterCompleteHandler = PtCloseAdapterComplete;
		PChars.SendCompleteHandler = PtSendComplete;
		PChars.TransferDataCompleteHandler = PtTransferDataComplete;
	
		PChars.ResetCompleteHandler = PtResetComplete;
		PChars.RequestCompleteHandler = PtRequestComplete;
		PChars.ReceiveHandler = PtReceive;
		PChars.ReceiveCompleteHandler = PtReceiveComplete;
		PChars.StatusHandler = PtStatus;
		PChars.StatusCompleteHandler = PtStatusComplete;
		PChars.BindAdapterHandler = PtBindAdapter;
		PChars.UnbindAdapterHandler = PtUnbindAdapter;
		PChars.UnloadHandler = PtUnloadProtocol;

		PChars.ReceivePacketHandler = PtReceivePacket;
		PChars.PnPEventHandler= PtPNPHandler;

		NdisRegisterProtocol(&Status,
 							&ProtHandle,
 							&PChars,
 							sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

		if (Status != NDIS_STATUS_SUCCESS)
		{
			NdisIMDeregisterLayeredMiniport(DriverHandle);
			break;
		}

		NdisIMAssociateMiniport(DriverHandle, ProtHandle);
	}
	while (FALSE);

	if (Status != NDIS_STATUS_SUCCESS)
	{
		NdisTerminateWrapper(NdisWrapperHandle, NULL);
	}

	return(Status);
}
Example #16
-1
File: main.c Project: GYGit/reactos
NTSTATUS NTAPI
DriverEntry(
  PDRIVER_OBJECT DriverObject,
  PUNICODE_STRING RegistryPath)
/*
 * FUNCTION: Main driver entry point
 * ARGUMENTS:
 *     DriverObject = Pointer to a driver object for this driver
 *     RegistryPath = Registry node for configuration parameters
 * RETURNS:
 *     Status of driver initialization
 */
{
  NTSTATUS Status;
  UNICODE_STRING strIpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME);
  UNICODE_STRING strRawDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME);
  UNICODE_STRING strUdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME);
  UNICODE_STRING strTcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME);
  UNICODE_STRING strNdisDeviceName = RTL_CONSTANT_STRING(TCPIP_PROTOCOL_NAME);
  NDIS_STATUS NdisStatus;
  LARGE_INTEGER DueTime;

  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Called\n"));

  /* TdiInitialize() ? */

  /* FIXME: Create symbolic links in Win32 namespace */

  /* Initialize our periodic timer and its associated DPC object. When the
     timer expires, the IPTimeout deferred procedure call (DPC) is queued */
  KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
  KeInitializeTimer(&IPTimer);

  /* Create IP device object */
  Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  ChewInit( IPDeviceObject );

  /* Create RawIP device object */
  Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create UDP device object */
  Status = IoCreateDevice(DriverObject, 0, &strUdpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create TCP device object */
  Status = IoCreateDevice(DriverObject, 0, &strTcpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Setup network layer and transport layer entities */
  KeInitializeSpinLock(&EntityListLock);
  EntityList = ExAllocatePoolWithTag(NonPagedPool,
                                     sizeof(TDIEntityID) * MAX_TDI_ENTITIES,
                                     TDI_ENTITY_TAG );
  if (!EntityList) {
    TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  EntityCount = 0;
  EntityMax   = MAX_TDI_ENTITIES;

  /* Allocate NDIS packet descriptors */
  NdisAllocatePacketPoolEx(&NdisStatus, &GlobalPacketPool, 500, 1500, sizeof(PACKET_CONTEXT));
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Allocate NDIS buffer descriptors */
  NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 2000);
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Initialize address file list and protecting spin lock */
  InitializeListHead(&AddressFileListHead);
  KeInitializeSpinLock(&AddressFileListLock);

  /* Initialize connection endpoint list and protecting spin lock */
  InitializeListHead(&ConnectionEndpointListHead);
  KeInitializeSpinLock(&ConnectionEndpointListLock);

  /* Initialize interface list and protecting spin lock */
  InitializeListHead(&InterfaceListHead);
  KeInitializeSpinLock(&InterfaceListLock);

  /* Initialize network level protocol subsystem */
  IPStartup(RegistryPath);

  /* Initialize transport level protocol subsystems */
  Status = RawIPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = UDPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = TCPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = ICMPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  /* Use direct I/O */
  IPDeviceObject->Flags    |= DO_DIRECT_IO;
  RawIPDeviceObject->Flags |= DO_DIRECT_IO;
  UDPDeviceObject->Flags   |= DO_DIRECT_IO;
  TCPDeviceObject->Flags   |= DO_DIRECT_IO;

  /* Initialize the driver object with this driver's entry points */
  DriverObject->MajorFunction[IRP_MJ_CREATE]  = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_CLOSE]   = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = TiDispatchInternal;
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TiDispatch;

  DriverObject->DriverUnload = TiUnload;

  /* Open loopback adapter */
  Status = LoopRegisterAdapter(NULL, NULL);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Register protocol with NDIS */
  /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
  Status = LANRegisterProtocol(&strNdisDeviceName);
  if (!NT_SUCCESS(Status)) {
	  TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status));
	  TiWriteErrorLog(
      DriverObject,
      EVENT_TRANSPORT_REGISTER_FAILED,
      TI_ERROR_DRIVERENTRY,
      Status,
      NULL,
      0,
      NULL);
      TiUnload(DriverObject);
      return Status;
  }

  /* Start the periodic timer with an initial and periodic
     relative expiration time of IP_TIMEOUT milliseconds */
  DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000;
  KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc);

  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Finished\n"));


  return STATUS_SUCCESS;
}