Example #1
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;
}
Example #2
0
NDIS_STATUS
FilterOidRequest(
    IN NDIS_HANDLE         FilterModuleContext,
    IN PNDIS_OID_REQUEST   Request
)
{
    PNETGW_ADAPT pAdapter = (PNETGW_ADAPT)FilterModuleContext;
    NDIS_STATUS Status = NDIS_STATUS_FAILURE;
    PNDIS_OID_REQUEST ClonedRequest = NULL;
    PFILTER_REQUEST_CONTEXT pContext = NULL;
    BOOLEAN bSubmit = FALSE;

    if (NdisRequestSetInformation == Request->RequestType ||
        NdisRequestQueryInformation == Request->RequestType) {

        if (OID_TCP_OFFLOAD_PARAMETERS == Request->DATA.QUERY_INFORMATION.Oid ||
            OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES == Request->DATA.QUERY_INFORMATION.Oid ||
            OID_TCP_OFFLOAD_CURRENT_CONFIG == Request->DATA.QUERY_INFORMATION.Oid
            ) {
            Status = NDIS_STATUS_NOT_SUPPORTED;
            goto finish;
        }
    }

    Status = NdisAllocateCloneOidRequest(pAdapter->FilterHandle,
        Request,
        FILTER_TAG,
        &ClonedRequest);

    if (Status != NDIS_STATUS_SUCCESS)
        goto finish;

    bSubmit = TRUE;

    ClonedRequest->RequestId = Request->RequestId;

    pContext = (PFILTER_REQUEST_CONTEXT)(&ClonedRequest->SourceReserved[0]);
    *pContext = (NDIS_OID_REQUEST*)&(pAdapter->m_IntReq);
    pAdapter->m_IntReq.pOrigReq = Request;
    pAdapter->m_IntReq.pReq = ClonedRequest;

    pAdapter->m_IntReq.bLocal = FALSE;
    pAdapter->m_IntReq.Status = NDIS_STATUS_PENDING;

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

    if (Status != NDIS_STATUS_PENDING) {
        FilterOidRequestComplete(pAdapter, ClonedRequest, Status);
        Status = NDIS_STATUS_PENDING;
    }

finish:

    if (bSubmit)
        return Status;

    switch (Request->RequestType) {
        case NdisRequestMethod:
        Request->DATA.METHOD_INFORMATION.BytesRead = 0;
        Request->DATA.METHOD_INFORMATION.BytesNeeded = 0;
        Request->DATA.METHOD_INFORMATION.BytesWritten = 0;
        break;

        case NdisRequestSetInformation:
        Request->DATA.SET_INFORMATION.BytesRead = 0;
        Request->DATA.SET_INFORMATION.BytesNeeded = 0;
        break;

        case NdisRequestQueryInformation:
        case NdisRequestQueryStatistics:

        break;
        default:
        Request->DATA.QUERY_INFORMATION.BytesWritten = 0;
        Request->DATA.QUERY_INFORMATION.BytesNeeded = 0;
        break;
    }

    return Status;
}
Example #3
0
_Use_decl_annotations_
NDIS_STATUS
FilterOidRequest(
    NDIS_HANDLE         FilterModuleContext,
    PNDIS_OID_REQUEST   Request
    )
/*++

Routine Description:

    Request handler
    Handle requests from upper layers

Arguments:

    FilterModuleContext   - our filter
    Request               - the request passed down


Return Value:

     NDIS_STATUS_SUCCESS
     NDIS_STATUS_PENDING
     NDIS_STATUS_XXX

NOTE: Called at <= DISPATCH_LEVEL  (unlike a miniport's MiniportOidRequest)

--*/
{
    PMS_FILTER              pFilter = (PMS_FILTER)FilterModuleContext;
    NDIS_STATUS             Status;
    PNDIS_OID_REQUEST       ClonedRequest=NULL;
    BOOLEAN                 bSubmitted = FALSE;
    POTLWF_REQUEST_CONTEXT Context;
    BOOLEAN                 bFalse = FALSE;

    LogFuncEntryMsg(DRIVER_OID, "Request %p", Request);

    //
    // Most of the time, a filter will clone the OID request and pass down
    // the clone.  When the clone completes, the filter completes the original
    // OID request.
    //
    // If your filter needs to modify a specific request, it can modify the
    // request before or after sending down the cloned request.  Or, it can
    // complete the original request on its own without sending down any
    // clone at all.
    //
    // If your filter driver does not need to modify any OID requests, then
    // you may simply omit this routine entirely; NDIS will pass OID requests
    // down on your behalf.  This is more efficient than implementing a 
    // routine that does nothing but clone all requests, as in the sample here.
    //

    do
    {
        Status = NdisAllocateCloneOidRequest(pFilter->FilterHandle,
                                            Request,
                                            OTLWF_CLONED_OID_TAG,
                                            &ClonedRequest);
        if (Status != NDIS_STATUS_SUCCESS)
        {
            LogWarning(DRIVER_OID, "Failed to Clone Request, %!NDIS_STATUS!", Status);
            break;
        }

        Context = (POTLWF_REQUEST_CONTEXT)(&ClonedRequest->SourceReserved[0]);
        *Context = Request;

        bSubmitted = TRUE;

        //
        // Use same request ID
        //
        ClonedRequest->RequestId = Request->RequestId;

        pFilter->PendingOidRequest = ClonedRequest;

        LogVerbose(DRIVER_OID, "Sending (cloned) Oid Request %p", ClonedRequest);

        Status = NdisFOidRequest(pFilter->FilterHandle, ClonedRequest);

        if (Status != NDIS_STATUS_PENDING)
        {
            FilterOidRequestComplete(pFilter, ClonedRequest, Status);
            Status = NDIS_STATUS_PENDING;
        }

    } while(bFalse);

    if (bSubmitted == FALSE)
    {
        switch(Request->RequestType)
        {
            case NdisRequestMethod:
                Request->DATA.METHOD_INFORMATION.BytesRead = 0;
                Request->DATA.METHOD_INFORMATION.BytesNeeded = 0;
                Request->DATA.METHOD_INFORMATION.BytesWritten = 0;
                break;

            case NdisRequestSetInformation:
                Request->DATA.SET_INFORMATION.BytesRead = 0;
                Request->DATA.SET_INFORMATION.BytesNeeded = 0;
                break;

            case NdisRequestQueryInformation:
            case NdisRequestQueryStatistics:
            default:
                Request->DATA.QUERY_INFORMATION.BytesWritten = 0;
                Request->DATA.QUERY_INFORMATION.BytesNeeded = 0;
                break;
        }

    }

    LogFuncExitNDIS(DRIVER_OID, Status);

    return Status;
}
Example #4
0
/*
 * --------------------------------------------------------------------------
 * Utility function to issue the specified OID to the NDIS stack. The OID is
 * directed towards the miniport edge of the extensible switch.
 * An OID that gets issued may not complete immediately, and in such cases, the
 * function waits for the OID to complete. Thus, this function must not be
 * called at the PASSIVE_LEVEL.
 * --------------------------------------------------------------------------
 */
static NDIS_STATUS
OvsIssueOidRequest(POVS_SWITCH_CONTEXT switchContext,
                   NDIS_REQUEST_TYPE oidType,
                   UINT32 oidRequestEnum,
                   PVOID oidInputBuffer,
                   UINT32 inputSize,
                   PVOID oidOutputBuffer,
                   UINT32 outputSize,
                   UINT32 *outputSizeNeeded)
{
    NDIS_STATUS status;
    PNDIS_OID_REQUEST oidRequest;
    POVS_OID_CONTEXT oidContext;
    ULONG OvsExtOidRequestId =          'ISVO';

    DBG_UNREFERENCED_PARAMETER(inputSize);
    DBG_UNREFERENCED_PARAMETER(oidInputBuffer);

    OVS_LOG_TRACE("Enter: switchContext: %p, oidType: %d",
                  switchContext, oidType);

    ASSERT(oidInputBuffer == NULL || inputSize != 0);
    ASSERT(oidOutputBuffer == NULL || outputSize != 0);
    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

    oidRequest = OvsAllocateMemoryWithTag(sizeof *oidRequest,
                                          OVS_OID_POOL_TAG);
    if (!oidRequest) {
        status = NDIS_STATUS_RESOURCES;
        goto done;
    }

    oidContext = OvsAllocateMemoryWithTag(sizeof *oidContext,
                                          OVS_OID_POOL_TAG);
    if (!oidContext) {
        OvsFreeMemoryWithTag(oidRequest, OVS_OID_POOL_TAG);
        status = NDIS_STATUS_RESOURCES;
        goto done;
    }

    RtlZeroMemory(oidRequest, sizeof *oidRequest);
    RtlZeroMemory(oidContext, sizeof *oidContext);

    oidRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
    oidRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1;
    oidRequest->Header.Size = NDIS_SIZEOF_OID_REQUEST_REVISION_1;

    oidRequest->RequestType = oidType;
    oidRequest->PortNumber = 0;
    oidRequest->Timeout = 0;
    oidRequest->RequestId = (PVOID)OvsExtOidRequestId;

    switch(oidType) {
    case NdisRequestQueryInformation:
        oidRequest->DATA.QUERY_INFORMATION.Oid = oidRequestEnum;
        oidRequest->DATA.QUERY_INFORMATION.InformationBuffer = oidOutputBuffer;
        oidRequest->DATA.QUERY_INFORMATION.InformationBufferLength = outputSize;
        break;
    default:
        ASSERT(FALSE);
        status = NDIS_STATUS_INVALID_PARAMETER;
        break;
    }

    /*
     * We make use of the SourceReserved field in the OID request to store
     * pointers to the original OID (if any), and also context for completion
     * (if any).
     */
    oidContext->status = NDIS_STATUS_SUCCESS;
    NdisInitializeEvent(&oidContext->oidComplete);

    OvsOidSetOrigRequest(oidRequest, NULL);
    OvsOidSetContext(oidRequest, oidContext);

    NdisInterlockedIncrement(&(switchContext->pendingOidCount));
    status = NdisFOidRequest(switchContext->NdisFilterHandle, oidRequest);
    if (status == NDIS_STATUS_PENDING) {
        NdisWaitEvent(&oidContext->oidComplete, 0);
    } else {
        NdisInterlockedDecrement(&(switchContext->pendingOidCount));
    }

    if (status == NDIS_STATUS_INVALID_LENGTH ||
        oidContext->status == NDIS_STATUS_INVALID_LENGTH) {
        switch(oidType) {
        case NdisRequestQueryInformation:
            *outputSizeNeeded = oidRequest->DATA.QUERY_INFORMATION.BytesNeeded;
        }
    }

    status = oidContext->status;
    ASSERT(status != NDIS_STATUS_PENDING);

    OvsFreeMemoryWithTag(oidRequest, OVS_OID_POOL_TAG);
    OvsFreeMemoryWithTag(oidContext, OVS_OID_POOL_TAG);

done:
    OVS_LOG_TRACE("Exit: status %8x.", status);
    return status;
}
Example #5
0
NDIS_STATUS
OvsExtOidRequest(NDIS_HANDLE filterModuleContext,
                 PNDIS_OID_REQUEST oidRequest)
{
    POVS_SWITCH_CONTEXT switchObject = (POVS_SWITCH_CONTEXT)filterModuleContext;
    NDIS_STATUS status = NDIS_STATUS_SUCCESS;
    PNDIS_OID_REQUEST clonedOidRequest = NULL;
    struct _METHOD *methodInfo = &(oidRequest->DATA.METHOD_INFORMATION);
    BOOLEAN completeOid = FALSE;
    ULONG bytesNeeded = 0;

    OVS_LOG_TRACE("Enter: oidRequest %p, reqType: %d",
                  oidRequest, oidRequest->RequestType);
    status = NdisAllocateCloneOidRequest(switchObject->NdisFilterHandle,
                                         oidRequest, OVS_MEMORY_TAG,
                                         &clonedOidRequest);
    if (status != NDIS_STATUS_SUCCESS) {
        goto done;
    }

    NdisInterlockedIncrement(&(switchObject->pendingOidCount));

    /* set the original oid request in cloned one. */
    OvsOidSetOrigRequest(clonedOidRequest, oidRequest);
    OvsOidSetContext(clonedOidRequest, NULL);

    switch(clonedOidRequest->RequestType) {
    case NdisRequestSetInformation:
        status = OvsProcessSetOid(switchObject, clonedOidRequest,
                                                   &completeOid);
        break;
    case NdisRequestMethod:
        status = OvsProcessMethodOid(switchObject, clonedOidRequest,
                                     &completeOid, &bytesNeeded);
        break;
    default:
        /* We do not handle other request types as of now.
         * We are just a passthrough for those. */
        break;
    }

    if (completeOid == TRUE) {
        /* dont leave any reference back to original request,
         * even if we are freeing it up. */
        OVS_LOG_INFO("Complete True oidRequest %p.", oidRequest);
        OvsOidSetOrigRequest(clonedOidRequest, NULL);
        NdisFreeCloneOidRequest(switchObject->NdisFilterHandle,
                                             clonedOidRequest);
        methodInfo->BytesNeeded = bytesNeeded;
        NdisInterlockedDecrement(&switchObject->pendingOidCount);
        goto done;
    }

    /* pass the request down */
    status = NdisFOidRequest(switchObject->NdisFilterHandle, clonedOidRequest);
    if (status != NDIS_STATUS_PENDING) {
        OvsExtOidRequestComplete(switchObject, clonedOidRequest, status);
        /* sample code says so */
        status = NDIS_STATUS_PENDING;
    }

done:
    OVS_LOG_TRACE("Exit: status %8x.", status);
    return status;
}
NDIS_STATUS
SxLibIssueOidRequest(
    _In_ PSX_SWITCH_OBJECT Switch,
    _In_ NDIS_REQUEST_TYPE RequestType,
    _In_ NDIS_OID Oid,
    _In_opt_ PVOID InformationBuffer,
    _In_ ULONG InformationBufferLength,
    _In_ ULONG OutputBufferLength,
    _In_ ULONG MethodId,
    _In_ UINT Timeout,
    _Out_ PULONG BytesNeeded
    )
{
    NDIS_STATUS status;
    PSX_OID_REQUEST oidRequest;
    PNDIS_OID_REQUEST ndisOidRequest;
    ULONG bytesNeeded;
    BOOLEAN asyncCompletion;

    status = NDIS_STATUS_SUCCESS;
    oidRequest = NULL;
    bytesNeeded = 0;
    asyncCompletion = FALSE;

    NdisInterlockedIncrement(&Switch->PendingOidCount);

    if (Switch->ControlFlowState != SxSwitchAttached)
    {
        status = NDIS_STATUS_CLOSING;
        goto Cleanup;
    }

    //
    // Dynamically allocate filter request so that we can handle asynchronous
    // completion.
    //
    oidRequest = (PSX_OID_REQUEST)ExAllocatePoolWithTag(NonPagedPoolNx,
                                                        sizeof(SX_OID_REQUEST),
                                                        SxExtAllocationTag);
    if (oidRequest == NULL)
    {
        goto Cleanup;
    }

    NdisZeroMemory(oidRequest, sizeof(SX_OID_REQUEST));
    ndisOidRequest = &oidRequest->NdisOidRequest;
    NdisInitializeEvent(&oidRequest->ReqEvent);

    ndisOidRequest->Header.Type = NDIS_OBJECT_TYPE_OID_REQUEST;
    ndisOidRequest->Header.Revision = NDIS_OID_REQUEST_REVISION_1;
    ndisOidRequest->Header.Size = sizeof(NDIS_OID_REQUEST);
    ndisOidRequest->RequestType = RequestType;
    ndisOidRequest->Timeout = Timeout;

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

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

    case NdisRequestMethod:
         ndisOidRequest->DATA.METHOD_INFORMATION.Oid = Oid;
         ndisOidRequest->DATA.METHOD_INFORMATION.MethodId = MethodId;
         ndisOidRequest->DATA.METHOD_INFORMATION.InformationBuffer =
             InformationBuffer;
         ndisOidRequest->DATA.METHOD_INFORMATION.InputBufferLength =
             InformationBufferLength;
         ndisOidRequest->DATA.METHOD_INFORMATION.OutputBufferLength =
             OutputBufferLength;
         break;

    default:
        NT_ASSERT(FALSE);
        break;
    }

    ndisOidRequest->RequestId = (PVOID)SxExtOidRequestId;
    status = NdisFOidRequest(Switch->NdisFilterHandle, ndisOidRequest);

    if (status == NDIS_STATUS_PENDING)
    {
        asyncCompletion = TRUE;
        NdisWaitEvent(&oidRequest->ReqEvent, 0);
    }
    else
    {
        SxpNdisCompleteInternalOidRequest(Switch, ndisOidRequest, status);
    }

    bytesNeeded = oidRequest->BytesNeeded;
    status = oidRequest->Status;

Cleanup:

    if (BytesNeeded != NULL)
    {
        *BytesNeeded = bytesNeeded;
    }
    
    if (!asyncCompletion)
    {
        NdisInterlockedDecrement(&Switch->PendingOidCount);
    }
    
    if (oidRequest != NULL)
    {
        ExFreePoolWithTag(oidRequest, SxExtAllocationTag);
    }
    
    return status;
}
Example #7
0
//
// FilterOidRequest Function
// http://msdn.microsoft.com/en-us/library/ff549954(v=VS.85).aspx
//
_Use_decl_annotations_
NDIS_STATUS
SxNdisOidRequest(
    NDIS_HANDLE FilterModuleContext,
    PNDIS_OID_REQUEST OidRequest
    )
{
    PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)FilterModuleContext;
    NDIS_STATUS status;
    PNDIS_OID_REQUEST clonedRequest=NULL;
    PVOID *cloneRequestContext;
    BOOLEAN completeOid = FALSE;
    ULONG bytesNeeded = 0;
   
    status = NDIS_STATUS_SUCCESS;

    DEBUGP(DL_TRACE, ("===>SxOidRequest: OidRequest %p.\n", OidRequest));
    
    NdisInterlockedIncrement(&switchObject->PendingOidCount);

    status = NdisAllocateCloneOidRequest(switchObject->NdisFilterHandle,
                                         OidRequest,
                                         SxExtAllocationTag,
                                         &clonedRequest);
    if (status != NDIS_STATUS_SUCCESS)
    {
        DEBUGP(DL_WARN, ("FilerOidRequest: Cannot Clone OidRequest\n"));
        goto Cleanup;
    }

    cloneRequestContext = (PVOID*)(&clonedRequest->SourceReserved[0]);
    *cloneRequestContext = OidRequest;
    
    switch (clonedRequest->RequestType)
    {           
        case NdisRequestSetInformation:
            status = SxpNdisProcessSetOid(switchObject,
                                          clonedRequest,
                                          &completeOid);
            break;
        
        case NdisRequestMethod:
            status = SxpNdisProcessMethodOid(switchObject,
                                             clonedRequest,
                                             &completeOid,
                                             &bytesNeeded);

            break;
    }
    
    if (completeOid)
    {
        NdisFreeCloneOidRequest(switchObject->NdisFilterHandle, clonedRequest);
        OidRequest->DATA.METHOD_INFORMATION.BytesNeeded = bytesNeeded;
        NdisInterlockedDecrement(&switchObject->PendingOidCount);
        goto Cleanup;
    }

    status = NdisFOidRequest(switchObject->NdisFilterHandle, clonedRequest);

    if (status != NDIS_STATUS_PENDING)
    {
        SxNdisOidRequestComplete(switchObject, clonedRequest, status);

        //
        // We must still return status as pending because we complete the
        // request using NdisFOidRequestComplete() in SxOidRequestComplete().
        //
        status = NDIS_STATUS_PENDING;
    }

Cleanup:

    DEBUGP(DL_TRACE, ("<===SxOidRequest: status %8x.\n", status));
    return status;
}