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

📄 transprt.c

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

    STATUS_SUCCESS if successful

Notes:

    Currently, only connection oriented transports are handled.

    In order to handle async. operations the uninitialization has to be coordinated
    with the referencing mechanism. It is for this reason that this routine sets up
    a rundown event and waits for it to be set.

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;

    PAGED_CODE();

    if (pCallbackRoutine == NULL &&
        IoGetCurrentProcess() == RxGetRDBSSProcess()) {
        SmbCepTearDownServerTransport(pServerEntry);
    } else {
        PSMBCE_SERVER_TRANSPORT_CONSTRUCTION_CONTEXT pContext;

        pContext = RxAllocatePoolWithTag(
                       NonPagedPool,
                       sizeof(SMBCE_SERVER_TRANSPORT_CONSTRUCTION_CONTEXT),
                       MRXSMB_TRANSPORT_POOLTAG);

        if (pContext != NULL) {
            KEVENT  CompletionEvent;

            RtlZeroMemory(
                pContext,
                sizeof(SMBCE_SERVER_TRANSPORT_CONSTRUCTION_CONTEXT));

            pContext->Status = STATUS_SUCCESS;
            pContext->pServerEntry = pServerEntry;

            if (pCallbackRoutine == NULL) {
                KeInitializeEvent(
                    &CompletionEvent,
                    NotificationEvent,
                    FALSE);

                pContext->pCompletionEvent = &CompletionEvent;
            } else {
                pContext->pCallbackContext   = pCallbackContext;
                pContext->pCompletionRoutine = pCallbackRoutine;
            }

            if (IoGetCurrentProcess() == RxGetRDBSSProcess()) {
                SmbCeTearDownServerTransport(pContext);
            } else {
                Status = RxPostToWorkerThread(
                             MRxSmbDeviceObject,
                             CriticalWorkQueue,
                             &pContext->WorkQueueItem,
                             SmbCeTearDownServerTransport,
                             pContext);
            }

            if (Status == STATUS_SUCCESS) {
                if (pCallbackRoutine == NULL) {
                    KeWaitForSingleObject(
                        &CompletionEvent,
                        Executive,
                        KernelMode,
                        FALSE,
                        NULL );
                } else {
                    Status = STATUS_PENDING;
                }
            } else {
                RxFreePool(pContext);
            }
        } else {
            Status = STATUS_INSUFFICIENT_RESOURCES;
        }
    }

    return Status;
}

VOID
SmbCeCompleteUninitializeServerTransport(
    PSMBCEDB_SERVER_ENTRY pServerEntry)
{
    // in case of async uninitialize server transport, an additional reference count of
    // server entry should be taken so that uninitialize server transport will not be
    // called once again from tear down server entry if its reference count comes to 0
    // before uninitialize server transport is done.
    SmbCeDereferenceServerEntry(pServerEntry);
}

NTSTATUS
SmbCeInitiateDisconnect(
    PSMBCEDB_SERVER_ENTRY   pServerEntry)
/*++

Routine Description:

    This routine initiates the TDI disconnect

Arguments:

    pServerEntry - the server entry instance in the database

Return Value:

    STATUS_SUCCESS - the server transport construction has been finalized.

    Other Status codes correspond to error situations.

Notes:

--*/
{
    NTSTATUS Status;

    PSMBCE_SERVER_TRANSPORT pTransport;

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

    Status = SmbCeReferenceServerTransport(&pServerEntry->pTransport);

    if (Status == STATUS_SUCCESS) {
        Status = (pServerEntry->pTransport->pDispatchVector->InitiateDisconnect)(
                    pServerEntry->pTransport);

        if (Status != STATUS_SUCCESS) {
            RxDbgTrace(0, Dbg, ("SmbCeInitiateDisconnect : Status %lx\n",Status));
        }

        SmbCeDereferenceServerTransport(&pServerEntry->pTransport);
    }

    return STATUS_SUCCESS;
}

LONG Initializes[SENTINEL_EXCHANGE] = {0,0,0,0};
LONG Uninitializes[SENTINEL_EXCHANGE] = {0,0,0,0};

NTSTATUS
SmbCeInitializeExchangeTransport(
   PSMB_EXCHANGE         pExchange)
/*++

Routine Description:

    This routine initializes the transport associated with the exchange

Arguments:

    pExchange - the exchange to be initialized

Return Value:

    STATUS_SUCCESS - the exchange transport initialization has been finalized.

    Other Status codes correspond to error situations.

Notes:

--*/
{
    NTSTATUS Status;

    PSMBCEDB_SERVER_ENTRY pServerEntry;

    PAGED_CODE();

    pServerEntry = SmbCeGetExchangeServerEntry(pExchange);

    Status = pExchange->SmbStatus;
    if (Status == STATUS_SUCCESS) {
        PSMBCE_SERVER_TRANSPORT *pTransportPointer;

        pTransportPointer = &pServerEntry->pTransport;

        if (*pTransportPointer != NULL) {
            Status = SmbCeReferenceServerTransport(pTransportPointer);

            if (Status == STATUS_SUCCESS) {
                Status = ((*pTransportPointer)->pDispatchVector->InitializeExchange)(
                             *pTransportPointer,
                             pExchange);

                if (Status == STATUS_SUCCESS) {
                    ULONG TransportInitialized;

                    InterlockedIncrement(&Initializes[pExchange->Type]);
                    TransportInitialized = InterlockedExchange(&pExchange->ExchangeTransportInitialized,1);
                    ASSERT(TransportInitialized == 0);
                } else {
                    SmbCeDereferenceServerTransport(pTransportPointer);
                }
            }
        } else {
            Status = STATUS_CONNECTION_DISCONNECTED;
        }
   }

   return Status;
}

NTSTATUS
SmbCeUninitializeExchangeTransport(
   PSMB_EXCHANGE         pExchange)
/*++

Routine Description:

    This routine uniinitializes the transport associated with the exchange

Arguments:

    pExchange - the exchange to be initialized

Return Value:

    STATUS_SUCCESS - the exchange transport initialization has been finalized.

    Other Status codes correspond to error situations.

Notes:

--*/
{
    NTSTATUS Status;
    PSMBCEDB_SERVER_ENTRY pServerEntry;

    PAGED_CODE();

    pServerEntry = SmbCeGetExchangeServerEntry(pExchange);

    if (InterlockedExchange(&pExchange->ExchangeTransportInitialized,0)==1) {
        PSMBCE_SERVER_TRANSPORT *pTransportPointer;

        pTransportPointer = &pServerEntry->pTransport;

        if (*pTransportPointer != NULL) {
            Status = ((*pTransportPointer)->pDispatchVector->UninitializeExchange)(
                        *pTransportPointer,
                        pExchange);

            SmbCeDereferenceServerTransport(pTransportPointer);
            InterlockedIncrement(&Uninitializes[pExchange->Type]);

            return Status;
        } else {
            return STATUS_CONNECTION_DISCONNECTED;
        }
    } else {
        return pExchange->SmbStatus;
    }
}

NTSTATUS
SmbCepReferenceServerTransport(
    PSMBCE_SERVER_TRANSPORT *pServerTransportPointer)
/*++

Routine Description:

    This routine references the transport associated with a server entry

Arguments:

    pServerEntry - the server entry instance in the database

Return Value:

    STATUS_SUCCESS - the server transport was successfully referenced

    Other Status codes correspond to error situations.

Notes:

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;

    SmbCeAcquireSpinLock();

    if (*pServerTransportPointer != NULL &&
        (*pServerTransportPointer)->State == SMBCEDB_ACTIVE) {
        InterlockedIncrement(&(*pServerTransportPointer)->SwizzleCount);
        Status = STATUS_SUCCESS;
    } else {
        Status = STATUS_CONNECTION_DISCONNECTED;
    }

    SmbCeReleaseSpinLock();

    return Status;
}

NTSTATUS
SmbCepDereferenceServerTransport(
    PSMBCE_SERVER_TRANSPORT *pServerTransportPointer)
/*++

Routine Description:

    This routine dereferences the transport associated with a server entry

Arguments:

    pServerTransportPointer - the server entry transport instance pointer

Return Value:

    STATUS_SUCCESS - the server transport was successfully dereferenced

    Other Status codes correspond to error situations.

Notes:

    On finalization this routine sets the event to enable the process awaiting
    tear down to restart. It also tears down the associated server transport
    instance.

    As a side effect the pointer value is set to NULL under the protection of a
    spin lock.

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;

    SmbCeAcquireSpinLock();

    if (*pServerTransportPointer != NULL) {
        LONG    FinalRefCount;
        PKEVENT pRundownEvent;
        PSMBCE_SERVER_TRANSPORT pServerTransport;

        pServerTransport = *pServerTransportPointer;

        FinalRefCount = InterlockedDecrement(&pServerTransport->SwizzleCount);

        if (FinalRefCount == 0) {
            pServerTransport->State = SMBCEDB_INVALID;

            // transport is set to NULL before the spinlock is release so that no
            // exchange should reference it after it's been torn down
            *pServerTransportPointer = NULL;
            pRundownEvent = pServerTransport->pRundownEvent;
        }

        SmbCeReleaseSpinLock();

        if (FinalRefCount == 0) {
            if (IoGetCurrentProcess() == RxGetRDBSSProcess()) {
                pServerTransport->pDispatchVector->TearDown(pServerTransport);
            } else {
                Status = RxDispatchToWorkerThread(
                             MRxSmbDeviceObject,
                             CriticalWorkQueue,
                             pServerTransport->pDispatchVector->TearDown,
                             pServerTransport);
            }
        }
    } else {
        SmbCeReleaseSpinLock();
        Status = STATUS_CONNECTION_DISCONNECTED;
    }

    return Status;
}


NTSTATUS
SmbCepReferenceTransport(
    PSMBCE_TRANSPORT pTransport)
/*++

Routine Description:

    This routine references the transport instance

Arguments:

    pTransport - the transport instance

Return Value:

    STATUS_SUCCESS - the server transport was successfully referenced

    Other Status codes correspond to error situations.

Notes:

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;

    if (pTransport != NULL) {
        SmbCeAcquireSpinLock();

        if (pTransport->Active) {
            InterlockedIncrement(&pTransport->SwizzleCount);
            Status = STATUS_SUCCESS;
        } else {
            Status = STATUS_UNSUCCESSFUL;
        }

        SmbCeReleaseSpinLock();
    } else {
        Status = STATUS_INVALID_PARAMETER;
    }

    return Status;
}

NTSTATUS
SmbCepDereferenceTransport(
    PSMBCE_TRANSPORT pTransport)
/*++

Routine Description:

    This routine dereferences the transport

Arguments:

    pTransport - the transport instance

Return Value:

    STATUS_SUCCESS - the server transport was successfully dereferenced

    Other Status codes correspond to error situations.

Notes:

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;
    BOOLEAN AttachToSystemProcess = FALSE;
    KAPC_STATE ApcState;

    PAGED_CODE();

    if (pTransport != NULL) {
        LONG FinalRefCount;

        FinalRefCount = InterlockedDecrement(&pTransport->SwizzleCount);

        if (FinalRefCount == 0) {
            SmbCeRemoveTransport(pTransport);

            if (IoGetCurrentProcess() != RxGetRDBSSProcess()) {
                KeStackAttachProcess(RxGetRDBSSProcess(),&ApcState);
                AttachToSystemProcess = TRUE;
            }

            RxCeTearDownAddress(&pTransport->RxCeAddress);

⌨️ 快捷键说明

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