Exemplo n.º 1
0
VOID
NbfWriteSingleParameter(
    IN HANDLE ParametersHandle,
    IN PWCHAR ValueName,
    IN ULONG ValueData
    )

/*++

Routine Description:

    This routine is called by NBF to write a single parameter
    from the registry.

Arguments:

    ParametersHandle - A pointer to the open registry.

    ValueName - The name of the value to store.

    ValueData - The data to store at the value.

Return Value:

    None.

--*/

{
    UNICODE_STRING ValueKeyName;
    NTSTATUS Status;
    ULONG TmpValueData = ValueData;

    RtlInitUnicodeString (&ValueKeyName, ValueName);

    Status = ZwSetValueKey(
                 ParametersHandle,
                 &ValueKeyName,
                 0,
                 REG_DWORD,
                 (PVOID)&TmpValueData,
                 sizeof(ULONG));

    if (!NT_SUCCESS(Status)) {
        NbfPrint1("NBF: Could not write dword key: %lx\n", Status);
    }

}   /* NbfWriteSingleParameter */
Exemplo n.º 2
0
NTSTATUS
NbfOpenParametersKey(
    IN HANDLE NbfConfigHandle,
    OUT PHANDLE ParametersHandle
    )

/*++

Routine Description:

    This routine is called by NBF to open the NBF "Parameters" key.

Arguments:

    ParametersHandle - Returns the handle used to read parameters.

Return Value:

    The status of the request.

--*/
{

    NTSTATUS Status;
    HANDLE ParamHandle;
    PWSTR ParametersString = L"Parameters";
    UNICODE_STRING ParametersKeyName;
    OBJECT_ATTRIBUTES TmpObjectAttributes;

    //
    // Open the NBF parameters key.
    //

    RtlInitUnicodeString (&ParametersKeyName, ParametersString);

    InitializeObjectAttributes(
        &TmpObjectAttributes,
        &ParametersKeyName,         // name
        OBJ_CASE_INSENSITIVE,       // attributes
        NbfConfigHandle,            // root
        NULL                        // security descriptor
        );


    Status = ZwOpenKey(
                 &ParamHandle,
                 KEY_READ,
                 &TmpObjectAttributes);

    if (!NT_SUCCESS(Status)) {

        NbfPrint1("Could not open parameters key: %lx\n", Status);
        return Status;

    }

    IF_NBFDBG (NBF_DEBUG_REGISTRY) {
        NbfPrint1("Opened parameters key: %lx\n", ParamHandle);
    }


    *ParametersHandle = ParamHandle;


    //
    // All keys successfully opened or created.
    //

    return STATUS_SUCCESS;

}   /* NbfOpenParametersKey */
Exemplo n.º 3
0
NTSTATUS
NbfConfigureTransport (
    IN PUNICODE_STRING RegistryPath,
    IN PCONFIG_DATA * ConfigurationInfoPtr
    )
/*++

Routine Description:

    This routine is called by NBF to get information from the configuration
    management routines. We read the registry, starting at RegistryPath,
    to get the parameters. If they don't exist, we use the defaults
    set in nbfcnfg.h file.

Arguments:

    RegistryPath - The name of NBF's node in the registry.

    ConfigurationInfoPtr - A pointer to the configuration information structure.

Return Value:

    Status - STATUS_SUCCESS if everything OK, STATUS_INSUFFICIENT_RESOURCES
            otherwise.

--*/
{

    NTSTATUS OpenStatus;
    HANDLE ParametersHandle;
    HANDLE NbfConfigHandle;
    NTSTATUS Status;
    ULONG Disposition;
    PWSTR RegistryPathBuffer;
    OBJECT_ATTRIBUTES TmpObjectAttributes;
    PCONFIG_DATA ConfigurationInfo;

    DECLARE_STRING(InitRequests);
    DECLARE_STRING(InitLinks);
    DECLARE_STRING(InitConnections);
    DECLARE_STRING(InitAddressFiles);
    DECLARE_STRING(InitAddresses);

    DECLARE_STRING(MaxRequests);
    DECLARE_STRING(MaxLinks);
    DECLARE_STRING(MaxConnections);
    DECLARE_STRING(MaxAddressFiles);
    DECLARE_STRING(MaxAddresses);

    DECLARE_STRING(InitPackets);
    DECLARE_STRING(InitReceivePackets);
    DECLARE_STRING(InitReceiveBuffers);
    DECLARE_STRING(InitUIFrames);

    DECLARE_STRING(SendPacketPoolSize);
    DECLARE_STRING(ReceivePacketPoolSize);
    DECLARE_STRING(MaxMemoryUsage);

    DECLARE_STRING(MinimumT1Timeout);
    DECLARE_STRING(DefaultT1Timeout);
    DECLARE_STRING(DefaultT2Timeout);
    DECLARE_STRING(DefaultTiTimeout);
    DECLARE_STRING(LlcRetries);
    DECLARE_STRING(LlcMaxWindowSize);
    DECLARE_STRING(MaximumIncomingFrames);

    DECLARE_STRING(NameQueryRetries);
    DECLARE_STRING(NameQueryTimeout);
    DECLARE_STRING(AddNameQueryRetries);
    DECLARE_STRING(AddNameQueryTimeout);
    DECLARE_STRING(GeneralRetries);
    DECLARE_STRING(GeneralTimeout);
    DECLARE_STRING(WanNameQueryRetries);

    DECLARE_STRING(UseDixOverEthernet);
    DECLARE_STRING(QueryWithoutSourceRouting);
    DECLARE_STRING(AllRoutesNameRecognized);
    DECLARE_STRING(MinimumSendWindowLimit);

    //
    // Open the registry.
    //

    InitializeObjectAttributes(
        &TmpObjectAttributes,
        RegistryPath,               // name
        OBJ_CASE_INSENSITIVE,       // attributes
        NULL,                       // root
        NULL                        // security descriptor
        );

    Status = ZwCreateKey(
                 &NbfConfigHandle,
                 KEY_WRITE,
                 &TmpObjectAttributes,
                 0,                 // title index
                 NULL,              // class
                 0,                 // create options
                 &Disposition);     // disposition

    if (!NT_SUCCESS(Status)) {
        NbfPrint1("NBF: Could not open/create NBF key: %lx\n", Status);
        return Status;
    }

    IF_NBFDBG (NBF_DEBUG_REGISTRY) {
        NbfPrint2("%s NBF key: %lx\n",
            (Disposition == REG_CREATED_NEW_KEY) ? "created" : "opened",
            NbfConfigHandle);
    }


    OpenStatus = NbfOpenParametersKey (NbfConfigHandle, &ParametersHandle);

    if (OpenStatus != STATUS_SUCCESS) {
        return OpenStatus;
    }

    //
    // Read in the NDIS binding information (if none is present
    // the array will be filled with all known drivers).
    //
    // NbfReadLinkageInformation expects a null-terminated path,
    // so we have to create one from the UNICODE_STRING.
    //

    RegistryPathBuffer = (PWSTR)ExAllocatePoolWithTag(
                                    NonPagedPool,
                                    RegistryPath->Length + sizeof(WCHAR),
                                    NBF_MEM_TAG_REGISTRY_PATH);
    if (RegistryPathBuffer == NULL) {
        NbfCloseParametersKey (ParametersHandle);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlCopyMemory (RegistryPathBuffer, RegistryPath->Buffer, RegistryPath->Length);
    *(PWCHAR)(((PUCHAR)RegistryPathBuffer)+RegistryPath->Length) = (WCHAR)'\0';

    NbfReadLinkageInformation (RegistryPathBuffer, ConfigurationInfoPtr);

    if (*ConfigurationInfoPtr == NULL) {
        ExFreePool (RegistryPathBuffer);
        NbfCloseParametersKey (ParametersHandle);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    ConfigurationInfo = *ConfigurationInfoPtr;


    //
    // Configure the initial values for some NBF resources.
    //

    ConfigurationInfo->InitRequests = 1;
    ConfigurationInfo->InitLinks = 2;
    ConfigurationInfo->InitConnections = 2;
    ConfigurationInfo->InitAddressFiles = 0;
    ConfigurationInfo->InitAddresses = 0;

    //
    // These are the initial values; remember that the
    // resources above also allocate some of these each
    // time they are allocated (shown in the comment).
    //

    ConfigurationInfo->InitPackets = 30;         // + link + 2*conn
    ConfigurationInfo->InitReceivePackets = 10;  // + link + addr
    ConfigurationInfo->InitReceiveBuffers = 5;   // + addr
    ConfigurationInfo->InitUIFrames = 5;         // + addr + conn

    //
    // Set the size of the packet pools and the total
    // allocateable by NBF.
    //

    ConfigurationInfo->SendPacketPoolSize = 100;
    ConfigurationInfo->ReceivePacketPoolSize = 30;
    ConfigurationInfo->MaxMemoryUsage = 0;       // no limit


    //
    // Now initialize the timeout etc. values.
    //
    
    ConfigurationInfo->MinimumT1Timeout = DLC_MINIMUM_T1;
    ConfigurationInfo->DefaultT1Timeout = DLC_DEFAULT_T1;
    ConfigurationInfo->DefaultT2Timeout = DLC_DEFAULT_T2;
    ConfigurationInfo->DefaultTiTimeout = DLC_DEFAULT_TI;
    ConfigurationInfo->LlcRetries = DLC_RETRIES;
    ConfigurationInfo->LlcMaxWindowSize = DLC_WINDOW_LIMIT;
    ConfigurationInfo->MaximumIncomingFrames = 4;
    ConfigurationInfo->NameQueryRetries = NAME_QUERY_RETRIES;
    ConfigurationInfo->NameQueryTimeout = NAME_QUERY_TIMEOUT;
    ConfigurationInfo->AddNameQueryRetries = ADD_NAME_QUERY_RETRIES;
    ConfigurationInfo->AddNameQueryTimeout = ADD_NAME_QUERY_TIMEOUT;
    ConfigurationInfo->GeneralRetries = NAME_QUERY_RETRIES;
    ConfigurationInfo->GeneralTimeout = NAME_QUERY_TIMEOUT;
    ConfigurationInfo->WanNameQueryRetries = WAN_NAME_QUERY_RETRIES;

    ConfigurationInfo->UseDixOverEthernet = 0;
    ConfigurationInfo->QueryWithoutSourceRouting = 0;
    ConfigurationInfo->AllRoutesNameRecognized = 0;
    ConfigurationInfo->MinimumSendWindowLimit = 2;


    //
    // Now read the optional "hidden" parameters; if these do
    // not exist then the current values are used. Note that
    // the current values will be 0 unless they have been
    // explicitly initialized above.
    //
    // NOTE: These macros expect "ConfigurationInfo" and
    // "ParametersHandle" to exist when they are expanded.
    //

    READ_HIDDEN_CONFIG (InitRequests);
    READ_HIDDEN_CONFIG (InitLinks);
    READ_HIDDEN_CONFIG (InitConnections);
    READ_HIDDEN_CONFIG (InitAddressFiles);
    READ_HIDDEN_CONFIG (InitAddresses);

    READ_HIDDEN_CONFIG (MaxRequests);
    READ_HIDDEN_CONFIG (MaxLinks);
    READ_HIDDEN_CONFIG (MaxConnections);
    READ_HIDDEN_CONFIG (MaxAddressFiles);
    READ_HIDDEN_CONFIG (MaxAddresses);

    READ_HIDDEN_CONFIG (InitPackets);
    READ_HIDDEN_CONFIG (InitReceivePackets);
    READ_HIDDEN_CONFIG (InitReceiveBuffers);
    READ_HIDDEN_CONFIG (InitUIFrames);

    READ_HIDDEN_CONFIG (SendPacketPoolSize);
    READ_HIDDEN_CONFIG (ReceivePacketPoolSize);
    READ_HIDDEN_CONFIG (MaxMemoryUsage);

    READ_HIDDEN_CONFIG (MinimumT1Timeout);
    READ_HIDDEN_CONFIG (DefaultT1Timeout);
    READ_HIDDEN_CONFIG (DefaultT2Timeout);
    READ_HIDDEN_CONFIG (DefaultTiTimeout);
    READ_HIDDEN_CONFIG (LlcRetries);
    READ_HIDDEN_CONFIG (LlcMaxWindowSize);
    READ_HIDDEN_CONFIG (MaximumIncomingFrames);

    READ_HIDDEN_CONFIG (NameQueryRetries);
    READ_HIDDEN_CONFIG (NameQueryTimeout);
    READ_HIDDEN_CONFIG (AddNameQueryRetries);
    READ_HIDDEN_CONFIG (AddNameQueryTimeout);
    READ_HIDDEN_CONFIG (GeneralRetries);
    READ_HIDDEN_CONFIG (GeneralTimeout);
    READ_HIDDEN_CONFIG (WanNameQueryRetries);

    READ_HIDDEN_CONFIG (UseDixOverEthernet);
    READ_HIDDEN_CONFIG (QueryWithoutSourceRouting);
    READ_HIDDEN_CONFIG (AllRoutesNameRecognized);
    READ_HIDDEN_CONFIG (MinimumSendWindowLimit);


    //
    // Print out some config info, to make sure it is read right.
    //

    IF_NBFDBG (NBF_DEBUG_REGISTRY) {
       NbfPrint2("Links: init %d, max %d\n",
                     ConfigurationInfo->InitLinks,
                     ConfigurationInfo->MaxLinks);
       NbfPrint3("Timeouts (NBF ticks): T1 %d, T2 %d, Ti %d\n",
                     ConfigurationInfo->DefaultT1Timeout / SHORT_TIMER_DELTA,
                     ConfigurationInfo->DefaultT2Timeout / SHORT_TIMER_DELTA,
                     ConfigurationInfo->DefaultTiTimeout / LONG_TIMER_DELTA);
       NbfPrint2("Pools: send %d, receive %d\n",
                     ConfigurationInfo->SendPacketPoolSize,
                     ConfigurationInfo->ReceivePacketPoolSize);
       NbfPrint1("Max mem %d\n",
                     ConfigurationInfo->MaxMemoryUsage);
       NbfPrint2("NQRetries %d, NQTimeout %d\n",
                     ConfigurationInfo->NameQueryRetries,
                     ConfigurationInfo->NameQueryTimeout / SHORT_TIMER_DELTA);
    }

    //
    // Save the "hidden" parameters, these may not exist in
    // the registry.
    //
    // NOTE: These macros expect "ConfigurationInfo" and
    // "ParametersHandle" to exist when they are expanded.
    //

    //
    // 5/22/92 - don't write the parameters that are set
    // based on Size, since otherwise these will overwrite
    // those values since hidden parameters are set up
    // after the Size-based configuration is done.
    //

    WRITE_HIDDEN_CONFIG (MaxRequests);
    WRITE_HIDDEN_CONFIG (MaxLinks);
    WRITE_HIDDEN_CONFIG (MaxConnections);
    WRITE_HIDDEN_CONFIG (MaxAddressFiles);
    WRITE_HIDDEN_CONFIG (MaxAddresses);

    WRITE_HIDDEN_CONFIG (MinimumT1Timeout);
    WRITE_HIDDEN_CONFIG (DefaultT1Timeout);
    WRITE_HIDDEN_CONFIG (DefaultT2Timeout);
    WRITE_HIDDEN_CONFIG (DefaultTiTimeout);
    WRITE_HIDDEN_CONFIG (LlcRetries);
    WRITE_HIDDEN_CONFIG (LlcMaxWindowSize);
    WRITE_HIDDEN_CONFIG (MaximumIncomingFrames);

    WRITE_HIDDEN_CONFIG (NameQueryRetries);
    WRITE_HIDDEN_CONFIG (NameQueryTimeout);
    WRITE_HIDDEN_CONFIG (AddNameQueryRetries);
    WRITE_HIDDEN_CONFIG (AddNameQueryTimeout);
    WRITE_HIDDEN_CONFIG (GeneralRetries);
    WRITE_HIDDEN_CONFIG (GeneralTimeout);
    WRITE_HIDDEN_CONFIG (WanNameQueryRetries);

    WRITE_HIDDEN_CONFIG (UseDixOverEthernet);
    WRITE_HIDDEN_CONFIG (QueryWithoutSourceRouting);
    WRITE_HIDDEN_CONFIG (AllRoutesNameRecognized);

    // ZwFlushKey (ParametersHandle);

    ExFreePool (RegistryPathBuffer);
    NbfCloseParametersKey (ParametersHandle);
    ZwClose (NbfConfigHandle);

    return STATUS_SUCCESS;

}   /* NbfConfigureTransport */
Exemplo n.º 4
0
NTSTATUS
NbfGetExportNameFromRegistry(
    IN  PUNICODE_STRING RegistryPath,
    IN  PUNICODE_STRING BindName,
    OUT PUNICODE_STRING ExportName
    )
{
    NTSTATUS OpenStatus;
    HANDLE ParametersHandle;
    HANDLE NbfConfigHandle;
    NTSTATUS Status;
    PWSTR RegistryPathBuffer;
    OBJECT_ATTRIBUTES TmpObjectAttributes;
    
    RTL_QUERY_REGISTRY_TABLE QueryTable[3];
    PWSTR Subkey = L"Linkage";
    PWSTR Bind = L"Bind";
    PWSTR Export = L"Export";
    LONG BindNumber;

    //
    // Open the registry.
    //

    InitializeObjectAttributes(
        &TmpObjectAttributes,
        RegistryPath,               // name
        OBJ_CASE_INSENSITIVE,       // attributes
        NULL,                       // root
        NULL                        // security descriptor
        );

    OpenStatus = ZwOpenKey(
                     &NbfConfigHandle,
                     KEY_WRITE,
                     &TmpObjectAttributes
                     );

    if (!NT_SUCCESS(OpenStatus)) {
        NbfPrint1("NBF: Could not open NBF key: %lx\n", OpenStatus);
        return OpenStatus;
    }

    Status = NbfOpenParametersKey (NbfConfigHandle, &ParametersHandle);

    if (Status != STATUS_SUCCESS) {
        ZwClose (NbfConfigHandle);
        return Status;
    }

    //
    // NbfReadLinkageInformation expects a null-terminated path,
    // so we have to create one from the UNICODE_STRING.
    //

    RegistryPathBuffer = (PWSTR)ExAllocatePoolWithTag(
                                    NonPagedPool,
                                    RegistryPath->Length + sizeof(WCHAR),
                                    NBF_MEM_TAG_REGISTRY_PATH);
                                    
    if (RegistryPathBuffer == NULL) {
        NbfCloseParametersKey (ParametersHandle);
        ZwClose (NbfConfigHandle);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlCopyMemory (RegistryPathBuffer, RegistryPath->Buffer, RegistryPath->Length);
    *(PWCHAR)(((PUCHAR)RegistryPathBuffer)+RegistryPath->Length) = (WCHAR)'\0';

    //
    // We have a new device whose binding was absent 
    // at boot - get export name given the bind name
    //

    // First we need to get index of the bind name
    
    // Set up QueryTable to do the following:

    //
    // 1) Switch to the Linkage key below NBF
    //

    QueryTable[0].QueryRoutine = NULL;
    QueryTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
    QueryTable[0].Name = Subkey;

    //
    // 2) Call NbfMatchBindName for each string in "Bind"
    //

    QueryTable[1].QueryRoutine = NbfMatchBindName;
    QueryTable[1].Flags = 0;
    QueryTable[1].Name = Bind;
    QueryTable[1].EntryContext = (PVOID)&BindNumber;
    QueryTable[1].DefaultType = REG_NONE;

    //
    // 3) Stop
    //

    QueryTable[2].QueryRoutine = NULL;
    QueryTable[2].Flags = 0;
    QueryTable[2].Name = NULL;


    BindNumber = -1;

    Status = RtlQueryRegistryValues(
                 RTL_REGISTRY_ABSOLUTE,
                 RegistryPathBuffer,
                 QueryTable,
                 (PVOID)BindName,
                 NULL);

    IF_NBFDBG (NBF_DEBUG_PNP) {
        NbfPrint2 ("Status from NbfMatchBindName's = %08x, Bind Number = %d\n",
                        Status, BindNumber);
    }

    if (Status != STATUS_NO_MORE_MATCHES)
    {
#if DBG
        DbgBreakPoint();
#endif
    
        if (Status == STATUS_SUCCESS) {
        
            // We did not find the device 'bind name'
            Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
            
            IF_NBFDBG (NBF_DEBUG_PNP) {
                NbfPrint1 ("NBF - cannot find dynamic binding %S\n", BindName->Buffer);
            }
        }
Exemplo n.º 5
0
VOID
NbfTdiRequestTimeoutHandler(
    IN PKDPC Dpc,
    IN PVOID DeferredContext,
    IN PVOID SystemArgument1,
    IN PVOID SystemArgument2
    )

/*++

Routine Description:

    This routine is executed as a DPC at DISPATCH_LEVEL when a request
    such as TdiSend, TdiReceive, TdiSendDatagram, TdiReceiveDatagram, etc.,
    encounters a timeout.  This routine cleans up the activity and cancels it.

Arguments:

    Dpc - Pointer to a system DPC object.

    DeferredContext - Pointer to the TP_REQUEST block representing the
        request that has timed out.

    SystemArgument1 - Not used.

    SystemArgument2 - Not used.

Return Value:

    none.

--*/

{
    KIRQL oldirql;
    PTP_REQUEST Request;
    PTP_CONNECTION Connection;
#if DBG
    LARGE_INTEGER time, difference;
#endif
    PIO_STACK_LOCATION IrpSp;
    PTDI_REQUEST_KERNEL_QUERY_INFORMATION query;
    PDEVICE_CONTEXT DeviceContext;

    Dpc, SystemArgument1, SystemArgument2; // prevent compiler warnings

    ENTER_NBF;

    Request = (PTP_REQUEST)DeferredContext;

    IF_NBFDBG (NBF_DEBUG_REQUEST) {
        NbfPrint1 ("RequestTimeoutHandler:  Entered, Request %lx\n", Request);
    }

    ACQUIRE_SPIN_LOCK (&Request->SpinLock, &oldirql);
    Request->Flags &= ~REQUEST_FLAGS_TIMER;
    if ((Request->Flags & REQUEST_FLAGS_STOPPING) == 0) {

#if DBG
        KeQuerySystemTime (&time);
        difference.QuadPart = time.QuadPart - (Request->Time).QuadPart;
        NbfPrint1 ("RequestTimeoutHandler: Request timed out, queued for %ld seconds\n",
                difference.LowPart / SECONDS);
#endif

        //
        // find reason for timeout
        //

        IrpSp = IoGetCurrentIrpStackLocation (Request->IoRequestPacket);
        if (IrpSp->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL) {
            switch (IrpSp->MinorFunction) {

                //
                // none of these should time out.
                //

            case TDI_SEND:
            case TDI_ACCEPT:
            case TDI_SET_INFORMATION:
            case TDI_SET_EVENT_HANDLER:
            case TDI_SEND_DATAGRAM:
            case TDI_RECEIVE_DATAGRAM:
            case TDI_RECEIVE:

#if DBG
                NbfPrint1 ("RequestTimeoutHandler: Request: %lx Timed out, and shouldn't have!\n",
                        Request);
#endif
                ASSERT (FALSE);
                RELEASE_SPIN_LOCK (&Request->SpinLock, oldirql);
                NbfCompleteRequest (Request, STATUS_IO_TIMEOUT, 0);
                break;


            case TDI_LISTEN:
            case TDI_CONNECT:

#if DBG
                NbfPrint2 ("RequestTimeoutHandler:  %s Failed, Request: %lx\n",
                            IrpSp->MinorFunction == TDI_LISTEN ?
                                "Listen" :
                                IrpSp->MinorFunction == TDI_CONNECT ?
                                    "Connect" : "Disconnect",
                            Request);
#endif
                Connection = (PTP_CONNECTION)(Request->Context);
                RELEASE_SPIN_LOCK (&Request->SpinLock, oldirql);

                //
                // Since these requests are part of the connection
                // itself, we just stop the connection and the
                // request will get torn down then. If we get the
                // situation where the request times out before
                // it is queued to the connection, then the code
                // that is about to queue it will check the STOPPING
                // flag and complete it then.
                //
                // Don't stop the connection if an automatic connection
                // is in progress.
                //

#ifdef RASAUTODIAL

#if DBG
                DbgPrint("RequestTimeoutHandler: AUTOCONNECTING=0x%x\n", Connection->Flags2 & CONNECTION_FLAGS2_AUTOCONNECTING);
#endif
                if (!(Connection->Flags2 & CONNECTION_FLAGS2_AUTOCONNECTING))
                    NbfStopConnection (Connection, STATUS_IO_TIMEOUT);
                break;

#endif

            case TDI_DISCONNECT:

                //
                // We don't create requests for TDI_DISCONNECT any more.
                //

                ASSERT(FALSE);
                break;

            case TDI_QUERY_INFORMATION:

                DeviceContext = (PDEVICE_CONTEXT)IrpSp->FileObject->DeviceObject;
                query = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;

                IF_NBFDBG (NBF_DEBUG_DEVCTX) {
                    NbfPrint1 ("RequestTimeout: %lx:\n", DeviceContext);
                }

                //
                // Determine if the request is done, or if we should
                // requeue it.
                //

                --Request->Retries;

                if (Request->Retries > 0) {

                    RELEASE_SPIN_LOCK (&Request->SpinLock, oldirql);

                    //
                    // Send another packet out, and restart the timer.
                    //

                    if (query->QueryType == TDI_QUERY_FIND_NAME) {

                        NbfSendQueryFindName (
                            DeviceContext,
                            Request);

                    } else if (query->QueryType == TDI_QUERY_ADAPTER_STATUS) {

                        PUCHAR SingleSR;
                        UINT SingleSRLength;

                        //
                        // Send the STATUS_QUERY frames out as
                        // single-route source routing.
                        //
                        // On a second status query this should
                        // really be sent directed, but currently we
                        // don't record the address anywhere.
                        //

                        MacReturnSingleRouteSR(
                            &DeviceContext->MacInfo,
                            &SingleSR,
                            &SingleSRLength);

                        NbfSendStatusQuery (
                            DeviceContext,
                            Request,
                            &DeviceContext->NetBIOSAddress,
                            SingleSR,
                            SingleSRLength);

                    } else {

                        ASSERT (FALSE);

                    }

                } else {

                    RELEASE_SPIN_LOCK (&Request->SpinLock, oldirql);

                    //
                    // That's it, we retried enough, complete it.
                    //

                    ACQUIRE_SPIN_LOCK (&DeviceContext->SpinLock,&oldirql);
                    RemoveEntryList (&Request->Linkage);
                    RELEASE_SPIN_LOCK (&DeviceContext->SpinLock, oldirql);

                    if (Request->BytesWritten > 0) {

                        NbfCompleteRequest (Request, STATUS_SUCCESS, Request->BytesWritten);

                    } else {

                        NbfCompleteRequest (Request, STATUS_IO_TIMEOUT, Request->BytesWritten);

                    }


                }

                break;

            default:
#if DBG
                NbfPrint2 ("RequestTimeoutHandler:  Unknown Request Timed out, Request: %lx Type: %x\n",
                            Request, IrpSp->MinorFunction);
#endif
                RELEASE_SPIN_LOCK (&Request->SpinLock, oldirql);
                break;

            }   // end of switch

        } else {