Exemplo n.º 1
0
Arquivo: Openclos.c Projeto: 52M/npcap
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;
}
Exemplo n.º 2
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.º 3
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;
}
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.º 5
0
VOID NDIS_API PacketBindAdapter(OUT PNDIS_STATUS pStatus,
                                IN  NDIS_HANDLE  BindAdapterContext,
                                IN  PNDIS_STRING pAdapterName,
                                IN  PVOID        SystemSpecific1,
                                IN  PVOID        SystemSpecific2)
{
  //   bind this driver to a NIC
  
  POPEN_INSTANCE    oiNew;
  NDIS_STATUS	    ErrorStatus, AllocStatus;
  UINT              Medium;
  NDIS_MEDIUM       MediumArray = NdisMedium802_3;
  UINT              i;


  //  allocate some memory for the open structure
  NdisAllocateMemory((PVOID *)&oiNew, sizeof(OPEN_INSTANCE), 0, -1);
  if (oiNew == NULL) { // not enough memory
    *pStatus = 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 packet pool for our xmit and receive packets
  NdisAllocatePacketPool(&AllocStatus,
                         &(oiNew->PacketPool),
                         TRANSMIT_PACKETS,
                         sizeof(PACKET_RESERVED));
  if (AllocStatus != NDIS_STATUS_SUCCESS) { // not enough memory
    NdisFreeMemory(oiNew, sizeof(OPEN_INSTANCE), 0);
    *pStatus = NDIS_STATUS_RESOURCES;
    return;
  }
  
  // Allocate a buffer pool for our xmit and receive buffers
  NdisAllocateBufferPool(&AllocStatus, &(oiNew->BufferPool), TRANSMIT_PACKETS);
  if (AllocStatus != NDIS_STATUS_SUCCESS) { // not enough memory
    NdisFreeMemory(oiNew, sizeof(OPEN_INSTANCE), 0);
    *pStatus = NDIS_STATUS_RESOURCES;
    return;
  }

  //  list to hold irp's that want to reset the adapter
  NdisAllocateSpinLock(&oiNew->ResetSpinLock);
  InitializeListHead(&oiNew->ResetIrpList);

  //  Initialize list for holding pending read requests
  NdisAllocateSpinLock(&oiNew->RcvQSpinLock);
  InitializeListHead(&oiNew->RcvList);
  
  //  Initialize the request list
  NdisAllocateSpinLock(&oiNew->RequestSpinLock);
  InitializeListHead(&oiNew->RequestList);
  
  //  link up the request stored in our open block
  for (i = 0; i < MAX_REQUESTS; i++) {
    // Braces are required as InsertTailList macro has multiple statements in it
    InsertTailList(&oiNew->RequestList, &oiNew->Requests[i].Reserved.ListElement);
  }
  
  //  Try to open the MAC
  NdisOpenAdapter(pStatus, &ErrorStatus, &oiNew->AdapterHandle, &Medium, &MediumArray, 1,
                  GlobalDeviceExtension->NdisProtocolHandle, oiNew, pAdapterName, 0, NULL);
  
  //  Save the status returned by NdisOpenAdapter for completion routine
  oiNew->Status = *pStatus;
  
  switch (*pStatus) {
    case NDIS_STATUS_PENDING:
      break;
    
    case NDIS_STATUS_SUCCESS:
      ErrorStatus = NDIS_STATUS_SUCCESS;
    
      // fall through to completion routine with oiNew->Status 
      // set to !NDIS_STATUS_PENDING
    
    default:
      PacketBindAdapterComplete(oiNew, *pStatus, ErrorStatus);
      break;
  }
}
Exemplo n.º 6
0
DWORD PacketOpen(PNDIS_STRING AdapterName,DWORD dwDDB,DWORD hDevice,PDIOCPARAMETERS pDiocParms)
{

    LARGE_INTEGER		SystemTime;
    __int64				ltime1;
    PDEVICE_EXTENSION	pde;
    POPEN_INSTANCE 		oiNew;
    NDIS_STATUS			nsErrorStatus, nsOpenStatus;
    UINT           	i;
    UINT           	uiMedium;
    NDIS_STRING		NameStr;
    NDIS_STATUS	Status;


    pde = GlobalDeviceExtension;
    /*Allocate an element that describe an adapter*/
    NdisAllocateMemory( (PVOID *)&oiNew, sizeof( OPEN_INSTANCE ), 0, -1 );
    if ( oiNew == NULL )
    {
        return NDIS_STATUS_FAILURE;
    }
    NdisZeroMemory( (PVOID)oiNew, sizeof( OPEN_INSTANCE ) );
    /*allocate a pool for the packet headers*/

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

    IF_TRACE_MSG( "PACKET_RESERVED_a :%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 );
        TRACE_LEAVE( "BindAdapter" );
        return NDIS_STATUS_FAILURE;
    }


    /*allocate a buffer 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 );
        TRACE_LEAVE( "BindAdapter" );
        return NDIS_STATUS_FAILURE;
    }
    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;

    /*initialize the timer variables for this session*/

    SystemTime=GetDate();

    ltime1=((__int64)SystemTime.HighPart*86400);
    ltime1+=(__int64)(SystemTime.LowPart/1000);	//current time from 1980 in seconds
    ltime1+=(__int64)315532800;	//current time from 1970 (Unix format) in seconds
    ltime1*=1193182;
    ltime1+=(SystemTime.LowPart%1000)*1193182/1000; //current time from 1970 in ticks
    ltime1-=QuerySystemTime();	//boot time from 1970 in ticks
    oiNew->StartTime=ltime1;


    oiNew->Dropped=0;		//reset the dropped packets counter
    oiNew->Received=0;		//reset the received packets counter
    oiNew->bpfprogram=NULL;	//set an accept-all filter
    oiNew->bpfprogramlen=0;
    oiNew->BufSize=0;		//set an empty buffer
    oiNew->Buffer=NULL;		//reset the buffer
    oiNew->Bhead=0;
    oiNew->Btail=0;
    oiNew->BLastByte=0;
    oiNew->TimeOut=0;		//reset the timeouts
    oiNew->ReadTimeoutTimer=0;
    oiNew->mode=0;			//set capture mode
    oiNew->Nbytes=0;		//reset the counters
    oiNew->Npackets=0;
    oiNew->hDevice=hDevice;
    oiNew->tagProcess=pDiocParms->tagProcess;
    oiNew->ReadEvent=0;		//reset the read event

    NdisAllocateSpinLock( &(oiNew->CountersLock) );
    /*open the MAC driver calling NDIS*/
    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 );
    }

    Status = oiNew->Status;
    if ( Status != NDIS_STATUS_SUCCESS )
    {
        NdisFreeMemory( oiNew, sizeof( OPEN_INSTANCE ) ,  0 );
        return NDIS_STATUS_FAILURE;
    }
    else
    {

    }

    TRACE_LEAVE( "BindAdapter" );

    /*return succesfully*/
    return STATUS_SUCCESS;

}
Exemplo n.º 7
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.º 8
0
/*
 * Opens the specified adapter and binds the protocol to it
 *
 * Arguments
 *		AdapterName		- The name of the adapter with which binding should happen
 *
 * Return Value
 *		Return TRUE if successfully bound otherwise returns FALSE
 *
 */
BOOL PKTOpenAdapter (PNDIS_STRING pAdapterName)
{
	POPEN_INSTANCE	pOI;
	NDIS_STATUS		nsOpen;
	NDIS_STATUS		nsError;
	SYSTEMTIME		SystemTime;
	FILETIME		FileTime;
	LARGE_INTEGER	liSysTime;
	LARGE_INTEGER	TimeFreq;
	LARGE_INTEGER	PTime;
	UINT			uiMedium;


	// Check if an instance is already opened
	if (g_pDeviceExtension->pOpenInstance) {
		SetLastError (ERROR_ALREADY_INITIALIZED);
		return FALSE;
	}

	// Time initialization
	GetSystemTime (&SystemTime);
	if (! (SystemTimeToFileTime (&SystemTime, &FileTime) &&
		QueryPerformanceCounter (&PTime) && QueryPerformanceFrequency (&TimeFreq))) {
		return FALSE;
	}
	NdisMoveMemory (&liSysTime, &FileTime, sizeof (LARGE_INTEGER));
	
	
	
	// allocate an instance that describes the adapter
	NdisAllocateMemory (&pOI, sizeof (OPEN_INSTANCE), 0, NDIS_ADDR_M1);
	if (pOI == NULL) {
		return FALSE;
	}
	NdisZeroMemory (pOI, sizeof (OPEN_INSTANCE));

	// init struct variables
	pOI->bpfprogram			= NULL;		//set an accept-all filter
	pOI->bpfprogramlen		= 0;
	pOI->BufSize			= 0;		//set an empty buffer
	pOI->Buffer				= NULL;		//reset the buffer
	pOI->Bhead				= 0;
	pOI->Btail				= 0;
	pOI->BLastByte			= 0;
	pOI->TimeOut			= 0;		//reset the timeouts


	// create the shared name read event
	pOI->ReadEvent = CreateEvent (NULL, FALSE, FALSE, SH_EVENT_NAME);
	if (pOI->ReadEvent == NULL) {
		NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0);
		return FALSE;
	}

	// set time values
	pOI->StartTime.QuadPart = (((liSysTime.QuadPart) % 10000000) * TimeFreq.QuadPart)/10000000;
	liSysTime.QuadPart = liSysTime.QuadPart / 10000000 - 11644473600;
	pOI->StartTime.QuadPart += (liSysTime.QuadPart) * TimeFreq.QuadPart - PTime.QuadPart;


	// allocate pool for the packet headers
	NdisAllocatePacketPool (&nsError, &(pOI->PacketPool), 
		TRANSMIT_PACKETS, sizeof (PACKET_RESERVED));
	if (nsError != NDIS_STATUS_SUCCESS) {
		CloseHandle (pOI->ReadEvent);
		NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0);
		return FALSE;
	}


	// allocate buffer pool for the packet data
	NdisAllocateBufferPool (&nsError, &(pOI->BufferPool), TRANSMIT_PACKETS);
	if (nsError != NDIS_STATUS_SUCCESS) {
		CloseHandle (pOI->ReadEvent);
		NdisFreePacketPool (pOI->PacketPool);
		NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0);
		return FALSE;
	}

	// set status pending
	pOI->Status = NDIS_STATUS_PENDING;

	// open the MAC driver
	NdisOpenAdapter (&nsOpen, &nsError, &pOI->AdapterHandle, &uiMedium, MediumArray,
		NUM_NDIS_MEDIA, g_pDeviceExtension->NdisProtocolHandle, pOI, pAdapterName, 0, NULL);


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

	// free the packet instance if not successful
	if (pOI->Status != NDIS_STATUS_SUCCESS) {
		CloseHandle (pOI->ReadEvent);
		NdisFreeMemory (pOI, sizeof (OPEN_INSTANCE), 0);
		return FALSE;
	}

	return TRUE;
}