Exemplo n.º 1
0
VOID NDIS_API PacketUnbindAdapter(OUT PNDIS_STATUS   Status,
                                  IN  POPEN_INSTANCE Open,
                                  IN  POPEN_INSTANCE junk)
{
  // detach protocol from the NIC clean up any pending I/O requests

  PLIST_ENTRY  PacketListEntry;
  PNDIS_PACKET pPacket;


  //  The open instance of the device is about to close
  //  We need to complete all pending I/O requests
  //  First we complete any pending read requests
  NdisAcquireSpinLock(&Open->RcvQSpinLock);

  while (!IsListEmpty(&Open->RcvList)) {
    PacketListEntry = RemoveHeadList(&Open->RcvList);
    pPacket = CONTAINING_RECORD(PacketListEntry, NDIS_PACKET, ProtocolReserved);

    //  complete normally
    PacketTransferDataComplete(Open, pPacket, NDIS_STATUS_SUCCESS, 0);
  }

  NdisReleaseSpinLock(&Open->RcvQSpinLock);

  // close the adapter
  NdisCloseAdapter(Status, Open->AdapterHandle);

  // Save status returned from NdisCloseAdapter for completion routine
  Open->Status = *Status;

  if (*Status != NDIS_STATUS_PENDING)
    PacketUnbindAdapterComplete(Open, *Status);
}
Exemplo n.º 2
0
/*
 * The plug and play support function. This function removes the adapter from
 * the global list of the adapter.
 *
 */
VOID PacketUnbindAdapter (OUT PNDIS_STATUS pStatus,
						  IN NDIS_HANDLE ProtocolBindingContext,
						  IN NDIS_HANDLE UnbindContext)
{
	POPEN_INSTANCE	pOI;
	NDIS_STATUS		nsCloseStatus;


	pOI = (POPEN_INSTANCE)ProtocolBindingContext;
	pOI->BindAdapterContext = UnbindContext;

	// Calls NDIS to close the selected adapter
	NdisCloseAdapter (&nsCloseStatus, pOI->AdapterHandle);
	if (nsCloseStatus == NDIS_STATUS_PENDING) {
		SuspendExecution (pOI);
	} else {
		PacketCloseAdapterComplete (pOI, nsCloseStatus);
	}

	// return the status back to the ndis framework
	*pStatus = pOI->Status;

	// set all the events to release the waits
	SetEvent (pOI->ReadEvent);
	CloseHandle (pOI->ReadEvent);

	// Free the open instance memory
	//NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0);

	// set no instances open
	g_pDeviceExtension->pOpenInstance = NULL;

	return;	
}
Exemplo n.º 3
0
/*
 * Closes the open adapter
 *
 */
BOOL PKTCloseAdapter (POPEN_INSTANCE pOI)
{
	BOOL			bRet = TRUE;
	NDIS_STATUS		nsError;


	// close the adapter
	NdisCloseAdapter (&nsError, pOI->AdapterHandle);

	if (nsError == NDIS_STATUS_PENDING) {
		SuspendExecution (pOI);
	} else {
		PacketCloseAdapterComplete (pOI, nsError);
	}

	if (pOI->Status != NDIS_STATUS_SUCCESS) {
		bRet = FALSE;
	}

	// set all the events to release the waits
	SetEvent (pOI->ReadEvent);
	CloseHandle (pOI->ReadEvent);

	// Free the open instance memory
	NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0);

	// set no instances open
	g_pDeviceExtension->pOpenInstance = NULL;

	return bRet;
}
Exemplo n.º 4
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);

}
Exemplo n.º 5
0
/************************************************************
Start the unbind of a network driver from the protocol driver
************************************************************/
VOID NDIS_API
PacketUnbindAdapter( OUT PNDIS_STATUS	Status,
                     IN  NDIS_HANDLE	ProtocolBindingContext,
                     IN  NDIS_HANDLE	UnbindContext )
{
    POPEN_INSTANCE	Open;
    NDIS_STATUS		nsCloseStatus;

    TRACE_ENTER( "UnbindAdapter" );


    Open = (POPEN_INSTANCE)ProtocolBindingContext;
    Open->BindAdapterContext = UnbindContext;
    /*clean the pending requests*/
    PacketCleanUp( Status, Open );
    Open->Status = NDIS_STATUS_PENDING;
    /*Calls NDIS to close the selected adapter*/

    NdisCloseAdapter( &nsCloseStatus, Open->AdapterHandle );
    if ( nsCloseStatus == NDIS_STATUS_PENDING )
    {
        while ( Open->Status == NDIS_STATUS_PENDING )
            YieldExecution();
    }
    else
    {
        PacketUnbindAdapterComplete( Open, nsCloseStatus );
    }
    *Status = Open->Status;
    if ( *Status == NDIS_STATUS_SUCCESS )
    {
        NdisFreeMemory( Open, sizeof( OPEN_INSTANCE ) ,  0 );
    }
    else
    {
        IF_TRACE( "Unbind Operation FAILED!" );
    }
    TRACE_LEAVE( "CloseAdapter" );

    return;
}
Exemplo n.º 6
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));
}
Exemplo n.º 7
0
Arquivo: Openclos.c Projeto: 52M/npcap
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);
}
Exemplo n.º 8
0
static
NDIS_STATUS
BindAdapterByName(PNDIS_STRING DeviceName)
{
    NDIS_STATUS OpenErrorStatus;
    PNDISUIO_ADAPTER_CONTEXT AdapterContext;
    NDIS_MEDIUM SupportedMedia[1] = {NdisMedium802_3};
    UINT SelectedMedium;
    NDIS_STATUS Status;
    NDIS_REQUEST Request;

    /* Allocate the adapter context */
    AdapterContext = ExAllocatePool(NonPagedPool, sizeof(*AdapterContext));
    if (!AdapterContext)
    {
        return NDIS_STATUS_RESOURCES;
    }

    /* Set up the adapter context */
    RtlZeroMemory(AdapterContext, sizeof(*AdapterContext));
    KeInitializeEvent(&AdapterContext->AsyncEvent, SynchronizationEvent, FALSE);
    KeInitializeEvent(&AdapterContext->PacketReadEvent, SynchronizationEvent, FALSE);
    KeInitializeSpinLock(&AdapterContext->Spinlock);
    InitializeListHead(&AdapterContext->PacketList);
    InitializeListHead(&AdapterContext->OpenEntryList);
    AdapterContext->OpenCount = 0;

    AdapterContext->DeviceName.Length =
    AdapterContext->DeviceName.MaximumLength = DeviceName->Length;
    AdapterContext->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceName->Length);
    if (!AdapterContext->DeviceName.Buffer)
    {
        ExFreePool(AdapterContext);
        return NDIS_STATUS_RESOURCES;
    }

    /* Copy the device name into the adapter context */
    RtlCopyMemory(AdapterContext->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
    
    DPRINT("Binding adapter %wZ\n", &AdapterContext->DeviceName);

    /* Create the buffer pool */
    NdisAllocateBufferPool(&Status,
                           &AdapterContext->BufferPoolHandle,
                           50);
    if (Status != NDIS_STATUS_SUCCESS)
    {
        DPRINT1("Failed to allocate buffer pool with status 0x%x\n", Status);
        RtlFreeUnicodeString(&AdapterContext->DeviceName);
        ExFreePool(AdapterContext);
        return Status;
    }

    /* Create the packet pool */
    NdisAllocatePacketPool(&Status,
                           &AdapterContext->PacketPoolHandle,
                           25,
                           PROTOCOL_RESERVED_SIZE_IN_PACKET);
    if (Status != NDIS_STATUS_SUCCESS)
    {
        DPRINT1("Failed to allocate packet pool with status 0x%x\n", Status);
        NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
        RtlFreeUnicodeString(&AdapterContext->DeviceName);
        ExFreePool(AdapterContext);
        return Status;
    }

    /* Send the open request */
    NdisOpenAdapter(&Status,
                    &OpenErrorStatus,
                    &AdapterContext->BindingHandle,
                    &SelectedMedium,
                    SupportedMedia,
                    1,
                    GlobalProtocolHandle,
                    AdapterContext,
                    DeviceName,
                    0,
                    NULL);
    
    /* Wait for a pending open */
    if (Status == NDIS_STATUS_PENDING)
    {
        KeWaitForSingleObject(&AdapterContext->AsyncEvent,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);
        Status = AdapterContext->AsyncStatus;
    }
    
    /* Check the final status */
    if (Status != NDIS_STATUS_SUCCESS)
    {
        DPRINT1("Failed to open adapter for bind with status 0x%x\n", Status);
        NdisFreePacketPool(AdapterContext->PacketPoolHandle);
        NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
        RtlFreeUnicodeString(&AdapterContext->DeviceName);
        ExFreePool(AdapterContext);
        return Status;
    }
    
    /* Get the MAC options */
    Request.RequestType = NdisRequestQueryInformation;
    Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAC_OPTIONS;
    Request.DATA.QUERY_INFORMATION.InformationBuffer = &AdapterContext->MacOptions;
    Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(ULONG);
    NdisRequest(&Status,
                AdapterContext->BindingHandle,
                &Request);

    /* Wait for a pending request */
    if (Status == NDIS_STATUS_PENDING)
    {
        KeWaitForSingleObject(&AdapterContext->AsyncEvent,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);
        Status = AdapterContext->AsyncStatus;
    }
    
    /* Check the final status */
    if (Status != NDIS_STATUS_SUCCESS)
    {
        NDIS_STATUS CloseStatus;

        DPRINT1("Failed to get MAC options with status 0x%x\n", Status);

        NdisCloseAdapter(&CloseStatus,
                         AdapterContext->BindingHandle);
        if (CloseStatus == NDIS_STATUS_PENDING)
        {
            KeWaitForSingleObject(&AdapterContext->AsyncEvent,
                                  Executive,
                                  KernelMode,
                                  FALSE,
                                  NULL);
        }

        NdisFreePacketPool(AdapterContext->PacketPoolHandle);
        NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
        RtlFreeUnicodeString(&AdapterContext->DeviceName);
        ExFreePool(AdapterContext);
        return Status;
    }
    
    /* Add the adapter context to the global list */
    ExInterlockedInsertTailList(&GlobalAdapterList,
                                &AdapterContext->ListEntry,
                                &GlobalAdapterListLock);

    return STATUS_SUCCESS;
}
Exemplo n.º 9
0
static
NDIS_STATUS
UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
{
    KIRQL OldIrql;
    PLIST_ENTRY CurrentEntry;
    PNDISUIO_OPEN_ENTRY OpenEntry;
    PNDISUIO_PACKET_ENTRY PacketEntry;
    NDIS_STATUS Status;
    
    DPRINT("Unbinding adapter %wZ\n", &AdapterContext->DeviceName);
    
    /* FIXME: We don't do anything with outstanding reads */

    /* Remove the adapter context from the global list */
    KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql);
    RemoveEntryList(&AdapterContext->ListEntry);
    KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql);
    
    /* Free the device name string */
    RtlFreeUnicodeString(&AdapterContext->DeviceName);

    /* Invalidate all handles to this adapter */
    CurrentEntry = AdapterContext->OpenEntryList.Flink;
    while (CurrentEntry != &AdapterContext->OpenEntryList)
    {
        OpenEntry = CONTAINING_RECORD(CurrentEntry, NDISUIO_OPEN_ENTRY, ListEntry);

        /* Make sure the entry is sane */
        ASSERT(OpenEntry->FileObject);

        /* Remove the adapter context pointer */
        ASSERT(AdapterContext == OpenEntry->FileObject->FsContext);
        OpenEntry->FileObject->FsContext = NULL;
        AdapterContext->OpenCount--;

        /* Remove the open entry pointer */
        ASSERT(OpenEntry == OpenEntry->FileObject->FsContext2);
        OpenEntry->FileObject->FsContext2 = NULL;
        
        /* Move to the next entry */
        CurrentEntry = CurrentEntry->Flink;

        /* Free the open entry */
        ExFreePool(OpenEntry);
    }

    /* If this fails, we have a refcount mismatch somewhere */
    ASSERT(AdapterContext->OpenCount == 0);
    
    /* Free all pending packet entries */
    CurrentEntry = AdapterContext->PacketList.Flink;
    while (CurrentEntry != &AdapterContext->PacketList)
    {
        PacketEntry = CONTAINING_RECORD(CurrentEntry, NDISUIO_PACKET_ENTRY, ListEntry);

        /* Move to the next entry */
        CurrentEntry = CurrentEntry->Flink;

        /* Free the packet entry */
        ExFreePool(PacketEntry);
    }
    
    /* Send the close request */
    NdisCloseAdapter(&Status,
                     AdapterContext->BindingHandle);
    
    /* Wait for a pending close */
    if (Status == NDIS_STATUS_PENDING)
    {
        KeWaitForSingleObject(&AdapterContext->AsyncEvent,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);
        Status = AdapterContext->AsyncStatus;
    }
    
    /* Free the context */
    ExFreePool(AdapterContext);
    
    return Status;
}
Exemplo n.º 10
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;
		}
	}
}
Exemplo n.º 11
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);
	}

}
Exemplo n.º 12
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));
}
Exemplo n.º 13
0
VOID
PtBindAdapter(
	OUT PNDIS_STATUS			Status,
	IN  NDIS_HANDLE				BindContext,
	IN  PNDIS_STRING			DeviceName,
	IN  PVOID					SystemSpecific1,
	IN  PVOID					SystemSpecific2
	)
/*++

Routine Description:

	Called by NDIS to bind to a miniport below.

Arguments:

	Status			- Return status of bind here.
	BindContext		- Can be passed to NdisCompleteBindAdapter if this call is pended.
	DeviceName 		- Device name to bind to. This is passed to NdisOpenAdapter.
	SystemSpecific1	- Can be passed to NdisOpenProtocolConfiguration to read per-binding information
	SystemSpecific2	- Unused

Return Value:

	NDIS_STATUS_PENDING	if this call is pended. In this case call NdisCompleteBindAdapter
	to complete.
	Anything else		Completes this call synchronously

--*/
{
	NDIS_HANDLE						ConfigHandle = NULL;
	PNDIS_CONFIGURATION_PARAMETER	Param;
	NDIS_STRING						DeviceStr = NDIS_STRING_CONST("UpperBindings");
	PADAPT							pAdapt = NULL;
	NDIS_STATUS						Sts;
	UINT							MediumIndex;
	ULONG							TotalSize;

	PNDIS_CONFIGURATION_PARAMETER	BundleParam;
	NDIS_STRING						BundleStr = NDIS_STRING_CONST("BundleId");
	NDIS_STATUS						BundleStatus;
	
	DBGPRINT(("==> Protocol BindAdapter\n"));

	do
	{
		//
		// Access the configuration section for our binding-specific
		// parameters.
		//
		NdisOpenProtocolConfiguration(Status,
		  							 &ConfigHandle,
		  							 SystemSpecific1);

		if (*Status != NDIS_STATUS_SUCCESS)
		{
		  	break;
		}

		//
		// Read the "UpperBindings" reserved key that contains a list
		// of device names representing our miniport instances corresponding
		// to this lower binding. Since this is a 1:1 IM driver, this key
		// contains exactly one name.
		//
		// If we want to implement a N:1 mux driver (N adapter instances
		// over a single lower binding), then UpperBindings will be a
		// MULTI_SZ containing a list of device names - we would loop through
		// this list, calling NdisIMInitializeDeviceInstanceEx once for
		// each name in it.
		//
		NdisReadConfiguration(Status,
							  &Param,
		  					  ConfigHandle,
		  					  &DeviceStr,
		  					  NdisParameterString);
		if (*Status != NDIS_STATUS_SUCCESS)
		{
		  	break;
		}

		//
		// Allocate memory for the Adapter structure. This represents both the
		// protocol context as well as the adapter structure when the miniport
		// is initialized.
		//
		// In addition to the base structure, allocate space for the device
		// instance string.
		//
		TotalSize = sizeof(ADAPT) + Param->ParameterData.StringData.MaximumLength;
		NdisAllocateMemoryWithTag(&pAdapt, TotalSize, TAG);

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

		//
		// Initialize the adapter structure. We copy in the IM device
		// name as well, because we may need to use it in a call to
		// NdisIMCancelInitializeDeviceInstance. The string returned
		// by NdisReadConfiguration is active (i.e. available) only
		// for the duration of this call to our BindAdapter handler.
		//
		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(ADAPT));
		NdisMoveMemory(pAdapt->DeviceName.Buffer,
					   Param->ParameterData.StringData.Buffer,
					   Param->ParameterData.StringData.MaximumLength);

		NdisInitializeEvent(&pAdapt->Event);

		//
		// Allocate a packet pool for sends. We need this to pass sends down.
		// We cannot use the same packet descriptor that came down to our send
		// handler (see also NDIS 5.1 packet stacking).
		//
		NdisAllocatePacketPoolEx(Status,
		  						 &pAdapt->SendPacketPoolHandle,
		  						 MIN_PACKET_POOL_SIZE,
		  						 MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
		  						 sizeof(SEND_RSVD));

		if (*Status != NDIS_STATUS_SUCCESS)
		{
		  	break;
		}

		//
		// Allocate a packet pool for receives. We need this to indicate receives.
		// Same consideration as sends (see also NDIS 5.1 packet stacking).
		//
		NdisAllocatePacketPoolEx(Status,
		  						 &pAdapt->RecvPacketPoolHandle,
		  						 MIN_PACKET_POOL_SIZE,
		  						 MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
		  						 PROTOCOL_RESERVED_SIZE_IN_PACKET);

		if (*Status != NDIS_STATUS_SUCCESS)
		{
		  	break;
		}

		//
		// Now open the adapter below and complete the initialization
		//
		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)
		{
		  	break;
		}

		pAdapt->Medium = MediumArray[MediumIndex];

		//
		// Now ask NDIS to initialize our miniport (upper) edge.
		// Set the flag below to synchronize with a possible call
		// to our protocol Unbind handler that may come in before
		// our miniport initialization happens.
		//
		pAdapt->MiniportInitPending = TRUE;
		NdisInitializeEvent(&pAdapt->MiniportInitEvent);

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

		if (*Status != NDIS_STATUS_SUCCESS)
		{
			DBGPRINT(("BindAdapter: Adapt %p, IMInitializeDeviceInstance error %x\n",
				pAdapt, *Status));
			break;
		}

	} while(FALSE);

	//
	// Close the configuration handle now - see comments above with
	// the call to NdisIMInitializeDeviceInstanceEx.
	//
	if (ConfigHandle != NULL)
	{
		NdisCloseConfiguration(ConfigHandle);
	}

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

				//
				// Close the binding we opened above.
				//
				NdisCloseAdapter(&LocalStatus, pAdapt->BindingHandle);
				pAdapt->BindingHandle = NULL;

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

			if (pAdapt->SendPacketPoolHandle != NULL)
			{
				 NdisFreePacketPool(pAdapt->SendPacketPoolHandle);
			}

			if (pAdapt->RecvPacketPoolHandle != NULL)
			{
				 NdisFreePacketPool(pAdapt->RecvPacketPoolHandle);
			}

			NdisFreeMemory(pAdapt, sizeof(ADAPT), 0);
			pAdapt = NULL;
		}
	}


	DBGPRINT(("<== Protocol BindAdapter: pAdapt %p, Status %x\n", pAdapt, *Status));
}
Exemplo n.º 14
0
/************************************************************
Function used by NDIS to update the VXD when a new MAC driver
is added
************************************************************/
VOID NDIS_API PacketBindAdapter( OUT PNDIS_STATUS Status,
                                 IN  NDIS_HANDLE  BindAdapterContext,
                                 IN  PNDIS_STRING AdapterName,
                                 IN  PVOID        SystemSpecific1,
                                 IN  PVOID        SystemSpecific2 )
{
    PDEVICE_EXTENSION	pde;
    POPEN_INSTANCE		oiNew;
    NDIS_STATUS			nsErrorStatus, nsOpenStatus;
    UINT           		uiMedium;
    UINT           		i;
    PWRAPPER_PROTOCOL_BLOCK				pWPBlock;
    PNDIS_PROTOCOL_CHARACTERISTICS	pNPChar;
    PADAPTER_NAME		AName;
    PWRAPPER_MAC_BLOCK	pWMBlock;
    PNDIS_MAC_CHARACTERISTICS	  pNMChar;
    BYTE                *lpzName;


    TRACE_ENTER( "BindAdapter" );
    pde = GlobalDeviceExtension;
    /*Allocate an element that describe an adapter*/
    NdisAllocateMemory( (PVOID *)&AName, sizeof(ADAPTER_NAME), 0, -1 );
    if ( AName == NULL )
    {
        *Status = NDIS_STATUS_RESOURCES;
        return;
    }

    NdisAllocateMemory( (PVOID *)&oiNew, sizeof( OPEN_INSTANCE ), 0, -1 );
    if ( oiNew == NULL )
    {
        *Status = NDIS_STATUS_RESOURCES;
        return;
    }
    NdisZeroMemory( (PVOID)oiNew, sizeof( OPEN_INSTANCE ) );

    /*Save Binding Context*/
    oiNew->BindAdapterContext = BindAdapterContext;

    /*Save the device handle*/

    oiNew->hDevice = (DWORD) SystemSpecific1;

    /*allocate a pool for the packet headers*/

    NdisAllocatePacketPool( &nsErrorStatus,
                            &(oiNew->PacketPool),
                            TRANSMIT_PACKETS,
                            sizeof(PACKET_RESERVED) );

    IF_TRACE_MSG( "PACKET_RESERVED_b :%lx",sizeof(PACKET_RESERVED));
    if ( nsErrorStatus != NDIS_STATUS_SUCCESS )
    {
        IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus );
        NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) ,  0 );
        *Status = NDIS_STATUS_RESOURCES;
        TRACE_LEAVE( "BindAdapter" );
        return;
    }


    /*allocate a pool for the packet data*/

    NdisAllocateBufferPool( &nsErrorStatus,
                            &(oiNew->BufferPool),
                            TRANSMIT_PACKETS );
    if ( nsErrorStatus != NDIS_STATUS_SUCCESS )
    {
        IF_TRACE_MSG( "Failed to allocate packet pool AllocStatus=%x", nsErrorStatus );
        NdisFreePacketPool( oiNew->PacketPool );
        NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) ,  0 );
        *Status = NDIS_STATUS_RESOURCES;
        TRACE_LEAVE( "BindAdapter" );
        return;
    }
    NdisAllocateSpinLock( &(oiNew->ResetSpinLock) );
    InitializeListHead( &(oiNew->ResetIrpList) );
    NdisAllocateSpinLock( &(oiNew->RcvQSpinLock) );
    InitializeListHead( &(oiNew->RcvList) );
    NdisAllocateSpinLock( &(oiNew->RequestSpinLock) );
    InitializeListHead( &(oiNew->RequestList) );

    for ( i=0; i<MAX_REQUESTS; i++ )
    {
        InsertTailList( &(oiNew->RequestList), &(oiNew->Requests[i].Reserved.ListElement) );
    }
    oiNew->Status = NDIS_STATUS_PENDING;
    oiNew->BindAdapterContext = BindAdapterContext;

    /*open the MAC driver calling NDIS*/

    oiNew->hDevice=0;
    oiNew->tagProcess=0;

    NdisOpenAdapter( &nsOpenStatus,
                     &nsErrorStatus,
                     &oiNew->AdapterHandle,
                     &uiMedium,
                     MediumArray,
                     NUM_NDIS_MEDIA,
                     pde->NdisProtocolHandle,
                     oiNew,
                     AdapterName,
                     0,
                     NULL );
    IF_TRACE_MSG( "Open Status                   : %lx", nsOpenStatus );
    IF_TRACE_MSG( "Error Status                  : %lx", nsErrorStatus );
    IF_TRACE_MSG( "Completion Status             : %lx", oiNew->Status );
    if ( nsOpenStatus == NDIS_STATUS_PENDING )
    {
        while ( oiNew->Status == NDIS_STATUS_PENDING )
            YieldExecution();
    }
    else
    {
        PacketOpenAdapterComplete( oiNew, nsOpenStatus, nsErrorStatus );
    }

    pWPBlock = ((PWRAPPER_OPEN_BLOCK)(oiNew->AdapterHandle))->ProtocolHandle;
    pNPChar  = &pWPBlock->ProtocolCharacteristics;
    IF_TRACE_MSG( "Protocol                      : %s",  pNPChar->Name.Buffer );
    IF_TRACE_MSG( "Protocol Handle               : %lx", pde->NdisProtocolHandle );
    IF_TRACE_MSG( "PWRAPPER_OPEN_BLOCK           : %lx", oiNew->AdapterHandle );
    IF_TRACE_MSG( "PWRAPPER_PROTOCOL_BLOCK       : %lx", pWPBlock );
    IF_TRACE_MSG( "NDIS_PROTOCOL_CHARACTERISTICS : %lx", pNPChar );
    IF_TRACE_MSG( "Name                          : %lx", &pNPChar->Name );
    IF_TRACE_MSG( "Adapter Name                  : %s",  AdapterName->Buffer );
    *Status = oiNew->Status;

    if ( *Status != NDIS_STATUS_SUCCESS )
    {
        NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) ,  0 );
        IF_TRACE( "Bind Operation FAILED!" );
    }
    else
    {
        AName->realnamestr.Length=AdapterName->Length;
        AName->realnamestr.MaximumLength=AdapterName->MaximumLength;
        AName->realnamestr.Buffer=AName->realname;
        for(i=0; i<32; i++)AName->realname[i]=AdapterName->Buffer[i];

        pWMBlock = ((PWRAPPER_OPEN_BLOCK)(oiNew->AdapterHandle))->MacHandle;
        pNMChar  = &pWMBlock->MacCharacteristics;
        lpzName  = pNMChar->Name.Buffer;
        for(i=0; i<32; i++)AName->devicename[i]=lpzName[i];
        InsertTailList( &GlobalDeviceExtension->AdapterNames, &AName->ListElement);

        //close the adapter
        NdisCloseAdapter(&nsErrorStatus,oiNew->AdapterHandle);

        if ( nsErrorStatus == NDIS_STATUS_PENDING )
        {
            while ( oiNew->Status == NDIS_STATUS_PENDING )
                YieldExecution();
        }
        else
        {
            PacketUnbindAdapterComplete( oiNew, nsErrorStatus );
        }
        *Status = oiNew->Status;
        if ( *Status == NDIS_STATUS_SUCCESS )
        {
            //remove this adapter from the list of open adapters
            RemoveEntryList(&(oiNew->ListElement));
            //free the memory
            NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) ,  0 );
        }
        else
        {
            IF_TRACE( "Close Operation FAILED!" );
        }

    }

    TRACE_LEAVE( "BindAdapter" );
    return;
}
Exemplo n.º 15
0
DWORD PacketClose(POPEN_INSTANCE Open,DWORD dwDDB,DWORD hDevice,PDIOCPARAMETERS pDiocParms)
{

    NDIS_STATUS			Status;
    NDIS_STATUS			nsErrorStatus;
    UINT				to;
    DWORD				TEvent;

    TRACE_ENTER( "PacketClose" );

    Open->BufSize=0;

    to=Open->ReadTimeoutTimer;
    Open->ReadTimeoutTimer=0;
    if(to!=0) {
        _asm push esi;
        _asm mov esi,to;
        CancelReadTimeOut();
        _asm pop esi;
    }

    // Free the read event
    TEvent=Open->ReadEvent;
    _asm mov eax,TEvent;
    VxDCall(_VWIN32_CloseVxDHandle);

    //close the adapter
    NdisCloseAdapter(&nsErrorStatus,Open->AdapterHandle);
    if ( nsErrorStatus == NDIS_STATUS_PENDING )
    {
        while ( Open->Status == NDIS_STATUS_PENDING )
            YieldExecution();

        if(Open->Status!=NDIS_STATUS_SUCCESS) {
            TRACE_LEAVE( "PacketClose" );
            return NDIS_STATUS_FAILURE;
        }
    }
    else
    {
        PacketUnbindAdapterComplete( Open, nsErrorStatus );
        if(nsErrorStatus!=NDIS_STATUS_SUCCESS) {
            TRACE_LEAVE( "PacketClose" );
            return NDIS_STATUS_FAILURE;
        }
    }

    Status = Open->Status;

    if(Open->Buffer!=NULL)NdisFreeMemory(Open->Buffer,Open->BufSize,0);
    Open->Buffer=NULL;
    if(Open->bpfprogram!=NULL)NdisFreeMemory(Open->bpfprogram,Open->bpfprogramlen,0);

    //remove this adapter from the list of open adapters
    NdisAcquireSpinLock( &GlobalDeviceExtension->OpenSpinLock );
    RemoveEntryList(&(Open->ListElement));
    NdisReleaseSpinLock( &GlobalDeviceExtension->OpenSpinLock );

    NdisFreeMemory( Open, sizeof( OPEN_INSTANCE ) ,  0 );

    if(pDiocParms!=NULL)
        *(DWORD *)(pDiocParms->lpcbBytesReturned) = 0;

    TRACE_LEAVE( "PacketClose" );
    return Status;

}