📄 transact.c
字号:
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 + -