Esempio n. 1
0
VOID
	natpUnbindAdapter(
		OUT PNDIS_STATUS Status,
		IN  NDIS_HANDLE ProtocolBindingContext,
		IN  NDIS_HANDLE UnbindContext
		)
{
	PFILTER_ADAPTER	pAdapt;
	NDIS_STATUS	LocalStatus;

	pAdapt = (PFILTER_ADAPTER)ProtocolBindingContext;

	UNREFERENCED_PARAMETER(UnbindContext);

	NdisAcquireSpinLock(&pAdapt->Lock);
	pAdapt->UnbindingInProcess = TRUE;
	if (pAdapt->QueuedRequest == TRUE){
		pAdapt->QueuedRequest = FALSE;
		NdisReleaseSpinLock(&pAdapt->Lock);

		natpRequestComplete(pAdapt,
			&pAdapt->IntReq.NdisRequest,
			NDIS_STATUS_FAILURE );

	}else{
		NdisReleaseSpinLock(&pAdapt->Lock);
	}

	if (pAdapt->MiniportInitPending == TRUE){
		LocalStatus =
			NdisIMCancelInitializeDeviceInstance(
				DriverHandle,
				&pAdapt->DeviceName
				);

		if (LocalStatus == NDIS_STATUS_SUCCESS){
			pAdapt->MiniportInitPending = FALSE;
			ASSERT(pAdapt->MiniportHandle == NULL);

		}else{

			NdisWaitEvent(&pAdapt->MiniportInitEvent, 0);
			ASSERT(pAdapt->MiniportInitPending == FALSE);
		}
	}

	if (pAdapt->MiniportHandle != NULL){
		*Status =
			NdisIMDeInitializeDeviceInstance(
				pAdapt->MiniportHandle
				);

		if (*Status != NDIS_STATUS_SUCCESS)
			*Status = NDIS_STATUS_FAILURE;
	}else{

		if(NULL != pAdapt->BindingHandle){
			
			NdisResetEvent(&pAdapt->Event);
			NdisCloseAdapter(Status, pAdapt->BindingHandle);

			if(*Status == NDIS_STATUS_PENDING){
				
				NdisWaitEvent(&pAdapt->Event, 0);
				*Status = pAdapt->Status;
			}
			pAdapt->BindingHandle = NULL;
		
		}else{
			*Status = NDIS_STATUS_FAILURE;
		}

		natFreeAllItems(&pAdapt->ctrl);
		natFreeAllFwSessionsAndRules(&pAdapt->ctrl);

		natmFreeAllPacketPools(pAdapt);

		if (pAdapt)
			NdisFreeSpinLock(&pAdapt->Lock);

		NdisFreeMemory(pAdapt, 0, 0);
	}

}
VOID
PtUnbindAdapter(
	OUT PNDIS_STATUS		Status,
	IN  NDIS_HANDLE			ProtocolBindingContext,
	IN  NDIS_HANDLE			UnbindContext
	)
/*++

Routine Description:

	Called by NDIS when we are required to unbind to the adapter below.
	This functions shares functionality with the miniport's HaltHandler.
	The code should ensure that NdisCloseAdapter and NdisFreeMemory is called
	only once between the two functions

Arguments:

	Status					Placeholder for return status
	ProtocolBindingContext	Pointer to the adapter structure
	UnbindContext			Context for NdisUnbindComplete() if this pends

Return Value:

	Status for NdisIMDeinitializeDeviceContext

--*/
{
	PADAPT		 pAdapt =(PADAPT)ProtocolBindingContext;
	NDIS_HANDLE BindingHandle = pAdapt->BindingHandle;
	NDIS_STATUS	LocalStatus;

	DBGPRINT(("==> PtUnbindAdapter: Adapt %p\n", pAdapt));

	if (pAdapt->QueuedRequest == TRUE)
	{
		pAdapt->QueuedRequest = FALSE;

		PtRequestComplete (pAdapt,
		                 &pAdapt->Request,
		                 NDIS_STATUS_FAILURE );

	}

#ifndef WIN9X
	//
	// Check if we had called NdisIMInitializeDeviceInstanceEx and
	// we are awaiting a call to MiniportInitialize.
	//
	if (pAdapt->MiniportInitPending == TRUE)
	{
		//
		// Try to cancel the pending IMInit process.
		//
		LocalStatus = NdisIMCancelInitializeDeviceInstance(
						DriverHandle,
						&pAdapt->DeviceName);

		if (LocalStatus == NDIS_STATUS_SUCCESS)
		{
			//
			// Successfully cancelled IM Initialization; our
			// Miniport Initialize routine will not be called
			// for this device.
			//
			pAdapt->MiniportInitPending = FALSE;
			ASSERT(pAdapt->MiniportHandle == NULL);
		}
		else
		{
			//
			// Our Miniport Initialize routine will be called
			// (may be running on another thread at this time).
			// Wait for it to finish.
			//
			NdisWaitEvent(&pAdapt->MiniportInitEvent, 0);
			ASSERT(pAdapt->MiniportInitPending == FALSE);
		}

	}
#endif // !WIN9X

	//
	// Call NDIS to remove our device-instance. We do most of the work
	// inside the HaltHandler.
	//
	// The Handle will be NULL if our miniport Halt Handler has been called or
	// if the IM device was never initialized
	//
	
	if (pAdapt->MiniportHandle != NULL)
	{
		*Status = NdisIMDeInitializeDeviceInstance(pAdapt->MiniportHandle);

		if (*Status != NDIS_STATUS_SUCCESS)
		{
			*Status = NDIS_STATUS_FAILURE;
		}
	}
	else
	{
		//
		// We need to do some work here. 
		// Close the binding below us 
		// and release the memory allocated.
		//
		if(pAdapt->BindingHandle != NULL)
		{
			NdisResetEvent(&pAdapt->Event);

			NdisCloseAdapter(Status, pAdapt->BindingHandle);

			//
			// Wait for it to complete
			//
			if(*Status == NDIS_STATUS_PENDING)
			{
				 NdisWaitEvent(&pAdapt->Event, 0);
				 *Status = pAdapt->Status;
			}
		}
		else
		{
			//
			// Both Our MiniportHandle and Binding Handle  should not be NULL.
			//
			*Status = NDIS_STATUS_FAILURE;
			ASSERT(0);
		}

		//
		//	Free the memory here, if was not released earlier(by calling the HaltHandler)
		//
		NdisFreeMemory(pAdapt, sizeof(ADAPT), 0);
	}

	DBGPRINT(("<== PtUnbindAdapter: Adapt %p\n", pAdapt));
}