⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 transprt.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:

            RxCeTearDownTransport(&pTransport->RxCeTransport);

            if (AttachToSystemProcess) {
                KeUnstackDetachProcess(&ApcState);
            }

            RxFreePool(pTransport);
        }
    } else {
        Status = STATUS_INVALID_PARAMETER;
    }

    return Status;
}







HANDLE MRxSmbTdiNotificationHandle = NULL;

KEVENT TdiNetStartupCompletionEvent;

LONG   TdiBindRequestsActive = 0;

BOOLEAN TdiPnpNetReadyEventReceived = FALSE;

// The TRANSPORT_BIND_CONTEXT contains the result of the priority determination
// as well as the name. The priority is used to order the transports in the order
// in which connection attempts will be made

typedef struct _TRANSPORT_BIND_CONTEXT_ {
    ULONG           Priority;
    UNICODE_STRING  TransportName;
} TRANSPORT_BIND_CONTEXT, *PTRANSPORT_BIND_CONTEXT;

VOID
SmbCeSignalNetReadyEvent()
/*++

Routine Description:

    The routine signals the net ready event if all the bind requests
    have been completed and if the net ready event has been received from TDI

Arguments:

--*/
{
    BOOLEAN SignalNetReadyEvent = FALSE;

    SmbCeAcquireSpinLock();

    if (TdiPnpNetReadyEventReceived &&
        TdiBindRequestsActive == 0) {
        SignalNetReadyEvent = TRUE;
    }

    SmbCeReleaseSpinLock();

    if (SignalNetReadyEvent) {
        KeSetEvent(
            &TdiNetStartupCompletionEvent,
            IO_NETWORK_INCREMENT,
            FALSE);
    }
}

VOID
MRxSmbpBindTransportCallback(
    IN PTRANSPORT_BIND_CONTEXT pTransportContext)
/*++

Routine Description:

    TDI calls this routine whenever a transport creates a new device object.

Arguments:

    TransportName - the name of the newly created device object

    TransportBindings - the transport bindings ( multi sz)

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;

    PSMBCE_TRANSPORT   pTransport;

    PUNICODE_STRING pTransportName;

    PAGED_CODE();

    ASSERT(IoGetCurrentProcess() == RxGetRDBSSProcess());

    pTransportName = &pTransportContext->TransportName;

    RxDbgTrace( 0, Dbg, ("MrxSmbpBindTransportCallback, Transport Name = %wZ\n", pTransportName ));

    pTransport = RxAllocatePoolWithTag(
                     NonPagedPool,
                     sizeof(SMBCE_TRANSPORT),
                     MRXSMB_TRANSPORT_POOLTAG);

    if (pTransport != NULL) {
        Status = RxCeBuildTransport(
                     &pTransport->RxCeTransport,
                     pTransportName,
                     0xffff);

        if (Status == STATUS_SUCCESS) {
            PRXCE_TRANSPORT_PROVIDER_INFO pProviderInfo;

            pProviderInfo = pTransport->RxCeTransport.pProviderInfo;

            if (!(pProviderInfo->ServiceFlags & TDI_SERVICE_CONNECTION_MODE) ||
                !(pProviderInfo->ServiceFlags & TDI_SERVICE_ERROR_FREE_DELIVERY)) {
                RxCeTearDownTransport(
                    &pTransport->RxCeTransport);

                Status = STATUS_PROTOCOL_UNREACHABLE;

                RxFreePool(pTransport);
            }
        }
    } else {
        Status = STATUS_INSUFFICIENT_RESOURCES;
    }

    if (Status == STATUS_SUCCESS) {
        // The connection capabilities match the capabilities required by the
        // SMB mini redirector. Attempt to register the local address with the
        // transport and if successful update the local transport list to include
        // this transport for future connection considerations.

        OEM_STRING   OemServerName;
        CHAR  TransportAddressBuffer[TDI_TRANSPORT_ADDRESS_LENGTH +
                          TDI_ADDRESS_LENGTH_NETBIOS];
        PTRANSPORT_ADDRESS pTransportAddress = (PTRANSPORT_ADDRESS)TransportAddressBuffer;
        PTDI_ADDRESS_NETBIOS pNetbiosAddress = (PTDI_ADDRESS_NETBIOS)pTransportAddress->Address[0].Address;

        pTransportAddress->TAAddressCount = 1;
        pTransportAddress->Address[0].AddressLength = TDI_ADDRESS_LENGTH_NETBIOS;
        pTransportAddress->Address[0].AddressType   = TDI_ADDRESS_TYPE_NETBIOS;
        pNetbiosAddress->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;

        OemServerName.MaximumLength = NETBIOS_NAME_LEN;
        OemServerName.Buffer        = pNetbiosAddress->NetbiosName;

        Status = RtlUpcaseUnicodeStringToOemString(
                     &OemServerName,
                     &SmbCeContext.ComputerName,
                     FALSE);

        if (NT_SUCCESS(Status)) {
            // Ensure that the name is always of the desired length by padding
            // white space to the end.
            RtlCopyMemory(
                &OemServerName.Buffer[OemServerName.Length],
                "                ",
                NETBIOS_NAME_LEN - OemServerName.Length);

            OemServerName.Buffer[NETBIOS_NAME_LEN - 1] = '\0';

            // Register the Transport address for this mini redirector with the connection
            // engine.

            Status = RxCeBuildAddress(
                        &pTransport->RxCeAddress,
                        &pTransport->RxCeTransport,
                        pTransportAddress,
                        &MRxSmbVctAddressEventHandler,
                        &SmbCeContext);

            if (Status == STATUS_SUCCESS) {
                RxDbgTrace( 0, Dbg, ("MRxSmbTransportUpdateHandler: Adding new transport\n"));

                pTransport->Active       = TRUE;
                pTransport->Priority     = pTransportContext->Priority;
                pTransport->SwizzleCount = 0;

                pTransport->ObjectCategory = SMB_SERVER_TRANSPORT_CATEGORY;
                pTransport->ObjectType     = SMBCEDB_OT_TRANSPORT;
                pTransport->State          = 0;
                pTransport->Flags          = 0;

                SmbCeAddTransport(pTransport);
                RxDbgTrace( 0, Dbg, ("MrxSmbpBindTransportCallback, Transport %wZ added\n", pTransportName ));
            } else {
                RxDbgTrace( 0, Dbg, ("MRxSmbTransportUpdateHandler: Address registration failed %lx\n",Status));
            }
        }

        if (Status != STATUS_SUCCESS) {
            RxDbgTrace( 0, Dbg, ("MrxSmbpBindTransportCallback, Transport %wZ unreachable 0x%x\n",
                                 pTransportName, Status ));
            RxCeTearDownTransport(
                &pTransport->RxCeTransport);

            Status = STATUS_PROTOCOL_UNREACHABLE;
            RxFreePool(pTransport);
        }
    }

    InterlockedDecrement(&TdiBindRequestsActive);
    SmbCeSignalNetReadyEvent();
}

VOID
MRxSmbpBindTransportWorkerThreadRoutine(
    IN PTRANSPORT_BIND_CONTEXT pTransportContext)
/*++

Routine Description:

    The TDI callbacks always do not occur in the context of the FSP process.
    Since there are a few TDi interfaces that accept handles we need to ensure
    that such calls always gets funnelled back to the FSP.

Arguments:

    pTransportContext - the transport binding context

--*/
{
    PAGED_CODE();

    MRxSmbpBindTransportCallback(pTransportContext);

    RxFreePool(pTransportContext);
}

VOID
MRxSmbpUnbindTransportCallback(
    PSMBCE_TRANSPORT pTransport)
/*++

Routine Description:

    The Unbind callback routine which is always executed in the context of the
    RDR process so that handles can be closed correctly

Arguments:

    pTransport - the transport for which the PNP_OP_DEL was received

Notes:

    On entry to this routine the appropriate transport must have been referenced
    This routine will dereference it and invalidate the existing exchanges using
    this transport.

--*/
{
    PAGED_CODE();

    // Remove this transport from the list of transports under consideration
    // in the mini redirector.

    SmbCeRemoveTransport(pTransport);

    // Enumerate the servers and mark those servers utilizing this transport
    // as having an invalid transport.
    SmbCeHandleTransportInvalidation(pTransport);

    // dereference the transport
    SmbCeDereferenceTransport(pTransport);
}


VOID
MRxSmbpOverrideBindingPriority(
    PUNICODE_STRING pTransportName,
    PULONG pPriority
    )

/*++

Routine Description:

This function obtains a overriding priority value from the registry for a given
transport.

The priority of a transport controls the order in which connections are accepted.  It is
sometimes useful for a customer to control which transport is used first in the redirector.

The priority is usually determined by the order of the transports in the binding list.  With
the new Connections UI model for network setup, it will no longer be possible to adjust
the order of the bindings in the binding list.  Thus, another mechanism is needed when the
user wants to override the priority assigned to a given binding.

Arguments:

    pTransportName - pointer to UNICODE_STRING descriptor for transport string, for example
        "\Device\Netbt_tcpip_{guid}"
    pPriority - pointer to LONG to receive new priority on success, otherwise not touched

Return Value:

    None

--*/

{
    WCHAR valueBuffer[128];
    UNICODE_STRING path, value, key;
    USHORT length,ulength;
    OBJECT_ATTRIBUTES objectAttributes;
    NTSTATUS status;
    HANDLE parametersHandle;
    ULONG temp;

    PAGED_CODE();

    // Validate input

    if (pTransportName->Length == 0) {
        return;
    }

    // Open parameters key

    RtlInitUnicodeString( &path, SMBMRX_MINIRDR_PARAMETERS );

    InitializeObjectAttributes(
        &objectAttributes,
        &path,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL
        );

    status = ZwOpenKey (&parametersHandle, KEY_READ, &objectAttributes);

    if (!NT_SUCCESS(status)) {
        return;
    }

    // Construct value name = "BindingPriority" + transportname
    // First, find the last slash.  Then form the value from the prefix and
    // the remainder of the transport name.
    ulength = pTransportName->Length / sizeof(WCHAR);
    for( length = ulength - 1; length != 0; length-- ) {
        if (pTransportName->Buffer[length] == L'\\') {
            break;
        }
    }

    length++;
    key.Buffer = pTransportName->Buffer + length;
    key.Length = (ulength - length) * sizeof(WCHAR);

    value.Buffer = valueBuffer;
    value.MaximumLength = 128 * sizeof(WCHAR);
    value.Length = 0;

    RtlAppendUnicodeToString( &value, L"BindingPriority" );
    RtlAppendUnicodeStringToString( &value, &key );

    // Check if the value is present.  If so, replace priority
    // A value of zero is valid and indicates do not bind this one

    status = MRxSmbGetUlongRegistryParameter(
                 parametersHandle,
                 value.Buffer,
                 (PULONG)&temp,
                 FALSE );

    if (NT_SUCCESS(status)) {
        *pPriority = temp;
    }

    ZwClose(parametersHandle);
}

VOID
MRxSmbPnPBindingHandler(
    __in TDI_PNP_OPCODE   PnPOpcode,
    __in PUNICODE_STRING  pTransportName,
    __in PWSTR            BindingList)
/*++

Routine Description:

    The TDI callbacks routine for binding changes

Arguments:

    PnPOpcode - the PNP op code

    pTransportName - the transport name

    BindingList - the binding order

--*/
{
    ULONG Priority;
    NTSTATUS       Status;

    PAGED_CODE();

    switch (PnPOpcode) {
    case TDI_PNP_OP_ADD:
        {
            BOOLEAN        fBindToTransport = FALSE;
            PWSTR          pSmbMRxTransports;
            UNICODE_STRING SmbMRxTransport;

            Status = SmbCeGetConfigurationInformation();

            if (Status != STATUS_SUCCESS) {
                return;
            }

            pSmbMRxTransports = (PWSTR)SmbCeContext.Transports.Buffer;
            Priority = 1;
            while (*pSmbMRxTransports) {
                SmbMRxTransport.Length = wcslen(pSmbMRxTransports) * sizeof(WCHAR);

                if (SmbMRxTransport.Length == pTransportName->Length) {
                    SmbMRxTransport.MaximumLength = SmbMRxTransport.Length;
                    SmbMRxTransport.Buffer = pSmbMRxTransports;

                    if (RtlCompareUnicodeString(
                           &SmbMRxTransport,
                           pTransportName,
                           TRUE) == 0) {
                        fBindToTransport = TRUE;
                        break;
                    }
                }

                pSmbMRxTransports += (SmbMRxTransport.Length / sizeof(WCHAR) + 1);
                Priority++;
            }

            // Provide a local registry means to alter binding priority
//            if (fBindToTransport) {
//                MRxSmbpOverrideBindingPriority( pTransportName, &Priority );
//                fBindToTransport = (Priority != 0);
//            }

            if (fBindToTransport) {
                InterlockedIncrement(&TdiBindRequestsActive);

                if (IoGetCurrentProcess() == RxGetRDBSSProcess()) {
                    TRANSPORT_BIND_CONTEXT TransportContext;

                    TransportContext.Priority = Priority;
                    TransportContext.TransportName = *pTransportName;
                    MRxSmbpBindTransportCallback(&TransportContext);
                } else {
                    PTRANSPORT_BIND_CONTEXT pNewTransportContext;

                    pNewTransportContext = RxAllocatePoolWithTag(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -