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

📄 transact.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
        IoFreeMdl(pTransactExchange->pReceiveSetupMdl);
    }

    if (pTransactExchange->pReceiveParamMdl != NULL) {
        MmUnlockPages(pTransactExchange->pReceiveParamMdl);
        IoFreeMdl(pTransactExchange->pReceiveParamMdl);
    }

    if (pTransactExchange->pReceiveDataMdl != NULL) {
        MmUnlockPages(pTransactExchange->pReceiveDataMdl);
        IoFreeMdl(pTransactExchange->pReceiveDataMdl);
    }

    if (pTransactExchange->pSendSetupMdl != NULL) {
        MmUnlockPages(pTransactExchange->pSendSetupMdl);
        IoFreeMdl(pTransactExchange->pSendSetupMdl);
    }

    if ((pTransactExchange->pSendDataMdl != NULL) &&
         !BooleanFlagOn(pTransactExchange->Flags,SMB_XACT_FLAGS_CALLERS_SENDDATAMDL)) {
        MmUnlockPages(pTransactExchange->pSendDataMdl);
        IoFreeMdl(pTransactExchange->pSendDataMdl);
    }

    if (pTransactExchange->pSendParamMdl != NULL) {
        MmUnlockPages(pTransactExchange->pSendParamMdl);
        IoFreeMdl(pTransactExchange->pSendParamMdl);
    }

    if ((pResumptionContext = pTransactExchange->pResumptionContext) != NULL) {
        NTSTATUS FinalStatus;
        PSMBCEDB_SERVER_ENTRY pServerEntry = SmbCeGetExchangeServerEntry((PSMB_EXCHANGE)pTransactExchange);

        RxDbgTrace(0, Dbg,
                 ("SmbCeTransactExchangeFinalize: everythings is good! parambytes (%ld) databytes (%ld)\n",
                  pTransactExchange->ParamBytesReceived, pTransactExchange->DataBytesReceived
                ));

        FinalStatus = pTransactExchange->Status;

        if (pServerEntry->ServerStatus != STATUS_SUCCESS) {
            // If the server entry is in error state, the transact cannot receive a response from server.
            // In this case, we return the server status.
            pResumptionContext->FinalStatusFromServer = pServerEntry->ServerStatus;
        } else {
            // If the server entry is in good or disconnected state, we return the smb status.
            pResumptionContext->FinalStatusFromServer = pTransactExchange->SmbStatus;
        }

        if ((FinalStatus == STATUS_SUCCESS)||
            (FinalStatus == STATUS_MORE_PROCESSING_REQUIRED)) {

            FinalStatus = pResumptionContext->FinalStatusFromServer;
        }

        pResumptionContext->SmbCeResumptionContext.Status = FinalStatus;
        pResumptionContext->SetupBytesReceived = pTransactExchange->SetupBytesReceived;
        pResumptionContext->DataBytesReceived = pTransactExchange->DataBytesReceived;
        pResumptionContext->ParameterBytesReceived = pTransactExchange->ParamBytesReceived;
        pResumptionContext->ServerVersion = pTransactExchange->ServerVersion;

        SmbCeResume(&pResumptionContext->SmbCeResumptionContext);
    }

    SmbCeDereferenceAndDiscardExchange((PSMB_EXCHANGE)pTransactExchange);
}

NTSTATUS
SmbCeSubmitTransactionRequest(
    PRX_CONTEXT                           RxContext,
    PSMB_TRANSACTION_OPTIONS              pOptions,
    PSMB_TRANSACTION_PARAMETERS           pSendParameters,
    PSMB_TRANSACTION_PARAMETERS           pReceiveParameters,
    PSMB_TRANSACTION_RESUMPTION_CONTEXT   pResumptionContext )
/*++

Routine Description:

    This routine submits a transaction request, i.e., allocates/initializes a transaction
    exchange, sets up the completion information and initiates it

Arguments:

    pNetRoot           - the netroot for which the transaction request is intended

    pOptions           - the transaction options

    pSendParameters    - the transaction parameters to be sent to the server

    pReceiveParameters - the transaction results from the server

    pResumptionContext - the context for resuming the local activity on completion of the
                         transaction

Return Value:

    RXSTATUS - The return status for the operation
      STATUS_PENDING -- if the transcation was initiated successfully
      Other error codes if the request could not be submitted successfully

Notes:

    Whenever a status of STATUS_PENDING is returned it implies that the transact
    exchange has assumed ownership of the MDLs passed in as receive and send
    parameters. They will be released on completion of the exchange.

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;

    RxCaptureFcb;
    RxCaptureFobx;

    PMRX_V_NET_ROOT pVNetRoot = NULL;

    PSMB_TRANSACT_EXCHANGE pTransactExchange;
    PSMB_EXCHANGE          pExchange = NULL;

    PAGED_CODE();

    if (capFobx == NULL) {
        if (RxContext->MajorFunction == IRP_MJ_CREATE) {
            pVNetRoot = RxContext->Create.pVNetRoot;
        }
    } else {
        // These are the root objects which are associated with the device FCB. In
        // such cases

        pVNetRoot = (PMRX_V_NET_ROOT)capFobx;

        if (NodeType(pVNetRoot) != RDBSS_NTC_V_NETROOT) {
            pVNetRoot = capFobx->pSrvOpen->pVNetRoot;
        }
    }

    if (pVNetRoot == NULL) {
        PSMBCEDB_SERVER_ENTRY pServerEntry;

        pServerEntry = SmbCeGetAssociatedServerEntry(capFcb->pNetRoot->pSrvCall);

        // Allocate and initialize an exchange for the given net root.
        Status = SmbCeInitializeExchange2(
                    &pExchange,
                    RxContext,
                    pServerEntry,
                    TRANSACT_EXCHANGE,
                    &TransactExchangeDispatch);
    } else {
        // Allocate and initialize an exchange for the given net root.
        Status = SmbCeInitializeExchange(
                    &pExchange,
                    RxContext,
                    pVNetRoot,
                    TRANSACT_EXCHANGE,
                    &TransactExchangeDispatch);
    }

    if (Status == STATUS_SUCCESS) {
        // Initialize the transact exchange
        pTransactExchange = (PSMB_TRANSACT_EXCHANGE)pExchange;

        Status = SmbCeInitializeTransactExchange(
                     pTransactExchange,
                     RxContext,
                     pOptions,
                     pSendParameters,
                     pReceiveParameters,
                     pResumptionContext);

        if (Status == STATUS_SUCCESS) {
            // The transact exchange can be either asynchronous or synchronous. In
            // the asynchronous case an additional reference is taken which is
            // passed onto the caller alongwith the exchange squirelled away in the
            // RX_CONTEXT if STATUS_PENDING is being returned. This enables the
            // caller to control when the exchange is discarded. This works
            // especially well in dealing with cancellation of asynchronous
            // exchanges.

            // This reference will be accounted for by the finalization routine
            // of the transact exchange.
            SmbCeReferenceExchange((PSMB_EXCHANGE)pTransactExchange);

            if (BooleanFlagOn(pOptions->Flags,SMB_XACT_FLAGS_ASYNCHRONOUS)) {
                // The corresponding dereference is the callers responsibility
                SmbCeReferenceExchange((PSMB_EXCHANGE)pTransactExchange);
            }

            pResumptionContext->pTransactExchange = pTransactExchange;
            pResumptionContext->SmbCeResumptionContext.Status = STATUS_SUCCESS;

            SmbCeIncrementPendingLocalOperations(pExchange);

            // Initiate the exchange
            Status = SmbCeInitiateExchange(pExchange);

            if (Status != STATUS_PENDING) {
                pExchange->Status = Status;

                if (pExchange->SmbStatus == STATUS_SUCCESS) {
                    pExchange->SmbStatus = Status;
                }

                if (BooleanFlagOn(pOptions->Flags,SMB_XACT_FLAGS_ASYNCHRONOUS)) {
                    PMRXSMB_RX_CONTEXT pMRxSmbContext = MRxSmbGetMinirdrContext(RxContext);

                    pMRxSmbContext->pExchange     = NULL;

                    // Since the exchange has already been completed there is no
                    // point in returning the additional reference to the caller
                    SmbCeDereferenceExchange((PSMB_EXCHANGE)pTransactExchange);
                }
            }

            SmbCeDecrementPendingLocalOperationsAndFinalize(pExchange);

            // Map the status to STATUS_PENDING so that continuation routines
            // do not attempt to finalize.
            Status = STATUS_PENDING;
        } else {
            PMRXSMB_RX_CONTEXT MRxSmbContext = MRxSmbGetMinirdrContext(RxContext);

            ASSERT(MRxSmbContext->pExchange == pExchange);
            MRxSmbContext->pExchange = NULL;

            SmbCeDiscardExchange(pExchange);
        }
    }

    return Status;
}

NTSTATUS
_SmbCeTransact(
   PRX_CONTEXT                         RxContext,
   PSMB_TRANSACTION_OPTIONS            pOptions,
   PVOID                               pInputSetupBuffer,
   ULONG                               InputSetupBufferLength,
   PVOID                               pOutputSetupBuffer,
   ULONG                               OutputSetupBufferLength,
   PVOID                               pInputParamBuffer,
   ULONG                               InputParamBufferLength,
   PVOID                               pOutputParamBuffer,
   ULONG                               OutputParamBufferLength,
   PVOID                               pInputDataBuffer,
   ULONG                               InputDataBufferLength,
   PVOID                               pOutputDataBuffer,
   ULONG                               OutputDataBufferLength,
   PSMB_TRANSACTION_RESUMPTION_CONTEXT pResumptionContext)
/*++

Routine Description:

    This routine implements a standardized mechanism of submitting transaction requests,
    and synchronizing with their completion. This does not provide the smae amount of control
    that SmbCeSubmitTransactRequest provides. Nevertheless, this implements a common mechanism
    that should satisfy most needs

Arguments:

    RxContext               - the context for the transaction

    pOptions                - the transaction options

    pSetupBuffer            - the transaction setup buffer

    SetupBufferlength       - the setup buffer length

    pInputParamBuffer       - the Input param buffer

    InputParamBufferLength  - the input param buffer length

    pOutputParamBuffer      - the output param buffer

    OutputParamBufferlength - the output param buffer length

    pInputDataBuffer        - the Input data buffer

    InputDataBufferLength   - the input data buffer length

    pOutputDataBuffer       - the output data buffer

    OutputDataBufferlength  - the output data buffer length

    pResumptionContext       - the transaction resumption context

Return Value:

    RXSTATUS - The return status for the operation
      STATUS_SUCCESS if successfull.
      Other error codes if the request could not be submitted successfully

Notes:

    In the case of asynchronous exchanges if STATUS_PENDING is returned the
    Exchange instance is squirelled away in the minirdr context associated with
    the given RX_CONTEXT instance. This exchange will not be discarded without
    the callers intervention. It is the callers responsibility to invoke
    SmbCeDereferenceAndDiscardExchange to discard the exchange

--*/
{
    NTSTATUS Status;

    SMB_TRANSACTION_SEND_PARAMETERS     SendParameters;
    SMB_TRANSACTION_RECEIVE_PARAMETERS  ReceiveParameters;
    BOOLEAN                             fAsynchronous;

    PAGED_CODE();

    fAsynchronous = BooleanFlagOn(pOptions->Flags,SMB_XACT_FLAGS_ASYNCHRONOUS);

    Status = SmbCeInitializeTransactionSendParameters(
                 pInputSetupBuffer,
                 (USHORT)InputSetupBufferLength,
                 pInputParamBuffer,
                 InputParamBufferLength,
                 pInputDataBuffer,
                 InputDataBufferLength,
                 &SendParameters);

⌨️ 快捷键说明

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