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; }
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; }
_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; }
// // 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; }