Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #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;
}
Beispiel #4
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;
}