/*************************************************************
Required NDIS procedure
Stops TX and RX path and finished the function of adapter
*************************************************************/
static VOID ParaNdis5_Halt(
	IN NDIS_HANDLE MiniportAdapterContext)
{
	NDIS_STATUS status = NDIS_STATUS_SUCCESS;
	BOOLEAN bUnused;
	PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportAdapterContext;
	DEBUG_ENTRY(0);

	ParaNdis_DebugHistory(pContext, hopHalt, NULL, 1, 0, 0);

	NdisCancelTimer(&pContext->ConnectTimer, &bUnused);
	NdisResetEvent(&pContext->HaltEvent);
	if (NDIS_STATUS_PENDING != ParaNdis5_StopSend(pContext, TRUE, OnSendStopped))
		NdisSetEvent(&pContext->HaltEvent);
	WaitHaltEvent(pContext, "Send");
	NdisResetEvent(&pContext->HaltEvent);
	if (NDIS_STATUS_PENDING != ParaNdis5_StopReceive(pContext, TRUE, OnReceiveStopped))
		NdisSetEvent(&pContext->HaltEvent);
	WaitHaltEvent(pContext, "Receive");
	ParaNdis_CleanupContext(pContext);
	NdisCancelTimer(&pContext->DPCPostProcessTimer, &bUnused);
	ParaNdis_DebugHistory(pContext, hopHalt, NULL, 0, 0, 0);
	ParaNdis_DebugRegisterMiniport(pContext, FALSE);
	NdisFreeMemory(pContext, 0, 0);
	DEBUG_EXIT_STATUS(0, status);
}
Beispiel #2
0
void
CAR6KMini::IndicateReceivePackets()
//
//  This function is called on the worker thread to indicate received
//  packets.
//
{
	NDIS_PACKET *pPacket;
	NDIS_PACKET *PacketArray[MAX_PACKETS_PER_INDICATE];
	ULONG        NumPacketsToIndicate;
	LIST_ENTRY  *pNode;
	boolean      bEventSignalled;

	NdisResetEvent(&m_RxWorkItemExitedEvent);

	while (false == m_Halting)
	{
		// Wait for packets to be placed on the list
		bEventSignalled = NdisWaitEvent(&m_RxPendingEvent, 0);
		if (m_Halting || !bEventSignalled)
			break;

		NumPacketsToIndicate = 0;

		//
		// Get up to MAX_PACKET_PER_INDICATE packets from the RxPending list.
		// Put the packet pointers into an array.
		//
		Lock();
		while (!IsListEmpty(&m_RxPendingPacketList))
		{
			pNode = RemoveHeadList(&m_RxPendingPacketList);
			pPacket = (PNDIS_PACKET)((PBYTE)pNode - offsetof(NDIS_PACKET, MiniportReserved));
			PacketArray[NumPacketsToIndicate++] = pPacket;
			if (NumPacketsToIndicate == MAX_PACKETS_PER_INDICATE) {
				Unlock();
				NdisMIndicateReceivePacket(m_MiniportAdapterHandle, PacketArray, NumPacketsToIndicate);
				Lock();
				NumPacketsToIndicate = 0;
			}
		}
		NdisResetEvent(&m_RxPendingEvent);
		Unlock();

		//
		// Indicate the received packets up to protocol drivers bound to us.
		//
		if (NumPacketsToIndicate)
			NdisMIndicateReceivePacket(m_MiniportAdapterHandle, PacketArray, NumPacketsToIndicate);
	}

	NdisSetEvent(&m_RxWorkItemExitedEvent);
}
//------------------------------------------------------------------------------
void eventkcal_getEventForUser(void* pEvent_p, size_t* pSize_p)
{
    tOplkError    error;
    BOOL          fRet;
    UINT32        timeout = 500;

    // Check parameter validity
    ASSERT(pEvent_p != NULL);
    ASSERT(pSize_p != NULL);

    if (!instance_l.fInitialized)
        return;

    fRet = NdisWaitEvent(&instance_l.userWaitEvent, timeout);

    if (fRet && (instance_l.userEventCount == 0))
    {
        NdisResetEvent(&instance_l.userWaitEvent);
        return;
    }

    NdisResetEvent(&instance_l.userWaitEvent);

    // Kernel-to-user queue is processed with higher priority.
    if (eventkcal_getEventCountCircbuf(kEventQueueK2U) > 0)
    {
        NdisInterlockedDecrement(&instance_l.userEventCount);

        error = eventkcal_getEventCircbuf(kEventQueueK2U, pEvent_p, pSize_p);
        if ((error != kErrorOk) || (pEvent_p == NULL))
        {
            DEBUG_LVL_ERROR_TRACE("%s() Error reading K2U events %d!\n", __func__, error);
        }

        return;
    }
    else if (eventkcal_getEventCountCircbuf(kEventQueueUInt) > 0)
    {
        NdisInterlockedDecrement(&instance_l.userEventCount);

        error = eventkcal_getEventCircbuf(kEventQueueUInt, pEvent_p, pSize_p);
        if (error != kErrorOk)
        {
            DEBUG_LVL_ERROR_TRACE("%s() Error reading UINT events %d!\n", __func__, error);
            return;
        }
    }
}
Beispiel #4
0
DWORD
hifIRQThread(void *Context)
{

	A_STATUS         status = A_OK;
	HIF_DEVICE      *device;

	device = (HIF_DEVICE *)Context;

	NDIS_DEBUG_PRINTF(DBG_LEVEL_HIF, " %s() is Running... \r\n",__FUNCTION__);


	while (TRUE) 
	{
		NdisWaitEvent(&hifIRQEvent, 0);
		NdisResetEvent(&hifIRQEvent);
		
		NDIS_DEBUG_PRINTF(DBG_TRACE, "%s() - Running  & ",__FUNCTION__);
		status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context);
		AR_DEBUG_ASSERT(status == A_OK);
		NDIS_DEBUG_PRINTF(DBG_TRACE, " Exit \r\n");
		
		SDIOConnectInterrupt(device->handle,hifIRQHandler);
				
	} // while
	return SD_API_STATUS_SUCCESS;
	
}
Beispiel #5
0
VOID
NPF_CloseOpenInstance(
				IN POPEN_INSTANCE pOpen
				)
{
	ULONG i = 0;
	NDIS_EVENT Event;

	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

	NdisInitializeEvent(&Event);
	NdisResetEvent(&Event);

	NdisAcquireSpinLock(&pOpen->OpenInUseLock);

	pOpen->ClosePending = TRUE;

	while(pOpen->NumPendingIrps > 0)
	{
		NdisReleaseSpinLock(&pOpen->OpenInUseLock);
		NdisWaitEvent(&Event,1);
		NdisAcquireSpinLock(&pOpen->OpenInUseLock);
	}

	NdisReleaseSpinLock(&pOpen->OpenInUseLock);
}
Beispiel #6
0
VOID
MiniportHalt5(
    IN NDIS_HANDLE                MiniportAdapterContext
    )
{
    PADAPTER           pAdapt = (PADAPTER)MiniportAdapterContext;
    NDIS_STATUS        Status;


    //
    // Delete the ioctl interface that was created when the miniport
    // was created.
    //
    (VOID)ProtocolDeregisterDevice();

#ifdef _DEBUG
	// 关闭直接包发送接口
	if(pAdapt->FileObject)
	{
		//
		//  Make sure any threads trying to send have finished.
		//
		pAdapt->FileObject->FsContext = NULL;
		pAdapt->FileObject = NULL;
	}
#endif

    //
    // If we have a valid bind, close the miniport below the protocol
    //
    if (pAdapt->BindingHandle != NULL)
    {
        //
        // Close the binding below. and wait for it to complete
        //
        NdisResetEvent(&pAdapt->Event);

        NdisCloseAdapter(&Status, pAdapt->BindingHandle);

        if (Status == NDIS_STATUS_PENDING)
        {
            NdisWaitEvent(&pAdapt->Event, 0);
            Status = pAdapt->Status;
        }

        ASSERT (Status == NDIS_STATUS_SUCCESS);

        pAdapt->BindingHandle = NULL;
    }

    //
    //  Free all resources on this adapter structure.
    //
    MiniportFreeAllPacketPools5(pAdapt);
    NdisFreeSpinLock(&pAdapt->Lock);
    NdisFreeMemory(pAdapt, 0, 0);

}
VOID ParaNdis_Suspend(PARANDIS_ADAPTER *pContext)
{
	DEBUG_ENTRY(0);
	NdisResetEvent(&pContext->ResetEvent);
	if (NDIS_STATUS_PENDING != ParaNdis5_StopSend(pContext, TRUE, OnSendStoppedOnReset))
	{
		NdisSetEvent(&pContext->ResetEvent);
	}
	NdisWaitEvent(&pContext->ResetEvent, 0);
	NdisResetEvent(&pContext->ResetEvent);
	if (NDIS_STATUS_PENDING != ParaNdis5_StopReceive(pContext, TRUE, OnReceiveStoppedOnReset))
	{
		NdisSetEvent(&pContext->ResetEvent);
	}
	NdisWaitEvent(&pContext->ResetEvent, 0);
	NdisResetEvent(&pContext->ResetEvent);
	DEBUG_EXIT_STATUS(0, 0);
}
//------------------------------------------------------------------------------
static void eventThread(void* pArg)
{
    INT         timeout = 50;
    PKTHREAD    thread;
    BOOL        fRet = FALSE;

    UNUSED_PARAMETER(pArg);

    // increase the priority of the thread
    thread = KeGetCurrentThread();
    KeSetPriorityThread(thread, HIGH_PRIORITY);

    instance_l.fThreadIsRunning = TRUE;

    while (!instance_l.fStopThread)
    {
        fRet = NdisWaitEvent(&instance_l.kernelWaitEvent, timeout);
        if (fRet && (instance_l.kernelEventCount == 0))
        {
            // Timeout occurred, continue to wait.
            NdisResetEvent(&instance_l.kernelWaitEvent);
            continue;
        }

        NdisResetEvent(&instance_l.kernelWaitEvent);

        /* first handle all kernel internal events --> higher priority! */
        while (eventkcal_getEventCountCircbuf(kEventQueueKInt) > 0)
        {
            eventkcal_processEventCircbuf(kEventQueueKInt);
            NdisInterlockedDecrement(&instance_l.kernelEventCount);
        }

        if (eventkcal_getEventCountCircbuf(kEventQueueU2K) > 0)
        {
            eventkcal_processEventCircbuf(kEventQueueU2K);
            NdisInterlockedDecrement(&instance_l.kernelEventCount);
        }
    }

    instance_l.fThreadIsRunning = FALSE;
}
Beispiel #9
0
NDIS_STATUS
shared_interrupt_register(OUT PNDIS_MINIPORT_INTERRUPT Interrupt,
NDIS_HANDLE MiniportAdapterHandle,
UINT InterruptVector,
UINT InterruptLevel,
BOOLEAN RequestIsr,
BOOLEAN SharedInterrupt,
NDIS_INTERRUPT_MODE InterruptMode,
shared_info_t *sh,
void (*isr_cb)(PBOOLEAN, PBOOLEAN, NDIS_HANDLE),
void *isr_arg,
void (*dpc_cb)(NDIS_HANDLE),
void *dpc_arg)
{
	if (sh->BusType == NdisInterfacePci || sh->BusType == NdisInterfacePcMcia) {
		return NdisMRegisterInterrupt(Interrupt, MiniportAdapterHandle,
		                        InterruptVector, InterruptLevel,
		                        RequestIsr,
		                        SharedInterrupt,
		                        InterruptMode);
	}
	else if (sh->BusType == NdisInterfaceSDIO) {
		sh->isr_cb  = isr_cb;
		sh->isr_arg = isr_arg;

		NdisInitializeEvent(&sh->dpc_event);
		NdisResetEvent(&sh->dpc_event);
		sh->dpc_handle = CreateThread(NULL,		/* security atributes */
						0,		/* initial stack size */
			(LPTHREAD_START_ROUTINE)shared_dpc_thread,	/* Main() function */
						sh,		/* arg to reader thread */
						0,		/* creation flags */
						&sh->dpc_thread_id); /* returned thread id */
		if (!sh->dpc_handle)
			return NDIS_STATUS_FAILURE;

		if (bcmsdh_intr_reg(sh->sdh, shared_isr, sh))
			return NDIS_STATUS_FAILURE;

	}

	sh->dpc_cb  = dpc_cb;
	sh->dpc_arg = dpc_arg;

	/* Initilize the timer required to reschdule the DPC, if necessary */
	NdisInitializeTimer(&sh->dpc_reshed_timer, shared_dpc_reschedule, (PVOID)sh);

	return NDIS_STATUS_SUCCESS;
}
VOID ParaNdis_Suspend(PARANDIS_ADAPTER *pContext)
{
    DPrintf(0, ("[%s]%s\n", __FUNCTION__, pContext->bFastSuspendInProcess ? "(Fast)" : ""));
    NdisResetEvent(&pContext->ResetEvent);
    if (NDIS_STATUS_PENDING != ParaNdis6_SendPauseRestart(pContext, TRUE, OnSendPauseCompleteOnReset))
    {
        NdisSetEvent(&pContext->ResetEvent);
    }
    NdisWaitEvent(&pContext->ResetEvent, 0);
    if (!pContext->bFastSuspendInProcess)
    {
        NdisResetEvent(&pContext->ResetEvent);
        if (NDIS_STATUS_PENDING != ParaNdis6_ReceivePauseRestart(pContext, TRUE, OnReceivePauseCompleteOnReset))
        {
            NdisSetEvent(&pContext->ResetEvent);
        }
        NdisWaitEvent(&pContext->ResetEvent, 0);
    }
    else
    {
        ParaNdis6_ReceivePauseRestart(pContext, TRUE, NULL);
    }
    DEBUG_EXIT_STATUS(0, 0);
}
Beispiel #11
0
static void
shared_dpc_thread(void *h)
{
	shared_info_t *sh = (shared_info_t *)h;

	/* Read the priority from registry */
	CeSetThreadPriority(GetCurrentThread(), sh->DPCPriority);

	while (TRUE) {
		NdisWaitEvent(&sh->dpc_event, 0);	/* wait forever */

		NdisResetEvent(&sh->dpc_event);		/* reset the event */

		(sh->dpc_cb)(sh->dpc_arg);
	}
}
/* Can only be called with sendLock held */
PTCB
VenetAllocTCB(PADAPTER a, PNET_BUFFER_LIST nbl)
{
    PLIST_ENTRY	e;
    PTCB		t = NULL;

    if (!IsListEmpty(&a->tcbFree)) {
        e = RemoveHeadList(&a->tcbFree);
        t = CONTAINING_RECORD(e, TCB, list);
        t->status = NDIS_STATUS_SUCCESS;
        t->nb_count = 0;
        t->nbl = nbl;
        InsertHeadList(&a->tcbBusy, &t->list);
        NdisResetEvent(&a->sendEvent);
        InterlockedDecrement((PLONG) &a->numTCBsFree);
    }
    return t;
}
Beispiel #13
0
	/* Initilize the timer required to reschdule the DPC, if necessary */
	NdisInitializeTimer(&sh->dpc_reshed_timer, shared_dpc_reschedule, (PVOID)sh);

	return NDIS_STATUS_SUCCESS;
}
#else /* !NDIS60 */
NDIS_STATUS
shared_interrupt_register(NDIS_HANDLE MiniportAdapterHandle,
shared_info_t *sh,
void (*isr_cb)(PBOOLEAN, PBOOLEAN, NDIS_HANDLE),
void *isr_arg,
void (*dpc_cb)(NDIS_HANDLE),
void *dpc_arg)
{
	if (sh->BusType == NdisInterfaceSDIO) {
		sh->isr_cb  = isr_cb;
		sh->isr_arg = isr_arg;

		sh->dpc_handle = CreateThread(NULL,		/* security atributes */
						0,		/* initial stack size */
			(LPTHREAD_START_ROUTINE)shared_dpc_thread,	/* Main() function */
						sh,		/* arg to reader thread */
						0,		/* creation flags */
						&sh->dpc_thread_id); /* returned thread id */
		if (!sh->dpc_handle)
		{
			 printf("---> shared_interrupt_register error 1\n");

			return NDIS_STATUS_FAILURE;
		}

		NdisInitializeEvent(&sh->dpc_event);
		NdisResetEvent(&sh->dpc_event);

		if (bcmsdh_intr_reg(sh->sdh, shared_isr, sh))
		{
			 printf("---> shared_interrupt_register Error 2\n");

			return NDIS_STATUS_FAILURE;
		}
	}

	sh->dpc_cb  = dpc_cb;
	sh->dpc_arg = dpc_arg;
	/* WM7 TODO: do we need this? */
	/* Initilize the timer required to reschdule the DPC, if necessary */
	NdisInitializeTimer(&sh->dpc_reshed_timer, shared_dpc_reschedule, (PVOID)sh);

	return NDIS_STATUS_SUCCESS;
}
Beispiel #14
0
VOID tapWaitForReceiveNblInFlightCountZeroEvent(__in PTAP_ADAPTER_CONTEXT Adapter) {
  LONG nblCount;

  //
  // Wait until higher-level protocol has returned all NBLs
  // to the driver.
  //

  // Add one NBL "bias" to insure allow event to be reset safely.
  nblCount = NdisInterlockedIncrement(&Adapter->ReceiveNblInFlightCount);
  ASSERT(nblCount > 0);
  NdisResetEvent(&Adapter->ReceiveNblInFlightCountZeroEvent);

  //
  // Now remove the bias and wait for the ReceiveNblInFlightCountZeroEvent
  // if the count returned is not zero.
  //
  nblCount = NdisInterlockedDecrement(&Adapter->ReceiveNblInFlightCount);
  ASSERT(nblCount >= 0);

  if (nblCount) {
    LARGE_INTEGER startTime, currentTime;

    NdisGetSystemUpTimeEx(&startTime);

    for (;;) {
      BOOLEAN waitResult =
          NdisWaitEvent(&Adapter->ReceiveNblInFlightCountZeroEvent, TAP_WAIT_POLL_LOOP_TIMEOUT);

      NdisGetSystemUpTimeEx(&currentTime);

      if (waitResult) {
        break;
      }

      DEBUGP(("[%s] Waiting for %d in-flight receive NBLs to be returned.\n",
              MINIPORT_INSTANCE_ID(Adapter), Adapter->ReceiveNblInFlightCount));
    }

    DEBUGP(("[%s] Waited %d ms for all in-flight NBLs to be returned.\n",
            MINIPORT_INSTANCE_ID(Adapter), (currentTime.LowPart - startTime.LowPart)));
  }
}
Beispiel #15
0
DWORD
hifIRQThread(LPVOID Context)
{
	SD_DEVICE_HANDLE hDevice = Context;
	A_STATUS         status;
    HIF_DEVICE      *device;

	if (hDevice == NULL) {
		return SD_API_STATUS_UNSUCCESSFUL;
	}
	while (1) {
		NdisWaitEvent(&hifIRQEvent, 0);
		NdisResetEvent(&hifIRQEvent);
		device = getHifDevice(hDevice);
		status = htcCallbacks.dsrHandler(device);
		AR_DEBUG_ASSERT(status == A_OK);
	} // while
    return SD_API_STATUS_SUCCESS;
}
Beispiel #16
0
VOID
	natpBindAdapter(
		OUT PNDIS_STATUS Status,
		IN  NDIS_HANDLE BindContext,
		IN  PNDIS_STRING DeviceName,
		IN  PVOID SystemSpecific1,
		IN  PVOID SystemSpecific2
		)
{
	NDIS_HANDLE ConfigHandle = NULL;
	PNDIS_CONFIGURATION_PARAMETER Param;
	NDIS_STRING DeviceStr = UPPER_BINDINGS;
	PFILTER_ADAPTER pAdapt = NULL;
	NDIS_STATUS Sts;
	UINT MediumIndex, i;
	ULONG TotalSize;
	WCHAR DevicePrefix[]  = L"\\Device\\";

	UNREFERENCED_PARAMETER(BindContext);
	UNREFERENCED_PARAMETER(SystemSpecific2);

	__try{
		
		NdisOpenProtocolConfiguration(
			Status,
			&ConfigHandle,
			SystemSpecific1
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisReadConfiguration(
			Status,
			&Param,
			ConfigHandle,
			&DeviceStr,
			NdisParameterString
			);
		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		TotalSize = sizeof(FILTER_ADAPTER) + Param->ParameterData.StringData.MaximumLength + DeviceName->MaximumLength;
		NdisAllocateMemoryWithTag(&pAdapt, TotalSize, NAT_TAG);

		if (NULL == pAdapt){
			*Status = NDIS_STATUS_RESOURCES;
			__leave;
		}


		NdisZeroMemory(pAdapt, TotalSize);
		pAdapt->DeviceName.MaximumLength = Param->ParameterData.StringData.MaximumLength;
		pAdapt->DeviceName.Length = Param->ParameterData.StringData.Length;
		pAdapt->DeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(FILTER_ADAPTER));
		NdisMoveMemory(
			pAdapt->DeviceName.Buffer,
			Param->ParameterData.StringData.Buffer,
			Param->ParameterData.StringData.MaximumLength
			);
		if(sizeof(DevicePrefix) >= DeviceName->Length){
		
			
		}else{
		
			pAdapt->RootDeviceName.MaximumLength = DeviceName->MaximumLength;
			pAdapt->RootDeviceName.Length = DeviceName->Length - sizeof(DevicePrefix) + sizeof(WCHAR);
			pAdapt->RootDeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(FILTER_ADAPTER) + Param->ParameterData.StringData.MaximumLength);
			NdisMoveMemory(
				pAdapt->RootDeviceName.Buffer,
				DeviceName->Buffer + sizeof(DevicePrefix)/sizeof(WCHAR) - 1,
				DeviceName->MaximumLength - sizeof(DevicePrefix)/sizeof(WCHAR) + 1
				);
		}

		NdisInitializeEvent(&pAdapt->Event);
		NdisAllocateSpinLock(&pAdapt->Lock);

		natInitControlBlock(&pAdapt->ctrl);

		NdisAllocatePacketPoolEx(
			Status,
			&pAdapt->SndPP1,
			MIN_PACKET_POOL_SIZE,
			MAX_PACKET_POOL_SIZE,
			PROTOCOL_RESERVED_SIZE_IN_PACKET
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisAllocatePacketPoolEx(
			Status,
			&pAdapt->SndPP2,
			MIN_PACKET_POOL_SIZE,
			MAX_PACKET_POOL_SIZE,
			PROTOCOL_RESERVED_SIZE_IN_PACKET
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisAllocateBufferPool(
			Status,
			&pAdapt->SndBP,
			MIN_PACKET_POOL_SIZE
			);
		if ( *Status != NDIS_STATUS_SUCCESS )
			__leave;

		NdisAllocatePacketPoolEx(
			Status,
			&pAdapt->RcvPP1,
			MIN_PACKET_POOL_SIZE,
			MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
			PROTOCOL_RESERVED_SIZE_IN_PACKET
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisAllocatePacketPoolEx(
			Status,
			&pAdapt->RcvPP2,
			MIN_PACKET_POOL_SIZE,
			MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
			PROTOCOL_RESERVED_SIZE_IN_PACKET
			);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;

		NdisAllocateBufferPool(
			Status,
			&pAdapt->RcvBP,
			MIN_PACKET_POOL_SIZE
			);
		if ( *Status != NDIS_STATUS_SUCCESS )
			__leave;

		NdisOpenAdapter(
			Status,
			&Sts,
			&pAdapt->BindingHandle,
			&MediumIndex,
			MediumArray,
			sizeof(MediumArray)/sizeof(NDIS_MEDIUM),
			ProtHandle,
			pAdapt,
			DeviceName,
			0,NULL
			);

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

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;
		pAdapt->Medium = MediumArray[MediumIndex];

		pAdapt->MiniportInitPending = TRUE;
		NdisInitializeEvent(&pAdapt->MiniportInitEvent);

		*Status = 
			NdisIMInitializeDeviceInstanceEx(
				DriverHandle,
				&pAdapt->DeviceName,
				pAdapt
				);

		if (*Status != NDIS_STATUS_SUCCESS)
			__leave;
		StartQueryInfo( pAdapt );

	} __finally{
	}

	if (ConfigHandle != NULL)
		NdisCloseConfiguration(ConfigHandle);

	if(NDIS_STATUS_SUCCESS != *Status){
		
		if (pAdapt != NULL){
			
			if (pAdapt->BindingHandle != NULL){

				NDIS_STATUS    LocalStatus;

				NdisResetEvent(&pAdapt->Event);

				NdisCloseAdapter(&LocalStatus, pAdapt->BindingHandle);
				pAdapt->BindingHandle = NULL;

				if (LocalStatus == NDIS_STATUS_PENDING){
					NdisWaitEvent(&pAdapt->Event, 0);
					LocalStatus = pAdapt->Status;
				}
			}

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

			for(i = 0;i<FLT_FW_SESSION_HASH_TBL_SZ;i++)
				NdisFreeSpinLock(pAdapt->ctrl.FwSessionLocks + i);

			NdisFreeSpinLock(&pAdapt->ctrl.IcmpRuleLock);
			NdisFreeSpinLock(&pAdapt->ctrl.UdpRuleLock);
			NdisFreeSpinLock(&pAdapt->ctrl.TcpRuleLock);

			natmFreeAllPacketPools(pAdapt);

			NdisFreeSpinLock(&pAdapt->Lock);

			NdisFreeMemory(pAdapt, 0, 0);
			pAdapt = NULL;
		}
	}
}
Beispiel #17
0
NTSTATUS
NPF_GetDeviceMTU(
			 IN POPEN_INSTANCE pOpen,
			 IN PIRP	pIrp,
			 OUT PUINT  pMtu)
{
    PLIST_ENTRY			RequestListEntry;
	PINTERNAL_REQUEST	MaxSizeReq;
	NDIS_STATUS			ReqStatus;

	TRACE_ENTER();

	ASSERT(pOpen != NULL);
	ASSERT(pIrp != NULL);
	ASSERT(pMtu != NULL);

	// Extract a request from the list of free ones
	RequestListEntry = ExInterlockedRemoveHeadList(&pOpen->RequestList, &pOpen->RequestSpinLock);

	if (RequestListEntry == NULL)
	{
		//
		// THIS IS WRONG
		//

		//
		// Assume Ethernet
		//
		*pMtu = 1514;	
		TRACE_EXIT();
		return STATUS_SUCCESS;
	}

	MaxSizeReq = CONTAINING_RECORD(RequestListEntry, INTERNAL_REQUEST, ListElement);

	MaxSizeReq->Request.RequestType = NdisRequestQueryInformation;
	MaxSizeReq->Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE;

	MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBuffer = pMtu;
	MaxSizeReq->Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(*pMtu);

	NdisResetEvent(&MaxSizeReq->InternalRequestCompletedEvent);

	//  submit the request
	NdisRequest(
		&ReqStatus,
		pOpen->AdapterHandle,
		&MaxSizeReq->Request);

	if (ReqStatus == NDIS_STATUS_PENDING)
	{
		NdisWaitEvent(&MaxSizeReq->InternalRequestCompletedEvent, 0);
		ReqStatus = MaxSizeReq->RequestStatus;
	}

	//
	// Put the request in the list of the free ones
	//
	ExInterlockedInsertTailList(&pOpen->RequestList, &MaxSizeReq->ListElement, &pOpen->RequestSpinLock);

	if (ReqStatus == NDIS_STATUS_SUCCESS)
	{
		TRACE_EXIT();
		return STATUS_SUCCESS;
	}
	else
	{
		//
		// THIS IS WRONG
		//

		//
		// Assume Ethernet
		//
		*pMtu = 1514;	

		TRACE_EXIT();
		return STATUS_SUCCESS;
	
		// return ReqStatus;
	}
}
Beispiel #18
0
VOID
MPHalt(
    IN NDIS_HANDLE                MiniportAdapterContext
    )
/*++

Routine Description:

    Halt handler. All the hard-work for clean-up is done here.

Arguments:

    MiniportAdapterContext    Pointer to the Adapter

Return Value:

    None.

--*/
{
    PADAPT             pAdapt = (PADAPT)MiniportAdapterContext;
    NDIS_STATUS        Status;
    PADAPT            *ppCursor;

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

    //
    // Remove this adapter from the global list
    //
    NdisAcquireSpinLock(&GlobalLock);

    for (ppCursor = &pAdaptList; *ppCursor != NULL; ppCursor = &(*ppCursor)->Next)
    {
        if (*ppCursor == pAdapt)
        {
            *ppCursor = pAdapt->Next;
            break;
        }
    }

    NdisReleaseSpinLock(&GlobalLock);

    //
    // Make Suprise Unbind Notification
    //
    netgOnUnbindAdapter( pAdapt->pOpenContext );

    //
    // Delete the ioctl interface that was created when the miniport
    // was created.
    //
    (VOID)PtDeregisterDevice();

   if (pAdapt->BindingHandle != NULL)
   {
      NDIS_STATUS    LocalStatus;

      //
      // Close the binding to the adapter
      //

      NdisResetEvent(&pAdapt->Event);

      NdisCloseAdapter(&LocalStatus, pAdapt->BindingHandle);
      pAdapt->BindingHandle = NULL;

      if (LocalStatus == NDIS_STATUS_PENDING)
      {
         NdisWaitEvent(&pAdapt->Event, 0);
         LocalStatus = pAdapt->Status;
      }

      ASSERT (LocalStatus == NDIS_STATUS_SUCCESS);
   }

   //
   // Remove Reference To The Adapter
   //
   PtDerefAdapter( pAdapt );

   DBGPRINT(("<== MiniportHalt: pAdapt %p\n", pAdapt));
}
Beispiel #19
0
NTSTATUS NPF_Open(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{

	PDEVICE_EXTENSION	DeviceExtension;
	POPEN_INSTANCE		Open;
	PIO_STACK_LOCATION  IrpSp;
	NDIS_STATUS			Status;
	NDIS_STATUS			ErrorStatus;
	UINT				i;
	PUCHAR				tpointer;
	PLIST_ENTRY			PacketListEntry;
	NTSTATUS			returnStatus;

//  
//	Old registry based WinPcap names
//
//	WCHAR				EventPrefix[MAX_WINPCAP_KEY_CHARS];
//	UINT				RegStrLen;

	TRACE_ENTER();

	DeviceExtension = DeviceObject->DeviceExtension;

	IrpSp = IoGetCurrentIrpStackLocation(Irp);

	//  allocate some memory for the open structure
	Open=ExAllocatePoolWithTag(NonPagedPool, sizeof(OPEN_INSTANCE), '0OWA');

	if (Open==NULL) {
		// no memory
		Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	RtlZeroMemory(
		Open,
		sizeof(OPEN_INSTANCE)
		);

//  
//	Old registry based WinPcap names
//
//	//
//	// Get the Event names base from the registry
//	//
//	RegStrLen = sizeof(EventPrefix)/sizeof(EventPrefix[0]);
//
//	NPF_QueryWinpcapRegistryString(NPF_EVENTS_NAMES_REG_KEY_WC,
//		EventPrefix,
//		RegStrLen,
//		NPF_EVENTS_NAMES_WIDECHAR);
//
		
	Open->DeviceExtension=DeviceExtension;

	//  Allocate a packet pool for our xmit and receive packets
	NdisAllocatePacketPool(
		&Status,
		&Open->PacketPool,
		TRANSMIT_PACKETS,
		sizeof(PACKET_RESERVED));

	if (Status != NDIS_STATUS_SUCCESS) {

		TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Failed to allocate packet pool");

		ExFreePool(Open);
		Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	NdisInitializeEvent(&Open->WriteEvent);
	NdisInitializeEvent(&Open->NdisRequestEvent);
	NdisInitializeEvent(&Open->NdisWriteCompleteEvent);
	NdisInitializeEvent(&Open->DumpEvent);
	NdisAllocateSpinLock(&Open->MachineLock);
	NdisAllocateSpinLock(&Open->WriteLock);
	Open->WriteInProgress = FALSE;

	for (i = 0; i < g_NCpu; i++)
	{
		NdisAllocateSpinLock(&Open->CpuData[i].BufferLock);
	}

	NdisInitializeEvent(&Open->NdisOpenCloseCompleteEvent);

	//  list to hold irp's want to reset the adapter
	InitializeListHead(&Open->ResetIrpList);

	//  Initialize the request list
	KeInitializeSpinLock(&Open->RequestSpinLock);
	InitializeListHead(&Open->RequestList);

#ifdef HAVE_BUGGY_TME_SUPPORT
	// Initializes the extended memory of the NPF machine
	Open->mem_ex.buffer = ExAllocatePoolWithTag(NonPagedPool, DEFAULT_MEM_EX_SIZE, '2OWA');
	if((Open->mem_ex.buffer) == NULL)
	{
		//
		// no memory
		//
		ExFreePool(Open);
		Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	Open->mem_ex.size = DEFAULT_MEM_EX_SIZE;
	RtlZeroMemory(Open->mem_ex.buffer, DEFAULT_MEM_EX_SIZE);
#endif //HAVE_BUGGY_TME_SUPPORT


	//
	// Initialize the open instance
	//
	Open->bpfprogram = NULL;	//reset the filter
	Open->mode = MODE_CAPT;
	Open->Nbytes.QuadPart = 0;
	Open->Npackets.QuadPart = 0;
	Open->Nwrites = 1;
	Open->Multiple_Write_Counter = 0;
	Open->MinToCopy = 0;
	Open->TimeOut.QuadPart = (LONGLONG)1;
	Open->DumpFileName.Buffer = NULL;
	Open->DumpFileHandle = NULL;
#ifdef HAVE_BUGGY_TME_SUPPORT
	Open->tme.active = TME_NONE_ACTIVE;
#endif // HAVE_BUGGY_TME_SUPPORT
	Open->DumpLimitReached = FALSE;
	Open->MaxFrameSize = 0;
	Open->WriterSN=0;
	Open->ReaderSN=0;
	Open->Size=0;
	Open->SkipSentPackets = FALSE;
	Open->ReadEvent = NULL;

	//
	// we need to keep a counter of the pending IRPs
	// so that when the IRP_MJ_CLEANUP dispatcher gets called,
	// we can wait for those IRPs to be completed
	//
	Open->NumPendingIrps = 0;
	Open->ClosePending = FALSE;
	NdisAllocateSpinLock(&Open->OpenInUseLock);

	//
	//allocate the spinlock for the statistic counters
	//
	NdisAllocateSpinLock(&Open->CountersLock);

	//
	//  link up the request stored in our open block
	//
	for (i = 0 ; i < MAX_REQUESTS ; i++ ) 
	{
		NdisInitializeEvent(&Open->Requests[i].InternalRequestCompletedEvent);

		ExInterlockedInsertTailList(
			&Open->RequestList,
			&Open->Requests[i].ListElement,
			&Open->RequestSpinLock);
	}

	NdisResetEvent(&Open->NdisOpenCloseCompleteEvent);

	// 
	// set the proper binding flags before trying to open the MAC
	//
	Open->AdapterBindingStatus = ADAPTER_BOUND;
	Open->AdapterHandleUsageCounter = 0;
	NdisAllocateSpinLock(&Open->AdapterHandleLock);

	//
	//  Try to open the MAC
	//
	TRACE_MESSAGE2(PACKET_DEBUG_LOUD,"Opening the device %ws, BindingContext=%p",DeviceExtension->AdapterName.Buffer, Open);

	returnStatus = STATUS_SUCCESS;

	NdisOpenAdapter(
		&Status,
		&ErrorStatus,
		&Open->AdapterHandle,
		&Open->Medium,
		MediumArray,
		NUM_NDIS_MEDIA,
		g_NdisProtocolHandle,
		Open,
		&DeviceExtension->AdapterName,
		0,
		NULL);

	TRACE_MESSAGE1(PACKET_DEBUG_LOUD,"Opened the device, Status=%x",Status);

	if (Status == NDIS_STATUS_PENDING)
	{
		NdisWaitEvent(&Open->NdisOpenCloseCompleteEvent, 0);

		if (!NT_SUCCESS(Open->OpenCloseStatus))
		{
			returnStatus = Open->OpenCloseStatus;
		}
		else
		{
			returnStatus = STATUS_SUCCESS;
		}
	}
	else
	{
		//
		// request not pending, we know the result, and OpenComplete has not been called.
		//
		if (Status == NDIS_STATUS_SUCCESS)
		{
			returnStatus = STATUS_SUCCESS;
		}
		else
		{
			//
			// this is not completely correct, as we are converting an NDIS_STATUS to a NTSTATUS
			//
			returnStatus = Status;

		}
	}

	if (returnStatus == STATUS_SUCCESS)
	{
		ULONG localNumOpenedInstances;	
		//
		// complete the open
		//
		localNumOpenedInstances = InterlockedIncrement(&g_NumOpenedInstances);

		TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "Opened Instances: %u", localNumOpenedInstances);

		// Get the absolute value of the system boot time.
		// This is used for timestamp conversion.
		TIME_SYNCHRONIZE(&G_Start_Time);

		returnStatus = NPF_GetDeviceMTU(Open, Irp, &Open->MaxFrameSize);

		if (!NT_SUCCESS(returnStatus))
		{
			//
			// Close the binding
			//
			NPF_CloseBinding(Open);
		}
	}

	if (!NT_SUCCESS(returnStatus))
	{
		NPF_ReleaseOpenInstanceResources(Open);
		//
		// Free the open instance itself
		//
		ExFreePool(Open);
		
	}
	else
	{
		//  Save or open here
		IrpSp->FileObject->FsContext=Open;
	}

	Irp->IoStatus.Status = returnStatus;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	TRACE_EXIT();
	return returnStatus;
}
Beispiel #20
0
A_STATUS 
HIFReadWrite(HIF_DEVICE		*device, 
             A_UINT32		address, 
             A_UCHAR		*buffer, 
             A_UINT32		length, 
             A_UINT32		request, 
             void			*context) 
{

    A_STATUS            status = A_OK;
	//unsigned long 		flags;
	BUS_REQUEST 		*busrequest;
	BUS_REQUEST 		*async;
	BUS_REQUEST 		*active;


	AR_DEBUG_ASSERT(device != NULL);
	
	
	
	do 
	{
		
		
		if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS))
		{
		
			/* serialize all requests through the async thread */
			NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: Execution mode: %s\n", (request & HIF_ASYNCHRONOUS) ?"Async":"Synch");

			busrequest = hifAllocateBusRequest(device);
			if (busrequest == NULL) {
				NDIS_DEBUG_PRINTF(DBG_ERR, "AR6000: no async bus requests available\n");
				return A_ERROR;
			}

			Hif_Lock();
			
			busrequest->address = address;
			busrequest->buffer = buffer;
			busrequest->length = length;
			busrequest->request = request;
			busrequest->context = context;

			//NDIS_DEBUG_PRINTF(1, " add = %x, length = %x, request = %d \r\n", address, length, request);
					
			/* add to async list */
			active = device->asyncreq;
			if (active == NULL) 
			{
				device->asyncreq = busrequest;
				device->asyncreq->inusenext = NULL;
			} 
			else 	
			{
				for (async = device->asyncreq; async != NULL; async = async->inusenext) {
					 active =  async;
				}
				active->inusenext = busrequest;
				busrequest->inusenext = NULL;
			}
			
			Hif_Unlock();
			
		    if (request & HIF_SYNCHRONOUS) 
			{

				NdisSetEvent(&device->sem_async);

				/* Wait Read/Write Complete from the async_task */
				if( ! NdisWaitEvent(&busrequest->sem_req, HIF_SYNCHRONOUS_WAIT_TIME)) {
					NDIS_DEBUG_PRINTF(DBG_ERR, " HIF Synchronous Read/Write Time Out !! \r\n");
					NdisResetEvent(&busrequest->sem_req);
					
					return A_ERROR;
				} 

				NdisResetEvent(&busrequest->sem_req);
				hifFreeBusRequest(device, busrequest);	
				
				if(busrequest->status != A_OK)
					NDIS_DEBUG_PRINTF(DBG_ERR, "%s() Read/Write Err \r\n", __FUNCTION__);
				
				
				return busrequest->status;
			} 
			else 
			{
				NdisSetEvent(&device->sem_async);	
				
				return  A_PENDING;
		  	}
			
		}
		else
		{
			NDIS_DEBUG_PRINTF(DBG_ERR, "AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request);
            status = A_EINVAL;
            break;			
		}
		
	}while(0);
    NDIS_DEBUG_PRINTF(0, "%s() :  - Exit \r\n",__FUNCTION__);
    return status;
}
Beispiel #21
0
VOID
NPF_CloseBinding(
    IN POPEN_INSTANCE pOpen)
{
	NDIS_EVENT Event;
	NDIS_STATUS Status;

	ASSERT(pOpen != NULL);
	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

	NdisInitializeEvent(&Event);
	NdisResetEvent(&Event);

	NdisAcquireSpinLock(&pOpen->AdapterHandleLock);

	while(pOpen->AdapterHandleUsageCounter > 0)
	{
		NdisReleaseSpinLock(&pOpen->AdapterHandleLock);
		NdisWaitEvent(&Event,1);
		NdisAcquireSpinLock(&pOpen->AdapterHandleLock);
	}

	//
	// now the UsageCounter is 0
	//

	while(pOpen->AdapterBindingStatus == ADAPTER_UNBINDING)
	{
		NdisReleaseSpinLock(&pOpen->AdapterHandleLock);
		NdisWaitEvent(&Event,1);
		NdisAcquireSpinLock(&pOpen->AdapterHandleLock);
	}

	//
	// now the binding status is either bound or unbound
	//

	if (pOpen->AdapterBindingStatus == ADAPTER_UNBOUND)
	{
		NdisReleaseSpinLock(&pOpen->AdapterHandleLock);
		return;
	}

	ASSERT(pOpen->AdapterBindingStatus == ADAPTER_BOUND);

	pOpen->AdapterBindingStatus = ADAPTER_UNBINDING;

	NdisReleaseSpinLock(&pOpen->AdapterHandleLock);

	//
	// do the release procedure
	//
	NdisResetEvent(&pOpen->NdisOpenCloseCompleteEvent);

	// Close the adapter
	NdisCloseAdapter(
		&Status,
		pOpen->AdapterHandle
		);

	if (Status == NDIS_STATUS_PENDING)
	{
		TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Pending NdisCloseAdapter");
		NdisWaitEvent(&pOpen->NdisOpenCloseCompleteEvent, 0);
	}
	else
	{
		TRACE_MESSAGE(PACKET_DEBUG_LOUD, "Not Pending NdisCloseAdapter");
	}

	NdisAcquireSpinLock(&pOpen->AdapterHandleLock);
	pOpen->AdapterBindingStatus = ADAPTER_UNBOUND;
	NdisReleaseSpinLock(&pOpen->AdapterHandleLock);
}
Beispiel #22
0
static int async_task(void *param)
{
	HIF_DEVICE      *device;
	BUS_REQUEST 	*request;
	A_STATUS 		status;

	static int		rw_cnt = 0;
	
	device = (HIF_DEVICE *)param;

	
	while(!device->async_shutdown)
	{

		/* wait for work */
		NdisWaitEvent(&device->sem_async, 0);
		NdisResetEvent(&device->sem_async);

		if (device->async_shutdown) {
			NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async task stopping\n");
			break;
		}		
		
		/* pull the request to work on */
		while (device->asyncreq != NULL) 
		{
			request = device->asyncreq;
	
			if (request->inusenext != NULL) 
				device->asyncreq = request->inusenext;
			else 
				device->asyncreq = NULL;
			
			/* call HIFReadWrite in sync mode to do the work */
			NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async_task processing req: 0x%X \r\n", (unsigned int)request);

			rw_cnt++;

			if(rw_cnt > 1)
				NDIS_DEBUG_PRINTF(DBG_ERR, "%s() : two time call !!!!! \r\n", __FUNCTION__);
			
			status = __HIFReadWrite(device, request->address, request->buffer,
			                      request->length, request->request & ~HIF_SYNCHRONOUS, NULL);
			rw_cnt --;
			if (request->request & HIF_ASYNCHRONOUS) 
			{
				NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async_task completion routine req: 0x%X\n", (unsigned int)request);
				device->htcCallbacks.rwCompletionHandler(request->context, status);
				NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async_task freeing req: 0x%X\n", (unsigned int)request);
				hifFreeBusRequest(device, request);
			} 
			else 
			{
			
				NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6000: async_task upping req: 0x%X\n", (unsigned int)request);
				request->status = status;
				NdisSetEvent(&request->sem_req);			
			}


        }

	}

	return 0;
}
Beispiel #23
0
void IoIncrement(OPEN_INSTANCE *pOpen)
{
	if(InterlockedIncrement((PLONG)&pOpen->nIrpCount) == 1)
		NdisResetEvent(&pOpen->CleanupEvent);
}
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));
}
Beispiel #25
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);
	}

}