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

📄 netroot.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 3 页
字号:
   This routine signals the completion of a reconnect attempt

Arguments:

    pCreateNetRootContext - the net root context

Return Value:

    RXSTATUS - The return status for the operation

--*/
{
   KeSetEvent(&pCreateNetRootContext->FinishEvent, IO_NETWORK_INCREMENT, FALSE );
}

NTSTATUS
SmbCeReconnect(
    IN PMRX_V_NET_ROOT            pVNetRoot)
/*++

Routine Description:

   This routine reconnects, i.e, establishes a new session and tree connect to a previously
   connected serverb share

Arguments:

    pVNetRoot - the virtual net root instance.

Return Value:

    RXSTATUS - The return status for the operation

--*/
{
    NTSTATUS Status;
    PSMBCEDB_SERVER_ENTRY     pServerEntry;
    PSMBCEDB_SESSION_ENTRY    pSessionEntry;
    PSMBCEDB_NET_ROOT_ENTRY   pNetRootEntry;
    PSMBCE_V_NET_ROOT_CONTEXT pVNetRootContext = (PSMBCE_V_NET_ROOT_CONTEXT)pVNetRoot->Context;

    PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext;

    PAGED_CODE();

    if ((pVNetRootContext != NULL) &&
        (pVNetRootContext->Header.State == SMBCEDB_ACTIVE)) {
        pServerEntry  = pVNetRootContext->pServerEntry;
        pSessionEntry = pVNetRootContext->pSessionEntry;
        pNetRootEntry = pVNetRootContext->pNetRootEntry;

        if ((pServerEntry->Header.State == SMBCEDB_ACTIVE) &&
            (pSessionEntry->Header.State == SMBCEDB_ACTIVE) &&
            (pNetRootEntry->Header.State == SMBCEDB_ACTIVE)) {
            return STATUS_SUCCESS;
        }
    }

    pCreateNetRootContext = (PMRX_CREATENETROOT_CONTEXT)
                            RxAllocatePoolWithTag(
                                NonPagedPool,
                                sizeof(MRX_CREATENETROOT_CONTEXT),
                                MRXSMB_NETROOT_POOLTAG);

    if (pCreateNetRootContext != NULL) {
        for (;;) {
            pCreateNetRootContext->pVNetRoot  = (PV_NET_ROOT)pVNetRoot;
            pCreateNetRootContext->NetRootStatus  = STATUS_SUCCESS;
            pCreateNetRootContext->VirtualNetRootStatus = STATUS_SUCCESS;
            pCreateNetRootContext->Callback       = SmbCeReconnectCallback;
            pCreateNetRootContext->RxContext      = NULL;

            KeInitializeEvent(
                &pCreateNetRootContext->FinishEvent,
                SynchronizationEvent,
                FALSE );

            // Since this is a reconnect instance the net root initialization is not required
            Status = SmbCeEstablishConnection(
                         pVNetRoot,
                         pCreateNetRootContext,
                         FALSE);

            if (Status == STATUS_PENDING) {
                // Wait for the construction to be completed.
                KeWaitForSingleObject(
                    &pCreateNetRootContext->FinishEvent,
                    Executive,
                    KernelMode,
                    FALSE,
                    NULL);

                Status = pCreateNetRootContext->VirtualNetRootStatus;
            }

            if (Status != STATUS_LINK_FAILED) {
                break;
            }
        }

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

    return Status;
}

NTSTATUS
SmbCeEstablishConnection(
    IN OUT PMRX_V_NET_ROOT        pVNetRoot,
    IN PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext,
    IN BOOLEAN                    fInitializeNetRoot
    )
/*++

Routine Description:

   This routine triggers off the connection attempt for initial establishment of a
   connection as well as subsequent reconnect attempts.

Arguments:

    pVNetRoot - the virtual net root instance.

    pCreateNetRootContext - the net root context for calling back

Return Value:

    RXSTATUS - The return status for the operation

--*/
{
    NTSTATUS Status;

    PSMBCEDB_SERVER_ENTRY     pServerEntry;
    PSMBCEDB_SESSION_ENTRY    pSessionEntry;
    PSMBCEDB_NET_ROOT_ENTRY   pNetRootEntry;
    PSMBCE_V_NET_ROOT_CONTEXT pVNetRootContext;

    PAGED_CODE();

    pVNetRootContext = SmbCeGetAssociatedVNetRootContext(pVNetRoot);
    
    if (pVNetRootContext == NULL) {
        Status = STATUS_BAD_NETWORK_PATH;
    } else {
        pServerEntry  = pVNetRootContext->pServerEntry;
        pSessionEntry = pVNetRootContext->pSessionEntry;
        pNetRootEntry = pVNetRootContext->pNetRootEntry;

        Status = STATUS_SUCCESS;
    }

    if (Status == STATUS_SUCCESS) {
        //
        // The following code initializes the NetRootEntry, VNetRootContext and
        // the session entry under certain cases.
        //
        // The session entry to a doenlevel server needs to be initialized. This
        // is not handled by the previous code since the session  entry and the
        // net root entry initialization can be combined into one exchange.
        //
        // The net root entry has not been initialized, i.e., this corresponds to
        // the construction of the first SMBCE_V_NET_ROOT_CONTEXT instance for a
        // given NetRootEntry.
        //
        // Subsequent SMBCE_V_NET_ROOT context constructions. In these cases the
        // construction of each context must obtain a new TID
        //

        BOOLEAN fNetRootExchangeRequired;

        fNetRootExchangeRequired = (
                                    (pSessionEntry->Header.State != SMBCEDB_ACTIVE) ||
                                    !BooleanFlagOn(
                                        pVNetRootContext->Flags,
                                        SMBCE_V_NET_ROOT_CONTEXT_FLAG_VALID_TID)
                                  );

        if (fNetRootExchangeRequired) {
            // This is a tree connect open which needs to be triggered immediately.
            PSMB_EXCHANGE                  pSmbExchange;
            PSMB_CONSTRUCT_NETROOT_EXCHANGE pNetRootExchange;

            pSmbExchange = SmbMmAllocateExchange(CONSTRUCT_NETROOT_EXCHANGE,NULL);
            if (pSmbExchange != NULL) {
                Status = SmbCeInitializeExchange(
                             &pSmbExchange,
                             NULL,
                             pVNetRoot,
                             CONSTRUCT_NETROOT_EXCHANGE,
                             &ConstructNetRootExchangeDispatch);

                if (Status == STATUS_SUCCESS) {
                    pNetRootExchange = (PSMB_CONSTRUCT_NETROOT_EXCHANGE)pSmbExchange;

                    // Attempt to reconnect( In this case it amounts to establishing the
                    // connection/session)
                    pNetRootExchange->SmbCeFlags |= (SMBCE_EXCHANGE_ATTEMPT_RECONNECTS |
                                                   SMBCE_EXCHANGE_TIMED_RECEIVE_OPERATION);

                    // Initialize the continuation for resumption upon completion of the
                    // tree connetcion.
                    pNetRootExchange->NetRootCallback       = pCreateNetRootContext->Callback;
                    pNetRootExchange->pCreateNetRootContext = pCreateNetRootContext;

                    pNetRootExchange->fInitializeNetRoot =  fInitializeNetRoot;

                    // Initiate the exchange.
                    Status = SmbCeInitiateExchange(pSmbExchange);

                    if (Status != STATUS_PENDING) {
                        SmbCeDiscardExchangeWorkerThreadRoutine(pSmbExchange);
                    }
                }
            } else {
                Status = STATUS_INSUFFICIENT_RESOURCES;
            }
        }
    }

    return Status;
}

//
// The net roots are normally constructed as part of some other exchange, i.e., the SMB for
// Tree connect is compounded with other operations. However, there is one situation in which
// the tree connect SMB needs to be sent by itself. This case refers to the prefix claim
// situation ( net use command ). This is handled by the construct net root exchange.
//

#define CONSTRUCT_NETROOT_BUFFER_SIZE (4096)

NTSTATUS
SmbConstructNetRootExchangeStart(
      PSMB_EXCHANGE  pExchange)
/*++

Routine Description:

    This is the start routine for net root construction exchanges. This initiates the
    construction of the appropriate SMB's if required.

Arguments:

    pExchange - the exchange instance

Return Value:

    RXSTATUS - The return status for the operation

--*/
{
    NTSTATUS Status;
    NTSTATUS RequestLockStatus = STATUS_UNSUCCESSFUL;
    NTSTATUS ResponseLockStatus = STATUS_UNSUCCESSFUL;

    PVOID pSmbActualBuffer;
    PVOID pSmbBuffer;
    UCHAR SmbCommand,LastCommandInHeader;
    ULONG SmbLength;

    PUCHAR pCommand;

    PMDL  pSmbRequestMdl,pSmbResponseMdl;
    ULONG SmbMdlSize;

    PSMB_CONSTRUCT_NETROOT_EXCHANGE pNetRootExchange;
    PSMBCEDB_SERVER_ENTRY pServerEntry = SmbCeGetExchangeServerEntry(pExchange);
    PMRX_NET_ROOT pNetRoot = pExchange->SmbCeContext.pVNetRoot->pNetRoot;

    PAGED_CODE();

    pNetRootExchange = (PSMB_CONSTRUCT_NETROOT_EXCHANGE)pExchange;

    ASSERT(pNetRootExchange->Type == CONSTRUCT_NETROOT_EXCHANGE);

    if (pNetRoot->Type == NET_ROOT_PIPE) {
        RxDbgTrace( 0, Dbg, ("pipe open to core server\n"));
        return STATUS_NOT_SUPPORTED;
    }

    pSmbRequestMdl = pSmbResponseMdl = NULL;

    pSmbActualBuffer = RxAllocatePoolWithTag(
                           PagedPool,
                           (CONSTRUCT_NETROOT_BUFFER_SIZE + TRANSPORT_HEADER_SIZE),
                           MRXSMB_NETROOT_POOLTAG);

    if (pSmbActualBuffer != NULL) {
        PSMBCE_SERVER pServer = SmbCeGetExchangeServer(pExchange);

        (PCHAR) pSmbBuffer = (PCHAR) pSmbActualBuffer + TRANSPORT_HEADER_SIZE;

        Status = SmbCeBuildSmbHeader(
                     pExchange,
                     pSmbBuffer,
                     CONSTRUCT_NETROOT_BUFFER_SIZE,
                     &SmbLength,
                     &LastCommandInHeader,
                     &pCommand);

        // Ensure that the NET_ROOT/SESSION still needs to be constructed before
        // sending it. It is likely that they were costructed by an earlier exchange
        if (NT_SUCCESS(Status) &&
            (SmbLength > sizeof(SMB_HEADER))) {

            if (LastCommandInHeader != SMB_COM_TREE_CONNECT){
                *pCommand = SMB_COM_NO_ANDX_COMMAND;
            }

            RxAllocateHeaderMdl(
                pSmbBuffer,
                SmbLength,
                pSmbRequestMdl
                );

            pSmbResponseMdl = RxAllocateMdl(pSmbBuffer,CONSTRUCT_NETROOT_BUFFER_SIZE);

            if ((pSmbRequestMdl != NULL) &&
                (pSmbResponseMdl != NULL)) {

                RxProbeAndLockHeaderPages(
                    pSmbRequestMdl,
                    KernelMode,
                    IoModifyAccess,
                    RequestLockStatus);

                RxProbeAndLockPages(
                    pSmbResponseMdl,
                    KernelMode,
                    IoModifyAccess,
                    ResponseLockStatus);

                if ((Status  == STATUS_SUCCESS) &&
                    ((Status = RequestLockStatus)  == STATUS_SUCCESS) &&
                    ((Status = ResponseLockStatus) == STATUS_SUCCESS)) {

                    pNetRootExchange->pSmbResponseMdl = pSmbResponseMdl;
                    pNetRootExchange->pSmbRequestMdl  = pSmbRequestMdl;
                    pNetRootExchange->pSmbActualBuffer = pSmbActualBuffer;
                    pNetRootExchange->pSmbBuffer      = pSmbBuffer;

                    Status = SmbCeTranceive(
                                 pExchange,
                                 (RXCE_SEND_PARTIAL | RXCE_SEND_SYNCHRONOUS),
                                 pNetRootExchange->pSmbRequestMdl,
                                 SmbLength);

                    RxDbgTrace( 0, Dbg, ("Net Root SmbCeTranceive returned %lx\n",Status));
                }
            } else {
                Status = STATUS_INSUFFICIENT_RESOURCES;
            }

            if ((Status != STATUS_PENDING) &&
                (Status != STATUS_SUCCESS)) {

                pNetRootExchange->pSmbResponseMdl = NULL;
                pNetRootExchange->pSmbRequestMdl  = NULL;
                pNetRootExchange->pSmbActualBuffer = NULL;
                pNetRootExchange->pSmbBuffer      = NULL;

                if (pSmbResponseMdl != NULL) {
                    if (ResponseLockStatus == STATUS_SUCCESS) {
                        MmUnlockPages(pSmbResponseMdl);
                    }

                    IoFreeMdl(pSmbResponseMdl);
                }

                if (pSmbRequestMdl != NULL) {
                    if (RequestLockStatus == STATUS_SUCCESS) {
                        RxUnlockHeaderPages(pSmbRequestMdl);
                    }

⌨️ 快捷键说明

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