VOID FilterOidRequestComplete( IN NDIS_HANDLE FilterModuleContext, IN PNDIS_OID_REQUEST Request, IN NDIS_STATUS Status ) { PNETGW_ADAPT pAdapter = (PNETGW_ADAPT)FilterModuleContext; PNDIS_OID_REQUEST OriginalRequest; PINTERNAL_OID_REQUEST pInternalRequest; PFILTER_REQUEST_CONTEXT Context; NdisAcquireSpinLock(&pAdapter->Lock); Context = (PFILTER_REQUEST_CONTEXT)(&Request->SourceReserved[0]); pInternalRequest = (PINTERNAL_OID_REQUEST)(*Context); if (pInternalRequest->bLocal) { NdisReleaseSpinLock(&pAdapter->Lock); NdisFreeMemory(pInternalRequest, 0, 0); return; } OriginalRequest = pInternalRequest->pOrigReq; pAdapter->m_IntReq.Status = Status; pAdapter->m_IntReq.pOrigReq = NULL; pAdapter->m_IntReq.pReq = NULL; NdisReleaseSpinLock(&pAdapter->Lock); switch (Request->RequestType) { case NdisRequestMethod: OriginalRequest->DATA.METHOD_INFORMATION.OutputBufferLength = Request->DATA.METHOD_INFORMATION.OutputBufferLength; OriginalRequest->DATA.METHOD_INFORMATION.BytesRead = Request->DATA.METHOD_INFORMATION.BytesRead; OriginalRequest->DATA.METHOD_INFORMATION.BytesNeeded = Request->DATA.METHOD_INFORMATION.BytesNeeded; OriginalRequest->DATA.METHOD_INFORMATION.BytesWritten = Request->DATA.METHOD_INFORMATION.BytesWritten; break; case NdisRequestSetInformation: OriginalRequest->DATA.SET_INFORMATION.BytesRead = Request->DATA.SET_INFORMATION.BytesRead; OriginalRequest->DATA.SET_INFORMATION.BytesNeeded = Request->DATA.SET_INFORMATION.BytesNeeded; break; case NdisRequestQueryInformation: case NdisRequestQueryStatistics: default: OriginalRequest->DATA.QUERY_INFORMATION.BytesWritten = Request->DATA.QUERY_INFORMATION.BytesWritten; OriginalRequest->DATA.QUERY_INFORMATION.BytesNeeded = Request->DATA.QUERY_INFORMATION.BytesNeeded; break; } (*Context) = NULL; NdisFreeCloneOidRequest(pAdapter->FilterHandle, Request); NdisFOidRequestComplete(pAdapter->FilterHandle, OriginalRequest, Status); }
/* * -------------------------------------------------------------------------- * Implements filter driver's FilterOidRequestComplete function. * -------------------------------------------------------------------------- */ VOID OvsExtOidRequestComplete(NDIS_HANDLE filterModuleContext, PNDIS_OID_REQUEST oidRequest, NDIS_STATUS status) { POVS_SWITCH_CONTEXT switchObject = (POVS_SWITCH_CONTEXT)filterModuleContext; PNDIS_OID_REQUEST origReq = OvsOidGetOrigRequest(oidRequest); POVS_OID_CONTEXT oidContext = OvsOidGetContext(oidRequest); /* Only one of the two should be set */ ASSERT(origReq != NULL || oidContext != NULL); ASSERT(oidContext != NULL || origReq != NULL); OVS_LOG_TRACE("Enter: oidRequest %p, reqType: %d", oidRequest, oidRequest->RequestType); if (origReq == NULL) { NdisInterlockedDecrement(&(switchObject->pendingOidCount)); oidContext->status = status; NdisSetEvent(&oidContext->oidComplete); OVS_LOG_INFO("Internally generated request"); goto done; } switch(oidRequest->RequestType) { case NdisRequestMethod: OvsOidRequestCompleteMethod(switchObject, oidRequest, origReq, status); break; case NdisRequestSetInformation: OvsOidRequestCompleteSetInfo(switchObject, oidRequest, origReq, status); break; case NdisRequestQueryInformation: case NdisRequestQueryStatistics: default: OvsOidRequestCompleteQuery(switchObject, oidRequest, origReq, status); break; } OvsOidSetOrigRequest(oidRequest, NULL); NdisFreeCloneOidRequest(switchObject->NdisFilterHandle, oidRequest); NdisFOidRequestComplete(switchObject->NdisFilterHandle, origReq, status); NdisInterlockedDecrement(&(switchObject->pendingOidCount)); done: OVS_LOG_TRACE("Exit"); }
_Use_decl_annotations_ VOID FilterOidRequestComplete( NDIS_HANDLE FilterModuleContext, PNDIS_OID_REQUEST Request, NDIS_STATUS Status ) /*++ Routine Description: Notification that an OID request has been completed If this filter sends a request down to a lower layer, and the request is pended, the FilterOidRequestComplete routine is invoked when the request is complete. Most requests we've sent are simply clones of requests received from a higher layer; all we need to do is complete the original higher request. However, if this filter driver sends original requests down, it must not attempt to complete a pending request to the higher layer. Arguments: FilterModuleContext - our filter context area NdisRequest - the completed request Status - completion status --*/ { PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext; PNDIS_OID_REQUEST OriginalRequest; POTLWF_REQUEST_CONTEXT Context; BOOLEAN bFalse = FALSE; LogFuncEntryMsg(DRIVER_OID, "Filter: %p, Request %p", FilterModuleContext, Request); Context = (POTLWF_REQUEST_CONTEXT)(&Request->SourceReserved[0]); OriginalRequest = (*Context); // // This is an internal request // if (OriginalRequest == NULL) { otLwfInternalRequestComplete(pFilter, Request, Status); LogFuncExit(DRIVER_OID); return; } FILTER_ACQUIRE_LOCK(&pFilter->PendingOidRequestLock, bFalse); ASSERT(pFilter->PendingOidRequest == Request); pFilter->PendingOidRequest = NULL; FILTER_RELEASE_LOCK(&pFilter->PendingOidRequestLock, bFalse); // // Copy the information from the returned request to the original request // switch(Request->RequestType) { case NdisRequestMethod: OriginalRequest->DATA.METHOD_INFORMATION.OutputBufferLength = Request->DATA.METHOD_INFORMATION.OutputBufferLength; OriginalRequest->DATA.METHOD_INFORMATION.BytesRead = Request->DATA.METHOD_INFORMATION.BytesRead; OriginalRequest->DATA.METHOD_INFORMATION.BytesNeeded = Request->DATA.METHOD_INFORMATION.BytesNeeded; OriginalRequest->DATA.METHOD_INFORMATION.BytesWritten = Request->DATA.METHOD_INFORMATION.BytesWritten; break; case NdisRequestSetInformation: OriginalRequest->DATA.SET_INFORMATION.BytesRead = Request->DATA.SET_INFORMATION.BytesRead; OriginalRequest->DATA.SET_INFORMATION.BytesNeeded = Request->DATA.SET_INFORMATION.BytesNeeded; break; case NdisRequestQueryInformation: case NdisRequestQueryStatistics: default: OriginalRequest->DATA.QUERY_INFORMATION.BytesWritten = Request->DATA.QUERY_INFORMATION.BytesWritten; OriginalRequest->DATA.QUERY_INFORMATION.BytesNeeded = Request->DATA.QUERY_INFORMATION.BytesNeeded; break; } (*Context) = NULL; LogVerbose(DRIVER_OID, "Freeing (cloned) Oid Request %p", Request); NdisFreeCloneOidRequest(pFilter->FilterHandle, Request); LogVerbose(DRIVER_OID, "Completing (external) Oid Request %p", OriginalRequest); NdisFOidRequestComplete(pFilter->FilterHandle, OriginalRequest, Status); LogFuncExit(DRIVER_OID); }
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; }
// // FilterOidRequestComplete Function // http://msdn.microsoft.com/en-us/library/ff549956(v=VS.85).aspx // _Use_decl_annotations_ VOID SxNdisOidRequestComplete( NDIS_HANDLE FilterModuleContext, PNDIS_OID_REQUEST NdisOidRequest, NDIS_STATUS Status ) { PSX_SWITCH_OBJECT switchObject = (PSX_SWITCH_OBJECT)FilterModuleContext; PNDIS_OID_REQUEST originalRequest; PVOID *oidRequestContext; PNDIS_SWITCH_NIC_OID_REQUEST nicOidRequestBuf; PNDIS_OBJECT_HEADER header; DEBUGP(DL_TRACE, ("===>SxOidRequestComplete, NdisOidRequest %p.\n", NdisOidRequest)); oidRequestContext = (PVOID*)(&NdisOidRequest->SourceReserved[0]); originalRequest = (*oidRequestContext); // // This is the internal request // if (originalRequest == NULL) { SxpNdisCompleteInternalOidRequest(switchObject, NdisOidRequest, Status); goto Cleanup; } // // Copy the information from the returned request to the original request // switch(NdisOidRequest->RequestType) { case NdisRequestMethod: originalRequest->DATA.METHOD_INFORMATION.OutputBufferLength = NdisOidRequest->DATA.METHOD_INFORMATION.OutputBufferLength; originalRequest->DATA.METHOD_INFORMATION.BytesRead = NdisOidRequest->DATA.METHOD_INFORMATION.BytesRead; originalRequest->DATA.METHOD_INFORMATION.BytesNeeded = NdisOidRequest->DATA.METHOD_INFORMATION.BytesNeeded; originalRequest->DATA.METHOD_INFORMATION.BytesWritten = NdisOidRequest->DATA.METHOD_INFORMATION.BytesWritten; if (NdisOidRequest->DATA.METHOD_INFORMATION.Oid == OID_SWITCH_NIC_REQUEST && switchObject->OldNicRequest != NULL) { nicOidRequestBuf = NdisOidRequest->DATA.METHOD_INFORMATION.InformationBuffer; Status = SxExtProcessNicRequestComplete(switchObject, switchObject->ExtensionContext, nicOidRequestBuf->OidRequest, nicOidRequestBuf->SourcePortId, nicOidRequestBuf->SourceNicIndex, nicOidRequestBuf->DestinationPortId, nicOidRequestBuf->DestinationNicIndex, Status); originalRequest->DATA.METHOD_INFORMATION.InformationBuffer = switchObject->OldNicRequest; switchObject->OldNicRequest = NULL; ExFreePoolWithTag(nicOidRequestBuf, SxExtAllocationTag); } break; case NdisRequestSetInformation: header = originalRequest->DATA.SET_INFORMATION.InformationBuffer; originalRequest->DATA.SET_INFORMATION.BytesRead = NdisOidRequest->DATA.SET_INFORMATION.BytesRead; originalRequest->DATA.SET_INFORMATION.BytesNeeded = NdisOidRequest->DATA.SET_INFORMATION.BytesNeeded; if (NdisOidRequest->DATA.METHOD_INFORMATION.Oid == OID_SWITCH_PORT_CREATE && Status != NDIS_STATUS_SUCCESS) { SxExtDeletePort(switchObject, switchObject->ExtensionContext, (PNDIS_SWITCH_PORT_PARAMETERS)header); } else if (NdisOidRequest->DATA.METHOD_INFORMATION.Oid == OID_SWITCH_PORT_CREATE && Status != NDIS_STATUS_SUCCESS) { SxExtDeleteNic(switchObject, switchObject->ExtensionContext, (PNDIS_SWITCH_NIC_PARAMETERS)header); } break; case NdisRequestQueryInformation: case NdisRequestQueryStatistics: default: originalRequest->DATA.QUERY_INFORMATION.BytesWritten = NdisOidRequest->DATA.QUERY_INFORMATION.BytesWritten; originalRequest->DATA.QUERY_INFORMATION.BytesNeeded = NdisOidRequest->DATA.QUERY_INFORMATION.BytesNeeded; break; } (*oidRequestContext) = NULL; NdisFreeCloneOidRequest(switchObject->NdisFilterHandle, NdisOidRequest); NdisFOidRequestComplete(switchObject->NdisFilterHandle, originalRequest, Status); DEBUGP(DL_TRACE, ("<===SxOidRequestComplete.\n")); Cleanup: NdisInterlockedDecrement(&switchObject->PendingOidCount); }
// // 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; }