/* * -------------------------------------------------------------------------- * Implements filter driver's FilterAttach function. * * This function allocates the switch context, and initializes its necessary * members. * -------------------------------------------------------------------------- */ NDIS_STATUS OvsExtAttach(NDIS_HANDLE ndisFilterHandle, NDIS_HANDLE filterDriverContext, PNDIS_FILTER_ATTACH_PARAMETERS attachParameters) { NDIS_STATUS status = NDIS_STATUS_FAILURE; NDIS_FILTER_ATTRIBUTES ovsExtAttributes; POVS_SWITCH_CONTEXT switchContext = NULL; UNREFERENCED_PARAMETER(filterDriverContext); OVS_LOG_TRACE("Enter: ndisFilterHandle %p", ndisFilterHandle); ASSERT(filterDriverContext == (NDIS_HANDLE)gOvsExtDriverObject); if (attachParameters->MiniportMediaType != NdisMedium802_3) { status = NDIS_STATUS_INVALID_PARAMETER; goto cleanup; } if (gOvsExtDriverHandle == NULL) { OVS_LOG_TRACE("Exit: OVSEXT driver is not loaded."); ASSERT(FALSE); goto cleanup; } NdisAcquireSpinLock(gOvsCtrlLock); if (gOvsSwitchContext) { NdisReleaseSpinLock(gOvsCtrlLock); OVS_LOG_TRACE("Exit: Failed to create OVS Switch, only one datapath is" "supported, %p.", gOvsSwitchContext); goto cleanup; } if (gOvsInAttach) { NdisReleaseSpinLock(gOvsCtrlLock); /* Just fail the request. */ OVS_LOG_TRACE("Exit: Failed to create OVS Switch, since another attach" "instance is in attach process."); goto cleanup; } gOvsInAttach = TRUE; NdisReleaseSpinLock(gOvsCtrlLock); status = OvsInitIpHelper(ndisFilterHandle); if (status != STATUS_SUCCESS) { OVS_LOG_ERROR("Exit: Failed to initialize IP helper."); goto cleanup; } status = OvsCreateSwitch(ndisFilterHandle, &switchContext); if (status != NDIS_STATUS_SUCCESS) { OvsCleanupIpHelper(); goto cleanup; } ASSERT(switchContext); /* * Register the switch context with NDIS so NDIS can pass it back to the * Filterxxx callback functions as the 'FilterModuleContext' parameter. */ RtlZeroMemory(&ovsExtAttributes, sizeof(NDIS_FILTER_ATTRIBUTES)); ovsExtAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1; ovsExtAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES); ovsExtAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES; ovsExtAttributes.Flags = 0; NDIS_DECLARE_FILTER_MODULE_CONTEXT(OVS_SWITCH_CONTEXT); status = NdisFSetAttributes(ndisFilterHandle, switchContext, &ovsExtAttributes); if (status != NDIS_STATUS_SUCCESS) { OVS_LOG_ERROR("Failed to set attributes."); OvsCleanupIpHelper(); goto cleanup; } /* Setup the state machine. */ switchContext->controlFlowState = OvsSwitchAttached; switchContext->dataFlowState = OvsSwitchPaused; gOvsSwitchContext = switchContext; KeMemoryBarrier(); cleanup: gOvsInAttach = FALSE; if (status != NDIS_STATUS_SUCCESS) { if (switchContext != NULL) { OvsDeleteSwitch(switchContext); } } OVS_LOG_TRACE("Exit: status %x", status); return status; }
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()
// // FilterAttach Function // http://msdn.microsoft.com/en-us/library/ff549905(v=VS.85).aspx // _Use_decl_annotations_ NDIS_STATUS SxNdisAttach( NDIS_HANDLE NdisFilterHandle, NDIS_HANDLE SxDriverContext, PNDIS_FILTER_ATTACH_PARAMETERS AttachParameters ) { NDIS_STATUS status; NDIS_FILTER_ATTRIBUTES sxAttributes; ULONG switchObjectSize; NDIS_SWITCH_CONTEXT switchContext; NDIS_SWITCH_OPTIONAL_HANDLERS switchHandler; PSX_SWITCH_OBJECT switchObject; UNREFERENCED_PARAMETER(SxDriverContext); DEBUGP(DL_TRACE, ("===>SxAttach: NdisFilterHandle %p\n", NdisFilterHandle)); status = NDIS_STATUS_SUCCESS; switchObject = NULL; NT_ASSERT(SxDriverContext == (NDIS_HANDLE)SxDriverObject); if (AttachParameters->MiniportMediaType != NdisMedium802_3) { status = NDIS_STATUS_INVALID_PARAMETER; goto Cleanup; } switchHandler.Header.Type = NDIS_OBJECT_TYPE_SWITCH_OPTIONAL_HANDLERS; switchHandler.Header.Size = NDIS_SIZEOF_SWITCH_OPTIONAL_HANDLERS_REVISION_1; switchHandler.Header.Revision = NDIS_SWITCH_OPTIONAL_HANDLERS_REVISION_1; status = NdisFGetOptionalSwitchHandlers(NdisFilterHandle, &switchContext, &switchHandler); if (status != NDIS_STATUS_SUCCESS) { DEBUGP(DL_ERROR, ("SxAttach: Extension is running in non-switch environment.\n")); goto Cleanup; } switchObjectSize = sizeof(SX_SWITCH_OBJECT); switchObject = ExAllocatePoolWithTag(NonPagedPoolNx, switchObjectSize, SxExtAllocationTag); if (switchObject == NULL) { status = NDIS_STATUS_RESOURCES; goto Cleanup; } RtlZeroMemory(switchObject, switchObjectSize); // // Initialize NDIS related information. // switchObject->NdisFilterHandle = NdisFilterHandle; switchObject->NdisSwitchContext = switchContext; RtlCopyMemory(&switchObject->NdisSwitchHandlers, &switchHandler, sizeof(NDIS_SWITCH_OPTIONAL_HANDLERS)); // // Let the extension create its own context. // status = SxExtCreateSwitch(switchObject, &(switchObject->ExtensionContext)); if (status != NDIS_STATUS_SUCCESS) { goto Cleanup; } // // Register the object with NDIS because NDIS passes this object when it // calls into the driver. // NdisZeroMemory(&sxAttributes, sizeof(NDIS_FILTER_ATTRIBUTES)); sxAttributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1; sxAttributes.Header.Size = sizeof(NDIS_FILTER_ATTRIBUTES); sxAttributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES; sxAttributes.Flags = 0; NDIS_DECLARE_FILTER_MODULE_CONTEXT(SX_SWITCH_OBJECT); status = NdisFSetAttributes(NdisFilterHandle, switchObject, &sxAttributes); if (status != NDIS_STATUS_SUCCESS) { DEBUGP(DL_ERROR, ("SxBase: Failed to set attributes.\n")); goto Cleanup; } switchObject->ControlFlowState = SxSwitchAttached; switchObject->DataFlowState = SxSwitchPaused; NdisAcquireSpinLock(&SxExtensionListLock); InsertHeadList(&SxExtensionList, &switchObject->Link); NdisReleaseSpinLock(&SxExtensionListLock); Cleanup: if (status != NDIS_STATUS_SUCCESS) { if (switchObject != NULL) { ExFreePool(switchObject); } } DEBUGP(DL_TRACE, ("<===SxAttach: status %x\n", status)); return status; }