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

📄 transact.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (Status == STATUS_SUCCESS) {
        Status = SmbCeInitializeTransactionReceiveParameters(
                     pOutputSetupBuffer,        // the setup information expected in return
                     (USHORT)OutputSetupBufferLength,   // the length of the setup information
                     pOutputParamBuffer,        // the buffer for the param information
                     OutputParamBufferLength,   // the length of the param buffer
                     pOutputDataBuffer,         // the buffer for data
                     OutputDataBufferLength,    // the length of the buffer
                     &ReceiveParameters);

        if (Status != STATUS_SUCCESS) {
            SmbCeUninitializeTransactionSendParameters(&SendParameters);
        }
    }

    if (Status == STATUS_SUCCESS) {
        Status = SmbCeSubmitTransactionRequest(
                     RxContext,                    // the RXContext for the transaction
                     pOptions,                     // transaction options
                     &SendParameters,              // input parameters
                     &ReceiveParameters,           // expected results
                     pResumptionContext            // the context for resumption.
                     );

        if ((Status != STATUS_SUCCESS) &&
            (Status != STATUS_PENDING)) {
            SmbCeUninitializeTransactionReceiveParameters(&ReceiveParameters);
            SmbCeUninitializeTransactionSendParameters(&SendParameters);
        } else {
            if (!fAsynchronous) {
                if (Status == STATUS_PENDING) {
                    SmbCeWaitOnTransactionResumptionContext(pResumptionContext);
                    Status = pResumptionContext->SmbCeResumptionContext.Status;
                    if (Status != STATUS_SUCCESS) {
                        RxDbgTrace(0,Dbg,("SmbCeTransact: Transaction Request Completion Status %lx\n",Status));
                    }
                } else if (Status != STATUS_SUCCESS) {
                    RxDbgTrace(0,Dbg,("SmbCeTransact: SmbCeSubmitTransactRequest returned %lx\n",Status));
                } else {
                    Status = pResumptionContext->SmbCeResumptionContext.Status;
                }
            }
        }
    }

    ASSERT(fAsynchronous || (Status != STATUS_PENDING));

    if (fAsynchronous && (Status != STATUS_PENDING)) {
        pResumptionContext->SmbCeResumptionContext.Status = Status;
        SmbCeResume(&pResumptionContext->SmbCeResumptionContext);
        Status = STATUS_PENDING;
    }

    return Status;
}

NTSTATUS
SmbTransactBuildHeader(
    PSMB_TRANSACT_EXCHANGE  pTransactExchange,
    UCHAR                   SmbCommand,
    PSMB_HEADER             pHeader)
/*++

Routine Description:

    This routine builds the SMB header for transact exchanges

Arguments:

    pTransactExchange  - the exchange instance

    SmbCommand - the SMB command

    pHeader    - the SMB buffer header

Return Value:

    RXSTATUS - The return status for the operation

Notes:

--*/
{
    NTSTATUS Status;
    ULONG    BufferConsumed;

    UCHAR    LastCommandInHeader;
    PUCHAR   pCommand;

    PAGED_CODE();

    // Initialize the SMB header  ...
    Status = SmbCeBuildSmbHeader(
                 (PSMB_EXCHANGE)pTransactExchange,
                 pHeader,
                 sizeof(SMB_HEADER),
                 &BufferConsumed,
                 &LastCommandInHeader,
                 &pCommand);

    if (Status == STATUS_SUCCESS) {
        PSMBCEDB_SERVER_ENTRY pServerEntry;

        ASSERT(LastCommandInHeader == SMB_COM_NO_ANDX_COMMAND);
        *pCommand = SmbCommand;

        pServerEntry = SmbCeGetExchangeServerEntry(pTransactExchange);

        if (FlagOn(pServerEntry->Server.DialectFlags,DF_NT_SMBS)) {
            // for NT servers, we have to set the pid/pidhigh fields so that RPC will work.
            SmbCeSetFullProcessIdInHeader(
                (PSMB_EXCHANGE)pTransactExchange,
                RxGetRequestorProcessId(pTransactExchange->RxContext),
                ((PNT_SMB_HEADER)pHeader));
        }

        if (pTransactExchange->Flags & SMB_XACT_FLAGS_DFS_AWARE) {
            pHeader->Flags2 |= SMB_FLAGS2_DFS;
        }
    }

    return Status;
}


NTSTATUS
SmbTransactExchangeStart(
      PSMB_EXCHANGE  pExchange)
/*++

Routine Description:

    This is the start routine for transact 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

Notes:

--*/
{
    NTSTATUS Status;

    PSMB_TRANSACT_EXCHANGE pTransactExchange;
    PVOID                  pActualPrimaryRequestSmbHeader;
    PSMB_HEADER            pPrimaryRequestSmbHeader;

    // The MDL's used in sending the primary request associated with the TRANSACT SMB
    PMDL  pPartialDataMdl       = NULL;
    PMDL  pPartialParamMdl      = NULL;
    PMDL  pPaddingMdl           = NULL;
    PMDL  pPrimaryRequestSmbMdl = NULL;
    PMDL  pLastMdlInChain       = NULL;

    ULONG   MaximumSmbBufferSize;
    ULONG   PrimaryRequestSmbSize = 0;
    ULONG   PaddingLength = 0;
    BOOLEAN QuadwordAlignmentRequired = FALSE;

    ULONG ParamBytesToBeSent = 0;
    ULONG DataBytesToBeSent = 0;

    ULONG ParamOffset,DataOffset;
    ULONG SmbLength;
    ULONG BccOffset;
    ULONG MdlLength;

    USHORT *pBcc;

    PAGED_CODE();

    pTransactExchange        = (PSMB_TRANSACT_EXCHANGE)pExchange;

    pActualPrimaryRequestSmbHeader = pTransactExchange->pActualPrimaryRequestSmbHeader;
    pPrimaryRequestSmbHeader = pTransactExchange->pPrimaryRequestSmbHeader;

    ASSERT(pActualPrimaryRequestSmbHeader != NULL);
    ASSERT(pPrimaryRequestSmbHeader != NULL);

    ASSERT(!(pExchange->SmbCeFlags & SMBCE_EXCHANGE_SESSION_CONSTRUCTOR) &&
           !(pExchange->SmbCeFlags & SMBCE_EXCHANGE_NETROOT_CONSTRUCTOR));

    // Initialize the SMB header  ...
    Status = SmbTransactBuildHeader(
                 pTransactExchange,
                 pTransactExchange->SmbCommand,
                 pPrimaryRequestSmbHeader);

    if ((Status != STATUS_SUCCESS)) {
        // Finalize the exchange.
        pExchange->Status = Status;
        return Status;
    }

    PrimaryRequestSmbSize = sizeof(SMB_HEADER);

    // Compute the BccOffset and the ParamOffset which is in turn used in computing the
    // param and data bytes to be sent as part of the primary request.
    switch (pTransactExchange->SmbCommand) {
    case SMB_COM_TRANSACTION:
    case SMB_COM_TRANSACTION2:
        {
            PREQ_TRANSACTION pTransactRequest = (PREQ_TRANSACTION)
                                             (pPrimaryRequestSmbHeader + 1);
            USHORT SetupLength = pTransactRequest->SetupCount * sizeof(WORD);

            BccOffset = sizeof(SMB_HEADER) +
                        FIELD_OFFSET(REQ_TRANSACTION,Buffer) +
                        SetupLength;

            ParamOffset = ROUND_UP_COUNT(
                              (BccOffset +
                              pTransactExchange->TransactionNameLength +
                              sizeof(USHORT)),
                              sizeof(DWORD));

            pBcc = (PUSHORT)((PBYTE)pPrimaryRequestSmbHeader + BccOffset);
        }
        break;

    case SMB_COM_NT_TRANSACT:
        {
            PREQ_NT_TRANSACTION pNtTransactRequest = (PREQ_NT_TRANSACTION)
                                                  (pPrimaryRequestSmbHeader + 1);
            USHORT SetupLength = pNtTransactRequest->SetupCount * sizeof(WORD);

            RxDbgTrace( 0, Dbg, ("SmbTransactExchangeSTAAT1: init for NT_T (p,d,mp,md) %d %d %d %d\n",
                         pNtTransactRequest->TotalParameterCount, pNtTransactRequest->TotalDataCount,
                         pNtTransactRequest->MaxParameterCount, pNtTransactRequest->MaxDataCount));
            RxDbgTrace( 0, Dbg, ("SmbTransactExchangeSTAyuk: init for NT_T (s,ms) %d %d \n",
                         pNtTransactRequest->SetupCount,  pNtTransactRequest->MaxSetupCount));


            BccOffset = sizeof(SMB_HEADER) +
                        FIELD_OFFSET(REQ_NT_TRANSACTION,Buffer[0]) +
                        SetupLength;

            ParamOffset = ROUND_UP_COUNT(
                              (BccOffset + sizeof(USHORT)),
                              sizeof(DWORD));

            pBcc = (PUSHORT)((PBYTE)pPrimaryRequestSmbHeader + BccOffset);

            if (pTransactExchange->NtTransactFunction == NT_TRANSACT_SET_QUOTA) {
                QuadwordAlignmentRequired = TRUE;
            }
       }
       break;

    default:
        ASSERT(!"Valid Smb Command for initiating Transaction");
        return STATUS_INVALID_PARAMETER;
    }

    // Compute the data/param bytes that can be sent as part of the primary request
    MaximumSmbBufferSize = pTransactExchange->MaximumTransmitSmbBufferSize;

    ParamBytesToBeSent = MIN(
                             (MaximumSmbBufferSize - ParamOffset),
                             pTransactExchange->SendParamBufferSize);
    if (!QuadwordAlignmentRequired) {
        DataOffset = ROUND_UP_COUNT(ParamOffset + ParamBytesToBeSent, sizeof(DWORD));
    } else {
        DataOffset = ROUND_UP_COUNT(ParamOffset + ParamBytesToBeSent, 2*sizeof(DWORD));
    }

    if (DataOffset < MaximumSmbBufferSize) {
        DataBytesToBeSent = MIN((MaximumSmbBufferSize - DataOffset),
                                pTransactExchange->SendDataBufferSize);
        PaddingLength = DataOffset - (ParamOffset + ParamBytesToBeSent);
    } else {
        DataBytesToBeSent = 0;
    }

    if ( DataBytesToBeSent == 0) {
        DataOffset = PaddingLength = 0;
    }

    RxDbgTrace( 0, Dbg, ("SmbCeTransactExchangeStart: params,padding,data=%d,%d,%d\n",
                           ParamBytesToBeSent,PaddingLength,DataBytesToBeSent  ));
    RxDbgTrace( 0, Dbg, ("SmbCeTransactExchangeStart: paramsoffset,dataoffset=%d,%d\n",
                           ParamOffset,DataOffset  ));
    RxDbgTrace( 0, Dbg, ("SmbCeTransactExchangeStart: phdr,pbcc=%08lx,%08lx\n",
                           pPrimaryRequestSmbHeader,pBcc  ));

    // Update the primary request buffer with the final sizes of the data/parameter etc.
    switch (pTransactExchange->SmbCommand) {
    case SMB_COM_TRANSACTION:
    case SMB_COM_TRANSACTION2:
        {
            PREQ_TRANSACTION pTransactRequest = (PREQ_TRANSACTION)
                                             (pPrimaryRequestSmbHeader + 1);

            RxDbgTrace( 0, Dbg, ("SmbCeTransactExchangeStart: TRANSACTION/TRANSACTION2\n"));

            SmbPutUshort( &pTransactRequest->ParameterCount, (USHORT)ParamBytesToBeSent );
            SmbPutUshort( &pTransactRequest->ParameterOffset, (USHORT)ParamOffset);
            SmbPutUshort( &pTransactRequest->DataCount, (USHORT)DataBytesToBeSent);
            SmbPutUshort( &pTransactRequest->DataOffset, (USHORT)DataOffset);
        }
        break;

   case SMB_COM_NT_TRANSACT:
        {
            PREQ_NT_TRANSACTION pNtTransactRequest = (PREQ_NT_TRANSACTION)
                                                  (pPrimaryRequestSmbHeader + 1);

            RxDbgTrace( 0, Dbg, ("SmbCeTransactExchangeStart: NT transacton\n"));
            RxDbgTrace( 0, Dbg, ("SmbTransactExchangeSTAAT2: init for NT_T (p,d,mp,md) %d %d %d %d\n",
                         pNtTransactRequest->TotalParameterCount, pNtTransactRequest->TotalDataCount,
                         pNtTransactRequest->MaxParameterCount, pNtTransactRequest->MaxDataCount));


            SmbPutUlong( &pNtTransactRequest->ParameterCount, ParamBytesToBeSent);

⌨️ 快捷键说明

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