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

📄 transact.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++
Copyright (c) 1987 - 1999  Microsoft Corporation

Module Name:

    transact.c

Abstract:

    This file conatins the implementation of the transact exchange.

--*/

#include "precomp.h"
#pragma hdrstop

#pragma warning(error:4100)   // Unreferenced formal parameter

#ifdef  ALLOC_PRAGMA
#pragma alloc_text(PAGE, SmbCeInitializeTransactionParameters)
#pragma alloc_text(PAGE, SmbCeUninitializeTransactionParameters)
#pragma alloc_text(PAGE, SmbCeDiscardTransactExchange)
#pragma alloc_text(PAGE, SmbCeSubmitTransactionRequest)
#pragma alloc_text(PAGE, _SmbCeTransact)
#pragma alloc_text(PAGE, SmbTransactBuildHeader)
#pragma alloc_text(PAGE, SmbTransactExchangeStart)
#pragma alloc_text(PAGE, SmbTransactExchangeAbort)
#pragma alloc_text(PAGE, SmbTransactExchangeErrorHandler)
#pragma alloc_text(PAGE, SmbTransactExchangeSendCallbackHandler)
#pragma alloc_text(PAGE, SmbCeInitializeTransactExchange)
#pragma alloc_text(PAGE, SendSecondaryRequests)
#endif

//#define SET_DONTSUBSUME_PARAMS
#ifdef SET_DONTSUBSUME_PARAMS
ULONG MRxSmbDontSubsumeParams = 1;
#else
ULONG MRxSmbDontSubsumeParams = 0;
#endif
#if DBG
#define DONTSUBSUME_PARAMS MRxSmbDontSubsumeParams
#else
#define DONTSUBSUME_PARAMS FALSE
#endif

SMB_TRANSACTION_OPTIONS RxDefaultTransactionOptions = DEFAULT_TRANSACTION_OPTIONS;

RXDT_DefineCategory(TRANSACT);
#define Dbg        (DEBUG_TRACE_TRANSACT)

#define MIN(x,y)  ((x) < (y) ? (x) : (y))

#define SMB_TRANSACT_MAXIMUM_PARAMETER_SIZE (0xffff)
#define SMB_TRANSACT_MAXIMUM_DATA_SIZE      (0xffff)

typedef struct _SMB_TRANSACT_RESP_FORMAT_DESCRIPTION {
    ULONG WordCount;
    ULONG TotalParameterCount;
    ULONG TotalDataCount;
    ULONG ParameterCount;
    ULONG ParameterOffset;
    ULONG ParameterDisplacement;
    ULONG DataCount;
    ULONG DataOffset;
    ULONG DataDisplacement;
    ULONG ByteCount;
    ULONG ApparentMsgLength;
} SMB_TRANSACT_RESP_FORMAT_DESCRIPTION, *PSMB_TRANSACT_RESP_FORMAT_DESCRIPTION;

NTSTATUS
SmbTransactAccrueAndValidateFormatData(
    IN struct _SMB_TRANSACT_EXCHANGE *pTransactExchange,    // The exchange instance
    IN  PSMB_HEADER pSmbHeader,
    IN  ULONG        BytesIndicated,
    OUT PSMB_TRANSACT_RESP_FORMAT_DESCRIPTION Format
    );

extern NTSTATUS
SmbTransactExchangeFinalize(
    PSMB_EXCHANGE pExchange,
    BOOLEAN       *pPostFinalize);

extern NTSTATUS
ParseTransactResponse(
    IN struct _SMB_TRANSACT_EXCHANGE *pTransactExchange,    // The exchange instance
    IN PSMB_TRANSACT_RESP_FORMAT_DESCRIPTION Format,
    IN ULONG        BytesIndicated,
    IN ULONG        BytesAvailable,
    OUT ULONG       *pBytesTaken,
    IN  PSMB_HEADER pSmbHeader,
    OUT PMDL        *pCopyRequestMdlPointer,
    OUT PULONG      pCopyRequestSize);


extern NTSTATUS
SendSecondaryRequests(PVOID pContext);

extern NTSTATUS
SmbCeInitializeTransactExchange(
    PSMB_TRANSACT_EXCHANGE              pTransactExchange,
    PRX_CONTEXT                         RxContext,
    PSMB_TRANSACTION_OPTIONS            pOptions,
    PSMB_TRANSACTION_SEND_PARAMETERS    pSendParameters,
    PSMB_TRANSACTION_RECEIVE_PARAMETERS pReceiveParameters,
    PSMB_TRANSACTION_RESUMPTION_CONTEXT pResumptionContext);

NTSTATUS
SmbCeInitializeTransactionParameters(
   PVOID  pSetup,
   USHORT SetupLength,
   PVOID  pParam,
   ULONG  ParamLength,
   PVOID  pData,
   ULONG  DataLength,
   PSMB_TRANSACTION_PARAMETERS pTransactionParameters
)
/*++

Routine Description:

    This routine initializes the transaction parameters

Arguments:

    pSetup             - the setup buffer

    SetupLength        - the setup buffer length

    pParam             - the param buffer

    ParamLength        - the param buffer length

    pData              - the data buffer

    DataLength         - the data buffer length

    pTransactionParameters - the transaction parameters instance

Return Value:

    RXSTATUS - The return status for the operation

Notes:

    The TRANSACTION parameters come in two flavours -- the send parameters for the data
    that is to be sent to the server and the receive parameters for receiving the data
    from the server. There is one subtle difference in the way in which the parameters are
    stored and referenced in these two cases. In the send case the Setup buffer is stored
    as a pointer itself while in the receive case it is stored in the form of a MDL.

    This is because the SMB protocol requires that the Header + setup information for a
    transaction request cannot be greated then the maximum SMB buffer size, i.e., setup
    information cannot spill to a secondary request. The buffer that is allocated for the
    header is made sufficiently large enough to hold the setup data as well. On the other
    hand the receives are handled in a two phase manner, -- the indication at the DPC
    level followed by a copy data request if required. In order to avoid having to transition
    between DPC level and a worker thread the MDL's for the buffers are eagerly evaluated.

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;
    PMDL     pSetupMdl = NULL;
    PMDL     pParamMdl = NULL;
    PMDL     pDataMdl  = NULL;

    PAGED_CODE();

    if (pTransactionParameters->Flags & TRANSACTION_RECEIVE_PARAMETERS_FLAG) {
        if (pSetup != NULL) {
            pSetupMdl = RxAllocateMdl(pSetup,SetupLength);
            if (pSetupMdl == NULL) {
                Status = STATUS_INSUFFICIENT_RESOURCES;
            } else {
                RxProbeAndLockPages(pSetupMdl,KernelMode,IoModifyAccess,Status);
                if (Status != STATUS_SUCCESS) {
                    IoFreeMdl(pSetupMdl);
                    pSetupMdl = NULL;
                } else {
                    if (MmGetSystemAddressForMdlSafe(pSetupMdl,LowPagePriority) == NULL) { //this maps the Mdl
                        Status = STATUS_INSUFFICIENT_RESOURCES;
                    }
                }
            }
        }

        if ((Status == STATUS_SUCCESS) && (pParam != NULL)) {
            pParamMdl = RxAllocateMdl(pParam,ParamLength);
            if (pParamMdl == NULL) {
                Status = STATUS_INSUFFICIENT_RESOURCES;
            } else {
                RxProbeAndLockPages(pParamMdl,KernelMode,IoModifyAccess,Status);
                if ((Status != STATUS_SUCCESS)) {
                    IoFreeMdl(pParamMdl);
                    pParamMdl = NULL;
                } else {
                    if (MmGetSystemAddressForMdlSafe(pParamMdl,LowPagePriority) == NULL) { //this maps the Mdl
                        Status = STATUS_INSUFFICIENT_RESOURCES;
                    }
                }
            }
        }

        pTransactionParameters->SetupLength = SetupLength;
        pTransactionParameters->ParamLength = ParamLength;
        pTransactionParameters->pParamMdl = pParamMdl;
        pTransactionParameters->pSetupMdl = pSetupMdl;
    } else {
        pTransactionParameters->SetupLength = SetupLength;
        pTransactionParameters->pSetup      = pSetup;
        pTransactionParameters->ParamLength = ParamLength;
        pTransactionParameters->pParam      = pParam;
        pTransactionParameters->pParamMdl = NULL;
    }

    ASSERT( !((pData == NULL)&&(DataLength!=0)) );
    if ((Status == STATUS_SUCCESS) && (pData != NULL) && (DataLength > 0)) {
        pDataMdl = RxAllocateMdl(pData,DataLength);
        if (pDataMdl == NULL) {
            Status = STATUS_INSUFFICIENT_RESOURCES;
        } else {
            RxProbeAndLockPages(pDataMdl,KernelMode,IoModifyAccess,Status);
            if ((Status != STATUS_SUCCESS)) {
                IoFreeMdl(pDataMdl);
                pDataMdl = NULL;
            } else {
                if (MmGetSystemAddressForMdlSafe(pDataMdl,LowPagePriority) == NULL) { //this maps the Mdl
                    Status = STATUS_INSUFFICIENT_RESOURCES;
                }
            }
        }
    }

    pTransactionParameters->pDataMdl  = pDataMdl;
    pTransactionParameters->DataLength  = DataLength;
    ASSERT((Status != STATUS_SUCCESS) || (DataLength == 0) || (pDataMdl != NULL));

    if ((Status != STATUS_SUCCESS)) {
        if (pTransactionParameters->Flags & TRANSACTION_RECEIVE_PARAMETERS_FLAG) {
            if (pSetupMdl != NULL) {
                MmUnlockPages(pSetupMdl);  //this unmaps as well
                IoFreeMdl(pSetupMdl);
            }

            if (pParamMdl != NULL) {
                MmUnlockPages(pParamMdl);
                IoFreeMdl(pParamMdl);
            }
        }

        if (pDataMdl != NULL) {
            MmUnlockPages(pDataMdl);
            IoFreeMdl(pDataMdl);
        }
    }

    return Status;
}

VOID
SmbCeUninitializeTransactionParameters(
   PSMB_TRANSACTION_PARAMETERS pTransactionParameters
)
/*++

Routine Description:

    This routine uninitializes the transaction parameters, i.e., free the associated MDL's

Arguments:

    pTransactionParameters - the parameter instance for uninitialization

--*/
{
    PAGED_CODE();

    if (pTransactionParameters->Flags & TRANSACTION_RECEIVE_PARAMETERS_FLAG) {
        if (pTransactionParameters->pSetupMdl != NULL) {
            MmUnlockPages(pTransactionParameters->pSetupMdl);
            IoFreeMdl(pTransactionParameters->pSetupMdl);
        }
    }

    if (pTransactionParameters->pParamMdl != NULL) {
         MmUnlockPages(pTransactionParameters->pParamMdl);
        IoFreeMdl(pTransactionParameters->pParamMdl);
    }

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

VOID
SmbCeDiscardTransactExchange(PSMB_TRANSACT_EXCHANGE pTransactExchange)
/*++

Routine Description:

    This routine discards a transact exchange

Arguments:

    pExchange - the exchange instance

--*/
{
    PSMB_TRANSACTION_RESUMPTION_CONTEXT pResumptionContext;

    PAGED_CODE();

    // Deallocate any transact exchange specfic allocations ...
    if (pTransactExchange->pActualPrimaryRequestSmbHeader != NULL) {
        RxFreePool(pTransactExchange->pActualPrimaryRequestSmbHeader);
    }

    if (pTransactExchange->pReceiveSetupMdl != NULL) {
        MmUnlockPages(pTransactExchange->pReceiveSetupMdl);

⌨️ 快捷键说明

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