Esempio n. 1
0
VOID
ExFreeToPagedLookasideList(
    IN PPAGED_LOOKASIDE_LIST Lookaside,
    IN PVOID Entry
    )

/*++

Routine Description:

    This function inserts (pushes) the specified entry into the specified
    paged lookaside list.

Arguments:

    Lookaside - Supplies a pointer to a paged lookaside list structure.

    Entry - Supples a pointer to the entry that is inserted in the
        lookaside list.

Return Value:

    None.

--*/

{

    Lookaside->L.TotalFrees += 1;

    if (Isx86FeaturePresent(KF_CMPXCHG8B)) {
        if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) {
            Lookaside->L.FreeMisses += 1;
            (Lookaside->L.Free)(Entry);

        } else {
            ExInterlockedPushEntrySList(&Lookaside->L.ListHead,
                                        (PSINGLE_LIST_ENTRY)Entry,
                                        NULL);
        }

        return;
    }

    ExAcquireFastMutex(&Lookaside->Lock);
    if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) {
        ExReleaseFastMutex(&Lookaside->Lock);
        Lookaside->L.FreeMisses += 1;
        (Lookaside->L.Free)(Entry);

    } else {
        PushEntryList(&Lookaside->L.ListHead.Next, (PSINGLE_LIST_ENTRY)Entry);
        Lookaside->L.ListHead.Depth += 1;
        ExReleaseFastMutex(&Lookaside->Lock);
    }

    return;
}
Esempio n. 2
0
NTSTATUS
SpWmiPushFreeRequestItem(
    IN PADAPTER_EXTENSION           fdoExtension
    )
/*++

Routine Description:

    Inserts the Entry into the interlocked SLIST.  (Of Free items)

Arguments:

    fdoExtension        - The extension on the adapter

Return Value:

    STATUS_SUCESS                   - If succesful
    STATUS_INSUFFICIENT_RESOURCES   - If memory allocation fails
    STATUS_UNSUCCESSFUL             - Free List not initialized

Notes:

    This code cannot be marked as pageable since it will be called from
    DPC level

    Theoricatlly this call can fail, but no one should call this function
    before we've been initialized

--*/
{
    PWMI_MINIPORT_REQUEST_ITEM      Entry = NULL;

    if (!fdoExtension->WmiFreeMiniPortRequestInitialized) {
        return (STATUS_UNSUCCESSFUL);
    }

    Entry = ExAllocatePoolWithTag(
        NonPagedPool,
        sizeof(WMI_MINIPORT_REQUEST_ITEM),
        SCSIPORT_TAG_WMI_EVENT);

    if (!Entry) {
        return(STATUS_INSUFFICIENT_RESOURCES);
    }

    Entry->NextRequest = NULL;

    // Insert Cell into interlocked list
    ExInterlockedPushEntrySList(
        &(fdoExtension->WmiFreeMiniPortRequestList),
        (PSINGLE_LIST_ENTRY)Entry,
        &(fdoExtension->WmiFreeMiniPortRequestLock));

    // Increment the value of the free count
    InterlockedIncrement(&(fdoExtension->WmiFreeMiniPortRequestCount));

    return(STATUS_SUCCESS);
}
Esempio n. 3
0
int dc_parallelized_crypt(
	   int   is_encrypt, xts_key *key, callback_ex on_complete, void *param1, void *param2,
	   const unsigned char *in, unsigned char *out, u32 len, u64 offset)
{
	req_item *item;
	req_part *part;
	u32       part_sz;
	u32       part_of;

	if ( (item = ExAllocateFromNPagedLookasideList(&pool_req_mem)) == NULL) {
		return 0;
	}
	item->is_encrypt = is_encrypt;
	item->length = len;
	item->in  = in;
	item->out = out;
	item->offset      = offset;
	item->on_complete = on_complete;
	item->param1 = param1;
	item->param2 = param2;
	item->key    = key;

	part_sz = _align(len / dc_cpu_count, F_MIN_REQ);
	part_of = 0; part = &item->parts[0];
	do
	{
		part_sz      = min(part_sz, len);
		part->item   = item;
		part->offset = part_of;
		part->length = part_sz;

		ExInterlockedPushEntrySList(&pool_head, &part->entry, &pool_lock);

		part_of += part_sz; len -= part_sz; part++;
	} while (len != 0);

	KeSetEvent(&pool_signal_event, IO_NO_INCREMENT, FALSE);
	return 1;
}
Esempio n. 4
0
NTSTATUS
SpCreateLogicalUnit(
    IN PDEVICE_OBJECT AdapterFdo,
    UCHAR PathId,
    UCHAR TargetId,
    UCHAR Lun,
    OUT PDEVICE_OBJECT *NewPdo
    )

/*++

Routine Description:

    This routine will create a physical device object for the specified device

Arguments:

    AdapterFdo - the FDO this device was enumerated from

    LunInfo - the scsi port lun info structure for this device

    NewPdo - a location to store the pointer to the new device

Return Value:

    status

--*/

{
    PADAPTER_EXTENSION deviceExtension = AdapterFdo->DeviceExtension;

    PIRP senseIrp;

    PDEVICE_OBJECT pdo = NULL;

    WCHAR wideDeviceName[64];
    UNICODE_STRING unicodeDeviceName;

    ULONG extensionSize;

    NTSTATUS status;

    PAGED_CODE();

    //
    // Attempt to allocate all the persistent resources we need before we 
    // try to create the device object itself.
    //

    //
    // Allocate a request sense irp.
    //

    senseIrp = IoAllocateIrp(1, FALSE);

    if(senseIrp == NULL) {
        DebugPrint((0, "SpCreateLogicalUnit: Could not allocate request sense "
                       "irp\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Build the name for the device
    //

    swprintf(wideDeviceName,
             L"%wsPort%xPath%xTarget%xLun%x",
             deviceExtension->DeviceName,
             deviceExtension->PortNumber,
             PathId,
             TargetId,
             Lun);

    RtlInitUnicodeString(&unicodeDeviceName, wideDeviceName);

    //
    // Round the size of the Hardware logical extension to the size of a
    // PVOID and add it to the port driver's logical extension.
    //

    extensionSize =
        (deviceExtension->HwLogicalUnitExtensionSize + sizeof(LONGLONG) - 1) &
        ~(sizeof(LONGLONG) -1);
    extensionSize += sizeof(LOGICAL_UNIT_EXTENSION);

    //
    // Create a physical device object
    //

    status = IoCreateDevice(
                AdapterFdo->DriverObject,
                extensionSize,
                &unicodeDeviceName,
                FILE_DEVICE_MASS_STORAGE,
                FILE_DEVICE_SECURE_OPEN,
                FALSE,
                &pdo
                );

    if(NT_SUCCESS(status)) {

        PCOMMON_EXTENSION commonExtension;
        PLOGICAL_UNIT_EXTENSION logicalUnitExtension;
        UCHAR i;
        ULONG bin;

        UCHAR rawDeviceName[64];
        ANSI_STRING ansiDeviceName;

        //
        // Set the device object's stack size
        //

        //
        // We need one stack location for the PDO to do lock tracking and
        // one stack location to issue scsi request to the FDO.
        //

        pdo->StackSize = 1;

        pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;

        pdo->Flags |= DO_DIRECT_IO;

        pdo->AlignmentRequirement = AdapterFdo->AlignmentRequirement;

        //
        // Initialize the device extension for the root device
        //

        commonExtension = pdo->DeviceExtension;
        logicalUnitExtension = pdo->DeviceExtension;

        RtlZeroMemory(logicalUnitExtension, extensionSize);

        commonExtension->DeviceObject = pdo;
        commonExtension->IsPdo = TRUE;
        commonExtension->LowerDeviceObject = AdapterFdo;
        commonExtension->MajorFunction = DeviceMajorFunctionTable;

        commonExtension->WmiInitialized            = FALSE;
        commonExtension->WmiMiniPortSupport        =
            deviceExtension->CommonExtension.WmiMiniPortSupport;

        commonExtension->WmiScsiPortRegInfoBuf     = NULL;
        commonExtension->WmiScsiPortRegInfoBufSize = 0;

        //
        // Initialize value to zero.  It will be incremented once pnp is aware
        // of its existance.
        //

        commonExtension->RemoveLock = 0;
#if DBG
        KeInitializeSpinLock(&commonExtension->RemoveTrackingSpinlock);
        commonExtension->RemoveTrackingList = NULL;

        ExInitializeNPagedLookasideList(
            &(commonExtension->RemoveTrackingLookasideList),
            NULL,
            NULL,
            0,
            sizeof(REMOVE_TRACKING_BLOCK),
            SCSIPORT_TAG_LOCK_TRACKING,
            64);

        commonExtension->RemoveTrackingLookasideListInitialized = TRUE;
#else
        commonExtension->RemoveTrackingSpinlock = (ULONG) -1L;
        commonExtension->RemoveTrackingList = (PVOID) -1L;
#endif

        commonExtension->CurrentPnpState = 0xff;
        commonExtension->PreviousPnpState = 0xff;

        //
        // Initialize the remove lock event.
        //

        KeInitializeEvent(
            &(logicalUnitExtension->CommonExtension.RemoveEvent),
            SynchronizationEvent,
            FALSE);

        logicalUnitExtension->LuFlags |= LU_RESCAN_ACTIVE;

        logicalUnitExtension->PortNumber = deviceExtension->PortNumber;

        logicalUnitExtension->PathId = PathId;
        logicalUnitExtension->TargetId = TargetId;
        logicalUnitExtension->Lun = Lun;

        logicalUnitExtension->HwLogicalUnitExtension =
            (PVOID) (logicalUnitExtension + 1);

        logicalUnitExtension->AdapterExtension = deviceExtension;

        //
        // Give the caller the benefit of the doubt.
        //

        logicalUnitExtension->IsMissing = FALSE;

        //
        // The device cannot have been enumerated yet.
        //

        logicalUnitExtension->IsEnumerated = FALSE;

        //
        // Set timer counters to -1 to inidicate that there are no outstanding
        // requests.
        //

        logicalUnitExtension->RequestTimeoutCounter = -1;

        //
        // Initialize the maximum queue depth size.
        //

        logicalUnitExtension->MaxQueueDepth = 0xFF;

        //
        // Initialize the request list.
        //

        InitializeListHead(&logicalUnitExtension->RequestList);

        //
        // Initialize the push/pop list of SRB_DATA blocks for use with bypass
        // requests.
        //

        KeInitializeSpinLock(&(logicalUnitExtension->BypassSrbDataSpinLock));
        ExInitializeSListHead(&(logicalUnitExtension->BypassSrbDataList));
        for(i = 0; i < NUMBER_BYPASS_SRB_DATA_BLOCKS; i++) {
            ExInterlockedPushEntrySList(
                &(logicalUnitExtension->BypassSrbDataList),
                &(logicalUnitExtension->BypassSrbDataBlocks[i].Reserved),
                &(logicalUnitExtension->BypassSrbDataSpinLock));
        }

        //
        // Assume devices are powered on by default.
        //

        commonExtension->CurrentDeviceState = PowerDeviceD0;
        commonExtension->DesiredDeviceState = PowerDeviceUnspecified;

        //
        // Assume that we're being initialized in a working system.
        //

        commonExtension->CurrentSystemState = PowerSystemWorking;

        //
        // Set the pnp state to unknown.
        //

        commonExtension->CurrentPnpState = 0xff;
        commonExtension->PreviousPnpState = 0xff;

        //
        // Setup the request sense resources.
        //

        logicalUnitExtension->RequestSenseIrp = senseIrp;
        KeInitializeSpinLock(&(logicalUnitExtension->RequestSenseLock));

        //
        // Link the device into the list of physical device objects
        //

        SpAddLogicalUnitToBin(deviceExtension, logicalUnitExtension);

        //
        // I guess this is as ready to be opened as it ever will be.
        //

        pdo->Flags &= ~DO_DEVICE_INITIALIZING;

    } else {

        DebugPrint((1, "ScsiBusCreatePdo: Error %#08lx creating device object\n",
                       status));
        pdo = NULL;
    }

    *NewPdo = pdo;

    return status;
}
Esempio n. 5
0
VOID
NbiProcessDatagram(
    IN NDIS_HANDLE MacBindingHandle,
    IN NDIS_HANDLE MacReceiveContext,
    IN PIPX_LOCAL_TARGET RemoteAddress,
    IN ULONG MacOptions,
    IN PUCHAR LookaheadBuffer,
    IN UINT LookaheadBufferSize,
    IN UINT LookaheadBufferOffset,
    IN UINT PacketSize,
    IN BOOLEAN Broadcast
    )

/*++

Routine Description:

    This routine handles datagram indications.

Arguments:

    MacBindingHandle - A handle to use when calling NdisTransferData.

    MacReceiveContext - A context to use when calling NdisTransferData.

    RemoteAddress - The local target this packet was received from.

    MacOptions - The MAC options for the underlying NDIS binding.

    LookaheadBuffer - The lookahead buffer, starting at the IPX
        header.

    LookaheadBufferSize - The length of the lookahead data.

    LookaheadBufferOffset - The offset to add when calling
        NdisTransferData.

    PacketSize - The total length of the packet, starting at the
        IPX header.

    Broadcast - TRUE if the frame was a broadcast datagram.

Return Value:

    None.

--*/

{

    PADDRESS Address;
    NDIS_STATUS NdisStatus;
    PUCHAR NetbiosName;
    NB_CONNECTIONLESS UNALIGNED * Connectionless =
                        (NB_CONNECTIONLESS UNALIGNED *)LookaheadBuffer;
    PDEVICE Device = NbiDevice;
    PSINGLE_LIST_ENTRY s;
    PNB_RECEIVE_RESERVED ReceiveReserved;
    PNB_RECEIVE_BUFFER ReceiveBuffer;
    ULONG DataOffset;
    UINT BytesTransferred;
    PNDIS_PACKET Packet;
    CTELockHandle   LockHandle;


    //
    // See if there is an address that might want this.
    //

    if (Broadcast) {
        NetbiosName = (PVOID)-1;
    } else {
        NetbiosName = (PUCHAR)Connectionless->Datagram.DestinationName;
        if (Device->AddressCounts[NetbiosName[0]] == 0) {
            return;
        }
    }

    DataOffset = sizeof(IPX_HEADER) + sizeof(NB_DATAGRAM);

#if     defined(_PNP_POWER)
    if ((PacketSize < DataOffset) ||
        (PacketSize > DataOffset + Device->CurMaxReceiveBufferSize)) {
#else
        if ((PacketSize < DataOffset) ||
            (PacketSize > DataOffset + Device->Bind.LineInfo.MaximumPacketSize)) {
#endif  _PNP_POWER

        NB_DEBUG (DATAGRAM, ("Datagram length %d discarded\n", PacketSize));
        return;
    }

    Address = NbiFindAddress (Device, NetbiosName);

    if (Address == NULL) {
        return;
    }

    //
    // We need to cache the remote name if the packet came across the router.
    // This allows this machine to get back to the RAS client which might
    // have sent this datagram. We currently dont allow broadcasts to go out
    // on the dial-in line.
    // Dont cache some of the widely used group names, that would be too much
    // to store in cache.
    //

#if 0
    if ( Connectionless->IpxHeader.TransportControl &&
         !( (Address->NetbiosAddress.NetbiosName[15] == 0x0 ) &&
            (Address->NetbiosAddress.NetbiosNameType & TDI_ADDRESS_NETBIOS_TYPE_GROUP))  &&
         !( (Address->NetbiosAddress.NetbiosName[15] == 0x01 ) &&
            (Address->NetbiosAddress.NetbiosNameType & TDI_ADDRESS_NETBIOS_TYPE_GROUP))  &&
         !( (Address->NetbiosAddress.NetbiosName[15] == 0x1E ) &&
            (Address->NetbiosAddress.NetbiosNameType & TDI_ADDRESS_NETBIOS_TYPE_GROUP))  ) {
#endif
    if ( Connectionless->IpxHeader.TransportControl &&
         ( (Address->NetbiosAddress.NetbiosName[15] == 0x1c ) &&
           (Address->NetbiosAddress.NetbiosNameType & TDI_ADDRESS_NETBIOS_TYPE_GROUP))  ) {

        PNETBIOS_CACHE CacheName;

        NB_GET_LOCK (&Device->Lock, &LockHandle);
        if ( FindInNetbiosCacheTable ( Device->NameCache,
                                       Connectionless->Datagram.SourceName,
                                       &CacheName ) != STATUS_SUCCESS ) {

            CacheName = NbiAllocateMemory (sizeof(NETBIOS_CACHE), MEMORY_CACHE, "Cache Entry");
            if (CacheName ) {
                RtlCopyMemory (CacheName->NetbiosName, Connectionless->Datagram.SourceName, 16);
                CacheName->Unique = TRUE;
                CacheName->ReferenceCount = 1;
                RtlCopyMemory (&CacheName->FirstResponse, Connectionless->IpxHeader.SourceNetwork, 12);
                CacheName->NetworksAllocated = 1;
                CacheName->NetworksUsed = 1;
                CacheName->Networks[0].Network = *(UNALIGNED ULONG *)(Connectionless->IpxHeader.SourceNetwork);
                CacheName->Networks[0].LocalTarget = *RemoteAddress;
                NB_DEBUG2 (CACHE, ("Alloc new cache from Datagram %lx for <%.16s>\n",
                                        CacheName, CacheName->NetbiosName));

                CacheName->TimeStamp = Device->CacheTimeStamp;

                InsertInNetbiosCacheTable(
                    Device->NameCache,
                    CacheName);

            }
        } else if ( CacheName->Unique ) {
            //
            // We already have an entry for this remote. We should update
            // the address. This is so that if the ras client dials-out
            // then dials-in again and gets a new address, we dont end up
            // caching the old address.
            //
            if ( !RtlEqualMemory( &CacheName->FirstResponse, Connectionless->IpxHeader.SourceNetwork, 12) ) {

                RtlCopyMemory (&CacheName->FirstResponse, Connectionless->IpxHeader.SourceNetwork, 12);
                CacheName->Networks[0].Network = *(UNALIGNED ULONG *)(Connectionless->IpxHeader.SourceNetwork);
                CacheName->Networks[0].LocalTarget = *RemoteAddress;

            }
        }
        NB_FREE_LOCK (&Device->Lock, LockHandle);
    }

    //
    // We need to allocate a packet and buffer for the transfer.
    //

    s = NbiPopReceivePacket (Device);
    if (s == NULL) {
        NbiDereferenceAddress (Address, AREF_FIND);
        return;
    }

    ReceiveReserved = CONTAINING_RECORD (s, NB_RECEIVE_RESERVED, PoolLinkage);


    s = NbiPopReceiveBuffer (Device);
    if (s == NULL) {
        ExInterlockedPushEntrySList(
            &Device->ReceivePacketList,
            &ReceiveReserved->PoolLinkage,
            &NbiGlobalPoolInterlock);
        NbiDereferenceAddress (Address, AREF_FIND);
        return;
    }

    ReceiveBuffer = CONTAINING_RECORD (s, NB_RECEIVE_BUFFER, PoolLinkage);

    Packet = CONTAINING_RECORD (ReceiveReserved, NDIS_PACKET, ProtocolReserved[0]);
    ReceiveReserved->u.RR_DG.ReceiveBuffer = ReceiveBuffer;


    //
    // Now that we have a packet and a buffer, set up the transfer.
    // The indication to the TDI clients will happen at receive
    // complete time.
    //

    NdisChainBufferAtFront (Packet, ReceiveBuffer->NdisBuffer);
    ReceiveBuffer->Address = Address;

    ReceiveReserved->Type = RECEIVE_TYPE_DATAGRAM;
    CTEAssert (!ReceiveReserved->TransferInProgress);
    ReceiveReserved->TransferInProgress = TRUE;

    TdiCopyLookaheadData(
        &ReceiveBuffer->RemoteName,
        Connectionless->Datagram.SourceName,
        16,
        (MacOptions & NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA) ? TDI_RECEIVE_COPY_LOOKAHEAD : 0);

    (*Device->Bind.TransferDataHandler) (
        &NdisStatus,
        MacBindingHandle,
        MacReceiveContext,
        LookaheadBufferOffset + DataOffset,
        PacketSize - DataOffset,
        Packet,
        &BytesTransferred);

    if (NdisStatus != NDIS_STATUS_PENDING) {
#if DBG
        if (NdisStatus == STATUS_SUCCESS) {
            CTEAssert (BytesTransferred == PacketSize - DataOffset);
        }
#endif

        NbiTransferDataComplete(
            Packet,
            NdisStatus,
            BytesTransferred);

    }

}   /* NbiProcessDatagram */


VOID
NbiIndicateDatagram(
    IN PADDRESS Address,
    IN PUCHAR RemoteName,
    IN PUCHAR Data,
    IN ULONG DataLength
    )

/*++

Routine Description:

    This routine indicates a datagram to clients on the specified
    address. It is called from NbiReceiveComplete.

Arguments:

    Address - The address the datagram was sent to.

    RemoteName - The source netbios address of the datagram.

    Data - The data.

    DataLength - The length of the data.

Return Value:

    None.

--*/

{
    PLIST_ENTRY p, q;
    PIRP Irp;
    ULONG IndicateBytesCopied;
    PREQUEST Request;
    TA_NETBIOS_ADDRESS SourceName;
    PTDI_CONNECTION_INFORMATION RemoteInformation;
    PADDRESS_FILE AddressFile, ReferencedAddressFile;
    PTDI_CONNECTION_INFORMATION DatagramInformation;
    TDI_ADDRESS_NETBIOS UNALIGNED * DatagramAddress;
    PDEVICE Device = NbiDevice;
    NB_DEFINE_LOCK_HANDLE (LockHandle)
    CTELockHandle   CancelLH;

    //
    // Update our statistics.
    //

    ++Device->Statistics.DatagramsReceived;
    ADD_TO_LARGE_INTEGER(
        &Device->Statistics.DatagramBytesReceived,
        DataLength);

    //
    // Call the client's ReceiveDatagram indication handler.  He may
    // want to accept the datagram that way.
    //

    TdiBuildNetbiosAddress (RemoteName, FALSE, &SourceName);
    ReferencedAddressFile = NULL;

    NB_SYNC_GET_LOCK (&Address->Lock, &LockHandle);

    for (p = Address->AddressFileDatabase.Flink;
         p != &Address->AddressFileDatabase;
         p = p->Flink) {

        //
        // Find the next open address file in the list.
        //

        AddressFile = CONTAINING_RECORD (p, ADDRESS_FILE, Linkage);
        if (AddressFile->State != ADDRESSFILE_STATE_OPEN) {
            continue;
        }

        NbiReferenceAddressFileLock (AddressFile, AFREF_INDICATION);

        //
        // do we have a datagram receive request outstanding? If so, we will
        // satisfy it first. We run through the receive datagram queue
        // until we find a datagram with no remote address or with
        // this sender's address as its remote address.
        //

        for (q = AddressFile->ReceiveDatagramQueue.Flink;
             q != &AddressFile->ReceiveDatagramQueue;
             q = q->Flink) {

            Request = LIST_ENTRY_TO_REQUEST (q);
            DatagramInformation = ((PTDI_REQUEST_KERNEL_RECEIVEDG)
                REQUEST_PARAMETERS(Request))->ReceiveDatagramInformation;

            if (DatagramInformation &&
                (DatagramInformation->RemoteAddress) &&
                (DatagramAddress = NbiParseTdiAddress(DatagramInformation->RemoteAddress, FALSE)) &&
                (!RtlEqualMemory(
                    RemoteName,
                    DatagramAddress->NetbiosName,
                    16))) {
                continue;
            }
            break;
        }

        if (q != &AddressFile->ReceiveDatagramQueue) {

            RemoveEntryList (q);
            NB_SYNC_FREE_LOCK (&Address->Lock, LockHandle);

            if (ReferencedAddressFile != NULL) {
                NbiDereferenceAddressFile (ReferencedAddressFile, AFREF_INDICATION);
            }
            ReferencedAddressFile = AddressFile;

            //
            // Do this deref now, we hold another one so it
            // will stick around.
            //

            NbiDereferenceAddressFile (AddressFile, AFREF_RCV_DGRAM);

            IndicateBytesCopied = 0;

            //
            // Fall past the else to copy the data.
            //

        } else {

            NB_SYNC_FREE_LOCK (&Address->Lock, LockHandle);

            if (ReferencedAddressFile != NULL) {
                NbiDereferenceAddressFile (ReferencedAddressFile, AFREF_INDICATION);
            }
            ReferencedAddressFile = AddressFile;

            //
            // No receive datagram requests; is there a kernel client?
            //

            if (AddressFile->RegisteredHandler[TDI_EVENT_RECEIVE_DATAGRAM]) {

                IndicateBytesCopied = 0;

                if ((*AddressFile->ReceiveDatagramHandler)(
                         AddressFile->HandlerContexts[TDI_EVENT_RECEIVE_DATAGRAM],
                         sizeof (TA_NETBIOS_ADDRESS),
                         &SourceName,
                         0,
                         NULL,
                         TDI_RECEIVE_COPY_LOOKAHEAD,
                         DataLength,      // indicated
                         DataLength,     // available
                         &IndicateBytesCopied,
                         Data,
                         &Irp) != STATUS_MORE_PROCESSING_REQUIRED) {

                    //
                    // The client did not return a request, go to the
                    // next address file.
                    //

                    NB_SYNC_GET_LOCK (&Address->Lock, &LockHandle);
                    continue;

                }

                Request = NbiAllocateRequest (Device, Irp);

                IF_NOT_ALLOCATED(Request) {
                    Irp->IoStatus.Information = 0;
                    Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                    IoCompleteRequest (Irp, IO_NETWORK_INCREMENT);


                    NB_SYNC_GET_LOCK (&Address->Lock, &LockHandle);
                    continue;
                }

            } else {

                //
                // The client has nothing posted and no handler,
                // go on to the next address file.
                //

                NB_SYNC_GET_LOCK (&Address->Lock, &LockHandle);
                continue;

            }

        }

        //
        // We have a request; copy the actual user data.
        //
        if ( REQUEST_NDIS_BUFFER (Request) ) {

            REQUEST_STATUS(Request) =
                TdiCopyBufferToMdl (
                         Data,
                         IndicateBytesCopied,
                         DataLength - IndicateBytesCopied,
                         REQUEST_NDIS_BUFFER (Request),
                         0,
                         &REQUEST_INFORMATION (Request));

        } else {
            //
            // No buffer specified in the request
            //
            REQUEST_INFORMATION (Request) = 0;
            //
            // If there was any data to be copied, return error o/w success
            //
            REQUEST_STATUS(Request) = ( (DataLength - IndicateBytesCopied) ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS );
        }

        //
        // Copy the addressing information.
        //

        RemoteInformation = ((PTDI_REQUEST_KERNEL_RECEIVEDG)
                REQUEST_PARAMETERS(Request))->ReturnDatagramInformation;

        if (RemoteInformation != NULL) {

            RtlCopyMemory(
                (PTA_NETBIOS_ADDRESS)RemoteInformation->RemoteAddress,
                &SourceName,
                (RemoteInformation->RemoteAddressLength < sizeof(TA_NETBIOS_ADDRESS)) ?
                    RemoteInformation->RemoteAddressLength : sizeof(TA_NETBIOS_ADDRESS));
        }


        NB_GET_CANCEL_LOCK( &CancelLH );
        IoSetCancelRoutine (Request, (PDRIVER_CANCEL)NULL);
        NB_FREE_CANCEL_LOCK( CancelLH );

        NbiCompleteRequest (Request);
        NbiFreeRequest (Device, Request);

        NB_SYNC_GET_LOCK (&Address->Lock, &LockHandle);

    }    // end of for loop through the address files