Example #1
0
VOID*
OvsAllocateMemoryWithTag(size_t size, ULONG tag)
{
    OVS_VERIFY_IRQL_LE(DISPATCH_LEVEL);
    return NdisAllocateMemoryWithTagPriority(gOvsExtDriverHandle,
        (UINT32)size, tag, NormalPoolPriority);
}
Example #2
0
VOID *
OvsAllocateMemory(size_t size)
{
    OVS_VERIFY_IRQL_LE(DISPATCH_LEVEL);
    return NdisAllocateMemoryWithTagPriority(gOvsExtDriverHandle,
        (UINT32)size, OVS_MEMORY_TAG, NormalPoolPriority);
}
/**********************************************************
Implements general-purpose memory allocation routine
Parameters:
    ULONG ulRequiredSize: block size
Return value:
    PVOID allocated memory block
    NULL on error
***********************************************************/
PVOID ParaNdis_AllocateMemoryRaw(NDIS_HANDLE MiniportHandle, ULONG ulRequiredSize)
{
    return NdisAllocateMemoryWithTagPriority(
            MiniportHandle,
            ulRequiredSize,
            PARANDIS_MEMORY_TAG,
            NormalPoolPriority);
}
PVOID
VenetAlloc(ULONG size)
{
    PVOID	p;

    p =  NdisAllocateMemoryWithTagPriority(mp_handle, size, VNET,
                                           HighPoolPriority);
    if (p)
        NdisZeroMemory(p, size);
    return p;
}
Example #5
0
_Ret_maybenull_
_Result_nullonfailure_
NON_PAGEABLE_FUNCTION
void* AX25Adapter::operator new(_In_ size_t size,
                                _In_ NDIS_HANDLE driverHandle) noexcept
{   
    // Check the size of the allocation makes sense
    if (size != sizeof(AX25Adapter))
    {
        // Invalid size - refuse to handle the request
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_ADAPTER, "Failed to allocate space for AX25Adapter: invalid size %d (expected %d)",
                    static_cast<int>(size), static_cast<int>(sizeof(AX25Adapter)));
        return nullptr;
    }

    // Verify the driver handle was passed in
    if (driverHandle == nullptr)
    {
        // invalid driver handle - refuse to try to pass this on to NDIS
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_ADAPTER, "Failed to allocate space for AX25Adapter: driverHandle is nullptr");
        return nullptr;
    }

    // Allocate the memory
    static_assert(sizeof(AX25Adapter) <= MAXUINT, "static_cast below is invalid for very large objects");
    void* result = NdisAllocateMemoryWithTagPriority(driverHandle,
                                                     static_cast<UINT>(size),
                                                     AX25_ADAPTER_TAG,
                                                     NormalPoolPriority);
    // Log if there was an error
    if (result == nullptr)
    {
        TraceEvents(TRACE_LEVEL_ERROR, TRACE_ADAPTER, "Failed to allocate space for AX25Adapter: NdisAllocateMemoryWithTagPriority returned nullptr");
    }
    else
    {
        TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_ADAPTER, "Allocated new AX25Adapter at %p", result);
    }

    return result;
}
static
BOOLEAN AllocateCPUMappingArray(NDIS_HANDLE NdisHandle, PPARANDIS_SCALING_SETTINGS RSSScalingSettings)
{
    ULONG i;
    ULONG CPUNumber = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS);
    PCHAR NewCPUMappingArray = (PCHAR) NdisAllocateMemoryWithTagPriority(
                                                                            NdisHandle,
                                                                            sizeof(CCHAR) * CPUNumber,
                                                                            PARANDIS_MEMORY_TAG,
                                                                            NormalPoolPriority);

    if(!NewCPUMappingArray)
        return FALSE;

    RSSScalingSettings->CPUIndexMapping = NewCPUMappingArray;
    RSSScalingSettings->CPUIndexMappingSize = CPUNumber;

    for(i = 0; i < CPUNumber; i++)
    {
        RSSScalingSettings->CPUIndexMapping[i] = PARANDIS_RECEIVE_QUEUE_UNCLASSIFIED;
    }

    return TRUE;
}
Example #7
0
PVOID
filterAuditAllocMem(
    NDIS_HANDLE  NdisHandle,    
	ULONG	     Size,
	ULONG	     FileNumber,
	ULONG	     LineNumber
)
{
	PVOID				pBuffer;
	PFILTERD_ALLOCATION	pAllocInfo;

	if (!filterdInitDone)
	{
		NdisAllocateSpinLock(&(filterdMemoryLock));
		filterdInitDone = TRUE;
	}

    //
    // Integer overflow check
    //
    if ((Size + sizeof(FILTERD_ALLOCATION)) < Size)
    {
        DEBUGP(DL_VERY_LOUD+50,
               ("filterAuditAllocMem: Integer overflow error file %d, line %d, Size %d \n",
			   FileNumber, LineNumber, Size));
    
        pBuffer = NULL;
    }
    else
    {
        
    	pAllocInfo = NdisAllocateMemoryWithTagPriority(
            NdisHandle,
    		Size+sizeof(FILTERD_ALLOCATION),
    		(ULONG)'gdTF',
            LowPoolPriority
    	);

    	if (pAllocInfo == (PFILTERD_ALLOCATION)NULL)
    	{
    		DEBUGP(DL_VERY_LOUD+50,
    			("filterAuditAllocMem: file %d, line %d, Size %d failed!\n",
    				FileNumber, LineNumber, Size));
    		pBuffer = NULL;
    	}
    	else
    	{
    		pBuffer = (PVOID)&(pAllocInfo->UserData);
    		NdisFillMemory(pBuffer, Size, 0xaf);
    		pAllocInfo->Signature = FILTERD_MEMORY_SIGNATURE;
    		pAllocInfo->FileNumber = FileNumber;
    		pAllocInfo->LineNumber = LineNumber;
    		pAllocInfo->Size = Size;
            pAllocInfo->OwnerHandle = NdisHandle;
    		pAllocInfo->Next = (PFILTERD_ALLOCATION)NULL;

    		NdisAcquireSpinLock(&(filterdMemoryLock));

    		pAllocInfo->Prev = filterdMemoryTail;
    		if (filterdMemoryTail == (PFILTERD_ALLOCATION)NULL)
    		{
                //
    			// empty list
                // 
    			filterdMemoryHead = filterdMemoryTail = pAllocInfo;
    		}
    		else
    		{
    			filterdMemoryTail->Next = pAllocInfo;
    		}
    		filterdMemoryTail = pAllocInfo;
    		
    		filterdAllocCount++;
    		NdisReleaseSpinLock(&(filterdMemoryLock));
    	}
    }

	DEBUGP(DL_VERY_LOUD+100,
	 ("filterAuditAllocMem: file %c%c%c%c, line %d, %d bytes, OwerHandle %p, Memory 0x%p\n",
	 			(CHAR)(FileNumber & 0xff),
	 			(CHAR)((FileNumber >> 8) & 0xff),
	 			(CHAR)((FileNumber >> 16) & 0xff),
	 			(CHAR)((FileNumber >> 24) & 0xff),
				LineNumber, Size, NdisHandle, pBuffer));

	return (pBuffer);

}
Example #8
0
    // Figure out the actual size of NDIS_QOS_PARAMETERS if it were to accommodate
    // NumClassificationElements classification elements. Note that the first
    // element must be aligned at the end of the parent NDIS_QOS_PARAMETERS
    // structure.
    //
    ParamSize = sizeof(NDIS_QOS_PARAMETERS);
    FirstElementOffset = ALIGN_UP(ParamSize, NDIS_QOS_CLASSIFICATION_ELEMENT);
    ParamSize = FirstElementOffset + NumClassificationElements * sizeof(NDIS_QOS_CLASSIFICATION_ELEMENT);

    //
    // Allocate the NDIS_QOS_PARAMETERS structure.
    //
    Parameters =
        NdisAllocateMemoryWithTagPriority(
            NdisDriverHandle,
            ParamSize,
            NIC_TAG_QOS_PARAMS,
            NormalPoolPriority);

    if (Parameters == NULL)
    {
        DEBUGP(MP_ERROR, "Failed to allocate NDIS_QOS_PARAMETERS.\n");
        return NULL;
    }

    //
    // Initialize the structure.
    //
    NdisZeroMemory(Parameters, ParamSize);
    Parameters->Header.Type = NDIS_OBJECT_TYPE_QOS_PARAMETERS;
    Parameters->Header.Revision = NDIS_QOS_PARAMETERS_REVISION_1;
Example #9
0
NDIS_STATUS
FilterDoInternalRequest(
    IN PNETGW_ADAPT FilterModuleContext,
    IN NDIS_REQUEST_TYPE RequestType,
    IN NDIS_OID Oid,
    IN PVOID InformationBuffer,
    IN ULONG InformationBufferLength,
    IN ULONG OutputBufferLength
)
{
    PNETGW_ADAPT pAdapter = (PNETGW_ADAPT)FilterModuleContext;
    PFILTER_REQUEST_CONTEXT pContext;
    PINTERNAL_OID_REQUEST pInternalRequest;
    PNDIS_OID_REQUEST pNdisRequest = NULL;
    NDIS_STATUS Status;

    UNREFERENCED_PARAMETER(OutputBufferLength);

    pInternalRequest = (PINTERNAL_OID_REQUEST)NdisAllocateMemoryWithTagPriority(
        pAdapter->FilterHandle, sizeof(INTERNAL_OID_REQUEST), FILTER_TAG, NormalPoolPriority);
    if (pInternalRequest == NULL)
        return NDIS_STATUS_RESOURCES;
    NdisZeroMemory(pInternalRequest, sizeof(*pInternalRequest));

    pNdisRequest = &pInternalRequest->NdisReq;
    pNdisRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
    pNdisRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1;
    pNdisRequest->Header.Size = sizeof(NDIS_OID_REQUEST);
    pNdisRequest->RequestType = RequestType;

    pInternalRequest->bLocal = TRUE;
    pInternalRequest->pReq = pNdisRequest;
    pInternalRequest->pOrigReq = NULL;

    pContext = (PFILTER_REQUEST_CONTEXT)(&pNdisRequest->SourceReserved[0]);
    *pContext = (NDIS_OID_REQUEST*)pInternalRequest;

    pNdisRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
    pNdisRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1;
    pNdisRequest->Header.Size = NDIS_SIZEOF_OID_REQUEST_REVISION_1;
    pNdisRequest->RequestHandle = pAdapter->FilterHandle;
    pNdisRequest->SupportedRevision = NDIS_OID_REQUEST_REVISION_1;

    switch (RequestType) {
        case NdisRequestQueryInformation:
        pNdisRequest->DATA.QUERY_INFORMATION.Oid = Oid;
        pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer =
            InformationBuffer;
        pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength =
            InformationBufferLength;
        break;

        case NdisRequestSetInformation:
        pNdisRequest->DATA.SET_INFORMATION.Oid = Oid;
        pNdisRequest->DATA.SET_INFORMATION.InformationBuffer =
            InformationBuffer;
        pNdisRequest->DATA.SET_INFORMATION.InformationBufferLength =
            InformationBufferLength;
        break;

        default:
        ASSERT(FALSE);
        break;
    }
    pNdisRequest->RequestId = (PVOID)FILTER_REQUEST_ID;

    Status = NdisFOidRequest(pAdapter->FilterHandle, pNdisRequest);

    if (Status != NDIS_STATUS_PENDING)
        FilterOidRequestComplete(pAdapter, pNdisRequest, Status);

    return Status;
}
/******************************************************************
Replacement of resource requirement list, when needed:
The procedure traverses over all the resource lists in existing resource requirement list
(we receive it in IRP information field).
When the driver is not built to work with MSI resources, we must remove them from the
resource requirement list, otherwise the driver will fail to initialize
Typically MSI interrupts are labeled as preferred ones, when line interrupts are labeled as
alternative resources. Removing message interrupts, remove also "alternative" label from line interrupts.
*******************************************************************/
static PIO_RESOURCE_REQUIREMENTS_LIST ParseFilterResourceIrp(
    IN NDIS_HANDLE  MiniportAddDeviceContext,
    PIO_RESOURCE_REQUIREMENTS_LIST prrl,
    BOOLEAN bRemoveMSIResources)
{
    tRRLData newRRLData;
    ULONG nRemoved = 0;
    PIO_RESOURCE_REQUIREMENTS_LIST newPrrl = NULL;
    DPrintf(resourceFilterLevel, ("[%s]%s\n", __FUNCTION__, bRemoveMSIResources ? "(Remove MSI resources...)" : ""));
    if (MiniportAddDeviceContext && prrl) newPrrl = (PIO_RESOURCE_REQUIREMENTS_LIST)NdisAllocateMemoryWithTagPriority(
            MiniportAddDeviceContext,
            prrl->ListSize,
            PARANDIS_MEMORY_TAG,
            NormalPoolPriority);
    InitializeNewResourceRequirementsList(&newRRLData, newPrrl, prrl);
    if (prrl)
    {
        ULONG n, offset;
        PVOID p = &prrl->List[0];
        DPrintf(resourceFilterLevel, ("[%s] %d bytes, %d lists\n", __FUNCTION__, prrl->ListSize, prrl->AlternativeLists));
        offset = RtlPointerToOffset(prrl, p);
        for (n = 0; n < prrl->AlternativeLists && offset < prrl->ListSize; ++n)
        {
            ULONG nDesc;
            IO_RESOURCE_LIST *pior = (IO_RESOURCE_LIST *)p;
            if ((offset + sizeof(*pior)) < prrl->ListSize)
            {
                IO_RESOURCE_DESCRIPTOR *pd = &pior->Descriptors[0];
                DPrintf(resourceFilterLevel, ("[%s]+%d %d:%d descriptors follow\n", __FUNCTION__, offset, n, pior->Count));
                offset += RtlPointerToOffset(p, pd);
                AddNewResourceList(&newRRLData, pior);
                for (nDesc = 0; nDesc < pior->Count; ++nDesc)
                {
                    BOOLEAN bRemove = FALSE;
                    if ((offset + sizeof(*pd)) <= prrl->ListSize)
                    {
                        DPrintf(resourceFilterLevel, ("[%s]+%d %d: type %d, flags %X, option %X\n", __FUNCTION__, offset, nDesc, pd->Type, pd->Flags, pd->Option));
                        if (pd->Type == CmResourceTypeInterrupt)
                        {
                            if (pd->Flags & CM_RESOURCE_INTERRUPT_MESSAGE)
                            {
                                bRemove = bRemoveMSIResources;
                            }
                            else
                            {
                                // reset IO_RESOURCE_ALTERNATIVE attribute on Line Interrupt,
                                // if we remove MSI vectors, otherwise Windows will not allocate it for the device
                                if (bRemoveMSIResources && (pd->Option & IO_RESOURCE_ALTERNATIVE))
                                {
                                    pd->Option &= ~IO_RESOURCE_ALTERNATIVE;
                                }
                            }
                        }
                        if (!bRemove) AddNewResourceDescriptor(&newRRLData, pd);
                        else nRemoved++;
                    }
                    offset += sizeof(*pd);
                    pd = (IO_RESOURCE_DESCRIPTOR *)RtlOffsetToPointer(prrl, offset);
                }
                FinalizeResourceList(&newRRLData);
                p = pd;
            }
        }
    }
    if (bRemoveMSIResources && nRemoved)
    {
        DPrintf(0, ("[%s] %d resources removed\n", __FUNCTION__, nRemoved));
    }
    return newPrrl;
}
/**********************************************************
Required NDIS handler
Initialize adapter context, prepare it for operation,
set in PAUSED STATE
Return value:
    SUCCESS or kind of error
***********************************************************/
static NDIS_STATUS ParaNdis6_Initialize(
    NDIS_HANDLE miniportAdapterHandle,
    NDIS_HANDLE miniportDriverContext,
    PNDIS_MINIPORT_INIT_PARAMETERS miniportInitParameters)
{
    NDIS_MINIPORT_ADAPTER_ATTRIBUTES        miniportAttributes;
    NDIS_STATUS  status = NDIS_STATUS_SUCCESS;
    BOOLEAN bNoPauseOnSuspend = FALSE;
    PARANDIS_ADAPTER *pContext;

    UNREFERENCED_PARAMETER(miniportDriverContext);
    DEBUG_ENTRY(0);
#pragma warning( suppress: 28197)
    /* allocate context structure */
    pContext = (PARANDIS_ADAPTER *)
        NdisAllocateMemoryWithTagPriority(
            miniportAdapterHandle,
            sizeof(PARANDIS_ADAPTER),
            PARANDIS_MEMORY_TAG,
            NormalPoolPriority);

    /* This call is for Static Driver Verifier only - has no real functionality*/
    __sdv_save_adapter_context(pContext);

    if (!pContext)
    {
        DPrintf(0, ("[%s] ERROR: Memory allocation failed!\n", __FUNCTION__));
        status = NDIS_STATUS_RESOURCES;
    }

    if (status == NDIS_STATUS_SUCCESS)
    {
        /* set mandatory fields which Common use */
        NdisZeroMemory(pContext, sizeof(PARANDIS_ADAPTER));
        pContext->ulUniqueID = NdisInterlockedIncrement(&gID);
        pContext->DriverHandle = DriverHandle;
        pContext->MiniportHandle = miniportAdapterHandle;
    }

    if (status == NDIS_STATUS_SUCCESS)
    {
        NdisZeroMemory(&miniportAttributes, sizeof(miniportAttributes));
        miniportAttributes.RegistrationAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
        miniportAttributes.RegistrationAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
        miniportAttributes.RegistrationAttributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
        miniportAttributes.RegistrationAttributes.MiniportAdapterContext = pContext;
        miniportAttributes.RegistrationAttributes.AttributeFlags =
            // actual for USB
            // NDIS_MINIPORT_ATTRIBUTES_SURPRISE_REMOVE_OK
            NDIS_MINIPORT_ATTRIBUTES_HARDWARE_DEVICE |
            NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER;
#ifndef NO_VISTA_POWER_MANAGEMENT
        miniportAttributes.RegistrationAttributes.AttributeFlags |= NDIS_MINIPORT_ATTRIBUTES_NO_HALT_ON_SUSPEND;
#endif
#if NDIS_SUPPORT_NDIS630
        miniportAttributes.RegistrationAttributes.AttributeFlags |= NDIS_MINIPORT_ATTRIBUTES_NO_PAUSE_ON_SUSPEND;
        bNoPauseOnSuspend = TRUE;
#endif
        miniportAttributes.RegistrationAttributes.CheckForHangTimeInSeconds = 4;
        miniportAttributes.RegistrationAttributes.InterfaceType = NdisInterfacePci;
        status = NdisMSetMiniportAttributes(miniportAdapterHandle, &miniportAttributes);
        if (status != NDIS_STATUS_SUCCESS)
        {
            DPrintf(0, ("[%s] ERROR: NdisMSetMiniportAttributes 1 failed (%X)!\n", __FUNCTION__, status));
        }
    }

    if (status == NDIS_STATUS_SUCCESS)
    {
        /* prepare statistics struct for further reports */
        pContext->Statistics.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
        pContext->Statistics.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
        pContext->Statistics.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
        /* let Common do all the rest */
        status = ParaNdis_InitializeContext(pContext, miniportInitParameters->AllocatedResources);
        if (status != NDIS_STATUS_SUCCESS)
        {
            DPrintf(0, ("[%s] ERROR: ParaNdis6_InitializeContext failed (%X)!\n", __FUNCTION__, status));
        }
        pContext->bNoPauseOnSuspend = bNoPauseOnSuspend; 
    }

    if (status == NDIS_STATUS_SUCCESS)
    {
        ULONG i;
        NDIS_PNP_CAPABILITIES power60Caps;
#if NDIS_SUPPORT_NDIS620
        NDIS_PM_CAPABILITIES power620Caps;
#endif
#ifdef NO_VISTA_POWER_MANAGEMENT
        pPowerCaps = NULL;
#endif
        ParaNdis_FillPowerCapabilities(&power60Caps);

        NdisZeroMemory(&miniportAttributes, sizeof(miniportAttributes));
        miniportAttributes.GeneralAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
        miniportAttributes.GeneralAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
        miniportAttributes.GeneralAttributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
#if NDIS_SUPPORT_NDIS620
        miniportAttributes.GeneralAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;
        miniportAttributes.GeneralAttributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_2;
        miniportAttributes.GeneralAttributes.PowerManagementCapabilitiesEx = &power620Caps;
        ParaNdis6_Fill620PowerCapabilities(&power620Caps);
#else
        miniportAttributes.GeneralAttributes.PowerManagementCapabilities = &power60Caps;
#endif
        miniportAttributes.GeneralAttributes.MediaType = NdisMedium802_3;
        miniportAttributes.GeneralAttributes.PhysicalMediumType = NdisPhysicalMedium802_3;
        miniportAttributes.GeneralAttributes.MtuSize = pContext->MaxPacketSize.nMaxDataSize;
        miniportAttributes.GeneralAttributes.LookaheadSize = pContext->MaxPacketSize.nMaxFullSizeOS;
        miniportAttributes.GeneralAttributes.MaxXmitLinkSpeed =
        miniportAttributes.GeneralAttributes.MaxRcvLinkSpeed  =  PARANDIS_FORMAL_LINK_SPEED;
        miniportAttributes.GeneralAttributes.MediaConnectState =
            pContext->bConnected ? MediaConnectStateConnected : MediaConnectStateDisconnected;
        miniportAttributes.GeneralAttributes.XmitLinkSpeed =
        miniportAttributes.GeneralAttributes.RcvLinkSpeed = pContext->bConnected ?
            PARANDIS_FORMAL_LINK_SPEED : NDIS_LINK_SPEED_UNKNOWN;
        miniportAttributes.GeneralAttributes.MediaDuplexState = MediaDuplexStateFull;
        miniportAttributes.GeneralAttributes.MacOptions =
                    NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |       /* NIC has no internal loopback support */
                    NDIS_MAC_OPTION_TRANSFERS_NOT_PEND  |       /* Must be set since using  NdisMIndicateReceivePacket */
                    NDIS_MAC_OPTION_NO_LOOPBACK;                /* NIC has no internal loopback support */
        if (IsPrioritySupported(pContext))
            miniportAttributes.GeneralAttributes.MacOptions |= NDIS_MAC_OPTION_8021P_PRIORITY;
        if (IsVlanSupported(pContext))
            miniportAttributes.GeneralAttributes.MacOptions |= NDIS_MAC_OPTION_8021Q_VLAN;
        miniportAttributes.GeneralAttributes.SupportedPacketFilters = PARANDIS_PACKET_FILTERS;
        miniportAttributes.GeneralAttributes.MaxMulticastListSize = PARANDIS_MULTICAST_LIST_SIZE;
        miniportAttributes.GeneralAttributes.MacAddressLength =     ETH_LENGTH_OF_ADDRESS;

#if PARANDIS_SUPPORT_RSS
        if(pContext->bRSSOffloadSupported)
        {
            miniportAttributes.GeneralAttributes.RecvScaleCapabilities =
                ParaNdis6_RSSCreateConfiguration(
                                                &pContext->RSSParameters,
                                                &pContext->RSSCapabilities,
                                                pContext->RSSMaxQueuesNumber);
            pContext->bRSSInitialized = TRUE;
        }
#endif

        for(i = 0; i < ARRAYSIZE(pContext->ReceiveQueues); i++)
        {
            NdisAllocateSpinLock(&pContext->ReceiveQueues[i].Lock);
            InitializeListHead(&pContext->ReceiveQueues[i].BuffersList);

            pContext->ReceiveQueues[i].BatchReceiveArray =
                ParaNdis_AllocateMemory(pContext, sizeof(*pContext->ReceiveQueues[i].BatchReceiveArray)*pContext->NetMaxReceiveBuffers);
            if(!pContext->ReceiveQueues[i].BatchReceiveArray)
            {
                pContext->ReceiveQueues[i].BatchReceiveArray = &pContext->ReceiveQueues[i].BatchReceiveEmergencyItem;
                pContext->ReceiveQueues[i].BatchReceiveArraySize = 1;
            }
            else
            {
                pContext->ReceiveQueues[i].BatchReceiveArraySize = pContext->NetMaxReceiveBuffers;
            }
        }

        pContext->ReceiveQueuesInitialized = TRUE;

        miniportAttributes.GeneralAttributes.AccessType = NET_IF_ACCESS_BROADCAST;
        miniportAttributes.GeneralAttributes.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
        miniportAttributes.GeneralAttributes.IfType = IF_TYPE_ETHERNET_CSMACD;
        miniportAttributes.GeneralAttributes.IfConnectorPresent = TRUE;
        miniportAttributes.GeneralAttributes.ConnectionType = NET_IF_CONNECTION_DEDICATED;

        ETH_COPY_NETWORK_ADDRESS(miniportAttributes.GeneralAttributes.PermanentMacAddress, pContext->PermanentMacAddress);
        ETH_COPY_NETWORK_ADDRESS(miniportAttributes.GeneralAttributes.CurrentMacAddress, pContext->CurrentMacAddress);

        ParaNdis6_GetSupportedOid(&miniportAttributes.GeneralAttributes);
        /* update also SupportedStatistics in ready to use statistics block */
        pContext->Statistics.SupportedStatistics = ParaNdis6_GetSupportedStatisticsFlags();
        status = NdisMSetMiniportAttributes(miniportAdapterHandle, &miniportAttributes);
        if (status != NDIS_STATUS_SUCCESS)
        {
            DPrintf(0, ("[%s] ERROR: NdisMSetMiniportAttributes 2 failed (%X)!\n", __FUNCTION__, status));
        }
    }

    if (pContext && status != NDIS_STATUS_SUCCESS && status != NDIS_STATUS_PENDING)
    {
        // no need to cleanup
        NdisFreeMemory(pContext, 0, 0);
        pContext = NULL;
    }

    if (pContext && status == NDIS_STATUS_SUCCESS)
    {
        status = ParaNdis_FinishInitialization(pContext);
        if (status != NDIS_STATUS_SUCCESS)
        {
            ParaNdis_CleanupContext(pContext);
            NdisFreeMemory(pContext, 0, 0);
            pContext = NULL;
        }
    }
    if (pContext && status == NDIS_STATUS_SUCCESS)
    {
        if (NDIS_STATUS_SUCCESS ==
            ParaNdis6_GetRegistrationOffloadInfo(pContext,
                &miniportAttributes.OffloadAttributes))
            status = NdisMSetMiniportAttributes(miniportAdapterHandle, &miniportAttributes);
            if (status != NDIS_STATUS_SUCCESS)
            {
                DPrintf(0, ("[%s] ERROR: NdisMSetMiniportAttributes 3 failed (%X)!\n", __FUNCTION__, status));
            }
    }

    if (pContext && status == NDIS_STATUS_SUCCESS)
    {
        ParaNdis_DebugRegisterMiniport(pContext, TRUE);
    }

    DEBUG_EXIT_STATUS(status ? 0 : 2, status);
    return status;
}
Example #12
0
VOID
IndicateReceivePacket(
    __in PTAP_ADAPTER_CONTEXT  Adapter,
    __in PUCHAR packetData,
    __in const unsigned int packetLength
    )
{
    PUCHAR  injectBuffer;

    //
    // Handle miniport Pause
    // ---------------------
    // NDIS 6 miniports implement a temporary "Pause" state normally followed
    // by the Restart. While in the Pause state it is forbidden for the miniport
    // to indicate receive NBLs.
    //
    // That is: The device interface may be "up", but the NDIS miniport send/receive
    // interface may be temporarily "down".
    //
    // BUGBUG!!! In the initial implementation of the NDIS 6 TapOas inject path
    // the code below will simply ignore inject packets passed to the driver while
    // the miniport is in the Paused state.
    //
    // The correct implementation is to go ahead and build the NBLs corresponding
    // to the inject packet - but queue them. When Restart is entered the
    // queued NBLs would be dequeued and indicated to the host.
    //
    if(tapAdapterSendAndReceiveReady(Adapter) != NDIS_STATUS_SUCCESS)
    {
        DEBUGP (("[%s] Lying send in IndicateReceivePacket while adapter paused\n",
            MINIPORT_INSTANCE_ID (Adapter)));

        return;
    }

    // Allocate flat buffer for packet data.
    injectBuffer = (PUCHAR )NdisAllocateMemoryWithTagPriority(
                        Adapter->MiniportAdapterHandle,
                        packetLength,
                        TAP_RX_INJECT_BUFFER_TAG,
                        NormalPoolPriority
                        );

    if( injectBuffer)
    {
        PMDL    mdl;

        // Copy packet data to flat buffer.
        NdisMoveMemory (injectBuffer, packetData, packetLength);

        // Allocate MDL for flat buffer.
        mdl = NdisAllocateMdl(
                Adapter->MiniportAdapterHandle,
                injectBuffer,
                packetLength
                );

        if( mdl )
        {
            PNET_BUFFER_LIST    netBufferList;

            mdl->Next = NULL;   // No next MDL

            // Allocate the NBL and NB. Link MDL chain to NB.
            netBufferList = NdisAllocateNetBufferAndNetBufferList(
                                Adapter->ReceiveNblPool,
                                0,                  // ContextSize
                                0,                  // ContextBackFill
                                mdl,                // MDL chain
                                0,
                                packetLength
                                );

            if(netBufferList != NULL)
            {
                ULONG       receiveFlags = 0;
                LONG        nblCount;

                NET_BUFFER_LIST_NEXT_NBL(netBufferList) = NULL; // Only one NBL

                if(KeGetCurrentIrql() == DISPATCH_LEVEL)
                {
                    receiveFlags |= NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL;
                }

                // Set flag indicating that this is an injected packet
                TAP_RX_NBL_FLAGS_CLEAR_ALL(netBufferList);
                TAP_RX_NBL_FLAG_SET(netBufferList,TAP_RX_NBL_FLAGS_IS_INJECTED);

                netBufferList->MiniportReserved[0] = NULL;
                netBufferList->MiniportReserved[1] = NULL;

                // Increment in-flight receive NBL count.
                nblCount = NdisInterlockedIncrement(&Adapter->ReceiveNblInFlightCount);
                ASSERT(nblCount > 0 );

                netBufferList->SourceHandle = Adapter->MiniportAdapterHandle;

                //
                // Indicate the packet
                // -------------------
                // Irp->AssociatedIrp.SystemBuffer with length irpSp->Parameters.Write.Length
                // contains the complete packet including Ethernet header and payload.
                //
                NdisMIndicateReceiveNetBufferLists(
                    Adapter->MiniportAdapterHandle,
                    netBufferList,
                    NDIS_DEFAULT_PORT_NUMBER,
                    1,      // NumberOfNetBufferLists
                    receiveFlags
                    );

                return;
            }
            else
            {
                DEBUGP (("[%s] NdisAllocateNetBufferAndNetBufferList failed in IndicateReceivePacket\n",
                    MINIPORT_INSTANCE_ID (Adapter)));
                NOTE_ERROR ();

                NdisFreeMdl(mdl);
                NdisFreeMemory(injectBuffer,0,0);
            }
        }
        else
        {
            DEBUGP (("[%s] NdisAllocateMdl failed in IndicateReceivePacket\n",
                MINIPORT_INSTANCE_ID (Adapter)));
            NOTE_ERROR ();

            NdisFreeMemory(injectBuffer,0,0);
        }
    }
    else
    {
        DEBUGP (("[%s] NdisAllocateMemoryWithTagPriority failed in IndicateReceivePacket\n",
            MINIPORT_INSTANCE_ID (Adapter)));
        NOTE_ERROR ();
    }
}
Example #13
0
// Returns with reference count initialized to one.
PTAP_ADAPTER_CONTEXT
tapAdapterContextAllocate(__in NDIS_HANDLE MiniportAdapterHandle) {
  PTAP_ADAPTER_CONTEXT adapter = NULL;

  adapter = (PTAP_ADAPTER_CONTEXT)NdisAllocateMemoryWithTagPriority(
      GlobalData.NdisDriverHandle, sizeof(TAP_ADAPTER_CONTEXT), TAP_ADAPTER_TAG,
      NormalPoolPriority);

  if (adapter) {
    NET_BUFFER_LIST_POOL_PARAMETERS nblPoolParameters = {0};

    NdisZeroMemory(adapter, sizeof(TAP_ADAPTER_CONTEXT));

    adapter->MiniportAdapterHandle = MiniportAdapterHandle;

    // Initialize cancel-safe IRP queue
    tapIrpCsqInitialize(&adapter->PendingReadIrpQueue);

    // Initialize TAP send packet queue.
    tapPacketQueueInitialize(&adapter->SendPacketQueue);

    // Allocate the adapter lock.
    NdisAllocateSpinLock(&adapter->AdapterLock);

    // NBL pool for making TAP receive indications.
    NdisZeroMemory(&nblPoolParameters, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));

    // Initialize event used to determine when all receive NBLs have been returned.
    NdisInitializeEvent(&adapter->ReceiveNblInFlightCountZeroEvent);

    nblPoolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
    nblPoolParameters.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
    nblPoolParameters.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
    nblPoolParameters.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
    nblPoolParameters.ContextSize = 0;
    // nblPoolParameters.ContextSize = sizeof(RX_NETBUFLIST_RSVD);
    nblPoolParameters.fAllocateNetBuffer = TRUE;
    nblPoolParameters.PoolTag = TAP_RX_NBL_TAG;

#pragma warning(suppress : 28197)
    adapter->ReceiveNblPool =
        NdisAllocateNetBufferListPool(adapter->MiniportAdapterHandle, &nblPoolParameters);

    if (adapter->ReceiveNblPool == NULL) {
      DEBUGP(("[TAP] Couldn't allocate adapter receive NBL pool\n"));
      NdisFreeMemory(adapter, 0, 0);
    }

    // Add initial reference. Normally removed in AdapterHalt.
    adapter->RefCount = 1;

    // Safe for multiple removes.
    NdisInitializeListHead(&adapter->AdapterListLink);

    //
    // The miniport adapter is initially powered up
    //
    adapter->CurrentPowerState = NdisDeviceStateD0;
  }

  return adapter;
}
Example #14
0
/**
 * This is a debug only function that performs memory management operations for us.
 * Memory allocated using this function is tracked, flagged when leaked, and caught for
 * overflows and underflows.
 * \warning Do not use this function directly. Using MP_ALLOCATE_MEMORY ensures that
 * this function gets called for debug version of the driver. Retail builds will use Ndis API
 * for allocation of memory
 * 
 * \param Size            The size in bytes of memory to allocate
 * \param FileName  The full path of file where this function is invoked from
 * \param LineNumber The line number in the file where this method was called from
 * \param Flags           Flags for special memory insturctions. Currently unused.
 * \return Pointer to the allocated memory or NULL in case of a failure
 * \sa MpFreeMemory, MP_ALLOCATE_MEMORY, MP_FREE_MEMORY, NdisAllocateMemoryWithTagPriority, MpFreeAllocatedBlocks
 */
PVOID 
MpAllocateMemory (
    NDIS_HANDLE           AllocateHandle,
    ULONG                 Size,
    ULONG                 Tag,
    EX_POOL_PRIORITY      Priority,
    __nullterminated PCHAR FileName,
    ULONG                 LineNumber,
    ULONG                 Flags
    )
{
    PVOID   memory = NULL;

    //
    // If the memory manager has not been initialized, do so now
    //
    if (!GlobalMemoryManagerInitialized)
    {
        //
        // NOTE: If two thread allocate the very first allocation simultaneously
        // it could cause double initialization of the memory manager. This is a
        // highly unlikely scenario and will occur in debug versions only.
        //
        NdisAllocateSpinLock(&GlobalMemoryLock);
        InitializeListHead(&GlobalMemoryList);
        GlobalMemoryManagerInitialized = TRUE;
    }

    //
    // Allocate the required memory chunk plus header and trailer bytes
    //
    memory = NdisAllocateMemoryWithTagPriority(
        AllocateHandle,
        Size + sizeof(MP_MEMORY_BLOCK) + sizeof(ULONG),
        Tag,
        Priority
        );

    if (memory != NULL)
    {
        //
        // Memory allocation succeeded. Add information about the allocated
        // block in the list that tracks all allocations.
        //
        PMP_MEMORY_BLOCK  memoryBlockHeader;

        // Fill in the memory header and trailer
        memoryBlockHeader = (PMP_MEMORY_BLOCK) memory;
        memoryBlockHeader->File = FileName;
        memoryBlockHeader->Line = LineNumber;
        memoryBlockHeader->Length = Size;
        memoryBlockHeader->Flags = Flags;
        memoryBlockHeader->HeaderPattern = MP_HEADER_PATTERN;
        *((PULONG) (((PUCHAR)(memory))+Size + sizeof(MP_MEMORY_BLOCK))) = MP_TRAILER_PATTERN;

        // Jump ahead by memory header so pointer returned to caller points at the right place
        memory = ((PUCHAR)memory) + sizeof (MP_MEMORY_BLOCK);

        // Store a reference to this block in the list
        NdisAcquireSpinLock (&GlobalMemoryLock);
        InsertHeadList (&GlobalMemoryList, &memoryBlockHeader->ListEntry);
        NdisReleaseSpinLock (&GlobalMemoryLock);
    }

    return memory;
}
Example #15
0
NDIS_STATUS
NDISLWF_AttachHandler(
    NDIS_HANDLE NdisFilterHandle,
    NDIS_HANDLE  FilterDriverContext,
    PNDIS_FILTER_ATTACH_PARAMETERS AttachParameters )
{
    PNDISLWF_CONTEXT FilterContext;
    NDIS_STATUS NdisStatus;
    NDIS_FILTER_ATTRIBUTES FilterAttributes;

    DPF(("%s!%s [%x.%x] (FilterHandle=%p DriverContext=%p AttachParameters=%p)\n", __MODULE__, __FUNCTION__, 
        PsGetCurrentProcessId(), PsGetCurrentThreadId(), 
        NdisFilterHandle, FilterDriverContext, AttachParameters )); 

    // Allocate an instance of the NDISLWF_CONTEXT structure
    // Use the pool tag CMfc (NdisAllocateMemoryWithTagPriority()) and store
    // the context in FilterContext
    if ( ( FilterContext = NdisAllocateMemoryWithTagPriority (
        NdisFilterHandle,
        sizeof(NDISLWF_CONTEXT),
        'cfMC', //CodeMachineFilterContext
        NormalPoolPriority ) ) == NULL ) {
        
        NdisStatus = NDIS_STATUS_RESOURCES;
        DPF(("%s!%s NdisAllocateMemoryWithTagPriority() FAIL\n", __MODULE__, __FUNCTION__)); 
        goto Exit;
    }

    NdisZeroMemory(FilterContext, sizeof(NDISLWF_CONTEXT));
    FilterContext->FilterHandle = NdisFilterHandle;
    FilterContext->MiniportIfIndex = AttachParameters->BaseMiniportIfIndex;

    // Initialize the FilterAttribute structure
    NdisZeroMemory(&FilterAttributes, sizeof(NDIS_FILTER_ATTRIBUTES));
    FilterAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;
    FilterAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES);
    FilterAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;
    FilterAttributes.Flags = 0;

    // Register the filter attributes in FilterAttributes with NDIS
    // and register the FilterContext allocated above as the FilterModuleContext
    // (NdisFSetAttributes())
    NdisStatus = NdisFSetAttributes(
        NdisFilterHandle, 
        FilterContext,
        &FilterAttributes);

    if (NdisStatus != NDIS_STATUS_SUCCESS) {
        DPF(("%s!%s NdisFSetAttributes() FAIL=%08x\n", __MODULE__, __FUNCTION__, NdisStatus)); 
        goto Exit;
    }

    return NdisStatus;

Exit :
    if ( FilterContext ) {
        // Free the filter context in FilterContext (NdisFreeMemory())
        NdisFreeMemory (
            FilterContext,
            sizeof(NDISLWF_CONTEXT),
            0 );
    }

    return NdisStatus;
} // NDISLWF_AttachHandler()
/******************************************************************
Replacement of resource requirement list, when needed:
The procedure traverses over all the resource lists in existing resource requirement list
(we receive it in IRP information field).
When the driver is not built to work with MSI resources, we must remove them from the
resource requirement list, otherwise the driver will fail to initialize
Typically MSI interrupts are labeled as preferred ones, when line interrupts are labeled as
alternative resources. Removing message interrupts, remove also "alternative" label from line interrupts.
*******************************************************************/
static PIO_RESOURCE_REQUIREMENTS_LIST ParseFilterResourceIrp(
    IN NDIS_HANDLE  MiniportAddDeviceContext,
    PIO_RESOURCE_REQUIREMENTS_LIST prrl,
    BOOLEAN bRemoveMSIResources)
{
    tRRLData newRRLData;
    ULONG nRemoved = 0;
    UINT nInterrupts = 0;
    PIO_RESOURCE_REQUIREMENTS_LIST newPrrl = NULL;
    ULONG QueueNumber;
#if NDIS_SUPPORT_NDIS620    
    QueueNumber = NdisGroupActiveProcessorCount(ALL_PROCESSOR_GROUPS) + 1;
#elif NDIS_SUPPORT_NDIS6
    QueueNumber = NdisSystemProcessorCount();
#else
    QueueNumber = 0; /* Don't create MSI resource descriptors*/
#endif


    if (QueueNumber > 2048)
        QueueNumber = 2048;

    DPrintf(resourceFilterLevel, ("[%s]%s\n", __FUNCTION__, bRemoveMSIResources ? "(Remove MSI resources...)" : ""));

    newPrrl = (PIO_RESOURCE_REQUIREMENTS_LIST)NdisAllocateMemoryWithTagPriority(
            MiniportAddDeviceContext,
            prrl->ListSize + (bRemoveMSIResources ? 0 : QueueNumber * sizeof(IO_RESOURCE_DESCRIPTOR)),
            PARANDIS_MEMORY_TAG,
            NormalPoolPriority);

    InitializeNewResourceRequirementsList(&newRRLData, newPrrl, prrl);
    if (prrl)
    {
        ULONG n, offset;
        PVOID p = &prrl->List[0];
        DPrintf(resourceFilterLevel, ("[%s] %d bytes, %d lists\n", __FUNCTION__, prrl->ListSize, prrl->AlternativeLists));
        offset = RtlPointerToOffset(prrl, p);
        for (n = 0; n < prrl->AlternativeLists && offset < prrl->ListSize; ++n)
        {
            ULONG nDesc;
            IO_RESOURCE_LIST *pior = (IO_RESOURCE_LIST *)p;
            if ((offset + sizeof(*pior)) < prrl->ListSize)
            {
                IO_RESOURCE_DESCRIPTOR *pd = &pior->Descriptors[0];
                DPrintf(resourceFilterLevel, ("[%s]+%d %d:%d descriptors follow\n", __FUNCTION__, offset, n, pior->Count));
                offset += RtlPointerToOffset(p, pd);
                AddNewResourceList(&newRRLData, pior);
                for (nDesc = 0; nDesc < pior->Count; ++nDesc)
                {
                    BOOLEAN bRemove = FALSE;
                    if ((offset + sizeof(*pd)) <= prrl->ListSize)
                    {
#ifdef DBG
                        DPrintf(resourceFilterLevel, ("[%s]+%d %d: type %d/%s, flags %X, option %X\n", __FUNCTION__, offset, nDesc, pd->Type, 
                            CM_RESOURCE_TYPE2String(pd->Type), pd->Flags, pd->Option));
#else
                        DPrintf(resourceFilterLevel, ("[%s]+%d %d: type %d, flags %X, option %X\n", __FUNCTION__, offset, nDesc, pd->Type,
                            pd->Flags, pd->Option));
#endif

                        if (pd->Type == CmResourceTypeInterrupt)
                        {
                            nInterrupts++;
                            DPrintf(0, ("[%s] min/max = %lx/%lx Option = 0x%lx, ShareDisposition = %u \n", __FUNCTION__, pd->u.Interrupt.MinimumVector, pd->u.Interrupt.MaximumVector,
                                pd->Option, pd->ShareDisposition));
                            if (pd->Flags & CM_RESOURCE_INTERRUPT_MESSAGE)
                            {
                                bRemove = bRemoveMSIResources;
                            }
                            else
                            {
                                // reset IO_RESOURCE_ALTERNATIVE attribute on Line Interrupt,
                                // if we remove MSI vectors, otherwise Windows will not allocate it for the device
                                if (bRemoveMSIResources && (pd->Option & IO_RESOURCE_ALTERNATIVE))
                                {
                                    pd->Option &= ~IO_RESOURCE_ALTERNATIVE;
                                }
                            }
                        }
                        if (!bRemove) AddNewResourceDescriptor(&newRRLData, pd);
                        else nRemoved++;
                    }
                    offset += sizeof(*pd);
                    pd = (IO_RESOURCE_DESCRIPTOR *)RtlOffsetToPointer(prrl, offset);
                }

                if (!bRemoveMSIResources)
                {
                    while (nInterrupts < QueueNumber)
                    {
                        IO_RESOURCE_DESCRIPTOR ior;
                        ior.Type = CmResourceTypeInterrupt;
                        ior.Flags = CM_RESOURCE_INTERRUPT_LATCHED | CM_RESOURCE_INTERRUPT_MESSAGE | CM_RESOURCE_INTERRUPT_POLICY_INCLUDED;
                        ior.Option = 0;
                        ior.ShareDisposition = CmResourceShareDeviceExclusive;
                        ior.u.Interrupt.MinimumVector = ior.u.Interrupt.MaximumVector = CM_RESOURCE_INTERRUPT_MESSAGE_TOKEN;
                        ior.u.Interrupt.AffinityPolicy = IrqPolicyMachineDefault;
                        ior.u.Interrupt.PriorityPolicy = IrqPriorityNormal;
                        AddNewResourceDescriptor(&newRRLData, &ior);
                        nInterrupts++;
                    }
                }

                FinalizeResourceList(&newRRLData);
                p = pd;
            }
        }
    }
    if (!bRemoveMSIResources)
    {
        SetupInterrruptAffinity(newPrrl);
    }
    if (bRemoveMSIResources && nRemoved)
    {
        DPrintf(0, ("[%s] %d resources removed\n", __FUNCTION__, nRemoved));
    }
    return newPrrl;
}